From 5cd5d491081ea23bdce7c236de58e924ef00e4d1 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Sun, 23 Feb 2020 12:46:17 +0100 Subject: [PATCH] gpu/backend: move backend interface types to a separate package Signed-off-by: Elias Naur --- app/headless/headless.go | 33 ++++---- app/headless/headless_darwin.go | 6 +- app/headless/headless_egl.go | 2 +- app/headless/headless_gl.go | 2 +- app/headless/headless_js.go | 6 +- app/internal/egl/egl.go | 4 +- app/internal/window/gl_ios.go | 4 +- app/internal/window/gl_js.go | 4 +- app/internal/window/gl_macos.go | 4 +- app/internal/window/window.go | 4 +- gpu/{ => backend}/backend.go | 6 +- gpu/build.go | 11 +-- gpu/gl/backend.go | 136 ++++++++++++++++---------------- gpu/gpu.go | 65 +++++++-------- gpu/path.go | 69 ++++++++-------- gpu/shaders.go | 54 +++++++------ gpu/timer.go | 10 ++- 17 files changed, 214 insertions(+), 206 deletions(-) rename gpu/{ => backend}/backend.go (97%) diff --git a/app/headless/headless.go b/app/headless/headless.go index f891e947..df56295b 100644 --- a/app/headless/headless.go +++ b/app/headless/headless.go @@ -9,21 +9,22 @@ import ( "runtime" "gioui.org/gpu" + "gioui.org/gpu/backend" "gioui.org/op" ) // Window is a headless window. type Window struct { size image.Point - ctx backend - backend gpu.Backend + ctx context + backend backend.Device gpu *gpu.GPU - fboTex gpu.Texture - fbo gpu.Framebuffer + fboTex backend.Texture + fbo backend.Framebuffer } -type backend interface { - Backend() (gpu.Backend, error) +type context interface { + Backend() (backend.Device, error) MakeCurrent() error ReleaseCurrent() Release() @@ -40,27 +41,27 @@ func NewWindow(width, height int) (*Window, error) { ctx: ctx, } err = contextDo(ctx, func() error { - backend, err := ctx.Backend() + dev, err := ctx.Backend() if err != nil { return err } - fboTex, err := backend.NewTexture( - gpu.TextureFormatSRGB, + fboTex, err := dev.NewTexture( + backend.TextureFormatSRGB, width, height, - gpu.FilterNearest, gpu.FilterNearest, - gpu.BufferBindingFramebuffer, + backend.FilterNearest, backend.FilterNearest, + backend.BufferBindingFramebuffer, ) if err != nil { return nil } const depthBits = 16 - fbo, err := backend.NewFramebuffer(fboTex, depthBits) + fbo, err := dev.NewFramebuffer(fboTex, depthBits) if err != nil { fboTex.Release() return err } - backend.BindFramebuffer(fbo) - gp, err := gpu.New(backend) + dev.BindFramebuffer(fbo) + gp, err := gpu.New(dev) if err != nil { fbo.Release() fboTex.Release() @@ -69,7 +70,7 @@ func NewWindow(width, height int) (*Window, error) { w.fboTex = fboTex w.fbo = fbo w.gpu = gp - w.backend = backend + w.backend = dev return err }) if err != nil { @@ -139,7 +140,7 @@ func (w *Window) Screenshot() (*image.RGBA, error) { return img, nil } -func contextDo(ctx backend, f func() error) error { +func contextDo(ctx context, f func() error) error { errCh := make(chan error) go func() { runtime.LockOSThread() diff --git a/app/headless/headless_darwin.go b/app/headless/headless_darwin.go index d569d4df..7282ae06 100644 --- a/app/headless/headless_darwin.go +++ b/app/headless/headless_darwin.go @@ -4,7 +4,7 @@ package headless import ( "gioui.org/app/internal/glimpl" - "gioui.org/gpu" + "gioui.org/gpu/backend" "gioui.org/gpu/gl" ) @@ -22,7 +22,7 @@ type nsContext struct { prepared bool } -func newGLContext() (backend, error) { +func newGLContext() (context, error) { ctx := C.gio_headless_newContext() return &nsContext{ctx: ctx, c: new(glimpl.Functions)}, nil } @@ -40,7 +40,7 @@ func (c *nsContext) ReleaseCurrent() { C.gio_headless_clearCurrentContext(c.ctx) } -func (c *nsContext) Backend() (gpu.Backend, error) { +func (c *nsContext) Backend() (backend.Device, error) { return gl.NewBackend(c.c) } diff --git a/app/headless/headless_egl.go b/app/headless/headless_egl.go index cc12b78f..bc107106 100644 --- a/app/headless/headless_egl.go +++ b/app/headless/headless_egl.go @@ -8,6 +8,6 @@ import ( "gioui.org/app/internal/egl" ) -func newGLContext() (backend, error) { +func newGLContext() (context, error) { return egl.NewContext(egl.EGL_DEFAULT_DISPLAY) } diff --git a/app/headless/headless_gl.go b/app/headless/headless_gl.go index 582516c2..3718969e 100644 --- a/app/headless/headless_gl.go +++ b/app/headless/headless_gl.go @@ -2,6 +2,6 @@ package headless -func newContext() (backend, error) { +func newContext() (context, error) { return newGLContext() } diff --git a/app/headless/headless_js.go b/app/headless/headless_js.go index ec03f43c..7ce860a2 100644 --- a/app/headless/headless_js.go +++ b/app/headless/headless_js.go @@ -7,7 +7,7 @@ import ( "syscall/js" "gioui.org/app/internal/glimpl" - "gioui.org/gpu" + "gioui.org/gpu/backend" "gioui.org/gpu/gl" ) @@ -16,7 +16,7 @@ type jsContext struct { f *glimpl.Functions } -func newGLContext() (backend, error) { +func newGLContext() (context, error) { version := 2 doc := js.Global().Get("document") cnv := doc.Call("createElement", "canvas") @@ -39,7 +39,7 @@ func newGLContext() (backend, error) { return c, nil } -func (c *jsContext) Backend() (gpu.Backend, error) { +func (c *jsContext) Backend() (backend.Device, error) { return gl.NewBackend(c.f) } diff --git a/app/internal/egl/egl.go b/app/internal/egl/egl.go index 1cca7332..cc028028 100644 --- a/app/internal/egl/egl.go +++ b/app/internal/egl/egl.go @@ -12,7 +12,7 @@ import ( "gioui.org/app/internal/glimpl" "gioui.org/app/internal/srgb" - "gioui.org/gpu" + "gioui.org/gpu/backend" "gioui.org/gpu/gl" ) @@ -121,7 +121,7 @@ func (c *Context) Functions() *glimpl.Functions { return c.c } -func (c *Context) Backend() (gpu.Backend, error) { +func (c *Context) Backend() (backend.Device, error) { return gl.NewBackend(c.c) } diff --git a/app/internal/window/gl_ios.go b/app/internal/window/gl_ios.go index 4bc03534..2dbd9710 100644 --- a/app/internal/window/gl_ios.go +++ b/app/internal/window/gl_ios.go @@ -17,7 +17,7 @@ import ( "fmt" "gioui.org/app/internal/glimpl" - "gioui.org/gpu" + "gioui.org/gpu/backend" "gioui.org/gpu/gl" ) @@ -51,7 +51,7 @@ func newContext(w *window) (*context, error) { return c, nil } -func (c *context) Backend() (gpu.Backend, error) { +func (c *context) Backend() (backend.Device, error) { return gl.NewBackend(c.c) } diff --git a/app/internal/window/gl_js.go b/app/internal/window/gl_js.go index c18d79e1..0adbdf4a 100644 --- a/app/internal/window/gl_js.go +++ b/app/internal/window/gl_js.go @@ -8,7 +8,7 @@ import ( "gioui.org/app/internal/glimpl" "gioui.org/app/internal/srgb" - "gioui.org/gpu" + "gioui.org/gpu/backend" "gioui.org/gpu/gl" ) @@ -47,7 +47,7 @@ func newContext(w *window) (*context, error) { return c, nil } -func (c *context) Backend() (gpu.Backend, error) { +func (c *context) Backend() (backend.Device, error) { return gl.NewBackend(c.f) } diff --git a/app/internal/window/gl_macos.go b/app/internal/window/gl_macos.go index 944b2327..bbbfda6e 100644 --- a/app/internal/window/gl_macos.go +++ b/app/internal/window/gl_macos.go @@ -6,7 +6,7 @@ package window import ( "gioui.org/app/internal/glimpl" - "gioui.org/gpu" + "gioui.org/gpu/backend" "gioui.org/gpu/gl" ) @@ -42,7 +42,7 @@ func newContext(w *window) (*context, error) { return c, nil } -func (c *context) Backend() (gpu.Backend, error) { +func (c *context) Backend() (backend.Device, error) { return gl.NewBackend(c.c) } diff --git a/app/internal/window/window.go b/app/internal/window/window.go index 36f7e16c..c351fdec 100644 --- a/app/internal/window/window.go +++ b/app/internal/window/window.go @@ -9,7 +9,7 @@ import ( "math" "time" - "gioui.org/gpu" + "gioui.org/gpu/backend" "gioui.org/io/event" "gioui.org/io/system" "gioui.org/unit" @@ -32,7 +32,7 @@ type Callbacks interface { } type Context interface { - Backend() (gpu.Backend, error) + Backend() (backend.Device, error) Present() error MakeCurrent() error Release() diff --git a/gpu/backend.go b/gpu/backend/backend.go similarity index 97% rename from gpu/backend.go rename to gpu/backend/backend.go index b5082deb..b65a2dc9 100644 --- a/gpu/backend.go +++ b/gpu/backend/backend.go @@ -1,16 +1,16 @@ // SPDX-License-Identifier: Unlicense OR MIT -package gpu +package backend import ( "image" "time" ) -// Backend represents the abstraction of underlying GPU +// Device represents the abstraction of underlying GPU // APIs such as OpenGL, Direct3D useful for rendering Gio // operations. -type Backend interface { +type Device interface { BeginFrame() EndFrame() Caps() Caps diff --git a/gpu/build.go b/gpu/build.go index c0647cdb..e5f8d747 100644 --- a/gpu/build.go +++ b/gpu/build.go @@ -85,6 +85,7 @@ func generate() error { var out bytes.Buffer out.WriteString("// Code generated by build.go. DO NOT EDIT.\n\n") out.WriteString("package gpu\n\n") + fmt.Fprintf(&out, "import %q\n\n", "gioui.org/gpu/backend") out.WriteString("var (\n") @@ -155,12 +156,12 @@ func generate() error { // only a single version. multiVariant := variants[0].gles2 != variants[1].gles2 if multiVariant { - fmt.Fprintf(&out, "[...]ShaderSources{\n") + fmt.Fprintf(&out, "[...]backend.ShaderSources{\n") } for _, src := range variants { - fmt.Fprintf(&out, "ShaderSources{\n") + fmt.Fprintf(&out, "backend.ShaderSources{\n") if len(src.inputs) > 0 { - fmt.Fprintf(&out, "Inputs: []InputLocation{\n") + fmt.Fprintf(&out, "Inputs: []backend.InputLocation{\n") for _, inp := range src.inputs { fmt.Fprintf(&out, "{Name: %q, Location: %d, Semantic: %q, ", inp.Name, inp.Location, inp.Semantic) fmt.Fprintf(&out, "SemanticIndex: %d, Type: %d, Size: %d},\n", inp.SemanticIndex, inp.Type, inp.Size) @@ -168,7 +169,7 @@ func generate() error { fmt.Fprintf(&out, "},\n") } if len(src.uniforms) > 0 { - fmt.Fprintf(&out, "Uniforms: []UniformLocation{\n") + fmt.Fprintf(&out, "Uniforms: []backend.UniformLocation{\n") for _, u := range src.uniforms { fmt.Fprintf(&out, "{Name: %q, Type: %d, Size: %d, Offset: %d},\n", u.Name, u.Type, u.Size, u.Offset) } @@ -178,7 +179,7 @@ func generate() error { fmt.Fprintf(&out, "UniformSize: %d,\n", src.uniformSize) } if len(src.textures) > 0 { - fmt.Fprintf(&out, "Textures: []TextureBinding{\n") + fmt.Fprintf(&out, "Textures: []backend.TextureBinding{\n") for _, t := range src.textures { fmt.Fprintf(&out, "{Name: %q, Binding: %d},\n", t.Name, t.Binding) } diff --git a/gpu/gl/backend.go b/gpu/gl/backend.go index caa76429..87f120cc 100644 --- a/gpu/gl/backend.go +++ b/gpu/gl/backend.go @@ -10,16 +10,16 @@ import ( "time" "unsafe" - "gioui.org/gpu" + "gioui.org/gpu/backend" ) -// Backend implements gpu.Backend. +// Backend implements backend.Device. type Backend struct { funcs Functions state glstate - feats gpu.Caps + feats backend.Caps // floatTriple holds the settings for floating point // textures. floatTriple textureTriple @@ -68,7 +68,7 @@ type gpuFramebuffer struct { type gpuBuffer struct { backend *Backend obj Buffer - typ gpu.BufferBinding + typ backend.BufferBinding size int immutable bool version int @@ -94,14 +94,14 @@ type uniformsTracker struct { type uniformLocation struct { uniform Uniform offset int - typ gpu.DataType + typ backend.DataType size int } type gpuInputLayout struct { backend *Backend - inputs []gpu.InputLocation - layout []gpu.InputDesc + inputs []backend.InputLocation + layout []backend.InputDesc } // textureTriple holds the type settings for @@ -134,7 +134,7 @@ func NewBackend(f Functions) (*Backend, error) { srgbaTriple: srgbaTriple, } if hasExtension(exts, "GL_EXT_disjoint_timer_query_webgl2") || hasExtension(exts, "GL_EXT_disjoint_timer_query") { - b.feats.Features |= gpu.FeatureTimers + b.feats.Features |= backend.FeatureTimers } b.feats.MaxTextureSize = f.GetInteger(MAX_TEXTURE_SIZE) return b, nil @@ -149,11 +149,11 @@ func (b *Backend) EndFrame() { b.funcs.ActiveTexture(TEXTURE0) } -func (b *Backend) Caps() gpu.Caps { +func (b *Backend) Caps() backend.Caps { return b.feats } -func (b *Backend) NewTimer() gpu.Timer { +func (b *Backend) NewTimer() backend.Timer { return &gpuTimer{ funcs: b.funcs, obj: b.funcs.CreateQuery(), @@ -164,7 +164,7 @@ func (b *Backend) IsTimeContinuous() bool { return b.funcs.GetInteger(GPU_DISJOINT_EXT) == FALSE } -func (b *Backend) NewFramebuffer(tex gpu.Texture, depthBits int) (gpu.Framebuffer, error) { +func (b *Backend) NewFramebuffer(tex backend.Texture, depthBits int) (backend.Framebuffer, error) { glErr(b.funcs) gltex := tex.(*gpuTexture) fb := b.funcs.CreateFramebuffer() @@ -200,18 +200,18 @@ func (b *Backend) NewFramebuffer(tex gpu.Texture, depthBits int) (gpu.Framebuffe return fbo, nil } -func (b *Backend) CurrentFramebuffer() gpu.Framebuffer { +func (b *Backend) CurrentFramebuffer() backend.Framebuffer { fboID := Framebuffer(b.funcs.GetBinding(FRAMEBUFFER_BINDING)) return &gpuFramebuffer{backend: b, obj: fboID, foreign: true} } -func (b *Backend) NewTexture(format gpu.TextureFormat, width, height int, minFilter, magFilter gpu.TextureFilter, binding gpu.BufferBinding) (gpu.Texture, error) { +func (b *Backend) NewTexture(format backend.TextureFormat, width, height int, minFilter, magFilter backend.TextureFilter, binding backend.BufferBinding) (backend.Texture, error) { glErr(b.funcs) tex := &gpuTexture{backend: b, obj: b.funcs.CreateTexture(), width: width, height: height} switch format { - case gpu.TextureFormatFloat: + case backend.TextureFormatFloat: tex.triple = b.floatTriple - case gpu.TextureFormatSRGB: + case backend.TextureFormatSRGB: tex.triple = b.srgbaTriple default: return nil, errors.New("unsupported texture format") @@ -229,17 +229,17 @@ func (b *Backend) NewTexture(format gpu.TextureFormat, width, height int, minFil return tex, nil } -func (b *Backend) NewBuffer(typ gpu.BufferBinding, size int) (gpu.Buffer, error) { +func (b *Backend) NewBuffer(typ backend.BufferBinding, size int) (backend.Buffer, error) { glErr(b.funcs) buf := &gpuBuffer{backend: b, typ: typ, size: size} - if typ&gpu.BufferBindingUniforms != 0 { - if typ != gpu.BufferBindingUniforms { + if typ&backend.BufferBindingUniforms != 0 { + if typ != backend.BufferBindingUniforms { return nil, errors.New("uniforms buffers cannot be bound as anything else") } // GLES 2 doesn't support uniform buffers. buf.data = make([]byte, size) } - if typ&^gpu.BufferBindingUniforms != 0 { + if typ&^backend.BufferBindingUniforms != 0 { buf.obj = b.funcs.CreateBuffer() if err := glErr(b.funcs); err != nil { buf.Release() @@ -249,7 +249,7 @@ func (b *Backend) NewBuffer(typ gpu.BufferBinding, size int) (gpu.Buffer, error) return buf, nil } -func (b *Backend) NewImmutableBuffer(typ gpu.BufferBinding, data []byte) (gpu.Buffer, error) { +func (b *Backend) NewImmutableBuffer(typ backend.BufferBinding, data []byte) (backend.Buffer, error) { glErr(b.funcs) obj := b.funcs.CreateBuffer() buf := &gpuBuffer{backend: b, obj: obj, typ: typ, size: len(data)} @@ -304,19 +304,19 @@ func (b *Backend) SetDepthTest(enable bool) { } } -func (b *Backend) BlendFunc(sfactor, dfactor gpu.BlendFactor) { +func (b *Backend) BlendFunc(sfactor, dfactor backend.BlendFactor) { b.funcs.BlendFunc(toGLBlendFactor(sfactor), toGLBlendFactor(dfactor)) } -func toGLBlendFactor(f gpu.BlendFactor) Enum { +func toGLBlendFactor(f backend.BlendFactor) Enum { switch f { - case gpu.BlendFactorOne: + case backend.BlendFactorOne: return ONE - case gpu.BlendFactorOneMinusSrcAlpha: + case backend.BlendFactorOneMinusSrcAlpha: return ONE_MINUS_SRC_ALPHA - case gpu.BlendFactorZero: + case backend.BlendFactorZero: return ZERO - case gpu.BlendFactorDstColor: + case backend.BlendFactorDstColor: return DST_COLOR default: panic("unsupported blend factor") @@ -335,14 +335,14 @@ func (b *Backend) SetBlend(enable bool) { } } -func (b *Backend) DrawElements(mode gpu.DrawMode, off, count int) { +func (b *Backend) DrawElements(mode backend.DrawMode, off, count int) { b.prepareDraw() // off is in 16-bit indices, but DrawElements take a byte offset. byteOff := off * 2 b.funcs.DrawElements(toGLDrawMode(mode), count, UNSIGNED_SHORT, byteOff) } -func (b *Backend) DrawArrays(mode gpu.DrawMode, off, count int) { +func (b *Backend) DrawArrays(mode backend.DrawMode, off, count int) { b.prepareDraw() b.funcs.DrawArrays(toGLDrawMode(mode), off, count) } @@ -354,11 +354,11 @@ func (b *Backend) prepareDraw() { } } -func toGLDrawMode(mode gpu.DrawMode) Enum { +func toGLDrawMode(mode backend.DrawMode) Enum { switch mode { - case gpu.DrawModeTriangleStrip: + case backend.DrawModeTriangleStrip: return TRIANGLE_STRIP - case gpu.DrawModeTriangles: + case backend.DrawModeTriangles: return TRIANGLES default: panic("unsupported draw mode") @@ -369,12 +369,12 @@ func (b *Backend) Viewport(x, y, width, height int) { b.funcs.Viewport(x, y, width, height) } -func (b *Backend) Clear(attachments gpu.BufferAttachments) { +func (b *Backend) Clear(attachments backend.BufferAttachments) { var mask Enum - if attachments&gpu.BufferAttachmentColor != 0 { + if attachments&backend.BufferAttachmentColor != 0 { mask |= COLOR_BUFFER_BIT } - if attachments&gpu.BufferAttachmentDepth != 0 { + if attachments&backend.BufferAttachmentDepth != 0 { mask |= DEPTH_BUFFER_BIT } b.funcs.Clear(mask) @@ -388,10 +388,10 @@ func (b *Backend) ClearColor(colR, colG, colB, colA float32) { b.funcs.ClearColor(colR, colG, colB, colA) } -func (b *Backend) DepthFunc(f gpu.DepthFunc) { +func (b *Backend) DepthFunc(f backend.DepthFunc) { var glfunc Enum switch f { - case gpu.DepthFuncGreater: + case backend.DepthFuncGreater: glfunc = GREATER default: panic("unsupported depth func") @@ -399,7 +399,7 @@ func (b *Backend) DepthFunc(f gpu.DepthFunc) { b.funcs.DepthFunc(glfunc) } -func (b *Backend) NewInputLayout(vs gpu.ShaderSources, layout []gpu.InputDesc) (gpu.InputLayout, error) { +func (b *Backend) NewInputLayout(vs backend.ShaderSources, layout []backend.InputDesc) (backend.InputLayout, error) { if len(vs.Inputs) != len(layout) { return nil, fmt.Errorf("NewInputLayout: got %d inputs, expected %d", len(layout), len(vs.Inputs)) } @@ -415,7 +415,7 @@ func (b *Backend) NewInputLayout(vs gpu.ShaderSources, layout []gpu.InputDesc) ( }, nil } -func (b *Backend) NewProgram(vssrc, fssrc gpu.ShaderSources) (gpu.Program, error) { +func (b *Backend) NewProgram(vssrc, fssrc backend.ShaderSources) (backend.Program, error) { attr := make([]string, len(vssrc.Inputs)) for _, inp := range vssrc.Inputs { attr[inp.Location] = inp.Name @@ -448,16 +448,16 @@ func (b *Backend) NewProgram(vssrc, fssrc gpu.ShaderSources) (gpu.Program, error return gpuProg, nil } -func lookupUniform(funcs Functions, p Program, loc gpu.UniformLocation) uniformLocation { +func lookupUniform(funcs Functions, p Program, loc backend.UniformLocation) uniformLocation { u := GetUniformLocation(funcs, p, loc.Name) return uniformLocation{uniform: u, offset: loc.Offset, typ: loc.Type, size: loc.Size} } -func (p *gpuProgram) SetVertexUniforms(buffer gpu.Buffer) { +func (p *gpuProgram) SetVertexUniforms(buffer backend.Buffer) { p.vertUniforms.setBuffer(buffer) } -func (p *gpuProgram) SetFragmentUniforms(buffer gpu.Buffer) { +func (p *gpuProgram) SetFragmentUniforms(buffer backend.Buffer) { p.fragUniforms.setBuffer(buffer) } @@ -466,7 +466,7 @@ func (p *gpuProgram) updateUniforms() { p.fragUniforms.update(p.backend.funcs) } -func (b *Backend) BindProgram(prog gpu.Program) { +func (b *Backend) BindProgram(prog backend.Program) { p := prog.(*gpuProgram) b.useProgram(p) b.enableVertexArrays(p.nattr) @@ -476,7 +476,7 @@ func (p *gpuProgram) Release() { p.backend.funcs.DeleteProgram(p.obj) } -func (u *uniformsTracker) setup(funcs Functions, p Program, uniformSize int, uniforms []gpu.UniformLocation) { +func (u *uniformsTracker) setup(funcs Functions, p Program, uniformSize int, uniforms []backend.UniformLocation) { u.locs = make([]uniformLocation, len(uniforms)) for i, uniform := range uniforms { u.locs[i] = lookupUniform(funcs, p, uniform) @@ -484,9 +484,9 @@ func (u *uniformsTracker) setup(funcs Functions, p Program, uniformSize int, uni u.size = uniformSize } -func (u *uniformsTracker) setBuffer(buffer gpu.Buffer) { +func (u *uniformsTracker) setBuffer(buffer backend.Buffer) { buf := buffer.(*gpuBuffer) - if buf.typ&gpu.BufferBindingUniforms == 0 { + if buf.typ&backend.BufferBindingUniforms == 0 { panic("not a uniform buffer") } if buf.size < u.size { @@ -507,19 +507,19 @@ func (p *uniformsTracker) update(funcs Functions) { for _, u := range p.locs { data := data[u.offset:] switch { - case u.typ == gpu.DataTypeFloat && u.size == 1: + case u.typ == backend.DataTypeFloat && u.size == 1: data := data[:4] v := *(*[1]float32)(unsafe.Pointer(&data[0])) funcs.Uniform1f(u.uniform, v[0]) - case u.typ == gpu.DataTypeFloat && u.size == 2: + case u.typ == backend.DataTypeFloat && u.size == 2: data := data[:8] v := *(*[2]float32)(unsafe.Pointer(&data[0])) funcs.Uniform2f(u.uniform, v[0], v[1]) - case u.typ == gpu.DataTypeFloat && u.size == 3: + case u.typ == backend.DataTypeFloat && u.size == 3: data := data[:12] v := *(*[3]float32)(unsafe.Pointer(&data[0])) funcs.Uniform3f(u.uniform, v[0], v[1], v[2]) - case u.typ == gpu.DataTypeFloat && u.size == 4: + case u.typ == backend.DataTypeFloat && u.size == 4: data := data[:16] v := *(*[4]float32)(unsafe.Pointer(&data[0])) funcs.Uniform4f(u.uniform, v[0], v[1], v[2], v[3]) @@ -537,10 +537,10 @@ func (b *gpuBuffer) Upload(data []byte) { panic("buffer size overflow") } b.version++ - if b.typ&gpu.BufferBindingUniforms != 0 { + if b.typ&backend.BufferBindingUniforms != 0 { copy(b.data, data) } - if b.typ&^gpu.BufferBindingUniforms != 0 { + if b.typ&^backend.BufferBindingUniforms != 0 { firstBinding := firstBufferType(b.typ) b.backend.funcs.BindBuffer(firstBinding, b.obj) b.backend.funcs.BufferData(firstBinding, data, STATIC_DRAW) @@ -548,14 +548,14 @@ func (b *gpuBuffer) Upload(data []byte) { } func (b *gpuBuffer) Release() { - if b.typ&^gpu.BufferBindingUniforms != 0 { + if b.typ&^backend.BufferBindingUniforms != 0 { b.backend.funcs.DeleteBuffer(b.obj) } } -func (b *Backend) BindVertexBuffer(buf gpu.Buffer, stride, offset int) { +func (b *Backend) BindVertexBuffer(buf backend.Buffer, stride, offset int) { gbuf := buf.(*gpuBuffer) - if gbuf.typ&gpu.BufferBindingVertices == 0 { + if gbuf.typ&backend.BufferBindingVertices == 0 { panic("not a vertex buffer") } b.state.buffer = bufferBinding{buf: gbuf, stride: stride, offset: offset} @@ -572,9 +572,9 @@ func (b *Backend) setupVertexArrays() { l := layout.layout[i] var gltyp Enum switch l.Type { - case gpu.DataTypeFloat: + case backend.DataTypeFloat: gltyp = FLOAT - case gpu.DataTypeShort: + case backend.DataTypeShort: gltyp = SHORT default: panic("unsupported data type") @@ -583,9 +583,9 @@ func (b *Backend) setupVertexArrays() { } } -func (b *Backend) BindIndexBuffer(buf gpu.Buffer) { +func (b *Backend) BindIndexBuffer(buf backend.Buffer) { gbuf := buf.(*gpuBuffer) - if gbuf.typ&gpu.BufferBindingIndices == 0 { + if gbuf.typ&backend.BufferBindingIndices == 0 { panic("not an index buffer") } b.funcs.BindBuffer(ELEMENT_ARRAY_BUFFER, gbuf.obj) @@ -601,7 +601,7 @@ func (f *gpuFramebuffer) ReadPixels(src image.Rectangle, pixels []byte) error { return glErr(f.backend.funcs) } -func (b *Backend) BindFramebuffer(fbo gpu.Framebuffer) { +func (b *Backend) BindFramebuffer(fbo backend.Framebuffer) { b.funcs.BindFramebuffer(FRAMEBUFFER, fbo.(*gpuFramebuffer).obj) } @@ -620,18 +620,18 @@ func (f *gpuFramebuffer) Release() { } } -func toTexFilter(f gpu.TextureFilter) int { +func toTexFilter(f backend.TextureFilter) int { switch f { - case gpu.FilterNearest: + case backend.FilterNearest: return NEAREST - case gpu.FilterLinear: + case backend.FilterLinear: return LINEAR default: panic("unsupported texture filter") } } -func (b *Backend) BindTexture(unit int, t gpu.Texture) { +func (b *Backend) BindTexture(unit int, t backend.Texture) { b.bindTexture(unit, t.(*gpuTexture)) } @@ -677,7 +677,7 @@ func (t *gpuTimer) Duration() (time.Duration, bool) { return time.Duration(nanos), true } -func (b *Backend) BindInputLayout(l gpu.InputLayout) { +func (b *Backend) BindInputLayout(l backend.InputLayout) { b.state.layout = l.(*gpuInputLayout) } @@ -753,13 +753,13 @@ func hasExtension(exts []string, ext string) bool { return false } -func firstBufferType(typ gpu.BufferBinding) Enum { +func firstBufferType(typ backend.BufferBinding) Enum { switch { - case typ&gpu.BufferBindingIndices != 0: + case typ&backend.BufferBindingIndices != 0: return ELEMENT_ARRAY_BUFFER - case typ&gpu.BufferBindingVertices != 0: + case typ&backend.BufferBindingVertices != 0: return ARRAY_BUFFER - case typ&gpu.BufferBindingUniforms != 0: + case typ&backend.BufferBindingUniforms != 0: return UNIFORM_BUFFER default: panic("unsupported buffer type") diff --git a/gpu/gpu.go b/gpu/gpu.go index bd31a955..51a21123 100644 --- a/gpu/gpu.go +++ b/gpu/gpu.go @@ -18,6 +18,7 @@ import ( "unsafe" "gioui.org/f32" + "gioui.org/gpu/backend" "gioui.org/internal/opconst" "gioui.org/internal/ops" "gioui.org/internal/path" @@ -30,18 +31,18 @@ type GPU struct { pathCache *opCache cache *resourceCache - defFBO Framebuffer + defFBO backend.Framebuffer profile string timers *timers frameStart time.Time zopsTimer, stencilTimer, coverTimer, cleanupTimer *timer drawOps drawOps - ctx Backend + ctx backend.Device renderer *renderer } type renderer struct { - ctx Backend + ctx backend.Device blitter *blitter pather *pather packer packer @@ -207,14 +208,14 @@ type resource interface { type texture struct { src *image.RGBA - tex Texture + tex backend.Texture } type blitter struct { - ctx Backend + ctx backend.Device viewport image.Point prog [2]*program - layout InputLayout + layout backend.InputLayout colUniforms struct { vert struct { blitUniforms @@ -230,16 +231,16 @@ type blitter struct { _ [8]byte // Padding to a multiple of 16. } } - quadVerts Buffer + quadVerts backend.Buffer } type uniformBuffer struct { - buf Buffer + buf backend.Buffer ptr []byte } type program struct { - prog Program + prog backend.Program vertUniforms *uniformBuffer fragUniforms *uniformBuffer } @@ -275,7 +276,7 @@ const ( attribUV = 1 ) -func New(ctx Backend) (*GPU, error) { +func New(ctx backend.Device) (*GPU, error) { defFBO := ctx.CurrentFramebuffer() g := &GPU{ defFBO: defFBO, @@ -288,7 +289,7 @@ func New(ctx Backend) (*GPU, error) { return g, nil } -func (g *GPU) init(ctx Backend) error { +func (g *GPU) init(ctx backend.Device) error { g.ctx = ctx g.renderer = newRenderer(ctx) return nil @@ -309,7 +310,7 @@ func (g *GPU) Collect(viewport image.Point, frameOps *op.Ops) { g.drawOps.reset(g.cache, viewport) g.drawOps.collect(g.cache, frameOps, viewport) g.frameStart = time.Now() - if g.drawOps.profile && g.timers == nil && g.ctx.Caps().Features.Has(FeatureTimers) { + if g.drawOps.profile && g.timers == nil && g.ctx.Caps().Features.Has(backend.FeatureTimers) { g.timers = newTimers(g.ctx) g.zopsTimer = g.timers.newTimer() g.stencilTimer = g.timers.newTimer() @@ -336,10 +337,10 @@ func (g *GPU) BeginFrame() { g.zopsTimer.begin() } g.ctx.BindFramebuffer(g.defFBO) - g.ctx.DepthFunc(DepthFuncGreater) + g.ctx.DepthFunc(backend.DepthFuncGreater) g.ctx.ClearColor(g.drawOps.clearColor[0], g.drawOps.clearColor[1], g.drawOps.clearColor[2], 1.0) g.ctx.ClearDepth(0.0) - g.ctx.Clear(BufferAttachmentColor | BufferAttachmentDepth) + g.ctx.Clear(backend.BufferAttachmentColor | backend.BufferAttachmentDepth) g.ctx.Viewport(0, 0, viewport.X, viewport.Y) g.renderer.drawZOps(g.drawOps.zimageOps) g.zopsTimer.end() @@ -379,11 +380,11 @@ func (g *GPU) Profile() string { return g.profile } -func (r *renderer) texHandle(t *texture) Texture { +func (r *renderer) texHandle(t *texture) backend.Texture { if t.tex != nil { return t.tex } - tex, err := r.ctx.NewTexture(TextureFormatSRGB, t.src.Bounds().Dx(), t.src.Bounds().Dy(), FilterLinear, FilterLinear, BufferBindingTexture) + tex, err := r.ctx.NewTexture(backend.TextureFormatSRGB, t.src.Bounds().Dx(), t.src.Bounds().Dy(), backend.FilterLinear, backend.FilterLinear, backend.BufferBindingTexture) if err != nil { panic(err) } @@ -398,7 +399,7 @@ func (t *texture) release() { } } -func newRenderer(ctx Backend) *renderer { +func newRenderer(ctx backend.Device) *renderer { r := &renderer{ ctx: ctx, blitter: newBlitter(ctx), @@ -414,8 +415,8 @@ func (r *renderer) release() { r.blitter.release() } -func newBlitter(ctx Backend) *blitter { - quadVerts, err := ctx.NewImmutableBuffer(BufferBindingVertices, +func newBlitter(ctx backend.Device) *blitter { + quadVerts, err := ctx.NewImmutableBuffer(backend.BufferBindingVertices, gunsafe.BytesView([]float32{ -1, +1, 0, 0, +1, +1, 1, 0, @@ -448,7 +449,7 @@ func (b *blitter) release() { b.layout.Release() } -func createColorPrograms(b Backend, vsSrc ShaderSources, fsSrc [2]ShaderSources, vertUniforms, fragUniforms [2]interface{}) ([2]*program, InputLayout, error) { +func createColorPrograms(b backend.Device, vsSrc backend.ShaderSources, fsSrc [2]backend.ShaderSources, vertUniforms, fragUniforms [2]interface{}) ([2]*program, backend.InputLayout, error) { var progs [2]*program prog, err := b.NewProgram(vsSrc, fsSrc[materialTexture]) if err != nil { @@ -479,9 +480,9 @@ func createColorPrograms(b Backend, vsSrc ShaderSources, fsSrc [2]ShaderSources, prog.SetFragmentUniforms(fragBuffer.buf) } progs[materialColor] = newProgram(prog, vertBuffer, fragBuffer) - layout, err := b.NewInputLayout(vsSrc, []InputDesc{ - {Type: DataTypeFloat, Size: 2, Offset: 0}, - {Type: DataTypeFloat, Size: 2, Offset: 4 * 2}, + layout, err := b.NewInputLayout(vsSrc, []backend.InputDesc{ + {Type: backend.DataTypeFloat, Size: 2, Offset: 0}, + {Type: backend.DataTypeFloat, Size: 2, Offset: 4 * 2}, }) if err != nil { progs[materialTexture].Release() @@ -502,7 +503,7 @@ func (r *renderer) stencilClips(pathCache *opCache, ops []*pathOp) { fbo = p.place.Idx f := r.pather.stenciler.cover(fbo) r.ctx.BindFramebuffer(f.fbo) - r.ctx.Clear(BufferAttachmentColor) + r.ctx.Clear(backend.BufferAttachmentColor) } data, _ := pathCache.get(p.pathKey) r.pather.stencilPath(p.clip, p.off, p.place.Pos, data.(*pathData)) @@ -525,7 +526,7 @@ func (r *renderer) intersect(ops []imageOp) { fbo = img.place.Idx f := r.pather.stenciler.intersections.fbos[fbo] r.ctx.BindFramebuffer(f.fbo) - r.ctx.Clear(BufferAttachmentColor) + r.ctx.Clear(backend.BufferAttachmentColor) } r.ctx.Viewport(img.place.Pos.X, img.place.Pos.Y, img.clip.Dx(), img.clip.Dy()) r.intersectPath(img.path, img.clip) @@ -550,7 +551,7 @@ func (r *renderer) intersectPath(p *pathOp, clip image.Rectangle) { r.pather.stenciler.iprog.uniforms.vert.uvScale = [2]float32{coverScale.X, coverScale.Y} r.pather.stenciler.iprog.uniforms.vert.uvOffset = [2]float32{coverOff.X, coverOff.Y} r.pather.stenciler.iprog.prog.UploadUniforms() - r.ctx.DrawArrays(DrawModeTriangleStrip, 0, 4) + r.ctx.DrawArrays(backend.DrawModeTriangleStrip, 0, 4) } func (r *renderer) packIntersections(ops []imageOp) { @@ -842,10 +843,10 @@ func (r *renderer) drawZOps(ops []imageOp) { func (r *renderer) drawOps(ops []imageOp) { r.ctx.SetDepthTest(true) r.ctx.DepthMask(false) - r.ctx.BlendFunc(BlendFactorOne, BlendFactorOneMinusSrcAlpha) + r.ctx.BlendFunc(backend.BlendFactorOne, backend.BlendFactorOneMinusSrcAlpha) r.ctx.BindVertexBuffer(r.blitter.quadVerts, 4*4, 0) r.ctx.BindInputLayout(r.pather.coverer.layout) - var coverTex Texture + var coverTex backend.Texture for _, img := range ops { m := img.material switch m.material { @@ -912,18 +913,18 @@ func (b *blitter) blit(z float32, mat materialType, col [4]float32, scale, off, uniforms.scale = [2]float32{scale.X, scale.Y} uniforms.offset = [2]float32{off.X, off.Y} p.UploadUniforms() - b.ctx.DrawArrays(DrawModeTriangleStrip, 0, 4) + b.ctx.DrawArrays(backend.DrawModeTriangleStrip, 0, 4) } // newUniformBuffer creates a new GPU uniform buffer backed by the // structure uniformBlock points to. -func newUniformBuffer(b Backend, uniformBlock interface{}) *uniformBuffer { +func newUniformBuffer(b backend.Device, uniformBlock interface{}) *uniformBuffer { ref := reflect.ValueOf(uniformBlock) // Determine the size of the uniforms structure, *uniforms. size := ref.Elem().Type().Size() // Map the uniforms structure as a byte slice. ptr := (*[1 << 30]byte)(unsafe.Pointer(ref.Pointer()))[:size:size] - ubuf, err := b.NewBuffer(BufferBindingUniforms, len(ptr)) + ubuf, err := b.NewBuffer(backend.BufferBindingUniforms, len(ptr)) if err != nil { panic(err) } @@ -939,7 +940,7 @@ func (u *uniformBuffer) Release() { u.buf = nil } -func newProgram(prog Program, vertUniforms, fragUniforms *uniformBuffer) *program { +func newProgram(prog backend.Program, vertUniforms, fragUniforms *uniformBuffer) *program { if vertUniforms != nil { prog.SetVertexUniforms(vertUniforms.buf) } diff --git a/gpu/path.go b/gpu/path.go index 120b2326..d305747c 100644 --- a/gpu/path.go +++ b/gpu/path.go @@ -10,12 +10,13 @@ import ( "unsafe" "gioui.org/f32" + "gioui.org/gpu/backend" "gioui.org/internal/path" gunsafe "gioui.org/internal/unsafe" ) type pather struct { - ctx Backend + ctx backend.Device viewport image.Point @@ -24,7 +25,7 @@ type pather struct { } type coverer struct { - ctx Backend + ctx backend.Device prog [2]*program texUniforms struct { vert struct { @@ -41,7 +42,7 @@ type coverer struct { colorUniforms } } - layout InputLayout + layout backend.InputLayout } type coverUniforms struct { @@ -56,7 +57,7 @@ type coverUniforms struct { } type stenciler struct { - ctx Backend + ctx backend.Device prog struct { prog *program uniforms struct { @@ -67,7 +68,7 @@ type stenciler struct { _ [8]byte // Padding to multiple of 16. } } - layout InputLayout + layout backend.InputLayout } iprog struct { prog *program @@ -77,11 +78,11 @@ type stenciler struct { uvOffset [2]float32 } } - layout InputLayout + layout backend.InputLayout } fbos fboSet intersections fboSet - indexBuf Buffer + indexBuf backend.Buffer } type fboSet struct { @@ -90,13 +91,13 @@ type fboSet struct { type stencilFBO struct { size image.Point - fbo Framebuffer - tex Texture + fbo backend.Framebuffer + tex backend.Texture } type pathData struct { ncurves int - data Buffer + data backend.Buffer } const ( @@ -112,7 +113,7 @@ const ( attribPathTo = 4 ) -func newPather(ctx Backend) *pather { +func newPather(ctx backend.Device) *pather { return &pather{ ctx: ctx, stenciler: newStenciler(ctx), @@ -120,7 +121,7 @@ func newPather(ctx Backend) *pather { } } -func newCoverer(ctx Backend) *coverer { +func newCoverer(ctx backend.Device) *coverer { c := &coverer{ ctx: ctx, } @@ -136,7 +137,7 @@ func newCoverer(ctx Backend) *coverer { return c } -func newStenciler(ctx Backend) *stenciler { +func newStenciler(ctx backend.Device) *stenciler { // Allocate a suitably large index buffer for drawing paths. indices := make([]uint16, pathBatchSize*6) for i := 0; i < pathBatchSize; i++ { @@ -148,23 +149,23 @@ func newStenciler(ctx Backend) *stenciler { indices[i*6+4] = i*4 + 1 indices[i*6+5] = i*4 + 3 } - indexBuf, err := ctx.NewImmutableBuffer(BufferBindingIndices, gunsafe.BytesView(indices)) + indexBuf, err := ctx.NewImmutableBuffer(backend.BufferBindingIndices, gunsafe.BytesView(indices)) if err != nil { panic(err) } - progLayout, err := ctx.NewInputLayout(shader_stencil_vert, []InputDesc{ - {Type: DataTypeShort, Size: 2, Offset: int(unsafe.Offsetof((*(*path.Vertex)(nil)).CornerX))}, - {Type: DataTypeFloat, Size: 1, Offset: int(unsafe.Offsetof((*(*path.Vertex)(nil)).MaxY))}, - {Type: DataTypeFloat, Size: 2, Offset: int(unsafe.Offsetof((*(*path.Vertex)(nil)).FromX))}, - {Type: DataTypeFloat, Size: 2, Offset: int(unsafe.Offsetof((*(*path.Vertex)(nil)).CtrlX))}, - {Type: DataTypeFloat, Size: 2, Offset: int(unsafe.Offsetof((*(*path.Vertex)(nil)).ToX))}, + progLayout, err := ctx.NewInputLayout(shader_stencil_vert, []backend.InputDesc{ + {Type: backend.DataTypeShort, Size: 2, Offset: int(unsafe.Offsetof((*(*path.Vertex)(nil)).CornerX))}, + {Type: backend.DataTypeFloat, Size: 1, Offset: int(unsafe.Offsetof((*(*path.Vertex)(nil)).MaxY))}, + {Type: backend.DataTypeFloat, Size: 2, Offset: int(unsafe.Offsetof((*(*path.Vertex)(nil)).FromX))}, + {Type: backend.DataTypeFloat, Size: 2, Offset: int(unsafe.Offsetof((*(*path.Vertex)(nil)).CtrlX))}, + {Type: backend.DataTypeFloat, Size: 2, Offset: int(unsafe.Offsetof((*(*path.Vertex)(nil)).ToX))}, }) if err != nil { panic(err) } - iprogLayout, err := ctx.NewInputLayout(shader_intersect_vert, []InputDesc{ - {Type: DataTypeFloat, Size: 2, Offset: 0}, - {Type: DataTypeFloat, Size: 2, Offset: 4 * 2}, + iprogLayout, err := ctx.NewInputLayout(shader_intersect_vert, []backend.InputDesc{ + {Type: backend.DataTypeFloat, Size: 2, Offset: 0}, + {Type: backend.DataTypeFloat, Size: 2, Offset: 4 * 2}, }) if err != nil { panic(err) @@ -190,7 +191,7 @@ func newStenciler(ctx Backend) *stenciler { return st } -func (s *fboSet) resize(ctx Backend, sizes []image.Point) { +func (s *fboSet) resize(ctx backend.Device, sizes []image.Point) { // Add fbos. for i := len(s.fbos); i < len(sizes); i++ { s.fbos = append(s.fbos, stencilFBO{}) @@ -208,8 +209,8 @@ func (s *fboSet) resize(ctx Backend, sizes []image.Point) { f.fbo.Release() f.tex.Release() } - tex, err := ctx.NewTexture(TextureFormatFloat, sz.X, sz.Y, FilterNearest, FilterNearest, - BufferBindingTexture|BufferBindingFramebuffer) + tex, err := ctx.NewTexture(backend.TextureFormatFloat, sz.X, sz.Y, backend.FilterNearest, backend.FilterNearest, + backend.BufferBindingTexture|backend.BufferBindingFramebuffer) fbo, err := ctx.NewFramebuffer(tex, 0) if err != nil { panic(err) @@ -223,13 +224,13 @@ func (s *fboSet) resize(ctx Backend, sizes []image.Point) { s.delete(ctx, len(sizes)) } -func (s *fboSet) invalidate(ctx Backend) { +func (s *fboSet) invalidate(ctx backend.Device) { for _, f := range s.fbos { f.fbo.Invalidate() } } -func (s *fboSet) delete(ctx Backend, idx int) { +func (s *fboSet) delete(ctx backend.Device, idx int) { for i := idx; i < len(s.fbos); i++ { f := s.fbos[i] f.fbo.Release() @@ -259,8 +260,8 @@ func (c *coverer) release() { c.layout.Release() } -func buildPath(ctx Backend, p []byte) *pathData { - buf, err := ctx.NewImmutableBuffer(BufferBindingVertices, p) +func buildPath(ctx backend.Device, p []byte) *pathData { + buf, err := ctx.NewImmutableBuffer(backend.BufferBindingVertices, p) if err != nil { panic(err) } @@ -283,7 +284,7 @@ func (p *pather) stencilPath(bounds image.Rectangle, offset f32.Point, uv image. } func (s *stenciler) beginIntersect(sizes []image.Point) { - s.ctx.BlendFunc(BlendFactorDstColor, BlendFactorZero) + s.ctx.BlendFunc(backend.BlendFactorDstColor, backend.BlendFactorZero) // 8 bit coverage is enough, but OpenGL ES only supports single channel // floating point formats. Replace with GL_RGB+GL_UNSIGNED_BYTE if // no floating point support is available. @@ -302,7 +303,7 @@ func (s *stenciler) cover(idx int) stencilFBO { } func (s *stenciler) begin(sizes []image.Point) { - s.ctx.BlendFunc(BlendFactorOne, BlendFactorOne) + s.ctx.BlendFunc(backend.BlendFactorOne, backend.BlendFactorOne) s.fbos.resize(s.ctx, sizes) s.ctx.ClearColor(0.0, 0.0, 0.0, 0.0) s.ctx.BindProgram(s.prog.prog.prog) @@ -330,7 +331,7 @@ func (s *stenciler) stencilPath(bounds image.Rectangle, offset f32.Point, uv ima } off := path.VertStride * start * 4 s.ctx.BindVertexBuffer(data.data, path.VertStride, off) - s.ctx.DrawElements(DrawModeTriangles, 0, batch*6) + s.ctx.DrawElements(backend.DrawModeTriangles, 0, batch*6) start += batch } } @@ -358,5 +359,5 @@ func (c *coverer) cover(z float32, mat materialType, col [4]float32, scale, off, uniforms.uvCoverScale = [2]float32{coverScale.X, coverScale.Y} uniforms.uvCoverOffset = [2]float32{coverOff.X, coverOff.Y} p.UploadUniforms() - c.ctx.DrawArrays(DrawModeTriangleStrip, 0, 4) + c.ctx.DrawArrays(backend.DrawModeTriangleStrip, 0, 4) } diff --git a/gpu/shaders.go b/gpu/shaders.go index e6053082..4573e69e 100644 --- a/gpu/shaders.go +++ b/gpu/shaders.go @@ -2,10 +2,12 @@ package gpu +import "gioui.org/gpu/backend" + var ( - shader_blit_frag = [...]ShaderSources{ - ShaderSources{ - Uniforms: []UniformLocation{ + shader_blit_frag = [...]backend.ShaderSources{ + backend.ShaderSources{ + Uniforms: []backend.UniformLocation{ {Name: "_12._color", Type: 0, Size: 4, Offset: 0}, }, UniformSize: 16, @@ -47,8 +49,8 @@ var ( */ HLSL: []byte(nil), }, - ShaderSources{ - Textures: []TextureBinding{ + backend.ShaderSources{ + Textures: []backend.TextureBinding{ {Name: "tex", Binding: 0}, }, GLES2: "#version 100\nprecision mediump float;\nprecision highp int;\n\nuniform mediump sampler2D tex;\n\nvarying vec2 vUV;\n\nvoid main()\n{\n gl_FragData[0] = texture2D(tex, vUV);\n}\n\n", @@ -87,12 +89,12 @@ var ( HLSL: []byte(nil), }, } - shader_blit_vert = ShaderSources{ - Inputs: []InputLocation{ + shader_blit_vert = backend.ShaderSources{ + Inputs: []backend.InputLocation{ {Name: "pos", Location: 0, Semantic: "POSITION", SemanticIndex: 0, Type: 0, Size: 2}, {Name: "uv", Location: 1, Semantic: "NORMAL", SemanticIndex: 0, Type: 0, Size: 2}, }, - Uniforms: []UniformLocation{ + Uniforms: []backend.UniformLocation{ {Name: "_15.z", Type: 0, Size: 1, Offset: 0}, {Name: "_15.scale", Type: 0, Size: 2, Offset: 8}, {Name: "_15.offset", Type: 0, Size: 2, Offset: 16}, @@ -152,13 +154,13 @@ var ( */ HLSL: []byte(nil), } - shader_cover_frag = [...]ShaderSources{ - ShaderSources{ - Uniforms: []UniformLocation{ + shader_cover_frag = [...]backend.ShaderSources{ + backend.ShaderSources{ + Uniforms: []backend.UniformLocation{ {Name: "_12._color", Type: 0, Size: 4, Offset: 0}, }, UniformSize: 16, - Textures: []TextureBinding{ + Textures: []backend.TextureBinding{ {Name: "cover", Binding: 1}, }, GLES2: "#version 100\nprecision mediump float;\nprecision highp int;\n\nstruct Color\n{\n vec4 _color;\n};\n\nuniform Color _12;\n\nuniform mediump sampler2D cover;\n\nvarying highp vec2 vCoverUV;\nvarying vec2 vUV;\n\nvoid main()\n{\n gl_FragData[0] = _12._color;\n float cover_1 = abs(texture2D(cover, vCoverUV).x);\n gl_FragData[0] *= cover_1;\n}\n\n", @@ -206,8 +208,8 @@ var ( */ HLSL: []byte(nil), }, - ShaderSources{ - Textures: []TextureBinding{ + backend.ShaderSources{ + Textures: []backend.TextureBinding{ {Name: "tex", Binding: 0}, {Name: "cover", Binding: 1}, }, @@ -254,12 +256,12 @@ var ( HLSL: []byte(nil), }, } - shader_cover_vert = ShaderSources{ - Inputs: []InputLocation{ + shader_cover_vert = backend.ShaderSources{ + Inputs: []backend.InputLocation{ {Name: "pos", Location: 0, Semantic: "POSITION", SemanticIndex: 0, Type: 0, Size: 2}, {Name: "uv", Location: 1, Semantic: "NORMAL", SemanticIndex: 0, Type: 0, Size: 2}, }, - Uniforms: []UniformLocation{ + Uniforms: []backend.UniformLocation{ {Name: "_19.z", Type: 0, Size: 1, Offset: 0}, {Name: "_19.scale", Type: 0, Size: 2, Offset: 8}, {Name: "_19.offset", Type: 0, Size: 2, Offset: 16}, @@ -324,8 +326,8 @@ var ( */ HLSL: []byte(nil), } - shader_intersect_frag = ShaderSources{ - Textures: []TextureBinding{ + shader_intersect_frag = backend.ShaderSources{ + Textures: []backend.TextureBinding{ {Name: "cover", Binding: 0}, }, GLES2: "#version 100\nprecision mediump float;\nprecision highp int;\n\nuniform mediump sampler2D cover;\n\nvarying highp vec2 vUV;\n\nvoid main()\n{\n float cover_1 = abs(texture2D(cover, vUV).x);\n gl_FragData[0].x = cover_1;\n}\n\n", @@ -364,12 +366,12 @@ var ( */ HLSL: []byte(nil), } - shader_intersect_vert = ShaderSources{ - Inputs: []InputLocation{ + shader_intersect_vert = backend.ShaderSources{ + Inputs: []backend.InputLocation{ {Name: "pos", Location: 0, Semantic: "POSITION", SemanticIndex: 0, Type: 0, Size: 2}, {Name: "uv", Location: 1, Semantic: "NORMAL", SemanticIndex: 0, Type: 0, Size: 2}, }, - Uniforms: []UniformLocation{ + Uniforms: []backend.UniformLocation{ {Name: "_40.scale", Type: 0, Size: 2, Offset: 0}, {Name: "_40.offset", Type: 0, Size: 2, Offset: 8}, }, @@ -422,7 +424,7 @@ var ( */ HLSL: []byte(nil), } - shader_stencil_frag = ShaderSources{ + shader_stencil_frag = backend.ShaderSources{ GLES2: "#version 100\nprecision mediump float;\nprecision highp int;\n\nvarying vec2 vTo;\nvarying vec2 vFrom;\nvarying vec2 vCtrl;\n\nvoid main()\n{\n float dx = vTo.x - vFrom.x;\n bool increasing = vTo.x >= vFrom.x;\n bvec2 _35 = bvec2(increasing);\n vec2 left = vec2(_35.x ? vFrom.x : vTo.x, _35.y ? vFrom.y : vTo.y);\n bvec2 _41 = bvec2(increasing);\n vec2 right = vec2(_41.x ? vTo.x : vFrom.x, _41.y ? vTo.y : vFrom.y);\n vec2 extent = clamp(vec2(vFrom.x, vTo.x), vec2(-0.5), vec2(0.5));\n float midx = mix(extent.x, extent.y, 0.5);\n float x0 = midx - left.x;\n vec2 p1 = vCtrl - left;\n vec2 v = right - vCtrl;\n float t = x0 / (p1.x + sqrt((p1.x * p1.x) + ((v.x - p1.x) * x0)));\n float y = mix(mix(left.y, vCtrl.y, t), mix(vCtrl.y, right.y, t), t);\n vec2 d_half = mix(p1, v, vec2(t));\n float dy = d_half.y / d_half.x;\n float width = extent.y - extent.x;\n dy = abs(dy * width);\n vec4 sides = vec4((dy * 0.5) + y, (dy * (-0.5)) + y, (0.5 - y) / dy, ((-0.5) - y) / dy);\n sides = clamp(sides + vec4(0.5), vec4(0.0), vec4(1.0));\n float area = 0.5 * ((((sides.z - (sides.z * sides.y)) + 1.0) - sides.x) + (sides.x * sides.w));\n area *= width;\n if (width == 0.0)\n {\n area = 0.0;\n }\n gl_FragData[0].x = area;\n}\n\n", /* static float2 vTo; @@ -486,15 +488,15 @@ var ( */ HLSL: []byte(nil), } - shader_stencil_vert = ShaderSources{ - Inputs: []InputLocation{ + shader_stencil_vert = backend.ShaderSources{ + Inputs: []backend.InputLocation{ {Name: "corner", Location: 0, Semantic: "POSITION", SemanticIndex: 0, Type: 0, Size: 2}, {Name: "maxy", Location: 1, Semantic: "NORMAL", SemanticIndex: 0, Type: 0, Size: 1}, {Name: "from", Location: 2, Semantic: "TEXCOORD", SemanticIndex: 0, Type: 0, Size: 2}, {Name: "ctrl", Location: 3, Semantic: "TEXCOORD", SemanticIndex: 1, Type: 0, Size: 2}, {Name: "to", Location: 4, Semantic: "TEXCOORD", SemanticIndex: 2, Type: 0, Size: 2}, }, - Uniforms: []UniformLocation{ + Uniforms: []backend.UniformLocation{ {Name: "_15.scale", Type: 0, Size: 2, Offset: 0}, {Name: "_15.offset", Type: 0, Size: 2, Offset: 8}, {Name: "_15.pathOffset", Type: 0, Size: 2, Offset: 16}, diff --git a/gpu/timer.go b/gpu/timer.go index 246d0c57..a1da9489 100644 --- a/gpu/timer.go +++ b/gpu/timer.go @@ -4,17 +4,19 @@ package gpu import ( "time" + + "gioui.org/gpu/backend" ) type timers struct { - backend Backend + backend backend.Device timers []*timer } type timer struct { Elapsed time.Duration - backend Backend - timer Timer + backend backend.Device + timer backend.Timer state timerState } @@ -26,7 +28,7 @@ const ( timerWaiting ) -func newTimers(b Backend) *timers { +func newTimers(b backend.Device) *timers { return &timers{ backend: b, }