1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2019 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "modules/skottie/src/effects/Effects.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "include/private/SkTPin.h" 11cb93a386Sopenharmony_ci#include "modules/skottie/src/SkottieValue.h" 12cb93a386Sopenharmony_ci#include "modules/sksg/include/SkSGRenderEffect.h" 13cb93a386Sopenharmony_ci#include "src/utils/SkJSON.h" 14cb93a386Sopenharmony_ci 15cb93a386Sopenharmony_cinamespace skottie { 16cb93a386Sopenharmony_cinamespace internal { 17cb93a386Sopenharmony_ci 18cb93a386Sopenharmony_cinamespace { 19cb93a386Sopenharmony_ci 20cb93a386Sopenharmony_ciclass GaussianBlurEffectAdapter final : public AnimatablePropertyContainer { 21cb93a386Sopenharmony_cipublic: 22cb93a386Sopenharmony_ci static sk_sp<GaussianBlurEffectAdapter> Make(const skjson::ArrayValue& jprops, 23cb93a386Sopenharmony_ci sk_sp<sksg::RenderNode> layer, 24cb93a386Sopenharmony_ci const AnimationBuilder* abuilder) { 25cb93a386Sopenharmony_ci return sk_sp<GaussianBlurEffectAdapter>(new GaussianBlurEffectAdapter(jprops, 26cb93a386Sopenharmony_ci std::move(layer), 27cb93a386Sopenharmony_ci abuilder)); 28cb93a386Sopenharmony_ci } 29cb93a386Sopenharmony_ci 30cb93a386Sopenharmony_ci const sk_sp<sksg::RenderNode>& node() const { return fImageFilterEffect; } 31cb93a386Sopenharmony_ci 32cb93a386Sopenharmony_ciprivate: 33cb93a386Sopenharmony_ci GaussianBlurEffectAdapter(const skjson::ArrayValue& jprops, 34cb93a386Sopenharmony_ci sk_sp<sksg::RenderNode> layer, 35cb93a386Sopenharmony_ci const AnimationBuilder* abuilder) 36cb93a386Sopenharmony_ci : fBlur(sksg::BlurImageFilter::Make()) 37cb93a386Sopenharmony_ci , fImageFilterEffect(sksg::ImageFilterEffect::Make(std::move(layer), fBlur)) { 38cb93a386Sopenharmony_ci enum : size_t { 39cb93a386Sopenharmony_ci kBlurriness_Index = 0, 40cb93a386Sopenharmony_ci kDimensions_Index = 1, 41cb93a386Sopenharmony_ci kRepeatEdge_Index = 2, 42cb93a386Sopenharmony_ci }; 43cb93a386Sopenharmony_ci 44cb93a386Sopenharmony_ci EffectBinder(jprops, *abuilder, this) 45cb93a386Sopenharmony_ci .bind(kBlurriness_Index, fBlurriness) 46cb93a386Sopenharmony_ci .bind(kDimensions_Index, fDimensions) 47cb93a386Sopenharmony_ci .bind(kRepeatEdge_Index, fRepeatEdge); 48cb93a386Sopenharmony_ci } 49cb93a386Sopenharmony_ci 50cb93a386Sopenharmony_ci void onSync() override { 51cb93a386Sopenharmony_ci static constexpr SkVector kDimensionsMap[] = { 52cb93a386Sopenharmony_ci { 1, 1 }, // 1 -> horizontal and vertical 53cb93a386Sopenharmony_ci { 1, 0 }, // 2 -> horizontal 54cb93a386Sopenharmony_ci { 0, 1 }, // 3 -> vertical 55cb93a386Sopenharmony_ci }; 56cb93a386Sopenharmony_ci 57cb93a386Sopenharmony_ci const auto dim_index = SkTPin<size_t>(static_cast<size_t>(fDimensions), 58cb93a386Sopenharmony_ci 1, SK_ARRAY_COUNT(kDimensionsMap)) - 1; 59cb93a386Sopenharmony_ci 60cb93a386Sopenharmony_ci const auto sigma = fBlurriness * kBlurSizeToSigma; 61cb93a386Sopenharmony_ci 62cb93a386Sopenharmony_ci fBlur->setSigma({ sigma * kDimensionsMap[dim_index].x(), 63cb93a386Sopenharmony_ci sigma * kDimensionsMap[dim_index].y() }); 64cb93a386Sopenharmony_ci 65cb93a386Sopenharmony_ci static constexpr SkTileMode kRepeatEdgeMap[] = { 66cb93a386Sopenharmony_ci SkTileMode::kDecal, // 0 -> repeat edge pixels: off 67cb93a386Sopenharmony_ci SkTileMode::kClamp, // 1 -> repeat edge pixels: on 68cb93a386Sopenharmony_ci }; 69cb93a386Sopenharmony_ci 70cb93a386Sopenharmony_ci const auto repeat_index = SkTPin<size_t>(static_cast<size_t>(fRepeatEdge), 71cb93a386Sopenharmony_ci 0, SK_ARRAY_COUNT(kRepeatEdgeMap) - 1); 72cb93a386Sopenharmony_ci fBlur->setTileMode(kRepeatEdgeMap[repeat_index]); 73cb93a386Sopenharmony_ci } 74cb93a386Sopenharmony_ci 75cb93a386Sopenharmony_ci const sk_sp<sksg::BlurImageFilter> fBlur; 76cb93a386Sopenharmony_ci const sk_sp<sksg::RenderNode> fImageFilterEffect; 77cb93a386Sopenharmony_ci 78cb93a386Sopenharmony_ci ScalarValue fBlurriness = 0, // Controls the blur sigma. 79cb93a386Sopenharmony_ci fDimensions = 1, // 1 -> horizontal & vertical, 2 -> horizontal, 3 -> vertical 80cb93a386Sopenharmony_ci fRepeatEdge = 0; // 0 -> clamp, 1 -> repeat 81cb93a386Sopenharmony_ci}; 82cb93a386Sopenharmony_ci 83cb93a386Sopenharmony_ci} // namespace 84cb93a386Sopenharmony_ci 85cb93a386Sopenharmony_cisk_sp<sksg::RenderNode> EffectBuilder::attachGaussianBlurEffect( 86cb93a386Sopenharmony_ci const skjson::ArrayValue& jprops, 87cb93a386Sopenharmony_ci sk_sp<sksg::RenderNode> layer) const { 88cb93a386Sopenharmony_ci return fBuilder->attachDiscardableAdapter<GaussianBlurEffectAdapter>(jprops, 89cb93a386Sopenharmony_ci std::move(layer), 90cb93a386Sopenharmony_ci fBuilder); 91cb93a386Sopenharmony_ci} 92cb93a386Sopenharmony_ci 93cb93a386Sopenharmony_ci} // namespace internal 94cb93a386Sopenharmony_ci} // namespace skottie 95