diff options
author | Florin Malita <fmalita@chromium.org> | 2018-04-26 14:13:14 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-04-27 15:02:12 +0000 |
commit | 0c51c2134379dfc81473a135b9bdf02fa383bcde (patch) | |
tree | 36bef78daffef00caa3c333ebc9bf56a3b8eff50 /experimental/skottie/Skottie.cpp | |
parent | 30573251161f7164d56f8c1f9a16055e5340427c (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/skottie/Skottie.cpp')
-rw-r--r-- | experimental/skottie/Skottie.cpp | 36 |
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, |