From 0c51c2134379dfc81473a135b9bdf02fa383bcde Mon Sep 17 00:00:00 2001 From: Florin Malita Date: Thu, 26 Apr 2018 14:13:14 -0400 Subject: [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 Commit-Queue: Florin Malita --- experimental/skottie/Skottie.cpp | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) (limited to 'experimental') 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 AttachMask(const Json::Value& jmask, if (!jmask.isArray()) return childNode; - auto mask_group = sksg::Group::Make(); + struct MaskRecord { + sk_sp mask_path; + sk_sp 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 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(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 AttachLayer(const Json::Value& jlayer, -- cgit v1.2.3