~eliasnaur/gio

7fba3bb8feedf907bc4ffd71f0bd6e43f4474fef — Elias Naur 24 days ago daecdca
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 <mail@eliasnaur.com>
M app/headless/backend_test.go => app/headless/backend_test.go +7 -9
@@ 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()

M app/internal/d3d11/backend_windows.go => app/internal/d3d11/backend_windows.go +8 -15
@@ 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
}

M app/internal/d3d11/d3d11_windows.go => app/internal/d3d11/d3d11_windows.go +1 -1
@@ 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,

M gpu/backend/backend.go => gpu/backend/backend.go +1 -9
@@ 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



@@ 158,11 155,6 @@ type Texture interface {
}

const (
	BufferAttachmentColor BufferAttachments = 1 << iota
	BufferAttachmentDepth
)

const (
	DepthFuncGreater DepthFunc = iota
)


M gpu/gl/backend.go => gpu/gl/backend.go +4 -13
@@ 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) {

M gpu/gpu.go => gpu/gpu.go +3 -4
@@ 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)

M gpu/path.go => gpu/path.go +0 -2
@@ 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)