mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-01 07:35:40 +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 {
|
||||
ctx Backend
|
||||
defFBO Framebuffer
|
||||
indexBufQuads int
|
||||
prog Program
|
||||
iprog Program
|
||||
fbos fboSet
|
||||
@@ -70,6 +69,11 @@ var (
|
||||
intersectAttribs = []string{"pos", "uv"}
|
||||
)
|
||||
|
||||
const (
|
||||
// Number of path quads per draw batch.
|
||||
pathBatchSize = 10000
|
||||
)
|
||||
|
||||
const (
|
||||
attribPathCorner = 0
|
||||
attribPathMaxY = 1
|
||||
@@ -128,6 +132,19 @@ func newStenciler(ctx Backend) *stenciler {
|
||||
}
|
||||
coverLoc := iprog.UniformFor("cover")
|
||||
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{
|
||||
ctx: ctx,
|
||||
defFBO: defFBO,
|
||||
@@ -138,7 +155,7 @@ func newStenciler(ctx Backend) *stenciler {
|
||||
uPathOffset: prog.UniformFor("pathOffset"),
|
||||
uIntersectUVScale: iprog.UniformFor("uvScale"),
|
||||
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
|
||||
for start < nquads {
|
||||
batch := nquads - start
|
||||
if max := int(^uint16(0)) / 6; batch > max {
|
||||
if max := pathBatchSize; 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
|
||||
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)))
|
||||
|
||||
Reference in New Issue
Block a user