[skottie] SkTArray begone
SkTArray is not a good choice for tigh allocations: - its minimum allocation count is 8 - reserve(sz) doesn't adjust capacity to the exact value, but padds the same way as normal growth (max(sz, 8, 50%)) - no shrink_to_fit() function to trim unneeded capacity Since keyframed properties with a small number of frames are quite common in Lottie, this adds significant heap overhead. Switch to std::vector(), reserve() to the estimated frame count and shrink_to_fit() when done parsing. Bug: skia:8340 Change-Id: Id575e2da2fd17537948c2b38485a8accdb9f7a8b Reviewed-on: https://skia-review.googlesource.com/150905 Reviewed-by: Mike Klein <mtklein@google.com> Commit-Queue: Florin Malita <fmalita@chromium.org>
This commit is contained in:
parent
a4cdfbb0d5
commit
ab706d85e0
@ -11,9 +11,9 @@
|
||||
#include "SkottieValue.h"
|
||||
#include "SkSGScene.h"
|
||||
#include "SkString.h"
|
||||
#include "SkTArray.h"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace skottie {
|
||||
namespace internal {
|
||||
@ -30,7 +30,7 @@ bool LogFail(const skjson::Value& json, const char* msg) {
|
||||
|
||||
class KeyframeAnimatorBase : public sksg::Animator {
|
||||
public:
|
||||
int count() const { return fRecs.count(); }
|
||||
size_t count() const { return fRecs.size(); }
|
||||
|
||||
protected:
|
||||
KeyframeAnimatorBase() = default;
|
||||
@ -110,7 +110,7 @@ protected:
|
||||
int cm_idx = -1;
|
||||
if (c0 != kDefaultC0 || c1 != kDefaultC1) {
|
||||
// TODO: is it worth de-duping these?
|
||||
cm_idx = fCubicMaps.count();
|
||||
cm_idx = SkToInt(fCubicMaps.size());
|
||||
fCubicMaps.emplace_back();
|
||||
// TODO: why do we have to plug these inverted?
|
||||
fCubicMaps.back().setPts(c1, c0);
|
||||
@ -124,9 +124,17 @@ protected:
|
||||
fRecs.pop_back();
|
||||
}
|
||||
|
||||
fRecs.shrink_to_fit();
|
||||
fCubicMaps.shrink_to_fit();
|
||||
|
||||
SkASSERT(fRecs.empty() || fRecs.back().isValid());
|
||||
}
|
||||
|
||||
void reserve(size_t frame_count) {
|
||||
fRecs.reserve(frame_count);
|
||||
fCubicMaps.reserve(frame_count);
|
||||
}
|
||||
|
||||
private:
|
||||
const KeyframeRec* findFrame(float t) const {
|
||||
SkASSERT(!fRecs.empty());
|
||||
@ -165,9 +173,9 @@ private:
|
||||
return f0;
|
||||
}
|
||||
|
||||
SkTArray<KeyframeRec> fRecs;
|
||||
SkTArray<SkCubicMap> fCubicMaps;
|
||||
const KeyframeRec* fCachedRec = nullptr;
|
||||
std::vector<KeyframeRec> fRecs;
|
||||
std::vector<SkCubicMap> fCubicMaps;
|
||||
const KeyframeRec* fCachedRec = nullptr;
|
||||
|
||||
using INHERITED = sksg::Animator;
|
||||
};
|
||||
@ -198,7 +206,16 @@ private:
|
||||
const AnimationBuilder* abuilder,
|
||||
std::function<void(const T&)>&& apply)
|
||||
: fApplyFunc(std::move(apply)) {
|
||||
// Generally, each keyframe holds two values (start, end) and a cubic mapper. Except
|
||||
// the last frame, which only holds a marker timestamp. Then, the values series is
|
||||
// contiguous (keyframe[i].end == keyframe[i + 1].start), and we dedupe them.
|
||||
// => we'll store (keyframes.size) values and (keyframe.size - 1) recs and cubic maps.
|
||||
fVs.reserve(jframes.size());
|
||||
this->reserve(SkTMax<size_t>(jframes.size(), 1) - 1);
|
||||
|
||||
this->parseKeyFrames(jframes, abuilder);
|
||||
|
||||
fVs.shrink_to_fit();
|
||||
}
|
||||
|
||||
int parseValue(const skjson::Value& jv, const AnimationBuilder* abuilder) override {
|
||||
@ -212,7 +229,7 @@ private:
|
||||
if (fVs.empty() || val != fVs.back()) {
|
||||
fVs.push_back(std::move(val));
|
||||
}
|
||||
return fVs.count() - 1;
|
||||
return SkToInt(fVs.size()) - 1;
|
||||
}
|
||||
|
||||
const T* eval(const KeyframeRec& rec, float t, T* v) const {
|
||||
@ -232,7 +249,7 @@ private:
|
||||
}
|
||||
|
||||
const std::function<void(const T&)> fApplyFunc;
|
||||
SkTArray<T> fVs;
|
||||
std::vector<T> fVs;
|
||||
|
||||
// LERP storage: we use this to temporarily store interpolation results.
|
||||
// Alternatively, the temp result could live on the stack -- but for vector values that would
|
||||
|
Loading…
Reference in New Issue
Block a user