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 |
(...skipping 10 matching lines...) Expand all Loading... |
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 return false; | 24 return false; |
25 } | 25 } |
26 | 26 |
27 bool SkMatrixClipStateMgr::MatrixClipState::ClipInfo::clipRegion(SkPictureRecord
* picRecord, | 27 bool SkMatrixClipStateMgr::MatrixClipState::ClipInfo::clipRegion(SkPictureRecord
* picRecord, |
28 int regionID, | 28 int regionID, |
29 SkRegion::Op op
, | 29 SkRegion::Op op
, |
30 int matrixID) { | 30 int matrixID) { |
31 // TODO: add a region dictionary so we don't have to copy the region in here | |
32 ClipOp* newClip = fClips.append(); | 31 ClipOp* newClip = fClips.append(); |
33 newClip->fClipType = kRegion_ClipType; | 32 newClip->fClipType = kRegion_ClipType; |
34 newClip->fGeom.fRegionID = regionID; | 33 newClip->fGeom.fRegionID = regionID; |
35 newClip->fOp = op; | 34 newClip->fOp = op; |
36 newClip->fDoAA = true; // not necessary but sanity preserving | 35 newClip->fDoAA = true; // not necessary but sanity preserving |
37 newClip->fMatrixID = matrixID; | 36 newClip->fMatrixID = matrixID; |
38 return false; | 37 return false; |
39 } | 38 } |
40 | 39 |
41 void SkMatrixClipStateMgr::writeDeltaMat(int currentMatID, int desiredMatID) { | 40 void SkMatrixClipStateMgr::writeDeltaMat(int currentMatID, int desiredMatID) { |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 ++fCurMCState->fLayerID; | 158 ++fCurMCState->fLayerID; |
160 fCurMCState->fIsSaveLayer = true; | 159 fCurMCState->fIsSaveLayer = true; |
161 | 160 |
162 #ifdef SK_DEBUG | 161 #ifdef SK_DEBUG |
163 if (saved) { | 162 if (saved) { |
164 fCurMCState->fExpectedDepth++; // 1 for nesting save | 163 fCurMCState->fExpectedDepth++; // 1 for nesting save |
165 } | 164 } |
166 fCurMCState->fExpectedDepth++; // 1 for saveLayer | 165 fCurMCState->fExpectedDepth++; // 1 for saveLayer |
167 #endif | 166 #endif |
168 | 167 |
169 fCurMCState->fSaveLayerBaseStateID = fCurOpenStateID; | 168 *fStateIDStack.append() = fCurOpenStateID; |
170 fCurMCState->fSavedSkipOffsets = fSkipOffsets; | 169 fCurMCState->fSavedSkipOffsets = fSkipOffsets; |
171 | 170 |
172 // TODO: recycle these rather then new & deleting them on every saveLayer/ | 171 // TODO: recycle these rather then new & deleting them on every saveLayer/ |
173 // restore | 172 // restore |
174 fSkipOffsets = SkNEW(SkTDArray<int>); | 173 fSkipOffsets = SkNEW(SkTDArray<int>); |
175 | 174 |
176 fPicRecord->recordSaveLayer(bounds, paint, | 175 fPicRecord->recordSaveLayer(bounds, paint, |
177 (SkCanvas::SaveFlags)(flags| SkCanvas::kMatrixCl
ip_SaveFlag)); | 176 (SkCanvas::SaveFlags)(flags| SkCanvas::kMatrixCl
ip_SaveFlag)); |
178 #ifdef SK_DEBUG | 177 #ifdef SK_DEBUG |
179 fActualDepth++; | 178 fActualDepth++; |
(...skipping 18 matching lines...) Expand all Loading... |
198 | 197 |
199 // The saveLayer's don't carry any matrix or clip state in the | 198 // The saveLayer's don't carry any matrix or clip state in the |
200 // new scheme so make sure the saveLayer's recordRestore doesn't | 199 // new scheme so make sure the saveLayer's recordRestore doesn't |
201 // try to finalize them (i.e., fill in their skip offsets). | 200 // try to finalize them (i.e., fill in their skip offsets). |
202 fPicRecord->recordRestore(false); // close of saveLayer | 201 fPicRecord->recordRestore(false); // close of saveLayer |
203 #ifdef SK_DEBUG | 202 #ifdef SK_DEBUG |
204 SkASSERT(fActualDepth > 0); | 203 SkASSERT(fActualDepth > 0); |
205 fActualDepth--; | 204 fActualDepth--; |
206 #endif | 205 #endif |
207 | 206 |
208 fCurOpenStateID = fCurMCState->fSaveLayerBaseStateID; | 207 SkASSERT(fStateIDStack.count() >= 1); |
| 208 fCurOpenStateID = fStateIDStack[fStateIDStack.count()-1]; |
| 209 fStateIDStack.pop(); |
209 | 210 |
210 SkASSERT(0 == fSkipOffsets->count()); | 211 SkASSERT(0 == fSkipOffsets->count()); |
211 SkASSERT(NULL != fCurMCState->fSavedSkipOffsets); | 212 SkASSERT(NULL != fCurMCState->fSavedSkipOffsets); |
212 | 213 |
213 SkDELETE(fSkipOffsets); | 214 SkDELETE(fSkipOffsets); |
214 fSkipOffsets = fCurMCState->fSavedSkipOffsets; | 215 fSkipOffsets = fCurMCState->fSavedSkipOffsets; |
215 } | 216 } |
216 | 217 |
217 bool prevHadOpen = fCurMCState->fHasOpen; | 218 bool prevHadOpen = fCurMCState->fHasOpen; |
218 bool prevWasSaveLayer = fCurMCState->fIsSaveLayer; | 219 bool prevWasSaveLayer = fCurMCState->fIsSaveLayer; |
(...skipping 17 matching lines...) Expand all Loading... |
236 | 237 |
237 // kIdentityWideOpenStateID (0) is reserved for the identity/wide-open clip stat
e | 238 // kIdentityWideOpenStateID (0) is reserved for the identity/wide-open clip stat
e |
238 int32_t SkMatrixClipStateMgr::NewMCStateID() { | 239 int32_t SkMatrixClipStateMgr::NewMCStateID() { |
239 // TODO: guard against wrap around | 240 // TODO: guard against wrap around |
240 // TODO: make uint32_t | 241 // TODO: make uint32_t |
241 static int32_t gMCStateID = kIdentityWideOpenStateID; | 242 static int32_t gMCStateID = kIdentityWideOpenStateID; |
242 ++gMCStateID; | 243 ++gMCStateID; |
243 return gMCStateID; | 244 return gMCStateID; |
244 } | 245 } |
245 | 246 |
246 bool SkMatrixClipStateMgr::isCurrentlyOpen(int32_t stateID) { | 247 bool SkMatrixClipStateMgr::isNestingMCState(int stateID) { |
247 if (fCurMCState->fIsSaveLayer) | 248 return fStateIDStack.count() > 0 && fStateIDStack[fStateIDStack.count()-1] =
= fCurOpenStateID; |
248 return false; | |
249 | |
250 SkDeque::Iter iter(fMatrixClipStack, SkDeque::Iter::kBack_IterStart); | |
251 | |
252 for (const MatrixClipState* state = (const MatrixClipState*) iter.prev(); | |
253 state != NULL; | |
254 state = (const MatrixClipState*) iter.prev()) { | |
255 if (state->fIsSaveLayer) { | |
256 if (state->fSaveLayerBaseStateID == stateID) { | |
257 return true; | |
258 } | |
259 } | |
260 } | |
261 | |
262 return false; | |
263 } | 249 } |
264 | 250 |
265 bool SkMatrixClipStateMgr::call(CallType callType) { | 251 bool SkMatrixClipStateMgr::call(CallType callType) { |
266 SkDEBUGCODE(this->validate();) | 252 SkDEBUGCODE(this->validate();) |
267 | 253 |
268 if (kMatrix_CallType == callType || kClip_CallType == callType) { | 254 if (kMatrix_CallType == callType || kClip_CallType == callType) { |
269 fCurMCState->fMCStateID = NewMCStateID(); | 255 fCurMCState->fMCStateID = NewMCStateID(); |
270 SkDEBUGCODE(this->validate();) | 256 SkDEBUGCODE(this->validate();) |
271 return false; | 257 return false; |
272 } | 258 } |
273 | 259 |
274 SkASSERT(kOther_CallType == callType); | 260 SkASSERT(kOther_CallType == callType); |
275 | 261 |
276 if (fCurMCState->fMCStateID == fCurOpenStateID) { | 262 if (fCurMCState->fMCStateID == fCurOpenStateID) { |
277 // Required MC state is already active one - nothing to do | 263 // Required MC state is already active one - nothing to do |
278 SkDEBUGCODE(this->validate();) | 264 SkDEBUGCODE(this->validate();) |
279 return false; | 265 return false; |
280 } | 266 } |
281 | 267 |
282 if (kIdentityWideOpenStateID != fCurOpenStateID && | 268 if (kIdentityWideOpenStateID != fCurOpenStateID && |
283 !this->isCurrentlyOpen(fCurOpenStateID)) { | 269 !this->isNestingMCState(fCurOpenStateID)) { |
284 // Don't write a restore if the open state is one in which a saveLayer | 270 // Don't write a restore if the open state is one in which a saveLayer |
285 // is nested. The save after the saveLayer's restore will close it. | 271 // is nested. The save after the saveLayer's restore will close it. |
286 fPicRecord->recordRestore(); // Close the open block | 272 fPicRecord->recordRestore(); // Close the open block |
287 fCurMCState->fHasOpen = false; | 273 fCurMCState->fHasOpen = false; |
288 #ifdef SK_DEBUG | 274 #ifdef SK_DEBUG |
289 SkASSERT(fActualDepth > 0); | 275 SkASSERT(fActualDepth > 0); |
290 fActualDepth--; | 276 fActualDepth--; |
291 #endif | 277 #endif |
292 } | 278 } |
293 | 279 |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 SkASSERT(fActualDepth > 0); | 376 SkASSERT(fActualDepth > 0); |
391 fActualDepth--; | 377 fActualDepth--; |
392 #endif | 378 #endif |
393 fCurOpenStateID = kIdentityWideOpenStateID; | 379 fCurOpenStateID = kIdentityWideOpenStateID; |
394 SkASSERT(!fCurMCState->fHasOpen); | 380 SkASSERT(!fCurMCState->fHasOpen); |
395 } | 381 } |
396 } | 382 } |
397 | 383 |
398 #ifdef SK_DEBUG | 384 #ifdef SK_DEBUG |
399 void SkMatrixClipStateMgr::validate() { | 385 void SkMatrixClipStateMgr::validate() { |
400 if (fCurOpenStateID == fCurMCState->fMCStateID && | 386 if (fCurOpenStateID == fCurMCState->fMCStateID && !this->isNestingMCState(fC
urOpenStateID)) { |
401 (!fCurMCState->fIsSaveLayer || | |
402 fCurOpenStateID != fCurMCState->fSaveLayerBaseStateID)) { | |
403 // The current state is the active one so it should have a skip | 387 // The current state is the active one so it should have a skip |
404 // offset for each clip | 388 // offset for each clip |
405 SkDeque::Iter iter(fMatrixClipStack, SkDeque::Iter::kBack_IterStart); | 389 SkDeque::Iter iter(fMatrixClipStack, SkDeque::Iter::kBack_IterStart); |
406 int clipCount = 0; | 390 int clipCount = 0; |
407 for (const MatrixClipState* state = (const MatrixClipState*) iter.prev()
; | 391 for (const MatrixClipState* state = (const MatrixClipState*) iter.prev()
; |
408 state != NULL; | 392 state != NULL; |
409 state = (const MatrixClipState*) iter.prev()) { | 393 state = (const MatrixClipState*) iter.prev()) { |
410 if (NULL == state->fPrev || state->fPrev->fClipInfo != state->fClipI
nfo) { | 394 if (NULL == state->fPrev || state->fPrev->fClipInfo != state->fClipI
nfo) { |
411 clipCount += state->fClipInfo->numClips(); | 395 clipCount += state->fClipInfo->numClips(); |
412 } | 396 } |
(...skipping 14 matching lines...) Expand all Loading... |
427 } | 411 } |
428 | 412 |
429 int SkMatrixClipStateMgr::addMatToDict(const SkMatrix& mat) { | 413 int SkMatrixClipStateMgr::addMatToDict(const SkMatrix& mat) { |
430 if (mat.isIdentity()) { | 414 if (mat.isIdentity()) { |
431 return kIdentityMatID; | 415 return kIdentityMatID; |
432 } | 416 } |
433 | 417 |
434 *fMatrixDict.append() = mat; | 418 *fMatrixDict.append() = mat; |
435 return fMatrixDict.count()-1; | 419 return fMatrixDict.count()-1; |
436 } | 420 } |
OLD | NEW |