Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(500)

Side by Side Diff: src/core/SkMatrixClipStateMgr.h

Issue 151033004: Add matrix dictionary to SkMatrixClipStateMgr (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: updated to Tot Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/core/SkMatrixClipStateMgr.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
11 #include "SkMatrix.h" 11 #include "SkMatrix.h"
12 #include "SkRegion.h" 12 #include "SkRegion.h"
13 #include "SkRRect.h" 13 #include "SkRRect.h"
14 #include "SkTypes.h" 14 #include "SkTypes.h"
15 #include "SkTArray.h" 15 #include "SkTArray.h"
16 #include "SkTDArray.h"
16 17
17 class SkPictureRecord; 18 class SkPictureRecord;
18 class SkWriter32; 19 class SkWriter32;
19 20
20 // The SkMatrixClipStateMgr collapses the matrix/clip state of an SkPicture into 21 // The SkMatrixClipStateMgr collapses the matrix/clip state of an SkPicture into
21 // a series of save/restore blocks of consistent matrix clip state, e.g.: 22 // a series of save/restore blocks of consistent matrix clip state, e.g.:
22 // 23 //
23 // save 24 // save
24 // clip(s) 25 // clip(s)
25 // concat 26 // concat
(...skipping 18 matching lines...) Expand all
44 // As a side effect of this process all saves and saveLayers will become 45 // As a side effect of this process all saves and saveLayers will become
45 // kMatrixClip_SaveFlag style saves/saveLayers. 46 // kMatrixClip_SaveFlag style saves/saveLayers.
46 47
47 // The SkMatrixClipStateMgr works by intercepting all the save*, restore, clip*, 48 // The SkMatrixClipStateMgr works by intercepting all the save*, restore, clip*,
48 // and matrix calls sent to SkCanvas in order to track the current matrix/clip 49 // and matrix calls sent to SkCanvas in order to track the current matrix/clip
49 // state. All the other canvas calls get funnelled into a generic "call" entry 50 // state. All the other canvas calls get funnelled into a generic "call" entry
50 // point that signals that a state block is required. 51 // point that signals that a state block is required.
51 class SkMatrixClipStateMgr { 52 class SkMatrixClipStateMgr {
52 public: 53 public:
53 static const int32_t kIdentityWideOpenStateID = 0; 54 static const int32_t kIdentityWideOpenStateID = 0;
55 static const int kIdentityMatID = 0;
54 56
55 class MatrixClipState { 57 class MatrixClipState {
56 public: 58 public:
57 class MatrixInfo { 59 class MatrixInfo {
58 public: 60 public:
61 void reset() {
62 fMatrixID = kIdentityMatID;
63 fMatrix.reset();
64 }
65
66 bool preTranslate(SkScalar dx, SkScalar dy) {
67 fMatrixID = -1;
68 return fMatrix.preTranslate(dx, dy);
69 }
70
71 bool preScale(SkScalar sx, SkScalar sy) {
72 fMatrixID = -1;
73 return fMatrix.preScale(sx, sy);
74 }
75
76 bool preRotate(SkScalar degrees) {
77 fMatrixID = -1;
78 return fMatrix.preRotate(degrees);
79 }
80
81 bool preSkew(SkScalar sx, SkScalar sy) {
82 fMatrixID = -1;
83 return fMatrix.preSkew(sx, sy);
84 }
85
86 bool preConcat(const SkMatrix& matrix) {
87 fMatrixID = -1;
88 return fMatrix.preConcat(matrix);
89 }
90
91 void setMatrix(const SkMatrix& matrix) {
92 fMatrixID = -1;
93 fMatrix = matrix;
94 }
95
96 int getID(SkMatrixClipStateMgr* mgr) {
97 if (fMatrixID >= 0) {
98 return fMatrixID;
99 }
100
101 fMatrixID = mgr->addMatToDict(fMatrix);
102 return fMatrixID;
103 }
104
105 private:
59 SkMatrix fMatrix; 106 SkMatrix fMatrix;
60 // TODO: add an internal dictionary and an ID here 107 int fMatrixID;
61 }; 108 };
62 109
63 class ClipInfo : public SkNoncopyable { 110 class ClipInfo : public SkNoncopyable {
64 public: 111 public:
65 ClipInfo() {} 112 ClipInfo() {}
66 113
67 bool clipRect(const SkRect& rect, 114 bool clipRect(const SkRect& rect,
68 SkRegion::Op op, 115 SkRegion::Op op,
69 bool doAA, 116 bool doAA,
70 const SkMatrix& matrix) { 117 int matrixID) {
71 ClipOp& newClip = fClips.push_back(); 118 ClipOp& newClip = fClips.push_back();
72 newClip.fClipType = kRect_ClipType; 119 newClip.fClipType = kRect_ClipType;
73 newClip.fGeom.fRRect.setRect(rect); // storing the clipRect in the RRect 120 newClip.fGeom.fRRect.setRect(rect); // storing the clipRect in the RRect
74 newClip.fOp = op; 121 newClip.fOp = op;
75 newClip.fDoAA = doAA; 122 newClip.fDoAA = doAA;
76 newClip.fMatrix = matrix; 123 newClip.fMatrixID = matrixID;
77 newClip.fOffset = kInvalidJumpOffset; 124 newClip.fOffset = kInvalidJumpOffset;
78 return false; 125 return false;
79 } 126 }
80 127
81 bool clipRRect(const SkRRect& rrect, 128 bool clipRRect(const SkRRect& rrect,
82 SkRegion::Op op, 129 SkRegion::Op op,
83 bool doAA, 130 bool doAA,
84 const SkMatrix& matrix) { 131 int matrixID) {
85 ClipOp& newClip = fClips.push_back(); 132 ClipOp& newClip = fClips.push_back();
86 newClip.fClipType = kRRect_ClipType; 133 newClip.fClipType = kRRect_ClipType;
87 newClip.fGeom.fRRect = rrect; 134 newClip.fGeom.fRRect = rrect;
88 newClip.fOp = op; 135 newClip.fOp = op;
89 newClip.fDoAA = doAA; 136 newClip.fDoAA = doAA;
90 newClip.fMatrix = matrix; 137 newClip.fMatrixID = matrixID;
91 newClip.fOffset = kInvalidJumpOffset; 138 newClip.fOffset = kInvalidJumpOffset;
92 return false; 139 return false;
93 } 140 }
94 141
95 bool clipPath(SkPictureRecord* picRecord, 142 bool clipPath(SkPictureRecord* picRecord,
96 const SkPath& path, 143 const SkPath& path,
97 SkRegion::Op op, 144 SkRegion::Op op,
98 bool doAA, 145 bool doAA,
99 const SkMatrix& matrix); 146 int matrixID);
100 bool clipRegion(SkPictureRecord* picRecord, 147 bool clipRegion(SkPictureRecord* picRecord,
101 const SkRegion& region, 148 const SkRegion& region,
102 SkRegion::Op op, 149 SkRegion::Op op,
103 const SkMatrix& matrix); 150 int matrixID);
104 void writeClip(SkMatrix* curMat, 151 void writeClip(int* curMatID,
105 SkPictureRecord* picRecord, 152 SkMatrixClipStateMgr* mgr,
106 bool* overrideFirstOp); 153 bool* overrideFirstOp);
107 void fillInSkips(SkWriter32* writer, int32_t restoreOffset); 154 void fillInSkips(SkWriter32* writer, int32_t restoreOffset);
108 155
109 #ifdef SK_DEBUG 156 #ifdef SK_DEBUG
110 void checkOffsetNotEqual(int32_t offset) { 157 void checkOffsetNotEqual(int32_t offset) {
111 for (int i = 0; i < fClips.count(); ++i) { 158 for (int i = 0; i < fClips.count(); ++i) {
112 ClipOp& curClip = fClips[i]; 159 ClipOp& curClip = fClips[i];
113 SkASSERT(offset != curClip.fOffset); 160 SkASSERT(offset != curClip.fOffset);
114 } 161 }
115 } 162 }
(...skipping 25 matching lines...) Expand all
141 // TODO: add internal dictionary of regions 188 // TODO: add internal dictionary of regions
142 // This parameter forces us to have a dtor and thus use 189 // This parameter forces us to have a dtor and thus use
143 // SkTArray rather then SkTDArray! 190 // SkTArray rather then SkTDArray!
144 const SkRegion* fRegion; 191 const SkRegion* fRegion;
145 } fGeom; 192 } fGeom;
146 193
147 bool fDoAA; 194 bool fDoAA;
148 SkRegion::Op fOp; 195 SkRegion::Op fOp;
149 196
150 // The CTM in effect when this clip call was issued 197 // The CTM in effect when this clip call was issued
151 // TODO: add an internal dictionary and replace with ID 198 int fMatrixID;
152 SkMatrix fMatrix;
153 199
154 // The offset of this clipOp's "jump-to-offset" location in the skp. 200 // The offset of this clipOp's "jump-to-offset" location in the skp.
155 // -1 means the offset hasn't been written. 201 // -1 means the offset hasn't been written.
156 int32_t fOffset; 202 int32_t fOffset;
157 }; 203 };
158 204
159 SkTArray<ClipOp> fClips; 205 SkTArray<ClipOp> fClips;
160 206
161 typedef SkNoncopyable INHERITED; 207 typedef SkNoncopyable INHERITED;
162 }; 208 };
163 209
164 MatrixClipState(MatrixClipState* prev, int flags) 210 MatrixClipState(MatrixClipState* prev, int flags)
165 #ifdef SK_DEBUG 211 #ifdef SK_DEBUG
166 : fPrev(prev) 212 : fPrev(prev)
167 #endif 213 #endif
168 { 214 {
169 if (NULL == prev) { 215 if (NULL == prev) {
170 fLayerID = 0; 216 fLayerID = 0;
171 217
172 fMatrixInfoStorage.fMatrix.reset(); 218 fMatrixInfoStorage.reset();
173 fMatrixInfo = &fMatrixInfoStorage; 219 fMatrixInfo = &fMatrixInfoStorage;
174 fClipInfo = &fClipInfoStorage; // ctor handles init of fClipInf oStorage 220 fClipInfo = &fClipInfoStorage; // ctor handles init of fClipInf oStorage
175 221
176 // The identity/wide-open-clip state is current by default 222 // The identity/wide-open-clip state is current by default
177 fMCStateID = kIdentityWideOpenStateID; 223 fMCStateID = kIdentityWideOpenStateID;
178 } 224 }
179 else { 225 else {
180 fLayerID = prev->fLayerID; 226 fLayerID = prev->fLayerID;
181 227
182 if (flags & SkCanvas::kMatrix_SaveFlag) { 228 if (flags & SkCanvas::kMatrix_SaveFlag) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 }; 276 };
231 277
232 SkMatrixClipStateMgr(); 278 SkMatrixClipStateMgr();
233 279
234 void init(SkPictureRecord* picRecord) { 280 void init(SkPictureRecord* picRecord) {
235 // Note: we're not taking a ref here. It is expected that the SkMatrixCl ipStateMgr 281 // Note: we're not taking a ref here. It is expected that the SkMatrixCl ipStateMgr
236 // is owned by the SkPictureRecord object 282 // is owned by the SkPictureRecord object
237 fPicRecord = picRecord; 283 fPicRecord = picRecord;
238 } 284 }
239 285
286 SkPictureRecord* getPicRecord() { return fPicRecord; }
287
240 // TODO: need to override canvas' getSaveCount. Right now we pass the 288 // TODO: need to override canvas' getSaveCount. Right now we pass the
241 // save* and restore calls on to the base SkCanvas in SkPictureRecord but 289 // save* and restore calls on to the base SkCanvas in SkPictureRecord but
242 // this duplicates effort. 290 // this duplicates effort.
243 int getSaveCount() const { return fMatrixClipStack.count(); } 291 int getSaveCount() const { return fMatrixClipStack.count(); }
244 292
245 int save(SkCanvas::SaveFlags flags); 293 int save(SkCanvas::SaveFlags flags);
246 294
247 int saveLayer(const SkRect* bounds, const SkPaint* paint, SkCanvas::SaveFlag s flags); 295 int saveLayer(const SkRect* bounds, const SkPaint* paint, SkCanvas::SaveFlag s flags);
248 296
249 bool isDrawingToLayer() const { 297 bool isDrawingToLayer() const {
250 return fCurMCState->fLayerID > 0; 298 return fCurMCState->fLayerID > 0;
251 } 299 }
252 300
253 void restore(); 301 void restore();
254 302
255 bool translate(SkScalar dx, SkScalar dy) { 303 bool translate(SkScalar dx, SkScalar dy) {
256 this->call(kMatrix_CallType); 304 this->call(kMatrix_CallType);
257 return fCurMCState->fMatrixInfo->fMatrix.preTranslate(dx, dy); 305 return fCurMCState->fMatrixInfo->preTranslate(dx, dy);
258 } 306 }
259 307
260 bool scale(SkScalar sx, SkScalar sy) { 308 bool scale(SkScalar sx, SkScalar sy) {
261 this->call(kMatrix_CallType); 309 this->call(kMatrix_CallType);
262 return fCurMCState->fMatrixInfo->fMatrix.preScale(sx, sy); 310 return fCurMCState->fMatrixInfo->preScale(sx, sy);
263 } 311 }
264 312
265 bool rotate(SkScalar degrees) { 313 bool rotate(SkScalar degrees) {
266 this->call(kMatrix_CallType); 314 this->call(kMatrix_CallType);
267 return fCurMCState->fMatrixInfo->fMatrix.preRotate(degrees); 315 return fCurMCState->fMatrixInfo->preRotate(degrees);
268 } 316 }
269 317
270 bool skew(SkScalar sx, SkScalar sy) { 318 bool skew(SkScalar sx, SkScalar sy) {
271 this->call(kMatrix_CallType); 319 this->call(kMatrix_CallType);
272 return fCurMCState->fMatrixInfo->fMatrix.preSkew(sx, sy); 320 return fCurMCState->fMatrixInfo->preSkew(sx, sy);
273 } 321 }
274 322
275 bool concat(const SkMatrix& matrix) { 323 bool concat(const SkMatrix& matrix) {
276 this->call(kMatrix_CallType); 324 this->call(kMatrix_CallType);
277 return fCurMCState->fMatrixInfo->fMatrix.preConcat(matrix); 325 return fCurMCState->fMatrixInfo->preConcat(matrix);
278 } 326 }
279 327
280 void setMatrix(const SkMatrix& matrix) { 328 void setMatrix(const SkMatrix& matrix) {
281 this->call(kMatrix_CallType); 329 this->call(kMatrix_CallType);
282 fCurMCState->fMatrixInfo->fMatrix = matrix; 330 fCurMCState->fMatrixInfo->setMatrix(matrix);
283 } 331 }
284 332
285 bool clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { 333 bool clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) {
286 this->call(SkMatrixClipStateMgr::kClip_CallType); 334 this->call(SkMatrixClipStateMgr::kClip_CallType);
287 return fCurMCState->fClipInfo->clipRect(rect, op, doAA, 335 return fCurMCState->fClipInfo->clipRect(rect, op, doAA,
288 fCurMCState->fMatrixInfo->fMatri x); 336 fCurMCState->fMatrixInfo->getID( this));
289 } 337 }
290 338
291 bool clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) { 339 bool clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) {
292 this->call(SkMatrixClipStateMgr::kClip_CallType); 340 this->call(SkMatrixClipStateMgr::kClip_CallType);
293 return fCurMCState->fClipInfo->clipRRect(rrect, op, doAA, 341 return fCurMCState->fClipInfo->clipRRect(rrect, op, doAA,
294 fCurMCState->fMatrixInfo->fMatr ix); 342 fCurMCState->fMatrixInfo->getID (this));
295 } 343 }
296 344
297 bool clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { 345 bool clipPath(const SkPath& path, SkRegion::Op op, bool doAA) {
298 this->call(SkMatrixClipStateMgr::kClip_CallType); 346 this->call(SkMatrixClipStateMgr::kClip_CallType);
299 return fCurMCState->fClipInfo->clipPath(fPicRecord, path, op, doAA, 347 return fCurMCState->fClipInfo->clipPath(fPicRecord, path, op, doAA,
300 fCurMCState->fMatrixInfo->fMatri x); 348 fCurMCState->fMatrixInfo->getID( this));
301 } 349 }
302 350
303 bool clipRegion(const SkRegion& region, SkRegion::Op op) { 351 bool clipRegion(const SkRegion& region, SkRegion::Op op) {
304 this->call(SkMatrixClipStateMgr::kClip_CallType); 352 this->call(SkMatrixClipStateMgr::kClip_CallType);
305 return fCurMCState->fClipInfo->clipRegion(fPicRecord, region, op, 353 return fCurMCState->fClipInfo->clipRegion(fPicRecord, region, op,
306 fCurMCState->fMatrixInfo->fMat rix); 354 fCurMCState->fMatrixInfo->getI D(this));
307 } 355 }
308 356
309 bool call(CallType callType); 357 bool call(CallType callType);
310 358
311 void fillInSkips(SkWriter32* writer, int32_t restoreOffset) { 359 void fillInSkips(SkWriter32* writer, int32_t restoreOffset) {
312 // Since we write out the entire clip stack at each block start we 360 // Since we write out the entire clip stack at each block start we
313 // need to update the skips for the entire stack each time too. 361 // need to update the skips for the entire stack each time too.
314 SkDeque::F2BIter iter(fMatrixClipStack); 362 SkDeque::F2BIter iter(fMatrixClipStack);
315 363
316 for (const MatrixClipState* state = (const MatrixClipState*) iter.next() ; 364 for (const MatrixClipState* state = (const MatrixClipState*) iter.next() ;
317 state != NULL; 365 state != NULL;
318 state = (const MatrixClipState*) iter.next()) { 366 state = (const MatrixClipState*) iter.next()) {
319 state->fClipInfo->fillInSkips(writer, restoreOffset); 367 state->fClipInfo->fillInSkips(writer, restoreOffset);
320 } 368 }
321 } 369 }
322 370
323 void finish(); 371 void finish();
324 372
325 protected: 373 protected:
326 SkPictureRecord* fPicRecord; 374 SkPictureRecord* fPicRecord;
327 375
328 uint32_t fMatrixClipStackStorage[43]; // sized to fit 2 clip states 376 uint32_t fMatrixClipStackStorage[43]; // sized to fit 2 clip states
329 SkDeque fMatrixClipStack; 377 SkDeque fMatrixClipStack;
330 MatrixClipState* fCurMCState; 378 MatrixClipState* fCurMCState;
331 379
380 // This dictionary doesn't actually de-duplicate the matrices (except for th e
381 // identity matrix). It merely stores the matrices and allows them to be loo ked
382 // up by ID later. The de-duplication mainly falls upon the matrix/clip stac k
383 // which stores the ID so a revisited clip/matrix (via popping the stack) wi ll
384 // use the same ID.
385 SkTDArray<SkMatrix> fMatrixDict;
386
332 // The MCStateID of the state currently in effect in the byte stream. 0 if n one. 387 // The MCStateID of the state currently in effect in the byte stream. 0 if n one.
333 int32_t fCurOpenStateID; 388 int32_t fCurOpenStateID;
334 389
335 SkDEBUGCODE(void validate();) 390 SkDEBUGCODE(void validate();)
336 391
337 static void WriteDeltaMat(SkPictureRecord* picRecord, 392 void writeDeltaMat(int currentMatID, int desiredMatID);
338 const SkMatrix& current,
339 const SkMatrix& desired);
340 static int32_t NewMCStateID(); 393 static int32_t NewMCStateID();
394
395 // TODO: add stats to check if the dictionary really does
396 // reduce the size of the SkPicture.
397 int addMatToDict(const SkMatrix& mat);
398 const SkMatrix& lookupMat(int index) {
399 SkASSERT(index >= 0 && index < fMatrixDict.count());
400 return fMatrixDict[index];
401 }
341 }; 402 };
342 403
343 #endif 404 #endif
OLDNEW
« no previous file with comments | « no previous file | src/core/SkMatrixClipStateMgr.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698