aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--experimental/skottie/Skottie.cpp32
-rw-r--r--experimental/skottie/Skottie.h15
-rw-r--r--tools/viewer/SkottieSlide.cpp50
-rw-r--r--tools/viewer/SkottieSlide.h6
4 files changed, 87 insertions, 16 deletions
diff --git a/experimental/skottie/Skottie.cpp b/experimental/skottie/Skottie.cpp
index a3b6d46b93..bb98ad75f0 100644
--- a/experimental/skottie/Skottie.cpp
+++ b/experimental/skottie/Skottie.cpp
@@ -38,6 +38,7 @@
#include "SkSGTrimEffect.h"
#include "SkStream.h"
#include "SkTArray.h"
+#include "SkTime.h"
#include "SkTHash.h"
#include <cmath>
@@ -1170,13 +1171,20 @@ sk_sp<sksg::RenderNode> AttachComposition(const Json::Value& comp, AttachContext
} // namespace
-sk_sp<Animation> Animation::Make(SkStream* stream, const ResourceProvider& res) {
+sk_sp<Animation> Animation::Make(SkStream* stream, const ResourceProvider& res, Stats* stats) {
+ Stats stats_storage;
+ if (!stats)
+ stats = &stats_storage;
+ memset(stats, 0, sizeof(struct Stats));
+
if (!stream->hasLength()) {
// TODO: handle explicit buffering?
LOG("!! cannot parse streaming content\n");
return nullptr;
}
+ const auto t0 = SkTime::GetMSecs();
+
Json::Value json;
{
auto data = SkData::MakeFromStream(stream, stream->getLength());
@@ -1184,6 +1192,7 @@ sk_sp<Animation> Animation::Make(SkStream* stream, const ResourceProvider& res)
LOG("!! could not read stream\n");
return nullptr;
}
+ stats->fJsonSize = data->size();
Json::Reader reader;
@@ -1194,6 +1203,9 @@ sk_sp<Animation> Animation::Make(SkStream* stream, const ResourceProvider& res)
}
}
+ const auto t1 = SkTime::GetMSecs();
+ stats->fJsonParseTimeMS = t1 - t0;
+
const auto version = ParseDefault(json["v"], SkString());
const auto size = SkSize::Make(ParseDefault(json["w"], 0.0f),
ParseDefault(json["h"], 0.0f));
@@ -1205,10 +1217,17 @@ sk_sp<Animation> Animation::Make(SkStream* stream, const ResourceProvider& res)
return nullptr;
}
- return sk_sp<Animation>(new Animation(res, std::move(version), size, fps, json));
+ const auto anim =
+ sk_sp<Animation>(new Animation(res, std::move(version), size, fps, json, stats));
+ const auto t2 = SkTime::GetMSecs();
+ stats->fSceneParseTimeMS = t2 - t1;
+ stats->fTotalLoadTimeMS = t2 - t0;
+
+ return anim;
}
-sk_sp<Animation> Animation::MakeFromFile(const char path[], const ResourceProvider* res) {
+sk_sp<Animation> Animation::MakeFromFile(const char path[], const ResourceProvider* res,
+ Stats* stats) {
class DirectoryResourceProvider final : public ResourceProvider {
public:
explicit DirectoryResourceProvider(SkString dir) : fDir(std::move(dir)) {}
@@ -1231,11 +1250,12 @@ sk_sp<Animation> Animation::MakeFromFile(const char path[], const ResourceProvid
defaultProvider = skstd::make_unique<DirectoryResourceProvider>(SkOSPath::Dirname(path));
}
- return Make(jsonStream.get(), res ? *res : *defaultProvider);
+ return Make(jsonStream.get(), res ? *res : *defaultProvider, stats);
}
Animation::Animation(const ResourceProvider& resources,
- SkString version, const SkSize& size, SkScalar fps, const Json::Value& json)
+ SkString version, const SkSize& size, SkScalar fps, const Json::Value& json,
+ Stats* stats)
: fVersion(std::move(version))
, fSize(size)
, fFrameRate(fps)
@@ -1255,7 +1275,7 @@ Animation::Animation(const ResourceProvider& resources,
AttachContext ctx = { resources, assets, fFrameRate, animators };
auto root = AttachComposition(json, &ctx);
- LOG("** Attached %d animators\n", animators.size());
+ stats->fAnimatorCount = animators.size();
fScene = sksg::Scene::Make(std::move(root), std::move(animators));
diff --git a/experimental/skottie/Skottie.h b/experimental/skottie/Skottie.h
index f14c4dc42b..44541fd81b 100644
--- a/experimental/skottie/Skottie.h
+++ b/experimental/skottie/Skottie.h
@@ -36,8 +36,17 @@ public:
class Animation : public SkRefCnt {
public:
- static sk_sp<Animation> Make(SkStream*, const ResourceProvider&);
- static sk_sp<Animation> MakeFromFile(const char path[], const ResourceProvider* = nullptr);
+ struct Stats {
+ float fTotalLoadTimeMS,
+ fJsonParseTimeMS,
+ fSceneParseTimeMS;
+ size_t fJsonSize,
+ fAnimatorCount;
+ };
+
+ static sk_sp<Animation> Make(SkStream*, const ResourceProvider&, Stats* = nullptr);
+ static sk_sp<Animation> MakeFromFile(const char path[], const ResourceProvider* = nullptr,
+ Stats* = nullptr);
~Animation() override;
@@ -56,7 +65,7 @@ public:
private:
Animation(const ResourceProvider&,
SkString ver, const SkSize& size, SkScalar fps,
- const Json::Value&);
+ const Json::Value&, Stats*);
SkString fVersion;
SkSize fSize;
diff --git a/tools/viewer/SkottieSlide.cpp b/tools/viewer/SkottieSlide.cpp
index 77501d8a9f..78cda5cbda 100644
--- a/tools/viewer/SkottieSlide.cpp
+++ b/tools/viewer/SkottieSlide.cpp
@@ -11,13 +11,51 @@
#include "SkCanvas.h"
#include "Skottie.h"
+static void draw_stats_box(SkCanvas* canvas, const skottie::Animation::Stats& stats) {
+ static constexpr SkRect kR = { 10, 10, 280, 120 };
+ static constexpr SkScalar kTextSize = 20;
+
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setColor(0xffeeeeee);
+ paint.setTextSize(kTextSize);
+
+ canvas->drawRect(kR, paint);
+
+ paint.setColor(SK_ColorBLACK);
+
+ const auto json_size = SkStringPrintf("Json size: %lu bytes",
+ stats.fJsonSize);
+ canvas->drawText(json_size.c_str(),
+ json_size.size(), kR.x() + 10, kR.y() + kTextSize * 1, paint);
+ const auto animator_count = SkStringPrintf("Animator count: %lu",
+ stats.fAnimatorCount);
+ canvas->drawText(animator_count.c_str(),
+ animator_count.size(), kR.x() + 10, kR.y() + kTextSize * 2, paint);
+ const auto json_parse_time = SkStringPrintf("Json parse time: %.3f ms",
+ stats.fJsonParseTimeMS);
+ canvas->drawText(json_parse_time.c_str(),
+ json_parse_time.size(), kR.x() + 10, kR.y() + kTextSize * 3, paint);
+ const auto scene_parse_time = SkStringPrintf("Scene build time: %.3f ms",
+ stats.fSceneParseTimeMS);
+ canvas->drawText(scene_parse_time.c_str(),
+ scene_parse_time.size(), kR.x() + 10, kR.y() + kTextSize * 4, paint);
+ const auto total_load_time = SkStringPrintf("Total load time: %.3f ms",
+ stats.fTotalLoadTimeMS);
+ canvas->drawText(total_load_time.c_str(),
+ total_load_time.size(), kR.x() + 10, kR.y() + kTextSize * 5, paint);
+
+ paint.setStyle(SkPaint::kStroke_Style);
+ canvas->drawRect(kR, paint);
+}
+
SkottieSlide::SkottieSlide(const SkString& name, const SkString& path)
: fPath(path) {
fName = name;
}
void SkottieSlide::load(SkScalar w, SkScalar h) {
- fAnimation = skottie::Animation::MakeFromFile(fPath.c_str());
+ fAnimation = skottie::Animation::MakeFromFile(fPath.c_str(), nullptr, &fAnimationStats);
fWinSize = SkSize::Make(w, h);
fTimeBase = 0; // force a time reset
@@ -47,6 +85,10 @@ void SkottieSlide::draw(SkCanvas* canvas) {
SkAutoCanvasRestore acr(canvas, true);
const auto dstR = SkRect::MakeSize(fWinSize);
fAnimation->render(canvas, &dstR);
+
+ if (fShowAnimationStats) {
+ draw_stats_box(canvas, fAnimationStats);
+ }
}
}
@@ -66,10 +108,7 @@ bool SkottieSlide::animate(const SkAnimTimer& timer) {
bool SkottieSlide::onChar(SkUnichar c) {
switch (c) {
case 'I':
- if (fAnimation) {
- fShowAnimationInval = !fShowAnimationInval;
- fAnimation->setShowInval(fShowAnimationInval);
- }
+ fShowAnimationStats = !fShowAnimationStats;
break;
default:
break;
@@ -82,6 +121,7 @@ bool SkottieSlide::onMouse(SkScalar x, SkScalar y, sk_app::Window::InputState st
switch (state) {
case sk_app::Window::kUp_InputState:
fShowAnimationInval = !fShowAnimationInval;
+ fShowAnimationStats = !fShowAnimationStats;
fAnimation->setShowInval(fShowAnimationInval);
break;
default:
diff --git a/tools/viewer/SkottieSlide.h b/tools/viewer/SkottieSlide.h
index b5770a0cf8..0bfe66eef4 100644
--- a/tools/viewer/SkottieSlide.h
+++ b/tools/viewer/SkottieSlide.h
@@ -9,8 +9,8 @@
#define SkottieSlide_DEFINED
#include "Slide.h"
+#include "Skottie.h"
-namespace skottie { class Animation; }
namespace sksg { class Scene; }
class SkottieSlide : public Slide {
@@ -32,9 +32,11 @@ public:
private:
SkString fPath;
sk_sp<skottie::Animation> fAnimation;
+ skottie::Animation::Stats fAnimationStats;
SkSize fWinSize = SkSize::MakeEmpty();
SkMSec fTimeBase = 0;
- bool fShowAnimationInval = false;
+ bool fShowAnimationInval = false,
+ fShowAnimationStats = false;
typedef Slide INHERITED;
};