gpu: make GPU an interface to prepare for second implementation

While here, merge BeginFrame and EndFrame; the split was done for
performance reasons, yet never measured.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2020-12-30 18:02:18 +01:00
parent b1ff179aa0
commit 6f2a98c667
3 changed files with 33 additions and 18 deletions
+2 -4
View File
@@ -18,7 +18,7 @@ type Window struct {
size image.Point
ctx context
backend backend.Device
gpu *gpu.GPU
gpu gpu.GPU
fboTex backend.Texture
fbo backend.Framebuffer
}
@@ -109,9 +109,7 @@ func (w *Window) Release() {
func (w *Window) Frame(frame *op.Ops) error {
return contextDo(w.ctx, func() error {
w.gpu.Collect(w.size, frame)
w.gpu.BeginFrame()
w.gpu.EndFrame()
return nil
return w.gpu.Frame()
})
}
+4 -3
View File
@@ -88,10 +88,11 @@ func (l *renderLoop) renderLoop(ctx window.Context) error {
g.Collect(frame.viewport, frame.ops)
// Signal that we're done with the frame ops.
l.ack <- struct{}{}
g.BeginFrame()
var res frameResult
res.err = ctx.Present()
g.EndFrame()
res.err = g.Frame()
if res.err == nil {
res.err = ctx.Present()
}
res.profile = g.Profile()
ctx.Unlock()
l.results <- res
+27 -11
View File
@@ -9,6 +9,7 @@ package gpu
import (
"encoding/binary"
"errors"
"fmt"
"image"
"image/color"
@@ -28,7 +29,14 @@ import (
"gioui.org/op/clip"
)
type GPU struct {
type GPU interface {
Release()
Collect(viewport image.Point, frameOps *op.Ops)
Frame() error
Profile() string
}
type gpu struct {
cache *resourceCache
defFBO backend.Framebuffer
@@ -363,9 +371,19 @@ const (
materialTexture
)
func New(ctx backend.Device) (*GPU, error) {
func New(ctx backend.Device) (GPU, error) {
feats := ctx.Caps().Features
switch {
case feats.Has(backend.FeatureFloatRenderTargets):
return newGPU(ctx)
default:
return nil, errors.New("gpu: no support for float render targets nor compute")
}
}
func newGPU(ctx backend.Device) (*gpu, error) {
defFBO := ctx.CurrentFramebuffer()
g := &GPU{
g := &gpu{
defFBO: defFBO,
cache: newResourceCache(),
}
@@ -376,13 +394,13 @@ func New(ctx backend.Device) (*GPU, error) {
return g, nil
}
func (g *GPU) init(ctx backend.Device) error {
func (g *gpu) init(ctx backend.Device) error {
g.ctx = ctx
g.renderer = newRenderer(ctx)
return nil
}
func (g *GPU) Release() {
func (g *gpu) Release() {
g.renderer.release()
g.drawOps.pathCache.release()
g.cache.release()
@@ -391,7 +409,7 @@ func (g *GPU) Release() {
}
}
func (g *GPU) Collect(viewport image.Point, frameOps *op.Ops) {
func (g *gpu) Collect(viewport image.Point, frameOps *op.Ops) {
g.renderer.blitter.viewport = viewport
g.renderer.pather.viewport = viewport
g.drawOps.reset(g.cache, viewport)
@@ -406,7 +424,7 @@ func (g *GPU) Collect(viewport image.Point, frameOps *op.Ops) {
}
}
func (g *GPU) BeginFrame() {
func (g *gpu) Frame() error {
g.ctx.BeginFrame()
defer g.ctx.EndFrame()
viewport := g.renderer.blitter.viewport
@@ -440,9 +458,6 @@ func (g *GPU) BeginFrame() {
g.renderer.pather.stenciler.invalidateFBO()
g.coverTimer.end()
g.ctx.BindFramebuffer(g.defFBO)
}
func (g *GPU) EndFrame() {
g.cleanupTimer.begin()
g.cache.frame()
g.drawOps.pathCache.frame()
@@ -456,9 +471,10 @@ func (g *GPU) EndFrame() {
ft = ft.Round(q)
g.profile = fmt.Sprintf("draw:%7s gpu:%7s zt:%7s st:%7s cov:%7s", frameDur, ft, zt, st, covt)
}
return nil
}
func (g *GPU) Profile() string {
func (g *gpu) Profile() string {
return g.profile
}