• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "modules/skottie/src/effects/Effects.h"
9 
10 #include "modules/skottie/src/SkottieAdapter.h"
11 #include "modules/skottie/src/SkottieValue.h"
12 #include "modules/sksg/include/SkSGRenderEffect.h"
13 #include "src/utils/SkJSON.h"
14 
15 namespace skottie {
16 namespace internal {
17 
18 namespace  {
19 
20 class GaussianBlurEffectAdapter final : public SkNVRefCnt<GaussianBlurEffectAdapter> {
21 public:
GaussianBlurEffectAdapter(sk_sp<sksg::BlurImageFilter> blur)22     explicit GaussianBlurEffectAdapter(sk_sp<sksg::BlurImageFilter> blur)
23         : fBlur(std::move(blur)) {
24         SkASSERT(fBlur);
25     }
26 
27     // AE/BM model properties.  These are all animatable/interpolatable.
28 
29     // Controls the blur sigma.
30     ADAPTER_PROPERTY(Blurriness, SkScalar, 0)
31 
32     // Enum selecting the blur dimensionality:
33     //
34     //   1 -> horizontal & vertical
35     //   2 -> horizontal
36     //   3 -> vertical
37     //
38     ADAPTER_PROPERTY(Dimensions, SkScalar, 1)
39 
40     // Enum selecting edge behavior:
41     //
42     //   0 -> clamp
43     //   1 -> repeat
44     //
45     ADAPTER_PROPERTY(RepeatEdge, SkScalar, 0)
46 
47 private:
apply()48     void apply() {
49         static constexpr SkVector kDimensionsMap[] = {
50             { 1, 1 }, // 1 -> horizontal and vertical
51             { 1, 0 }, // 2 -> horizontal
52             { 0, 1 }, // 3 -> vertical
53         };
54 
55         const auto dim_index = SkTPin<size_t>(static_cast<size_t>(fDimensions),
56                                               1, SK_ARRAY_COUNT(kDimensionsMap)) - 1;
57 
58         // Close enough to AE.
59         static constexpr SkScalar kBlurrinessToSigmaFactor = 0.3f;
60         const auto sigma = fBlurriness * kBlurrinessToSigmaFactor;
61 
62         fBlur->setSigma({ sigma * kDimensionsMap[dim_index].x(),
63                           sigma * kDimensionsMap[dim_index].y() });
64 
65         static constexpr SkTileMode kRepeatEdgeMap[] = {
66             SkTileMode::kDecal, // 0 -> repeat edge pixels: off
67             SkTileMode::kClamp, // 1 -> repeat edge pixels: on
68         };
69 
70         const auto repeat_index = SkTPin<size_t>(static_cast<size_t>(fRepeatEdge),
71                                                  0, SK_ARRAY_COUNT(kRepeatEdgeMap) - 1);
72         fBlur->setTileMode(kRepeatEdgeMap[repeat_index]);
73     }
74 
75     const sk_sp<sksg::BlurImageFilter> fBlur;
76 };
77 
78 } // anonymous ns
79 
attachGaussianBlurEffect(const skjson::ArrayValue & jprops,sk_sp<sksg::RenderNode> layer) const80 sk_sp<sksg::RenderNode> EffectBuilder::attachGaussianBlurEffect(
81         const skjson::ArrayValue& jprops,
82         sk_sp<sksg::RenderNode> layer) const {
83     enum : size_t {
84         kBlurriness_Index = 0,
85         kDimensions_Index = 1,
86         kRepeatEdge_Index = 2,
87     };
88 
89     auto blur_effect   = sksg::BlurImageFilter::Make();
90     auto blur_addapter = sk_make_sp<GaussianBlurEffectAdapter>(blur_effect);
91 
92     fBuilder->bindProperty<ScalarValue>(GetPropValue(jprops, kBlurriness_Index),
93         [blur_addapter](const ScalarValue& b) {
94             blur_addapter->setBlurriness(b);
95         });
96     fBuilder->bindProperty<ScalarValue>(GetPropValue(jprops, kDimensions_Index),
97         [blur_addapter](const ScalarValue& d) {
98             blur_addapter->setDimensions(d);
99         });
100     fBuilder->bindProperty<ScalarValue>(GetPropValue(jprops, kRepeatEdge_Index),
101         [blur_addapter](const ScalarValue& r) {
102             blur_addapter->setRepeatEdge(r);
103         });
104 
105     return sksg::ImageFilterEffect::Make(std::move(layer), std::move(blur_effect));
106 }
107 
108 } // namespace internal
109 } // namespace skottie
110