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