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

Side by Side Diff: src/core/SkPathRef.h

Issue 18029006: Remove SK_DEBUG_PATH_REF (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « src/core/SkPath.cpp ('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 /* 2 /*
3 * Copyright 2012 Google Inc. 3 * Copyright 2012 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 #ifndef SkPathRef_DEFINED 9 #ifndef SkPathRef_DEFINED
10 #define SkPathRef_DEFINED 10 #define SkPathRef_DEFINED
(...skipping 11 matching lines...) Expand all
22 * 22 *
23 * The points and verbs are stored in a single allocation. The points are at the begining of the 23 * The points and verbs are stored in a single allocation. The points are at the begining of the
24 * allocation while the verbs are stored at end of the allocation, in reverse or der. Thus the points 24 * allocation while the verbs are stored at end of the allocation, in reverse or der. Thus the points
25 * and verbs both grow into the middle of the allocation until the meet. To acce ss verb i in the 25 * and verbs both grow into the middle of the allocation until the meet. To acce ss verb i in the
26 * verb array use ref.verbs()[~i] (because verbs() returns a pointer just beyond the first 26 * verb array use ref.verbs()[~i] (because verbs() returns a pointer just beyond the first
27 * logical verb or the last verb in memory). 27 * logical verb or the last verb in memory).
28 */ 28 */
29 29
30 class SkPathRef; 30 class SkPathRef;
31 31
32 // This path ref should never be deleted once it is created. It should not be gl obal but was made
33 // so for checks when SK_DEBUG_PATH_REF is enabled. It we be re-hidden when the debugging code is
34 // reverted.
35 SkPathRef* gEmptyPathRef;
36
37 // Temporary hackery to try to nail down http://code.google.com/p/chromium/issue s/detail?id=148637
38 #if SK_DEBUG_PATH_REF
39 #define PR_CONTAINER SkPath::PathRefDebugRef
40 #define SkDEBUGCODE_X(code) code
41 #define SkASSERT_X(cond) SK_DEBUGBREAK(cond)
42 // We put the mutex in a factory function to protect against static-initiali zion order
43 // fiasco when SkPaths are created before main().
44 static SkMutex* owners_mutex() {
45 static SkMutex* gOwnersMutex;
46 if (!gOwnersMutex) {
47 gOwnersMutex = new SkMutex(); // leak!
48 }
49 return gOwnersMutex;
50 }
51 // We have a static initializer that calls owners_mutex before main() so tha t
52 // hopefully that we only wind up with one mutex (assuming no threads create d
53 // before static initialization is finished.)
54 static const SkMutex* gOwnersMutexForce = owners_mutex();
55 #else
56 #define PR_CONTAINER SkAutoTUnref<SkPathRef>
57 #define SkDEBUGCODE_X(code) SkDEBUGCODE(code)
58 #define SkASSERT_X(cond) SkASSERT(cond)
59 #endif
60
61 class SkPathRef : public ::SkRefCnt { 32 class SkPathRef : public ::SkRefCnt {
62 public: 33 public:
63 SK_DECLARE_INST_COUNT(SkPathRef); 34 SK_DECLARE_INST_COUNT(SkPathRef);
64 35
65 class Editor { 36 class Editor {
66 public: 37 public:
67 Editor(PR_CONTAINER* pathRef, 38 Editor(SkAutoTUnref<SkPathRef>* pathRef,
68 int incReserveVerbs = 0, 39 int incReserveVerbs = 0,
69 int incReservePoints = 0) { 40 int incReservePoints = 0) {
70 if (pathRef->get()->getRefCnt() > 1) { 41 if (pathRef->get()->getRefCnt() > 1) {
71 SkPathRef* copy = SkNEW(SkPathRef); 42 SkPathRef* copy = SkNEW(SkPathRef);
72 copy->copy(*pathRef->get(), incReserveVerbs, incReservePoints); 43 copy->copy(*pathRef->get(), incReserveVerbs, incReservePoints);
73 pathRef->reset(copy); 44 pathRef->reset(copy);
74 } else { 45 } else {
75 (*pathRef)->incReserve(incReserveVerbs, incReservePoints); 46 (*pathRef)->incReserve(incReserveVerbs, incReservePoints);
76 } 47 }
77 fPathRef = pathRef->get(); 48 fPathRef = pathRef->get();
78 fPathRef->fGenerationID = 0; 49 fPathRef->fGenerationID = 0;
79 SkDEBUGCODE_X(sk_atomic_inc(&fPathRef->fEditorsAttached);) 50 SkDEBUGCODE(sk_atomic_inc(&fPathRef->fEditorsAttached);)
80 } 51 }
81 52
82 ~Editor() { SkDEBUGCODE_X(sk_atomic_dec(&fPathRef->fEditorsAttached);) } 53 ~Editor() { SkDEBUGCODE(sk_atomic_dec(&fPathRef->fEditorsAttached);) }
83 54
84 /** 55 /**
85 * Returns the array of points. 56 * Returns the array of points.
86 */ 57 */
87 SkPoint* points() { return fPathRef->fPoints; } 58 SkPoint* points() { return fPathRef->fPoints; }
88 59
89 /** 60 /**
90 * Gets the ith point. Shortcut for this->points() + i 61 * Gets the ith point. Shortcut for this->points() + i
91 */ 62 */
92 SkPoint* atPoint(int i) { 63 SkPoint* atPoint(int i) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 /** 109 /**
139 * Gets the path ref that is wrapped in the Editor. 110 * Gets the path ref that is wrapped in the Editor.
140 */ 111 */
141 SkPathRef* pathRef() { return fPathRef; } 112 SkPathRef* pathRef() { return fPathRef; }
142 113
143 private: 114 private:
144 SkPathRef* fPathRef; 115 SkPathRef* fPathRef;
145 }; 116 };
146 117
147 public: 118 public:
148 #if SK_DEBUG_PATH_REF
149 void addOwner(SkPath* owner) {
150 SkAutoMutexAcquire ac(owners_mutex());
151 for (int i = 0; i < fOwners.count(); ++i) {
152 SkASSERT_X(fOwners[i] != owner);
153 }
154 *fOwners.append() = owner;
155 SkASSERT_X((this->getRefCnt() == fOwners.count()) ||
156 (this == gEmptyPathRef && this->getRefCnt() == fOwners.count( ) + 1));
157 }
158
159 void removeOwner(SkPath* owner) {
160 SkAutoMutexAcquire ac(owners_mutex());
161 SkASSERT_X((this->getRefCnt() == fOwners.count()) ||
162 (this == gEmptyPathRef && this->getRefCnt() == fOwners.count( ) + 1));
163 bool found = false;
164 for (int i = 0; !found && i < fOwners.count(); ++i) {
165 found = (owner == fOwners[i]);
166 if (found) {
167 fOwners.remove(i);
168 }
169 }
170 SkASSERT_X(found);
171 }
172 #endif
173
174 /** 119 /**
175 * Gets a path ref with no verbs or points. 120 * Gets a path ref with no verbs or points.
176 */ 121 */
177 static SkPathRef* CreateEmpty() { 122 static SkPathRef* CreateEmpty() {
123 static SkPathRef* gEmptyPathRef;
178 if (!gEmptyPathRef) { 124 if (!gEmptyPathRef) {
179 gEmptyPathRef = SkNEW(SkPathRef); // leak! 125 gEmptyPathRef = SkNEW(SkPathRef); // leak!
180 } 126 }
181 return SkRef(gEmptyPathRef); 127 return SkRef(gEmptyPathRef);
182 } 128 }
183 129
184 /** 130 /**
185 * Transforms a path ref by a matrix, allocating a new one only if necessary . 131 * Transforms a path ref by a matrix, allocating a new one only if necessary .
186 */ 132 */
187 static void CreateTransformedCopy(PR_CONTAINER* dst, 133 static void CreateTransformedCopy(SkAutoTUnref<SkPathRef>* dst,
188 const SkPathRef& src, 134 const SkPathRef& src,
189 const SkMatrix& matrix) { 135 const SkMatrix& matrix) {
190 src.validate(); 136 src.validate();
191 if (matrix.isIdentity()) { 137 if (matrix.isIdentity()) {
192 if (dst->get() != &src) { 138 if (dst->get() != &src) {
193 src.ref(); 139 src.ref();
194 dst->reset(const_cast<SkPathRef*>(&src)); 140 dst->reset(const_cast<SkPathRef*>(&src));
195 (*dst)->validate(); 141 (*dst)->validate();
196 } 142 }
197 return; 143 return;
(...skipping 27 matching lines...) Expand all
225 buffer->read(ref->fPoints, pointCount * sizeof(SkPoint)); 171 buffer->read(ref->fPoints, pointCount * sizeof(SkPoint));
226 buffer->read(ref->fConicWeights.begin(), conicCount * sizeof(SkScalar)); 172 buffer->read(ref->fConicWeights.begin(), conicCount * sizeof(SkScalar));
227 return ref; 173 return ref;
228 } 174 }
229 175
230 /** 176 /**
231 * Rollsback a path ref to zero verbs and points with the assumption that th e path ref will be 177 * Rollsback a path ref to zero verbs and points with the assumption that th e path ref will be
232 * repopulated with approximately the same number of verbs and points. A new path ref is created 178 * repopulated with approximately the same number of verbs and points. A new path ref is created
233 * only if necessary. 179 * only if necessary.
234 */ 180 */
235 static void Rewind(PR_CONTAINER* pathRef) { 181 static void Rewind(SkAutoTUnref<SkPathRef>* pathRef) {
236 if (1 == (*pathRef)->getRefCnt()) { 182 if (1 == (*pathRef)->getRefCnt()) {
237 (*pathRef)->validate(); 183 (*pathRef)->validate();
238 (*pathRef)->fVerbCnt = 0; 184 (*pathRef)->fVerbCnt = 0;
239 (*pathRef)->fPointCnt = 0; 185 (*pathRef)->fPointCnt = 0;
240 (*pathRef)->fFreeSpace = (*pathRef)->currSize(); 186 (*pathRef)->fFreeSpace = (*pathRef)->currSize();
241 (*pathRef)->fGenerationID = 0; 187 (*pathRef)->fGenerationID = 0;
242 (*pathRef)->fConicWeights.rewind(); 188 (*pathRef)->fConicWeights.rewind();
243 (*pathRef)->validate(); 189 (*pathRef)->validate();
244 } else { 190 } else {
245 int oldVCnt = (*pathRef)->countVerbs(); 191 int oldVCnt = (*pathRef)->countVerbs();
246 int oldPCnt = (*pathRef)->countPoints(); 192 int oldPCnt = (*pathRef)->countPoints();
247 pathRef->reset(SkNEW(SkPathRef)); 193 pathRef->reset(SkNEW(SkPathRef));
248 (*pathRef)->resetToSize(0, 0, 0, oldVCnt, oldPCnt); 194 (*pathRef)->resetToSize(0, 0, 0, oldVCnt, oldPCnt);
249 } 195 }
250 } 196 }
251 197
252 virtual ~SkPathRef() { 198 virtual ~SkPathRef() {
253 SkASSERT_X(this != gEmptyPathRef);
254 #if SK_DEBUG_PATH_REF
255 SkASSERT_X(!fOwners.count());
256 #endif
257
258 this->validate(); 199 this->validate();
259 sk_free(fPoints); 200 sk_free(fPoints);
260 201
261 SkDEBUGCODE_X(fPoints = NULL;) 202 SkDEBUGCODE(fPoints = NULL;)
262 SkDEBUGCODE_X(fVerbs = NULL;) 203 SkDEBUGCODE(fVerbs = NULL;)
263 SkDEBUGCODE_X(fVerbCnt = 0x9999999;) 204 SkDEBUGCODE(fVerbCnt = 0x9999999;)
264 SkDEBUGCODE_X(fPointCnt = 0xAAAAAAA;) 205 SkDEBUGCODE(fPointCnt = 0xAAAAAAA;)
265 SkDEBUGCODE_X(fPointCnt = 0xBBBBBBB;) 206 SkDEBUGCODE(fPointCnt = 0xBBBBBBB;)
266 SkDEBUGCODE_X(fGenerationID = 0xEEEEEEEE;) 207 SkDEBUGCODE(fGenerationID = 0xEEEEEEEE;)
267 SkDEBUGCODE_X(fEditorsAttached = 0x7777777;) 208 SkDEBUGCODE(fEditorsAttached = 0x7777777;)
268 } 209 }
269 210
270 int countPoints() const { this->validate(); return fPointCnt; } 211 int countPoints() const { this->validate(); return fPointCnt; }
271 int countVerbs() const { this->validate(); return fVerbCnt; } 212 int countVerbs() const { this->validate(); return fVerbCnt; }
272 213
273 /** 214 /**
274 * Returns a pointer one beyond the first logical verb (last verb in memory order). 215 * Returns a pointer one beyond the first logical verb (last verb in memory order).
275 */ 216 */
276 const uint8_t* verbs() const { this->validate(); return fVerbs; } 217 const uint8_t* verbs() const { this->validate(); return fVerbs; }
277 218
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 ref.fGenerationID = this->genID(); 284 ref.fGenerationID = this->genID();
344 } 285 }
345 return true; 286 return true;
346 } 287 }
347 288
348 /** 289 /**
349 * Writes the path points and verbs to a buffer. 290 * Writes the path points and verbs to a buffer.
350 */ 291 */
351 void writeToBuffer(SkWBuffer* buffer) { 292 void writeToBuffer(SkWBuffer* buffer) {
352 this->validate(); 293 this->validate();
353 SkDEBUGCODE_X(size_t beforePos = buffer->pos();) 294 SkDEBUGCODE(size_t beforePos = buffer->pos();)
354 295
355 // TODO: write gen ID here. Problem: We don't know if we're cross proces s or not from 296 // TODO: write gen ID here. Problem: We don't know if we're cross proces s or not from
356 // SkWBuffer. Until this is fixed we write 0. 297 // SkWBuffer. Until this is fixed we write 0.
357 buffer->write32(0); 298 buffer->write32(0);
358 buffer->write32(fVerbCnt); 299 buffer->write32(fVerbCnt);
359 buffer->write32(fPointCnt); 300 buffer->write32(fPointCnt);
360 buffer->write32(fConicWeights.count()); 301 buffer->write32(fConicWeights.count());
361 buffer->write(verbsMemBegin(), fVerbCnt * sizeof(uint8_t)); 302 buffer->write(verbsMemBegin(), fVerbCnt * sizeof(uint8_t));
362 buffer->write(fPoints, fPointCnt * sizeof(SkPoint)); 303 buffer->write(fPoints, fPointCnt * sizeof(SkPoint));
363 buffer->write(fConicWeights.begin(), fConicWeights.bytes()); 304 buffer->write(fConicWeights.begin(), fConicWeights.bytes());
(...skipping 12 matching lines...) Expand all
376 } 317 }
377 318
378 private: 319 private:
379 SkPathRef() { 320 SkPathRef() {
380 fPointCnt = 0; 321 fPointCnt = 0;
381 fVerbCnt = 0; 322 fVerbCnt = 0;
382 fVerbs = NULL; 323 fVerbs = NULL;
383 fPoints = NULL; 324 fPoints = NULL;
384 fFreeSpace = 0; 325 fFreeSpace = 0;
385 fGenerationID = kEmptyGenID; 326 fGenerationID = kEmptyGenID;
386 SkDEBUGCODE_X(fEditorsAttached = 0;) 327 SkDEBUGCODE(fEditorsAttached = 0;)
387 this->validate(); 328 this->validate();
388 } 329 }
389 330
390 void copy(const SkPathRef& ref, int additionalReserveVerbs, int additionalRe servePoints) { 331 void copy(const SkPathRef& ref, int additionalReserveVerbs, int additionalRe servePoints) {
391 this->validate(); 332 this->validate();
392 this->resetToSize(ref.fVerbCnt, ref.fPointCnt, ref.fConicWeights.count() , 333 this->resetToSize(ref.fVerbCnt, ref.fPointCnt, ref.fConicWeights.count() ,
393 additionalReserveVerbs, additionalReservePoints); 334 additionalReserveVerbs, additionalReservePoints);
394 memcpy(this->verbsMemWritable(), ref.verbsMemBegin(), ref.fVerbCnt * siz eof(uint8_t)); 335 memcpy(this->verbsMemWritable(), ref.verbsMemBegin(), ref.fVerbCnt * siz eof(uint8_t));
395 memcpy(this->fPoints, ref.fPoints, ref.fPointCnt * sizeof(SkPoint)); 336 memcpy(this->fPoints, ref.fPoints, ref.fPointCnt * sizeof(SkPoint));
396 fConicWeights = ref.fConicWeights; 337 fConicWeights = ref.fConicWeights;
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
544 return reinterpret_cast<intptr_t>(fVerbs) - reinterpret_cast<intptr_t>(f Points); 485 return reinterpret_cast<intptr_t>(fVerbs) - reinterpret_cast<intptr_t>(f Points);
545 } 486 }
546 487
547 /** 488 /**
548 * Gets an ID that uniquely identifies the contents of the path ref. If two path refs have the 489 * Gets an ID that uniquely identifies the contents of the path ref. If two path refs have the
549 * same ID then they have the same verbs and points. However, two path refs may have the same 490 * same ID then they have the same verbs and points. However, two path refs may have the same
550 * contents but different genIDs. Zero is reserved and means an ID has not y et been determined 491 * contents but different genIDs. Zero is reserved and means an ID has not y et been determined
551 * for the path ref. 492 * for the path ref.
552 */ 493 */
553 int32_t genID() const { 494 int32_t genID() const {
554 SkASSERT_X(!fEditorsAttached); 495 SkASSERT(!fEditorsAttached);
555 if (!fGenerationID) { 496 if (!fGenerationID) {
556 if (0 == fPointCnt && 0 == fVerbCnt) { 497 if (0 == fPointCnt && 0 == fVerbCnt) {
557 fGenerationID = kEmptyGenID; 498 fGenerationID = kEmptyGenID;
558 } else { 499 } else {
559 static int32_t gPathRefGenerationID; 500 static int32_t gPathRefGenerationID;
560 // do a loop in case our global wraps around, as we never want t o return a 0 or the 501 // do a loop in case our global wraps around, as we never want t o return a 0 or the
561 // empty ID 502 // empty ID
562 do { 503 do {
563 fGenerationID = sk_atomic_inc(&gPathRefGenerationID) + 1; 504 fGenerationID = sk_atomic_inc(&gPathRefGenerationID) + 1;
564 } while (fGenerationID <= kEmptyGenID); 505 } while (fGenerationID <= kEmptyGenID);
(...skipping 22 matching lines...) Expand all
587 uint8_t* fVerbs; // points just past the end of the allocation (v erbs grow backwards) 528 uint8_t* fVerbs; // points just past the end of the allocation (v erbs grow backwards)
588 int fVerbCnt; 529 int fVerbCnt;
589 int fPointCnt; 530 int fPointCnt;
590 size_t fFreeSpace; // redundant but saves computation 531 size_t fFreeSpace; // redundant but saves computation
591 SkTDArray<SkScalar> fConicWeights; 532 SkTDArray<SkScalar> fConicWeights;
592 533
593 enum { 534 enum {
594 kEmptyGenID = 1, // GenID reserved for path ref with zero points and zer o verbs. 535 kEmptyGenID = 1, // GenID reserved for path ref with zero points and zer o verbs.
595 }; 536 };
596 mutable int32_t fGenerationID; 537 mutable int32_t fGenerationID;
597 SkDEBUGCODE_X(int32_t fEditorsAttached;) // assert that only one editor in u se at any time. 538 SkDEBUGCODE(int32_t fEditorsAttached;) // assert that only one editor in use at any time.
598
599 #if SK_DEBUG_PATH_REF
600 SkTDArray<SkPath*> fOwners;
601 #endif
602 539
603 typedef SkRefCnt INHERITED; 540 typedef SkRefCnt INHERITED;
604 }; 541 };
605 542
606 SK_DEFINE_INST_COUNT(SkPathRef); 543 SK_DEFINE_INST_COUNT(SkPathRef);
607 544
608 #endif 545 #endif
OLDNEW
« no previous file with comments | « src/core/SkPath.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698