forked from joejulian/gio
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:
+9
-15
@@ -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)
|
||||||
|
|||||||
@@ -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]
|
||||||
|
|||||||
Reference in New Issue
Block a user