Skip to content

Commit 0b94e62

Browse files
committed
Use DisplayListMatrixClipTracker in DisplayListBuilder
1 parent bc1647f commit 0b94e62

File tree

4 files changed

+79
-80
lines changed

4 files changed

+79
-80
lines changed

display_list/display_list_builder.cc

Lines changed: 29 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -67,16 +67,16 @@ sk_sp<DisplayList> DisplayListBuilder::Build() {
6767
}
6868

6969
DisplayListBuilder::DisplayListBuilder(const SkRect& cull_rect,
70-
bool prepare_rtree) {
70+
bool prepare_rtree)
71+
: tracker_(cull_rect.isEmpty() ? SkRect::MakeEmpty() : cull_rect,
72+
SkMatrix::I()) {
7173
if (prepare_rtree) {
7274
accumulator_ = std::make_unique<RTreeBoundsAccumulator>();
7375
} else {
7476
accumulator_ = std::make_unique<RectBoundsAccumulator>();
7577
}
7678

77-
// isEmpty protects us against NaN as we normalize any empty cull rects
78-
SkRect cull = cull_rect.isEmpty() ? SkRect::MakeEmpty() : cull_rect;
79-
layer_stack_.emplace_back(SkM44(), SkMatrix::I(), cull);
79+
layer_stack_.emplace_back(LayerInfo());
8080
current_layer_ = &layer_stack_.back();
8181
}
8282

@@ -443,6 +443,7 @@ void DisplayListBuilder::save() {
443443
layer_stack_.emplace_back(current_layer_);
444444
current_layer_ = &layer_stack_.back();
445445
current_layer_->has_deferred_save_op_ = true;
446+
tracker_.save();
446447
accumulator()->save();
447448
}
448449

@@ -455,6 +456,7 @@ void DisplayListBuilder::restore() {
455456
// on the stack.
456457
LayerInfo layer_info = layer_stack_.back();
457458

459+
tracker_.restore();
458460
layer_stack_.pop_back();
459461
current_layer_ = &layer_stack_.back();
460462
bool is_unbounded = layer_info.is_unbounded();
@@ -463,7 +465,7 @@ void DisplayListBuilder::restore() {
463465
// current accumulator and adjust it as required based on the filter.
464466
std::shared_ptr<const DlImageFilter> filter = layer_info.filter();
465467
if (filter) {
466-
const SkRect* clip = &current_layer_->clip_bounds();
468+
const SkRect clip = tracker_.device_cull_rect();
467469
if (!accumulator()->restore(
468470
[filter = filter, matrix = getTransform()](const SkRect& input,
469471
SkRect& output) {
@@ -473,7 +475,7 @@ void DisplayListBuilder::restore() {
473475
output.set(output_bounds);
474476
return ret;
475477
},
476-
clip)) {
478+
&clip)) {
477479
is_unbounded = true;
478480
}
479481
} else {
@@ -549,6 +551,7 @@ void DisplayListBuilder::saveLayer(const SkRect* bounds,
549551
} else {
550552
layer_stack_.emplace_back(current_layer_, save_layer_offset, true, nullptr);
551553
}
554+
tracker_.save();
552555
accumulator()->save();
553556
current_layer_ = &layer_stack_.back();
554557
if (options.renders_with_attributes()) {
@@ -566,7 +569,7 @@ void DisplayListBuilder::saveLayer(const SkRect* bounds,
566569
// use them as the temporary layer bounds during rendering the layer, so
567570
// we set them as if a clip operation were performed.
568571
if (bounds) {
569-
intersect(*bounds);
572+
tracker_.clipRect(*bounds, SkClipOp::kIntersect, false);
570573
}
571574
if (backdrop) {
572575
// A backdrop will affect up to the entire surface, bounded by the clip
@@ -590,34 +593,30 @@ void DisplayListBuilder::translate(SkScalar tx, SkScalar ty) {
590593
(tx != 0.0 || ty != 0.0)) {
591594
checkForDeferredSave();
592595
Push<TranslateOp>(0, 1, tx, ty);
593-
current_layer_->matrix().preTranslate(tx, ty);
594-
current_layer_->update_matrix33();
596+
tracker_.translate(tx, ty);
595597
}
596598
}
597599
void DisplayListBuilder::scale(SkScalar sx, SkScalar sy) {
598600
if (SkScalarIsFinite(sx) && SkScalarIsFinite(sy) &&
599601
(sx != 1.0 || sy != 1.0)) {
600602
checkForDeferredSave();
601603
Push<ScaleOp>(0, 1, sx, sy);
602-
current_layer_->matrix().preScale(sx, sy);
603-
current_layer_->update_matrix33();
604+
tracker_.scale(sx, sy);
604605
}
605606
}
606607
void DisplayListBuilder::rotate(SkScalar degrees) {
607608
if (SkScalarMod(degrees, 360.0) != 0.0) {
608609
checkForDeferredSave();
609610
Push<RotateOp>(0, 1, degrees);
610-
current_layer_->matrix().preConcat(SkMatrix::RotateDeg(degrees));
611-
current_layer_->update_matrix33();
611+
tracker_.rotate(degrees);
612612
}
613613
}
614614
void DisplayListBuilder::skew(SkScalar sx, SkScalar sy) {
615615
if (SkScalarIsFinite(sx) && SkScalarIsFinite(sy) &&
616616
(sx != 0.0 || sy != 0.0)) {
617617
checkForDeferredSave();
618618
Push<SkewOp>(0, 1, sx, sy);
619-
current_layer_->matrix().preConcat(SkMatrix::Skew(sx, sy));
620-
current_layer_->update_matrix33();
619+
tracker_.skew(sx, sy);
621620
}
622621
}
623622

@@ -636,11 +635,10 @@ void DisplayListBuilder::transform2DAffine(
636635
Push<Transform2DAffineOp>(0, 1,
637636
mxx, mxy, mxt,
638637
myx, myy, myt);
639-
current_layer_->matrix().preConcat(SkM44(mxx, mxy, 0, mxt,
640-
myx, myy, 0, myt,
641-
0, 0, 1, 0,
642-
0, 0, 0, 1));
643-
current_layer_->update_matrix33();
638+
tracker_.transform(SkM44(mxx, mxy, 0, mxt,
639+
myx, myy, 0, myt,
640+
0, 0, 1, 0,
641+
0, 0, 0, 1));
644642
}
645643
}
646644
// full 4x4 transform in row major order
@@ -665,19 +663,17 @@ void DisplayListBuilder::transformFullPerspective(
665663
myx, myy, myz, myt,
666664
mzx, mzy, mzz, mzt,
667665
mwx, mwy, mwz, mwt);
668-
current_layer_->matrix().preConcat(SkM44(mxx, mxy, mxz, mxt,
669-
myx, myy, myz, myt,
670-
mzx, mzy, mzz, mzt,
671-
mwx, mwy, mwz, mwt));
672-
current_layer_->update_matrix33();
666+
tracker_.transform(SkM44(mxx, mxy, mxz, mxt,
667+
myx, myy, myz, myt,
668+
mzx, mzy, mzz, mzt,
669+
mwx, mwy, mwz, mwt));
673670
}
674671
}
675672
// clang-format on
676673
void DisplayListBuilder::transformReset() {
677674
checkForDeferredSave();
678675
Push<TransformResetOp>(0, 0);
679-
current_layer_->matrix().setIdentity();
680-
current_layer_->update_matrix33();
676+
tracker_.setIdentity();
681677
}
682678
void DisplayListBuilder::transform(const SkMatrix* matrix) {
683679
if (matrix != nullptr) {
@@ -704,12 +700,12 @@ void DisplayListBuilder::clipRect(const SkRect& rect,
704700
switch (clip_op) {
705701
case SkClipOp::kIntersect:
706702
Push<ClipIntersectRectOp>(0, 1, rect, is_aa);
707-
intersect(rect);
708703
break;
709704
case SkClipOp::kDifference:
710705
Push<ClipDifferenceRectOp>(0, 1, rect, is_aa);
711706
break;
712707
}
708+
tracker_.clipRect(rect, clip_op, is_aa);
713709
}
714710
void DisplayListBuilder::clipRRect(const SkRRect& rrect,
715711
SkClipOp clip_op,
@@ -721,12 +717,12 @@ void DisplayListBuilder::clipRRect(const SkRRect& rrect,
721717
switch (clip_op) {
722718
case SkClipOp::kIntersect:
723719
Push<ClipIntersectRRectOp>(0, 1, rrect, is_aa);
724-
intersect(rrect.getBounds());
725720
break;
726721
case SkClipOp::kDifference:
727722
Push<ClipDifferenceRRectOp>(0, 1, rrect, is_aa);
728723
break;
729724
}
725+
tracker_.clipRRect(rrect, clip_op, is_aa);
730726
}
731727
}
732728
void DisplayListBuilder::clipPath(const SkPath& path,
@@ -753,33 +749,12 @@ void DisplayListBuilder::clipPath(const SkPath& path,
753749
switch (clip_op) {
754750
case SkClipOp::kIntersect:
755751
Push<ClipIntersectPathOp>(0, 1, path, is_aa);
756-
if (!path.isInverseFillType()) {
757-
intersect(path.getBounds());
758-
}
759752
break;
760753
case SkClipOp::kDifference:
761754
Push<ClipDifferencePathOp>(0, 1, path, is_aa);
762-
// Map "kDifference of inverse path" to "kIntersect of the original path".
763-
if (path.isInverseFillType()) {
764-
intersect(path.getBounds());
765-
}
766755
break;
767756
}
768-
}
769-
void DisplayListBuilder::intersect(const SkRect& rect) {
770-
SkRect dev_clip_bounds = getTransform().mapRect(rect);
771-
if (!current_layer_->clip_bounds().intersect(dev_clip_bounds)) {
772-
current_layer_->clip_bounds().setEmpty();
773-
}
774-
}
775-
SkRect DisplayListBuilder::getLocalClipBounds() {
776-
SkM44 inverse;
777-
if (current_layer_->matrix().invert(&inverse)) {
778-
SkRect dev_bounds;
779-
current_layer_->clip_bounds().roundOut(&dev_bounds);
780-
return inverse.asM33().mapRect(dev_bounds);
781-
}
782-
return kMaxCullRect;
757+
tracker_.clipPath(path, clip_op, is_aa);
783758
}
784759

785760
bool DisplayListBuilder::quickReject(const SkRect& bounds) const {
@@ -794,7 +769,7 @@ bool DisplayListBuilder::quickReject(const SkRect& bounds) const {
794769
}
795770
SkRect dev_bounds;
796771
matrix.mapRect(bounds).roundOut(&dev_bounds);
797-
return !current_layer_->clip_bounds().intersects(dev_bounds);
772+
return !tracker_.device_cull_rect().intersects(dev_bounds);
798773
}
799774

800775
void DisplayListBuilder::drawPaint() {
@@ -1357,7 +1332,7 @@ bool DisplayListBuilder::AdjustBoundsForPaint(SkRect& bounds,
13571332
}
13581333

13591334
void DisplayListBuilder::AccumulateUnbounded() {
1360-
accumulator()->accumulate(current_layer_->clip_bounds());
1335+
accumulator()->accumulate(tracker_.device_cull_rect());
13611336
}
13621337

13631338
void DisplayListBuilder::AccumulateOpBounds(SkRect& bounds,
@@ -1370,7 +1345,7 @@ void DisplayListBuilder::AccumulateOpBounds(SkRect& bounds,
13701345
}
13711346
void DisplayListBuilder::AccumulateBounds(SkRect& bounds) {
13721347
getTransform().mapRect(&bounds);
1373-
if (bounds.intersect(current_layer_->clip_bounds())) {
1348+
if (bounds.intersect(tracker_.device_cull_rect())) {
13741349
accumulator()->accumulate(bounds);
13751350
}
13761351
}

display_list/display_list_builder.h

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "flutter/display_list/display_list_dispatcher.h"
1212
#include "flutter/display_list/display_list_flags.h"
1313
#include "flutter/display_list/display_list_image.h"
14+
#include "flutter/display_list/display_list_matrix_clip_tracker.h"
1415
#include "flutter/display_list/display_list_paint.h"
1516
#include "flutter/display_list/display_list_path_effect.h"
1617
#include "flutter/display_list/display_list_sampling_options.h"
@@ -210,11 +211,11 @@ class DisplayListBuilder final : public virtual Dispatcher,
210211
/// Returns the 4x4 full perspective transform representing all transform
211212
/// operations executed so far in this DisplayList within the enclosing
212213
/// save stack.
213-
SkM44 getTransformFullPerspective() const { return current_layer_->matrix(); }
214+
SkM44 getTransformFullPerspective() const { return tracker_.matrix_4x4(); }
214215
/// Returns the 3x3 partial perspective transform representing all transform
215216
/// operations executed so far in this DisplayList within the enclosing
216217
/// save stack.
217-
SkMatrix getTransform() const { return current_layer_->matrix33(); }
218+
SkMatrix getTransform() const { return tracker_.matrix_3x3(); }
218219

219220
void clipRect(const SkRect& rect, SkClipOp clip_op, bool is_aa) override;
220221
void clipRRect(const SkRRect& rrect, SkClipOp clip_op, bool is_aa) override;
@@ -223,11 +224,11 @@ class DisplayListBuilder final : public virtual Dispatcher,
223224
/// Conservative estimate of the bounds of all outstanding clip operations
224225
/// measured in the coordinate space within which this DisplayList will
225226
/// be rendered.
226-
SkRect getDestinationClipBounds() { return current_layer_->clip_bounds(); }
227+
SkRect getDestinationClipBounds() { return tracker_.device_cull_rect(); }
227228
/// Conservative estimate of the bounds of all outstanding clip operations
228229
/// transformed into the local coordinate space in which currently
229230
/// recorded rendering operations are interpreted.
230-
SkRect getLocalClipBounds();
231+
SkRect getLocalClipBounds() { return tracker_.local_cull_rect(); }
231232

232233
/// Return true iff the supplied bounds are easily shown to be outside
233234
/// of the current clip bounds. This method may conservatively return
@@ -386,32 +387,21 @@ class DisplayListBuilder final : public virtual Dispatcher,
386387

387388
class LayerInfo {
388389
public:
389-
explicit LayerInfo(const SkM44& matrix,
390-
const SkMatrix& matrix33,
391-
const SkRect& clip_bounds,
392-
size_t save_layer_offset = 0,
390+
explicit LayerInfo(size_t save_layer_offset = 0,
393391
bool has_layer = false,
394392
std::shared_ptr<const DlImageFilter> filter = nullptr)
395393
: save_layer_offset_(save_layer_offset),
396394
has_layer_(has_layer),
397395
cannot_inherit_opacity_(false),
398396
has_compatible_op_(false),
399-
matrix_(matrix),
400-
matrix33_(matrix33),
401-
clip_bounds_(clip_bounds),
402397
filter_(filter),
403398
is_unbounded_(false) {}
404399

405400
explicit LayerInfo(const LayerInfo* current_layer,
406401
size_t save_layer_offset = 0,
407402
bool has_layer = false,
408403
std::shared_ptr<const DlImageFilter> filter = nullptr)
409-
: LayerInfo(current_layer->matrix_,
410-
current_layer->matrix33_,
411-
current_layer->clip_bounds_,
412-
save_layer_offset,
413-
has_layer,
414-
filter) {}
404+
: LayerInfo(save_layer_offset, has_layer, filter) {}
415405

416406
// The offset into the memory buffer where the saveLayer DLOp record
417407
// for this saveLayer() call is placed. This may be needed if the
@@ -424,11 +414,6 @@ class DisplayListBuilder final : public virtual Dispatcher,
424414
bool has_layer() const { return has_layer_; }
425415
bool cannot_inherit_opacity() const { return cannot_inherit_opacity_; }
426416
bool has_compatible_op() const { return cannot_inherit_opacity_; }
427-
SkM44& matrix() { return matrix_; }
428-
SkMatrix& matrix33() { return matrix33_; }
429-
SkRect& clip_bounds() { return clip_bounds_; }
430-
431-
void update_matrix33() { matrix33_ = matrix_.asM33(); }
432417

433418
bool is_group_opacity_compatible() const {
434419
return !cannot_inherit_opacity_;
@@ -486,9 +471,6 @@ class DisplayListBuilder final : public virtual Dispatcher,
486471
bool has_layer_;
487472
bool cannot_inherit_opacity_;
488473
bool has_compatible_op_;
489-
SkM44 matrix_;
490-
SkMatrix matrix33_;
491-
SkRect clip_bounds_;
492474
std::shared_ptr<const DlImageFilter> filter_;
493475
bool is_unbounded_;
494476
bool has_deferred_save_op_ = false;
@@ -640,6 +622,7 @@ class DisplayListBuilder final : public virtual Dispatcher,
640622
DlPaint current_;
641623
// If |current_blender_| is set then ignore |current_.getBlendMode()|
642624
sk_sp<SkBlender> current_blender_;
625+
DisplayListMatrixClipTracker tracker_;
643626
};
644627

645628
} // namespace flutter

display_list/display_list_matrix_clip_tracker.cc

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,19 @@ void DisplayListMatrixClipTracker::clipRRect(const SkRRect& rrect,
183183
void DisplayListMatrixClipTracker::clipPath(const SkPath& path,
184184
SkClipOp op,
185185
bool is_aa) {
186+
// Map "kDifference of inverse path" to "kIntersect of the original path" and
187+
// map "kIntersect of inverse path" to "kDifference of the original path"
188+
if (path.isInverseFillType()) {
189+
switch (op) {
190+
case SkClipOp::kIntersect:
191+
op = SkClipOp::kDifference;
192+
break;
193+
case SkClipOp::kDifference:
194+
op = SkClipOp::kIntersect;
195+
break;
196+
}
197+
}
198+
186199
SkRect bounds;
187200
switch (op) {
188201
case SkClipOp::kIntersect:
@@ -323,7 +336,9 @@ SkRect Data3x3::local_cull_rect() const {
323336
// cull rect.
324337
return DisplayListBuilder::kMaxCullRect;
325338
}
326-
return inverse.mapRect(cull_rect_);
339+
SkRect expended_rect;
340+
cull_rect_.roundOut(&expended_rect);
341+
return inverse.mapRect(expended_rect);
327342
}
328343

329344
} // namespace flutter

0 commit comments

Comments
 (0)