From: Youngbok Shin Date: Fri, 3 Aug 2018 04:38:04 +0000 (+0900) Subject: lottie: don't redraw path item if its properties are not changed X-Git-Tag: submit/tizen/20180917.042405~140 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F56%2F185856%2F3;p=platform%2Fcore%2Fuifw%2Flottie-player.git lottie: don't redraw path item if its properties are not changed A path item has few animation frames, it has to be redrawn only in animated frames. If the path item became static after animation frames, it shouldn't redraw its path. It will improve performance. Change-Id: I583f2b8a889208a07530f6d06ed90469bcee726c --- diff --git a/example/resource/dynamic_path_test.json b/example/resource/dynamic_path_test.json new file mode 100644 index 0000000..a01e506 --- /dev/null +++ b/example/resource/dynamic_path_test.json @@ -0,0 +1 @@ +{"v":"5.1.17","fr":29.9700012207031,"ip":0,"op":150.000006109625,"w":300,"h":300,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[150,150,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":20,"s":[135,135],"e":[116,116]},{"t":137.000005580124}],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":20,"s":[24,25],"e":[57,52],"to":[5.5,4.5],"ti":[-5.5,-4.5]},{"t":129.000005254278}],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[54]},{"t":149.000006068894}],"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":0,"s":[100,100],"e":[50,50]},{"t":40.0000016292334}],"ix":2},"p":{"a":0,"k":[-26,-37],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.145327582955,0.057777773589,0.866666674614,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 2","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"sr","sy":1,"d":1,"pt":{"a":0,"k":5,"ix":3},"p":{"a":0,"k":[26,-54],"ix":4},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":110,"s":[0],"e":[184]},{"t":149.000006068894}],"ix":5},"ir":{"a":0,"k":30,"ix":6},"is":{"a":0,"k":27,"ix":8},"or":{"a":0,"k":59,"ix":7},"os":{"a":0,"k":73,"ix":9},"ix":5,"nm":"Polystar Path 1","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"fl","c":{"a":0,"k":[0.07993286103,0.716212213039,0.766274511814,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 3","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":150.000006109625,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/src/lottie/lottieitem.cpp b/src/lottie/lottieitem.cpp index c3bdd77..e76100d 100644 --- a/src/lottie/lottieitem.cpp +++ b/src/lottie/lottieitem.cpp @@ -669,7 +669,7 @@ void LOTPathDataItem::update(int frameNo, const VMatrix &parentMatrix, mCombinedAlpha = parentAlpha; // 1. update the local path if needed - if (!(mInit && mStaticPath)) { + if (!(mInit && mStaticPath) && hasChanged(frameNo)) { updatePath(mLocalPath, frameNo); mInit = true; mPathChanged = true; @@ -731,12 +731,13 @@ void LOTRectItem::updatePath(VPath& path, int frameNo) { VPointF pos = mData->mPos.value(frameNo); VPointF size = mData->mSize.value(frameNo); - float radius = mData->mRound.value(frameNo); + float roundness = mData->mRound.value(frameNo); VRectF r(pos.x() - size.x() / 2, pos.y() - size.y() / 2, size.x(), size.y()); path.reset(); - path.addRoundRect(r, radius, radius, mData->direction()); + path.addRoundRect(r, roundness, roundness, mData->direction()); + updateCache(frameNo, pos, size, roundness); } LOTEllipseItem::LOTEllipseItem(LOTEllipseData *data) @@ -753,6 +754,7 @@ void LOTEllipseItem::updatePath(VPath& path, int frameNo) path.reset(); path.addOval(r, mData->direction()); + updateCache(frameNo, pos, size); } LOTShapeItem::LOTShapeItem(LOTShapeData *data) @@ -794,6 +796,8 @@ void LOTPolystarItem::updatePath(VPath& path, int frameNo) m.translate(pos.x(), pos.y()).rotate(rotation); m.rotate(rotation); path.transform(m); + updateCache(frameNo, pos, points, innerRadius, outerRadius, + innerRoundness, outerRoundness, rotation); } /* diff --git a/src/lottie/lottieitem.h b/src/lottie/lottieitem.h index 1d35d48..c7480df 100644 --- a/src/lottie/lottieitem.h +++ b/src/lottie/lottieitem.h @@ -226,6 +226,7 @@ private: float mCombinedAlpha; protected: virtual void updatePath(VPath& path, int frameNo) = 0; + virtual bool hasChanged(int frameNo) = 0; }; class LOTRectItem: public LOTPathDataItem @@ -235,6 +236,35 @@ public: protected: void updatePath(VPath& path, int frameNo) final; LOTRectData *mData; + + struct Cache { + int mFrameNo; + VPointF mPos; + VPointF mSize; + float mRoundness; + }; + Cache mCache; + + void updateCache(int frameNo, VPointF pos, VPointF size, float roundness) { + mCache.mFrameNo = frameNo; + mCache.mPos = pos; + mCache.mSize = size; + mCache.mRoundness = roundness; + } + bool hasChanged(int frameNo) final { + if (mCache.mFrameNo == frameNo) return false; + + VPointF pos = mData->mPos.value(frameNo); + VPointF size = mData->mSize.value(frameNo); + float roundness = mData->mRound.value(frameNo); + + if (vCompare(mCache.mPos.x(), pos.x()) && vCompare(mCache.mPos.y(), pos.y()) && + vCompare(mCache.mSize.x(), size.x()) && vCompare(mCache.mSize.y(), size.y()) && + vCompare(mCache.mRoundness, roundness)) + return false; + + return true; + } }; class LOTEllipseItem: public LOTPathDataItem @@ -244,6 +274,31 @@ public: private: void updatePath(VPath& path, int frameNo) final; LOTEllipseData *mData; + + struct Cache { + int mFrameNo; + VPointF mPos; + VPointF mSize; + }; + Cache mCache; + + void updateCache(int frameNo, VPointF pos, VPointF size) { + mCache.mFrameNo = frameNo; + mCache.mPos = pos; + mCache.mSize = size; + } + bool hasChanged(int frameNo) final { + if (mCache.mFrameNo == frameNo) return false; + + VPointF pos = mData->mPos.value(frameNo); + VPointF size = mData->mSize.value(frameNo); + + if (vCompare(mCache.mPos.x(), pos.x()) && vCompare(mCache.mPos.y(), pos.y()) && + vCompare(mCache.mSize.x(), size.x()) && vCompare(mCache.mSize.y(), size.y())) + return false; + + return true; + } }; class LOTShapeItem: public LOTPathDataItem @@ -253,6 +308,7 @@ public: private: void updatePath(VPath& path, int frameNo) final; LOTShapeData *mData; + bool hasChanged(int frameNo) final { return true; } }; class LOTPolystarItem: public LOTPathDataItem @@ -262,6 +318,49 @@ public: private: void updatePath(VPath& path, int frameNo) final; LOTPolystarData *mData; + + struct Cache { + int mFrameNo; + VPointF mPos; + float mPoints; + float mInnerRadius; + float mOuterRadius; + float mInnerRoundness; + float mOuterRoundness; + float mRotation; + }; + Cache mCache; + + void updateCache(int frameNo, VPointF pos, float points, float innerRadius, float outerRadius, + float innerRoundness, float outerRoundness, float rotation) { + mCache.mFrameNo = frameNo; + mCache.mPos = pos; + mCache.mPoints = points; + mCache.mInnerRadius = innerRadius; + mCache.mOuterRadius = outerRadius; + mCache.mInnerRoundness = innerRoundness; + mCache.mOuterRoundness = outerRoundness; + mCache.mRotation = rotation; + } + bool hasChanged(int frameNo) final { + if (mCache.mFrameNo == frameNo) return false; + + VPointF pos = mData->mPos.value(frameNo); + float points = mData->mPointCount.value(frameNo); + float innerRadius = mData->mInnerRadius.value(frameNo); + float outerRadius = mData->mOuterRadius.value(frameNo); + float innerRoundness = mData->mInnerRoundness.value(frameNo); + float outerRoundness = mData->mOuterRoundness.value(frameNo); + float rotation = mData->mRotation.value(frameNo); + + if (vCompare(mCache.mPos.x(), pos.x()) && vCompare(mCache.mPos.y(), pos.y()) && + vCompare(mCache.mPoints, points) && vCompare(mCache.mRotation, rotation) && + vCompare(mCache.mInnerRadius, innerRadius) && vCompare(mCache.mOuterRadius, outerRadius) && + vCompare(mCache.mInnerRoundness, innerRoundness) && vCompare(mCache.mOuterRoundness, outerRoundness)) + return false; + + return true; + } };