Layer.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  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. #include "modules/skottie/src/SkottiePriv.h"
  8. #include "modules/skottie/src/SkottieAdapter.h"
  9. #include "modules/skottie/src/SkottieJson.h"
  10. #include "modules/skottie/src/effects/Effects.h"
  11. #include "modules/skottie/src/effects/MotionBlurEffect.h"
  12. #include "modules/sksg/include/SkSGClipEffect.h"
  13. #include "modules/sksg/include/SkSGDraw.h"
  14. #include "modules/sksg/include/SkSGGroup.h"
  15. #include "modules/sksg/include/SkSGMaskEffect.h"
  16. #include "modules/sksg/include/SkSGMerge.h"
  17. #include "modules/sksg/include/SkSGPaint.h"
  18. #include "modules/sksg/include/SkSGPath.h"
  19. #include "modules/sksg/include/SkSGRect.h"
  20. #include "modules/sksg/include/SkSGRenderEffect.h"
  21. #include "modules/sksg/include/SkSGRenderNode.h"
  22. #include "modules/sksg/include/SkSGTransform.h"
  23. namespace skottie {
  24. namespace internal {
  25. namespace {
  26. static constexpr int kNullLayerType = 3;
  27. static constexpr int kCameraLayerType = 13;
  28. struct MaskInfo {
  29. SkBlendMode fBlendMode; // used when masking with layers/blending
  30. sksg::Merge::Mode fMergeMode; // used when clipping
  31. bool fInvertGeometry;
  32. };
  33. const MaskInfo* GetMaskInfo(char mode) {
  34. static constexpr MaskInfo k_add_info =
  35. { SkBlendMode::kSrcOver , sksg::Merge::Mode::kUnion , false };
  36. static constexpr MaskInfo k_int_info =
  37. { SkBlendMode::kSrcIn , sksg::Merge::Mode::kIntersect , false };
  38. // AE 'subtract' is the same as 'intersect' + inverted geometry
  39. // (draws the opacity-adjusted paint *outside* the shape).
  40. static constexpr MaskInfo k_sub_info =
  41. { SkBlendMode::kSrcIn , sksg::Merge::Mode::kIntersect , true };
  42. static constexpr MaskInfo k_dif_info =
  43. { SkBlendMode::kDifference, sksg::Merge::Mode::kDifference, false };
  44. switch (mode) {
  45. case 'a': return &k_add_info;
  46. case 'f': return &k_dif_info;
  47. case 'i': return &k_int_info;
  48. case 's': return &k_sub_info;
  49. default: break;
  50. }
  51. return nullptr;
  52. }
  53. sk_sp<sksg::RenderNode> AttachMask(const skjson::ArrayValue* jmask,
  54. const AnimationBuilder* abuilder,
  55. AnimatorScope* ascope,
  56. sk_sp<sksg::RenderNode> childNode) {
  57. if (!jmask) return childNode;
  58. struct MaskRecord {
  59. sk_sp<sksg::Path> mask_path; // for clipping and masking
  60. sk_sp<sksg::Color> mask_paint; // for masking
  61. sk_sp<sksg::BlurImageFilter> mask_blur; // for masking
  62. sksg::Merge::Mode merge_mode; // for clipping
  63. };
  64. SkSTArray<4, MaskRecord, true> mask_stack;
  65. bool has_effect = false;
  66. auto blur_effect = sksg::BlurImageFilter::Make();
  67. for (const skjson::ObjectValue* m : *jmask) {
  68. if (!m) continue;
  69. const skjson::StringValue* jmode = (*m)["mode"];
  70. if (!jmode || jmode->size() != 1) {
  71. abuilder->log(Logger::Level::kError, &(*m)["mode"], "Invalid mask mode.");
  72. continue;
  73. }
  74. const auto mode = *jmode->begin();
  75. if (mode == 'n') {
  76. // "None" masks have no effect.
  77. continue;
  78. }
  79. const auto* mask_info = GetMaskInfo(mode);
  80. if (!mask_info) {
  81. abuilder->log(Logger::Level::kWarning, nullptr, "Unsupported mask mode: '%c'.", mode);
  82. continue;
  83. }
  84. auto mask_path = abuilder->attachPath((*m)["pt"], ascope);
  85. if (!mask_path) {
  86. abuilder->log(Logger::Level::kError, m, "Could not parse mask path.");
  87. continue;
  88. }
  89. // "inv" is cumulative with mask info fInvertGeometry
  90. const auto inverted =
  91. (mask_info->fInvertGeometry != ParseDefault<bool>((*m)["inv"], false));
  92. mask_path->setFillType(inverted ? SkPath::kInverseWinding_FillType
  93. : SkPath::kWinding_FillType);
  94. auto mask_paint = sksg::Color::Make(SK_ColorBLACK);
  95. mask_paint->setAntiAlias(true);
  96. // First mask in the stack initializes the mask buffer.
  97. mask_paint->setBlendMode(mask_stack.empty() ? SkBlendMode::kSrc
  98. : mask_info->fBlendMode);
  99. has_effect |= abuilder->bindProperty<ScalarValue>((*m)["o"], ascope,
  100. [mask_paint](const ScalarValue& o) {
  101. mask_paint->setOpacity(o * 0.01f);
  102. }, 100.0f);
  103. static const VectorValue default_feather = { 0, 0 };
  104. if (abuilder->bindProperty<VectorValue>((*m)["f"], ascope,
  105. [blur_effect](const VectorValue& feather) {
  106. // Close enough to AE.
  107. static constexpr SkScalar kFeatherToSigma = 0.38f;
  108. auto sX = feather.size() > 0 ? feather[0] * kFeatherToSigma : 0,
  109. sY = feather.size() > 1 ? feather[1] * kFeatherToSigma : 0;
  110. blur_effect->setSigma({ sX, sY });
  111. }, default_feather)) {
  112. has_effect = true;
  113. mask_stack.push_back({ mask_path,
  114. mask_paint,
  115. std::move(blur_effect),
  116. mask_info->fMergeMode});
  117. blur_effect = sksg::BlurImageFilter::Make();
  118. } else {
  119. mask_stack.push_back({mask_path, mask_paint, nullptr, mask_info->fMergeMode});
  120. }
  121. }
  122. if (mask_stack.empty())
  123. return childNode;
  124. // If the masks are fully opaque, we can clip.
  125. if (!has_effect) {
  126. sk_sp<sksg::GeometryNode> clip_node;
  127. if (mask_stack.count() == 1) {
  128. // Single path -> just clip.
  129. clip_node = std::move(mask_stack.front().mask_path);
  130. } else {
  131. // Multiple clip paths -> merge.
  132. std::vector<sksg::Merge::Rec> merge_recs;
  133. merge_recs.reserve(SkToSizeT(mask_stack.count()));
  134. for (auto& mask : mask_stack) {
  135. const auto mode = merge_recs.empty() ? sksg::Merge::Mode::kMerge : mask.merge_mode;
  136. merge_recs.push_back({std::move(mask.mask_path), mode});
  137. }
  138. clip_node = sksg::Merge::Make(std::move(merge_recs));
  139. }
  140. return sksg::ClipEffect::Make(std::move(childNode), std::move(clip_node), true);
  141. }
  142. const auto make_mask = [](const MaskRecord& rec) {
  143. auto mask = sksg::Draw::Make(std::move(rec.mask_path),
  144. std::move(rec.mask_paint));
  145. // Optional mask blur (feather).
  146. return sksg::ImageFilterEffect::Make(std::move(mask), std::move(rec.mask_blur));
  147. };
  148. sk_sp<sksg::RenderNode> maskNode;
  149. if (mask_stack.count() == 1) {
  150. // no group needed for single mask
  151. maskNode = make_mask(mask_stack.front());
  152. } else {
  153. std::vector<sk_sp<sksg::RenderNode>> masks;
  154. masks.reserve(SkToSizeT(mask_stack.count()));
  155. for (auto& rec : mask_stack) {
  156. masks.push_back(make_mask(rec));
  157. }
  158. maskNode = sksg::Group::Make(std::move(masks));
  159. }
  160. return sksg::MaskEffect::Make(std::move(childNode), std::move(maskNode));
  161. }
  162. class LayerController final : public sksg::Animator {
  163. public:
  164. LayerController(sksg::AnimatorList&& layer_animators,
  165. sk_sp<sksg::RenderNode> layer,
  166. size_t tanim_count, float in, float out)
  167. : fLayerAnimators(std::move(layer_animators))
  168. , fLayerNode(std::move(layer))
  169. , fTransformAnimatorsCount(tanim_count)
  170. , fIn(in)
  171. , fOut(out) {}
  172. protected:
  173. void onTick(float t) override {
  174. const auto active = (t >= fIn && t < fOut);
  175. if (fLayerNode) {
  176. fLayerNode->setVisible(active);
  177. }
  178. // When active, dispatch ticks to all layer animators.
  179. // When inactive, we must still dispatch ticks to the layer transform animators
  180. // (active child layers depend on transforms being updated).
  181. const auto dispatch_count = active ? fLayerAnimators.size()
  182. : fTransformAnimatorsCount;
  183. for (size_t i = 0; i < dispatch_count; ++i) {
  184. fLayerAnimators[i]->tick(t);
  185. }
  186. }
  187. private:
  188. const sksg::AnimatorList fLayerAnimators;
  189. const sk_sp<sksg::RenderNode> fLayerNode;
  190. const size_t fTransformAnimatorsCount;
  191. const float fIn,
  192. fOut;
  193. };
  194. class MotionBlurController final : public sksg::Animator {
  195. public:
  196. explicit MotionBlurController(sk_sp<MotionBlurEffect> mbe)
  197. : fMotionBlurEffect(std::move(mbe)) {}
  198. protected:
  199. // When motion blur is present, time ticks are not passed to layer animators
  200. // but to the motion blur effect. The effect then drives the animators/scene-graph
  201. // during reval and render phases.
  202. void onTick(float t) override {
  203. fMotionBlurEffect->setT(t);
  204. }
  205. private:
  206. const sk_sp<MotionBlurEffect> fMotionBlurEffect;
  207. };
  208. } // namespace
  209. AnimationBuilder::AttachLayerContext::AttachLayerContext(const skjson::ArrayValue& jlayers)
  210. : fLayerList(jlayers) {}
  211. AnimationBuilder::AttachLayerContext::~AttachLayerContext() = default;
  212. AnimationBuilder::AttachLayerContext::TransformRec
  213. AnimationBuilder::AttachLayerContext::attachLayerTransform(const skjson::ObjectValue& jlayer,
  214. const AnimationBuilder* abuilder,
  215. TransformType type) {
  216. TransformRec result;
  217. const auto layer_index = ParseDefault<int>(jlayer["ind"], -1);
  218. if (layer_index >= 0) {
  219. auto* rec = fLayerTransformMap.find(layer_index);
  220. if (!rec) {
  221. rec = this->attachLayerTransformImpl(jlayer, abuilder, type, layer_index);
  222. }
  223. SkASSERT(rec);
  224. // Note: the transform animator scope is *moved* to the result, because
  225. // we want the animators transferred to the LayerController.
  226. //
  227. // This is safe because a) the scope is not used internally, and
  228. // b) there is exactly one attachLayerTransform call per layer.
  229. // The transform node OTOH may be used at a later time for parenting.
  230. result.fTransformNode = rec->fTransformNode;
  231. result.fTransformScope = std::move(rec->fTransformScope);
  232. }
  233. return result;
  234. }
  235. sk_sp<sksg::Transform>
  236. AnimationBuilder::AttachLayerContext::attachParentLayerTransform(const skjson::ObjectValue& jlayer,
  237. const AnimationBuilder* abuilder,
  238. int layer_index) {
  239. const auto parent_index = ParseDefault<int>(jlayer["parent"], -1);
  240. if (parent_index < 0 || parent_index == layer_index)
  241. return nullptr;
  242. if (const auto* rec = fLayerTransformMap.find(parent_index))
  243. return rec->fTransformNode;
  244. for (const skjson::ObjectValue* l : fLayerList) {
  245. if (!l) continue;
  246. if (ParseDefault<int>((*l)["ind"], -1) == parent_index) {
  247. const auto parent_type = ParseDefault<int>((*l)["ty"], -1) == kCameraLayerType
  248. ? TransformType::kCamera
  249. : TransformType::kLayer;
  250. return this->attachLayerTransformImpl(*l,
  251. abuilder,
  252. parent_type,
  253. parent_index)->fTransformNode;
  254. }
  255. }
  256. return nullptr;
  257. }
  258. sk_sp<sksg::Transform>
  259. AnimationBuilder::AttachLayerContext::attachTransformNode(const skjson::ObjectValue& jlayer,
  260. const AnimationBuilder* abuilder,
  261. AnimatorScope* ascope,
  262. sk_sp<sksg::Transform> parent_transform,
  263. TransformType type) const {
  264. const skjson::ObjectValue* jtransform = jlayer["ks"];
  265. if (!jtransform) {
  266. return nullptr;
  267. }
  268. if (type == TransformType::kCamera) {
  269. auto camera_adapter = sk_make_sp<CameraAdapter>(abuilder->fSize);
  270. abuilder->bindProperty<ScalarValue>(jlayer["pe"], ascope,
  271. [camera_adapter] (const ScalarValue& pe) {
  272. // 'pe' (perspective?) corresponds to AE's "zoom" camera property.
  273. camera_adapter->setZoom(pe);
  274. });
  275. // parent_transform applies to the camera itself => it pre-composes inverted to the
  276. // camera/view/adapter transform.
  277. //
  278. // T_camera' = T_camera x Inv(parent_transform)
  279. //
  280. parent_transform = sksg::Transform::MakeInverse(std::move(parent_transform));
  281. return abuilder->attachMatrix3D(*jtransform, ascope,
  282. std::move(parent_transform),
  283. std::move(camera_adapter),
  284. true); // pre-compose parent
  285. }
  286. return (ParseDefault<int>(jlayer["ddd"], 0) == 0)
  287. ? abuilder->attachMatrix2D(*jtransform, ascope, std::move(parent_transform))
  288. : abuilder->attachMatrix3D(*jtransform, ascope, std::move(parent_transform));
  289. }
  290. AnimationBuilder::AttachLayerContext::TransformRec*
  291. AnimationBuilder::AttachLayerContext::attachLayerTransformImpl(const skjson::ObjectValue& jlayer,
  292. const AnimationBuilder* abuilder,
  293. TransformType type,
  294. int layer_index) {
  295. SkASSERT(!fLayerTransformMap.find(layer_index));
  296. // Add a stub entry to break recursion cycles.
  297. fLayerTransformMap.set(layer_index, { nullptr, {} });
  298. auto parent_matrix = this->attachParentLayerTransform(jlayer, abuilder, layer_index);
  299. AnimatorScope ascope;
  300. auto transform = this->attachTransformNode(jlayer,
  301. abuilder,
  302. &ascope,
  303. std::move(parent_matrix),
  304. type);
  305. return fLayerTransformMap.set(layer_index, { std::move(transform), std::move(ascope) });
  306. }
  307. bool AnimationBuilder::AttachLayerContext::hasMotionBlur(const skjson::ObjectValue& jlayer) const {
  308. return fMotionBlurSamples > 1
  309. && fMotionBlurAngle > 0
  310. && ParseDefault(jlayer["mb"], false);
  311. }
  312. sk_sp<sksg::RenderNode> AnimationBuilder::attachLayer(const skjson::ObjectValue* jlayer,
  313. AnimatorScope* ascope,
  314. AttachLayerContext* layerCtx) const {
  315. if (!jlayer) {
  316. return nullptr;
  317. }
  318. LayerInfo layer_info = {
  319. fSize,
  320. ParseDefault<float>((*jlayer)["ip"], 0.0f),
  321. ParseDefault<float>((*jlayer)["op"], 0.0f),
  322. };
  323. if (layer_info.fInPoint >= layer_info.fOutPoint) {
  324. this->log(Logger::Level::kError, nullptr,
  325. "Invalid layer in/out points: %f/%f.", layer_info.fInPoint, layer_info.fOutPoint);
  326. return nullptr;
  327. }
  328. const AutoPropertyTracker apt(this, *jlayer);
  329. using LayerBuilder = sk_sp<sksg::RenderNode> (AnimationBuilder::*)(const skjson::ObjectValue&,
  330. LayerInfo*,
  331. AnimatorScope*) const;
  332. // AE is annoyingly inconsistent in how effects interact with layer transforms: depending on
  333. // the layer type, effects are applied before or after the content is transformed.
  334. //
  335. // Empirically, pre-rendered layers (for some loose meaning of "pre-rendered") are in the
  336. // former category (effects are subject to transformation), while the remaining types are in
  337. // the latter.
  338. enum : uint32_t {
  339. kTransformEffects = 1, // The layer transform also applies to its effects.
  340. };
  341. static constexpr struct {
  342. LayerBuilder fBuilder;
  343. uint32_t fFlags;
  344. } gLayerBuildInfo[] = {
  345. { &AnimationBuilder::attachPrecompLayer, kTransformEffects }, // 'ty': 0 -> precomp
  346. { &AnimationBuilder::attachSolidLayer , kTransformEffects }, // 'ty': 1 -> solid
  347. { &AnimationBuilder::attachImageLayer , kTransformEffects }, // 'ty': 2 -> image
  348. { &AnimationBuilder::attachNullLayer , 0 }, // 'ty': 3 -> null
  349. { &AnimationBuilder::attachShapeLayer , 0 }, // 'ty': 4 -> shape
  350. { &AnimationBuilder::attachTextLayer , 0 }, // 'ty': 5 -> text
  351. };
  352. const auto type = ParseDefault<int>((*jlayer)["ty"], -1);
  353. if ((type < 0) ||
  354. (type >= SkTo<int>(SK_ARRAY_COUNT(gLayerBuildInfo)) && type != kCameraLayerType)) {
  355. return nullptr;
  356. }
  357. // Optional layer transform.
  358. const auto transform_type = (type == kCameraLayerType)
  359. ? AttachLayerContext::TransformType::kCamera
  360. : AttachLayerContext::TransformType::kLayer;
  361. auto layer_transform_rec = layerCtx->attachLayerTransform(*jlayer, this, transform_type);
  362. if (type == kCameraLayerType) {
  363. // Camera layers are special: they don't build normal SG fragments, but drive a root-level
  364. // transform.
  365. if (layerCtx->fCameraTransform) {
  366. this->log(Logger::Level::kWarning, jlayer, "Ignoring duplicate camera layer.");
  367. return nullptr;
  368. }
  369. layerCtx->fCameraTransform = layer_transform_rec.fTransformNode;
  370. }
  371. AnimatorScope layer_animators = std::move(layer_transform_rec.fTransformScope);
  372. const auto transform_animator_count = layer_animators.size();
  373. const auto is_hidden = ParseDefault<bool>((*jlayer)["hd"], false) || type == kCameraLayerType;
  374. const auto& build_info = gLayerBuildInfo[is_hidden ? kNullLayerType : type];
  375. // Build the layer content fragment.
  376. auto layer = (this->*(build_info.fBuilder))(*jlayer, &layer_info, &layer_animators);
  377. // Clip layers with explicit dimensions.
  378. float w = 0, h = 0;
  379. if (Parse<float>((*jlayer)["w"], &w) && Parse<float>((*jlayer)["h"], &h)) {
  380. layer = sksg::ClipEffect::Make(std::move(layer),
  381. sksg::Rect::Make(SkRect::MakeWH(w, h)),
  382. true);
  383. }
  384. // Optional layer mask.
  385. layer = AttachMask((*jlayer)["masksProperties"], this, &layer_animators, std::move(layer));
  386. // Does the transform apply to effects also?
  387. // (AE quirk: it doesn't - except for solid layers)
  388. const auto transform_effects = (build_info.fFlags & kTransformEffects);
  389. // Attach the transform before effects, when needed.
  390. if (layer_transform_rec.fTransformNode && !transform_effects) {
  391. layer = sksg::TransformEffect::Make(std::move(layer), layer_transform_rec.fTransformNode);
  392. }
  393. // Optional layer effects.
  394. if (const skjson::ArrayValue* jeffects = (*jlayer)["ef"]) {
  395. layer = EffectBuilder(this, layer_info.fSize, &layer_animators)
  396. .attachEffects(*jeffects, std::move(layer));
  397. }
  398. // Attach the transform after effects, when needed.
  399. if (layer_transform_rec.fTransformNode && transform_effects) {
  400. layer = sksg::TransformEffect::Make(std::move(layer),
  401. std::move(layer_transform_rec.fTransformNode));
  402. }
  403. // Optional layer opacity.
  404. // TODO: de-dupe this "ks" lookup with matrix above.
  405. if (const skjson::ObjectValue* jtransform = (*jlayer)["ks"]) {
  406. layer = this->attachOpacity(*jtransform, &layer_animators, std::move(layer));
  407. }
  408. // Optional blend mode.
  409. layer = this->attachBlendMode(*jlayer, std::move(layer));
  410. const auto has_animators = !layer_animators.empty();
  411. sk_sp<sksg::Animator> controller = sk_make_sp<LayerController>(std::move(layer_animators),
  412. layer,
  413. transform_animator_count,
  414. layer_info.fInPoint,
  415. layer_info.fOutPoint);
  416. // Optional motion blur.
  417. if (has_animators && layerCtx->hasMotionBlur(*jlayer)) {
  418. SkASSERT(layerCtx->fMotionBlurAngle >= 0);
  419. // Wrap both the layer node and the controller.
  420. auto motion_blur = MotionBlurEffect::Make(std::move(controller), std::move(layer),
  421. layerCtx->fMotionBlurSamples,
  422. layerCtx->fMotionBlurAngle,
  423. layerCtx->fMotionBlurPhase);
  424. controller = sk_make_sp<MotionBlurController>(motion_blur);
  425. layer = std::move(motion_blur);
  426. }
  427. ascope->push_back(std::move(controller));
  428. if (!layer) {
  429. return nullptr;
  430. }
  431. if (ParseDefault<bool>((*jlayer)["td"], false)) {
  432. // This layer is a matte. We apply it as a mask to the next layer.
  433. layerCtx->fCurrentMatte = std::move(layer);
  434. return nullptr;
  435. }
  436. if (layerCtx->fCurrentMatte) {
  437. // There is a pending matte. Apply and reset.
  438. static constexpr sksg::MaskEffect::Mode gMaskModes[] = {
  439. sksg::MaskEffect::Mode::kNormal, // tt: 1
  440. sksg::MaskEffect::Mode::kInvert, // tt: 2
  441. };
  442. const auto matteType = ParseDefault<size_t>((*jlayer)["tt"], 1) - 1;
  443. if (matteType < SK_ARRAY_COUNT(gMaskModes)) {
  444. return sksg::MaskEffect::Make(std::move(layer),
  445. std::move(layerCtx->fCurrentMatte),
  446. gMaskModes[matteType]);
  447. }
  448. layerCtx->fCurrentMatte.reset();
  449. }
  450. return layer;
  451. }
  452. } // namespace internal
  453. } // namespace skottie