• 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/SkottieJson.h"
11 #include "modules/skottie/src/Transform.h"
12 #include "modules/sksg/include/SkSGOpacityEffect.h"
13 #include "modules/sksg/include/SkSGTransform.h"
14 
15 namespace skottie {
16 namespace internal {
17 
18 namespace  {
19 
20 class TransformEffectAdapter final : public DiscardableAdapterBase<TransformEffectAdapter,
21                                                                    sksg::OpacityEffect> {
22 public:
TransformEffectAdapter(const AnimationBuilder & abuilder,const skjson::ObjectValue * jopacity,const skjson::ObjectValue * jscale_uniform,const skjson::ObjectValue * jscale_width,const skjson::ObjectValue * jscale_height,sk_sp<TransformAdapter2D> tadapter,sk_sp<sksg::RenderNode> child)23     TransformEffectAdapter(const AnimationBuilder& abuilder,
24                            const skjson::ObjectValue* jopacity,
25                            const skjson::ObjectValue* jscale_uniform,
26                            const skjson::ObjectValue* jscale_width,
27                            const skjson::ObjectValue* jscale_height,
28                            sk_sp<TransformAdapter2D> tadapter,
29                            sk_sp<sksg::RenderNode> child)
30         : INHERITED(sksg::OpacityEffect::Make(std::move(child)))
31         , fTransformAdapter(std::move(tadapter)) {
32         this->bind(abuilder, jopacity      , fOpacity     );
33         this->bind(abuilder, jscale_uniform, fUniformScale);
34         this->bind(abuilder, jscale_width  , fScaleWidth  );
35         this->bind(abuilder, jscale_height , fScaleHeight );
36 
37         this->attachDiscardableAdapter(fTransformAdapter);
38     }
39 
40 private:
onSync()41     void onSync() override {
42         this->node()->setOpacity(fOpacity * 0.01f);
43 
44         // In uniform mode, the scale is based solely in ScaleHeight.
45         const auto scale = SkVector::Make(SkScalarRoundToInt(fUniformScale) ? fScaleHeight
46                                                                             : fScaleWidth,
47                                           fScaleHeight);
48 
49         // NB: this triggers an transform adapter -> SG sync.
50         fTransformAdapter->setScale(scale);
51     }
52 
53     const sk_sp<TransformAdapter2D> fTransformAdapter;
54 
55     ScalarValue fOpacity      = 100,
56                 fUniformScale =   0, // bool
57                 fScaleWidth   = 100,
58                 fScaleHeight  = 100;
59 
60     using INHERITED = DiscardableAdapterBase<TransformEffectAdapter, sksg::OpacityEffect>;
61 };
62 
63 }  // namespace
64 
attachTransformEffect(const skjson::ArrayValue & jprops,sk_sp<sksg::RenderNode> layer) const65 sk_sp<sksg::RenderNode> EffectBuilder::attachTransformEffect(const skjson::ArrayValue& jprops,
66                                                              sk_sp<sksg::RenderNode> layer) const {
67     enum : size_t {
68         kAnchorPoint_Index            =  0,
69         kPosition_Index               =  1,
70         kUniformScale_Index           =  2,
71         kScaleHeight_Index            =  3,
72         kScaleWidth_Index             =  4,
73         kSkew_Index                   =  5,
74         kSkewAxis_Index               =  6,
75         kRotation_Index               =  7,
76         kOpacity_Index                =  8,
77         // kUseCompShutterAngle_Index =  9,
78         // kShutterAngle_Index        = 10,
79         // kSampling_Index            = 11,
80     };
81 
82     auto transform_adapter = TransformAdapter2D::Make(*fBuilder,
83                                                       GetPropValue(jprops, kAnchorPoint_Index),
84                                                       GetPropValue(jprops, kPosition_Index),
85                                                       nullptr, // scale is handled externally
86                                                       GetPropValue(jprops, kRotation_Index),
87                                                       GetPropValue(jprops, kSkew_Index),
88                                                       GetPropValue(jprops, kSkewAxis_Index));
89     if (!transform_adapter) {
90         return nullptr;
91     }
92 
93     auto transform_effect_node = sksg::TransformEffect::Make(std::move(layer),
94                                                              transform_adapter->node());
95     return fBuilder->attachDiscardableAdapter<TransformEffectAdapter>
96             (*fBuilder,
97              GetPropValue(jprops, kOpacity_Index),
98              GetPropValue(jprops, kUniformScale_Index),
99              GetPropValue(jprops, kScaleWidth_Index),
100              GetPropValue(jprops, kScaleHeight_Index),
101              std::move(transform_adapter),
102              std::move(transform_effect_node)
103              );
104 }
105 
106 } // namespace internal
107 } // namespace skottie
108