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 #ifndef SkMatrixClipStateMgr_DEFINED | 7 #ifndef SkMatrixClipStateMgr_DEFINED |
8 #define SkMatrixClipStateMgr_DEFINED | 8 #define SkMatrixClipStateMgr_DEFINED |
9 | 9 |
10 #include "SkCanvas.h" | 10 #include "SkCanvas.h" |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 bool clipRect(const SkRect& rect, | 113 bool clipRect(const SkRect& rect, |
114 SkRegion::Op op, | 114 SkRegion::Op op, |
115 bool doAA, | 115 bool doAA, |
116 int matrixID) { | 116 int matrixID) { |
117 ClipOp* newClip = fClips.append(); | 117 ClipOp* newClip = fClips.append(); |
118 newClip->fClipType = kRect_ClipType; | 118 newClip->fClipType = kRect_ClipType; |
119 newClip->fGeom.fRRect.setRect(rect); // storing the clipRect i
n the RRect | 119 newClip->fGeom.fRRect.setRect(rect); // storing the clipRect i
n the RRect |
120 newClip->fOp = op; | 120 newClip->fOp = op; |
121 newClip->fDoAA = doAA; | 121 newClip->fDoAA = doAA; |
122 newClip->fMatrixID = matrixID; | 122 newClip->fMatrixID = matrixID; |
123 newClip->fOffset = kInvalidJumpOffset; | |
124 return false; | 123 return false; |
125 } | 124 } |
126 | 125 |
127 bool clipRRect(const SkRRect& rrect, | 126 bool clipRRect(const SkRRect& rrect, |
128 SkRegion::Op op, | 127 SkRegion::Op op, |
129 bool doAA, | 128 bool doAA, |
130 int matrixID) { | 129 int matrixID) { |
131 ClipOp* newClip = fClips.append(); | 130 ClipOp* newClip = fClips.append(); |
132 newClip->fClipType = kRRect_ClipType; | 131 newClip->fClipType = kRRect_ClipType; |
133 newClip->fGeom.fRRect = rrect; | 132 newClip->fGeom.fRRect = rrect; |
134 newClip->fOp = op; | 133 newClip->fOp = op; |
135 newClip->fDoAA = doAA; | 134 newClip->fDoAA = doAA; |
136 newClip->fMatrixID = matrixID; | 135 newClip->fMatrixID = matrixID; |
137 newClip->fOffset = kInvalidJumpOffset; | |
138 return false; | 136 return false; |
139 } | 137 } |
140 | 138 |
141 bool clipPath(SkPictureRecord* picRecord, | 139 bool clipPath(SkPictureRecord* picRecord, |
142 const SkPath& path, | 140 const SkPath& path, |
143 SkRegion::Op op, | 141 SkRegion::Op op, |
144 bool doAA, | 142 bool doAA, |
145 int matrixID); | 143 int matrixID); |
146 bool clipRegion(SkPictureRecord* picRecord, | 144 bool clipRegion(SkPictureRecord* picRecord, |
147 int regionID, | 145 int regionID, |
148 SkRegion::Op op, | 146 SkRegion::Op op, |
149 int matrixID); | 147 int matrixID); |
150 void writeClip(int* curMatID, | 148 void writeClip(int* curMatID, SkMatrixClipStateMgr* mgr); |
151 SkMatrixClipStateMgr* mgr, | |
152 bool* overrideFirstOp); | |
153 void fillInSkips(SkWriter32* writer, int32_t restoreOffset); | |
154 | 149 |
155 #ifdef SK_DEBUG | 150 SkDEBUGCODE(int numClips() const { return fClips.count(); }) |
156 void checkOffsetNotEqual(int32_t offset) { | 151 |
157 for (int i = 0; i < fClips.count(); ++i) { | |
158 ClipOp& curClip = fClips[i]; | |
159 SkASSERT(offset != curClip.fOffset); | |
160 } | |
161 } | |
162 #endif | |
163 private: | 152 private: |
164 enum ClipType { | 153 enum ClipType { |
165 kRect_ClipType, | 154 kRect_ClipType, |
166 kRRect_ClipType, | 155 kRRect_ClipType, |
167 kPath_ClipType, | 156 kPath_ClipType, |
168 kRegion_ClipType | 157 kRegion_ClipType |
169 }; | 158 }; |
170 | 159 |
171 static const int kInvalidJumpOffset = -1; | |
172 | |
173 class ClipOp { | 160 class ClipOp { |
174 public: | 161 public: |
175 ClipType fClipType; | 162 ClipType fClipType; |
176 | 163 |
177 union { | 164 union { |
178 SkRRect fRRect; // also stores clipRect | 165 SkRRect fRRect; // also stores clipRect |
179 int fPathID; | 166 int fPathID; |
180 int fRegionID; | 167 int fRegionID; |
181 } fGeom; | 168 } fGeom; |
182 | 169 |
183 bool fDoAA; | 170 bool fDoAA; |
184 SkRegion::Op fOp; | 171 SkRegion::Op fOp; |
185 | 172 |
186 // The CTM in effect when this clip call was issued | 173 // The CTM in effect when this clip call was issued |
187 int fMatrixID; | 174 int fMatrixID; |
188 | |
189 // The offset of this clipOp's "jump-to-offset" location in the
skp. | |
190 // -1 means the offset hasn't been written. | |
191 int32_t fOffset; | |
192 }; | 175 }; |
193 | 176 |
194 SkTDArray<ClipOp> fClips; | 177 SkTDArray<ClipOp> fClips; |
195 | 178 |
196 typedef SkNoncopyable INHERITED; | 179 typedef SkNoncopyable INHERITED; |
197 }; | 180 }; |
198 | 181 |
199 MatrixClipState(MatrixClipState* prev, int flags) | 182 MatrixClipState(MatrixClipState* prev, int flags) |
200 #ifdef SK_DEBUG | 183 #ifdef SK_DEBUG |
201 : fPrev(prev) | 184 : fPrev(prev) |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
242 ClipInfo* fClipInfo; | 225 ClipInfo* fClipInfo; |
243 ClipInfo fClipInfoStorage; | 226 ClipInfo fClipInfoStorage; |
244 | 227 |
245 // Tracks the current depth of saveLayers to support the isDrawingToLaye
r call | 228 // Tracks the current depth of saveLayers to support the isDrawingToLaye
r call |
246 int fLayerID; | 229 int fLayerID; |
247 // Does this MC state represent a saveLayer call? | 230 // Does this MC state represent a saveLayer call? |
248 bool fIsSaveLayer; | 231 bool fIsSaveLayer; |
249 | 232 |
250 // The next two fields are only valid when fIsSaveLayer is set. | 233 // The next two fields are only valid when fIsSaveLayer is set. |
251 int32_t fSaveLayerBaseStateID; | 234 int32_t fSaveLayerBaseStateID; |
252 bool fSaveLayerBracketed; | 235 SkTDArray<int>* fSavedSkipOffsets; |
253 | 236 |
254 #ifdef SK_DEBUG | 237 #ifdef SK_DEBUG |
255 MatrixClipState* fPrev; // debugging aid | 238 MatrixClipState* fPrev; // debugging aid |
256 #endif | 239 #endif |
257 | 240 |
258 int32_t fMCStateID; | 241 int32_t fMCStateID; |
259 }; | 242 }; |
260 | 243 |
261 enum CallType { | 244 enum CallType { |
262 kMatrix_CallType, | 245 kMatrix_CallType, |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
340 | 323 |
341 bool clipRegion(const SkRegion& region, SkRegion::Op op) { | 324 bool clipRegion(const SkRegion& region, SkRegion::Op op) { |
342 this->call(SkMatrixClipStateMgr::kClip_CallType); | 325 this->call(SkMatrixClipStateMgr::kClip_CallType); |
343 int regionID = this->addRegionToDict(region); | 326 int regionID = this->addRegionToDict(region); |
344 return fCurMCState->fClipInfo->clipRegion(fPicRecord, regionID, op, | 327 return fCurMCState->fClipInfo->clipRegion(fPicRecord, regionID, op, |
345 fCurMCState->fMatrixInfo->getI
D(this)); | 328 fCurMCState->fMatrixInfo->getI
D(this)); |
346 } | 329 } |
347 | 330 |
348 bool call(CallType callType); | 331 bool call(CallType callType); |
349 | 332 |
350 void fillInSkips(SkWriter32* writer, int32_t restoreOffset) { | 333 void fillInSkips(SkWriter32* writer, int32_t restoreOffset); |
351 // Since we write out the entire clip stack at each block start we | |
352 // need to update the skips for the entire stack each time too. | |
353 SkDeque::F2BIter iter(fMatrixClipStack); | |
354 | |
355 for (const MatrixClipState* state = (const MatrixClipState*) iter.next()
; | |
356 state != NULL; | |
357 state = (const MatrixClipState*) iter.next()) { | |
358 state->fClipInfo->fillInSkips(writer, restoreOffset); | |
359 } | |
360 } | |
361 | 334 |
362 void finish(); | 335 void finish(); |
363 | 336 |
364 protected: | 337 protected: |
365 SkPictureRecord* fPicRecord; | 338 SkPictureRecord* fPicRecord; |
366 | 339 |
367 uint32_t fMatrixClipStackStorage[43]; // sized to fit 2 clip states | 340 uint32_t fMatrixClipStackStorage[43]; // sized to fit 2 clip states |
368 SkDeque fMatrixClipStack; | 341 SkDeque fMatrixClipStack; |
369 MatrixClipState* fCurMCState; | 342 MatrixClipState* fCurMCState; |
370 | 343 |
371 // This dictionary doesn't actually de-duplicate the matrices (except for th
e | 344 // This dictionary doesn't actually de-duplicate the matrices (except for th
e |
372 // identity matrix). It merely stores the matrices and allows them to be loo
ked | 345 // identity matrix). It merely stores the matrices and allows them to be loo
ked |
373 // up by ID later. The de-duplication mainly falls upon the matrix/clip stac
k | 346 // up by ID later. The de-duplication mainly falls upon the matrix/clip stac
k |
374 // which stores the ID so a revisited clip/matrix (via popping the stack) wi
ll | 347 // which stores the ID so a revisited clip/matrix (via popping the stack) wi
ll |
375 // use the same ID. | 348 // use the same ID. |
376 SkTDArray<SkMatrix> fMatrixDict; | 349 SkTDArray<SkMatrix> fMatrixDict; |
377 | 350 |
378 SkTDArray<SkRegion*> fRegionDict; | 351 SkTDArray<SkRegion*> fRegionDict; |
379 | 352 |
380 // The MCStateID of the state currently in effect in the byte stream. 0 if n
one. | 353 // The MCStateID of the state currently in effect in the byte stream. 0 if n
one. |
381 int32_t fCurOpenStateID; | 354 int32_t fCurOpenStateID; |
| 355 // The skip offsets for the current open state. These are the locations in t
he |
| 356 // skp that must be filled in when the current open state is closed. These a
re |
| 357 // here rather then distributed across the MatrixClipState's because saveLay
ers |
| 358 // can cause MC states to be nested. |
| 359 SkTDArray<int32_t> *fSkipOffsets; |
382 | 360 |
383 SkDEBUGCODE(void validate();) | 361 SkDEBUGCODE(void validate();) |
384 | 362 |
| 363 int MCStackPush(SkCanvas::SaveFlags flags); |
| 364 |
| 365 void addClipOffset(int offset) { |
| 366 SkASSERT(NULL != fSkipOffsets); |
| 367 SkASSERT(kIdentityWideOpenStateID != fCurOpenStateID); |
| 368 |
| 369 *fSkipOffsets->append() = offset; |
| 370 } |
| 371 |
385 void writeDeltaMat(int currentMatID, int desiredMatID); | 372 void writeDeltaMat(int currentMatID, int desiredMatID); |
386 static int32_t NewMCStateID(); | 373 static int32_t NewMCStateID(); |
387 | 374 |
388 int addRegionToDict(const SkRegion& region); | 375 int addRegionToDict(const SkRegion& region); |
389 const SkRegion* lookupRegion(int index) { | 376 const SkRegion* lookupRegion(int index) { |
390 SkASSERT(index >= 0 && index < fRegionDict.count()); | 377 SkASSERT(index >= 0 && index < fRegionDict.count()); |
391 return fRegionDict[index]; | 378 return fRegionDict[index]; |
392 } | 379 } |
393 | 380 |
394 // TODO: add stats to check if the dictionary really does | 381 // TODO: add stats to check if the dictionary really does |
395 // reduce the size of the SkPicture. | 382 // reduce the size of the SkPicture. |
396 int addMatToDict(const SkMatrix& mat); | 383 int addMatToDict(const SkMatrix& mat); |
397 const SkMatrix& lookupMat(int index) { | 384 const SkMatrix& lookupMat(int index) { |
398 SkASSERT(index >= 0 && index < fMatrixDict.count()); | 385 SkASSERT(index >= 0 && index < fMatrixDict.count()); |
399 return fMatrixDict[index]; | 386 return fMatrixDict[index]; |
400 } | 387 } |
401 }; | 388 }; |
402 | 389 |
403 #endif | 390 #endif |
OLD | NEW |