[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 <fmalita@chromium.org>
Commit-Queue: Florin Malita <fmalita@chromium.org>
This commit is contained in:
Florin Malita 2018-01-28 14:27:51 -05:00 committed by Skia Commit-Bot
parent 75f4c40588
commit 4a49068faf

View File

@ -40,7 +40,6 @@
#include "SkTHash.h" #include "SkTHash.h"
#include <cmath> #include <cmath>
#include <unordered_map>
#include <vector> #include <vector>
#include "stdlib.h" #include "stdlib.h"
@ -798,32 +797,29 @@ struct AttachLayerContext {
AttachLayerContext(const Json::Value& jlayers, AttachContext* ctx) AttachLayerContext(const Json::Value& jlayers, AttachContext* ctx)
: fLayerList(jlayers), fCtx(ctx) {} : fLayerList(jlayers), fCtx(ctx) {}
const Json::Value& fLayerList; const Json::Value& fLayerList;
AttachContext* fCtx; AttachContext* fCtx;
std::unordered_map<const Json::Value*, sk_sp<sksg::Matrix>> fLayerMatrixCache; SkTHashMap<int, sk_sp<sksg::Matrix>> fLayerMatrixMap;
std::unordered_map<int, const Json::Value*> fLayerIndexCache; sk_sp<sksg::RenderNode> fCurrentMatte;
sk_sp<sksg::RenderNode> fCurrentMatte;
const Json::Value* findLayer(int index) { sk_sp<sksg::Matrix> AttachParentLayerMatrix(const Json::Value& jlayer) {
SkASSERT(jlayer.isObject());
SkASSERT(fLayerList.isArray()); SkASSERT(fLayerList.isArray());
if (index < 0) { const auto parent_index = ParseDefault(jlayer["parent"], -1);
if (parent_index < 0)
return nullptr; return nullptr;
}
const auto cached = fLayerIndexCache.find(index); if (auto* m = fLayerMatrixMap.find(parent_index))
if (cached != fLayerIndexCache.end()) { return *m;
return cached->second;
}
for (const auto& l : fLayerList) { for (const auto& l : fLayerList) {
if (!l.isObject()) { if (!l.isObject()) {
continue; continue;
} }
if (ParseDefault(l["ind"], -1) == index) { if (ParseDefault(l["ind"], -1) == parent_index) {
fLayerIndexCache.insert(std::make_pair(index, &l)); return this->AttachLayerMatrix(l);
return &l;
} }
} }
@ -833,21 +829,22 @@ struct AttachLayerContext {
sk_sp<sksg::Matrix> AttachLayerMatrix(const Json::Value& jlayer) { sk_sp<sksg::Matrix> AttachLayerMatrix(const Json::Value& jlayer) {
SkASSERT(jlayer.isObject()); SkASSERT(jlayer.isObject());
const auto cached = fLayerMatrixCache.find(&jlayer); const auto layer_index = ParseDefault(jlayer["ind"], -1);
if (cached != fLayerMatrixCache.end()) { if (layer_index < 0)
return cached->second; return nullptr;
}
const auto* parentLayer = this->findLayer(ParseDefault(jlayer["parent"], -1)); if (auto* m = fLayerMatrixMap.find(layer_index))
return *m;
// TODO: cycle detection? // Add a stub entry to break recursion cycles.
auto parentMatrix = (parentLayer && parentLayer != &jlayer) fLayerMatrixMap.set(layer_index, nullptr);
? this->AttachLayerMatrix(*parentLayer) : nullptr;
auto layerMatrix = AttachMatrix(jlayer["ks"], fCtx, std::move(parentMatrix)); auto parent_matrix = this->AttachParentLayerMatrix(jlayer);
fLayerMatrixCache.insert(std::make_pair(&jlayer, layerMatrix));
return layerMatrix; return *fLayerMatrixMap.set(layer_index,
AttachMatrix(jlayer["ks"],
fCtx,
this->AttachParentLayerMatrix(jlayer)));
} }
}; };