lottie/model: keep a stat of model for future local allocator.
authorsub.mohanty@samsung.com <sub.mohanty@samsung.com>
Sun, 18 Aug 2019 09:24:36 +0000 (18:24 +0900)
committerHermet Park <hermetpark@gmail.com>
Tue, 17 Sep 2019 01:23:15 +0000 (10:23 +0900)
In a complex lottie resource layer counts can exceed above 100 or in
some cases 1000. As in each frame rendering we visit the whole tree
allocating all of them using a local allocator will speed up the tree
visit as well as creation and destruction.

As the number of layer objects are fixed in a resource we can make use of
a dumb monotonic allocator to allocate all objects in one place.

Change-Id: I6c6c8ea83c8d6382609ea58b6640c033f7fd51f3

src/lottie/lottiemodel.cpp
src/lottie/lottiemodel.h
src/lottie/lottieparser.cpp

index 149ff4d..86201a7 100644 (file)
@@ -74,7 +74,6 @@ public:
     void visit(LOTData *obj)
     {
         switch (obj->type()) {
-        case LOTData::Type::Repeater:
         case LOTData::Type::ShapeGroup:
         case LOTData::Type::Layer: {
             visitChildren(static_cast<LOTGroupData *>(obj));
@@ -86,12 +85,73 @@ public:
     }
 };
 
+class LottieUpdateStatVisitor {
+    LOTModelStat *stat;
+public:
+    explicit LottieUpdateStatVisitor(LOTModelStat *s):stat(s){}
+    void visitChildren(LOTGroupData *obj)
+    {
+        for (const auto &child : obj->mChildren) {
+            if (child) visit(child.get());
+        }
+    }
+    void visitLayer(LOTLayerData *layer)
+    {
+        switch (layer->mLayerType) {
+        case LayerType::Precomp:
+            stat->precompLayerCount++;
+            break;
+        case LayerType::Null:
+            stat->nullLayerCount++;
+            break;
+        case LayerType::Shape:
+            stat->shapeLayerCount++;
+            break;
+        case LayerType::Solid:
+            stat->solidLayerCount++;
+            break;
+        case LayerType::Image:
+            stat->imageLayerCount++;
+            break;
+        default:
+            break;
+        }
+        visitChildren(layer);
+    }
+    void visit(LOTData *obj)
+    {
+        switch (obj->type()) {
+        case LOTData::Type::Layer: {
+            visitLayer(static_cast<LOTLayerData *>(obj));
+            break;
+        }
+        case LOTData::Type::Repeater: {
+            visitChildren(static_cast<LOTRepeaterData *>(obj)->content());
+            break;
+        }
+        case LOTData::Type::ShapeGroup: {
+            visitChildren(static_cast<LOTGroupData *>(obj));
+            break;
+        }
+        default:
+            break;
+        }
+    }
+
+};
+
 void LOTCompositionData::processRepeaterObjects()
 {
     LottieRepeaterProcesser visitor;
     visitor.visit(mRootLayer.get());
 }
 
+void LOTCompositionData::updateStats()
+{
+    LottieUpdateStatVisitor visitor(&mStats);
+    visitor.visit(mRootLayer.get());
+}
+
 VMatrix LOTRepeaterTransform::matrix(int frameNo, float multiplier) const
 {
     VPointF scale = mScale.value(frameNo) / 100.f;
index 87cf59f..8e98af0 100644 (file)
@@ -53,6 +53,16 @@ class LottieShapeData;
 class LOTPolystarData;
 class LOTMaskData;
 
+struct LOTModelStat
+{
+    uint16_t precompLayerCount{0};
+    uint16_t solidLayerCount{0};
+    uint16_t shapeLayerCount{0};
+    uint16_t imageLayerCount{0};
+    uint16_t nullLayerCount{0};
+
+};
+
 enum class MatteType: uchar
 {
     None = 0,
@@ -382,6 +392,8 @@ public:
        mData._hidden = false;
     }
     ~LOTData() { if (!shortString() && mPtr) free(mPtr); }
+    LOTData(const LOTData&) = delete;
+    LOTData& operator =(const LOTData&) = delete;
 
     void setStatic(bool value) { mData._static = value;}
     bool isStatic() const {return mData._static;}
@@ -409,7 +421,7 @@ private:
     void setShortString(bool value) {mData._shortString = value;}
     bool shortString() const {return mData._shortString;}
     struct Data{
-      char           _buffer[14];
+      char           _buffer[maxShortStringLength];
       LOTData::Type  _type;
       bool           _static      : 1;
       bool           _hidden      : 1;
@@ -631,6 +643,7 @@ public:
     long endFrame() const {return mEndFrame;}
     VSize size() const {return mSize;}
     void processRepeaterObjects();
+    void updateStats();
 public:
     std::string          mVersion;
     VSize                mSize;
@@ -643,7 +656,7 @@ public:
                        std::shared_ptr<LOTAsset>>    mAssets;
 
     std::vector<LayerInfo>  mLayerInfoList;
-
+    LOTModelStat            mStats;
 };
 
 /**
index 6a48584..c8974c7 100644 (file)
@@ -2270,6 +2270,8 @@ std::shared_ptr<LOTModel> LottieParser::model()
     std::shared_ptr<LOTModel> model = std::make_shared<LOTModel>();
     model->mRoot = d->composition();
     model->mRoot->processRepeaterObjects();
+    model->mRoot->updateStats();
+
 
 #ifdef LOTTIE_DUMP_TREE_SUPPORT
     LOTDataInspector inspector;