mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-05 17:35:36 +00:00
gpu: allocate path draw index buffer once
Before this change, the index buffer would start empty and grow up to the maximum size (128kb). It would never shrink. We're about to tighten the GPU buffer API to be immutable for performance and to better match Direct3D, so allocate the index buffer once at startup, and limit it to a reasonable size. Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
+20
-18
@@ -38,7 +38,6 @@ type coverer struct {
|
|||||||
type stenciler struct {
|
type stenciler struct {
|
||||||
ctx Backend
|
ctx Backend
|
||||||
defFBO Framebuffer
|
defFBO Framebuffer
|
||||||
indexBufQuads int
|
|
||||||
prog Program
|
prog Program
|
||||||
iprog Program
|
iprog Program
|
||||||
fbos fboSet
|
fbos fboSet
|
||||||
@@ -70,6 +69,11 @@ var (
|
|||||||
intersectAttribs = []string{"pos", "uv"}
|
intersectAttribs = []string{"pos", "uv"}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Number of path quads per draw batch.
|
||||||
|
pathBatchSize = 10000
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
attribPathCorner = 0
|
attribPathCorner = 0
|
||||||
attribPathMaxY = 1
|
attribPathMaxY = 1
|
||||||
@@ -128,6 +132,19 @@ func newStenciler(ctx Backend) *stenciler {
|
|||||||
}
|
}
|
||||||
coverLoc := iprog.UniformFor("cover")
|
coverLoc := iprog.UniformFor("cover")
|
||||||
iprog.Uniform1i(coverLoc, 0)
|
iprog.Uniform1i(coverLoc, 0)
|
||||||
|
// Allocate a suitably large index buffer for drawing paths.
|
||||||
|
indices := make([]uint16, pathBatchSize*6)
|
||||||
|
for i := 0; i < pathBatchSize; i++ {
|
||||||
|
i := uint16(i)
|
||||||
|
indices[i*6+0] = i*4 + 0
|
||||||
|
indices[i*6+1] = i*4 + 1
|
||||||
|
indices[i*6+2] = i*4 + 2
|
||||||
|
indices[i*6+3] = i*4 + 2
|
||||||
|
indices[i*6+4] = i*4 + 1
|
||||||
|
indices[i*6+5] = i*4 + 3
|
||||||
|
}
|
||||||
|
indexBuf := ctx.NewBuffer(BufferTypeIndices)
|
||||||
|
indexBuf.Upload(BufferUsageStaticDraw, gunsafe.BytesView(indices))
|
||||||
return &stenciler{
|
return &stenciler{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
defFBO: defFBO,
|
defFBO: defFBO,
|
||||||
@@ -138,7 +155,7 @@ func newStenciler(ctx Backend) *stenciler {
|
|||||||
uPathOffset: prog.UniformFor("pathOffset"),
|
uPathOffset: prog.UniformFor("pathOffset"),
|
||||||
uIntersectUVScale: iprog.UniformFor("uvScale"),
|
uIntersectUVScale: iprog.UniformFor("uvScale"),
|
||||||
uIntersectUVOffset: iprog.UniformFor("uvOffset"),
|
uIntersectUVOffset: iprog.UniformFor("uvOffset"),
|
||||||
indexBuf: ctx.NewBuffer(BufferTypeIndices),
|
indexBuf: indexBuf,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,24 +291,9 @@ func (s *stenciler) stencilPath(bounds image.Rectangle, offset f32.Point, uv ima
|
|||||||
nquads := data.ncurves / 4
|
nquads := data.ncurves / 4
|
||||||
for start < nquads {
|
for start < nquads {
|
||||||
batch := nquads - start
|
batch := nquads - start
|
||||||
if max := int(^uint16(0)) / 6; batch > max {
|
if max := pathBatchSize; batch > max {
|
||||||
batch = max
|
batch = max
|
||||||
}
|
}
|
||||||
// Enlarge VBO if necessary.
|
|
||||||
if batch > s.indexBufQuads {
|
|
||||||
indices := make([]uint16, batch*6)
|
|
||||||
for i := 0; i < batch; i++ {
|
|
||||||
i := uint16(i)
|
|
||||||
indices[i*6+0] = i*4 + 0
|
|
||||||
indices[i*6+1] = i*4 + 1
|
|
||||||
indices[i*6+2] = i*4 + 2
|
|
||||||
indices[i*6+3] = i*4 + 2
|
|
||||||
indices[i*6+4] = i*4 + 1
|
|
||||||
indices[i*6+5] = i*4 + 3
|
|
||||||
}
|
|
||||||
s.indexBuf.Upload(BufferUsageStaticDraw, gunsafe.BytesView(indices))
|
|
||||||
s.indexBufQuads = batch
|
|
||||||
}
|
|
||||||
off := path.VertStride * start * 4
|
off := path.VertStride * start * 4
|
||||||
s.ctx.SetupVertexArray(attribPathCorner, 2, DataTypeShort, path.VertStride, off+int(unsafe.Offsetof((*(*path.Vertex)(nil)).CornerX)))
|
s.ctx.SetupVertexArray(attribPathCorner, 2, DataTypeShort, path.VertStride, off+int(unsafe.Offsetof((*(*path.Vertex)(nil)).CornerX)))
|
||||||
s.ctx.SetupVertexArray(attribPathMaxY, 1, DataTypeFloat, path.VertStride, off+int(unsafe.Offsetof((*(*path.Vertex)(nil)).MaxY)))
|
s.ctx.SetupVertexArray(attribPathMaxY, 1, DataTypeFloat, path.VertStride, off+int(unsafe.Offsetof((*(*path.Vertex)(nil)).MaxY)))
|
||||||
|
|||||||
Reference in New Issue
Block a user