• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 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 "include/effects/SkRuntimeEffect.h"
11 #include "modules/skottie/src/Adapter.h"
12 #include "modules/skottie/src/SkottieJson.h"
13 #include "modules/skottie/src/SkottieValue.h"
14 #include "modules/sksg/include/SkSGColorFilter.h"
15 
16 namespace skottie::internal {
17 
18 #ifdef SK_ENABLE_SKSL
19 
20 namespace  {
21 
22 // Convert to black & white, based on input luminance and a threshold uniform.
23 static constexpr char gThresholdSkSL[] =
24     "uniform half t;"
25 
26     "half4 main(half4 color) {"
27         "half4 c = unpremul(color);"
28 
29         "half lum = dot(c.rgb, half3(0.2126, 0.7152, 0.0722)),"
30               "bw = step(t, lum);"
31 
32         "return bw.xxx1 * c.a;"
33     "}"
34 ;
35 
threshold_effect()36 static sk_sp<SkRuntimeEffect> threshold_effect() {
37     static const SkRuntimeEffect* effect =
38         SkRuntimeEffect::MakeForColorFilter(SkString(gThresholdSkSL), {}).effect.release();
39     SkASSERT(effect);
40 
41     return sk_ref_sp(effect);
42 }
43 
44 class ThresholdAdapter final : public DiscardableAdapterBase<ThresholdAdapter,
45                                                              sksg::ExternalColorFilter> {
46 public:
ThresholdAdapter(const skjson::ArrayValue & jprops,sk_sp<sksg::RenderNode> layer,const AnimationBuilder & abuilder)47     ThresholdAdapter(const skjson::ArrayValue& jprops,
48                      sk_sp<sksg::RenderNode> layer,
49                      const AnimationBuilder& abuilder)
50         : INHERITED(sksg::ExternalColorFilter::Make(std::move(layer)))
51     {
52         enum : size_t {
53             kLevel_Index = 0,
54         };
55 
56         EffectBinder(jprops, abuilder, this).bind(kLevel_Index, fLevel);
57     }
58 
59 private:
onSync()60     void onSync() override {
61         auto cf =
62                 threshold_effect()->makeColorFilter(SkData::MakeWithCopy(&fLevel, sizeof(fLevel)));
63 
64         this->node()->setColorFilter(std::move(cf));
65     }
66 
67     ScalarValue fLevel = 0;
68 
69     using INHERITED = DiscardableAdapterBase<ThresholdAdapter, sksg::ExternalColorFilter>;
70 };
71 
72 } // namespace
73 
74 #endif  // SK_ENABLE_SKSL
75 
attachThresholdEffect(const skjson::ArrayValue & jprops,sk_sp<sksg::RenderNode> layer) const76 sk_sp<sksg::RenderNode> EffectBuilder::attachThresholdEffect(const skjson::ArrayValue& jprops,
77                                                              sk_sp<sksg::RenderNode> layer) const {
78 #ifdef SK_ENABLE_SKSL
79     return fBuilder->attachDiscardableAdapter<ThresholdAdapter>(jprops,
80                                                                 std::move(layer),
81                                                                 *fBuilder);
82 #else
83     // TODO(skia:12197)
84     return layer;
85 #endif
86 }
87 
88 } // namespace skottie::internal
89