~eliasnaur/gio

84b586ae6ce6de14f9310425dc948c5ab3c5df5d — Elias Naur 3 years ago 686d680
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>
5 files changed, 35 insertions(+), 6 deletions(-)

M app/headless/headless.go
M app/loop.go
M gpu/compute.go
M gpu/gpu.go
M internal/rendertest/util_test.go
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) {