gpu/backend: move backend interface types to a separate package

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2020-02-23 12:46:17 +01:00
parent 50e98d1e13
commit 5cd5d49108
17 changed files with 214 additions and 206 deletions
+17 -16
View File
@@ -9,21 +9,22 @@ import (
"runtime" "runtime"
"gioui.org/gpu" "gioui.org/gpu"
"gioui.org/gpu/backend"
"gioui.org/op" "gioui.org/op"
) )
// Window is a headless window. // Window is a headless window.
type Window struct { type Window struct {
size image.Point size image.Point
ctx backend ctx context
backend gpu.Backend backend backend.Device
gpu *gpu.GPU gpu *gpu.GPU
fboTex gpu.Texture fboTex backend.Texture
fbo gpu.Framebuffer fbo backend.Framebuffer
} }
type backend interface { type context interface {
Backend() (gpu.Backend, error) Backend() (backend.Device, error)
MakeCurrent() error MakeCurrent() error
ReleaseCurrent() ReleaseCurrent()
Release() Release()
@@ -40,27 +41,27 @@ func NewWindow(width, height int) (*Window, error) {
ctx: ctx, ctx: ctx,
} }
err = contextDo(ctx, func() error { err = contextDo(ctx, func() error {
backend, err := ctx.Backend() dev, err := ctx.Backend()
if err != nil { if err != nil {
return err return err
} }
fboTex, err := backend.NewTexture( fboTex, err := dev.NewTexture(
gpu.TextureFormatSRGB, backend.TextureFormatSRGB,
width, height, width, height,
gpu.FilterNearest, gpu.FilterNearest, backend.FilterNearest, backend.FilterNearest,
gpu.BufferBindingFramebuffer, backend.BufferBindingFramebuffer,
) )
if err != nil { if err != nil {
return nil return nil
} }
const depthBits = 16 const depthBits = 16
fbo, err := backend.NewFramebuffer(fboTex, depthBits) fbo, err := dev.NewFramebuffer(fboTex, depthBits)
if err != nil { if err != nil {
fboTex.Release() fboTex.Release()
return err return err
} }
backend.BindFramebuffer(fbo) dev.BindFramebuffer(fbo)
gp, err := gpu.New(backend) gp, err := gpu.New(dev)
if err != nil { if err != nil {
fbo.Release() fbo.Release()
fboTex.Release() fboTex.Release()
@@ -69,7 +70,7 @@ func NewWindow(width, height int) (*Window, error) {
w.fboTex = fboTex w.fboTex = fboTex
w.fbo = fbo w.fbo = fbo
w.gpu = gp w.gpu = gp
w.backend = backend w.backend = dev
return err return err
}) })
if err != nil { if err != nil {
@@ -139,7 +140,7 @@ func (w *Window) Screenshot() (*image.RGBA, error) {
return img, nil return img, nil
} }
func contextDo(ctx backend, f func() error) error { func contextDo(ctx context, f func() error) error {
errCh := make(chan error) errCh := make(chan error)
go func() { go func() {
runtime.LockOSThread() runtime.LockOSThread()
+3 -3
View File
@@ -4,7 +4,7 @@ package headless
import ( import (
"gioui.org/app/internal/glimpl" "gioui.org/app/internal/glimpl"
"gioui.org/gpu" "gioui.org/gpu/backend"
"gioui.org/gpu/gl" "gioui.org/gpu/gl"
) )
@@ -22,7 +22,7 @@ type nsContext struct {
prepared bool prepared bool
} }
func newGLContext() (backend, error) { func newGLContext() (context, error) {
ctx := C.gio_headless_newContext() ctx := C.gio_headless_newContext()
return &nsContext{ctx: ctx, c: new(glimpl.Functions)}, nil return &nsContext{ctx: ctx, c: new(glimpl.Functions)}, nil
} }
@@ -40,7 +40,7 @@ func (c *nsContext) ReleaseCurrent() {
C.gio_headless_clearCurrentContext(c.ctx) 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) return gl.NewBackend(c.c)
} }
+1 -1
View File
@@ -8,6 +8,6 @@ import (
"gioui.org/app/internal/egl" "gioui.org/app/internal/egl"
) )
func newGLContext() (backend, error) { func newGLContext() (context, error) {
return egl.NewContext(egl.EGL_DEFAULT_DISPLAY) return egl.NewContext(egl.EGL_DEFAULT_DISPLAY)
} }
+1 -1
View File
@@ -2,6 +2,6 @@
package headless package headless
func newContext() (backend, error) { func newContext() (context, error) {
return newGLContext() return newGLContext()
} }
+3 -3
View File
@@ -7,7 +7,7 @@ import (
"syscall/js" "syscall/js"
"gioui.org/app/internal/glimpl" "gioui.org/app/internal/glimpl"
"gioui.org/gpu" "gioui.org/gpu/backend"
"gioui.org/gpu/gl" "gioui.org/gpu/gl"
) )
@@ -16,7 +16,7 @@ type jsContext struct {
f *glimpl.Functions f *glimpl.Functions
} }
func newGLContext() (backend, error) { func newGLContext() (context, error) {
version := 2 version := 2
doc := js.Global().Get("document") doc := js.Global().Get("document")
cnv := doc.Call("createElement", "canvas") cnv := doc.Call("createElement", "canvas")
@@ -39,7 +39,7 @@ func newGLContext() (backend, error) {
return c, nil return c, nil
} }
func (c *jsContext) Backend() (gpu.Backend, error) { func (c *jsContext) Backend() (backend.Device, error) {
return gl.NewBackend(c.f) return gl.NewBackend(c.f)
} }
+2 -2
View File
@@ -12,7 +12,7 @@ import (
"gioui.org/app/internal/glimpl" "gioui.org/app/internal/glimpl"
"gioui.org/app/internal/srgb" "gioui.org/app/internal/srgb"
"gioui.org/gpu" "gioui.org/gpu/backend"
"gioui.org/gpu/gl" "gioui.org/gpu/gl"
) )
@@ -121,7 +121,7 @@ func (c *Context) Functions() *glimpl.Functions {
return c.c return c.c
} }
func (c *Context) Backend() (gpu.Backend, error) { func (c *Context) Backend() (backend.Device, error) {
return gl.NewBackend(c.c) return gl.NewBackend(c.c)
} }
+2 -2
View File
@@ -17,7 +17,7 @@ import (
"fmt" "fmt"
"gioui.org/app/internal/glimpl" "gioui.org/app/internal/glimpl"
"gioui.org/gpu" "gioui.org/gpu/backend"
"gioui.org/gpu/gl" "gioui.org/gpu/gl"
) )
@@ -51,7 +51,7 @@ func newContext(w *window) (*context, error) {
return c, nil return c, nil
} }
func (c *context) Backend() (gpu.Backend, error) { func (c *context) Backend() (backend.Device, error) {
return gl.NewBackend(c.c) return gl.NewBackend(c.c)
} }
+2 -2
View File
@@ -8,7 +8,7 @@ import (
"gioui.org/app/internal/glimpl" "gioui.org/app/internal/glimpl"
"gioui.org/app/internal/srgb" "gioui.org/app/internal/srgb"
"gioui.org/gpu" "gioui.org/gpu/backend"
"gioui.org/gpu/gl" "gioui.org/gpu/gl"
) )
@@ -47,7 +47,7 @@ func newContext(w *window) (*context, error) {
return c, nil return c, nil
} }
func (c *context) Backend() (gpu.Backend, error) { func (c *context) Backend() (backend.Device, error) {
return gl.NewBackend(c.f) return gl.NewBackend(c.f)
} }
+2 -2
View File
@@ -6,7 +6,7 @@ package window
import ( import (
"gioui.org/app/internal/glimpl" "gioui.org/app/internal/glimpl"
"gioui.org/gpu" "gioui.org/gpu/backend"
"gioui.org/gpu/gl" "gioui.org/gpu/gl"
) )
@@ -42,7 +42,7 @@ func newContext(w *window) (*context, error) {
return c, nil return c, nil
} }
func (c *context) Backend() (gpu.Backend, error) { func (c *context) Backend() (backend.Device, error) {
return gl.NewBackend(c.c) return gl.NewBackend(c.c)
} }
+2 -2
View File
@@ -9,7 +9,7 @@ import (
"math" "math"
"time" "time"
"gioui.org/gpu" "gioui.org/gpu/backend"
"gioui.org/io/event" "gioui.org/io/event"
"gioui.org/io/system" "gioui.org/io/system"
"gioui.org/unit" "gioui.org/unit"
@@ -32,7 +32,7 @@ type Callbacks interface {
} }
type Context interface { type Context interface {
Backend() (gpu.Backend, error) Backend() (backend.Device, error)
Present() error Present() error
MakeCurrent() error MakeCurrent() error
Release() Release()
+3 -3
View File
@@ -1,16 +1,16 @@
// SPDX-License-Identifier: Unlicense OR MIT // SPDX-License-Identifier: Unlicense OR MIT
package gpu package backend
import ( import (
"image" "image"
"time" "time"
) )
// Backend represents the abstraction of underlying GPU // Device represents the abstraction of underlying GPU
// APIs such as OpenGL, Direct3D useful for rendering Gio // APIs such as OpenGL, Direct3D useful for rendering Gio
// operations. // operations.
type Backend interface { type Device interface {
BeginFrame() BeginFrame()
EndFrame() EndFrame()
Caps() Caps Caps() Caps
+6 -5
View File
@@ -85,6 +85,7 @@ func generate() error {
var out bytes.Buffer var out bytes.Buffer
out.WriteString("// Code generated by build.go. DO NOT EDIT.\n\n") out.WriteString("// Code generated by build.go. DO NOT EDIT.\n\n")
out.WriteString("package gpu\n\n") out.WriteString("package gpu\n\n")
fmt.Fprintf(&out, "import %q\n\n", "gioui.org/gpu/backend")
out.WriteString("var (\n") out.WriteString("var (\n")
@@ -155,12 +156,12 @@ func generate() error {
// only a single version. // only a single version.
multiVariant := variants[0].gles2 != variants[1].gles2 multiVariant := variants[0].gles2 != variants[1].gles2
if multiVariant { if multiVariant {
fmt.Fprintf(&out, "[...]ShaderSources{\n") fmt.Fprintf(&out, "[...]backend.ShaderSources{\n")
} }
for _, src := range variants { for _, src := range variants {
fmt.Fprintf(&out, "ShaderSources{\n") fmt.Fprintf(&out, "backend.ShaderSources{\n")
if len(src.inputs) > 0 { if len(src.inputs) > 0 {
fmt.Fprintf(&out, "Inputs: []InputLocation{\n") fmt.Fprintf(&out, "Inputs: []backend.InputLocation{\n")
for _, inp := range src.inputs { for _, inp := range src.inputs {
fmt.Fprintf(&out, "{Name: %q, Location: %d, Semantic: %q, ", inp.Name, inp.Location, inp.Semantic) 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) 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") fmt.Fprintf(&out, "},\n")
} }
if len(src.uniforms) > 0 { if len(src.uniforms) > 0 {
fmt.Fprintf(&out, "Uniforms: []UniformLocation{\n") fmt.Fprintf(&out, "Uniforms: []backend.UniformLocation{\n")
for _, u := range src.uniforms { 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) 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) fmt.Fprintf(&out, "UniformSize: %d,\n", src.uniformSize)
} }
if len(src.textures) > 0 { if len(src.textures) > 0 {
fmt.Fprintf(&out, "Textures: []TextureBinding{\n") fmt.Fprintf(&out, "Textures: []backend.TextureBinding{\n")
for _, t := range src.textures { for _, t := range src.textures {
fmt.Fprintf(&out, "{Name: %q, Binding: %d},\n", t.Name, t.Binding) fmt.Fprintf(&out, "{Name: %q, Binding: %d},\n", t.Name, t.Binding)
} }
+68 -68
View File
@@ -10,16 +10,16 @@ import (
"time" "time"
"unsafe" "unsafe"
"gioui.org/gpu" "gioui.org/gpu/backend"
) )
// Backend implements gpu.Backend. // Backend implements backend.Device.
type Backend struct { type Backend struct {
funcs Functions funcs Functions
state glstate state glstate
feats gpu.Caps feats backend.Caps
// floatTriple holds the settings for floating point // floatTriple holds the settings for floating point
// textures. // textures.
floatTriple textureTriple floatTriple textureTriple
@@ -68,7 +68,7 @@ type gpuFramebuffer struct {
type gpuBuffer struct { type gpuBuffer struct {
backend *Backend backend *Backend
obj Buffer obj Buffer
typ gpu.BufferBinding typ backend.BufferBinding
size int size int
immutable bool immutable bool
version int version int
@@ -94,14 +94,14 @@ type uniformsTracker struct {
type uniformLocation struct { type uniformLocation struct {
uniform Uniform uniform Uniform
offset int offset int
typ gpu.DataType typ backend.DataType
size int size int
} }
type gpuInputLayout struct { type gpuInputLayout struct {
backend *Backend backend *Backend
inputs []gpu.InputLocation inputs []backend.InputLocation
layout []gpu.InputDesc layout []backend.InputDesc
} }
// textureTriple holds the type settings for // textureTriple holds the type settings for
@@ -134,7 +134,7 @@ func NewBackend(f Functions) (*Backend, error) {
srgbaTriple: srgbaTriple, srgbaTriple: srgbaTriple,
} }
if hasExtension(exts, "GL_EXT_disjoint_timer_query_webgl2") || hasExtension(exts, "GL_EXT_disjoint_timer_query") { 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) b.feats.MaxTextureSize = f.GetInteger(MAX_TEXTURE_SIZE)
return b, nil return b, nil
@@ -149,11 +149,11 @@ func (b *Backend) EndFrame() {
b.funcs.ActiveTexture(TEXTURE0) b.funcs.ActiveTexture(TEXTURE0)
} }
func (b *Backend) Caps() gpu.Caps { func (b *Backend) Caps() backend.Caps {
return b.feats return b.feats
} }
func (b *Backend) NewTimer() gpu.Timer { func (b *Backend) NewTimer() backend.Timer {
return &gpuTimer{ return &gpuTimer{
funcs: b.funcs, funcs: b.funcs,
obj: b.funcs.CreateQuery(), obj: b.funcs.CreateQuery(),
@@ -164,7 +164,7 @@ func (b *Backend) IsTimeContinuous() bool {
return b.funcs.GetInteger(GPU_DISJOINT_EXT) == FALSE 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) glErr(b.funcs)
gltex := tex.(*gpuTexture) gltex := tex.(*gpuTexture)
fb := b.funcs.CreateFramebuffer() fb := b.funcs.CreateFramebuffer()
@@ -200,18 +200,18 @@ func (b *Backend) NewFramebuffer(tex gpu.Texture, depthBits int) (gpu.Framebuffe
return fbo, nil return fbo, nil
} }
func (b *Backend) CurrentFramebuffer() gpu.Framebuffer { func (b *Backend) CurrentFramebuffer() backend.Framebuffer {
fboID := Framebuffer(b.funcs.GetBinding(FRAMEBUFFER_BINDING)) fboID := Framebuffer(b.funcs.GetBinding(FRAMEBUFFER_BINDING))
return &gpuFramebuffer{backend: b, obj: fboID, foreign: true} 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) glErr(b.funcs)
tex := &gpuTexture{backend: b, obj: b.funcs.CreateTexture(), width: width, height: height} tex := &gpuTexture{backend: b, obj: b.funcs.CreateTexture(), width: width, height: height}
switch format { switch format {
case gpu.TextureFormatFloat: case backend.TextureFormatFloat:
tex.triple = b.floatTriple tex.triple = b.floatTriple
case gpu.TextureFormatSRGB: case backend.TextureFormatSRGB:
tex.triple = b.srgbaTriple tex.triple = b.srgbaTriple
default: default:
return nil, errors.New("unsupported texture format") 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 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) glErr(b.funcs)
buf := &gpuBuffer{backend: b, typ: typ, size: size} buf := &gpuBuffer{backend: b, typ: typ, size: size}
if typ&gpu.BufferBindingUniforms != 0 { if typ&backend.BufferBindingUniforms != 0 {
if typ != gpu.BufferBindingUniforms { if typ != backend.BufferBindingUniforms {
return nil, errors.New("uniforms buffers cannot be bound as anything else") return nil, errors.New("uniforms buffers cannot be bound as anything else")
} }
// GLES 2 doesn't support uniform buffers. // GLES 2 doesn't support uniform buffers.
buf.data = make([]byte, size) buf.data = make([]byte, size)
} }
if typ&^gpu.BufferBindingUniforms != 0 { if typ&^backend.BufferBindingUniforms != 0 {
buf.obj = b.funcs.CreateBuffer() buf.obj = b.funcs.CreateBuffer()
if err := glErr(b.funcs); err != nil { if err := glErr(b.funcs); err != nil {
buf.Release() buf.Release()
@@ -249,7 +249,7 @@ func (b *Backend) NewBuffer(typ gpu.BufferBinding, size int) (gpu.Buffer, error)
return buf, nil 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) glErr(b.funcs)
obj := b.funcs.CreateBuffer() obj := b.funcs.CreateBuffer()
buf := &gpuBuffer{backend: b, obj: obj, typ: typ, size: len(data)} 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)) b.funcs.BlendFunc(toGLBlendFactor(sfactor), toGLBlendFactor(dfactor))
} }
func toGLBlendFactor(f gpu.BlendFactor) Enum { func toGLBlendFactor(f backend.BlendFactor) Enum {
switch f { switch f {
case gpu.BlendFactorOne: case backend.BlendFactorOne:
return ONE return ONE
case gpu.BlendFactorOneMinusSrcAlpha: case backend.BlendFactorOneMinusSrcAlpha:
return ONE_MINUS_SRC_ALPHA return ONE_MINUS_SRC_ALPHA
case gpu.BlendFactorZero: case backend.BlendFactorZero:
return ZERO return ZERO
case gpu.BlendFactorDstColor: case backend.BlendFactorDstColor:
return DST_COLOR return DST_COLOR
default: default:
panic("unsupported blend factor") 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() b.prepareDraw()
// off is in 16-bit indices, but DrawElements take a byte offset. // off is in 16-bit indices, but DrawElements take a byte offset.
byteOff := off * 2 byteOff := off * 2
b.funcs.DrawElements(toGLDrawMode(mode), count, UNSIGNED_SHORT, byteOff) 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.prepareDraw()
b.funcs.DrawArrays(toGLDrawMode(mode), off, count) 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 { switch mode {
case gpu.DrawModeTriangleStrip: case backend.DrawModeTriangleStrip:
return TRIANGLE_STRIP return TRIANGLE_STRIP
case gpu.DrawModeTriangles: case backend.DrawModeTriangles:
return TRIANGLES return TRIANGLES
default: default:
panic("unsupported draw mode") panic("unsupported draw mode")
@@ -369,12 +369,12 @@ func (b *Backend) Viewport(x, y, width, height int) {
b.funcs.Viewport(x, y, width, height) b.funcs.Viewport(x, y, width, height)
} }
func (b *Backend) Clear(attachments gpu.BufferAttachments) { func (b *Backend) Clear(attachments backend.BufferAttachments) {
var mask Enum var mask Enum
if attachments&gpu.BufferAttachmentColor != 0 { if attachments&backend.BufferAttachmentColor != 0 {
mask |= COLOR_BUFFER_BIT mask |= COLOR_BUFFER_BIT
} }
if attachments&gpu.BufferAttachmentDepth != 0 { if attachments&backend.BufferAttachmentDepth != 0 {
mask |= DEPTH_BUFFER_BIT mask |= DEPTH_BUFFER_BIT
} }
b.funcs.Clear(mask) b.funcs.Clear(mask)
@@ -388,10 +388,10 @@ func (b *Backend) ClearColor(colR, colG, colB, colA float32) {
b.funcs.ClearColor(colR, colG, colB, colA) b.funcs.ClearColor(colR, colG, colB, colA)
} }
func (b *Backend) DepthFunc(f gpu.DepthFunc) { func (b *Backend) DepthFunc(f backend.DepthFunc) {
var glfunc Enum var glfunc Enum
switch f { switch f {
case gpu.DepthFuncGreater: case backend.DepthFuncGreater:
glfunc = GREATER glfunc = GREATER
default: default:
panic("unsupported depth func") panic("unsupported depth func")
@@ -399,7 +399,7 @@ func (b *Backend) DepthFunc(f gpu.DepthFunc) {
b.funcs.DepthFunc(glfunc) 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) { if len(vs.Inputs) != len(layout) {
return nil, fmt.Errorf("NewInputLayout: got %d inputs, expected %d", len(layout), len(vs.Inputs)) 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 }, 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)) attr := make([]string, len(vssrc.Inputs))
for _, inp := range vssrc.Inputs { for _, inp := range vssrc.Inputs {
attr[inp.Location] = inp.Name attr[inp.Location] = inp.Name
@@ -448,16 +448,16 @@ func (b *Backend) NewProgram(vssrc, fssrc gpu.ShaderSources) (gpu.Program, error
return gpuProg, nil 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) u := GetUniformLocation(funcs, p, loc.Name)
return uniformLocation{uniform: u, offset: loc.Offset, typ: loc.Type, size: loc.Size} 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) p.vertUniforms.setBuffer(buffer)
} }
func (p *gpuProgram) SetFragmentUniforms(buffer gpu.Buffer) { func (p *gpuProgram) SetFragmentUniforms(buffer backend.Buffer) {
p.fragUniforms.setBuffer(buffer) p.fragUniforms.setBuffer(buffer)
} }
@@ -466,7 +466,7 @@ func (p *gpuProgram) updateUniforms() {
p.fragUniforms.update(p.backend.funcs) p.fragUniforms.update(p.backend.funcs)
} }
func (b *Backend) BindProgram(prog gpu.Program) { func (b *Backend) BindProgram(prog backend.Program) {
p := prog.(*gpuProgram) p := prog.(*gpuProgram)
b.useProgram(p) b.useProgram(p)
b.enableVertexArrays(p.nattr) b.enableVertexArrays(p.nattr)
@@ -476,7 +476,7 @@ func (p *gpuProgram) Release() {
p.backend.funcs.DeleteProgram(p.obj) 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)) u.locs = make([]uniformLocation, len(uniforms))
for i, uniform := range uniforms { for i, uniform := range uniforms {
u.locs[i] = lookupUniform(funcs, p, uniform) 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 u.size = uniformSize
} }
func (u *uniformsTracker) setBuffer(buffer gpu.Buffer) { func (u *uniformsTracker) setBuffer(buffer backend.Buffer) {
buf := buffer.(*gpuBuffer) buf := buffer.(*gpuBuffer)
if buf.typ&gpu.BufferBindingUniforms == 0 { if buf.typ&backend.BufferBindingUniforms == 0 {
panic("not a uniform buffer") panic("not a uniform buffer")
} }
if buf.size < u.size { if buf.size < u.size {
@@ -507,19 +507,19 @@ func (p *uniformsTracker) update(funcs Functions) {
for _, u := range p.locs { for _, u := range p.locs {
data := data[u.offset:] data := data[u.offset:]
switch { switch {
case u.typ == gpu.DataTypeFloat && u.size == 1: case u.typ == backend.DataTypeFloat && u.size == 1:
data := data[:4] data := data[:4]
v := *(*[1]float32)(unsafe.Pointer(&data[0])) v := *(*[1]float32)(unsafe.Pointer(&data[0]))
funcs.Uniform1f(u.uniform, v[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] data := data[:8]
v := *(*[2]float32)(unsafe.Pointer(&data[0])) v := *(*[2]float32)(unsafe.Pointer(&data[0]))
funcs.Uniform2f(u.uniform, v[0], v[1]) 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] data := data[:12]
v := *(*[3]float32)(unsafe.Pointer(&data[0])) v := *(*[3]float32)(unsafe.Pointer(&data[0]))
funcs.Uniform3f(u.uniform, v[0], v[1], v[2]) 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] data := data[:16]
v := *(*[4]float32)(unsafe.Pointer(&data[0])) v := *(*[4]float32)(unsafe.Pointer(&data[0]))
funcs.Uniform4f(u.uniform, v[0], v[1], v[2], v[3]) 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") panic("buffer size overflow")
} }
b.version++ b.version++
if b.typ&gpu.BufferBindingUniforms != 0 { if b.typ&backend.BufferBindingUniforms != 0 {
copy(b.data, data) copy(b.data, data)
} }
if b.typ&^gpu.BufferBindingUniforms != 0 { if b.typ&^backend.BufferBindingUniforms != 0 {
firstBinding := firstBufferType(b.typ) firstBinding := firstBufferType(b.typ)
b.backend.funcs.BindBuffer(firstBinding, b.obj) b.backend.funcs.BindBuffer(firstBinding, b.obj)
b.backend.funcs.BufferData(firstBinding, data, STATIC_DRAW) b.backend.funcs.BufferData(firstBinding, data, STATIC_DRAW)
@@ -548,14 +548,14 @@ func (b *gpuBuffer) Upload(data []byte) {
} }
func (b *gpuBuffer) Release() { func (b *gpuBuffer) Release() {
if b.typ&^gpu.BufferBindingUniforms != 0 { if b.typ&^backend.BufferBindingUniforms != 0 {
b.backend.funcs.DeleteBuffer(b.obj) 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) gbuf := buf.(*gpuBuffer)
if gbuf.typ&gpu.BufferBindingVertices == 0 { if gbuf.typ&backend.BufferBindingVertices == 0 {
panic("not a vertex buffer") panic("not a vertex buffer")
} }
b.state.buffer = bufferBinding{buf: gbuf, stride: stride, offset: offset} b.state.buffer = bufferBinding{buf: gbuf, stride: stride, offset: offset}
@@ -572,9 +572,9 @@ func (b *Backend) setupVertexArrays() {
l := layout.layout[i] l := layout.layout[i]
var gltyp Enum var gltyp Enum
switch l.Type { switch l.Type {
case gpu.DataTypeFloat: case backend.DataTypeFloat:
gltyp = FLOAT gltyp = FLOAT
case gpu.DataTypeShort: case backend.DataTypeShort:
gltyp = SHORT gltyp = SHORT
default: default:
panic("unsupported data type") 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) gbuf := buf.(*gpuBuffer)
if gbuf.typ&gpu.BufferBindingIndices == 0 { if gbuf.typ&backend.BufferBindingIndices == 0 {
panic("not an index buffer") panic("not an index buffer")
} }
b.funcs.BindBuffer(ELEMENT_ARRAY_BUFFER, gbuf.obj) 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) 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) 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 { switch f {
case gpu.FilterNearest: case backend.FilterNearest:
return NEAREST return NEAREST
case gpu.FilterLinear: case backend.FilterLinear:
return LINEAR return LINEAR
default: default:
panic("unsupported texture filter") 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)) b.bindTexture(unit, t.(*gpuTexture))
} }
@@ -677,7 +677,7 @@ func (t *gpuTimer) Duration() (time.Duration, bool) {
return time.Duration(nanos), true return time.Duration(nanos), true
} }
func (b *Backend) BindInputLayout(l gpu.InputLayout) { func (b *Backend) BindInputLayout(l backend.InputLayout) {
b.state.layout = l.(*gpuInputLayout) b.state.layout = l.(*gpuInputLayout)
} }
@@ -753,13 +753,13 @@ func hasExtension(exts []string, ext string) bool {
return false return false
} }
func firstBufferType(typ gpu.BufferBinding) Enum { func firstBufferType(typ backend.BufferBinding) Enum {
switch { switch {
case typ&gpu.BufferBindingIndices != 0: case typ&backend.BufferBindingIndices != 0:
return ELEMENT_ARRAY_BUFFER return ELEMENT_ARRAY_BUFFER
case typ&gpu.BufferBindingVertices != 0: case typ&backend.BufferBindingVertices != 0:
return ARRAY_BUFFER return ARRAY_BUFFER
case typ&gpu.BufferBindingUniforms != 0: case typ&backend.BufferBindingUniforms != 0:
return UNIFORM_BUFFER return UNIFORM_BUFFER
default: default:
panic("unsupported buffer type") panic("unsupported buffer type")
+33 -32
View File
@@ -18,6 +18,7 @@ import (
"unsafe" "unsafe"
"gioui.org/f32" "gioui.org/f32"
"gioui.org/gpu/backend"
"gioui.org/internal/opconst" "gioui.org/internal/opconst"
"gioui.org/internal/ops" "gioui.org/internal/ops"
"gioui.org/internal/path" "gioui.org/internal/path"
@@ -30,18 +31,18 @@ type GPU struct {
pathCache *opCache pathCache *opCache
cache *resourceCache cache *resourceCache
defFBO Framebuffer defFBO backend.Framebuffer
profile string profile string
timers *timers timers *timers
frameStart time.Time frameStart time.Time
zopsTimer, stencilTimer, coverTimer, cleanupTimer *timer zopsTimer, stencilTimer, coverTimer, cleanupTimer *timer
drawOps drawOps drawOps drawOps
ctx Backend ctx backend.Device
renderer *renderer renderer *renderer
} }
type renderer struct { type renderer struct {
ctx Backend ctx backend.Device
blitter *blitter blitter *blitter
pather *pather pather *pather
packer packer packer packer
@@ -207,14 +208,14 @@ type resource interface {
type texture struct { type texture struct {
src *image.RGBA src *image.RGBA
tex Texture tex backend.Texture
} }
type blitter struct { type blitter struct {
ctx Backend ctx backend.Device
viewport image.Point viewport image.Point
prog [2]*program prog [2]*program
layout InputLayout layout backend.InputLayout
colUniforms struct { colUniforms struct {
vert struct { vert struct {
blitUniforms blitUniforms
@@ -230,16 +231,16 @@ type blitter struct {
_ [8]byte // Padding to a multiple of 16. _ [8]byte // Padding to a multiple of 16.
} }
} }
quadVerts Buffer quadVerts backend.Buffer
} }
type uniformBuffer struct { type uniformBuffer struct {
buf Buffer buf backend.Buffer
ptr []byte ptr []byte
} }
type program struct { type program struct {
prog Program prog backend.Program
vertUniforms *uniformBuffer vertUniforms *uniformBuffer
fragUniforms *uniformBuffer fragUniforms *uniformBuffer
} }
@@ -275,7 +276,7 @@ const (
attribUV = 1 attribUV = 1
) )
func New(ctx Backend) (*GPU, error) { func New(ctx backend.Device) (*GPU, error) {
defFBO := ctx.CurrentFramebuffer() defFBO := ctx.CurrentFramebuffer()
g := &GPU{ g := &GPU{
defFBO: defFBO, defFBO: defFBO,
@@ -288,7 +289,7 @@ func New(ctx Backend) (*GPU, error) {
return g, nil return g, nil
} }
func (g *GPU) init(ctx Backend) error { func (g *GPU) init(ctx backend.Device) error {
g.ctx = ctx g.ctx = ctx
g.renderer = newRenderer(ctx) g.renderer = newRenderer(ctx)
return nil return nil
@@ -309,7 +310,7 @@ func (g *GPU) Collect(viewport image.Point, frameOps *op.Ops) {
g.drawOps.reset(g.cache, viewport) g.drawOps.reset(g.cache, viewport)
g.drawOps.collect(g.cache, frameOps, viewport) g.drawOps.collect(g.cache, frameOps, viewport)
g.frameStart = time.Now() 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.timers = newTimers(g.ctx)
g.zopsTimer = g.timers.newTimer() g.zopsTimer = g.timers.newTimer()
g.stencilTimer = g.timers.newTimer() g.stencilTimer = g.timers.newTimer()
@@ -336,10 +337,10 @@ func (g *GPU) BeginFrame() {
g.zopsTimer.begin() g.zopsTimer.begin()
} }
g.ctx.BindFramebuffer(g.defFBO) 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.ClearColor(g.drawOps.clearColor[0], g.drawOps.clearColor[1], g.drawOps.clearColor[2], 1.0)
g.ctx.ClearDepth(0.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.ctx.Viewport(0, 0, viewport.X, viewport.Y)
g.renderer.drawZOps(g.drawOps.zimageOps) g.renderer.drawZOps(g.drawOps.zimageOps)
g.zopsTimer.end() g.zopsTimer.end()
@@ -379,11 +380,11 @@ func (g *GPU) Profile() string {
return g.profile return g.profile
} }
func (r *renderer) texHandle(t *texture) Texture { func (r *renderer) texHandle(t *texture) backend.Texture {
if t.tex != nil { if t.tex != nil {
return t.tex 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 { if err != nil {
panic(err) panic(err)
} }
@@ -398,7 +399,7 @@ func (t *texture) release() {
} }
} }
func newRenderer(ctx Backend) *renderer { func newRenderer(ctx backend.Device) *renderer {
r := &renderer{ r := &renderer{
ctx: ctx, ctx: ctx,
blitter: newBlitter(ctx), blitter: newBlitter(ctx),
@@ -414,8 +415,8 @@ func (r *renderer) release() {
r.blitter.release() r.blitter.release()
} }
func newBlitter(ctx Backend) *blitter { func newBlitter(ctx backend.Device) *blitter {
quadVerts, err := ctx.NewImmutableBuffer(BufferBindingVertices, quadVerts, err := ctx.NewImmutableBuffer(backend.BufferBindingVertices,
gunsafe.BytesView([]float32{ gunsafe.BytesView([]float32{
-1, +1, 0, 0, -1, +1, 0, 0,
+1, +1, 1, 0, +1, +1, 1, 0,
@@ -448,7 +449,7 @@ func (b *blitter) release() {
b.layout.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 var progs [2]*program
prog, err := b.NewProgram(vsSrc, fsSrc[materialTexture]) prog, err := b.NewProgram(vsSrc, fsSrc[materialTexture])
if err != nil { if err != nil {
@@ -479,9 +480,9 @@ func createColorPrograms(b Backend, vsSrc ShaderSources, fsSrc [2]ShaderSources,
prog.SetFragmentUniforms(fragBuffer.buf) prog.SetFragmentUniforms(fragBuffer.buf)
} }
progs[materialColor] = newProgram(prog, vertBuffer, fragBuffer) progs[materialColor] = newProgram(prog, vertBuffer, fragBuffer)
layout, err := b.NewInputLayout(vsSrc, []InputDesc{ layout, err := b.NewInputLayout(vsSrc, []backend.InputDesc{
{Type: DataTypeFloat, Size: 2, Offset: 0}, {Type: backend.DataTypeFloat, Size: 2, Offset: 0},
{Type: DataTypeFloat, Size: 2, Offset: 4 * 2}, {Type: backend.DataTypeFloat, Size: 2, Offset: 4 * 2},
}) })
if err != nil { if err != nil {
progs[materialTexture].Release() progs[materialTexture].Release()
@@ -502,7 +503,7 @@ func (r *renderer) stencilClips(pathCache *opCache, ops []*pathOp) {
fbo = p.place.Idx fbo = p.place.Idx
f := r.pather.stenciler.cover(fbo) f := r.pather.stenciler.cover(fbo)
r.ctx.BindFramebuffer(f.fbo) r.ctx.BindFramebuffer(f.fbo)
r.ctx.Clear(BufferAttachmentColor) r.ctx.Clear(backend.BufferAttachmentColor)
} }
data, _ := pathCache.get(p.pathKey) data, _ := pathCache.get(p.pathKey)
r.pather.stencilPath(p.clip, p.off, p.place.Pos, data.(*pathData)) 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 fbo = img.place.Idx
f := r.pather.stenciler.intersections.fbos[fbo] f := r.pather.stenciler.intersections.fbos[fbo]
r.ctx.BindFramebuffer(f.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.ctx.Viewport(img.place.Pos.X, img.place.Pos.Y, img.clip.Dx(), img.clip.Dy())
r.intersectPath(img.path, img.clip) 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.uvScale = [2]float32{coverScale.X, coverScale.Y}
r.pather.stenciler.iprog.uniforms.vert.uvOffset = [2]float32{coverOff.X, coverOff.Y} r.pather.stenciler.iprog.uniforms.vert.uvOffset = [2]float32{coverOff.X, coverOff.Y}
r.pather.stenciler.iprog.prog.UploadUniforms() 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) { func (r *renderer) packIntersections(ops []imageOp) {
@@ -842,10 +843,10 @@ func (r *renderer) drawZOps(ops []imageOp) {
func (r *renderer) drawOps(ops []imageOp) { func (r *renderer) drawOps(ops []imageOp) {
r.ctx.SetDepthTest(true) r.ctx.SetDepthTest(true)
r.ctx.DepthMask(false) 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.BindVertexBuffer(r.blitter.quadVerts, 4*4, 0)
r.ctx.BindInputLayout(r.pather.coverer.layout) r.ctx.BindInputLayout(r.pather.coverer.layout)
var coverTex Texture var coverTex backend.Texture
for _, img := range ops { for _, img := range ops {
m := img.material m := img.material
switch m.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.scale = [2]float32{scale.X, scale.Y}
uniforms.offset = [2]float32{off.X, off.Y} uniforms.offset = [2]float32{off.X, off.Y}
p.UploadUniforms() 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 // newUniformBuffer creates a new GPU uniform buffer backed by the
// structure uniformBlock points to. // structure uniformBlock points to.
func newUniformBuffer(b Backend, uniformBlock interface{}) *uniformBuffer { func newUniformBuffer(b backend.Device, uniformBlock interface{}) *uniformBuffer {
ref := reflect.ValueOf(uniformBlock) ref := reflect.ValueOf(uniformBlock)
// Determine the size of the uniforms structure, *uniforms. // Determine the size of the uniforms structure, *uniforms.
size := ref.Elem().Type().Size() size := ref.Elem().Type().Size()
// Map the uniforms structure as a byte slice. // Map the uniforms structure as a byte slice.
ptr := (*[1 << 30]byte)(unsafe.Pointer(ref.Pointer()))[:size:size] 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 { if err != nil {
panic(err) panic(err)
} }
@@ -939,7 +940,7 @@ func (u *uniformBuffer) Release() {
u.buf = nil u.buf = nil
} }
func newProgram(prog Program, vertUniforms, fragUniforms *uniformBuffer) *program { func newProgram(prog backend.Program, vertUniforms, fragUniforms *uniformBuffer) *program {
if vertUniforms != nil { if vertUniforms != nil {
prog.SetVertexUniforms(vertUniforms.buf) prog.SetVertexUniforms(vertUniforms.buf)
} }
+35 -34
View File
@@ -10,12 +10,13 @@ import (
"unsafe" "unsafe"
"gioui.org/f32" "gioui.org/f32"
"gioui.org/gpu/backend"
"gioui.org/internal/path" "gioui.org/internal/path"
gunsafe "gioui.org/internal/unsafe" gunsafe "gioui.org/internal/unsafe"
) )
type pather struct { type pather struct {
ctx Backend ctx backend.Device
viewport image.Point viewport image.Point
@@ -24,7 +25,7 @@ type pather struct {
} }
type coverer struct { type coverer struct {
ctx Backend ctx backend.Device
prog [2]*program prog [2]*program
texUniforms struct { texUniforms struct {
vert struct { vert struct {
@@ -41,7 +42,7 @@ type coverer struct {
colorUniforms colorUniforms
} }
} }
layout InputLayout layout backend.InputLayout
} }
type coverUniforms struct { type coverUniforms struct {
@@ -56,7 +57,7 @@ type coverUniforms struct {
} }
type stenciler struct { type stenciler struct {
ctx Backend ctx backend.Device
prog struct { prog struct {
prog *program prog *program
uniforms struct { uniforms struct {
@@ -67,7 +68,7 @@ type stenciler struct {
_ [8]byte // Padding to multiple of 16. _ [8]byte // Padding to multiple of 16.
} }
} }
layout InputLayout layout backend.InputLayout
} }
iprog struct { iprog struct {
prog *program prog *program
@@ -77,11 +78,11 @@ type stenciler struct {
uvOffset [2]float32 uvOffset [2]float32
} }
} }
layout InputLayout layout backend.InputLayout
} }
fbos fboSet fbos fboSet
intersections fboSet intersections fboSet
indexBuf Buffer indexBuf backend.Buffer
} }
type fboSet struct { type fboSet struct {
@@ -90,13 +91,13 @@ type fboSet struct {
type stencilFBO struct { type stencilFBO struct {
size image.Point size image.Point
fbo Framebuffer fbo backend.Framebuffer
tex Texture tex backend.Texture
} }
type pathData struct { type pathData struct {
ncurves int ncurves int
data Buffer data backend.Buffer
} }
const ( const (
@@ -112,7 +113,7 @@ const (
attribPathTo = 4 attribPathTo = 4
) )
func newPather(ctx Backend) *pather { func newPather(ctx backend.Device) *pather {
return &pather{ return &pather{
ctx: ctx, ctx: ctx,
stenciler: newStenciler(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{ c := &coverer{
ctx: ctx, ctx: ctx,
} }
@@ -136,7 +137,7 @@ func newCoverer(ctx Backend) *coverer {
return c return c
} }
func newStenciler(ctx Backend) *stenciler { func newStenciler(ctx backend.Device) *stenciler {
// Allocate a suitably large index buffer for drawing paths. // Allocate a suitably large index buffer for drawing paths.
indices := make([]uint16, pathBatchSize*6) indices := make([]uint16, pathBatchSize*6)
for i := 0; i < pathBatchSize; i++ { 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+4] = i*4 + 1
indices[i*6+5] = i*4 + 3 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 { if err != nil {
panic(err) panic(err)
} }
progLayout, err := ctx.NewInputLayout(shader_stencil_vert, []InputDesc{ progLayout, err := ctx.NewInputLayout(shader_stencil_vert, []backend.InputDesc{
{Type: DataTypeShort, Size: 2, Offset: int(unsafe.Offsetof((*(*path.Vertex)(nil)).CornerX))}, {Type: backend.DataTypeShort, Size: 2, Offset: int(unsafe.Offsetof((*(*path.Vertex)(nil)).CornerX))},
{Type: DataTypeFloat, Size: 1, Offset: int(unsafe.Offsetof((*(*path.Vertex)(nil)).MaxY))}, {Type: backend.DataTypeFloat, Size: 1, Offset: int(unsafe.Offsetof((*(*path.Vertex)(nil)).MaxY))},
{Type: DataTypeFloat, Size: 2, Offset: int(unsafe.Offsetof((*(*path.Vertex)(nil)).FromX))}, {Type: backend.DataTypeFloat, Size: 2, Offset: int(unsafe.Offsetof((*(*path.Vertex)(nil)).FromX))},
{Type: DataTypeFloat, Size: 2, Offset: int(unsafe.Offsetof((*(*path.Vertex)(nil)).CtrlX))}, {Type: backend.DataTypeFloat, Size: 2, Offset: int(unsafe.Offsetof((*(*path.Vertex)(nil)).CtrlX))},
{Type: DataTypeFloat, Size: 2, Offset: int(unsafe.Offsetof((*(*path.Vertex)(nil)).ToX))}, {Type: backend.DataTypeFloat, Size: 2, Offset: int(unsafe.Offsetof((*(*path.Vertex)(nil)).ToX))},
}) })
if err != nil { if err != nil {
panic(err) panic(err)
} }
iprogLayout, err := ctx.NewInputLayout(shader_intersect_vert, []InputDesc{ iprogLayout, err := ctx.NewInputLayout(shader_intersect_vert, []backend.InputDesc{
{Type: DataTypeFloat, Size: 2, Offset: 0}, {Type: backend.DataTypeFloat, Size: 2, Offset: 0},
{Type: DataTypeFloat, Size: 2, Offset: 4 * 2}, {Type: backend.DataTypeFloat, Size: 2, Offset: 4 * 2},
}) })
if err != nil { if err != nil {
panic(err) panic(err)
@@ -190,7 +191,7 @@ func newStenciler(ctx Backend) *stenciler {
return st return st
} }
func (s *fboSet) resize(ctx Backend, sizes []image.Point) { func (s *fboSet) resize(ctx backend.Device, sizes []image.Point) {
// Add fbos. // Add fbos.
for i := len(s.fbos); i < len(sizes); i++ { for i := len(s.fbos); i < len(sizes); i++ {
s.fbos = append(s.fbos, stencilFBO{}) s.fbos = append(s.fbos, stencilFBO{})
@@ -208,8 +209,8 @@ func (s *fboSet) resize(ctx Backend, sizes []image.Point) {
f.fbo.Release() f.fbo.Release()
f.tex.Release() f.tex.Release()
} }
tex, err := ctx.NewTexture(TextureFormatFloat, sz.X, sz.Y, FilterNearest, FilterNearest, tex, err := ctx.NewTexture(backend.TextureFormatFloat, sz.X, sz.Y, backend.FilterNearest, backend.FilterNearest,
BufferBindingTexture|BufferBindingFramebuffer) backend.BufferBindingTexture|backend.BufferBindingFramebuffer)
fbo, err := ctx.NewFramebuffer(tex, 0) fbo, err := ctx.NewFramebuffer(tex, 0)
if err != nil { if err != nil {
panic(err) panic(err)
@@ -223,13 +224,13 @@ func (s *fboSet) resize(ctx Backend, sizes []image.Point) {
s.delete(ctx, len(sizes)) s.delete(ctx, len(sizes))
} }
func (s *fboSet) invalidate(ctx Backend) { func (s *fboSet) invalidate(ctx backend.Device) {
for _, f := range s.fbos { for _, f := range s.fbos {
f.fbo.Invalidate() 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++ { for i := idx; i < len(s.fbos); i++ {
f := s.fbos[i] f := s.fbos[i]
f.fbo.Release() f.fbo.Release()
@@ -259,8 +260,8 @@ func (c *coverer) release() {
c.layout.Release() c.layout.Release()
} }
func buildPath(ctx Backend, p []byte) *pathData { func buildPath(ctx backend.Device, p []byte) *pathData {
buf, err := ctx.NewImmutableBuffer(BufferBindingVertices, p) buf, err := ctx.NewImmutableBuffer(backend.BufferBindingVertices, p)
if err != nil { if err != nil {
panic(err) 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) { 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 // 8 bit coverage is enough, but OpenGL ES only supports single channel
// floating point formats. Replace with GL_RGB+GL_UNSIGNED_BYTE if // floating point formats. Replace with GL_RGB+GL_UNSIGNED_BYTE if
// no floating point support is available. // no floating point support is available.
@@ -302,7 +303,7 @@ func (s *stenciler) cover(idx int) stencilFBO {
} }
func (s *stenciler) begin(sizes []image.Point) { 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.fbos.resize(s.ctx, sizes)
s.ctx.ClearColor(0.0, 0.0, 0.0, 0.0) s.ctx.ClearColor(0.0, 0.0, 0.0, 0.0)
s.ctx.BindProgram(s.prog.prog.prog) 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 off := path.VertStride * start * 4
s.ctx.BindVertexBuffer(data.data, path.VertStride, off) 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 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.uvCoverScale = [2]float32{coverScale.X, coverScale.Y}
uniforms.uvCoverOffset = [2]float32{coverOff.X, coverOff.Y} uniforms.uvCoverOffset = [2]float32{coverOff.X, coverOff.Y}
p.UploadUniforms() p.UploadUniforms()
c.ctx.DrawArrays(DrawModeTriangleStrip, 0, 4) c.ctx.DrawArrays(backend.DrawModeTriangleStrip, 0, 4)
} }
+28 -26
View File
@@ -2,10 +2,12 @@
package gpu package gpu
import "gioui.org/gpu/backend"
var ( var (
shader_blit_frag = [...]ShaderSources{ shader_blit_frag = [...]backend.ShaderSources{
ShaderSources{ backend.ShaderSources{
Uniforms: []UniformLocation{ Uniforms: []backend.UniformLocation{
{Name: "_12._color", Type: 0, Size: 4, Offset: 0}, {Name: "_12._color", Type: 0, Size: 4, Offset: 0},
}, },
UniformSize: 16, UniformSize: 16,
@@ -47,8 +49,8 @@ var (
*/ */
HLSL: []byte(nil), HLSL: []byte(nil),
}, },
ShaderSources{ backend.ShaderSources{
Textures: []TextureBinding{ Textures: []backend.TextureBinding{
{Name: "tex", Binding: 0}, {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", 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), HLSL: []byte(nil),
}, },
} }
shader_blit_vert = ShaderSources{ shader_blit_vert = backend.ShaderSources{
Inputs: []InputLocation{ Inputs: []backend.InputLocation{
{Name: "pos", Location: 0, Semantic: "POSITION", SemanticIndex: 0, Type: 0, Size: 2}, {Name: "pos", Location: 0, Semantic: "POSITION", SemanticIndex: 0, Type: 0, Size: 2},
{Name: "uv", Location: 1, Semantic: "NORMAL", 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.z", Type: 0, Size: 1, Offset: 0},
{Name: "_15.scale", Type: 0, Size: 2, Offset: 8}, {Name: "_15.scale", Type: 0, Size: 2, Offset: 8},
{Name: "_15.offset", Type: 0, Size: 2, Offset: 16}, {Name: "_15.offset", Type: 0, Size: 2, Offset: 16},
@@ -152,13 +154,13 @@ var (
*/ */
HLSL: []byte(nil), HLSL: []byte(nil),
} }
shader_cover_frag = [...]ShaderSources{ shader_cover_frag = [...]backend.ShaderSources{
ShaderSources{ backend.ShaderSources{
Uniforms: []UniformLocation{ Uniforms: []backend.UniformLocation{
{Name: "_12._color", Type: 0, Size: 4, Offset: 0}, {Name: "_12._color", Type: 0, Size: 4, Offset: 0},
}, },
UniformSize: 16, UniformSize: 16,
Textures: []TextureBinding{ Textures: []backend.TextureBinding{
{Name: "cover", Binding: 1}, {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", 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), HLSL: []byte(nil),
}, },
ShaderSources{ backend.ShaderSources{
Textures: []TextureBinding{ Textures: []backend.TextureBinding{
{Name: "tex", Binding: 0}, {Name: "tex", Binding: 0},
{Name: "cover", Binding: 1}, {Name: "cover", Binding: 1},
}, },
@@ -254,12 +256,12 @@ var (
HLSL: []byte(nil), HLSL: []byte(nil),
}, },
} }
shader_cover_vert = ShaderSources{ shader_cover_vert = backend.ShaderSources{
Inputs: []InputLocation{ Inputs: []backend.InputLocation{
{Name: "pos", Location: 0, Semantic: "POSITION", SemanticIndex: 0, Type: 0, Size: 2}, {Name: "pos", Location: 0, Semantic: "POSITION", SemanticIndex: 0, Type: 0, Size: 2},
{Name: "uv", Location: 1, Semantic: "NORMAL", 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.z", Type: 0, Size: 1, Offset: 0},
{Name: "_19.scale", Type: 0, Size: 2, Offset: 8}, {Name: "_19.scale", Type: 0, Size: 2, Offset: 8},
{Name: "_19.offset", Type: 0, Size: 2, Offset: 16}, {Name: "_19.offset", Type: 0, Size: 2, Offset: 16},
@@ -324,8 +326,8 @@ var (
*/ */
HLSL: []byte(nil), HLSL: []byte(nil),
} }
shader_intersect_frag = ShaderSources{ shader_intersect_frag = backend.ShaderSources{
Textures: []TextureBinding{ Textures: []backend.TextureBinding{
{Name: "cover", Binding: 0}, {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", 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), HLSL: []byte(nil),
} }
shader_intersect_vert = ShaderSources{ shader_intersect_vert = backend.ShaderSources{
Inputs: []InputLocation{ Inputs: []backend.InputLocation{
{Name: "pos", Location: 0, Semantic: "POSITION", SemanticIndex: 0, Type: 0, Size: 2}, {Name: "pos", Location: 0, Semantic: "POSITION", SemanticIndex: 0, Type: 0, Size: 2},
{Name: "uv", Location: 1, Semantic: "NORMAL", 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.scale", Type: 0, Size: 2, Offset: 0},
{Name: "_40.offset", Type: 0, Size: 2, Offset: 8}, {Name: "_40.offset", Type: 0, Size: 2, Offset: 8},
}, },
@@ -422,7 +424,7 @@ var (
*/ */
HLSL: []byte(nil), 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", 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; static float2 vTo;
@@ -486,15 +488,15 @@ var (
*/ */
HLSL: []byte(nil), HLSL: []byte(nil),
} }
shader_stencil_vert = ShaderSources{ shader_stencil_vert = backend.ShaderSources{
Inputs: []InputLocation{ Inputs: []backend.InputLocation{
{Name: "corner", Location: 0, Semantic: "POSITION", SemanticIndex: 0, Type: 0, Size: 2}, {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: "maxy", Location: 1, Semantic: "NORMAL", SemanticIndex: 0, Type: 0, Size: 1},
{Name: "from", Location: 2, Semantic: "TEXCOORD", SemanticIndex: 0, Type: 0, Size: 2}, {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: "ctrl", Location: 3, Semantic: "TEXCOORD", SemanticIndex: 1, Type: 0, Size: 2},
{Name: "to", Location: 4, Semantic: "TEXCOORD", SemanticIndex: 2, 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.scale", Type: 0, Size: 2, Offset: 0},
{Name: "_15.offset", Type: 0, Size: 2, Offset: 8}, {Name: "_15.offset", Type: 0, Size: 2, Offset: 8},
{Name: "_15.pathOffset", Type: 0, Size: 2, Offset: 16}, {Name: "_15.pathOffset", Type: 0, Size: 2, Offset: 16},
+6 -4
View File
@@ -4,17 +4,19 @@ package gpu
import ( import (
"time" "time"
"gioui.org/gpu/backend"
) )
type timers struct { type timers struct {
backend Backend backend backend.Device
timers []*timer timers []*timer
} }
type timer struct { type timer struct {
Elapsed time.Duration Elapsed time.Duration
backend Backend backend backend.Device
timer Timer timer backend.Timer
state timerState state timerState
} }
@@ -26,7 +28,7 @@ const (
timerWaiting timerWaiting
) )
func newTimers(b Backend) *timers { func newTimers(b backend.Device) *timers {
return &timers{ return &timers{
backend: b, backend: b,
} }