diff --git a/gpu/compute.go b/gpu/compute.go index 7f3b744d..50e81460 100644 --- a/gpu/compute.go +++ b/gpu/compute.go @@ -280,7 +280,7 @@ func (g *compute) Frame() error { Y: (viewport.Y + tileHeightPx - 1) / tileHeightPx, } - defFBO := g.ctx.BeginFrame(viewport) + defFBO := g.ctx.BeginFrame(g.drawOps.clear, viewport) defer g.ctx.EndFrame() if g.drawOps.profile && g.timers.t == nil && g.ctx.Caps().Features.Has(driver.FeatureTimers) { diff --git a/gpu/gpu.go b/gpu/gpu.go index 9ca9fa02..0e44f2fc 100644 --- a/gpu/gpu.go +++ b/gpu/gpu.go @@ -426,7 +426,7 @@ func (g *gpu) Collect(viewport image.Point, frameOps *op.Ops) { func (g *gpu) Frame() error { viewport := g.renderer.blitter.viewport - defFBO := g.ctx.BeginFrame(viewport) + defFBO := g.ctx.BeginFrame(g.drawOps.clear, viewport) defer g.ctx.EndFrame() for _, img := range g.drawOps.imageOps { expandPathOp(img.path, img.clip) diff --git a/gpu/headless/driver_test.go b/gpu/headless/driver_test.go index 98e209ce..a0b69389 100644 --- a/gpu/headless/driver_test.go +++ b/gpu/headless/driver_test.go @@ -174,7 +174,7 @@ func newDriver(t *testing.T) driver.Device { if err != nil { t.Fatal(err) } - b.BeginFrame(image.Pt(1, 1)) + b.BeginFrame(true, image.Pt(1, 1)) t.Cleanup(func() { b.EndFrame() ctx.ReleaseCurrent() diff --git a/gpu/internal/d3d11/d3d11_windows.go b/gpu/internal/d3d11/d3d11_windows.go index 50fb77de..c06fbcc9 100644 --- a/gpu/internal/d3d11/d3d11_windows.go +++ b/gpu/internal/d3d11/d3d11_windows.go @@ -164,7 +164,7 @@ func newDirect3D11Device(api driver.Direct3D11) (driver.Device, error) { return b, nil } -func (b *Backend) BeginFrame(viewport image.Point) driver.Framebuffer { +func (b *Backend) BeginFrame(clear bool, viewport image.Point) driver.Framebuffer { renderTarget, depthView := b.ctx.OMGetRenderTargets() // Assume someone else is holding on to the render targets. if renderTarget != nil { diff --git a/gpu/internal/driver/driver.go b/gpu/internal/driver/driver.go index 97dbcf78..aa6a57e7 100644 --- a/gpu/internal/driver/driver.go +++ b/gpu/internal/driver/driver.go @@ -12,7 +12,7 @@ import ( // APIs such as OpenGL, Direct3D useful for rendering Gio // operations. type Device interface { - BeginFrame(viewport image.Point) Framebuffer + BeginFrame(clear bool, viewport image.Point) Framebuffer EndFrame() Caps() Caps NewTimer() Timer diff --git a/gpu/internal/opengl/opengl.go b/gpu/internal/opengl/opengl.go index f02113a8..8e0a4f39 100644 --- a/gpu/internal/opengl/opengl.go +++ b/gpu/internal/opengl/opengl.go @@ -19,6 +19,7 @@ import ( type Backend struct { funcs *gl.Functions + clear bool state glstate glver [2]int @@ -171,7 +172,8 @@ func newOpenGLDevice(api driver.OpenGL) (driver.Device, error) { return b, nil } -func (b *Backend) BeginFrame(viewport image.Point) driver.Framebuffer { +func (b *Backend) BeginFrame(clear bool, viewport image.Point) driver.Framebuffer { + b.clear = clear // Assume GL state is reset between frames. b.state = glstate{} b.defFBO = gl.Framebuffer(b.funcs.GetBinding(gl.FRAMEBUFFER_BINDING)) @@ -198,6 +200,9 @@ func (b *Backend) BeginFrame(viewport image.Point) driver.Framebuffer { renderFBO = b.sRGBFBO.Framebuffer() } b.funcs.BindFramebuffer(gl.FRAMEBUFFER, renderFBO) + if b.sRGBFBO != nil && !clear { + b.Clear(0, 0, 0, 0) + } return &gpuFramebuffer{backend: b, obj: renderFBO, foreign: true} } @@ -205,8 +210,15 @@ func (b *Backend) EndFrame() { b.funcs.ActiveTexture(gl.TEXTURE0) if b.sRGBFBO != nil { b.funcs.BindFramebuffer(gl.FRAMEBUFFER, b.defFBO) + if b.clear { + b.SetBlend(false) + } else { + b.BlendFunc(driver.BlendFactorOne, driver.BlendFactorOneMinusSrcAlpha) + b.SetBlend(true) + } b.sRGBFBO.Blit() } + b.SetBlend(false) b.funcs.BindFramebuffer(gl.FRAMEBUFFER, b.defFBO) }