[skottie] Apply opaque masks as clips
When the mask stack contains exactly one opaque mask path, we can apply as
a clip.
TBR=
Change-Id: Iadff7534bfa4925557bfbddd59529113f4958d0d
Reviewed-on: https://skia-review.googlesource.com/124000
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Florin Malita <fmalita@chromium.org>
diff --git a/experimental/skottie/Skottie.cpp b/experimental/skottie/Skottie.cpp
index 194efe7..a3b6d46 100644
--- a/experimental/skottie/Skottie.cpp
+++ b/experimental/skottie/Skottie.cpp
@@ -943,7 +943,14 @@
if (!jmask.isArray())
return childNode;
- auto mask_group = sksg::Group::Make();
+ struct MaskRecord {
+ sk_sp<sksg::Path> mask_path;
+ sk_sp<sksg::Color> mask_paint;
+ };
+
+ SkSTArray<4, MaskRecord, true> mask_stack;
+
+ bool opaque_mask = true;
for (const auto& m : jmask) {
if (!m.isObject())
@@ -969,15 +976,34 @@
auto mask_paint = sksg::Color::Make(SK_ColorBLACK);
mask_paint->setAntiAlias(true);
mask_paint->setBlendMode(MaskBlendMode(mode.c_str()[0]));
+
+ const auto animator_count = ctx->fAnimators.size();
BindProperty<ScalarValue>(m["o"], &ctx->fAnimators,
[mask_paint](const ScalarValue& o) { mask_paint->setOpacity(o * 0.01f); });
- mask_group->addChild(sksg::Draw::Make(std::move(mask_path), std::move(mask_paint)));
+ opaque_mask &= (animator_count == ctx->fAnimators.size() && mask_paint->getOpacity() >= 1);
+
+ mask_stack.push_back({mask_path, mask_paint});
}
- return mask_group->empty()
- ? childNode
- : sksg::MaskEffect::Make(std::move(childNode), std::move(mask_group));
+ if (mask_stack.empty())
+ return childNode;
+
+ if (mask_stack.count() == 1 && opaque_mask) {
+ // Single opaque mask => clip path.
+ return sksg::ClipEffect::Make(std::move(childNode),
+ std::move(mask_stack.front().mask_path),
+ true);
+ }
+
+ auto mask_group = sksg::Group::Make();
+ for (const auto& rec : mask_stack) {
+ mask_group->addChild(sksg::Draw::Make(std::move(rec.mask_path),
+ std::move(rec.mask_paint)));
+
+ }
+
+ return sksg::MaskEffect::Make(std::move(childNode), std::move(mask_group));
}
sk_sp<sksg::RenderNode> AttachLayer(const Json::Value& jlayer,