[skottie] Convert (most of) SkottieSlide2 to SkSceneGraph

Each Skottie animation is now a transformed sksg node.

TBR=

Change-Id: Ib5c153e8279e1a74a242b0eb193c4463898b09ea
Reviewed-on: https://skia-review.googlesource.com/102201
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Florin Malita <fmalita@chromium.org>
This commit is contained in:
Florin Malita 2018-01-31 11:08:58 -05:00 committed by Skia Commit-Bot
parent 75454f58f5
commit bcd07230eb
3 changed files with 90 additions and 22 deletions

View File

@ -1970,6 +1970,7 @@ if (skia_enable_tools) {
include_dirs = []
deps = [
":experimental_skottie",
":experimental_sksg",
":flags",
":gm",
":gpu_tool_utils",

View File

@ -11,6 +11,7 @@
#include "Slide.h"
namespace skottie { class Animation; }
namespace sksg { class Scene; }
class SkottieSlide : public Slide {
public:
@ -50,20 +51,23 @@ public:
bool animate(const SkAnimTimer&) override;
bool onMouse(SkScalar x, SkScalar y, sk_app::Window::InputState, uint32_t modifiers) override;
private:
class AnimationWrapper;
struct Rec {
std::unique_ptr<skottie::Animation> fAnimation;
sk_sp<AnimationWrapper> fWrapper;
SkMSec fTimeBase = 0;
SkString fName;
bool fShowAnimationInval = false;
Rec(std::unique_ptr<skottie::Animation> anim);
explicit Rec(sk_sp<AnimationWrapper>);
Rec(Rec&& o);
};
int findCell(float x, float y) const;
SkString fPath;
SkTArray<Rec> fAnims;
SkString fPath;
SkTArray<Rec> fAnims;
std::unique_ptr<sksg::Scene> fScene;
int fTrackingCell = -1;

View File

@ -12,24 +12,52 @@
#include "Skottie.h"
#include "SkOSFile.h"
#include "SkOSPath.h"
#include "SkSGGroup.h"
#include "SkSGRenderNode.h"
#include "SkSGScene.h"
#include "SkSGTransform.h"
#include "SkStream.h"
const int CELL_WIDTH = 240;
const int CELL_HEIGHT = 160;
const int COL_COUNT = 4;
const int SPACER_X = 12;
const int SPACER_Y = 24;
const int MARGIN = 8;
static constexpr int CELL_WIDTH = 240;
static constexpr int CELL_HEIGHT = 160;
static constexpr int COL_COUNT = 4;
static constexpr int SPACER_X = 12;
static constexpr int SPACER_Y = 24;
static constexpr int MARGIN = 8;
SkottieSlide2::Rec::Rec(std::unique_ptr<skottie::Animation> anim) : fAnimation(std::move(anim))
{}
class SkottieSlide2::AnimationWrapper final : public sksg::RenderNode {
public:
explicit AnimationWrapper(std::unique_ptr<skottie::Animation> anim)
: fAnimation(std::move(anim)) {
SkASSERT(fAnimation);
}
SkottieSlide2::Rec::Rec(Rec&& o)
: fAnimation(std::move(o.fAnimation))
, fTimeBase(o.fTimeBase)
, fName(o.fName)
, fShowAnimationInval(o.fShowAnimationInval)
{}
void tick(SkMSec t) {
fAnimation->animationTick(t);
this->invalidate();
}
void setShowInval(bool show) { fAnimation->setShowInval(show); }
protected:
SkRect onRevalidate(sksg::InvalidationController* ic, const SkMatrix& ctm) override {
return SkRect::MakeSize(fAnimation->size());
}
void onRender(SkCanvas* canvas) const override {
fAnimation->render(canvas);
}
private:
const std::unique_ptr<skottie::Animation> fAnimation;
using INHERITED = sksg::RenderNode;
};
SkottieSlide2::Rec::Rec(sk_sp<AnimationWrapper> wrapper)
: fWrapper(std::move(wrapper)) {}
SkottieSlide2::Rec::Rec(Rec&& o) = default;
SkottieSlide2::SkottieSlide2(const SkString& path)
: fPath(path)
@ -40,16 +68,49 @@ SkottieSlide2::SkottieSlide2(const SkString& path)
void SkottieSlide2::load(SkScalar, SkScalar) {
SkString name;
SkOSFile::Iter iter(fPath.c_str(), "json");
int x = 0, y = 0;
// Build a global scene using tranformed animation fragments:
//
// [Group]
// [Transform]
// [AnimationWrapper]
// [Transform]
// [AnimationWrapper]
// ...
//
// Note: for now animation wrappers are also tracked externally in fAnims, for tick dispatching.
auto scene_root = sksg::Group::Make();
while (iter.next(&name)) {
SkString path = SkOSPath::Join(fPath.c_str(), name.c_str());
if (auto anim = skottie::Animation::MakeFromFile(path.c_str())) {
fAnims.push_back(Rec(std::move(anim))).fName = name;
const SkRect src = SkRect::MakeSize(anim->size()),
dst = SkRect::MakeXYWH(MARGIN + x * (CELL_WIDTH + SPACER_X),
MARGIN + y * (CELL_HEIGHT + SPACER_Y),
CELL_WIDTH, CELL_HEIGHT);
auto wrapper = sk_make_sp<AnimationWrapper>(std::move(anim));
auto matrix = sksg::Matrix::Make(
SkMatrix::MakeRectToRect(src, dst, SkMatrix::kCenter_ScaleToFit));
auto xform = sksg::Transform::Make(wrapper, std::move(matrix));
scene_root->addChild(xform);
fAnims.emplace_back(std::move(wrapper)).fName = name;
if (++x == COL_COUNT) {
x = 0;
y += 1;
}
}
}
fScene = sksg::Scene::Make(std::move(scene_root), sksg::AnimatorList());
}
void SkottieSlide2::unload() {
fAnims.reset();
fScene.reset();
}
SkISize SkottieSlide2::getDimensions() const {
@ -61,6 +122,9 @@ SkISize SkottieSlide2::getDimensions() const {
}
void SkottieSlide2::draw(SkCanvas* canvas) {
fScene->render(canvas);
// TODO: this is all only to draw labels; replace with sksg::Text nodes, when available.
SkPaint paint;
paint.setTextSize(12);
paint.setAntiAlias(true);
@ -75,7 +139,6 @@ void SkottieSlide2::draw(SkCanvas* canvas) {
canvas->translate(x * (CELL_WIDTH + SPACER_X), y * (CELL_HEIGHT + SPACER_Y));
canvas->drawText(rec.fName.c_str(), rec.fName.size(),
dst.centerX(), dst.bottom() + paint.getTextSize(), paint);
rec.fAnimation->render(canvas, &dst);
if (++x == COL_COUNT) {
x = 0;
y += 1;
@ -89,7 +152,7 @@ bool SkottieSlide2::animate(const SkAnimTimer& timer) {
// Reset the animation time.
rec.fTimeBase = timer.msec();
}
rec.fAnimation->animationTick(timer.msec() - rec.fTimeBase);
rec.fWrapper->tick(timer.msec() - rec.fTimeBase);
}
return true;
}
@ -103,7 +166,7 @@ bool SkottieSlide2::onMouse(SkScalar x, SkScalar y, sk_app::Window::InputState s
int index = this->findCell(x, y);
if (fTrackingCell == index) {
fAnims[index].fShowAnimationInval = !fAnims[index].fShowAnimationInval;
fAnims[index].fAnimation->setShowInval(fAnims[index].fShowAnimationInval);
fAnims[index].fWrapper->setShowInval(fAnims[index].fShowAnimationInval);
}
fTrackingCell = -1;
}