diff --git a/app/loop.go b/app/loop.go index 6007df05..1d388b62 100644 --- a/app/loop.go +++ b/app/loop.go @@ -97,10 +97,9 @@ func (l *renderLoop) renderLoop(ctx wm.Context) error { } else { 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. l.ack <- struct{}{} - res.err = g.Frame(ctx.RenderTarget()) if res.err == nil { res.err = ctx.Present() } diff --git a/gpu/compute.go b/gpu/compute.go index 8fe104ef..d630818f 100644 --- a/gpu/compute.go +++ b/gpu/compute.go @@ -559,7 +559,12 @@ func newShaders(ctx driver.Device, vsrc, fsrc shader.Sources) (vert driver.Verte 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.collector.reset() for i := range g.output.layerAtlases { @@ -575,7 +580,7 @@ func (g *compute) Clear(col color.NRGBA) { g.collector.clearColor = f32color.LinearFromSRGB(col) } -func (g *compute) Frame(target RenderTarget) error { +func (g *compute) frame(target RenderTarget) error { viewport := g.viewport defFBO := g.ctx.BeginFrame(target, g.collector.clear, viewport) defer g.ctx.EndFrame() diff --git a/gpu/gpu.go b/gpu/gpu.go index 826aebd9..f3bc42fb 100644 --- a/gpu/gpu.go +++ b/gpu/gpu.go @@ -43,12 +43,10 @@ type GPU interface { Release() // Clear sets the clear color for the next Frame. Clear(color color.NRGBA) - // Collect the graphics operations from frame, given the viewport. - Collect(viewport image.Point, frame *op.Ops) - // Frame draws the collected operations to target. - Frame(target RenderTarget) error + // Frame draws the graphics operations from op into a viewport of target. + Frame(frame *op.Ops, target RenderTarget, viewport image.Point) error // 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. Profile() string } @@ -399,7 +397,12 @@ func (g *gpu) 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.pather.viewport = 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 defFBO := g.ctx.BeginFrame(target, g.drawOps.clear, viewport) defer g.ctx.EndFrame() diff --git a/gpu/headless/headless.go b/gpu/headless/headless.go index 14c8df7e..5870bf06 100644 --- a/gpu/headless/headless.go +++ b/gpu/headless/headless.go @@ -109,8 +109,7 @@ func (w *Window) Release() { func (w *Window) Frame(frame *op.Ops) error { return contextDo(w.ctx, func() error { w.gpu.Clear(color.NRGBA{}) - w.gpu.Collect(w.size, frame) - return w.gpu.Frame(driver.RenderTarget(w.fbo)) + return w.gpu.Frame(frame, driver.RenderTarget(w.fbo), w.size) }) } diff --git a/io/system/system.go b/io/system/system.go index f1279f9a..e1458252 100644 --- a/io/system/system.go +++ b/io/system/system.go @@ -26,27 +26,8 @@ type FrameEvent struct { Size image.Point // Insets is the insets to apply. Insets Insets - // Frame is the callback to supply the list of - // operations to complete the FrameEvent. - // - // 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 completes the FrameEvent by drawing the graphical operations + // from ops into the window. Frame func(frame *op.Ops) // Queue supplies the events for event handlers. Queue event.Queue diff --git a/op/paint/paint.go b/op/paint/paint.go index 7eed07cb..be090cf5 100644 --- a/op/paint/paint.go +++ b/op/paint/paint.go @@ -16,9 +16,6 @@ import ( ) // 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 { uniform bool color color.NRGBA @@ -47,9 +44,7 @@ type LinearGradientOp struct { type PaintOp struct { } -// NewImageOp creates an ImageOp backed by src. See -// gioui.org/io/system.FrameEvent for a description of when data -// referenced by operations is safe to re-use. +// NewImageOp creates an ImageOp backed by src. // // NewImageOp assumes the backing image is immutable, and may cache a // copy of its contents in a GPU-friendly way. Create new ImageOps to