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

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

Issue 139093003: Collapse matrix & clip stack in PictureRecord (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: update 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 | « gyp/tests.gyp ('k') | src/core/SkPictureRecord.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 /* 2 /*
3 * Copyright 2011 Google Inc. 3 * Copyright 2011 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 #ifndef SkPictureRecord_DEFINED 8 #ifndef SkPictureRecord_DEFINED
9 #define SkPictureRecord_DEFINED 9 #define SkPictureRecord_DEFINED
10 10
11 #include "SkCanvas.h" 11 #include "SkCanvas.h"
12 #include "SkFlattenable.h" 12 #include "SkFlattenable.h"
13 #include "SkPathHeap.h" 13 #include "SkPathHeap.h"
14 #include "SkPicture.h" 14 #include "SkPicture.h"
15 #include "SkPictureFlat.h" 15 #include "SkPictureFlat.h"
16 #include "SkTemplates.h" 16 #include "SkTemplates.h"
17 #include "SkWriter32.h" 17 #include "SkWriter32.h"
18 18
19 #define COLLAPSE_MATRIX_CLIP_STATE 1
20
21 #ifdef COLLAPSE_MATRIX_CLIP_STATE
22 #include "SkTypes.h"
23
24 class MatrixClipState {
25 public:
26 class MatrixInfo {
27 public:
28 SkMatrix fMatrix;
29 // TODO: add an internal dictionary and an ID here
30 };
31
32 class ClipInfo : public SkNoncopyable {
33 public:
34 ClipInfo() {}
35
36 bool clipRect(const SkRect& rect, SkRegion::Op op, bool doAA, const SkMa trix& matrix) {
37 ClipOp* newClip = fClips.append();
38 newClip->fClipType = kRect_ClipType;
39 newClip->fGeom.fRRect.setRect(rect); // store the clipRect in the RRect
40 newClip->fOp = op;
41 newClip->fDoAA = doAA;
42 newClip->fMatrix = matrix;
43 newClip->fOffset = kInvalidJumpOffset;
44 return false;
45 }
46
47 bool clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA, const S kMatrix& matrix) {
48 ClipOp* newClip = fClips.append();
49 newClip->fClipType = kRRect_ClipType;
50 newClip->fGeom.fRRect = rrect;
51 newClip->fOp = op;
52 newClip->fDoAA = doAA;
53 newClip->fMatrix = matrix;
54 newClip->fOffset = kInvalidJumpOffset;
55 return false;
56 }
57
58 bool clipPath(SkPictureRecord* picRecord,
59 const SkPath& path,
60 SkRegion::Op op,
61 bool doAA,
62 const SkMatrix& matrix);
63 bool clipRegion(SkPictureRecord* picRecord,
64 const SkRegion& region,
65 SkRegion::Op op,
66 const SkMatrix& matrix);
67 void writeClip(SkMatrix* curMat, SkPictureRecord* picRecord,
68 bool* overrideFirstOp);
69 void fillInSkips(SkWriter32* writer, int32_t restoreOffset);
70
71 private:
72 enum ClipType {
73 kRect_ClipType,
74 kRRect_ClipType,
75 kPath_ClipType,
76 kRegion_ClipType
77 };
78
79 static const int kInvalidJumpOffset = -1;
80
81 struct ClipOp {
82 ClipType fClipType;
83
84 union {
85 SkRRect fRRect; // also stores clipRect
86 int fPathID;
87 // TODO: add internal dictionary of regions
88 // Arrg - need to free this in dtor!!!
89 const SkRegion* fRegion;
90 } fGeom;
91
92 bool fDoAA;
93 SkRegion::Op fOp;
94
95 // This used to be and int (when matrices were in a dictionary)
96 // now it is a full matrix.
97 // The CTM in effect when this clip call was issued
98 SkMatrix fMatrix;
99
100 // The offset of this clipOp's "jump-to-offset" variable in the skp.
101 // -1 means the offset hasn't been written.
102 int32_t fOffset;
103 };
104
105 SkTDArray<ClipOp> fClips;
106
107 typedef SkNoncopyable INHERITED;
108 };
109
110 MatrixClipState(MatrixClipState *prev, int flags) {
111 if (NULL == prev) {
112 fLayerID = 0;
113
114 fMatrixInfoStorage.fMatrix.reset();
115 fMatrixInfo = &fMatrixInfoStorage;
116 fClipInfo = &fClipInfoStorage;
117
118 fIsCurrent = true;
119 }
120 else {
121 fLayerID = prev->fLayerID;
122
123 if (flags & SkCanvas::kMatrix_SaveFlag) {
124 fMatrixInfoStorage = *prev->fMatrixInfo;
125 fMatrixInfo = &fMatrixInfoStorage;
126 } else {
127 fMatrixInfo = prev->fMatrixInfo;
128 }
129
130 if (flags & SkCanvas::kClip_SaveFlag) {
131 // We don't copy the ClipOps of the previous clip states
132 fClipInfo = &fClipInfoStorage;
133 } else {
134 fClipInfo = prev->fClipInfo;
135 }
136
137 fIsCurrent = prev->fIsCurrent;
138 }
139
140 fWroteSave = false;
141 fIsSaveLayer = false;
142 }
143
144 MatrixInfo* fMatrixInfo;
145 MatrixInfo fMatrixInfoStorage;
146
147 ClipInfo* fClipInfo;
148 ClipInfo fClipInfoStorage;
149
150 int fLayerID;
151 // Does this MC state represent a saveLayer call?
152 bool fIsSaveLayer;
153 // Is this the current MC state in the picture command stream?
154 bool fIsCurrent;
155 // Is there an unbalanced 'save' for this MC state already in the command st ream?
156 bool fWroteSave;
157 };
158
159
160 class MatrixClipStateMgr {
161 public:
162 enum CallType {
163 kMatrix_CallType,
164 kClip_CallType,
165 kOther_CallType
166 };
167
168 MatrixClipStateMgr();
169
170 void init(SkPictureRecord* picRecord) {
171 fPicRecord = picRecord;
172 }
173
174 // TODO: need to override canvas' getSaveCount
175 int getSaveCount() const { return fMatrixClipStack.count(); }
176
177 int save(SkCanvas::SaveFlags flags) {
178 MatrixClipState* newTop = (MatrixClipState*)fMatrixClipStack.push_back() ;
179 new (newTop) MatrixClipState(fCurMCState, flags); // balanced in rest ore()
180 fCurMCState = newTop;
181 return fMatrixClipStack.count();
182 }
183
184 int saveLayer(const SkRect* bounds, const SkPaint* paint,
185 SkCanvas::SaveFlags flags) {
186 int result = this->save(flags);
187 ++fCurMCState->fLayerID;
188 fCurMCState->fIsSaveLayer = true;
189 return result;
190 }
191
192 bool isDrawingToLayer() const {
193 return fCurMCState->fLayerID > 0;
194 }
195
196 void restore();
197
198 bool translate(SkScalar dx, SkScalar dy) {
199 this->call(kMatrix_CallType);
200 bool result = fCurMCState->fMatrixInfo->fMatrix.preTranslate(dx, dy);
201 // fCurMCState->fMatrixInfo->fID = -1;
202 fCurMCState->fIsCurrent = false;
203 return result;
204 }
205
206 bool scale(SkScalar sx, SkScalar sy) {
207 this->call(kMatrix_CallType);
208 bool result = fCurMCState->fMatrixInfo->fMatrix.preScale(sx, sy);
209 // fCurMCState->fMatrixInfo->fID = -1;
210 fCurMCState->fIsCurrent = false;
211 return result;
212 }
213
214 bool rotate(SkScalar degrees) {
215 this->call(kMatrix_CallType);
216 bool result = fCurMCState->fMatrixInfo->fMatrix.preRotate(degrees);
217 // fCurMCState->fMatrixInfo->fID = -1;
218 fCurMCState->fIsCurrent = false;
219 return result;
220 }
221
222 bool skew(SkScalar sx, SkScalar sy) {
223 this->call(kMatrix_CallType);
224 bool result = fCurMCState->fMatrixInfo->fMatrix.preSkew(sx, sy);
225 // fCurMCState->fMatrixInfo->fID = -1;
226 fCurMCState->fIsCurrent = false;
227 return result;
228 }
229
230 bool concat(const SkMatrix& matrix) {
231 this->call(kMatrix_CallType);
232 bool result = fCurMCState->fMatrixInfo->fMatrix.preConcat(matrix);
233 // fCurMCState->fMatrixInfo->fID = -1;
234 fCurMCState->fIsCurrent = false;
235 return result;
236 }
237
238 void setMatrix(const SkMatrix& matrix) {
239 this->call(kMatrix_CallType);
240 fCurMCState->fMatrixInfo->fMatrix = matrix;
241 // fCurMCState->fMatrixInfo->fID = -1;
242 fCurMCState->fIsCurrent = false;
243 }
244
245 bool clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) {
246 this->call(MatrixClipStateMgr::kClip_CallType);
247
248 fCurMCState->fIsCurrent = false;
249 return fCurMCState->fClipInfo->clipRect(rect, op, doAA,
250 fCurMCState->fMatrixInfo->fMatri x);
251 }
252
253 bool clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) {
254 this->call(MatrixClipStateMgr::kClip_CallType);
255
256 fCurMCState->fIsCurrent = false;
257 return fCurMCState->fClipInfo->clipRRect(rrect, op, doAA,
258 fCurMCState->fMatrixInfo->fMatr ix);
259 }
260
261 bool clipPath(const SkPath& path, SkRegion::Op op, bool doAA) {
262 this->call(MatrixClipStateMgr::kClip_CallType);
263
264 fCurMCState->fIsCurrent = false;
265 bool result = fCurMCState->fClipInfo->clipPath(fPicRecord, path, op, doA A,
266 fCurMCState->fMatrixInfo- >fMatrix);
267 return result;
268 }
269
270 bool clipRegion(const SkRegion& region, SkRegion::Op op) {
271 this->call(MatrixClipStateMgr::kClip_CallType);
272
273 fCurMCState->fIsCurrent = false;
274 bool result = fCurMCState->fClipInfo->clipRegion(fPicRecord, region, op,
275 fCurMCState->fMatrixInf o->fMatrix);
276 return result;
277 }
278
279 void call(CallType callType);
280
281 void fillInSkips(SkWriter32* writer, int32_t restoreOffset) {
282 fCurMCState->fClipInfo->fillInSkips(writer, restoreOffset);
283 }
284
285 void finish1() {
286 #if 0
287 if (fCurMCState->fWroteSave) {
288 fCurMCState->fWroteSave = false;
289 fPicRecord->restoreImpl();
290 }
291 #endif
292 }
293
294 protected:
295 SkPictureRecord* fPicRecord;
296
297 uint32_t fMatrixClipStackStorage[43]; // sized to fit 2 clip states
298 SkDeque fMatrixClipStack;
299 MatrixClipState* fCurMCState;
300 };
301 #endif
302
303
19 class SkPictureStateTree; 304 class SkPictureStateTree;
20 class SkBBoxHierarchy; 305 class SkBBoxHierarchy;
21 306
22 // These macros help with packing and unpacking a single byte value and 307 // These macros help with packing and unpacking a single byte value and
23 // a 3 byte value into/out of a uint32_t 308 // a 3 byte value into/out of a uint32_t
24 #define MASK_24 0x00FFFFFF 309 #define MASK_24 0x00FFFFFF
25 #define UNPACK_8_24(combined, small, large) \ 310 #define UNPACK_8_24(combined, small, large) \
26 small = (combined >> 24) & 0xFF; \ 311 small = (combined >> 24) & 0xFF; \
27 large = combined & MASK_24; 312 large = combined & MASK_24;
28 #define PACK_8_24(small, large) ((small << 24) | large) 313 #define PACK_8_24(small, large) ((small << 24) | large)
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 386
102 const SkWriter32& writeStream() const { 387 const SkWriter32& writeStream() const {
103 return fWriter; 388 return fWriter;
104 } 389 }
105 390
106 void beginRecording(); 391 void beginRecording();
107 void endRecording(); 392 void endRecording();
108 393
109 private: 394 private:
110 void handleOptimization(int opt); 395 void handleOptimization(int opt);
111 void recordRestoreOffsetPlaceholder(SkRegion::Op); 396 int recordRestoreOffsetPlaceholder(SkRegion::Op);
112 void fillRestoreOffsetPlaceholdersForCurrentStackLevel( 397 void fillRestoreOffsetPlaceholdersForCurrentStackLevel(uint32_t restoreOffse t);
113 uint32_t restoreOffset);
114 398
399 #ifndef COLLAPSE_MATRIX_CLIP_STATE
115 SkTDArray<int32_t> fRestoreOffsetStack; 400 SkTDArray<int32_t> fRestoreOffsetStack;
116 int fFirstSavedLayerIndex; 401 int fFirstSavedLayerIndex;
117 enum { 402 enum {
118 kNoSavedLayerIndex = -1 403 kNoSavedLayerIndex = -1
119 }; 404 };
405 #endif
120 406
121 /* 407 /*
122 * Write the 'drawType' operation and chunk size to the skp. 'size' 408 * Write the 'drawType' operation and chunk size to the skp. 'size'
123 * can potentially be increased if the chunk size needs its own storage 409 * can potentially be increased if the chunk size needs its own storage
124 * location (i.e., it overflows 24 bits). 410 * location (i.e., it overflows 24 bits).
125 * Returns the start offset of the chunk. This is the location at which 411 * Returns the start offset of the chunk. This is the location at which
126 * the opcode & size are stored. 412 * the opcode & size are stored.
127 * TODO: since we are handing the size into here we could call reserve 413 * TODO: since we are handing the size into here we could call reserve
128 * and then return a pointer to the memory storage. This could decrease 414 * and then return a pointer to the memory storage. This could decrease
129 * allocation overhead but could lead to more wasted space (the tail 415 * allocation overhead but could lead to more wasted space (the tail
(...skipping 24 matching lines...) Expand all
154 } 440 }
155 441
156 void addInt(int value) { 442 void addInt(int value) {
157 fWriter.writeInt(value); 443 fWriter.writeInt(value);
158 } 444 }
159 void addScalar(SkScalar scalar) { 445 void addScalar(SkScalar scalar) {
160 fWriter.writeScalar(scalar); 446 fWriter.writeScalar(scalar);
161 } 447 }
162 448
163 void addBitmap(const SkBitmap& bitmap); 449 void addBitmap(const SkBitmap& bitmap);
450 int addMatrixToHeap(const SkMatrix& matrix);
164 void addMatrix(const SkMatrix& matrix); 451 void addMatrix(const SkMatrix& matrix);
165 const SkFlatData* addPaint(const SkPaint& paint) { return this->addPaintPtr( &paint); } 452 const SkFlatData* addPaint(const SkPaint& paint) { return this->addPaintPtr( &paint); }
166 const SkFlatData* addPaintPtr(const SkPaint* paint); 453 const SkFlatData* addPaintPtr(const SkPaint* paint);
167 void addFlatPaint(const SkFlatData* flatPaint); 454 void addFlatPaint(const SkFlatData* flatPaint);
455 int addPathToHeap(const SkPath& path);
168 void addPath(const SkPath& path); 456 void addPath(const SkPath& path);
169 void addPicture(SkPicture& picture); 457 void addPicture(SkPicture& picture);
170 void addPoint(const SkPoint& point); 458 void addPoint(const SkPoint& point);
171 void addPoints(const SkPoint pts[], int count); 459 void addPoints(const SkPoint pts[], int count);
172 void addRect(const SkRect& rect); 460 void addRect(const SkRect& rect);
173 void addRectPtr(const SkRect* rect); 461 void addRectPtr(const SkRect* rect);
174 void addIRect(const SkIRect& rect); 462 void addIRect(const SkIRect& rect);
175 void addIRectPtr(const SkIRect* rect); 463 void addIRectPtr(const SkIRect* rect);
176 void addRRect(const SkRRect&); 464 void addRRect(const SkRRect&);
465 int addRegionToHeap(const SkRegion& region);
177 void addRegion(const SkRegion& region); 466 void addRegion(const SkRegion& region);
178 void addText(const void* text, size_t byteLength); 467 void addText(const void* text, size_t byteLength);
179 468
180 int find(const SkBitmap& bitmap); 469 int find(const SkBitmap& bitmap);
181 470
182 #ifdef SK_DEBUG_DUMP 471 #ifdef SK_DEBUG_DUMP
183 public: 472 public:
184 void dumpMatrices(); 473 void dumpMatrices();
185 void dumpPaints(); 474 void dumpPaints();
186 #endif 475 #endif
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 // Will return a cached version when possible. 519 // Will return a cached version when possible.
231 const SkFlatData* getFlatPaintData(const SkPaint& paint); 520 const SkFlatData* getFlatPaintData(const SkPaint& paint);
232 /** 521 /**
233 * SkBBoxRecord::drawPosTextH gets a flat paint and uses it, 522 * SkBBoxRecord::drawPosTextH gets a flat paint and uses it,
234 * then it calls this, using the extra parameter, to avoid duplication. 523 * then it calls this, using the extra parameter, to avoid duplication.
235 */ 524 */
236 void drawPosTextHImpl(const void* text, size_t byteLength, 525 void drawPosTextHImpl(const void* text, size_t byteLength,
237 const SkScalar xpos[], SkScalar constY, 526 const SkScalar xpos[], SkScalar constY,
238 const SkPaint& paint, const SkFlatData* flatPaintData) ; 527 const SkPaint& paint, const SkFlatData* flatPaintData) ;
239 528
529 void concatImpl(const SkMatrix& matrix);
530 void setMatrixImpl(const SkMatrix& matrix);
531 int clipRectImpl(const SkRect& rect, SkRegion::Op op, bool doAA);
532 int clipRRectImpl(const SkRRect& rrect, SkRegion::Op op, bool doAA);
533 int clipPathImpl(int pathID, SkRegion::Op op, bool doAA);
534 int clipRegionImpl(const SkRegion& region, SkRegion::Op op);
535 void saveImpl(SaveFlags flags);
536 void restoreImpl();
537
240 // These are set to NULL in our constructor, but may be changed by 538 // These are set to NULL in our constructor, but may be changed by
241 // subclasses, in which case they will be SkSafeUnref'd in our destructor. 539 // subclasses, in which case they will be SkSafeUnref'd in our destructor.
242 SkBBoxHierarchy* fBoundingHierarchy; 540 SkBBoxHierarchy* fBoundingHierarchy;
243 SkPictureStateTree* fStateTree; 541 SkPictureStateTree* fStateTree;
244 542
245 // Allocated in the constructor and managed by this class. 543 // Allocated in the constructor and managed by this class.
246 SkBitmapHeap* fBitmapHeap; 544 SkBitmapHeap* fBitmapHeap;
247 545
248 private: 546 private:
547 #ifdef COLLAPSE_MATRIX_CLIP_STATE
548 friend class MatrixClipState; // for access to *Impl methods
549 friend class MatrixClipStateMgr; // for access to *Impl methods
550 #endif
551
249 SkChunkFlatController fFlattenableHeap; 552 SkChunkFlatController fFlattenableHeap;
250 553
251 SkPaintDictionary fPaints; 554 SkPaintDictionary fPaints;
252 555
253 SkPathHeap* fPathHeap; // reference counted 556 SkPathHeap* fPathHeap; // reference counted
254 SkWriter32 fWriter; 557 SkWriter32 fWriter;
255 558
256 // we ref each item in these arrays 559 // we ref each item in these arrays
257 SkTDArray<SkPicture*> fPictureRefs; 560 SkTDArray<SkPicture*> fPictureRefs;
258 561
259 uint32_t fRecordFlags; 562 uint32_t fRecordFlags;
260 int fInitialSaveCount; 563 int fInitialSaveCount;
261 564
262 friend class SkPicturePlayback; 565 friend class SkPicturePlayback;
263 friend class SkPictureTester; // for unit testing 566 friend class SkPictureTester; // for unit testing
264 567
568 #ifdef COLLAPSE_MATRIX_CLIP_STATE
569 MatrixClipStateMgr fMCMgr;
570 #endif
571
265 typedef SkCanvas INHERITED; 572 typedef SkCanvas INHERITED;
266 }; 573 };
267 574
268 #endif 575 #endif
OLDNEW
« no previous file with comments | « gyp/tests.gyp ('k') | src/core/SkPictureRecord.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698