From abf01b96a03d5a8833cd7cfe5d1c3593001a439f Mon Sep 17 00:00:00 2001 From: subhransu mohanty Date: Fri, 20 Jul 2018 15:44:58 +0900 Subject: [PATCH] lottie/vector: make the pathmesure class thread safe. Change-Id: I10dc4e0a0c6c050bc573c792f819cf91c2982f03 --- src/vector/vpathmesure.cpp | 64 +++++++++++++++++++++++++++++++++++--- src/vector/vpathmesure.h | 8 ++++- 2 files changed, 66 insertions(+), 6 deletions(-) diff --git a/src/vector/vpathmesure.cpp b/src/vector/vpathmesure.cpp index 52e93e8..9e92b04 100644 --- a/src/vector/vpathmesure.cpp +++ b/src/vector/vpathmesure.cpp @@ -5,30 +5,80 @@ V_BEGIN_NAMESPACE struct VPathMesureData { + VPathMesureData():ref(-1){} void setPath(const VPath &path) { mPath = path; } - VPath& getPath() { return mPath; } + VPath& getPath() { return mPath; } VPath mPath; + RefCount ref; }; -V_END_NAMESPACE +static const struct VPathMesureData shared_empty; + +inline void VPathMesure::cleanUp(VPathMesureData *d) +{ + delete d; +} -static const struct VPathMesureData shared_empty = {VPath()}; +void VPathMesure::detach() +{ + if (d->ref.isShared()) + *this = copy(); +} + +VPathMesure VPathMesure::copy() const +{ + VPathMesure other; + + other.d = new VPathMesureData; + other.d->mPath = d->mPath; + other.d->ref.setOwned(); + return other; +} VPathMesure::~VPathMesure() { + if (!d->ref.deref()) + cleanUp(d); } VPathMesure::VPathMesure() - : d(const_cast(&shared_empty)) + : d(const_cast(&shared_empty)) +{ +} + +VPathMesure::VPathMesure(const VPathMesure &other) +{ + d = other.d; + d->ref.ref(); +} + +VPathMesure::VPathMesure(VPathMesure &&other): d(other.d) { + other.d = const_cast(&shared_empty); } -VPathMesure::VPathMesure(const VPath *p, bool foceClose) +VPathMesure &VPathMesure::operator=(const VPathMesure &other) { + other.d->ref.ref(); + if (!d->ref.deref()) + cleanUp(d); + + d = other.d; + return *this; +} + +inline VPathMesure &VPathMesure::operator=(VPathMesure &&other) +{ + if (!d->ref.deref()) + cleanUp(d); + d = other.d; + other.d = const_cast(&shared_empty); + return *this; } void VPathMesure::setStart(float pos) { + detach(); VPath &path = d->getPath(); const std::vector &elm = path.elements(); const std::vector &pts = path.points(); @@ -168,6 +218,7 @@ void VPathMesure::setStart(float pos) void VPathMesure::setEnd(float pos) { + detach(); VPath &path = d->getPath(); const std::vector &elm = path.elements(); const std::vector &pts = path.points(); @@ -299,6 +350,7 @@ void VPathMesure::setEnd(float pos) void VPathMesure::setPath(const VPath &path) { + detach(); d->setPath(path); } @@ -306,3 +358,5 @@ VPath VPathMesure::getPath() { return d->getPath(); } + +V_END_NAMESPACE diff --git a/src/vector/vpathmesure.h b/src/vector/vpathmesure.h index 88fc9fd..e95c966 100644 --- a/src/vector/vpathmesure.h +++ b/src/vector/vpathmesure.h @@ -11,13 +11,19 @@ class VPathMesure public: ~VPathMesure(); VPathMesure(); - VPathMesure(const VPath *path, bool foceClose); + VPathMesure(const VPathMesure &other); + VPathMesure(VPathMesure &&other); + VPathMesure &operator=(const VPathMesure &); + VPathMesure &operator=(VPathMesure &&other); int getLength() const; void setPath(const VPath &path); VPath getPath(); void setStart(float pos); void setEnd(float pos); private: + VPathMesure copy() const; + void detach(); + void cleanUp(VPathMesureData *x); VPathMesureData *d; }; -- 2.34.1