Flutter Engine
The Flutter Engine
GradientEffect.cpp
Go to the documentation of this file.
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
19
20#include <cstddef>
21#include <utility>
22
23namespace skjson {
24class ArrayValue;
25}
26
27namespace skottie {
28namespace internal {
29
30namespace {
31
32class GradientRampEffectAdapter final : public AnimatablePropertyContainer {
33public:
36 const AnimationBuilder* abuilder) {
37 return sk_sp<GradientRampEffectAdapter>(new GradientRampEffectAdapter(jprops,
38 std::move(layer),
39 abuilder));
40 }
41
42 sk_sp<sksg::RenderNode> node() const { return fShaderEffect; }
43
44private:
45 GradientRampEffectAdapter(const skjson::ArrayValue& jprops,
47 const AnimationBuilder* abuilder)
48 : fShaderEffect(sksg::ShaderEffect::Make(std::move(layer))) {
49 enum : size_t {
50 kStartPoint_Index = 0,
51 kStartColor_Index = 1,
52 kEndPoint_Index = 2,
53 kEndColor_Index = 3,
54 kRampShape_Index = 4,
55 kRampScatter_Index = 5,
56 kBlendRatio_Index = 6,
57 };
58
59 EffectBinder(jprops, *abuilder, this)
60 .bind( kStartPoint_Index, fStartPoint)
61 .bind( kStartColor_Index, fStartColor)
62 .bind( kEndPoint_Index, fEndPoint )
63 .bind( kEndColor_Index, fEndColor )
64 .bind( kRampShape_Index, fShape )
65 .bind(kRampScatter_Index, fScatter )
66 .bind( kBlendRatio_Index, fBlend );
67 }
68
69 enum class InstanceType {
70 kNone,
71 kLinear,
72 kRadial,
73 };
74
75 void onSync() override {
76 // This adapter manages a SG fragment with the following structure:
77 //
78 // - ShaderEffect [fRoot]
79 // \ GradientShader [fGradient]
80 // \ child/wrapped fragment
81 //
82 // The gradient shader is updated based on the (animatable) instance type (linear/radial).
83
84 auto update_gradient = [this] (InstanceType new_type) {
85 if (new_type != fInstanceType) {
86 fGradient = new_type == InstanceType::kLinear
89
90 fShaderEffect->setShader(fGradient);
91 fInstanceType = new_type;
92 }
93
94 fGradient->setColorStops({{0, fStartColor},
95 {1, fEndColor}});
96 };
97
98 static constexpr int kLinearShapeValue = 1;
99 const auto instance_type = (SkScalarRoundToInt(fShape) == kLinearShapeValue)
101 : InstanceType::kRadial;
102
103 // Sync the gradient shader instance if needed.
104 update_gradient(instance_type);
105
106 // Sync instance-dependent gradient params.
107 const auto start_point = SkPoint{fStartPoint.x, fStartPoint.y},
108 end_point = SkPoint{ fEndPoint.x, fEndPoint.y};
109 if (instance_type == InstanceType::kLinear) {
110 auto* lg = static_cast<sksg::LinearGradient*>(fGradient.get());
111 lg->setStartPoint(start_point);
112 lg->setEndPoint(end_point);
113 } else {
114 SkASSERT(instance_type == InstanceType::kRadial);
115
116 auto* rg = static_cast<sksg::RadialGradient*>(fGradient.get());
117 rg->setStartCenter(start_point);
118 rg->setEndCenter(start_point);
119 rg->setEndRadius(SkPoint::Distance(start_point, end_point));
120 }
121
122 // TODO: blend, scatter
123 }
124
125 const sk_sp<sksg::ShaderEffect> fShaderEffect;
126 sk_sp<sksg::Gradient> fGradient;
127
128 InstanceType fInstanceType = InstanceType::kNone;
129
130 ColorValue fStartColor,
131 fEndColor;
132 Vec2Value fStartPoint = {0,0},
133 fEndPoint = {0,0};
134 ScalarValue fBlend = 0,
135 fScatter = 0,
136 fShape = 0; // 1 -> linear, 7 -> radial (?!)
137};
138
139} // namespace
140
141sk_sp<sksg::RenderNode> EffectBuilder::attachGradientEffect(const skjson::ArrayValue& jprops,
142 sk_sp<sksg::RenderNode> layer) const {
143 return fBuilder->attachDiscardableAdapter<GradientRampEffectAdapter>(jprops,
144 std::move(layer),
145 fBuilder);
146}
147
148} // namespace internal
149} // namespace skottie
#define SkASSERT(cond)
Definition: SkAssert.h:116
#define SkScalarRoundToInt(x)
Definition: SkScalar.h:37
GrStyledShape fShape
void attachDiscardableAdapter(sk_sp< T > adapter) const
Definition: SkottiePriv.h:139
static sk_sp< LinearGradient > Make()
Definition: SkSGGradient.h:60
SK_API sk_sp< SkDocument > Make(SkWStream *dst, const SkSerialProcs *=nullptr, std::function< void(const SkPicture *)> onEndPage=nullptr)
static constexpr skcms_TransferFunction kLinear
Definition: SkColorSpace.h:51
@ kNone
Definition: layer.h:53
CanvasGradient Gradient
Definition: dart_ui.cc:57
SK_API sk_sp< PrecompileShader > RadialGradient()
SkScalar ScalarValue
Definition: SkottieValue.h:22
SkV2 Vec2Value
Definition: SkottieValue.h:23
Definition: Skottie.h:32
Definition: ref_ptr.h:256
static float Distance(const SkPoint &a, const SkPoint &b)
Definition: SkPoint_impl.h:508