gpu: don't automatically clear screen before rendering

Gio UI may be overlaid on top of custom graphics such as in the glfw example.
That will only work if Gio doesn't clear the screen (to white).

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2021-01-22 18:33:34 +01:00
parent 686d680ea3
commit 84b586ae6c
5 changed files with 35 additions and 6 deletions
+2
View File
@@ -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()
})
+2
View File
@@ -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{}{}
+10 -2
View File
@@ -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)
}
+20 -3
View File
@@ -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++
+1 -1
View File
@@ -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) {