app,app/headless: expose Backends from window and headless contexts

This is a refactoring change to prepare for another gpu.Backend
implementations.

Notably, app/loop.go no longer imports gpu/gl.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2020-02-15 18:29:14 +01:00
parent f62725ea77
commit 94fdc26cb5
9 changed files with 42 additions and 19 deletions
+2 -1
View File
@@ -26,6 +26,7 @@ type Window struct {
type context interface { type context interface {
Functions() *glimpl.Functions Functions() *glimpl.Functions
Backend() (gpu.Backend, error)
MakeCurrent() error MakeCurrent() error
ReleaseCurrent() ReleaseCurrent()
Release() Release()
@@ -53,7 +54,7 @@ func NewWindow(width, height int) (*Window, error) {
ctx.Release() ctx.Release()
return err return err
} }
backend, err := gl.NewBackend(f) backend, err := ctx.Backend()
if err != nil { if err != nil {
fbo.Release() fbo.Release()
ctx.Release() ctx.Release()
+6
View File
@@ -4,6 +4,8 @@ package headless
import ( import (
"gioui.org/app/internal/glimpl" "gioui.org/app/internal/glimpl"
"gioui.org/gpu"
"gioui.org/gpu/gl"
) )
/* /*
@@ -38,6 +40,10 @@ func (c *nsContext) ReleaseCurrent() {
C.gio_headless_clearCurrentContext(c.ctx) C.gio_headless_clearCurrentContext(c.ctx)
} }
func (c *nsContext) Backend() (gpu.Backend, error) {
return gl.NewBackend(c.c)
}
func (c *nsContext) Functions() *glimpl.Functions { func (c *nsContext) Functions() *glimpl.Functions {
return c.c return c.c
} }
+6
View File
@@ -7,6 +7,8 @@ import (
"syscall/js" "syscall/js"
"gioui.org/app/internal/glimpl" "gioui.org/app/internal/glimpl"
"gioui.org/gpu"
"gioui.org/gpu/gl"
) )
type jsContext struct { type jsContext struct {
@@ -37,6 +39,10 @@ func newContext() (*jsContext, error) {
return c, nil return c, nil
} }
func (c *jsContext) Backend() (gpu.Backend, error) {
return gl.NewBackend(c.f)
}
func (c *jsContext) Functions() *glimpl.Functions { func (c *jsContext) Functions() *glimpl.Functions {
return c.f return c.f
} }
+6
View File
@@ -12,6 +12,8 @@ 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/gl"
) )
type Context struct { type Context struct {
@@ -119,6 +121,10 @@ func (c *Context) Functions() *glimpl.Functions {
return c.c return c.c
} }
func (c *Context) Backend() (gpu.Backend, error) {
return gl.NewBackend(c.c)
}
func (c *Context) ReleaseSurface() { func (c *Context) ReleaseSurface() {
if c.eglSurf == nilEGLSurface { if c.eglSurf == nilEGLSurface {
return return
+3 -2
View File
@@ -17,6 +17,7 @@ import (
"fmt" "fmt"
"gioui.org/app/internal/glimpl" "gioui.org/app/internal/glimpl"
"gioui.org/gpu"
"gioui.org/gpu/gl" "gioui.org/gpu/gl"
) )
@@ -50,8 +51,8 @@ func newContext(w *window) (*context, error) {
return c, nil return c, nil
} }
func (c *context) Functions() *glimpl.Functions { func (c *context) Backend() (gpu.Backend, error) {
return c.c return gl.NewBackend(c.c)
} }
func (c *context) Release() { func (c *context) Release() {
+4 -2
View File
@@ -8,6 +8,8 @@ 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/gl"
) )
type context struct { type context struct {
@@ -45,8 +47,8 @@ func newContext(w *window) (*context, error) {
return c, nil return c, nil
} }
func (c *context) Functions() *glimpl.Functions { func (c *context) Backend() (gpu.Backend, error) {
return c.f return gl.NewBackend(c.f)
} }
func (c *context) Release() { func (c *context) Release() {
+4 -2
View File
@@ -6,6 +6,8 @@ package window
import ( import (
"gioui.org/app/internal/glimpl" "gioui.org/app/internal/glimpl"
"gioui.org/gpu"
"gioui.org/gpu/gl"
) )
/* /*
@@ -40,8 +42,8 @@ func newContext(w *window) (*context, error) {
return c, nil return c, nil
} }
func (c *context) Functions() *glimpl.Functions { func (c *context) Backend() (gpu.Backend, error) {
return c.c return gl.NewBackend(c.c)
} }
func (c *context) Release() { func (c *context) Release() {
+2 -2
View File
@@ -9,7 +9,7 @@ import (
"math" "math"
"time" "time"
"gioui.org/app/internal/glimpl" "gioui.org/gpu"
"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 {
Functions() *glimpl.Functions Backend() (gpu.Backend, error)
Present() error Present() error
MakeCurrent() error MakeCurrent() error
Release() Release()
+9 -10
View File
@@ -8,7 +8,6 @@ import (
"gioui.org/app/internal/window" "gioui.org/app/internal/window"
"gioui.org/gpu" "gioui.org/gpu"
"gioui.org/gpu/gl"
"gioui.org/op" "gioui.org/op"
) )
@@ -54,7 +53,7 @@ func newLoop(ctx window.Context) (*renderLoop, error) {
return l, nil return l, nil
} }
func (l *renderLoop) renderLoop(glctx window.Context) error { func (l *renderLoop) renderLoop(ctx window.Context) error {
// GL Operations must happen on a single OS thread, so // GL Operations must happen on a single OS thread, so
// pass initialization result through a channel. // pass initialization result through a channel.
initErr := make(chan error) initErr := make(chan error)
@@ -63,38 +62,38 @@ func (l *renderLoop) renderLoop(glctx window.Context) error {
runtime.LockOSThread() runtime.LockOSThread()
// Don't UnlockOSThread to avoid reuse by the Go runtime. // Don't UnlockOSThread to avoid reuse by the Go runtime.
if err := glctx.MakeCurrent(); err != nil { if err := ctx.MakeCurrent(); err != nil {
initErr <- err initErr <- err
return return
} }
ctx, err := gl.NewBackend(glctx.Functions()) b, err := ctx.Backend()
if err != nil { if err != nil {
initErr <- err initErr <- err
return return
} }
g, err := gpu.New(ctx) g, err := gpu.New(b)
if err != nil { if err != nil {
initErr <- err initErr <- err
return return
} }
defer glctx.Release() defer ctx.Release()
initErr <- nil initErr <- nil
loop: loop:
for { for {
select { select {
case <-l.refresh: case <-l.refresh:
l.refreshErr <- glctx.MakeCurrent() l.refreshErr <- ctx.MakeCurrent()
case frame := <-l.frames: case frame := <-l.frames:
glctx.Lock() ctx.Lock()
g.Collect(frame.viewport, frame.ops) g.Collect(frame.viewport, frame.ops)
// Signal that we're done with the frame ops. // Signal that we're done with the frame ops.
l.ack <- struct{}{} l.ack <- struct{}{}
g.BeginFrame() g.BeginFrame()
var res frameResult var res frameResult
res.err = glctx.Present() res.err = ctx.Present()
g.EndFrame() g.EndFrame()
res.profile = g.Profile() res.profile = g.Profile()
glctx.Unlock() ctx.Unlock()
l.results <- res l.results <- res
case <-l.stop: case <-l.stop:
break loop break loop