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 <viktor.ogeman@gmail.com>
This commit is contained in:
Viktor
2020-06-20 23:29:58 +02:00
committed by Elias Naur
parent 062cb210ea
commit 818d0c4af1
2 changed files with 9 additions and 19 deletions
+9 -15
View File
@@ -60,12 +60,11 @@ type drawOps struct {
// zimageOps are the rectangle clipped opaque images // zimageOps are the rectangle clipped opaque images
// that can use fast front-to-back rendering with z-test // that can use fast front-to-back rendering with z-test
// and no blending. // and no blending.
zimageOps []imageOp zimageOps []imageOp
pathOps []*pathOp pathOps []*pathOp
pathOpCache []pathOp pathOpCache []pathOp
qs quadSplitter qs quadSplitter
pathCache *opCache pathCache *opCache
uniqueKeyCounter int
} }
type drawState struct { 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 // split a transform into two parts, one which is pur offset and the
// other representing the scaling, shearing and rotation part // other representing the scaling, shearing and rotation part
func splitTransform(t f32.Affine2D) (srs f32.Affine2D, offset f32.Point) { func splitTransform(t f32.Affine2D) (srs f32.Affine2D, offset f32.Point) {
@@ -756,7 +748,8 @@ loop:
} }
} else { } else {
aux, op.bounds, _ = d.boundsForTransformedRect(bounds, trans) 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)) state.clip = state.clip.Intersect(op.bounds.Add(off))
if state.clip.Empty() { if state.clip.Empty() {
@@ -787,7 +780,8 @@ loop:
if clipData != nil { if clipData != nil {
// The paint operation is sheared or rotated, add a clip path representing // The paint operation is sheared or rotated, add a clip path representing
// this transformed rectangle. // 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) bounds := boundRectF(clip)
-4
View File
@@ -54,10 +54,6 @@ type opMacroDef struct {
endpc pc 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. // Reset start reading from the op list.
func (r *Reader) Reset(ops *op.Ops) { func (r *Reader) Reset(ops *op.Ops) {
r.stack = r.stack[:0] r.stack = r.stack[:0]