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->ownData = false;
d->roData = false;
d->ref = 1;
d->ref.setOwned();
}
VBitmap VBitmap::copy(const VRect& r) const

View File

@ -36,42 +36,43 @@ typedef uint8_t uchar;
#define VECTOR_FALLTHROUGH
#include<atomic>
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<int> atomic;
};
template <typename T>

View File

@ -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();
}

View File

@ -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<VPointF>(),
std::vector<VPath::Element>(),
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;

View File

@ -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), &regionPrivate};
const VRegion::VRegionData VRegion::shared_empty;
inline VRect box_to_rect(box_type_t *box)
{

View File

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

View File

@ -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)
{