diff options
-rw-r--r-- | experimental/skottie/Skottie.cpp | 32 | ||||
-rw-r--r-- | experimental/skottie/Skottie.h | 15 | ||||
-rw-r--r-- | tools/viewer/SkottieSlide.cpp | 50 | ||||
-rw-r--r-- | tools/viewer/SkottieSlide.h | 6 |
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; }; |