mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-01 07:35:40 +00:00
gpu/backend: move backend interface types to a separate package
Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
+17
-16
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
|
||||
package headless
|
||||
|
||||
func newContext() (backend, error) {
|
||||
func newContext() (context, error) {
|
||||
return newGLContext()
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
+6
-5
@@ -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)
|
||||
}
|
||||
|
||||
+68
-68
@@ -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")
|
||||
|
||||
+33
-32
@@ -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)
|
||||
}
|
||||
|
||||
+35
-34
@@ -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)
|
||||
}
|
||||
|
||||
+28
-26
@@ -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},
|
||||
|
||||
+6
-4
@@ -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,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user