Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(146)

Side by Side Diff: src/core/SkPath.cpp

Issue 1372103003: Make SkPath fFirstDirection atomic to fix tsan. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: WS fix Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « include/core/SkPath.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2006 The Android Open Source Project 2 * Copyright 2006 The Android Open Source Project
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkBuffer.h" 8 #include "SkBuffer.h"
9 #include "SkErrorInternals.h" 9 #include "SkErrorInternals.h"
10 #include "SkGeometry.h" 10 #include "SkGeometry.h"
(...skipping 18 matching lines...) Expand all
29 29
30 static bool is_degenerate(const SkPath& path) { 30 static bool is_degenerate(const SkPath& path) {
31 SkPath::Iter iter(path, false); 31 SkPath::Iter iter(path, false);
32 SkPoint pts[4]; 32 SkPoint pts[4];
33 return SkPath::kDone_Verb == iter.next(pts); 33 return SkPath::kDone_Verb == iter.next(pts);
34 } 34 }
35 35
36 class SkAutoDisableDirectionCheck { 36 class SkAutoDisableDirectionCheck {
37 public: 37 public:
38 SkAutoDisableDirectionCheck(SkPath* path) : fPath(path) { 38 SkAutoDisableDirectionCheck(SkPath* path) : fPath(path) {
39 fSaved = static_cast<SkPathPriv::FirstDirection>(fPath->fFirstDirection) ; 39 fSaved = static_cast<SkPathPriv::FirstDirection>(fPath->fFirstDirection. load());
40 } 40 }
41 41
42 ~SkAutoDisableDirectionCheck() { 42 ~SkAutoDisableDirectionCheck() {
43 fPath->fFirstDirection = fSaved; 43 fPath->fFirstDirection = fSaved;
44 } 44 }
45 45
46 private: 46 private:
47 SkPath* fPath; 47 SkPath* fPath;
48 SkPathPriv::FirstDirection fSaved; 48 SkPathPriv::FirstDirection fSaved;
49 }; 49 };
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 } 159 }
160 SkDEBUGCODE(this->validate();) 160 SkDEBUGCODE(this->validate();)
161 return *this; 161 return *this;
162 } 162 }
163 163
164 void SkPath::copyFields(const SkPath& that) { 164 void SkPath::copyFields(const SkPath& that) {
165 //fPathRef is assumed to have been set by the caller. 165 //fPathRef is assumed to have been set by the caller.
166 fLastMoveToIndex = that.fLastMoveToIndex; 166 fLastMoveToIndex = that.fLastMoveToIndex;
167 fFillType = that.fFillType; 167 fFillType = that.fFillType;
168 fConvexity = that.fConvexity; 168 fConvexity = that.fConvexity;
169 fFirstDirection = that.fFirstDirection; 169 // Simulate fFirstDirection = that.fFirstDirection;
170 fFirstDirection.store(that.fFirstDirection.load());
170 fIsVolatile = that.fIsVolatile; 171 fIsVolatile = that.fIsVolatile;
171 } 172 }
172 173
173 bool operator==(const SkPath& a, const SkPath& b) { 174 bool operator==(const SkPath& a, const SkPath& b) {
174 // note: don't need to look at isConvex or bounds, since just comparing the 175 // note: don't need to look at isConvex or bounds, since just comparing the
175 // raw data is sufficient. 176 // raw data is sufficient.
176 return &a == &b || 177 return &a == &b ||
177 (a.fFillType == b.fFillType && *a.fPathRef.get() == *b.fPathRef.get()); 178 (a.fFillType == b.fFillType && *a.fPathRef.get() == *b.fPathRef.get());
178 } 179 }
179 180
180 void SkPath::swap(SkPath& that) { 181 void SkPath::swap(SkPath& that) {
181 if (this != &that) { 182 if (this != &that) {
182 fPathRef.swap(&that.fPathRef); 183 fPathRef.swap(&that.fPathRef);
183 SkTSwap<int>(fLastMoveToIndex, that.fLastMoveToIndex); 184 SkTSwap<int>(fLastMoveToIndex, that.fLastMoveToIndex);
184 SkTSwap<uint8_t>(fFillType, that.fFillType); 185 SkTSwap<uint8_t>(fFillType, that.fFillType);
185 SkTSwap<uint8_t>(fConvexity, that.fConvexity); 186 SkTSwap<uint8_t>(fConvexity, that.fConvexity);
186 SkTSwap<uint8_t>(fFirstDirection, that.fFirstDirection); 187 // Simulate SkTSwap<uint8_t>(fFirstDirection, that.fFirstDirection);
188 uint8_t temp = fFirstDirection;
189 fFirstDirection.store(that.fFirstDirection.load());
190 that.fFirstDirection.store(temp);
187 SkTSwap<SkBool8>(fIsVolatile, that.fIsVolatile); 191 SkTSwap<SkBool8>(fIsVolatile, that.fIsVolatile);
188 } 192 }
189 } 193 }
190 194
191 static inline bool check_edge_against_rect(const SkPoint& p0, 195 static inline bool check_edge_against_rect(const SkPoint& p0,
192 const SkPoint& p1, 196 const SkPoint& p1,
193 const SkRect& rect, 197 const SkRect& rect,
194 SkPathPriv::FirstDirection dir) { 198 SkPathPriv::FirstDirection dir) {
195 const SkPoint* edgeBegin; 199 const SkPoint* edgeBegin;
196 SkVector v; 200 SkVector v;
(...skipping 1291 matching lines...) Expand 10 before | Expand all | Expand 10 after
1488 dst->fIsVolatile = fIsVolatile; 1492 dst->fIsVolatile = fIsVolatile;
1489 } 1493 }
1490 1494
1491 if (SkPathPriv::kUnknown_FirstDirection == fFirstDirection) { 1495 if (SkPathPriv::kUnknown_FirstDirection == fFirstDirection) {
1492 dst->fFirstDirection = SkPathPriv::kUnknown_FirstDirection; 1496 dst->fFirstDirection = SkPathPriv::kUnknown_FirstDirection;
1493 } else { 1497 } else {
1494 SkScalar det2x2 = 1498 SkScalar det2x2 =
1495 SkScalarMul(matrix.get(SkMatrix::kMScaleX), matrix.get(SkMatrix: :kMScaleY)) - 1499 SkScalarMul(matrix.get(SkMatrix::kMScaleX), matrix.get(SkMatrix: :kMScaleY)) -
1496 SkScalarMul(matrix.get(SkMatrix::kMSkewX), matrix.get(SkMatrix:: kMSkewY)); 1500 SkScalarMul(matrix.get(SkMatrix::kMSkewX), matrix.get(SkMatrix:: kMSkewY));
1497 if (det2x2 < 0) { 1501 if (det2x2 < 0) {
1498 dst->fFirstDirection = SkPathPriv::OppositeFirstDirection((SkPat hPriv::FirstDirection)fFirstDirection); 1502 dst->fFirstDirection = SkPathPriv::OppositeFirstDirection(
1503 (SkPathPriv::FirstDirection)fFirstDirection.load());
1499 } else if (det2x2 > 0) { 1504 } else if (det2x2 > 0) {
1500 dst->fFirstDirection = fFirstDirection; 1505 dst->fFirstDirection = fFirstDirection.load();
1501 } else { 1506 } else {
1502 dst->fConvexity = kUnknown_Convexity; 1507 dst->fConvexity = kUnknown_Convexity;
1503 dst->fFirstDirection = SkPathPriv::kUnknown_FirstDirection; 1508 dst->fFirstDirection = SkPathPriv::kUnknown_FirstDirection;
1504 } 1509 }
1505 } 1510 }
1506 1511
1507 SkDEBUGCODE(dst->validate();) 1512 SkDEBUGCODE(dst->validate();)
1508 } 1513 }
1509 } 1514 }
1510 1515
(...skipping 957 matching lines...) Expand 10 before | Expand all | Expand 10 after
2468 2473
2469 /* 2474 /*
2470 * We loop through all contours, and keep the computed cross-product of the 2475 * We loop through all contours, and keep the computed cross-product of the
2471 * contour that contained the global y-max. If we just look at the first 2476 * contour that contained the global y-max. If we just look at the first
2472 * contour, we may find one that is wound the opposite way (correctly) since 2477 * contour, we may find one that is wound the opposite way (correctly) since
2473 * it is the interior of a hole (e.g. 'o'). Thus we must find the contour 2478 * it is the interior of a hole (e.g. 'o'). Thus we must find the contour
2474 * that is outer most (or at least has the global y-max) before we can consider 2479 * that is outer most (or at least has the global y-max) before we can consider
2475 * its cross product. 2480 * its cross product.
2476 */ 2481 */
2477 bool SkPathPriv::CheapComputeFirstDirection(const SkPath& path, FirstDirection* dir) { 2482 bool SkPathPriv::CheapComputeFirstDirection(const SkPath& path, FirstDirection* dir) {
2478 if (kUnknown_FirstDirection != path.fFirstDirection) { 2483 if (kUnknown_FirstDirection != path.fFirstDirection.load()) {
2479 *dir = static_cast<FirstDirection>(path.fFirstDirection); 2484 *dir = static_cast<FirstDirection>(path.fFirstDirection.load());
2480 return true; 2485 return true;
2481 } 2486 }
2482 2487
2483 // don't want to pay the cost for computing this if it 2488 // don't want to pay the cost for computing this if it
2484 // is unknown, so we don't call isConvex() 2489 // is unknown, so we don't call isConvex()
2485 if (SkPath::kConvex_Convexity == path.getConvexityOrUnknown()) { 2490 if (SkPath::kConvex_Convexity == path.getConvexityOrUnknown()) {
2486 SkASSERT(kUnknown_FirstDirection == path.fFirstDirection); 2491 SkASSERT(kUnknown_FirstDirection == path.fFirstDirection);
2487 *dir = static_cast<FirstDirection>(path.fFirstDirection); 2492 *dir = static_cast<FirstDirection>(path.fFirstDirection.load());
2488 return false; 2493 return false;
2489 } 2494 }
2490 2495
2491 ContourIter iter(*path.fPathRef.get()); 2496 ContourIter iter(*path.fPathRef.get());
2492 2497
2493 // initialize with our logical y-min 2498 // initialize with our logical y-min
2494 SkScalar ymax = path.getBounds().fTop; 2499 SkScalar ymax = path.getBounds().fTop;
2495 SkScalar ymaxCross = 0; 2500 SkScalar ymaxCross = 0;
2496 2501
2497 for (; !iter.done(); iter.next()) { 2502 for (; !iter.done(); iter.next()) {
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
2808 switch (this->getFillType()) { 2813 switch (this->getFillType()) {
2809 case SkPath::kEvenOdd_FillType: 2814 case SkPath::kEvenOdd_FillType:
2810 case SkPath::kInverseEvenOdd_FillType: 2815 case SkPath::kInverseEvenOdd_FillType:
2811 w &= 1; 2816 w &= 1;
2812 break; 2817 break;
2813 default: 2818 default:
2814 break; 2819 break;
2815 } 2820 }
2816 return SkToBool(w); 2821 return SkToBool(w);
2817 } 2822 }
OLDNEW
« no previous file with comments | « include/core/SkPath.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698