lottie/vector: make all copy_on_write class in vector thread safe.

Change-Id: Ibf3781775d0d26c0240970b720a59fbfed43f6b2
This commit is contained in:
subhransu mohanty 2018-07-20 08:36:43 +09:00
parent 048dd0d7a3
commit f2bf8eabc9
7 changed files with 34 additions and 28 deletions

View File

@ -156,7 +156,7 @@ VBitmap::VBitmap(uchar *data, int w, int h, int bytesPerLine, VBitmap::Format fo
d->cleanupInfo = nullptr; d->cleanupInfo = nullptr;
d->ownData = false; d->ownData = false;
d->roData = false; d->roData = false;
d->ref = 1; d->ref.setOwned();
} }
VBitmap VBitmap::copy(const VRect& r) const VBitmap VBitmap::copy(const VRect& r) const

View File

@ -36,42 +36,43 @@ typedef uint8_t uchar;
#define VECTOR_FALLTHROUGH #define VECTOR_FALLTHROUGH
#include<atomic>
class RefCount class RefCount
{ {
public: public:
inline RefCount(){}
inline RefCount(int i):atomic(i){} inline RefCount(int i):atomic(i){}
inline bool ref() { inline bool ref() {
int count = atomic; int count = atomic.load();
if (count == 0) // !isSharable if (count == 0) // !isSharable
return false; return false;
if (count != -1) // !isStatic if (count != -1) // !isStatic
atomic++; atomic.fetch_add(1);
return true; return true;
} }
inline bool deref() { inline bool deref() {
int count = atomic; int count = atomic.load();
if (count == 0) // !isSharable if (count == 0) // !isSharable
return false; return false;
if (count == -1) // isStatic if (count == -1) // isStatic
return true; return true;
return --atomic; atomic.fetch_sub(1);
return --count;
} }
bool isShared() const bool isShared() const
{ {
int count = atomic; int count = atomic.load();
return (count != 1) && (count != 0); return (count != 1) && (count != 0);
} }
bool isStatic() const bool isStatic() const
{ {
// Persistent object, never deleted // Persistent object, never deleted
return atomic == -1; int count = atomic.load();
return count == -1;
} }
inline int count()const{return atomic;} inline int count()const{return atomic;}
void setOwned() { atomic = 1; } void setOwned() { atomic.store(1); }
void setUnsharable() { atomic = 0; }
private: private:
int atomic; std::atomic<int> atomic;
}; };
template <typename T> template <typename T>

View File

@ -12,6 +12,12 @@ V_BEGIN_NAMESPACE
*/ */
struct VMatrixData { struct VMatrixData {
VMatrixData(): ref(-1),
type(VMatrix::MatrixType::None),
dirty(VMatrix::MatrixType::None),
m11(1), m12(0), m13(0),
m21(0), m22(1), m23(0),
mtx(0), mty(0), m33(1){}
RefCount ref; RefCount ref;
VMatrix::MatrixType type; VMatrix::MatrixType type;
VMatrix::MatrixType dirty; VMatrix::MatrixType dirty;
@ -19,12 +25,9 @@ struct VMatrixData {
float m21, m22, m23; float m21, m22, m23;
float mtx, mty, m33; float mtx, mty, m33;
}; };
static const struct VMatrixData shared_empty = {RefCount(-1),
VMatrix::MatrixType::None, static const struct VMatrixData shared_empty;
VMatrix::MatrixType::None,
1, 0, 0,
0, 1, 0,
0, 0, 1};
inline float VMatrix::determinant() const inline float VMatrix::determinant() const
{ {
return d->m11*(d->m33*d->m22 - d->mty*d->m23) - return d->m11*(d->m33*d->m22 - d->mty*d->m23) -
@ -95,7 +98,6 @@ VMatrix::~VMatrix()
VMatrix::VMatrix(bool init V_UNUSED) VMatrix::VMatrix(bool init V_UNUSED)
{ {
d = new VMatrixData; d = new VMatrixData;
memcpy(d, &shared_empty, sizeof(VMatrixData));
d->ref.setOwned(); d->ref.setOwned();
} }

View File

@ -9,6 +9,13 @@ V_BEGIN_NAMESPACE
struct VPathData struct VPathData
{ {
VPathData():ref(-1),
m_points(),
m_elements(),
m_segments(0),
mStartPoint(),
mNewSegment(true){}
void copy(VPathData *o); void copy(VPathData *o);
void moveTo(const VPointF &pt); void moveTo(const VPointF &pt);
void lineTo(const VPointF &pt); void lineTo(const VPointF &pt);
@ -95,12 +102,7 @@ int VPathData::segments() const
} }
static const struct VPathData shared_empty = {RefCount(-1), static const struct VPathData shared_empty;
std::vector<VPointF>(),
std::vector<VPath::Element>(),
0,
VPointF(),
true};
inline void VPath::cleanUp(VPathData *d) inline void VPath::cleanUp(VPathData *d)
{ {
@ -117,7 +119,7 @@ VPath VPath::copy() const
{ {
VPath other; VPath other;
other.d = new VPathData(shared_empty); other.d = new VPathData;
other.d->m_points = d->m_points; other.d->m_points = d->m_points;
other.d->m_elements = d->m_elements; other.d->m_elements = d->m_elements;
other.d->m_segments = d->m_segments; other.d->m_segments = d->m_segments;

View File

@ -2044,7 +2044,7 @@ typedef region_type_t VRegionPrivate;
V_BEGIN_NAMESPACE V_BEGIN_NAMESPACE
static VRegionPrivate regionPrivate = {{0,0,0,0}, NULL}; static VRegionPrivate regionPrivate = {{0,0,0,0}, NULL};
const VRegion::VRegionData VRegion::shared_empty = {RefCount(-1), &regionPrivate}; const VRegion::VRegionData VRegion::shared_empty;
inline VRect box_to_rect(box_type_t *box) inline VRect box_to_rect(box_type_t *box)
{ {

View File

@ -55,6 +55,7 @@ private:
void detach(); void detach();
struct VRegionData { struct VRegionData {
VRegionData():ref(-1),rgn(nullptr){}
RefCount ref; RefCount ref;
VRegionPrivate *rgn; VRegionPrivate *rgn;
}; };

View File

@ -555,12 +555,12 @@ void VRleImpl::addSpan(const VRle::Span *span, int count)
struct VRleData struct VRleData
{ {
VRleData():ref(-1), impl(){}
RefCount ref; RefCount ref;
VRleImpl impl; VRleImpl impl;
}; };
static const struct VRleData shared_empty = {RefCount(-1), static const struct VRleData shared_empty;
VRleImpl()};
inline void VRle::cleanUp(VRleData *d) inline void VRle::cleanUp(VRleData *d)
{ {