gpu: Merge GPU.Collect and GPU.Frame

There's no meaningful reason to have them separate. The intention was to
enable rendering concurrent with other processing, but that's gaining
framerate at the expense of input latency and complicating ImageOp
semantics.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2021-08-24 08:25:10 +02:00
parent 7acc031ccf
commit 414be0a0b3
6 changed files with 22 additions and 40 deletions
+1 -2
View File
@@ -97,10 +97,9 @@ func (l *renderLoop) renderLoop(ctx wm.Context) error {
} else { } else {
g.Clear(color.NRGBA{A: 0xff, R: 0xff, G: 0xff, B: 0xff}) g.Clear(color.NRGBA{A: 0xff, R: 0xff, G: 0xff, B: 0xff})
} }
g.Collect(frame.viewport, frame.ops) res.err = g.Frame(frame.ops, ctx.RenderTarget(), frame.viewport)
// Signal that we're done with the frame ops. // Signal that we're done with the frame ops.
l.ack <- struct{}{} l.ack <- struct{}{}
res.err = g.Frame(ctx.RenderTarget())
if res.err == nil { if res.err == nil {
res.err = ctx.Present() res.err = ctx.Present()
} }
+7 -2
View File
@@ -559,7 +559,12 @@ func newShaders(ctx driver.Device, vsrc, fsrc shader.Sources) (vert driver.Verte
return return
} }
func (g *compute) Collect(viewport image.Point, ops *op.Ops) { func (g *compute) Frame(frameOps *op.Ops, target RenderTarget, viewport image.Point) error {
g.collect(viewport, frameOps)
return g.frame(target)
}
func (g *compute) collect(viewport image.Point, ops *op.Ops) {
g.viewport = viewport g.viewport = viewport
g.collector.reset() g.collector.reset()
for i := range g.output.layerAtlases { for i := range g.output.layerAtlases {
@@ -575,7 +580,7 @@ func (g *compute) Clear(col color.NRGBA) {
g.collector.clearColor = f32color.LinearFromSRGB(col) g.collector.clearColor = f32color.LinearFromSRGB(col)
} }
func (g *compute) Frame(target RenderTarget) error { func (g *compute) frame(target RenderTarget) error {
viewport := g.viewport viewport := g.viewport
defFBO := g.ctx.BeginFrame(target, g.collector.clear, viewport) defFBO := g.ctx.BeginFrame(target, g.collector.clear, viewport)
defer g.ctx.EndFrame() defer g.ctx.EndFrame()
+10 -7
View File
@@ -43,12 +43,10 @@ type GPU interface {
Release() Release()
// Clear sets the clear color for the next Frame. // Clear sets the clear color for the next Frame.
Clear(color color.NRGBA) Clear(color color.NRGBA)
// Collect the graphics operations from frame, given the viewport. // Frame draws the graphics operations from op into a viewport of target.
Collect(viewport image.Point, frame *op.Ops) Frame(frame *op.Ops, target RenderTarget, viewport image.Point) error
// Frame draws the collected operations to target.
Frame(target RenderTarget) error
// Profile returns the last available profiling information. Profiling // Profile returns the last available profiling information. Profiling
// information is requested when Collect sees an io/profile.Op, and the result // information is requested when Frame sees an io/profile.Op, and the result
// is available through Profile at some later time. // is available through Profile at some later time.
Profile() string Profile() string
} }
@@ -399,7 +397,12 @@ func (g *gpu) Release() {
g.ctx.Release() g.ctx.Release()
} }
func (g *gpu) Collect(viewport image.Point, frameOps *op.Ops) { func (g *gpu) Frame(frameOps *op.Ops, target RenderTarget, viewport image.Point) error {
g.collect(viewport, frameOps)
return g.frame(target)
}
func (g *gpu) collect(viewport image.Point, frameOps *op.Ops) {
g.renderer.blitter.viewport = viewport g.renderer.blitter.viewport = viewport
g.renderer.pather.viewport = viewport g.renderer.pather.viewport = viewport
g.drawOps.reset(g.cache, viewport) g.drawOps.reset(g.cache, viewport)
@@ -413,7 +416,7 @@ func (g *gpu) Collect(viewport image.Point, frameOps *op.Ops) {
} }
} }
func (g *gpu) Frame(target RenderTarget) error { func (g *gpu) frame(target RenderTarget) error {
viewport := g.renderer.blitter.viewport viewport := g.renderer.blitter.viewport
defFBO := g.ctx.BeginFrame(target, g.drawOps.clear, viewport) defFBO := g.ctx.BeginFrame(target, g.drawOps.clear, viewport)
defer g.ctx.EndFrame() defer g.ctx.EndFrame()
+1 -2
View File
@@ -109,8 +109,7 @@ func (w *Window) Release() {
func (w *Window) Frame(frame *op.Ops) error { func (w *Window) Frame(frame *op.Ops) error {
return contextDo(w.ctx, func() error { return contextDo(w.ctx, func() error {
w.gpu.Clear(color.NRGBA{}) w.gpu.Clear(color.NRGBA{})
w.gpu.Collect(w.size, frame) return w.gpu.Frame(frame, driver.RenderTarget(w.fbo), w.size)
return w.gpu.Frame(driver.RenderTarget(w.fbo))
}) })
} }
+2 -21
View File
@@ -26,27 +26,8 @@ type FrameEvent struct {
Size image.Point Size image.Point
// Insets is the insets to apply. // Insets is the insets to apply.
Insets Insets Insets Insets
// Frame is the callback to supply the list of // Frame completes the FrameEvent by drawing the graphical operations
// operations to complete the FrameEvent. // from ops into the window.
//
// Note that the operation list and the operations themselves
// may not be mutated until another FrameEvent is received from
// the same event source.
// That means that calls to frame.Reset and changes to referenced
// data such as ImageOp backing images should happen between
// receiving a FrameEvent and calling Frame.
//
// Example:
//
// var w *app.Window
// var frame *op.Ops
// for e := range w.Events() {
// if e, ok := e.(system.FrameEvent); ok {
// // Call frame.Reset and manipulate images for ImageOps
// // here.
// e.Frame(frame)
// }
// }
Frame func(frame *op.Ops) Frame func(frame *op.Ops)
// Queue supplies the events for event handlers. // Queue supplies the events for event handlers.
Queue event.Queue Queue event.Queue
+1 -6
View File
@@ -16,9 +16,6 @@ import (
) )
// ImageOp sets the brush to an image. // ImageOp sets the brush to an image.
//
// Note: the ImageOp may keep a reference to the backing image.
// See NewImageOp for details.
type ImageOp struct { type ImageOp struct {
uniform bool uniform bool
color color.NRGBA color color.NRGBA
@@ -47,9 +44,7 @@ type LinearGradientOp struct {
type PaintOp struct { type PaintOp struct {
} }
// NewImageOp creates an ImageOp backed by src. See // NewImageOp creates an ImageOp backed by src.
// gioui.org/io/system.FrameEvent for a description of when data
// referenced by operations is safe to re-use.
// //
// NewImageOp assumes the backing image is immutable, and may cache a // NewImageOp assumes the backing image is immutable, and may cache a
// copy of its contents in a GPU-friendly way. Create new ImageOps to // copy of its contents in a GPU-friendly way. Create new ImageOps to