From 7fba3bb8feedf907bc4ffd71f0bd6e43f4474fef Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Sun, 15 Mar 2020 12:20:19 +0100 Subject: [PATCH] gpu/backend: remove clear color and depth state Specifying the clear color and depth at the time of clearing is less error prone and a better for modern GPU APIs. As a bonus, we can get rid of the BufferAttachment type. Signed-off-by: Elias Naur --- app/headless/backend_test.go | 16 +++++++--------- app/internal/d3d11/backend_windows.go | 23 ++++++++--------------- app/internal/d3d11/d3d11_windows.go | 2 +- gpu/backend/backend.go | 10 +--------- gpu/gl/backend.go | 17 ++++------------- gpu/gpu.go | 7 +++---- gpu/path.go | 2 -- 7 files changed, 24 insertions(+), 53 deletions(-) diff --git a/app/headless/backend_test.go b/app/headless/backend_test.go index c1e97f24..4c652e1b 100644 --- a/app/headless/backend_test.go +++ b/app/headless/backend_test.go @@ -110,12 +110,10 @@ func TestFramebuffers(t *testing.T) { col2 = color.RGBA{R: 0xfe, G: 0xba, B: 0xbe, A: 0xca} ) fcol1, fcol2 := f32color.RGBAFromSRGB(col1), f32color.RGBAFromSRGB(col2) - b.ClearColor(fcol1.Float32()) b.BindFramebuffer(fbo1) - b.Clear(backend.BufferAttachmentColor) - b.ClearColor(fcol2.Float32()) + b.Clear(fcol1.Float32()) b.BindFramebuffer(fbo2) - b.Clear(backend.BufferAttachmentColor) + b.Clear(fcol2.Float32()) img := screenshot(t, fbo1, sz) if got := img.RGBAAt(0, 0); got != col1 { t.Errorf("got color %v, expected %v", got, col1) @@ -129,7 +127,11 @@ func TestFramebuffers(t *testing.T) { func setupFBO(t *testing.T, b backend.Device, size image.Point) backend.Framebuffer { fbo := newFBO(t, b, size) b.BindFramebuffer(fbo) - b.Clear(backend.BufferAttachmentColor | backend.BufferAttachmentDepth) + // ClearColor accepts linear RGBA colors, while 8-bit colors + // are in the sRGB color space. + col := f32color.RGBAFromSRGB(clearCol) + b.Clear(col.Float32()) + b.ClearDepth(0.0) b.Viewport(0, 0, size.X, size.Y) return fbo } @@ -172,10 +174,6 @@ func newBackend(t *testing.T) backend.Device { t.Fatal(err) } b.BeginFrame() - // ClearColor accepts linear RGBA colors, while 8-bit colors - // are in the sRGB color space. - col := f32color.RGBAFromSRGB(clearCol) - b.ClearColor(col.Float32()) t.Cleanup(func() { b.EndFrame() ctx.ReleaseCurrent() diff --git a/app/internal/d3d11/backend_windows.go b/app/internal/d3d11/backend_windows.go index 049f275f..fc9e0df5 100644 --- a/app/internal/d3d11/backend_windows.go +++ b/app/internal/d3d11/backend_windows.go @@ -10,7 +10,6 @@ import ( "unsafe" "gioui.org/gpu/backend" - "gioui.org/internal/f32color" gunsafe "gioui.org/internal/unsafe" "golang.org/x/sys/windows" ) @@ -27,8 +26,8 @@ type Device struct { } type Backend struct { - clearColor f32color.RGBA - clearDepth float32 + // Temporary storage to avoid garbage. + clearColor [4]float32 viewport _D3D11_VIEWPORT depthState depthState blendState blendState @@ -539,16 +538,14 @@ func (b *Backend) NewProgram(vertexShader, fragmentShader backend.ShaderSources) return p, nil } -func (b *Backend) ClearColor(colr, colg, colb, cola float32) { - b.clearColor = f32color.RGBA{R: colr, G: colg, B: colb, A: cola} +func (b *Backend) Clear(colr, colg, colb, cola float32) { + b.clearColor = [4]float32{colr, colg, colb, cola} + b.dev.ctx.ClearRenderTargetView(b.fbo.renderTarget, &b.clearColor) } -func (b *Backend) Clear(buffers backend.BufferAttachments) { - if buffers&backend.BufferAttachmentColor != 0 { - b.dev.ctx.ClearRenderTargetView(b.fbo.renderTarget, &b.clearColor) - } - if buffers&backend.BufferAttachmentDepth != 0 && b.fbo.depthView != nil { - b.dev.ctx.ClearDepthStencilView(b.fbo.depthView, _D3D11_CLEAR_DEPTH|_D3D11_CLEAR_STENCIL, b.clearDepth, 0) +func (b *Backend) ClearDepth(depth float32) { + if b.fbo.depthView != nil { + b.dev.ctx.ClearDepthStencilView(b.fbo.depthView, _D3D11_CLEAR_DEPTH|_D3D11_CLEAR_STENCIL, depth, 0) } } @@ -650,10 +647,6 @@ func (b *Backend) DepthFunc(f backend.DepthFunc) { b.depthState.fn = f } -func (b *Backend) ClearDepth(d float32) { - b.clearDepth = d -} - func (b *Backend) SetBlend(enable bool) { b.blendState.enable = enable } diff --git a/app/internal/d3d11/d3d11_windows.go b/app/internal/d3d11/d3d11_windows.go index 6c65adf5..5c1e36bc 100644 --- a/app/internal/d3d11/d3d11_windows.go +++ b/app/internal/d3d11/d3d11_windows.go @@ -1034,7 +1034,7 @@ func (c *_ID3D11DeviceContext) ClearDepthStencilView(target *_ID3D11DepthStencil ) } -func (c *_ID3D11DeviceContext) ClearRenderTargetView(target *_ID3D11RenderTargetView, color *f32color.RGBA) { +func (c *_ID3D11DeviceContext) ClearRenderTargetView(target *_ID3D11RenderTargetView, color *[4]float32) { syscall.Syscall( c.vtbl.ClearRenderTargetView, 3, diff --git a/gpu/backend/backend.go b/gpu/backend/backend.go index 8cd187b5..9ece5510 100644 --- a/gpu/backend/backend.go +++ b/gpu/backend/backend.go @@ -27,9 +27,8 @@ type Device interface { NewInputLayout(vertexShader ShaderSources, layout []InputDesc) (InputLayout, error) DepthFunc(f DepthFunc) - ClearColor(r, g, b, a float32) ClearDepth(d float32) - Clear(buffers BufferAttachments) + Clear(r, g, b, a float32) Viewport(x, y, width, height int) DrawArrays(mode DrawMode, off, count int) DrawElements(mode DrawMode, off, count int) @@ -110,8 +109,6 @@ type BlendFactor uint8 type DrawMode uint8 -type BufferAttachments uint - type TextureFilter uint8 type TextureFormat uint8 @@ -157,11 +154,6 @@ type Texture interface { Release() } -const ( - BufferAttachmentColor BufferAttachments = 1 << iota - BufferAttachmentDepth -) - const ( DepthFuncGreater DepthFunc = iota ) diff --git a/gpu/gl/backend.go b/gpu/gl/backend.go index 20c6f747..e7ce1e20 100644 --- a/gpu/gl/backend.go +++ b/gpu/gl/backend.go @@ -385,23 +385,14 @@ func (b *Backend) Viewport(x, y, width, height int) { b.funcs.Viewport(x, y, width, height) } -func (b *Backend) Clear(attachments backend.BufferAttachments) { - var mask Enum - if attachments&backend.BufferAttachmentColor != 0 { - mask |= COLOR_BUFFER_BIT - } - if attachments&backend.BufferAttachmentDepth != 0 { - mask |= DEPTH_BUFFER_BIT - } - b.funcs.Clear(mask) +func (b *Backend) Clear(colR, colG, colB, colA float32) { + b.funcs.ClearColor(colR, colG, colB, colA) + b.funcs.Clear(COLOR_BUFFER_BIT) } func (b *Backend) ClearDepth(d float32) { b.funcs.ClearDepthf(d) -} - -func (b *Backend) ClearColor(colR, colG, colB, colA float32) { - b.funcs.ClearColor(colR, colG, colB, colA) + b.funcs.Clear(DEPTH_BUFFER_BIT) } func (b *Backend) DepthFunc(f backend.DepthFunc) { diff --git a/gpu/gpu.go b/gpu/gpu.go index ef4c782b..1010ff3d 100644 --- a/gpu/gpu.go +++ b/gpu/gpu.go @@ -335,9 +335,8 @@ func (g *GPU) BeginFrame() { } g.ctx.BindFramebuffer(g.defFBO) g.ctx.DepthFunc(backend.DepthFuncGreater) - g.ctx.ClearColor(g.drawOps.clearColor.Float32()) g.ctx.ClearDepth(0.0) - g.ctx.Clear(backend.BufferAttachmentColor | backend.BufferAttachmentDepth) + g.ctx.Clear(g.drawOps.clearColor.Float32()) g.ctx.Viewport(0, 0, viewport.X, viewport.Y) g.renderer.drawZOps(g.drawOps.zimageOps) g.zopsTimer.end() @@ -502,7 +501,7 @@ func (r *renderer) stencilClips(pathCache *opCache, ops []*pathOp) { fbo = p.place.Idx f := r.pather.stenciler.cover(fbo) r.ctx.BindFramebuffer(f.fbo) - r.ctx.Clear(backend.BufferAttachmentColor) + r.ctx.Clear(0.0, 0.0, 0.0, 0.0) } data, _ := pathCache.get(p.pathKey) r.pather.stencilPath(p.clip, p.off, p.place.Pos, data.(*pathData)) @@ -525,7 +524,7 @@ func (r *renderer) intersect(ops []imageOp) { fbo = img.place.Idx f := r.pather.stenciler.intersections.fbos[fbo] r.ctx.BindFramebuffer(f.fbo) - r.ctx.Clear(backend.BufferAttachmentColor) + r.ctx.Clear(1.0, 0.0, 0.0, 0.0) } r.ctx.Viewport(img.place.Pos.X, img.place.Pos.Y, img.clip.Dx(), img.clip.Dy()) r.intersectPath(img.path, img.clip) diff --git a/gpu/path.go b/gpu/path.go index 9c028c88..73e72f50 100644 --- a/gpu/path.go +++ b/gpu/path.go @@ -292,7 +292,6 @@ func (s *stenciler) beginIntersect(sizes []image.Point) { // floating point formats. Replace with GL_RGB+GL_UNSIGNED_BYTE if // no floating point support is available. s.intersections.resize(s.ctx, sizes) - s.ctx.ClearColor(1.0, 0.0, 0.0, 0.0) s.ctx.BindProgram(s.iprog.prog.prog) } @@ -308,7 +307,6 @@ func (s *stenciler) cover(idx int) stencilFBO { func (s *stenciler) begin(sizes []image.Point) { s.ctx.BlendFunc(backend.BlendFactorOne, backend.BlendFactorOne) s.fbos.resize(s.ctx, sizes) - s.ctx.ClearColor(0.0, 0.0, 0.0, 0.0) s.ctx.BindProgram(s.prog.prog.prog) s.ctx.BindInputLayout(s.prog.layout) s.ctx.BindIndexBuffer(s.indexBuf)