optimization: move rare propery field to extra structure to minimize memory footprint...
authorsubhransu mohanty <sub.mohanty@samsung.com>
Thu, 1 Aug 2019 01:52:12 +0000 (10:52 +0900)
committerHermet Park <hermetpark@gmail.com>
Mon, 12 Aug 2019 08:30:39 +0000 (17:30 +0900)
- only layer transform object can have position property as separate X and Y
  by keeping them in the main structure incurs an overhead of 32 bytes to the user of the structure.
  as well as 8 byte on the book keeping (mSeparate) by moving those rarely used field along with 3D
  data to ExtraData we could trim the object size by 40bytes.

- with this patch now the object size is reduced from 128 bytes to 88bytes.

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

index 4c6b7e3be351e5e778678f4724bcfd81e942eaf5..ab7e984acd582c6823a932ba85f16c96925f4402 100644 (file)
@@ -111,19 +111,19 @@ VMatrix TransformData::matrix(int frameNo, bool autoOrient) const
 {
     VMatrix m;
     VPointF position;
-    if (mSeparate) {
-        position.setX(mX.value(frameNo));
-        position.setY(mY.value(frameNo));
+    if (mExtra && mExtra->mSeparate) {
+        position.setX(mExtra->mSeparateX.value(frameNo));
+        position.setY(mExtra->mSeparateY.value(frameNo));
     } else {
         position = mPosition.value(frameNo);
     }
 
     float angle = autoOrient ? mPosition.angle(frameNo) : 0;
-    if (m3D) {
+    if (mExtra && mExtra->m3DData) {
         m.translate(position)
-            .rotate(m3D->mRz.value(frameNo) + angle)
-            .rotate(m3D->mRy.value(frameNo), VMatrix::Axis::Y)
-            .rotate(m3D->mRx.value(frameNo), VMatrix::Axis::X)
+            .rotate(mExtra->m3DRz.value(frameNo) + angle)
+            .rotate(mExtra->m3DRy.value(frameNo), VMatrix::Axis::Y)
+            .rotate(mExtra->m3DRx.value(frameNo), VMatrix::Axis::X)
             .scale(mScale.value(frameNo) / 100.f)
             .translate(-mAnchor.value(frameNo));
     } else {
index 550a0030976b3089c7a181f3bdc95dd0debce1d4..db66ebbe2b724918505d3f12671ef4715f4ae762 100644 (file)
@@ -423,37 +423,40 @@ struct LOTAsset
     VBitmap                                   mBitmap;
 };
 
-struct LOT3DData
+struct TransformDataExtra
 {
-    LOTAnimatable<float>     mRx{0};
-    LOTAnimatable<float>     mRy{0};
-    LOTAnimatable<float>     mRz{0};
+    LOTAnimatable<float>     m3DRx{0};
+    LOTAnimatable<float>     m3DRy{0};
+    LOTAnimatable<float>     m3DRz{0};
+    LOTAnimatable<float>     mSeparateX{0};
+    LOTAnimatable<float>     mSeparateY{0};
+    bool                     mSeparate{false};
+    bool                     m3DData{false};
 };
 
 struct TransformData
 {
     VMatrix matrix(int frameNo, bool autoOrient = false) const;
     float opacity(int frameNo) const { return mOpacity.value(frameNo)/100.0f; }
-    bool isStatic() const { return mStatic;}
-    std::unique_ptr<LOT3DData>    m3D;
-    LOTAnimatable<float>          mRotation{0};  /* "r" */
-    LOTAnimatable<VPointF>        mScale{{100, 100}};     /* "s" */
-    LOTAnimatable<VPointF>        mPosition;  /* "p" */
-    LOTAnimatable<float>          mX{0};
-    LOTAnimatable<float>          mY{0};
-    LOTAnimatable<VPointF>        mAnchor;    /* "a" */
-    LOTAnimatable<float>          mOpacity{100};   /* "o" */
-    bool                          mSeparate{false};
-    bool                          mStatic{false};
+    void createExtraData()
+    {
+        if (!mExtra) mExtra = std::make_unique<TransformDataExtra>();
+    }
+    LOTAnimatable<float>                   mRotation{0};  /* "r" */
+    LOTAnimatable<VPointF>                 mScale{{100, 100}};     /* "s" */
+    LOTAnimatable<VPointF>                 mPosition;  /* "p" */
+    LOTAnimatable<VPointF>                 mAnchor;    /* "a" */
+    LOTAnimatable<float>                   mOpacity{100};   /* "o" */
+    std::unique_ptr<TransformDataExtra>    mExtra;
 };
 
 class LOTTransformData : public LOTData
 {
 public:
     LOTTransformData():LOTData(LOTData::Type::Transform){}
-    void set(std::unique_ptr<TransformData> data)
+    void set(std::unique_ptr<TransformData> data, bool staticFlag)
     {
-        setStatic(data->isStatic());
+        setStatic(staticFlag);
         if (isStatic()) {
             new (&impl.mStaticData) static_data(data->matrix(0), data->opacity(0));
         } else {
index 3d84a4fdf9c84e30e13b9e823a0a62fca61261bf..7212e03c876e3693682c022b0c431b221fc54819 100644 (file)
@@ -1387,7 +1387,10 @@ std::shared_ptr<LOTTransformData> LottieParserImpl::parseTransformObject(
         std::make_shared<LOTTransformData>();
 
     auto obj = std::make_unique<TransformData>();
-    if (ddd) obj->m3D = std::make_unique<LOT3DData>();
+    if (ddd) {
+        obj->createExtraData();
+        obj->mExtra->m3DData = true;
+    }
 
     while (const char *key = NextObjectKey()) {
         if (0 == strcmp(key, "nm")) {
@@ -1396,15 +1399,18 @@ std::shared_ptr<LOTTransformData> LottieParserImpl::parseTransformObject(
             parseProperty(obj->mAnchor);
         } else if (0 == strcmp(key, "p")) {
             EnterObject();
+            bool separate = false;
             while (const char *key = NextObjectKey()) {
                 if (0 == strcmp(key, "k")) {
                     parsePropertyHelper(obj->mPosition);
                 } else if (0 == strcmp(key, "s")) {
-                    obj->mSeparate = GetBool();
-                } else if (obj->mSeparate && (0 == strcmp(key, "x"))) {
-                    parseProperty(obj->mX);
-                } else if (obj->mSeparate && (0 == strcmp(key, "y"))) {
-                    parseProperty(obj->mY);
+                    obj->createExtraData();
+                    obj->mExtra->mSeparate = GetBool();
+                    separate = true;
+                } else if (separate && (0 == strcmp(key, "x"))) {
+                    parseProperty(obj->mExtra->mSeparateX);
+                } else if (separate && (0 == strcmp(key, "y"))) {
+                    parseProperty(obj->mExtra->mSeparateY);
                 } else {
                     Skip(key);
                 }
@@ -1418,25 +1424,28 @@ std::shared_ptr<LOTTransformData> LottieParserImpl::parseTransformObject(
         } else if (0 == strcmp(key, "hd")) {
             sharedTransform->mHidden = GetBool();
         } else if (0 == strcmp(key, "rx")) {
-            parseProperty(obj->m3D->mRx);
+            parseProperty(obj->mExtra->m3DRx);
         } else if (0 == strcmp(key, "ry")) {
-            parseProperty(obj->m3D->mRy);
+            parseProperty(obj->mExtra->m3DRy);
         } else if (0 == strcmp(key, "rz")) {
-            parseProperty(obj->m3D->mRz);
+            parseProperty(obj->mExtra->m3DRz);
         } else {
             Skip(key);
         }
     }
-    obj->mStatic = obj->mAnchor.isStatic() && obj->mPosition.isStatic() &&
-                   obj->mRotation.isStatic() && obj->mScale.isStatic() &&
-                   obj->mX.isStatic() && obj->mY.isStatic() &&
-                   obj->mOpacity.isStatic();
-    if (obj->m3D) {
-        obj->mStatic = obj->mStatic && obj->m3D->mRx.isStatic() &&
-                       obj->m3D->mRy.isStatic() && obj->m3D->mRz.isStatic();
+    bool isStatic = obj->mAnchor.isStatic() && obj->mPosition.isStatic() &&
+                    obj->mRotation.isStatic() && obj->mScale.isStatic() &&
+                    obj->mOpacity.isStatic();
+    if (obj->mExtra) {
+        isStatic = isStatic &&
+                   obj->mExtra->m3DRx.isStatic() &&
+                   obj->mExtra->m3DRy.isStatic() &&
+                   obj->mExtra->m3DRz.isStatic() &&
+                   obj->mExtra->mSeparateX.isStatic() &&
+                   obj->mExtra->mSeparateY.isStatic();
     }
 
-    sharedTransform->set(std::move(obj));
+    sharedTransform->set(std::move(obj), isStatic);
 
     return sharedTransform;
 }