rlottie/model: Refactor LOTTransformData object to optimize object size
authorsubhransu mohanty <sub.mohanty@samsung.com>
Tue, 25 Jun 2019 00:58:38 +0000 (09:58 +0900)
committerHermet Park <hermetpark@gmail.com>
Tue, 25 Jun 2019 11:59:38 +0000 (20:59 +0900)
src/lottie/lottieitem.cpp
src/lottie/lottiemodel.cpp
src/lottie/lottiemodel.h
src/lottie/lottieparser.cpp

index c87a43628f68db6bc8dab4f543e4f63ad670672c..8dcdebe274fb25f924b318a419ab1fd55b0064a4 100644 (file)
@@ -1040,8 +1040,7 @@ void LOTContentGroupItem::update(int frameNo, const VMatrix &parentMatrix,
 
     if (mData && mData->mTransform) {
         // update the matrix and the flag
-        if ((flag & DirtyFlagBit::Matrix) ||
-            !mData->mTransform->staticMatrix()) {
+        if ((flag & DirtyFlagBit::Matrix) || !mData->mTransform->isStatic()) {
             newFlag |= DirtyFlagBit::Matrix;
         }
         m = mData->mTransform->matrix(frameNo);
index 6da671ffb9ce2080c844ba356f9eb28ca16ec312..e51941cadbc47e3cc40d428045fe76b1740ce510 100644 (file)
@@ -107,42 +107,28 @@ VMatrix LOTRepeaterTransform::matrix(int frameNo, float multiplier) const
     return m;
 }
 
-VMatrix LOTTransformData::matrix(int frameNo, bool autoOrient) const
-{
-    if (mStaticMatrix)
-        return mCachedMatrix;
-    else
-        return computeMatrix(frameNo, autoOrient);
-}
-
-void LOTTransformData::cacheMatrix()
-{
-    mCachedMatrix = computeMatrix(0);
-}
-
-VMatrix LOTTransformData::computeMatrix(int frameNo, bool autoOrient) const
+VMatrix TransformData::matrix(int frameNo, bool autoOrient) const
 {
     VMatrix m;
-    VPointF position = mPosition.value(frameNo);
+    VPointF position;
     if (mSeparate) {
         position.setX(mX.value(frameNo));
         position.setY(mY.value(frameNo));
+    } else {
+        position = mPosition.value(frameNo);
     }
 
     float angle = autoOrient ? mPosition.angle(frameNo) : 0;
-    if (ddd()) {
+    if (m3D) {
         m.translate(position)
-            .rotate(mRotation.value(frameNo))
-            .rotate(angle)
-            .rotate(m3D->mRz.value(frameNo))
+            .rotate(m3D->mRz.value(frameNo) + angle)
             .rotate(m3D->mRy.value(frameNo), VMatrix::Axis::Y)
             .rotate(m3D->mRx.value(frameNo), VMatrix::Axis::X)
             .scale(mScale.value(frameNo) / 100.f)
             .translate(-mAnchor.value(frameNo));
     } else {
         m.translate(position)
-            .rotate(mRotation.value(frameNo))
-            .rotate(angle)
+            .rotate(mRotation.value(frameNo) + angle)
             .scale(mScale.value(frameNo) / 100.f)
             .translate(-mAnchor.value(frameNo));
     }
index 5a63dc4241a73977e690e8823db4cd6a5c77a5f2..6fe933593e9fa200ad1aabf1d385189721d8c778 100644 (file)
@@ -266,7 +266,7 @@ class LOTAnimatable
 {
 public:
     LOTAnimatable() { construct(impl.mValue, {}); }
-    LOTAnimatable(T value) { construct(impl.mValue, std::move(value)); }
+    explicit LOTAnimatable(T value) { construct(impl.mValue, std::move(value)); }
 
     const LOTAnimInfo<T>& animation() const {return *(impl.mAnimInfo.get());}
     const T& value() const {return impl.mValue;}
@@ -418,31 +418,71 @@ struct LOT3DData
     LOTAnimatable<float>     mRz{0};
 };
 
-class LOTTransformData : public LOTData
+struct TransformData
 {
-public:
-    LOTTransformData():LOTData(LOTData::Type::Transform),mScale({100, 100}){}
     VMatrix matrix(int frameNo, bool autoOrient = false) const;
-    float opacity(int frameNo) const { return mOpacity.value(frameNo)/100;}
-    void cacheMatrix();
-    bool staticMatrix() const {return mStaticMatrix;}
-    bool ddd() const {return m3D ? true : false;}
-private:
-    VMatrix computeMatrix(int frameNo, bool autoOrient = false) const;
-public:
+    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;     /* "s" */
+    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" */
-    LOTAnimatable<float>          mSkew{0};      /* "sk" */
-    LOTAnimatable<float>          mSkewAxis{0};  /* "sa" */
-    bool                          mStaticMatrix{true};
     bool                          mSeparate{false};
-    VMatrix                       mCachedMatrix;
+    bool                          mStatic{false};
+};
+
+class LOTTransformData : public LOTData
+{
+public:
+    LOTTransformData():LOTData(LOTData::Type::Transform){}
+    void set(std::unique_ptr<TransformData> data)
+    {
+        setStatic(data->isStatic());
+        if (isStatic()) {
+            new (&impl.mStaticData) static_data(data->matrix(0), data->opacity(0));
+        } else {
+            new (&impl.mData) std::unique_ptr<TransformData>(std::move(data));
+        }
+    }
+    VMatrix matrix(int frameNo, bool autoOrient = false) const
+    {
+        if (isStatic()) return impl.mStaticData.mMatrix;
+        return impl.mData->matrix(frameNo, autoOrient);
+    }
+    float opacity(int frameNo) const
+    {
+        if (isStatic()) return impl.mStaticData.mOpacity;
+        return impl.mData->opacity(frameNo);
+    }
+
+    LOTTransformData& operator=(LOTTransformData&&) = delete;
+    ~LOTTransformData() {destroy();}
+
+private:
+    void destroy() {
+        if (isStatic()) {
+            impl.mStaticData.~static_data();
+        } else {
+            using std::unique_ptr;
+            impl.mData.~unique_ptr<TransformData>();
+        }
+    }
+    struct static_data {
+       static_data(VMatrix &&m, float opacity):
+           mOpacity(opacity), mMatrix(std::move(m)){}
+       float    mOpacity;
+       VMatrix  mMatrix;
+    };
+    union details {
+        std::unique_ptr<TransformData>   mData;
+        static_data                      mStaticData;
+        details(){}
+        ~details(){}
+    }impl;
 };
 
 class LOTLayerData : public LOTGroupData
index c51623967157705ae80cac2c21aaa9ccfe4b42d8..614ea335ca01b5706dd4e0e3d0593066ca013e76 100644 (file)
@@ -1350,13 +1350,13 @@ std::shared_ptr<LOTTransformData> LottieParserImpl::parseTransformObject(
 {
     std::shared_ptr<LOTTransformData> sharedTransform =
         std::make_shared<LOTTransformData>();
-    LOTTransformData *obj = sharedTransform.get();
 
+    auto obj = std::make_unique<TransformData>();
     if (ddd) obj->m3D = std::make_unique<LOT3DData>();
 
     while (const char *key = NextObjectKey()) {
         if (0 == strcmp(key, "nm")) {
-            obj->mName = GetString();
+            sharedTransform->mName = GetString();
         } else if (0 == strcmp(key, "a")) {
             parseProperty(obj->mAnchor);
         } else if (0 == strcmp(key, "p")) {
@@ -1378,14 +1378,10 @@ std::shared_ptr<LOTTransformData> LottieParserImpl::parseTransformObject(
             parseProperty(obj->mRotation);
         } else if (0 == strcmp(key, "s")) {
             parseProperty(obj->mScale);
-        } else if (0 == strcmp(key, "sk")) {
-            parseProperty(obj->mSkew);
-        } else if (0 == strcmp(key, "sa")) {
-            parseProperty(obj->mSkewAxis);
         } else if (0 == strcmp(key, "o")) {
             parseProperty(obj->mOpacity);
         } else if (0 == strcmp(key, "hd")) {
-            obj->mHidden = GetBool();
+            sharedTransform->mHidden = GetBool();
         } else if (0 == strcmp(key, "rx")) {
             parseProperty(obj->m3D->mRx);
         } else if (0 == strcmp(key, "ry")) {
@@ -1396,19 +1392,16 @@ std::shared_ptr<LOTTransformData> LottieParserImpl::parseTransformObject(
             Skip(key);
         }
     }
-    obj->mStaticMatrix = obj->mAnchor.isStatic() && obj->mPosition.isStatic() &&
-                         obj->mRotation.isStatic() && obj->mScale.isStatic() &&
-                         obj->mSkew.isStatic() && obj->mSkewAxis.isStatic() &&
-                         obj->mX.isStatic() && obj->mY.isStatic();
+    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->mStaticMatrix = obj->mStaticMatrix && obj->m3D->mRx.isStatic() &&
-                             obj->m3D->mRy.isStatic() &&
-                             obj->m3D->mRz.isStatic();
+        obj->mStatic = obj->mStatic && obj->m3D->mRx.isStatic() &&
+                       obj->m3D->mRy.isStatic() && obj->m3D->mRz.isStatic();
     }
 
-    obj->setStatic(obj->mStaticMatrix && obj->mOpacity.isStatic());
-
-    if (obj->mStaticMatrix) obj->cacheMatrix();
+    sharedTransform->set(std::move(obj));
 
     return sharedTransform;
 }