gpu: move drawState.clip to pathOp

The clip field tracks the intersection of the clip stack, and belongs in
the clip stack entries. This is a refactor that makes it easier to
implement scoped clip operations.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2021-10-02 19:36:02 +02:00
parent a96c68fed1
commit 8ebea5ad1f
+21 -13
View File
@@ -89,7 +89,6 @@ type drawOps struct {
} }
type drawState struct { type drawState struct {
clip f32.Rectangle
t f32.Affine2D t f32.Affine2D
cpath *pathOp cpath *pathOp
@@ -113,8 +112,11 @@ type pathOp struct {
rect bool rect bool
// clip is the union of all // clip is the union of all
// later clip rectangles. // later clip rectangles.
clip image.Rectangle clip image.Rectangle
bounds f32.Rectangle bounds f32.Rectangle
// intersect is the intersection of bounds and all
// previous clip bounds.
intersect f32.Rectangle
pathKey opKey pathKey opKey
path bool path bool
pathVerts []byte pathVerts []byte
@@ -823,15 +825,14 @@ func (d *drawOps) reset(cache *resourceCache, viewport image.Point) {
} }
func (d *drawOps) collect(root *op.Ops, viewport image.Point) { func (d *drawOps) collect(root *op.Ops, viewport image.Point) {
clip := f32.Rectangle{ viewf := f32.Rectangle{
Max: f32.Point{X: float32(viewport.X), Y: float32(viewport.Y)}, Max: f32.Point{X: float32(viewport.X), Y: float32(viewport.Y)},
} }
d.reader.Reset(root) d.reader.Reset(root)
state := drawState{ state := drawState{
clip: clip,
color: color.NRGBA{A: 0xff}, color: color.NRGBA{A: 0xff},
} }
d.collectOps(&d.reader, state) d.collectOps(&d.reader, viewf, state)
} }
func (d *drawOps) buildPaths(ctx driver.Device) { func (d *drawOps) buildPaths(ctx driver.Device) {
@@ -855,10 +856,15 @@ func (d *drawOps) newPathOp() *pathOp {
func (d *drawOps) addClipPath(state *drawState, aux []byte, auxKey opKey, bounds f32.Rectangle, off f32.Point) { func (d *drawOps) addClipPath(state *drawState, aux []byte, auxKey opKey, bounds f32.Rectangle, off f32.Point) {
npath := d.newPathOp() npath := d.newPathOp()
*npath = pathOp{ *npath = pathOp{
parent: state.cpath, parent: state.cpath,
bounds: bounds, bounds: bounds,
off: off, off: off,
rect: npath.parent == nil || npath.parent.rect, intersect: bounds.Add(off),
rect: true,
}
if npath.parent != nil {
npath.rect = npath.parent.rect
npath.intersect = npath.parent.intersect.Intersect(npath.intersect)
} }
if len(aux) > 0 { if len(aux) > 0 {
npath.rect = false npath.rect = false
@@ -895,7 +901,7 @@ func (k opKey) SetTransform(t f32.Affine2D) opKey {
return k return k
} }
func (d *drawOps) collectOps(r *ops.Reader, state drawState) { func (d *drawOps) collectOps(r *ops.Reader, viewport f32.Rectangle, state drawState) {
var ( var (
quads quadsOp quads quadsOp
str clip.StrokeStyle str clip.StrokeStyle
@@ -950,7 +956,6 @@ loop:
quads.key = opKey{Key: encOp.Key} quads.key = opKey{Key: encOp.Key}
quads.key.SetTransform(trans) // TODO: This call has no effect. quads.key.SetTransform(trans) // TODO: This call has no effect.
} }
state.clip = state.clip.Intersect(op.bounds.Add(off))
d.addClipPath(&state, quads.aux, quads.key, op.bounds, off) d.addClipPath(&state, quads.aux, quads.key, op.bounds, off)
quads = quadsOp{} quads = quadsOp{}
str = clip.StrokeStyle{} str = clip.StrokeStyle{}
@@ -981,7 +986,10 @@ loop:
dst = layout.FRect(state.image.src.Rect) dst = layout.FRect(state.image.src.Rect)
} }
clipData, bnd, partialTrans := d.boundsForTransformedRect(dst, trans) clipData, bnd, partialTrans := d.boundsForTransformedRect(dst, trans)
cl := state.clip.Intersect(bnd.Add(off)) cl := viewport.Intersect(bnd.Add(off))
if state.cpath != nil {
cl = state.cpath.intersect.Intersect(cl)
}
if cl.Empty() { if cl.Empty() {
continue continue
} }