aboutsummaryrefslogtreecommitdiffhomepage
path: root/experimental
diff options
context:
space:
mode:
authorGravatar Florin Malita <fmalita@chromium.org>2018-01-22 12:57:06 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-01-22 18:31:17 +0000
commit35efaa8fd7538f636dfd3593f172a961745a5cd8 (patch)
tree30ecabe76f9e9f826cbc65a729f9656648c69b24 /experimental
parent5d750edfdd4fcf75bc51155f29f553bb0c46b59d (diff)
[sksg] Animator, Scene
Relocate some reusable logic from Skottie TBR= Change-Id: I8764e666c9f1127ed895ee1d16cd66d052469ac5 Reviewed-on: https://skia-review.googlesource.com/98160 Reviewed-by: Florin Malita <fmalita@chromium.org> Commit-Queue: Florin Malita <fmalita@chromium.org>
Diffstat (limited to 'experimental')
-rw-r--r--experimental/skottie/Skottie.cpp59
-rw-r--r--experimental/skottie/Skottie.h21
-rw-r--r--experimental/skottie/SkottieAnimator.h15
-rw-r--r--experimental/sksg/SkSGScene.cpp61
-rw-r--r--experimental/sksg/SkSGScene.h73
5 files changed, 170 insertions, 59 deletions
diff --git a/experimental/skottie/Skottie.cpp b/experimental/skottie/Skottie.cpp
index 7a08cec9df..becf3bf470 100644
--- a/experimental/skottie/Skottie.cpp
+++ b/experimental/skottie/Skottie.cpp
@@ -31,6 +31,7 @@
#include "SkSGOpacityEffect.h"
#include "SkSGPath.h"
#include "SkSGRect.h"
+#include "SkSGScene.h"
#include "SkSGTransform.h"
#include "SkSGTrimEffect.h"
#include "SkStream.h"
@@ -50,9 +51,9 @@ namespace {
using AssetMap = SkTHashMap<SkString, const Json::Value*>;
struct AttachContext {
- const ResourceProvider& fResources;
- const AssetMap& fAssets;
- SkTArray<std::unique_ptr<AnimatorBase>>& fAnimators;
+ const ResourceProvider& fResources;
+ const AssetMap& fAssets;
+ sksg::Scene::AnimatorList& fAnimators;
};
bool LogFail(const Json::Value& json, const char* msg) {
@@ -878,14 +879,14 @@ sk_sp<sksg::RenderNode> AttachLayer(const Json::Value& jlayer,
layer = AttachOpacity(jlayer["ks"], layerCtx->fCtx, std::move(layer));
// TODO: we should also disable related/inactive animators.
- class Activator final : public AnimatorBase {
+ class Activator final : public sksg::Animator {
public:
Activator(sk_sp<sksg::OpacityEffect> controlNode, float in, float out)
: fControlNode(std::move(controlNode))
, fIn(in)
, fOut(out) {}
- void tick(float t) override {
+ void onTick(float t) override {
// Keep the layer fully transparent except for its [in..out] lifespan.
// (note: opacity == 0 disables rendering, while opacity == 1 is a noop)
fControlNode->setOpacity(t >= fIn && t <= fOut ? 1 : 0);
@@ -1035,59 +1036,49 @@ Animation::Animation(const ResourceProvider& resources,
assets.set(ParseString(asset["id"], ""), &asset);
}
- AttachContext ctx = { resources, assets, fAnimators };
- fDom = AttachComposition(json, &ctx);
+ sksg::Scene::AnimatorList animators;
+ AttachContext ctx = { resources, assets, animators };
+ auto root = AttachComposition(json, &ctx);
+
+ LOG("** Attached %d animators\n", animators.size());
+
+ fScene = sksg::Scene::Make(std::move(root), std::move(animators));
// In case the client calls render before the first tick.
this->animationTick(0);
-
- LOG("** Attached %d animators\n", fAnimators.count());
}
Animation::~Animation() = default;
+void Animation::setShowInval(bool show) {
+ if (fScene) {
+ fScene->setShowInval(show);
+ }
+}
+
void Animation::render(SkCanvas* canvas, const SkRect* dstR) const {
- if (!fDom)
+ if (!fScene)
return;
- sksg::InvalidationController ic;
- fDom->revalidate(&ic, SkMatrix::I());
-
- // TODO: proper inval
SkAutoCanvasRestore restore(canvas, true);
const SkRect srcR = SkRect::MakeSize(this->size());
if (dstR) {
canvas->concat(SkMatrix::MakeRectToRect(srcR, *dstR, SkMatrix::kCenter_ScaleToFit));
}
canvas->clipRect(srcR);
- fDom->render(canvas);
-
- if (!fShowInval)
- return;
-
- SkPaint fill, stroke;
- fill.setAntiAlias(true);
- fill.setColor(0x40ff0000);
- stroke.setAntiAlias(true);
- stroke.setColor(0xffff0000);
- stroke.setStyle(SkPaint::kStroke_Style);
-
- for (const auto& r : ic) {
- canvas->drawRect(r, fill);
- canvas->drawRect(r, stroke);
- }
+ fScene->render(canvas);
}
void Animation::animationTick(SkMSec ms) {
+ if (!fScene)
+ return;
+
// 't' in the BM model really means 'frame #'
auto t = static_cast<float>(ms) * fFrameRate / 1000;
t = fInPoint + std::fmod(t, fOutPoint - fInPoint);
- // TODO: this can be optimized quite a bit with some sorting/state tracking.
- for (const auto& a : fAnimators) {
- a->tick(t);
- }
+ fScene->animate(t);
}
} // namespace skottie
diff --git a/experimental/skottie/Skottie.h b/experimental/skottie/Skottie.h
index e13bd0ae98..d2486dc946 100644
--- a/experimental/skottie/Skottie.h
+++ b/experimental/skottie/Skottie.h
@@ -23,12 +23,10 @@ class SkStream;
namespace Json { class Value; }
-namespace sksg { class RenderNode; }
+namespace sksg { class Scene; }
namespace skottie {
-class AnimatorBase;
-
class ResourceProvider : public SkNoncopyable {
public:
virtual ~ResourceProvider() = default;
@@ -54,23 +52,20 @@ public:
SkScalar inPoint() const { return fInPoint; }
SkScalar outPoint() const { return fOutPoint; }
- void setShowInval(bool show) { fShowInval = show; }
+ void setShowInval(bool show);
private:
Animation(const ResourceProvider&,
SkString ver, const SkSize& size, SkScalar fps,
const Json::Value&);
- SkString fVersion;
- SkSize fSize;
- SkScalar fFrameRate,
- fInPoint,
- fOutPoint;
-
- sk_sp<sksg::RenderNode> fDom;
- SkTArray<std::unique_ptr<AnimatorBase>> fAnimators;
+ SkString fVersion;
+ SkSize fSize;
+ SkScalar fFrameRate,
+ fInPoint,
+ fOutPoint;
- bool fShowInval = false;
+ std::unique_ptr<sksg::Scene> fScene;
typedef SkNoncopyable INHERITED;
};
diff --git a/experimental/skottie/SkottieAnimator.h b/experimental/skottie/SkottieAnimator.h
index 4e63e12833..4ab877ecaf 100644
--- a/experimental/skottie/SkottieAnimator.h
+++ b/experimental/skottie/SkottieAnimator.h
@@ -12,6 +12,7 @@
#include "SkMakeUnique.h"
#include "SkottiePriv.h"
#include "SkottieProperties.h"
+#include "SkSGScene.h"
#include "SkTypes.h"
#include <memory>
@@ -19,16 +20,6 @@
namespace skottie {
-class AnimatorBase : public SkNoncopyable {
-public:
- virtual ~AnimatorBase() = default;
-
- virtual void tick(float) = 0;
-
-protected:
- AnimatorBase() = default;
-};
-
class KeyframeIntervalBase : public SkNoncopyable {
public:
KeyframeIntervalBase() = default;
@@ -112,7 +103,7 @@ std::vector<KeyframeInterval<T>> ParseFrames(const Json::Value& jframes) {
// Binds an animated/keyframed property to a node attribute setter.
template <typename ValT, typename NodeT>
-class Animator : public AnimatorBase {
+class Animator final : public sksg::Animator {
public:
using ApplyFuncT = void(*)(NodeT*, const ValT&);
static std::unique_ptr<Animator> Make(std::vector<KeyframeInterval<ValT>>&& frames,
@@ -125,7 +116,7 @@ public:
: nullptr;
}
- void tick(float t) override {
+ void onTick(float t) override {
const auto& frame = this->findFrame(t);
ValT val;
diff --git a/experimental/sksg/SkSGScene.cpp b/experimental/sksg/SkSGScene.cpp
new file mode 100644
index 0000000000..85a1b43b1c
--- /dev/null
+++ b/experimental/sksg/SkSGScene.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkSGScene.h"
+
+#include "SkCanvas.h"
+#include "SkMatrix.h"
+#include "SkPaint.h"
+#include "SkSGInvalidationController.h"
+#include "SkSGRenderNode.h"
+
+namespace sksg {
+
+Animator::Animator() = default;
+Animator::~Animator() = default;
+
+void Animator::tick(float t) {
+ this->onTick(t);
+}
+
+std::unique_ptr<Scene> Scene::Make(sk_sp<RenderNode> root, AnimatorList&& anims) {
+ return root ? std::unique_ptr<Scene>(new Scene(std::move(root), std::move(anims))) : nullptr;
+}
+
+Scene::Scene(sk_sp<RenderNode> root, AnimatorList&& animators)
+ : fRoot(std::move(root))
+ , fAnimators(std::move(animators)) {}
+
+Scene::~Scene() = default;
+
+void Scene::render(SkCanvas* canvas) const {
+ InvalidationController ic;
+ fRoot->revalidate(&ic, SkMatrix::I());
+ fRoot->render(canvas);
+
+ if (fShowInval) {
+ SkPaint fill, stroke;
+ fill.setAntiAlias(true);
+ fill.setColor(0x40ff0000);
+ stroke.setAntiAlias(true);
+ stroke.setColor(0xffff0000);
+ stroke.setStyle(SkPaint::kStroke_Style);
+
+ for (const auto& r : ic) {
+ canvas->drawRect(r, fill);
+ canvas->drawRect(r, stroke);
+ }
+ }
+}
+
+void Scene::animate(float t) {
+ for (const auto& anim : fAnimators) {
+ anim->tick(t);
+ }
+}
+
+} // namespace sksg
diff --git a/experimental/sksg/SkSGScene.h b/experimental/sksg/SkSGScene.h
new file mode 100644
index 0000000000..32186498d2
--- /dev/null
+++ b/experimental/sksg/SkSGScene.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkSGScene_DEFINED
+#define SkSGScene_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkTypes.h"
+
+#include <memory>
+#include <vector>
+
+class SkCanvas;
+
+namespace sksg {
+
+class RenderNode;
+
+/**
+ * Base class for animators.
+ *
+ */
+class Animator : public SkNoncopyable {
+public:
+ virtual ~Animator();
+
+ void tick(float t);
+
+protected:
+ Animator();
+
+ virtual void onTick(float t) = 0;
+
+private:
+ using INHERITED = SkNoncopyable;
+};
+
+/**
+ * Holds a scene root and a list of animators.
+ *
+ * Provides high-level mehods for driving rendering and animations.
+ *
+ */
+class Scene final : SkNoncopyable {
+public:
+ using AnimatorList = std::vector<std::unique_ptr<Animator>>;
+
+ static std::unique_ptr<Scene> Make(sk_sp<RenderNode> root, AnimatorList&& animators);
+ ~Scene();
+
+ void render(SkCanvas*) const;
+ void animate(float t);
+
+ void setShowInval(bool show) { fShowInval = show; }
+
+private:
+ Scene(sk_sp<RenderNode> root, AnimatorList&& animators);
+
+ const sk_sp<RenderNode> fRoot;
+ const AnimatorList fAnimators;
+
+ bool fShowInval = false;
+
+ using INHERITED = SkNoncopyable;
+};
+
+} // namespace sksg
+
+#endif // SkSGScene_DEFINED