Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 471a946

Browse files
fmalitaSkia Commit-Bot
authored andcommitted
[skottie] Make AnimationBuilder available for value parsing
Plumb AnimationBuilder throught a bazillion layers to make it reachable when parsing animatable values. This is in preparation of keyframed text, which will require access to the font set when parsing. Refactor only, no functional changes. TBR= Change-Id: Ide2ef2ba66fbcc75fdcc785f987b364d45dff5b6 Reviewed-on: https://skia-review.googlesource.com/149264 Commit-Queue: Florin Malita <fmalita@chromium.org> Reviewed-by: Florin Malita <fmalita@chromium.org>
1 parent 3054989 commit 471a946

13 files changed

+301
-264
lines changed

modules/skottie/skottie.gni

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ skia_skottie_sources = [
1414
"$_src/SkottieAdapter.cpp",
1515
"$_src/SkottieAdapter.h",
1616
"$_src/SkottieAnimator.cpp",
17-
"$_src/SkottieAnimator.h",
1817
"$_src/SkottieJson.cpp",
1918
"$_src/SkottieJson.h",
2019
"$_src/SkottieLayer.cpp",

modules/skottie/src/Skottie.cpp

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
#include "SkTime.h"
2626
#include "SkTo.h"
2727
#include "SkottieAdapter.h"
28-
#include "SkottieAnimator.h"
2928
#include "SkottieJson.h"
3029
#include "SkottiePriv.h"
3130
#include "SkottieValue.h"
@@ -43,23 +42,24 @@ void LogJSON(const skjson::Value& json, const char msg[]) {
4342
LOG("%s: %s\n", msg, dump.c_str());
4443
}
4544

46-
sk_sp<sksg::Matrix> AttachMatrix(const skjson::ObjectValue& t, AnimatorScope* ascope,
47-
sk_sp<sksg::Matrix> parentMatrix) {
45+
sk_sp<sksg::Matrix> AnimationBuilder::attachMatrix(const skjson::ObjectValue& t,
46+
AnimatorScope* ascope,
47+
sk_sp<sksg::Matrix> parentMatrix) const {
4848
static const VectorValue g_default_vec_0 = { 0, 0},
4949
g_default_vec_100 = {100, 100};
5050

5151
auto matrix = sksg::Matrix::Make(SkMatrix::I(), parentMatrix);
5252
auto adapter = sk_make_sp<TransformAdapter>(matrix);
5353

54-
auto bound = BindProperty<VectorValue>(t["a"], ascope,
54+
auto bound = this->bindProperty<VectorValue>(t["a"], ascope,
5555
[adapter](const VectorValue& a) {
5656
adapter->setAnchorPoint(ValueTraits<VectorValue>::As<SkPoint>(a));
5757
}, g_default_vec_0);
58-
bound |= BindProperty<VectorValue>(t["p"], ascope,
58+
bound |= this->bindProperty<VectorValue>(t["p"], ascope,
5959
[adapter](const VectorValue& p) {
6060
adapter->setPosition(ValueTraits<VectorValue>::As<SkPoint>(p));
6161
}, g_default_vec_0);
62-
bound |= BindProperty<VectorValue>(t["s"], ascope,
62+
bound |= this->bindProperty<VectorValue>(t["s"], ascope,
6363
[adapter](const VectorValue& s) {
6464
adapter->setScale(ValueTraits<VectorValue>::As<SkVector>(s));
6565
}, g_default_vec_100);
@@ -70,30 +70,31 @@ sk_sp<sksg::Matrix> AttachMatrix(const skjson::ObjectValue& t, AnimatorScope* as
7070
// we can still make use of rz.
7171
jrotation = &t["rz"];
7272
}
73-
bound |= BindProperty<ScalarValue>(*jrotation, ascope,
73+
bound |= this->bindProperty<ScalarValue>(*jrotation, ascope,
7474
[adapter](const ScalarValue& r) {
7575
adapter->setRotation(r);
7676
}, 0.0f);
77-
bound |= BindProperty<ScalarValue>(t["sk"], ascope,
77+
bound |= this->bindProperty<ScalarValue>(t["sk"], ascope,
7878
[adapter](const ScalarValue& sk) {
7979
adapter->setSkew(sk);
8080
}, 0.0f);
81-
bound |= BindProperty<ScalarValue>(t["sa"], ascope,
81+
bound |= this->bindProperty<ScalarValue>(t["sa"], ascope,
8282
[adapter](const ScalarValue& sa) {
8383
adapter->setSkewAxis(sa);
8484
}, 0.0f);
8585

8686
return bound ? matrix : parentMatrix;
8787
}
8888

89-
sk_sp<sksg::RenderNode> AttachOpacity(const skjson::ObjectValue& jtransform, AnimatorScope* ascope,
90-
sk_sp<sksg::RenderNode> childNode) {
89+
sk_sp<sksg::RenderNode> AnimationBuilder::attachOpacity(const skjson::ObjectValue& jtransform,
90+
AnimatorScope* ascope,
91+
sk_sp<sksg::RenderNode> childNode) const {
9192
if (!childNode)
9293
return nullptr;
9394

9495
auto opacityNode = sksg::OpacityEffect::Make(childNode);
9596

96-
if (!BindProperty<ScalarValue>(jtransform["o"], ascope,
97+
if (!this->bindProperty<ScalarValue>(jtransform["o"], ascope,
9798
[opacityNode](const ScalarValue& o) {
9899
// BM opacity is [0..100]
99100
opacityNode->setOpacity(o * 0.01f);
@@ -105,9 +106,10 @@ sk_sp<sksg::RenderNode> AttachOpacity(const skjson::ObjectValue& jtransform, Ani
105106
return std::move(opacityNode);
106107
}
107108

108-
sk_sp<sksg::Path> AttachPath(const skjson::Value& jpath, AnimatorScope* ascope) {
109+
sk_sp<sksg::Path> AnimationBuilder::attachPath(const skjson::Value& jpath,
110+
AnimatorScope* ascope) const {
109111
auto path_node = sksg::Path::Make();
110-
return BindProperty<ShapeValue>(jpath, ascope,
112+
return this->bindProperty<ShapeValue>(jpath, ascope,
111113
[path_node](const ShapeValue& p) {
112114
// FillType is tracked in the SG node, not in keyframes -- make sure we preserve it.
113115
auto path = ValueTraits<ShapeValue>::As<SkPath>(p);
@@ -118,10 +120,11 @@ sk_sp<sksg::Path> AttachPath(const skjson::Value& jpath, AnimatorScope* ascope)
118120
: nullptr;
119121
}
120122

121-
sk_sp<sksg::Color> AttachColor(const skjson::ObjectValue& jcolor, AnimatorScope* ascope,
122-
const char prop_name[]) {
123+
sk_sp<sksg::Color> AnimationBuilder::attachColor(const skjson::ObjectValue& jcolor,
124+
AnimatorScope* ascope,
125+
const char prop_name[]) const {
123126
auto color_node = sksg::Color::Make(SK_ColorBLACK);
124-
BindProperty<VectorValue>(jcolor[prop_name], ascope,
127+
this->bindProperty<VectorValue>(jcolor[prop_name], ascope,
125128
[color_node](const VectorValue& c) {
126129
color_node->setColor(ValueTraits<VectorValue>::As<SkColor>(c));
127130
});

modules/skottie/src/SkottieAnimator.cpp

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
* found in the LICENSE file.
66
*/
77

8-
#include "SkottieAnimator.h"
9-
108
#include "SkCubicMap.h"
119
#include "SkottieJson.h"
10+
#include "SkottiePriv.h"
1211
#include "SkottieValue.h"
12+
#include "SkSGScene.h"
1313
#include "SkString.h"
1414
#include "SkTArray.h"
1515

@@ -68,9 +68,9 @@ class KeyframeAnimatorBase : public sksg::Animator {
6868
: SkTPin(fCubicMaps[rec.cmidx].computeYFromX(lt), 0.0f, 1.0f);
6969
}
7070

71-
virtual int parseValue(const skjson::Value&) = 0;
71+
virtual int parseValue(const skjson::Value&, const AnimationBuilder* abuilder) = 0;
7272

73-
void parseKeyFrames(const skjson::ArrayValue& jframes) {
73+
void parseKeyFrames(const skjson::ArrayValue& jframes, const AnimationBuilder* abuilder) {
7474
for (const skjson::ObjectValue* jframe : jframes) {
7575
if (!jframe) continue;
7676

@@ -88,7 +88,7 @@ class KeyframeAnimatorBase : public sksg::Animator {
8888
fRecs.back().t1 = t0;
8989
}
9090

91-
const auto vidx0 = this->parseValue((*jframe)["s"]);
91+
const auto vidx0 = this->parseValue((*jframe)["s"], abuilder);
9292
if (vidx0 < 0)
9393
continue;
9494

@@ -97,7 +97,7 @@ class KeyframeAnimatorBase : public sksg::Animator {
9797

9898
if (!ParseDefault<bool>((*jframe)["h"], false)) {
9999
// Regular frame, requires an end value.
100-
vidx1 = this->parseValue((*jframe)["e"]);
100+
vidx1 = this->parseValue((*jframe)["e"], abuilder);
101101
if (vidx1 < 0)
102102
continue;
103103

@@ -176,10 +176,12 @@ template <typename T>
176176
class KeyframeAnimator final : public KeyframeAnimatorBase {
177177
public:
178178
static std::unique_ptr<KeyframeAnimator> Make(const skjson::ArrayValue* jv,
179+
const AnimationBuilder* abuilder,
179180
std::function<void(const T&)>&& apply) {
180181
if (!jv) return nullptr;
181182

182-
std::unique_ptr<KeyframeAnimator> animator(new KeyframeAnimator(*jv, std::move(apply)));
183+
std::unique_ptr<KeyframeAnimator> animator(
184+
new KeyframeAnimator(*jv, abuilder, std::move(apply)));
183185
if (!animator->count())
184186
return nullptr;
185187

@@ -193,14 +195,16 @@ class KeyframeAnimator final : public KeyframeAnimatorBase {
193195

194196
private:
195197
KeyframeAnimator(const skjson::ArrayValue& jframes,
198+
const AnimationBuilder* abuilder,
196199
std::function<void(const T&)>&& apply)
197200
: fApplyFunc(std::move(apply)) {
198-
this->parseKeyFrames(jframes);
201+
this->parseKeyFrames(jframes, abuilder);
199202
}
200203

201-
int parseValue(const skjson::Value& jv) override {
204+
int parseValue(const skjson::Value& jv, const AnimationBuilder* abuilder) override {
202205
T val;
203-
if (!Parse<T>(jv, &val) || (!fVs.empty() && !ValueTraits<T>::CanLerp(val, fVs.back()))) {
206+
if (!ValueTraits<T>::FromJSON(jv, abuilder, &val) ||
207+
(!fVs.empty() && !ValueTraits<T>::CanLerp(val, fVs.back()))) {
204208
return -1;
205209
}
206210

@@ -241,7 +245,8 @@ class KeyframeAnimator final : public KeyframeAnimatorBase {
241245

242246
template <typename T>
243247
static inline bool BindPropertyImpl(const skjson::ObjectValue* jprop,
244-
sksg::AnimatorList* animators,
248+
const AnimationBuilder* abuilder,
249+
AnimatorScope* ascope,
245250
std::function<void(const T&)>&& apply,
246251
const T* noop = nullptr) {
247252
if (!jprop) return false;
@@ -257,7 +262,7 @@ static inline bool BindPropertyImpl(const skjson::ObjectValue* jprop,
257262
// For those, we attempt to parse both ways.
258263
if (!ParseDefault<bool>(jpropA, false)) {
259264
T val;
260-
if (Parse<T>(jpropK, &val)) {
265+
if (ValueTraits<T>::FromJSON(jpropK, abuilder, &val)) {
261266
// Static property.
262267
if (noop && val == *noop)
263268
return false;
@@ -272,20 +277,21 @@ static inline bool BindPropertyImpl(const skjson::ObjectValue* jprop,
272277
}
273278

274279
// Keyframe property.
275-
auto animator = KeyframeAnimator<T>::Make(jpropK, std::move(apply));
280+
auto animator = KeyframeAnimator<T>::Make(jpropK, abuilder, std::move(apply));
276281

277282
if (!animator) {
278283
return LogFail(*jprop, "Could not parse keyframed property");
279284
}
280285

281-
animators->push_back(std::move(animator));
286+
ascope->push_back(std::move(animator));
282287

283288
return true;
284289
}
285290

286291
class SplitPointAnimator final : public sksg::Animator {
287292
public:
288293
static std::unique_ptr<SplitPointAnimator> Make(const skjson::ObjectValue* jprop,
294+
const AnimationBuilder* abuilder,
289295
std::function<void(const VectorValue&)>&& apply,
290296
const VectorValue*) {
291297
if (!jprop) return nullptr;
@@ -297,9 +303,9 @@ class SplitPointAnimator final : public sksg::Animator {
297303
// the object itself, so the scope is bound to the life time of the object.
298304
auto* split_animator_ptr = split_animator.get();
299305

300-
if (!BindPropertyImpl<ScalarValue>((*jprop)["x"], &split_animator->fAnimators,
306+
if (!BindPropertyImpl<ScalarValue>((*jprop)["x"], abuilder, &split_animator->fAnimators,
301307
[split_animator_ptr](const ScalarValue& x) { split_animator_ptr->setX(x); }) ||
302-
!BindPropertyImpl<ScalarValue>((*jprop)["y"], &split_animator->fAnimators,
308+
!BindPropertyImpl<ScalarValue>((*jprop)["y"], abuilder, &split_animator->fAnimators,
303309
[split_animator_ptr](const ScalarValue& y) { split_animator_ptr->setY(y); })) {
304310
LogFail(*jprop, "Could not parse split property");
305311
return nullptr;
@@ -340,11 +346,12 @@ class SplitPointAnimator final : public sksg::Animator {
340346
};
341347

342348
bool BindSplitPositionProperty(const skjson::Value& jv,
343-
sksg::AnimatorList* animators,
349+
const AnimationBuilder* abuilder,
350+
AnimatorScope* ascope,
344351
std::function<void(const VectorValue&)>&& apply,
345352
const VectorValue* noop) {
346-
if (auto split_animator = SplitPointAnimator::Make(jv, std::move(apply), noop)) {
347-
animators->push_back(std::unique_ptr<sksg::Animator>(split_animator.release()));
353+
if (auto split_animator = SplitPointAnimator::Make(jv, abuilder, std::move(apply), noop)) {
354+
ascope->push_back(std::unique_ptr<sksg::Animator>(split_animator.release()));
348355
return true;
349356
}
350357

@@ -354,32 +361,32 @@ bool BindSplitPositionProperty(const skjson::Value& jv,
354361
} // namespace
355362

356363
template <>
357-
bool BindProperty(const skjson::Value& jv,
364+
bool AnimationBuilder::bindProperty(const skjson::Value& jv,
358365
AnimatorScope* ascope,
359366
std::function<void(const ScalarValue&)>&& apply,
360-
const ScalarValue* noop) {
361-
return BindPropertyImpl(jv, ascope, std::move(apply), noop);
367+
const ScalarValue* noop) const {
368+
return BindPropertyImpl(jv, this, ascope, std::move(apply), noop);
362369
}
363370

364371
template <>
365-
bool BindProperty(const skjson::Value& jv,
372+
bool AnimationBuilder::bindProperty(const skjson::Value& jv,
366373
AnimatorScope* ascope,
367374
std::function<void(const VectorValue&)>&& apply,
368-
const VectorValue* noop) {
375+
const VectorValue* noop) const {
369376
if (!jv.is<skjson::ObjectValue>())
370377
return false;
371378

372379
return ParseDefault<bool>(jv.as<skjson::ObjectValue>()["s"], false)
373-
? BindSplitPositionProperty(jv, ascope, std::move(apply), noop)
374-
: BindPropertyImpl(jv, ascope, std::move(apply), noop);
380+
? BindSplitPositionProperty(jv, this, ascope, std::move(apply), noop)
381+
: BindPropertyImpl(jv, this, ascope, std::move(apply), noop);
375382
}
376383

377384
template <>
378-
bool BindProperty(const skjson::Value& jv,
385+
bool AnimationBuilder::bindProperty(const skjson::Value& jv,
379386
AnimatorScope* ascope,
380387
std::function<void(const ShapeValue&)>&& apply,
381-
const ShapeValue* noop) {
382-
return BindPropertyImpl(jv, ascope, std::move(apply), noop);
388+
const ShapeValue* noop) const {
389+
return BindPropertyImpl(jv, this, ascope, std::move(apply), noop);
383390
}
384391

385392
} // namespace internal

modules/skottie/src/SkottieAnimator.h

Lines changed: 0 additions & 39 deletions
This file was deleted.

0 commit comments

Comments
 (0)