lottie/render: Move drawable class to vector.

Change-Id: I4cb296e7a1d86b5215ab191b4306514d3fcdeacf
This commit is contained in:
subhransu mohanty 2018-07-27 11:09:13 +09:00
parent 8b77e6ce93
commit 1c62266e43
6 changed files with 206 additions and 194 deletions

View File

@ -5,158 +5,6 @@
#include"vdasher.h" #include"vdasher.h"
#include <cmath> #include <cmath>
VDrawable::VDrawable():mFlag(DirtyState::All),
mType(Type::Fill),
mFillRule(FillRule::Winding)
{
mStroke.dashArraySize = 0;
mStroke.cap = CapStyle::Round;
mStroke.join= JoinStyle::Round;
mStroke.meterLimit = 10;
mStroke.enable = false;
}
void VDrawable::preprocess()
{
if (mFlag & (DirtyState::Path)) {
if (mStroke.enable) {
VPath newPath = mPath;
if (mStroke.dashArraySize) {
VDasher dasher(mStroke.dashArray, mStroke.dashArraySize);
newPath = dasher.dashed(mPath);
}
mRleTask = VRaster::instance().generateStrokeInfo(mPath, mStroke.cap, mStroke.join,
mStroke.width, mStroke.meterLimit);
} else {
mRleTask = VRaster::instance().generateFillInfo(mPath, mFillRule);
}
mFlag &= ~DirtyFlag(DirtyState::Path);
}
}
VRle VDrawable::rle()
{
if (mRleTask.valid()) {
mRle = std::move(mRleTask.get());
}
return mRle;
}
void VDrawable::setStrokeInfo(CapStyle cap, JoinStyle join, float meterLimit, float strokeWidth)
{
mStroke.enable = true;
mStroke.cap = cap;
mStroke.join = join;
mStroke.meterLimit = meterLimit;
mStroke.width = strokeWidth;
mFlag |= DirtyState::Path;
}
void VDrawable::setDashInfo(float *array, int size)
{
mStroke.dashArray = array;
mStroke.dashArraySize = size;
mFlag |= DirtyState::Path;
}
void VDrawable::sync()
{
mCNode.mFlag = ChangeFlagNone;
if (mFlag & DirtyState::None) return;
if (mFlag & DirtyState::Path) {
const std::vector<VPath::Element> &elm = mPath.elements();
const std::vector<VPointF> &pts = mPath.points();
const float *ptPtr = reinterpret_cast<const float *>(pts.data());
const char *elmPtr = reinterpret_cast<const char *>(elm.data());
mCNode.mPath.elmPtr = elmPtr;
mCNode.mPath.elmCount = elm.size();
mCNode.mPath.ptPtr = ptPtr;
mCNode.mPath.ptCount = 2 * pts.size();
mCNode.mFlag |= ChangeFlagPath;
}
if (mStroke.enable) {
mCNode.mStroke.width = mStroke.width;
mCNode.mStroke.meterLimit = mStroke.meterLimit;
mCNode.mStroke.enable = 1;
switch (mFillRule) {
case FillRule::EvenOdd:
mCNode.mFillRule = LOTNode::EvenOdd;
break;
default:
mCNode.mFillRule = LOTNode::Winding;
break;
}
switch (mStroke.cap) {
case CapStyle::Flat:
mCNode.mStroke.cap = LOTNode::FlatCap;
break;
case CapStyle::Square:
mCNode.mStroke.cap = LOTNode::SquareCap;
break;
case CapStyle::Round:
mCNode.mStroke.cap = LOTNode::RoundCap;
break;
default:
mCNode.mStroke.cap = LOTNode::FlatCap;
break;
}
switch (mStroke.join) {
case JoinStyle::Miter:
mCNode.mStroke.join = LOTNode::MiterJoin;
break;
case JoinStyle::Bevel:
mCNode.mStroke.join = LOTNode::BevelJoin;
break;
case JoinStyle::Round:
mCNode.mStroke.join = LOTNode::RoundJoin;
break;
default:
mCNode.mStroke.join = LOTNode::MiterJoin;
break;
}
mCNode.mStroke.dashArray = mStroke.dashArray;
mCNode.mStroke.dashArraySize = mStroke.dashArraySize;
} else {
mCNode.mStroke.enable = 0;
}
switch (mBrush.type()) {
case VBrush::Type::Solid:
mCNode.mType = LOTNode::BrushSolid;
mCNode.mColor.r = mBrush.mColor.r;
mCNode.mColor.g = mBrush.mColor.g;
mCNode.mColor.b = mBrush.mColor.b;
mCNode.mColor.a = mBrush.mColor.a;
break;
case VBrush::Type::LinearGradient:
mCNode.mType = LOTNode::BrushGradient;
mCNode.mGradient.type = LOTNode::Gradient::Linear;
mCNode.mGradient.start.x = mBrush.mGradient->linear.x1;
mCNode.mGradient.start.y = mBrush.mGradient->linear.y1;
mCNode.mGradient.end.x = mBrush.mGradient->linear.x2;
mCNode.mGradient.end.y = mBrush.mGradient->linear.y2;
break;
case VBrush::Type::RadialGradient:
mCNode.mType = LOTNode::BrushGradient;
mCNode.mGradient.type = LOTNode::Gradient::Radial;
mCNode.mGradient.center.x = mBrush.mGradient->radial.cx;
mCNode.mGradient.center.y = mBrush.mGradient->radial.cy;
mCNode.mGradient.focal.x = mBrush.mGradient->radial.fx;
mCNode.mGradient.focal.y = mBrush.mGradient->radial.fy;
mCNode.mGradient.cradius = mBrush.mGradient->radial.cradius;
mCNode.mGradient.fradius = mBrush.mGradient->radial.fradius;
break;
default:
break;
}
}
/* Lottie Layer Rules /* Lottie Layer Rules
* 1. time stretch is pre calculated and applied to all the properties of the lottilayer model and all its children * 1. time stretch is pre calculated and applied to all the properties of the lottilayer model and all its children
* 2. The frame property could be reversed using,time-reverse layer property in AE. which means (start frame > endFrame) * 2. The frame property could be reversed using,time-reverse layer property in AE. which means (start frame > endFrame)
@ -276,8 +124,9 @@ void LOTCompItem::buildRenderList()
mRenderList.clear(); mRenderList.clear();
for(auto i : mDrawableList) { for(auto i : mDrawableList) {
i->sync(); LOTDrawable *lotDrawable = static_cast<LOTDrawable *>(i);
mRenderList.push_back(&i->mCNode); lotDrawable->sync();
mRenderList.push_back(&lotDrawable->mCNode);
} }
} }
@ -563,7 +412,7 @@ LOTSolidLayerItem::LOTSolidLayerItem(LOTLayerData *layerData):LOTLayerItem(layer
void LOTSolidLayerItem::updateContent() void LOTSolidLayerItem::updateContent()
{ {
if (!mRenderNode) { if (!mRenderNode) {
mRenderNode = std::make_unique<VDrawable>(); mRenderNode = std::make_unique<LOTDrawable>();
mRenderNode->mType = VDrawable::Type::Fill; mRenderNode->mType = VDrawable::Type::Fill;
mRenderNode->mFlag |= VDrawable::DirtyState::All; mRenderNode->mFlag |= VDrawable::DirtyState::All;
} }
@ -764,7 +613,7 @@ void LOTPathDataItem::addPaintOperation(std::vector<LOTPaintDataItem *> &list, i
{ {
for(auto paintItem : list) { for(auto paintItem : list) {
bool sameGroup = (externalCount-- > 0) ? false : true; bool sameGroup = (externalCount-- > 0) ? false : true;
mNodeList.push_back(std::make_unique<VDrawable>()); mNodeList.push_back(std::make_unique<LOTDrawable>());
mRenderList.push_back(LOTRenderNode(this, paintItem, mNodeList.back().get(), sameGroup)); mRenderList.push_back(LOTRenderNode(this, paintItem, mNodeList.back().get(), sameGroup));
} }
} }
@ -1107,3 +956,103 @@ void LOTRepeaterItem::renderList(std::vector<VDrawable *> &list)
} }
void LOTDrawable::sync()
{
mCNode.mFlag = ChangeFlagNone;
if (mFlag & DirtyState::None) return;
if (mFlag & DirtyState::Path) {
const std::vector<VPath::Element> &elm = mPath.elements();
const std::vector<VPointF> &pts = mPath.points();
const float *ptPtr = reinterpret_cast<const float *>(pts.data());
const char *elmPtr = reinterpret_cast<const char *>(elm.data());
mCNode.mPath.elmPtr = elmPtr;
mCNode.mPath.elmCount = elm.size();
mCNode.mPath.ptPtr = ptPtr;
mCNode.mPath.ptCount = 2 * pts.size();
mCNode.mFlag |= ChangeFlagPath;
}
if (mStroke.enable) {
mCNode.mStroke.width = mStroke.width;
mCNode.mStroke.meterLimit = mStroke.meterLimit;
mCNode.mStroke.enable = 1;
switch (mFillRule) {
case FillRule::EvenOdd:
mCNode.mFillRule = LOTNode::EvenOdd;
break;
default:
mCNode.mFillRule = LOTNode::Winding;
break;
}
switch (mStroke.cap) {
case CapStyle::Flat:
mCNode.mStroke.cap = LOTNode::FlatCap;
break;
case CapStyle::Square:
mCNode.mStroke.cap = LOTNode::SquareCap;
break;
case CapStyle::Round:
mCNode.mStroke.cap = LOTNode::RoundCap;
break;
default:
mCNode.mStroke.cap = LOTNode::FlatCap;
break;
}
switch (mStroke.join) {
case JoinStyle::Miter:
mCNode.mStroke.join = LOTNode::MiterJoin;
break;
case JoinStyle::Bevel:
mCNode.mStroke.join = LOTNode::BevelJoin;
break;
case JoinStyle::Round:
mCNode.mStroke.join = LOTNode::RoundJoin;
break;
default:
mCNode.mStroke.join = LOTNode::MiterJoin;
break;
}
mCNode.mStroke.dashArray = mStroke.dashArray;
mCNode.mStroke.dashArraySize = mStroke.dashArraySize;
} else {
mCNode.mStroke.enable = 0;
}
switch (mBrush.type()) {
case VBrush::Type::Solid:
mCNode.mType = LOTNode::BrushSolid;
mCNode.mColor.r = mBrush.mColor.r;
mCNode.mColor.g = mBrush.mColor.g;
mCNode.mColor.b = mBrush.mColor.b;
mCNode.mColor.a = mBrush.mColor.a;
break;
case VBrush::Type::LinearGradient:
mCNode.mType = LOTNode::BrushGradient;
mCNode.mGradient.type = LOTNode::Gradient::Linear;
mCNode.mGradient.start.x = mBrush.mGradient->linear.x1;
mCNode.mGradient.start.y = mBrush.mGradient->linear.y1;
mCNode.mGradient.end.x = mBrush.mGradient->linear.x2;
mCNode.mGradient.end.y = mBrush.mGradient->linear.y2;
break;
case VBrush::Type::RadialGradient:
mCNode.mType = LOTNode::BrushGradient;
mCNode.mGradient.type = LOTNode::Gradient::Radial;
mCNode.mGradient.center.x = mBrush.mGradient->radial.cx;
mCNode.mGradient.center.y = mBrush.mGradient->radial.cy;
mCNode.mGradient.focal.x = mBrush.mGradient->radial.fx;
mCNode.mGradient.focal.y = mBrush.mGradient->radial.fy;
mCNode.mGradient.cradius = mBrush.mGradient->radial.cradius;
mCNode.mGradient.fradius = mBrush.mGradient->radial.fradius;
break;
default:
break;
}
}

View File

@ -10,8 +10,8 @@
#include"vpoint.h" #include"vpoint.h"
#include"vpathmesure.h" #include"vpathmesure.h"
#include"lottieplayer.h" #include"lottieplayer.h"
#include"vbrush.h"
#include"vpainter.h" #include"vpainter.h"
#include"vdrawable.h"
V_USE_NAMESPACE V_USE_NAMESPACE
@ -156,47 +156,11 @@ public:
VRle mRle; VRle mRle;
}; };
class VDrawable class LOTDrawable : public VDrawable
{ {
public: public:
enum class DirtyState {
None = 0x00000000,
Path = 0x00000001,
Stroke = 0x00000010,
Brush = 0x00000100,
All = (None | Path | Stroke | Brush)
};
enum class Type {
Fill,
Stroke,
};
typedef vFlag<DirtyState> DirtyFlag;
VDrawable();
void sync(); void sync();
void setPath(const VPath &path);
void setFillRule(FillRule rule){mFillRule = rule;}
void setBrush(const VBrush &brush){mBrush = brush;}
void setStrokeInfo(CapStyle cap, JoinStyle join, float meterLimit, float strokeWidth);
void setDashInfo(float *array, int size);
void preprocess();
VRle rle();
public: public:
DirtyFlag mFlag;
VDrawable::Type mType;
VBrush mBrush;
VPath mPath;
FillRule mFillRule;
std::future<VRle> mRleTask;
VRle mRle;
struct {
bool enable;
float width;
CapStyle cap;
JoinStyle join;
float meterLimit;
float *dashArray;
int dashArraySize;
}mStroke;
LOTNode mCNode; LOTNode mCNode;
}; };

View File

@ -20,6 +20,7 @@ target_sources(lottie-player
"${CMAKE_CURRENT_LIST_DIR}/vinterpolator.cpp" "${CMAKE_CURRENT_LIST_DIR}/vinterpolator.cpp"
"${CMAKE_CURRENT_LIST_DIR}/vbezier.cpp" "${CMAKE_CURRENT_LIST_DIR}/vbezier.cpp"
"${CMAKE_CURRENT_LIST_DIR}/vraster.cpp" "${CMAKE_CURRENT_LIST_DIR}/vraster.cpp"
"${CMAKE_CURRENT_LIST_DIR}/vdrawable.cpp"
) )
target_include_directories(lottie-player target_include_directories(lottie-player

View File

@ -10,6 +10,8 @@ source_file += files('vpainter.cpp')
source_file += files('vcompositionfunctions.cpp') source_file += files('vcompositionfunctions.cpp')
source_file += files('vdrawhelper.cpp') source_file += files('vdrawhelper.cpp')
source_file += files('vdrawhelper_sse2.cpp') source_file += files('vdrawhelper_sse2.cpp')
source_file += files('vdrawable.cpp')
source_file += files('vregion.cpp') source_file += files('vregion.cpp')
source_file += files('vrle.cpp') source_file += files('vrle.cpp')

46
src/vector/vdrawable.cpp Normal file
View File

@ -0,0 +1,46 @@
#include "vdrawable.h"
#include"vdasher.h"
#include"vraster.h"
void VDrawable::preprocess()
{
if (mFlag & (DirtyState::Path)) {
if (mStroke.enable) {
VPath newPath = mPath;
if (mStroke.dashArraySize) {
VDasher dasher(mStroke.dashArray, mStroke.dashArraySize);
newPath = dasher.dashed(mPath);
}
mRleTask = VRaster::instance().generateStrokeInfo(mPath, mStroke.cap, mStroke.join,
mStroke.width, mStroke.meterLimit);
} else {
mRleTask = VRaster::instance().generateFillInfo(mPath, mFillRule);
}
mFlag &= ~DirtyFlag(DirtyState::Path);
}
}
VRle VDrawable::rle()
{
if (mRleTask.valid()) {
mRle = std::move(mRleTask.get());
}
return mRle;
}
void VDrawable::setStrokeInfo(CapStyle cap, JoinStyle join, float meterLimit, float strokeWidth)
{
mStroke.enable = true;
mStroke.cap = cap;
mStroke.join = join;
mStroke.meterLimit = meterLimit;
mStroke.width = strokeWidth;
mFlag |= DirtyState::Path;
}
void VDrawable::setDashInfo(float *array, int size)
{
mStroke.dashArray = array;
mStroke.dashArraySize = size;
mFlag |= DirtyState::Path;
}

50
src/vector/vdrawable.h Normal file
View File

@ -0,0 +1,50 @@
#ifndef VDRAWABLE_H
#define VDRAWABLE_H
#include "vbrush.h"
#include "vpath.h"
#include "vrle.h"
#include<future>
class VDrawable
{
public:
enum class DirtyState {
None = 0x00000000,
Path = 0x00000001,
Stroke = 0x00000010,
Brush = 0x00000100,
All = (None | Path | Stroke | Brush)
};
enum class Type {
Fill,
Stroke,
};
typedef vFlag<DirtyState> DirtyFlag;
VDrawable() = default;
void setPath(const VPath &path);
void setFillRule(FillRule rule){mFillRule = rule;}
void setBrush(const VBrush &brush){mBrush = brush;}
void setStrokeInfo(CapStyle cap, JoinStyle join, float meterLimit, float strokeWidth);
void setDashInfo(float *array, int size);
void preprocess();
VRle rle();
public:
DirtyFlag mFlag {DirtyState::All};
VDrawable::Type mType {Type::Fill};
VBrush mBrush;
VPath mPath;
FillRule mFillRule{FillRule::Winding};
std::future<VRle> mRleTask;
VRle mRle;
struct {
bool enable {false};
float width {0.0};
CapStyle cap {CapStyle::Flat};
JoinStyle join {JoinStyle::Bevel};
float meterLimit {10};
float *dashArray {nullptr};
int dashArraySize {0};
}mStroke;
};
#endif // VDRAWABLE_H