| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
| 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 "SkLazyPtr.h" | 9 #include "SkLazyPtr.h" |
| 10 #include "SkPath.h" | 10 #include "SkPath.h" |
| 11 #include "SkPathRef.h" | 11 #include "SkPathRef.h" |
| 12 | 12 |
| 13 ////////////////////////////////////////////////////////////////////////////// | 13 ////////////////////////////////////////////////////////////////////////////// |
| 14 SkPathRef::Editor::Editor(SkAutoTUnref<SkPathRef>* pathRef, | 14 SkPathRef::Editor::Editor(SkAutoTUnref<SkPathRef>* pathRef, |
| 15 int incReserveVerbs, | 15 int incReserveVerbs, |
| 16 int incReservePoints) | 16 int incReservePoints) |
| 17 { | 17 { |
| 18 if ((*pathRef)->unique()) { | 18 if ((*pathRef)->unique()) { |
| 19 (*pathRef)->incReserve(incReserveVerbs, incReservePoints); | 19 (*pathRef)->incReserve(incReserveVerbs, incReservePoints); |
| 20 } else { | 20 } else { |
| 21 SkPathRef* copy = SkNEW(SkPathRef); | 21 SkPathRef* copy = new SkPathRef; |
| 22 copy->copy(**pathRef, incReserveVerbs, incReservePoints); | 22 copy->copy(**pathRef, incReserveVerbs, incReservePoints); |
| 23 pathRef->reset(copy); | 23 pathRef->reset(copy); |
| 24 } | 24 } |
| 25 fPathRef = *pathRef; | 25 fPathRef = *pathRef; |
| 26 fPathRef->callGenIDChangeListeners(); | 26 fPathRef->callGenIDChangeListeners(); |
| 27 fPathRef->fGenerationID = 0; | 27 fPathRef->fGenerationID = 0; |
| 28 SkDEBUGCODE(sk_atomic_inc(&fPathRef->fEditorsAttached);) | 28 SkDEBUGCODE(sk_atomic_inc(&fPathRef->fEditorsAttached);) |
| 29 } | 29 } |
| 30 | 30 |
| 31 ////////////////////////////////////////////////////////////////////////////// | 31 ////////////////////////////////////////////////////////////////////////////// |
| 32 | 32 |
| 33 SkPathRef::~SkPathRef() { | 33 SkPathRef::~SkPathRef() { |
| 34 this->callGenIDChangeListeners(); | 34 this->callGenIDChangeListeners(); |
| 35 SkDEBUGCODE(this->validate();) | 35 SkDEBUGCODE(this->validate();) |
| 36 sk_free(fPoints); | 36 sk_free(fPoints); |
| 37 | 37 |
| 38 SkDEBUGCODE(fPoints = NULL;) | 38 SkDEBUGCODE(fPoints = NULL;) |
| 39 SkDEBUGCODE(fVerbs = NULL;) | 39 SkDEBUGCODE(fVerbs = NULL;) |
| 40 SkDEBUGCODE(fVerbCnt = 0x9999999;) | 40 SkDEBUGCODE(fVerbCnt = 0x9999999;) |
| 41 SkDEBUGCODE(fPointCnt = 0xAAAAAAA;) | 41 SkDEBUGCODE(fPointCnt = 0xAAAAAAA;) |
| 42 SkDEBUGCODE(fPointCnt = 0xBBBBBBB;) | 42 SkDEBUGCODE(fPointCnt = 0xBBBBBBB;) |
| 43 SkDEBUGCODE(fGenerationID = 0xEEEEEEEE;) | 43 SkDEBUGCODE(fGenerationID = 0xEEEEEEEE;) |
| 44 SkDEBUGCODE(fEditorsAttached = 0x7777777;) | 44 SkDEBUGCODE(fEditorsAttached = 0x7777777;) |
| 45 } | 45 } |
| 46 | 46 |
| 47 // As a template argument, this must have external linkage. | 47 // As a template argument, this must have external linkage. |
| 48 SkPathRef* sk_create_empty_pathref() { | 48 SkPathRef* sk_create_empty_pathref() { |
| 49 SkPathRef* empty = SkNEW(SkPathRef); | 49 SkPathRef* empty = new SkPathRef; |
| 50 empty->computeBounds(); // Avoids races later to be the first to do this. | 50 empty->computeBounds(); // Avoids races later to be the first to do this. |
| 51 return empty; | 51 return empty; |
| 52 } | 52 } |
| 53 | 53 |
| 54 SK_DECLARE_STATIC_LAZY_PTR(SkPathRef, empty, sk_create_empty_pathref); | 54 SK_DECLARE_STATIC_LAZY_PTR(SkPathRef, empty, sk_create_empty_pathref); |
| 55 | 55 |
| 56 SkPathRef* SkPathRef::CreateEmpty() { | 56 SkPathRef* SkPathRef::CreateEmpty() { |
| 57 return SkRef(empty.get()); | 57 return SkRef(empty.get()); |
| 58 } | 58 } |
| 59 | 59 |
| 60 void SkPathRef::CreateTransformedCopy(SkAutoTUnref<SkPathRef>* dst, | 60 void SkPathRef::CreateTransformedCopy(SkAutoTUnref<SkPathRef>* dst, |
| 61 const SkPathRef& src, | 61 const SkPathRef& src, |
| 62 const SkMatrix& matrix) { | 62 const SkMatrix& matrix) { |
| 63 SkDEBUGCODE(src.validate();) | 63 SkDEBUGCODE(src.validate();) |
| 64 if (matrix.isIdentity()) { | 64 if (matrix.isIdentity()) { |
| 65 if (*dst != &src) { | 65 if (*dst != &src) { |
| 66 src.ref(); | 66 src.ref(); |
| 67 dst->reset(const_cast<SkPathRef*>(&src)); | 67 dst->reset(const_cast<SkPathRef*>(&src)); |
| 68 SkDEBUGCODE((*dst)->validate();) | 68 SkDEBUGCODE((*dst)->validate();) |
| 69 } | 69 } |
| 70 return; | 70 return; |
| 71 } | 71 } |
| 72 | 72 |
| 73 if (!(*dst)->unique()) { | 73 if (!(*dst)->unique()) { |
| 74 dst->reset(SkNEW(SkPathRef)); | 74 dst->reset(new SkPathRef); |
| 75 } | 75 } |
| 76 | 76 |
| 77 if (*dst != &src) { | 77 if (*dst != &src) { |
| 78 (*dst)->resetToSize(src.fVerbCnt, src.fPointCnt, src.fConicWeights.count
()); | 78 (*dst)->resetToSize(src.fVerbCnt, src.fPointCnt, src.fConicWeights.count
()); |
| 79 memcpy((*dst)->verbsMemWritable(), src.verbsMemBegin(), src.fVerbCnt * s
izeof(uint8_t)); | 79 memcpy((*dst)->verbsMemWritable(), src.verbsMemBegin(), src.fVerbCnt * s
izeof(uint8_t)); |
| 80 (*dst)->fConicWeights = src.fConicWeights; | 80 (*dst)->fConicWeights = src.fConicWeights; |
| 81 } | 81 } |
| 82 | 82 |
| 83 SkASSERT((*dst)->countPoints() == src.countPoints()); | 83 SkASSERT((*dst)->countPoints() == src.countPoints()); |
| 84 SkASSERT((*dst)->countVerbs() == src.countVerbs()); | 84 SkASSERT((*dst)->countVerbs() == src.countVerbs()); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 116 | 116 |
| 117 (*dst)->fSegmentMask = src.fSegmentMask; | 117 (*dst)->fSegmentMask = src.fSegmentMask; |
| 118 | 118 |
| 119 // It's an oval only if it stays a rect. | 119 // It's an oval only if it stays a rect. |
| 120 (*dst)->fIsOval = src.fIsOval && matrix.rectStaysRect(); | 120 (*dst)->fIsOval = src.fIsOval && matrix.rectStaysRect(); |
| 121 | 121 |
| 122 SkDEBUGCODE((*dst)->validate();) | 122 SkDEBUGCODE((*dst)->validate();) |
| 123 } | 123 } |
| 124 | 124 |
| 125 SkPathRef* SkPathRef::CreateFromBuffer(SkRBuffer* buffer) { | 125 SkPathRef* SkPathRef::CreateFromBuffer(SkRBuffer* buffer) { |
| 126 SkPathRef* ref = SkNEW(SkPathRef); | 126 SkPathRef* ref = new SkPathRef; |
| 127 bool isOval; | 127 bool isOval; |
| 128 uint8_t segmentMask; | 128 uint8_t segmentMask; |
| 129 | 129 |
| 130 int32_t packed; | 130 int32_t packed; |
| 131 if (!buffer->readS32(&packed)) { | 131 if (!buffer->readS32(&packed)) { |
| 132 SkDELETE(ref); | 132 delete ref; |
| 133 return NULL; | 133 return NULL; |
| 134 } | 134 } |
| 135 | 135 |
| 136 ref->fIsFinite = (packed >> kIsFinite_SerializationShift) & 1; | 136 ref->fIsFinite = (packed >> kIsFinite_SerializationShift) & 1; |
| 137 segmentMask = (packed >> kSegmentMask_SerializationShift) & 0xF; | 137 segmentMask = (packed >> kSegmentMask_SerializationShift) & 0xF; |
| 138 isOval = (packed >> kIsOval_SerializationShift) & 1; | 138 isOval = (packed >> kIsOval_SerializationShift) & 1; |
| 139 | 139 |
| 140 int32_t verbCount, pointCount, conicCount; | 140 int32_t verbCount, pointCount, conicCount; |
| 141 if (!buffer->readU32(&(ref->fGenerationID)) || | 141 if (!buffer->readU32(&(ref->fGenerationID)) || |
| 142 !buffer->readS32(&verbCount) || | 142 !buffer->readS32(&verbCount) || |
| 143 !buffer->readS32(&pointCount) || | 143 !buffer->readS32(&pointCount) || |
| 144 !buffer->readS32(&conicCount)) { | 144 !buffer->readS32(&conicCount)) { |
| 145 SkDELETE(ref); | 145 delete ref; |
| 146 return NULL; | 146 return NULL; |
| 147 } | 147 } |
| 148 | 148 |
| 149 ref->resetToSize(verbCount, pointCount, conicCount); | 149 ref->resetToSize(verbCount, pointCount, conicCount); |
| 150 SkASSERT(verbCount == ref->countVerbs()); | 150 SkASSERT(verbCount == ref->countVerbs()); |
| 151 SkASSERT(pointCount == ref->countPoints()); | 151 SkASSERT(pointCount == ref->countPoints()); |
| 152 SkASSERT(conicCount == ref->fConicWeights.count()); | 152 SkASSERT(conicCount == ref->fConicWeights.count()); |
| 153 | 153 |
| 154 if (!buffer->read(ref->verbsMemWritable(), verbCount * sizeof(uint8_t)) || | 154 if (!buffer->read(ref->verbsMemWritable(), verbCount * sizeof(uint8_t)) || |
| 155 !buffer->read(ref->fPoints, pointCount * sizeof(SkPoint)) || | 155 !buffer->read(ref->fPoints, pointCount * sizeof(SkPoint)) || |
| 156 !buffer->read(ref->fConicWeights.begin(), conicCount * sizeof(SkScalar))
|| | 156 !buffer->read(ref->fConicWeights.begin(), conicCount * sizeof(SkScalar))
|| |
| 157 !buffer->read(&ref->fBounds, sizeof(SkRect))) { | 157 !buffer->read(&ref->fBounds, sizeof(SkRect))) { |
| 158 SkDELETE(ref); | 158 delete ref; |
| 159 return NULL; | 159 return NULL; |
| 160 } | 160 } |
| 161 ref->fBoundsIsDirty = false; | 161 ref->fBoundsIsDirty = false; |
| 162 | 162 |
| 163 // resetToSize clears fSegmentMask and fIsOval | 163 // resetToSize clears fSegmentMask and fIsOval |
| 164 ref->fSegmentMask = segmentMask; | 164 ref->fSegmentMask = segmentMask; |
| 165 ref->fIsOval = isOval; | 165 ref->fIsOval = isOval; |
| 166 return ref; | 166 return ref; |
| 167 } | 167 } |
| 168 | 168 |
| 169 void SkPathRef::Rewind(SkAutoTUnref<SkPathRef>* pathRef) { | 169 void SkPathRef::Rewind(SkAutoTUnref<SkPathRef>* pathRef) { |
| 170 if ((*pathRef)->unique()) { | 170 if ((*pathRef)->unique()) { |
| 171 SkDEBUGCODE((*pathRef)->validate();) | 171 SkDEBUGCODE((*pathRef)->validate();) |
| 172 (*pathRef)->callGenIDChangeListeners(); | 172 (*pathRef)->callGenIDChangeListeners(); |
| 173 (*pathRef)->fBoundsIsDirty = true; // this also invalidates fIsFinite | 173 (*pathRef)->fBoundsIsDirty = true; // this also invalidates fIsFinite |
| 174 (*pathRef)->fVerbCnt = 0; | 174 (*pathRef)->fVerbCnt = 0; |
| 175 (*pathRef)->fPointCnt = 0; | 175 (*pathRef)->fPointCnt = 0; |
| 176 (*pathRef)->fFreeSpace = (*pathRef)->currSize(); | 176 (*pathRef)->fFreeSpace = (*pathRef)->currSize(); |
| 177 (*pathRef)->fGenerationID = 0; | 177 (*pathRef)->fGenerationID = 0; |
| 178 (*pathRef)->fConicWeights.rewind(); | 178 (*pathRef)->fConicWeights.rewind(); |
| 179 (*pathRef)->fSegmentMask = 0; | 179 (*pathRef)->fSegmentMask = 0; |
| 180 (*pathRef)->fIsOval = false; | 180 (*pathRef)->fIsOval = false; |
| 181 SkDEBUGCODE((*pathRef)->validate();) | 181 SkDEBUGCODE((*pathRef)->validate();) |
| 182 } else { | 182 } else { |
| 183 int oldVCnt = (*pathRef)->countVerbs(); | 183 int oldVCnt = (*pathRef)->countVerbs(); |
| 184 int oldPCnt = (*pathRef)->countPoints(); | 184 int oldPCnt = (*pathRef)->countPoints(); |
| 185 pathRef->reset(SkNEW(SkPathRef)); | 185 pathRef->reset(new SkPathRef); |
| 186 (*pathRef)->resetToSize(0, 0, 0, oldVCnt, oldPCnt); | 186 (*pathRef)->resetToSize(0, 0, 0, oldVCnt, oldPCnt); |
| 187 } | 187 } |
| 188 } | 188 } |
| 189 | 189 |
| 190 bool SkPathRef::operator== (const SkPathRef& ref) const { | 190 bool SkPathRef::operator== (const SkPathRef& ref) const { |
| 191 SkDEBUGCODE(this->validate();) | 191 SkDEBUGCODE(this->validate();) |
| 192 SkDEBUGCODE(ref.validate();) | 192 SkDEBUGCODE(ref.validate();) |
| 193 | 193 |
| 194 // We explicitly check fSegmentMask as a quick-reject. We could skip it, | 194 // We explicitly check fSegmentMask as a quick-reject. We could skip it, |
| 195 // since it is only a cache of info in the fVerbs, but its a fast way to | 195 // since it is only a cache of info in the fVerbs, but its a fast way to |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 437 do { | 437 do { |
| 438 fGenerationID = (sk_atomic_inc(&gPathRefGenerationID) + 1) & kMa
sk; | 438 fGenerationID = (sk_atomic_inc(&gPathRefGenerationID) + 1) & kMa
sk; |
| 439 } while (fGenerationID <= kEmptyGenID); | 439 } while (fGenerationID <= kEmptyGenID); |
| 440 } | 440 } |
| 441 } | 441 } |
| 442 return fGenerationID; | 442 return fGenerationID; |
| 443 } | 443 } |
| 444 | 444 |
| 445 void SkPathRef::addGenIDChangeListener(GenIDChangeListener* listener) { | 445 void SkPathRef::addGenIDChangeListener(GenIDChangeListener* listener) { |
| 446 if (NULL == listener || this == empty.get()) { | 446 if (NULL == listener || this == empty.get()) { |
| 447 SkDELETE(listener); | 447 delete listener; |
| 448 return; | 448 return; |
| 449 } | 449 } |
| 450 *fGenIDChangeListeners.append() = listener; | 450 *fGenIDChangeListeners.append() = listener; |
| 451 } | 451 } |
| 452 | 452 |
| 453 // we need to be called *before* the genID gets changed or zerod | 453 // we need to be called *before* the genID gets changed or zerod |
| 454 void SkPathRef::callGenIDChangeListeners() { | 454 void SkPathRef::callGenIDChangeListeners() { |
| 455 for (int i = 0; i < fGenIDChangeListeners.count(); i++) { | 455 for (int i = 0; i < fGenIDChangeListeners.count(); i++) { |
| 456 fGenIDChangeListeners[i]->onChange(); | 456 fGenIDChangeListeners[i]->onChange(); |
| 457 } | 457 } |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 526 break; | 526 break; |
| 527 default: | 527 default: |
| 528 SkDEBUGFAIL("Unknown Verb"); | 528 SkDEBUGFAIL("Unknown Verb"); |
| 529 break; | 529 break; |
| 530 } | 530 } |
| 531 } | 531 } |
| 532 SkASSERT(mask == fSegmentMask); | 532 SkASSERT(mask == fSegmentMask); |
| 533 #endif // SK_DEBUG_PATH | 533 #endif // SK_DEBUG_PATH |
| 534 } | 534 } |
| 535 #endif | 535 #endif |
| OLD | NEW |