OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 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 "SkMatrixClipStateMgr.h" | 8 #include "SkMatrixClipStateMgr.h" |
9 #include "SkPictureRecord.h" | 9 #include "SkPictureRecord.h" |
10 | 10 |
11 bool SkMatrixClipStateMgr::MatrixClipState::ClipInfo::clipPath(SkPictureRecord*
picRecord, | 11 bool SkMatrixClipStateMgr::MatrixClipState::ClipInfo::clipPath(SkPictureRecord*
picRecord, |
12 const SkPath& pat
h, | 12 const SkPath& pat
h, |
13 SkRegion::Op op, | 13 SkRegion::Op op, |
14 bool doAA, | 14 bool doAA, |
15 int matrixID) { | 15 int matrixID) { |
16 int pathID = picRecord->addPathToHeap(path); | 16 int pathID = picRecord->addPathToHeap(path); |
17 | 17 |
18 ClipOp* newClip = fClips.append(); | 18 ClipOp* newClip = fClips.append(); |
19 newClip->fClipType = kPath_ClipType; | 19 newClip->fClipType = kPath_ClipType; |
20 newClip->fGeom.fPathID = pathID; | 20 newClip->fGeom.fPathID = pathID; |
21 newClip->fOp = op; | 21 newClip->fOp = op; |
22 newClip->fDoAA = doAA; | 22 newClip->fDoAA = doAA; |
23 newClip->fMatrixID = matrixID; | 23 newClip->fMatrixID = matrixID; |
| 24 newClip->fOffset = kInvalidJumpOffset; |
24 return false; | 25 return false; |
25 } | 26 } |
26 | 27 |
27 bool SkMatrixClipStateMgr::MatrixClipState::ClipInfo::clipRegion(SkPictureRecord
* picRecord, | 28 bool SkMatrixClipStateMgr::MatrixClipState::ClipInfo::clipRegion(SkPictureRecord
* picRecord, |
28 int regionID, | 29 int regionID, |
29 SkRegion::Op op
, | 30 SkRegion::Op op
, |
30 int matrixID) { | 31 int matrixID) { |
31 // TODO: add a region dictionary so we don't have to copy the region in here | 32 // TODO: add a region dictionary so we don't have to copy the region in here |
32 ClipOp* newClip = fClips.append(); | 33 ClipOp* newClip = fClips.append(); |
33 newClip->fClipType = kRegion_ClipType; | 34 newClip->fClipType = kRegion_ClipType; |
34 newClip->fGeom.fRegionID = regionID; | 35 newClip->fGeom.fRegionID = regionID; |
35 newClip->fOp = op; | 36 newClip->fOp = op; |
36 newClip->fDoAA = true; // not necessary but sanity preserving | 37 newClip->fDoAA = true; // not necessary but sanity preserving |
37 newClip->fMatrixID = matrixID; | 38 newClip->fMatrixID = matrixID; |
| 39 newClip->fOffset = kInvalidJumpOffset; |
38 return false; | 40 return false; |
39 } | 41 } |
40 | 42 |
41 void SkMatrixClipStateMgr::writeDeltaMat(int currentMatID, int desiredMatID) { | 43 void SkMatrixClipStateMgr::writeDeltaMat(int currentMatID, int desiredMatID) { |
42 const SkMatrix& current = this->lookupMat(currentMatID); | 44 const SkMatrix& current = this->lookupMat(currentMatID); |
43 const SkMatrix& desired = this->lookupMat(desiredMatID); | 45 const SkMatrix& desired = this->lookupMat(desiredMatID); |
44 | 46 |
45 SkMatrix delta; | 47 SkMatrix delta; |
46 bool result = current.invert(&delta); | 48 bool result = current.invert(&delta); |
47 if (result) { | 49 if (result) { |
48 delta.preConcat(desired); | 50 delta.preConcat(desired); |
49 } | 51 } |
50 fPicRecord->recordConcat(delta); | 52 fPicRecord->recordConcat(delta); |
51 } | 53 } |
52 | 54 |
53 // Note: this only writes out the clips for the current save state. To get the | 55 // Note: this only writes out the clips for the current save state. To get the |
54 // entire clip stack requires iterating of the entire matrix/clip stack. | 56 // entire clip stack requires iterating of the entire matrix/clip stack. |
55 void SkMatrixClipStateMgr::MatrixClipState::ClipInfo::writeClip(int* curMatID, | 57 void SkMatrixClipStateMgr::MatrixClipState::ClipInfo::writeClip(int* curMatID, |
56 SkMatrixClipStat
eMgr* mgr) { | 58 SkMatrixClipStat
eMgr* mgr, |
| 59 bool* overrideFi
rstOp) { |
57 for (int i = 0; i < fClips.count(); ++i) { | 60 for (int i = 0; i < fClips.count(); ++i) { |
58 ClipOp& curClip = fClips[i]; | 61 ClipOp& curClip = fClips[i]; |
59 | 62 |
| 63 SkRegion::Op op = curClip.fOp; |
| 64 if (*overrideFirstOp) { |
| 65 op = SkRegion::kReplace_Op; |
| 66 *overrideFirstOp = false; |
| 67 } |
| 68 |
60 // TODO: use the matrix ID to skip writing the identity matrix | 69 // TODO: use the matrix ID to skip writing the identity matrix |
61 // over and over, i.e.: | 70 // over and over, i.e.: |
62 // if (*curMatID != curClip.fMatrixID) { | 71 // if (*curMatID != curClip.fMatrixID) { |
63 // mgr->writeDeltaMat... | 72 // mgr->writeDeltaMat... |
64 // *curMatID... | 73 // *curMatID... |
65 // } | 74 // } |
66 // Right now this optimization would throw off the testing harness. | 75 // Right now this optimization would throw off the testing harness. |
67 // TODO: right now we're writing out the delta matrix from the prior | 76 // TODO: right now we're writing out the delta matrix from the prior |
68 // matrix state. This is a side-effect of writing out the entire | 77 // matrix state. This is a side-effect of writing out the entire |
69 // clip stack and should be resolved when that is fixed. | 78 // clip stack and should be resolved when that is fixed. |
70 mgr->writeDeltaMat(*curMatID, curClip.fMatrixID); | 79 mgr->writeDeltaMat(*curMatID, curClip.fMatrixID); |
71 *curMatID = curClip.fMatrixID; | 80 *curMatID = curClip.fMatrixID; |
72 | 81 |
73 int offset; | |
74 | |
75 switch (curClip.fClipType) { | 82 switch (curClip.fClipType) { |
76 case kRect_ClipType: | 83 case kRect_ClipType: |
77 offset = mgr->getPicRecord()->recordClipRect(curClip.fGeom.fRRect.re
ct(), | 84 curClip.fOffset = mgr->getPicRecord()->recordClipRect(curClip.fGeom.
fRRect.rect(), |
78 curClip.fOp, curClip.fD
oAA); | 85 op, curClip.fD
oAA); |
79 break; | 86 break; |
80 case kRRect_ClipType: | 87 case kRRect_ClipType: |
81 offset = mgr->getPicRecord()->recordClipRRect(curClip.fGeom.fRRect,
curClip.fOp, | 88 curClip.fOffset = mgr->getPicRecord()->recordClipRRect(curClip.fGeom
.fRRect, op, |
82 curClip.fDoAA); | 89 curClip.fDoAA
); |
83 break; | 90 break; |
84 case kPath_ClipType: | 91 case kPath_ClipType: |
85 offset = mgr->getPicRecord()->recordClipPath(curClip.fGeom.fPathID,
curClip.fOp, | 92 curClip.fOffset = mgr->getPicRecord()->recordClipPath(curClip.fGeom.
fPathID, op, |
86 curClip.fDoAA); | 93 curClip.fDoAA)
; |
87 break; | 94 break; |
88 case kRegion_ClipType: { | 95 case kRegion_ClipType: { |
89 const SkRegion* region = mgr->lookupRegion(curClip.fGeom.fRegionID); | 96 const SkRegion* region = mgr->lookupRegion(curClip.fGeom.fRegionID); |
90 offset = mgr->getPicRecord()->recordClipRegion(*region, curClip.fOp)
; | 97 curClip.fOffset = mgr->getPicRecord()->recordClipRegion(*region, op)
; |
91 break; | 98 break; |
92 } | 99 } |
93 default: | 100 default: |
94 SkASSERT(0); | 101 SkASSERT(0); |
95 } | 102 } |
96 | |
97 mgr->addClipOffset(offset); | |
98 } | 103 } |
99 } | 104 } |
100 | 105 |
| 106 // Fill in the skip offsets for all the clips written in the current block |
| 107 void SkMatrixClipStateMgr::MatrixClipState::ClipInfo::fillInSkips(SkWriter32* wr
iter, |
| 108 int32_t restor
eOffset) { |
| 109 for (int i = 0; i < fClips.count(); ++i) { |
| 110 ClipOp& curClip = fClips[i]; |
| 111 |
| 112 if (-1 == curClip.fOffset) { |
| 113 continue; |
| 114 } |
| 115 // SkDEBUGCODE(uint32_t peek = writer->read32At(curClip.fOffset);) |
| 116 // SkASSERT(-1 == peek); |
| 117 writer->overwriteTAt(curClip.fOffset, restoreOffset); |
| 118 SkDEBUGCODE(curClip.fOffset = -1;) |
| 119 } |
| 120 } |
| 121 |
101 SkMatrixClipStateMgr::SkMatrixClipStateMgr() | 122 SkMatrixClipStateMgr::SkMatrixClipStateMgr() |
102 : fPicRecord(NULL) | 123 : fPicRecord(NULL) |
103 , fMatrixClipStack(sizeof(MatrixClipState), | 124 , fMatrixClipStack(sizeof(MatrixClipState), |
104 fMatrixClipStackStorage, | 125 fMatrixClipStackStorage, |
105 sizeof(fMatrixClipStackStorage)) | 126 sizeof(fMatrixClipStackStorage)) |
106 , fCurOpenStateID(kIdentityWideOpenStateID) { | 127 , fCurOpenStateID(kIdentityWideOpenStateID) { |
107 | 128 |
108 fSkipOffsets = SkNEW(SkTDArray<int>); | |
109 | |
110 // The first slot in the matrix dictionary is reserved for the identity matr
ix | 129 // The first slot in the matrix dictionary is reserved for the identity matr
ix |
111 fMatrixDict.append()->reset(); | 130 fMatrixDict.append()->reset(); |
112 | 131 |
113 fCurMCState = (MatrixClipState*)fMatrixClipStack.push_back(); | 132 fCurMCState = (MatrixClipState*)fMatrixClipStack.push_back(); |
114 new (fCurMCState) MatrixClipState(NULL, 0); // balanced in restore() | 133 new (fCurMCState) MatrixClipState(NULL, 0); // balanced in restore() |
115 } | 134 } |
116 | 135 |
117 SkMatrixClipStateMgr::~SkMatrixClipStateMgr() { | 136 SkMatrixClipStateMgr::~SkMatrixClipStateMgr() { |
118 for (int i = 0; i < fRegionDict.count(); ++i) { | 137 for (int i = 0; i < fRegionDict.count(); ++i) { |
119 SkDELETE(fRegionDict[i]); | 138 SkDELETE(fRegionDict[i]); |
120 } | 139 } |
121 | |
122 SkDELETE(fSkipOffsets); | |
123 } | 140 } |
124 | 141 |
125 | 142 |
126 int SkMatrixClipStateMgr::MCStackPush(SkCanvas::SaveFlags flags) { | 143 int SkMatrixClipStateMgr::save(SkCanvas::SaveFlags flags) { |
| 144 SkDEBUGCODE(this->validate();) |
| 145 |
127 MatrixClipState* newTop = (MatrixClipState*)fMatrixClipStack.push_back(); | 146 MatrixClipState* newTop = (MatrixClipState*)fMatrixClipStack.push_back(); |
128 new (newTop) MatrixClipState(fCurMCState, flags); // balanced in restore() | 147 new (newTop) MatrixClipState(fCurMCState, flags); // balanced in restore() |
129 fCurMCState = newTop; | 148 fCurMCState = newTop; |
130 | 149 |
131 SkDEBUGCODE(this->validate();) | 150 SkDEBUGCODE(this->validate();) |
132 | 151 |
133 return fMatrixClipStack.count(); | 152 return fMatrixClipStack.count(); |
134 } | 153 } |
135 | 154 |
136 int SkMatrixClipStateMgr::save(SkCanvas::SaveFlags flags) { | |
137 SkDEBUGCODE(this->validate();) | |
138 | |
139 return this->MCStackPush(flags); | |
140 } | |
141 | |
142 int SkMatrixClipStateMgr::saveLayer(const SkRect* bounds, const SkPaint* paint, | 155 int SkMatrixClipStateMgr::saveLayer(const SkRect* bounds, const SkPaint* paint, |
143 SkCanvas::SaveFlags flags) { | 156 SkCanvas::SaveFlags flags) { |
144 // Since the saveLayer call draws something we need to potentially dump | 157 int result = this->save(flags); |
145 // out the MC state | |
146 this->call(kOther_CallType); | |
147 | |
148 int result = this->MCStackPush(flags); | |
149 ++fCurMCState->fLayerID; | 158 ++fCurMCState->fLayerID; |
150 fCurMCState->fIsSaveLayer = true; | 159 fCurMCState->fIsSaveLayer = true; |
151 | 160 |
| 161 fCurMCState->fSaveLayerBracketed = this->call(kOther_CallType); |
152 fCurMCState->fSaveLayerBaseStateID = fCurOpenStateID; | 162 fCurMCState->fSaveLayerBaseStateID = fCurOpenStateID; |
153 fCurMCState->fSavedSkipOffsets = fSkipOffsets; | |
154 | |
155 // TODO: recycle these rather then new & deleting them on every saveLayer/ | |
156 // restore | |
157 fSkipOffsets = SkNEW(SkTDArray<int>); | |
158 | |
159 fPicRecord->recordSaveLayer(bounds, paint, | 163 fPicRecord->recordSaveLayer(bounds, paint, |
160 (SkCanvas::SaveFlags)(flags| SkCanvas::kMatrixCl
ip_SaveFlag)); | 164 (SkCanvas::SaveFlags)(flags| SkCanvas::kMatrixCl
ip_SaveFlag)); |
161 return result; | 165 return result; |
162 } | 166 } |
163 | 167 |
164 void SkMatrixClipStateMgr::restore() { | 168 void SkMatrixClipStateMgr::restore() { |
165 SkDEBUGCODE(this->validate();) | 169 SkDEBUGCODE(this->validate();) |
166 | 170 |
167 if (fCurMCState->fIsSaveLayer) { | 171 if (fCurMCState->fIsSaveLayer) { |
168 if (fCurMCState->fSaveLayerBaseStateID != fCurOpenStateID) { | 172 if (fCurMCState->fSaveLayerBaseStateID != fCurOpenStateID) { |
169 fPicRecord->recordRestore(); // Close the open block inside the save
Layer | 173 fPicRecord->recordRestore(); // Close the open block |
170 } | 174 } |
171 // The saveLayer's don't carry any matrix or clip state in the | 175 // The saveLayer's don't carry any matrix or clip state in the |
172 // new scheme so make sure the saveLayer's recordRestore doesn't | 176 // new scheme so make sure the saveLayer's recordRestore doesn't |
173 // try to finalize them (i.e., fill in their skip offsets). | 177 // try to finalize them (i.e., fill in their skip offsets). |
174 fPicRecord->recordRestore(false); // close of saveLayer | 178 fPicRecord->recordRestore(false); // close of saveLayer |
175 | 179 |
176 fCurOpenStateID = fCurMCState->fSaveLayerBaseStateID; | 180 // Close the Save that brackets the saveLayer. TODO: this doesn't handle |
| 181 // the skip offsets correctly |
| 182 if (fCurMCState->fSaveLayerBracketed) { |
| 183 fPicRecord->recordRestore(false); |
| 184 } |
177 | 185 |
178 SkASSERT(0 == fSkipOffsets->count()); | 186 // MC states can be allowed to fuse across saveLayer/restore boundaries |
179 SkASSERT(NULL != fCurMCState->fSavedSkipOffsets); | 187 fCurOpenStateID = kIdentityWideOpenStateID; |
180 | |
181 SkDELETE(fSkipOffsets); | |
182 fSkipOffsets = fCurMCState->fSavedSkipOffsets; | |
183 } | 188 } |
184 | 189 |
185 fCurMCState->~MatrixClipState(); // balanced in save() | 190 fCurMCState->~MatrixClipState(); // balanced in save() |
186 fMatrixClipStack.pop_back(); | 191 fMatrixClipStack.pop_back(); |
187 fCurMCState = (MatrixClipState*)fMatrixClipStack.back(); | 192 fCurMCState = (MatrixClipState*)fMatrixClipStack.back(); |
188 | 193 |
189 SkDEBUGCODE(this->validate();) | 194 SkDEBUGCODE(this->validate();) |
190 } | 195 } |
191 | 196 |
192 // kIdentityWideOpenStateID (0) is reserved for the identity/wide-open clip stat
e | 197 // kIdentityWideOpenStateID (0) is reserved for the identity/wide-open clip stat
e |
(...skipping 15 matching lines...) Expand all Loading... |
208 } | 213 } |
209 | 214 |
210 SkASSERT(kOther_CallType == callType); | 215 SkASSERT(kOther_CallType == callType); |
211 | 216 |
212 if (fCurMCState->fMCStateID == fCurOpenStateID) { | 217 if (fCurMCState->fMCStateID == fCurOpenStateID) { |
213 // Required MC state is already active one - nothing to do | 218 // Required MC state is already active one - nothing to do |
214 SkDEBUGCODE(this->validate();) | 219 SkDEBUGCODE(this->validate();) |
215 return false; | 220 return false; |
216 } | 221 } |
217 | 222 |
218 if (kIdentityWideOpenStateID != fCurOpenStateID && | 223 if (kIdentityWideOpenStateID != fCurOpenStateID) { |
219 (!fCurMCState->fIsSaveLayer || | |
220 fCurMCState->fSaveLayerBaseStateID != fCurOpenStateID)) { | |
221 // Don't write a restore if the open state is one in which a saveLayer | |
222 // is nested. The save after the saveLayer's restore will close it. | |
223 fPicRecord->recordRestore(); // Close the open block | 224 fPicRecord->recordRestore(); // Close the open block |
224 } | 225 } |
225 | 226 |
226 // Install the required MC state as the active one | 227 // Install the required MC state as the active one |
227 fCurOpenStateID = fCurMCState->fMCStateID; | 228 fCurOpenStateID = fCurMCState->fMCStateID; |
228 | 229 |
229 fPicRecord->recordSave(SkCanvas::kMatrixClip_SaveFlag); | 230 fPicRecord->recordSave(SkCanvas::kMatrixClip_SaveFlag); |
230 | 231 |
231 // write out clips | 232 // write out clips |
232 SkDeque::Iter iter(fMatrixClipStack, SkDeque::Iter::kBack_IterStart); | 233 SkDeque::F2BIter iter(fMatrixClipStack); |
233 const MatrixClipState* state; | 234 bool firstClip = true; |
234 // Loop back across the MC states until the last saveLayer. The MC | 235 |
235 // state in front of the saveLayer has already been written out. | 236 int curMatID = kIdentityMatID; |
236 for (state = (const MatrixClipState*) iter.prev(); | 237 for (const MatrixClipState* state = (const MatrixClipState*) iter.next(); |
237 state != NULL; | 238 state != NULL; |
238 state = (const MatrixClipState*) iter.prev()) { | 239 state = (const MatrixClipState*) iter.next()) { |
239 if (state->fIsSaveLayer) { | 240 state->fClipInfo->writeClip(&curMatID, this, &firstClip); |
240 break; | |
241 } | |
242 } | |
243 | |
244 if (NULL == state) { | |
245 // There was no saveLayer in the MC stack so we need to output them all | |
246 iter.reset(fMatrixClipStack, SkDeque::Iter::kFront_IterStart); | |
247 state = (const MatrixClipState*) iter.next(); | |
248 } else { | |
249 // SkDeque's iterators actually return the previous location so we | |
250 // need to reverse and go forward one to get back on track. | |
251 iter.next(); | |
252 SkDEBUGCODE(const MatrixClipState* test =) (const MatrixClipState*) iter
.next(); | |
253 SkASSERT(test == state); | |
254 } | |
255 | |
256 int curMatID = NULL != state ? state->fMatrixInfo->getID(this) : kIdentityMa
tID; | |
257 for ( ; state != NULL; state = (const MatrixClipState*) iter.next()) { | |
258 state->fClipInfo->writeClip(&curMatID, this); | |
259 } | 241 } |
260 | 242 |
261 // write out matrix | 243 // write out matrix |
262 // TODO: this test isn't quite right. It should be: | |
263 // if (curMatID != fCurMCState->fMatrixInfo->getID(this)) { | |
264 // but right now the testing harness always expects a matrix if | |
265 // the matrices are non-I | |
266 if (kIdentityMatID != fCurMCState->fMatrixInfo->getID(this)) { | 244 if (kIdentityMatID != fCurMCState->fMatrixInfo->getID(this)) { |
267 // TODO: writing out the delta matrix here is an artifact of the writing | 245 // TODO: writing out the delta matrix here is an artifact of the writing |
268 // out of the entire clip stack (with its matrices). Ultimately we will | 246 // out of the entire clip stack (with its matrices). Ultimately we will |
269 // write out the CTM here when the clip state is collapsed to a single p
ath. | 247 // write out the CTM here when the clip state is collapsed to a single p
ath. |
270 this->writeDeltaMat(curMatID, fCurMCState->fMatrixInfo->getID(this)); | 248 this->writeDeltaMat(curMatID, fCurMCState->fMatrixInfo->getID(this)); |
271 } | 249 } |
272 | 250 |
273 SkDEBUGCODE(this->validate();) | 251 SkDEBUGCODE(this->validate();) |
274 | 252 |
275 return true; | 253 return true; |
276 } | 254 } |
277 | 255 |
278 // Fill in the skip offsets for all the clips written in the current block | |
279 void SkMatrixClipStateMgr::fillInSkips(SkWriter32* writer, int32_t restoreOffset
) { | |
280 for (int i = 0; i < fSkipOffsets->count(); ++i) { | |
281 SkDEBUGCODE(uint32_t peek = writer->readTAt<int32_t>((*fSkipOffsets)[i])
;) | |
282 // SkASSERT(-1 == peek); | |
283 writer->overwriteTAt<int32_t>((*fSkipOffsets)[i], restoreOffset); | |
284 } | |
285 | |
286 fSkipOffsets->rewind(); | |
287 } | |
288 | |
289 void SkMatrixClipStateMgr::finish() { | 256 void SkMatrixClipStateMgr::finish() { |
290 if (kIdentityWideOpenStateID != fCurOpenStateID) { | 257 if (kIdentityWideOpenStateID != fCurOpenStateID) { |
291 fPicRecord->recordRestore(); // Close the open block | 258 fPicRecord->recordRestore(); // Close the open block |
292 fCurOpenStateID = kIdentityWideOpenStateID; | 259 fCurOpenStateID = kIdentityWideOpenStateID; |
293 } | 260 } |
294 } | 261 } |
295 | 262 |
296 #ifdef SK_DEBUG | 263 #ifdef SK_DEBUG |
297 void SkMatrixClipStateMgr::validate() { | 264 void SkMatrixClipStateMgr::validate() { |
298 if (fCurOpenStateID == fCurMCState->fMCStateID && | 265 if (fCurOpenStateID == fCurMCState->fMCStateID) { |
299 (!fCurMCState->fIsSaveLayer || | 266 // The current state is the active one so all its skip offsets should |
300 fCurOpenStateID != fCurMCState->fSaveLayerBaseStateID)) { | 267 // still be -1 |
301 // The current state is the active one so it should have a skip | 268 SkDeque::F2BIter iter(fMatrixClipStack); |
302 // offset for each clip | 269 |
303 SkDeque::Iter iter(fMatrixClipStack, SkDeque::Iter::kBack_IterStart); | 270 for (const MatrixClipState* state = (const MatrixClipState*) iter.next()
; |
304 int clipCount = 0; | |
305 for (const MatrixClipState* state = (const MatrixClipState*) iter.prev()
; | |
306 state != NULL; | 271 state != NULL; |
307 state = (const MatrixClipState*) iter.prev()) { | 272 state = (const MatrixClipState*) iter.next()) { |
308 clipCount += state->fClipInfo->numClips(); | 273 state->fClipInfo->checkOffsetNotEqual(-1); |
309 if (state->fIsSaveLayer) { | |
310 break; | |
311 } | |
312 } | 274 } |
313 | |
314 SkASSERT(fSkipOffsets->count() == clipCount); | |
315 } | 275 } |
316 } | 276 } |
317 #endif | 277 #endif |
318 | 278 |
319 int SkMatrixClipStateMgr::addRegionToDict(const SkRegion& region) { | 279 int SkMatrixClipStateMgr::addRegionToDict(const SkRegion& region) { |
320 int index = fRegionDict.count(); | 280 int index = fRegionDict.count(); |
321 *fRegionDict.append() = SkNEW(SkRegion(region)); | 281 *fRegionDict.append() = SkNEW(SkRegion(region)); |
322 return index; | 282 return index; |
323 } | 283 } |
324 | 284 |
325 int SkMatrixClipStateMgr::addMatToDict(const SkMatrix& mat) { | 285 int SkMatrixClipStateMgr::addMatToDict(const SkMatrix& mat) { |
326 if (mat.isIdentity()) { | 286 if (mat.isIdentity()) { |
327 return kIdentityMatID; | 287 return kIdentityMatID; |
328 } | 288 } |
329 | 289 |
330 *fMatrixDict.append() = mat; | 290 *fMatrixDict.append() = mat; |
331 return fMatrixDict.count()-1; | 291 return fMatrixDict.count()-1; |
332 } | 292 } |
OLD | NEW |