driver.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. // SPDX-License-Identifier: Unlicense OR MIT
  2. package driver
  3. import (
  4. "errors"
  5. "image"
  6. "time"
  7. "gioui.org/internal/f32color"
  8. "gioui.org/shader"
  9. )
  10. // Device represents the abstraction of underlying GPU
  11. // APIs such as OpenGL, Direct3D useful for rendering Gio
  12. // operations.
  13. type Device interface {
  14. BeginFrame(target RenderTarget, clear bool, viewport image.Point) Texture
  15. EndFrame()
  16. Caps() Caps
  17. NewTimer() Timer
  18. // IsContinuousTime reports whether all timer measurements
  19. // are valid at the point of call.
  20. IsTimeContinuous() bool
  21. NewTexture(format TextureFormat, width, height int, minFilter, magFilter TextureFilter, bindings BufferBinding) (Texture, error)
  22. NewImmutableBuffer(typ BufferBinding, data []byte) (Buffer, error)
  23. NewBuffer(typ BufferBinding, size int) (Buffer, error)
  24. NewComputeProgram(shader shader.Sources) (Program, error)
  25. NewVertexShader(src shader.Sources) (VertexShader, error)
  26. NewFragmentShader(src shader.Sources) (FragmentShader, error)
  27. NewPipeline(desc PipelineDesc) (Pipeline, error)
  28. Viewport(x, y, width, height int)
  29. DrawArrays(off, count int)
  30. DrawElements(off, count int)
  31. BeginRenderPass(t Texture, desc LoadDesc)
  32. EndRenderPass()
  33. PrepareTexture(t Texture)
  34. BindProgram(p Program)
  35. BindPipeline(p Pipeline)
  36. BindTexture(unit int, t Texture)
  37. BindVertexBuffer(b Buffer, offset int)
  38. BindIndexBuffer(b Buffer)
  39. BindImageTexture(unit int, texture Texture)
  40. BindUniforms(buf Buffer)
  41. BindStorageBuffer(binding int, buf Buffer)
  42. BeginCompute()
  43. EndCompute()
  44. CopyTexture(dst Texture, dstOrigin image.Point, src Texture, srcRect image.Rectangle)
  45. DispatchCompute(x, y, z int)
  46. Release()
  47. }
  48. var ErrDeviceLost = errors.New("GPU device lost")
  49. type LoadDesc struct {
  50. Action LoadAction
  51. ClearColor f32color.RGBA
  52. }
  53. type Pipeline interface {
  54. Release()
  55. }
  56. type PipelineDesc struct {
  57. VertexShader VertexShader
  58. FragmentShader FragmentShader
  59. VertexLayout VertexLayout
  60. BlendDesc BlendDesc
  61. PixelFormat TextureFormat
  62. Topology Topology
  63. }
  64. type VertexLayout struct {
  65. Inputs []InputDesc
  66. Stride int
  67. }
  68. // InputDesc describes a vertex attribute as laid out in a Buffer.
  69. type InputDesc struct {
  70. Type shader.DataType
  71. Size int
  72. Offset int
  73. }
  74. type BlendDesc struct {
  75. Enable bool
  76. SrcFactor, DstFactor BlendFactor
  77. }
  78. type BlendFactor uint8
  79. type Topology uint8
  80. type TextureFilter uint8
  81. type TextureFormat uint8
  82. type BufferBinding uint8
  83. type LoadAction uint8
  84. type Features uint
  85. type Caps struct {
  86. // BottomLeftOrigin is true if the driver has the origin in the lower left
  87. // corner. The OpenGL driver returns true.
  88. BottomLeftOrigin bool
  89. Features Features
  90. MaxTextureSize int
  91. }
  92. type VertexShader interface {
  93. Release()
  94. }
  95. type FragmentShader interface {
  96. Release()
  97. }
  98. type Program interface {
  99. Release()
  100. }
  101. type Buffer interface {
  102. Release()
  103. Upload(data []byte)
  104. Download(data []byte) error
  105. }
  106. type Timer interface {
  107. Begin()
  108. End()
  109. Duration() (time.Duration, bool)
  110. Release()
  111. }
  112. type Texture interface {
  113. RenderTarget
  114. Upload(offset, size image.Point, pixels []byte, stride int)
  115. ReadPixels(src image.Rectangle, pixels []byte, stride int) error
  116. Release()
  117. }
  118. const (
  119. BufferBindingIndices BufferBinding = 1 << iota
  120. BufferBindingVertices
  121. BufferBindingUniforms
  122. BufferBindingTexture
  123. BufferBindingFramebuffer
  124. BufferBindingShaderStorageRead
  125. BufferBindingShaderStorageWrite
  126. )
  127. const (
  128. TextureFormatSRGBA TextureFormat = iota
  129. TextureFormatFloat
  130. TextureFormatRGBA8
  131. // TextureFormatOutput denotes the format used by the output framebuffer.
  132. TextureFormatOutput
  133. )
  134. const (
  135. FilterNearest TextureFilter = iota
  136. FilterLinear
  137. FilterLinearMipmapLinear
  138. )
  139. const (
  140. FeatureTimers Features = 1 << iota
  141. FeatureFloatRenderTargets
  142. FeatureCompute
  143. FeatureSRGB
  144. )
  145. const (
  146. TopologyTriangleStrip Topology = iota
  147. TopologyTriangles
  148. )
  149. const (
  150. BlendFactorOne BlendFactor = iota
  151. BlendFactorOneMinusSrcAlpha
  152. BlendFactorZero
  153. BlendFactorDstColor
  154. )
  155. const (
  156. LoadActionKeep LoadAction = iota
  157. LoadActionClear
  158. LoadActionInvalidate
  159. )
  160. var ErrContentLost = errors.New("buffer content lost")
  161. func (f Features) Has(feats Features) bool {
  162. return f&feats == feats
  163. }
  164. func DownloadImage(d Device, t Texture, img *image.RGBA) error {
  165. r := img.Bounds()
  166. if err := t.ReadPixels(r, img.Pix, img.Stride); err != nil {
  167. return err
  168. }
  169. if d.Caps().BottomLeftOrigin {
  170. // OpenGL origin is in the lower-left corner. Flip the image to
  171. // match.
  172. flipImageY(r.Dx()*4, r.Dy(), img.Pix)
  173. }
  174. return nil
  175. }
  176. func flipImageY(stride, height int, pixels []byte) {
  177. // Flip image in y-direction. OpenGL's origin is in the lower
  178. // left corner.
  179. row := make([]uint8, stride)
  180. for y := 0; y < height/2; y++ {
  181. y1 := height - y - 1
  182. dest := y1 * stride
  183. src := y * stride
  184. copy(row, pixels[dest:])
  185. copy(pixels[dest:], pixels[src:src+len(row)])
  186. copy(pixels[src:], row)
  187. }
  188. }
  189. func UploadImage(t Texture, offset image.Point, img *image.RGBA) {
  190. var pixels []byte
  191. size := img.Bounds().Size()
  192. min := img.Rect.Min
  193. start := img.PixOffset(min.X, min.Y)
  194. end := img.PixOffset(min.X+size.X, min.Y+size.Y-1)
  195. pixels = img.Pix[start:end]
  196. t.Upload(offset, size, pixels, img.Stride)
  197. }