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