[skottie] Apply fully opaque masks as clips
We already have a clip optimization when there is only one opaque mask.
Extend to cover multiple opaque masks, using Merge scene nodes.
TBR=
Change-Id: I24b61f0c0d080b13438c6777e98a8e2fefd09fdd
Reviewed-on: https://skia-review.googlesource.com/140002
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Florin Malita <fmalita@chromium.org>
diff --git a/modules/sksg/src/SkSGMerge.cpp b/modules/sksg/src/SkSGMerge.cpp
index be1ff41..ff50021 100644
--- a/modules/sksg/src/SkSGMerge.cpp
+++ b/modules/sksg/src/SkSGMerge.cpp
@@ -12,17 +12,16 @@
namespace sksg {
-Merge::Merge(std::vector<sk_sp<GeometryNode>>&& geos, Mode mode)
- : fGeos(std::move(geos))
- , fMode(mode) {
- for (const auto& geo : fGeos) {
- this->observeInval(geo);
+Merge::Merge(std::vector<Rec>&& recs)
+ : fRecs(std::move(recs)) {
+ for (const auto& rec : fRecs) {
+ this->observeInval(rec.fGeo);
}
}
Merge::~Merge() {
- for (const auto& geo : fGeos) {
- this->unobserveInval(geo);
+ for (const auto& rec : fRecs) {
+ this->unobserveInval(rec.fGeo);
}
}
@@ -60,21 +59,34 @@
SkRect Merge::onRevalidate(InvalidationController* ic, const SkMatrix& ctm) {
SkASSERT(this->hasInval());
- const auto op = mode_to_op(fMode);
SkOpBuilder builder;
fMerged.reset();
+ bool in_builder = false;
- for (const auto& geo : fGeos) {
- geo->revalidate(ic, ctm);
- if (fMode == Mode::kMerge) {
- fMerged.addPath(geo->asPath());
- } else {
- builder.add(geo->asPath(), geo == fGeos.front() ? kUnion_SkPathOp : op);
+ for (const auto& rec : fRecs) {
+ rec.fGeo->revalidate(ic, ctm);
+
+ // Merge is not currently supported by SkOpBuidler.
+ if (rec.fMode == Mode::kMerge) {
+ if (in_builder) {
+ builder.resolve(&fMerged);
+ in_builder = false;
+ }
+
+ fMerged.addPath(rec.fGeo->asPath());
+ continue;
}
+
+ if (!in_builder) {
+ builder.add(fMerged, kUnion_SkPathOp);
+ in_builder = true;
+ }
+
+ builder.add(rec.fGeo->asPath(), mode_to_op(rec.fMode));
}
- if (fMode != Mode::kMerge) {
+ if (in_builder) {
builder.resolve(&fMerged);
}