From 4a49068fafa8ea0dc25a6ede547f662152b30359 Mon Sep 17 00:00:00 2001 From: Florin Malita Date: Sun, 28 Jan 2018 14:27:51 -0500 Subject: [skottie] Simplify layer matrix caching Switch to SkTHashMap, unify the cache based on layer index. TBR= Change-Id: I7e7622571156d67b4fe5ef91ee9a9a49b089c78f Reviewed-on: https://skia-review.googlesource.com/101001 Reviewed-by: Florin Malita Commit-Queue: Florin Malita --- experimental/skottie/Skottie.cpp | 51 +++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 27 deletions(-) (limited to 'experimental') diff --git a/experimental/skottie/Skottie.cpp b/experimental/skottie/Skottie.cpp index efd3d075d7..8545de8391 100644 --- a/experimental/skottie/Skottie.cpp +++ b/experimental/skottie/Skottie.cpp @@ -40,7 +40,6 @@ #include "SkTHash.h" #include -#include #include #include "stdlib.h" @@ -798,32 +797,29 @@ struct AttachLayerContext { AttachLayerContext(const Json::Value& jlayers, AttachContext* ctx) : fLayerList(jlayers), fCtx(ctx) {} - const Json::Value& fLayerList; - AttachContext* fCtx; - std::unordered_map> fLayerMatrixCache; - std::unordered_map fLayerIndexCache; - sk_sp fCurrentMatte; + const Json::Value& fLayerList; + AttachContext* fCtx; + SkTHashMap> fLayerMatrixMap; + sk_sp fCurrentMatte; - const Json::Value* findLayer(int index) { + sk_sp AttachParentLayerMatrix(const Json::Value& jlayer) { + SkASSERT(jlayer.isObject()); SkASSERT(fLayerList.isArray()); - if (index < 0) { + const auto parent_index = ParseDefault(jlayer["parent"], -1); + if (parent_index < 0) return nullptr; - } - const auto cached = fLayerIndexCache.find(index); - if (cached != fLayerIndexCache.end()) { - return cached->second; - } + if (auto* m = fLayerMatrixMap.find(parent_index)) + return *m; for (const auto& l : fLayerList) { if (!l.isObject()) { continue; } - if (ParseDefault(l["ind"], -1) == index) { - fLayerIndexCache.insert(std::make_pair(index, &l)); - return &l; + if (ParseDefault(l["ind"], -1) == parent_index) { + return this->AttachLayerMatrix(l); } } @@ -833,21 +829,22 @@ struct AttachLayerContext { sk_sp AttachLayerMatrix(const Json::Value& jlayer) { SkASSERT(jlayer.isObject()); - const auto cached = fLayerMatrixCache.find(&jlayer); - if (cached != fLayerMatrixCache.end()) { - return cached->second; - } + const auto layer_index = ParseDefault(jlayer["ind"], -1); + if (layer_index < 0) + return nullptr; - const auto* parentLayer = this->findLayer(ParseDefault(jlayer["parent"], -1)); + if (auto* m = fLayerMatrixMap.find(layer_index)) + return *m; - // TODO: cycle detection? - auto parentMatrix = (parentLayer && parentLayer != &jlayer) - ? this->AttachLayerMatrix(*parentLayer) : nullptr; + // Add a stub entry to break recursion cycles. + fLayerMatrixMap.set(layer_index, nullptr); - auto layerMatrix = AttachMatrix(jlayer["ks"], fCtx, std::move(parentMatrix)); - fLayerMatrixCache.insert(std::make_pair(&jlayer, layerMatrix)); + auto parent_matrix = this->AttachParentLayerMatrix(jlayer); - return layerMatrix; + return *fLayerMatrixMap.set(layer_index, + AttachMatrix(jlayer["ks"], + fCtx, + this->AttachParentLayerMatrix(jlayer))); } }; -- cgit v1.2.3