aboutsummaryrefslogtreecommitdiffhomepage
path: root/experimental
diff options
context:
space:
mode:
authorGravatar Florin Malita <fmalita@chromium.org>2018-04-26 14:13:14 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-04-27 15:02:12 +0000
commit0c51c2134379dfc81473a135b9bdf02fa383bcde (patch)
tree36bef78daffef00caa3c333ebc9bf56a3b8eff50 /experimental
parent30573251161f7164d56f8c1f9a16055e5340427c (diff)
[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>
Diffstat (limited to 'experimental')
-rw-r--r--experimental/skottie/Skottie.cpp36
1 files changed, 31 insertions, 5 deletions
diff --git a/experimental/skottie/Skottie.cpp b/experimental/skottie/Skottie.cpp
index 194efe70c4..a3b6d46b93 100644
--- a/experimental/skottie/Skottie.cpp
+++ b/experimental/skottie/Skottie.cpp
@@ -943,7 +943,14 @@ sk_sp<sksg::RenderNode> AttachMask(const Json::Value& jmask,
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 @@ sk_sp<sksg::RenderNode> AttachMask(const Json::Value& jmask,
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});
+ }
+
+ 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 mask_group->empty()
- ? childNode
- : sksg::MaskEffect::Make(std::move(childNode), std::move(mask_group));
+ return sksg::MaskEffect::Make(std::move(childNode), std::move(mask_group));
}
sk_sp<sksg::RenderNode> AttachLayer(const Json::Value& jlayer,