Flutter Engine
The Flutter Engine
Effects.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
9
16
17#include <algorithm>
18#include <cstdint>
19#include <cstring>
20#include <iterator>
21#include <limits>
22#include <utility>
23
24namespace skottie {
25namespace internal {
26
28 const SkSize& layer_size,
29 CompositionBuilder* cbuilder)
30 : fBuilder(abuilder)
31 , fCompBuilder(cbuilder)
32 , fLayerSize(layer_size) {}
33
34EffectBuilder::EffectBuilderT EffectBuilder::findBuilder(const skjson::ObjectValue& jeffect) const {
35 static constexpr struct BuilderInfo {
36 const char* fName;
37 EffectBuilderT fBuilder;
38 } gBuilderInfo[] = {
39 // alphabetized for binary search lookup
40 { "ADBE Black&White" , &EffectBuilder::attachBlackAndWhiteEffect },
41 { "ADBE Brightness & Contrast 2", &EffectBuilder::attachBrightnessContrastEffect },
42 { "ADBE Bulge" , &EffectBuilder::attachBulgeEffect },
43 { "ADBE Corner Pin" , &EffectBuilder::attachCornerPinEffect },
44 { "ADBE Displacement Map" , &EffectBuilder::attachDisplacementMapEffect },
45 { "ADBE Drop Shadow" , &EffectBuilder::attachDropShadowEffect },
46 { "ADBE Easy Levels2" , &EffectBuilder::attachEasyLevelsEffect },
47 { "ADBE Fill" , &EffectBuilder::attachFillEffect },
48 { "ADBE Fractal Noise" , &EffectBuilder::attachFractalNoiseEffect },
49 { "ADBE Gaussian Blur 2" , &EffectBuilder::attachGaussianBlurEffect },
50 { "ADBE Geometry2" , &EffectBuilder::attachTransformEffect },
51 { "ADBE HUE SATURATION" , &EffectBuilder::attachHueSaturationEffect },
52 { "ADBE Invert" , &EffectBuilder::attachInvertEffect },
53 { "ADBE Linear Wipe" , &EffectBuilder::attachLinearWipeEffect },
54 { "ADBE Motion Blur" , &EffectBuilder::attachDirectionalBlurEffect },
55 { "ADBE Pro Levels2" , &EffectBuilder::attachProLevelsEffect },
56 { "ADBE Radial Wipe" , &EffectBuilder::attachRadialWipeEffect },
57 { "ADBE Ramp" , &EffectBuilder::attachGradientEffect },
58 { "ADBE Sharpen" , &EffectBuilder::attachSharpenEffect },
59 { "ADBE Shift Channels" , &EffectBuilder::attachShiftChannelsEffect },
60 { "ADBE Threshold2" , &EffectBuilder::attachThresholdEffect },
61 { "ADBE Tile" , &EffectBuilder::attachMotionTileEffect },
62 { "ADBE Tint" , &EffectBuilder::attachTintEffect },
63 { "ADBE Tritone" , &EffectBuilder::attachTritoneEffect },
64 { "ADBE Venetian Blinds" , &EffectBuilder::attachVenetianBlindsEffect },
65 { "CC Sphere" , &EffectBuilder::attachSphereEffect },
66 { "CC Toner" , &EffectBuilder::attachCCTonerEffect },
67 { "SkSL Color Filter" , &EffectBuilder::attachSkSLColorFilter },
68 { "SkSL Shader" , &EffectBuilder::attachSkSLShader },
69 };
70
71 const skjson::StringValue* mn = jeffect["mn"];
72 if (mn) {
73 const BuilderInfo key { mn->begin(), nullptr };
74 const auto* binfo = std::lower_bound(std::begin(gBuilderInfo),
75 std::end (gBuilderInfo),
76 key,
77 [](const BuilderInfo& a, const BuilderInfo& b) {
78 return strcmp(a.fName, b.fName) < 0;
79 });
80 if (binfo != std::end(gBuilderInfo) && !strcmp(binfo->fName, key.fName)) {
81 return binfo->fBuilder;
82 }
83 }
84
85 // Some legacy clients rely solely on the 'ty' field and generate (non-BM) JSON
86 // without a valid 'mn' string. TODO: we should update them and remove this fallback.
87 enum : int32_t {
88 kTint_Effect = 20,
89 kFill_Effect = 21,
90 kTritone_Effect = 23,
91 kDropShadow_Effect = 25,
92 kRadialWipe_Effect = 26,
93 kGaussianBlur_Effect = 29,
94 };
95
96 switch (ParseDefault<int>(jeffect["ty"], -1)) {
97 case kTint_Effect: return &EffectBuilder::attachTintEffect;
98 case kFill_Effect: return &EffectBuilder::attachFillEffect;
99 case kTritone_Effect: return &EffectBuilder::attachTritoneEffect;
100 case kDropShadow_Effect: return &EffectBuilder::attachDropShadowEffect;
101 case kRadialWipe_Effect: return &EffectBuilder::attachRadialWipeEffect;
102 case kGaussianBlur_Effect: return &EffectBuilder::attachGaussianBlurEffect;
103 default: break;
104 }
105
106 fBuilder->log(Logger::Level::kWarning, &jeffect,
107 "Unsupported layer effect: %s", mn ? mn->begin() : "(unknown)");
108
109 return nullptr;
110}
111
113 sk_sp<sksg::RenderNode> layer) const {
114 if (!layer) {
115 return nullptr;
116 }
117
118 for (const skjson::ObjectValue* jeffect : jeffects) {
119 if (!jeffect) {
120 continue;
121 }
122
123 const auto builder = this->findBuilder(*jeffect);
124 const skjson::ArrayValue* jprops = (*jeffect)["ef"];
125 if (!builder || !jprops) {
126 continue;
127 }
128
130 layer = (this->*builder)(*jprops, std::move(layer));
131
132 if (!layer) {
133 fBuilder->log(Logger::Level::kError, jeffect, "Invalid layer effect.");
134 return nullptr;
135 }
136 }
137
138 return layer;
139}
140
142 sk_sp<sksg::RenderNode> layer) const {
143#if !defined(SKOTTIE_DISABLE_STYLES)
144 if (!layer) {
145 return nullptr;
146 }
147
148 using StyleBuilder =
151 static constexpr StyleBuilder gStyleBuilders[] = {
152 nullptr, // 'ty': 0 -> stroke
153 &EffectBuilder::attachDropShadowStyle, // 'ty': 1 -> drop shadow
154 &EffectBuilder::attachInnerShadowStyle, // 'ty': 2 -> inner shadow
155 &EffectBuilder::attachOuterGlowStyle, // 'ty': 3 -> outer glow
156 &EffectBuilder::attachInnerGlowStyle, // 'ty': 4 -> inner glow
157 };
158
159 for (const skjson::ObjectValue* jstyle : jstyles) {
160 if (!jstyle) {
161 continue;
162 }
163
164 const auto style_type =
165 ParseDefault<size_t>((*jstyle)["ty"], std::numeric_limits<size_t>::max());
166 auto builder = style_type < std::size(gStyleBuilders) ? gStyleBuilders[style_type]
167 : nullptr;
168
169 if (!builder) {
170 fBuilder->log(Logger::Level::kWarning, jstyle, "Unsupported layer style.");
171 continue;
172 }
173
174 layer = (this->*builder)(*jstyle, std::move(layer));
175 }
176#endif // !defined(SKOTTIE_DISABLE_STYLES)
177
178 return layer;
179}
180
182 size_t prop_index) {
183 static skjson::NullValue kNull;
184
185 if (prop_index >= jprops.size()) {
186 return kNull;
187 }
188
189 const skjson::ObjectValue* jprop = jprops[prop_index];
190
191 return jprop ? (*jprop)["v"] : kNull;
192}
193
195 : fMaskEffectNode(sksg::MaskShaderEffect::Make(std::move(child)))
196 , fLayerSize(ls) {}
197
198void MaskShaderEffectBase::onSync() {
199 const auto minfo = this->onMakeMask();
200
201 fMaskEffectNode->setVisible(minfo.fVisible);
202 fMaskEffectNode->setShader(std::move(minfo.fMaskShader));
203}
204
205} // namespace internal
206} // namespace skottie
const char * fName
const char * begin() const
Definition: SkJSON.h:315
size_t size() const
Definition: SkJSON.h:262
void log(Logger::Level, const skjson::Value *, const char fmt[],...) const SK_PRINTF_LIKE(4
Definition: Skottie.cpp:71
sk_sp< sksg::RenderNode > attachEffects(const skjson::ArrayValue &, sk_sp< sksg::RenderNode >) const
Definition: Effects.cpp:112
EffectBuilder(const AnimationBuilder *, const SkSize &, CompositionBuilder *)
Definition: Effects.cpp:27
static const skjson::Value & GetPropValue(const skjson::ArrayValue &jprops, size_t prop_index)
Definition: Effects.cpp:181
sk_sp< sksg::RenderNode > attachStyles(const skjson::ArrayValue &, sk_sp< sksg::RenderNode >) const
Definition: Effects.cpp:141
MaskShaderEffectBase(sk_sp< sksg::RenderNode >, const SkSize &)
Definition: Effects.cpp:194
virtual MaskInfo onMakeMask() const =0
static const char * begin(const StringSlice &s)
Definition: editor.cpp:252
static bool b
struct MyStruct a[10]
static float max(float r, float g, float b)
Definition: hsl.cpp:49
SK_API sk_sp< SkDocument > Make(SkWStream *dst, const SkSerialProcs *=nullptr, std::function< void(const SkPicture *)> onEndPage=nullptr)
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
Definition: Skottie.h:32
Definition: ref_ptr.h:256
Definition: SkSize.h:52