M app/headless/headless.go => app/headless/headless.go +2 -0
@@ 6,6 6,7 @@ package headless
import (
"image"
+ "image/color"
"runtime"
"gioui.org/gpu"
@@ 108,6 109,7 @@ func (w *Window) Release() {
// operation list.
func (w *Window) Frame(frame *op.Ops) error {
return contextDo(w.ctx, func() error {
+ w.gpu.Clear(color.NRGBA{A: 0xff, R: 0xff, G: 0xff, B: 0xff})
w.gpu.Collect(w.size, frame)
return w.gpu.Frame()
})
M app/loop.go => app/loop.go +2 -0
@@ 4,6 4,7 @@ package app
import (
"image"
+ "image/color"
"runtime"
"gioui.org/app/internal/window"
@@ 85,6 86,7 @@ func (l *renderLoop) renderLoop(ctx window.Context) error {
l.refreshErr <- ctx.MakeCurrent()
case frame := <-l.frames:
ctx.Lock()
+ g.Clear(color.NRGBA{A: 0xff, R: 0xff, G: 0xff, B: 0xff})
g.Collect(frame.viewport, frame.ops)
// Signal that we're done with the frame ops.
l.ack <- struct{}{}
M gpu/compute.go => gpu/compute.go +10 -2
@@ 230,6 230,11 @@ func (g *compute) Collect(viewport image.Point, ops *op.Ops) {
}
}
+func (g *compute) Clear(col color.NRGBA) {
+ g.drawOps.clear = true
+ g.drawOps.clearColor = f32color.LinearFromSRGB(col)
+}
+
func (g *compute) Frame() error {
viewport := g.drawOps.viewport
tileDims := image.Point{
@@ 285,8 290,11 @@ func (g *compute) encode(viewport image.Point) {
// Flip Y-axis.
flipY := f32.Affine2D{}.Scale(f32.Pt(0, 0), f32.Pt(1, -1)).Offset(f32.Pt(0, float32(viewport.Y)))
g.enc.transform(flipY)
- g.enc.rect(f32.Rectangle{Max: layout.FPt(viewport)}, false)
- g.enc.fill(f32color.NRGBAToRGBA(g.drawOps.clearColor.SRGB()))
+ if g.drawOps.clear {
+ g.drawOps.clear = false
+ g.enc.rect(f32.Rectangle{Max: layout.FPt(viewport)}, false)
+ g.enc.fill(f32color.NRGBAToRGBA(g.drawOps.clearColor.SRGB()))
+ }
g.encodeOps(flipY, viewport, g.drawOps.allImageOps)
}
M gpu/gpu.go => gpu/gpu.go +20 -3
@@ 31,9 31,17 @@ import (
)
type GPU interface {
+ // Release non-Go resources. The GPU is no longer valid after Release.
Release()
- Collect(viewport image.Point, frameOps *op.Ops)
+ // 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 clears the color buffer and draws the collected operations.
Frame() error
+ // Profile returns the last available profiling information. Profiling
+ // information is requested when Collect sees a ProfileOp, and the result
+ // is available through Profile at some later time.
Profile() string
}
@@ 65,6 73,7 @@ type drawOps struct {
cache *resourceCache
vertCache []byte
viewport image.Point
+ clear bool
clearColor f32color.RGBA
// allImageOps is the combined list of imageOps and
// zimageOps, in drawing order.
@@ 404,6 413,11 @@ func (g *gpu) init(ctx backend.Device) error {
return nil
}
+func (g *gpu) Clear(col color.NRGBA) {
+ g.drawOps.clear = true
+ g.drawOps.clearColor = f32color.LinearFromSRGB(col)
+}
+
func (g *gpu) Release() {
g.renderer.release()
g.drawOps.pathCache.release()
@@ 442,7 456,10 @@ func (g *gpu) Frame() error {
g.ctx.DepthFunc(backend.DepthFuncGreater)
// Note that Clear must be before ClearDepth if nothing else is rendered
// (len(zimageOps) == 0). If not, the Fairphone 2 will corrupt the depth buffer.
- g.ctx.Clear(g.drawOps.clearColor.Float32())
+ if g.drawOps.clear {
+ g.drawOps.clear = false
+ g.ctx.Clear(g.drawOps.clearColor.Float32())
+ }
g.ctx.ClearDepth(0.0)
g.ctx.Viewport(0, 0, viewport.X, viewport.Y)
g.renderer.drawZOps(g.cache, g.drawOps.zimageOps)
@@ 799,7 816,6 @@ func floor(v float32) int {
func (d *drawOps) reset(cache *resourceCache, viewport image.Point) {
d.profile = false
- d.clearColor = f32color.RGBA{R: 1.0, G: 1.0, B: 1.0, A: 1.0}
d.cache = cache
d.viewport = viewport
d.imageOps = d.imageOps[:0]
@@ 1006,6 1022,7 @@ loop:
d.imageOps = d.imageOps[:0]
z = 0
d.clearColor = mat.color.Opaque()
+ d.clear = true
continue
}
z++
M internal/rendertest/util_test.go => internal/rendertest/util_test.go +1 -1
@@ 161,7 161,7 @@ func verifyRef(t *testing.T, img *image.RGBA, frame int) (ok bool) {
}
ref, ok := r.(*image.RGBA)
if !ok {
- t.Error("ref image note RGBA")
+ t.Errorf("image is a %T, expected *image.RGBA", r)
return
}
if len(ref.Pix) != len(img.Pix) {