aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar herb <herb@google.com>2015-09-28 11:05:47 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-09-28 11:05:47 -0700
commit9f4dbca3290cfaca7dd17b71eb6b5b3a0ba5323e (patch)
treedd8b718075779650af0f8c9f569688cbb882f80b
parent449d9b7e2d1b2e20963f18639c6e541ef953f069 (diff)
Make SkPath fFirstDirection atomic to fix tsan.
There is no API change. TBR=reed@google.com BUG=skia: Review URL: https://codereview.chromium.org/1372103003
-rw-r--r--include/core/SkPath.h12
-rw-r--r--src/core/SkPath.cpp21
2 files changed, 19 insertions, 14 deletions
diff --git a/include/core/SkPath.h b/include/core/SkPath.h
index caf4cfe5ec..d3673b6d5d 100644
--- a/include/core/SkPath.h
+++ b/include/core/SkPath.h
@@ -938,13 +938,13 @@ private:
kCurrent_Version = 1
};
- SkAutoTUnref<SkPathRef> fPathRef;
+ SkAutoTUnref<SkPathRef> fPathRef;
- int fLastMoveToIndex;
- uint8_t fFillType;
- mutable uint8_t fConvexity;
- mutable uint8_t fFirstDirection; // SkPathPriv::FirstDirection
- mutable SkBool8 fIsVolatile;
+ int fLastMoveToIndex;
+ uint8_t fFillType;
+ mutable uint8_t fConvexity;
+ mutable SkAtomic<uint8_t> fFirstDirection; // SkPathPriv::FirstDirection
+ mutable SkBool8 fIsVolatile;
/** Resets all fields other than fPathRef to their initial 'empty' values.
* Assumes the caller has already emptied fPathRef.
diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp
index 8da15804de..97e34386dc 100644
--- a/src/core/SkPath.cpp
+++ b/src/core/SkPath.cpp
@@ -36,7 +36,7 @@ static bool is_degenerate(const SkPath& path) {
class SkAutoDisableDirectionCheck {
public:
SkAutoDisableDirectionCheck(SkPath* path) : fPath(path) {
- fSaved = static_cast<SkPathPriv::FirstDirection>(fPath->fFirstDirection);
+ fSaved = static_cast<SkPathPriv::FirstDirection>(fPath->fFirstDirection.load());
}
~SkAutoDisableDirectionCheck() {
@@ -166,7 +166,8 @@ void SkPath::copyFields(const SkPath& that) {
fLastMoveToIndex = that.fLastMoveToIndex;
fFillType = that.fFillType;
fConvexity = that.fConvexity;
- fFirstDirection = that.fFirstDirection;
+ // Simulate fFirstDirection = that.fFirstDirection;
+ fFirstDirection.store(that.fFirstDirection.load());
fIsVolatile = that.fIsVolatile;
}
@@ -183,7 +184,10 @@ void SkPath::swap(SkPath& that) {
SkTSwap<int>(fLastMoveToIndex, that.fLastMoveToIndex);
SkTSwap<uint8_t>(fFillType, that.fFillType);
SkTSwap<uint8_t>(fConvexity, that.fConvexity);
- SkTSwap<uint8_t>(fFirstDirection, that.fFirstDirection);
+ // Simulate SkTSwap<uint8_t>(fFirstDirection, that.fFirstDirection);
+ uint8_t temp = fFirstDirection;
+ fFirstDirection.store(that.fFirstDirection.load());
+ that.fFirstDirection.store(temp);
SkTSwap<SkBool8>(fIsVolatile, that.fIsVolatile);
}
}
@@ -1495,9 +1499,10 @@ void SkPath::transform(const SkMatrix& matrix, SkPath* dst) const {
SkScalarMul(matrix.get(SkMatrix::kMScaleX), matrix.get(SkMatrix::kMScaleY)) -
SkScalarMul(matrix.get(SkMatrix::kMSkewX), matrix.get(SkMatrix::kMSkewY));
if (det2x2 < 0) {
- dst->fFirstDirection = SkPathPriv::OppositeFirstDirection((SkPathPriv::FirstDirection)fFirstDirection);
+ dst->fFirstDirection = SkPathPriv::OppositeFirstDirection(
+ (SkPathPriv::FirstDirection)fFirstDirection.load());
} else if (det2x2 > 0) {
- dst->fFirstDirection = fFirstDirection;
+ dst->fFirstDirection = fFirstDirection.load();
} else {
dst->fConvexity = kUnknown_Convexity;
dst->fFirstDirection = SkPathPriv::kUnknown_FirstDirection;
@@ -2475,8 +2480,8 @@ static void crossToDir(SkScalar cross, SkPathPriv::FirstDirection* dir) {
* its cross product.
*/
bool SkPathPriv::CheapComputeFirstDirection(const SkPath& path, FirstDirection* dir) {
- if (kUnknown_FirstDirection != path.fFirstDirection) {
- *dir = static_cast<FirstDirection>(path.fFirstDirection);
+ if (kUnknown_FirstDirection != path.fFirstDirection.load()) {
+ *dir = static_cast<FirstDirection>(path.fFirstDirection.load());
return true;
}
@@ -2484,7 +2489,7 @@ bool SkPathPriv::CheapComputeFirstDirection(const SkPath& path, FirstDirection*
// is unknown, so we don't call isConvex()
if (SkPath::kConvex_Convexity == path.getConvexityOrUnknown()) {
SkASSERT(kUnknown_FirstDirection == path.fFirstDirection);
- *dir = static_cast<FirstDirection>(path.fFirstDirection);
+ *dir = static_cast<FirstDirection>(path.fFirstDirection.load());
return false;
}