From 818d0c4af1f83a87dc81ec39c539c5e6148fe5a5 Mon Sep 17 00:00:00 2001 From: Viktor Date: Sat, 20 Jun 2020 23:29:58 +0200 Subject: [PATCH] gpu: cache transformed bounds To avoid duplicate work when using macros and non-offset transforms, cache also the new bounding boxes set up for them. The ops.Reader already generates Keys for all operations, so use them in the cache. Signed-off-by: Viktor --- gpu/gpu.go | 24 +++++++++--------------- internal/ops/reader.go | 4 ---- 2 files changed, 9 insertions(+), 19 deletions(-) diff --git a/gpu/gpu.go b/gpu/gpu.go index 6a6abe43..cd87f2a2 100644 --- a/gpu/gpu.go +++ b/gpu/gpu.go @@ -60,12 +60,11 @@ type drawOps struct { // zimageOps are the rectangle clipped opaque images // that can use fast front-to-back rendering with z-test // and no blending. - zimageOps []imageOp - pathOps []*pathOp - pathOpCache []pathOp - qs quadSplitter - pathCache *opCache - uniqueKeyCounter int + zimageOps []imageOp + pathOps []*pathOp + pathOpCache []pathOp + qs quadSplitter + pathCache *opCache } type drawState struct { @@ -704,13 +703,6 @@ func (d *drawOps) addClipPath(state *drawState, aux []byte, auxKey ops.Key, boun } } -// noCacheKey creates a new key for caches, but one that is unique and -// thus will never lead to re-use. -func (d *drawOps) noCacheKey() ops.Key { - d.uniqueKeyCounter-- - return d.reader.NewKey(d.uniqueKeyCounter) -} - // split a transform into two parts, one which is pur offset and the // other representing the scaling, shearing and rotation part func splitTransform(t f32.Affine2D) (srs f32.Affine2D, offset f32.Point) { @@ -756,7 +748,8 @@ loop: } } else { aux, op.bounds, _ = d.boundsForTransformedRect(bounds, trans) - auxKey = d.noCacheKey() + auxKey = encOp.Key + auxKey.SetTransform(trans) } state.clip = state.clip.Intersect(op.bounds.Add(off)) if state.clip.Empty() { @@ -787,7 +780,8 @@ loop: if clipData != nil { // The paint operation is sheared or rotated, add a clip path representing // this transformed rectangle. - d.addClipPath(&state, clipData, d.noCacheKey(), bnd, off) + encOp.Key.SetTransform(trans) + d.addClipPath(&state, clipData, encOp.Key, bnd, off) } bounds := boundRectF(clip) diff --git a/internal/ops/reader.go b/internal/ops/reader.go index 7e607281..cf768c01 100644 --- a/internal/ops/reader.go +++ b/internal/ops/reader.go @@ -54,10 +54,6 @@ type opMacroDef struct { endpc pc } -func (r *Reader) NewKey(pc int) Key { - return Key{ops: r.ops, pc: pc, version: r.ops.Version()} -} - // Reset start reading from the op list. func (r *Reader) Reset(ops *op.Ops) { r.stack = r.stack[:0]