From f2bf8eabc922e9dcd169f326d7f0c6a52c6c143f Mon Sep 17 00:00:00 2001 From: subhransu mohanty Date: Fri, 20 Jul 2018 08:36:43 +0900 Subject: [PATCH] lottie/vector: make all copy_on_write class in vector thread safe. Change-Id: Ibf3781775d0d26c0240970b720a59fbfed43f6b2 --- src/vector/vbitmap.cpp | 2 +- src/vector/vglobal.h | 21 +++++++++++---------- src/vector/vmatrix.cpp | 16 +++++++++------- src/vector/vpath.cpp | 16 +++++++++------- src/vector/vregion.cpp | 2 +- src/vector/vregion.h | 1 + src/vector/vrle.cpp | 4 ++-- 7 files changed, 34 insertions(+), 28 deletions(-) diff --git a/src/vector/vbitmap.cpp b/src/vector/vbitmap.cpp index a8edd23..c4a0190 100644 --- a/src/vector/vbitmap.cpp +++ b/src/vector/vbitmap.cpp @@ -156,7 +156,7 @@ VBitmap::VBitmap(uchar *data, int w, int h, int bytesPerLine, VBitmap::Format fo d->cleanupInfo = nullptr; d->ownData = false; d->roData = false; - d->ref = 1; + d->ref.setOwned(); } VBitmap VBitmap::copy(const VRect& r) const diff --git a/src/vector/vglobal.h b/src/vector/vglobal.h index 8984600..0585955 100644 --- a/src/vector/vglobal.h +++ b/src/vector/vglobal.h @@ -36,42 +36,43 @@ typedef uint8_t uchar; #define VECTOR_FALLTHROUGH +#include class RefCount { public: - inline RefCount(){} inline RefCount(int i):atomic(i){} inline bool ref() { - int count = atomic; + int count = atomic.load(); if (count == 0) // !isSharable return false; if (count != -1) // !isStatic - atomic++; + atomic.fetch_add(1); return true; } inline bool deref() { - int count = atomic; + int count = atomic.load(); if (count == 0) // !isSharable return false; if (count == -1) // isStatic return true; - return --atomic; + atomic.fetch_sub(1); + return --count; } bool isShared() const { - int count = atomic; + int count = atomic.load(); return (count != 1) && (count != 0); } bool isStatic() const { // Persistent object, never deleted - return atomic == -1; + int count = atomic.load(); + return count == -1; } inline int count()const{return atomic;} - void setOwned() { atomic = 1; } - void setUnsharable() { atomic = 0; } + void setOwned() { atomic.store(1); } private: - int atomic; + std::atomic atomic; }; template diff --git a/src/vector/vmatrix.cpp b/src/vector/vmatrix.cpp index 2a72700..22ec612 100644 --- a/src/vector/vmatrix.cpp +++ b/src/vector/vmatrix.cpp @@ -12,6 +12,12 @@ V_BEGIN_NAMESPACE */ 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; VMatrix::MatrixType type; VMatrix::MatrixType dirty; @@ -19,12 +25,9 @@ struct VMatrixData { float m21, m22, m23; float mtx, mty, m33; }; -static const struct VMatrixData shared_empty = {RefCount(-1), - VMatrix::MatrixType::None, - VMatrix::MatrixType::None, - 1, 0, 0, - 0, 1, 0, - 0, 0, 1}; + +static const struct VMatrixData shared_empty; + inline float VMatrix::determinant() const { return d->m11*(d->m33*d->m22 - d->mty*d->m23) - @@ -95,7 +98,6 @@ VMatrix::~VMatrix() VMatrix::VMatrix(bool init V_UNUSED) { d = new VMatrixData; - memcpy(d, &shared_empty, sizeof(VMatrixData)); d->ref.setOwned(); } diff --git a/src/vector/vpath.cpp b/src/vector/vpath.cpp index ba352ee..592bd97 100644 --- a/src/vector/vpath.cpp +++ b/src/vector/vpath.cpp @@ -9,6 +9,13 @@ V_BEGIN_NAMESPACE struct VPathData { + VPathData():ref(-1), + m_points(), + m_elements(), + m_segments(0), + mStartPoint(), + mNewSegment(true){} + void copy(VPathData *o); void moveTo(const VPointF &pt); void lineTo(const VPointF &pt); @@ -95,12 +102,7 @@ int VPathData::segments() const } -static const struct VPathData shared_empty = {RefCount(-1), - std::vector(), - std::vector(), - 0, - VPointF(), - true}; +static const struct VPathData shared_empty; inline void VPath::cleanUp(VPathData *d) { @@ -117,7 +119,7 @@ VPath VPath::copy() const { VPath other; - other.d = new VPathData(shared_empty); + other.d = new VPathData; other.d->m_points = d->m_points; other.d->m_elements = d->m_elements; other.d->m_segments = d->m_segments; diff --git a/src/vector/vregion.cpp b/src/vector/vregion.cpp index a0cd00e..7738690 100644 --- a/src/vector/vregion.cpp +++ b/src/vector/vregion.cpp @@ -2044,7 +2044,7 @@ typedef region_type_t VRegionPrivate; V_BEGIN_NAMESPACE static VRegionPrivate regionPrivate = {{0,0,0,0}, NULL}; -const VRegion::VRegionData VRegion::shared_empty = {RefCount(-1), ®ionPrivate}; +const VRegion::VRegionData VRegion::shared_empty; inline VRect box_to_rect(box_type_t *box) { diff --git a/src/vector/vregion.h b/src/vector/vregion.h index e5986af..b5d019c 100644 --- a/src/vector/vregion.h +++ b/src/vector/vregion.h @@ -55,6 +55,7 @@ private: void detach(); struct VRegionData { + VRegionData():ref(-1),rgn(nullptr){} RefCount ref; VRegionPrivate *rgn; }; diff --git a/src/vector/vrle.cpp b/src/vector/vrle.cpp index c41871f..1d9ef27 100644 --- a/src/vector/vrle.cpp +++ b/src/vector/vrle.cpp @@ -555,12 +555,12 @@ void VRleImpl::addSpan(const VRle::Span *span, int count) struct VRleData { + VRleData():ref(-1), impl(){} RefCount ref; VRleImpl impl; }; -static const struct VRleData shared_empty = {RefCount(-1), - VRleImpl()}; +static const struct VRleData shared_empty; inline void VRle::cleanUp(VRleData *d) { -- 2.34.1