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

Side by Side Diff: src/core/SkRecordDraw.cpp

Issue 468193003: Start tracking the CTM while filling the BBH in SkRecordDraw. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: rebase Created 6 years, 4 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
« no previous file with comments | « src/core/SkCanvas.cpp ('k') | src/core/SkRecorder.h » ('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 7
8 #include "SkRecordDraw.h" 8 #include "SkRecordDraw.h"
9 #include "SkTSort.h" 9 #include "SkTSort.h"
10 10
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 // To implement this, we keep a stack of active Save blocks. As we consume ops 110 // To implement this, we keep a stack of active Save blocks. As we consume ops
111 // inside the Save/Restore block, drawing ops are unioned with the bounds of 111 // inside the Save/Restore block, drawing ops are unioned with the bounds of
112 // the block, and control ops are stashed away for later. When we finish the 112 // the block, and control ops are stashed away for later. When we finish the
113 // block with a Restore, our bounds are complete, and we go back and fill them 113 // block with a Restore, our bounds are complete, and we go back and fill them
114 // in for all the control ops we stashed away. 114 // in for all the control ops we stashed away.
115 class FillBounds : SkNoncopyable { 115 class FillBounds : SkNoncopyable {
116 public: 116 public:
117 FillBounds(const SkRecord& record, SkBBoxHierarchy* bbh) : fBounds(record.co unt()) { 117 FillBounds(const SkRecord& record, SkBBoxHierarchy* bbh) : fBounds(record.co unt()) {
118 // Calculate bounds for all ops. This won't go quite in order, so we'll need 118 // Calculate bounds for all ops. This won't go quite in order, so we'll need
119 // to store the bounds separately then feed them in to the BBH later in order. 119 // to store the bounds separately then feed them in to the BBH later in order.
120 fCTM.setIdentity();
120 for (fCurrentOp = 0; fCurrentOp < record.count(); fCurrentOp++) { 121 for (fCurrentOp = 0; fCurrentOp < record.count(); fCurrentOp++) {
121 record.visit<void>(fCurrentOp, *this); 122 record.visit<void>(fCurrentOp, *this);
122 } 123 }
123 124
124 // If we have any lingering unpaired Saves, simulate restores to make 125 // If we have any lingering unpaired Saves, simulate restores to make
125 // sure all ops in those Save blocks have their bounds calculated. 126 // sure all ops in those Save blocks have their bounds calculated.
126 while (!fSaveStack.isEmpty()) { 127 while (!fSaveStack.isEmpty()) {
127 this->popSaveBlock(); 128 this->popSaveBlock();
128 } 129 }
129 130
130 // Any control ops not part of any Save/Restore block draw everywhere. 131 // Any control ops not part of any Save/Restore block draw everywhere.
131 while (!fControlIndices.isEmpty()) { 132 while (!fControlIndices.isEmpty()) {
132 this->popControl(SkIRect::MakeLargest()); 133 this->popControl(SkIRect::MakeLargest());
133 } 134 }
134 135
135 // Finally feed all stored bounds into the BBH. They'll be returned in this order. 136 // Finally feed all stored bounds into the BBH. They'll be returned in this order.
136 SkASSERT(NULL != bbh); 137 SkASSERT(NULL != bbh);
137 for (uintptr_t i = 0; i < record.count(); i++) { 138 for (uintptr_t i = 0; i < record.count(); i++) {
138 if (!fBounds[i].isEmpty()) { 139 if (!fBounds[i].isEmpty()) {
139 bbh->insert((void*)i, fBounds[i], true/*ok to defer*/); 140 bbh->insert((void*)i, fBounds[i], true/*ok to defer*/);
140 } 141 }
141 } 142 }
142 bbh->flushDeferredInserts(); 143 bbh->flushDeferredInserts();
143 } 144 }
144 145
145 template <typename T> void operator()(const T& r) { 146 template <typename T> void operator()(const T& r) {
147 this->updateCTM(r);
146 this->trackBounds(r); 148 this->trackBounds(r);
147 } 149 }
148 150
149 private: 151 private:
150 struct SaveBounds { 152 struct SaveBounds {
151 int controlOps; // Number of control ops in this Save block, including the Save. 153 int controlOps; // Number of control ops in this Save block, including the Save.
152 SkIRect bounds; // Bounds of everything in the block. 154 SkIRect bounds; // Bounds of everything in the block.
153 }; 155 };
154 156
157 template <typename T> void updateCTM(const T&) { /* most ops don't change th e CTM */ }
158 void updateCTM(const Restore& r) { fCTM = r.matrix; }
159 void updateCTM(const SetMatrix& r) { fCTM = r.matrix; }
160 void updateCTM(const Concat& r) { fCTM.preConcat(r.matrix); }
161
155 // The bounds of these ops must be calculated when we hit the Restore 162 // The bounds of these ops must be calculated when we hit the Restore
156 // from the bounds of the ops in the same Save block. 163 // from the bounds of the ops in the same Save block.
157 void trackBounds(const Save&) { this->pushSaveBlock(); } 164 void trackBounds(const Save&) { this->pushSaveBlock(); }
158 // TODO: bounds of SaveLayer may be more complicated? 165 // TODO: bounds of SaveLayer may be more complicated?
159 void trackBounds(const SaveLayer&) { this->pushSaveBlock(); } 166 void trackBounds(const SaveLayer&) { this->pushSaveBlock(); }
160 void trackBounds(const Restore&) { fBounds[fCurrentOp] = this->popSaveBlo ck(); } 167 void trackBounds(const Restore&) { fBounds[fCurrentOp] = this->popSaveBlo ck(); }
161 168
162 void trackBounds(const Concat&) { this->pushControl(); } 169 void trackBounds(const Concat&) { this->pushControl(); }
163 void trackBounds(const SetMatrix&) { this->pushControl(); } 170 void trackBounds(const SetMatrix&) { this->pushControl(); }
164 void trackBounds(const ClipRect&) { this->pushControl(); } 171 void trackBounds(const ClipRect&) { this->pushControl(); }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 void updateSaveBounds(const SkIRect& bounds) { 219 void updateSaveBounds(const SkIRect& bounds) {
213 // If we're in a Save block, expand its bounds to cover these bounds too . 220 // If we're in a Save block, expand its bounds to cover these bounds too .
214 if (!fSaveStack.isEmpty()) { 221 if (!fSaveStack.isEmpty()) {
215 fSaveStack.top().bounds.join(bounds); 222 fSaveStack.top().bounds.join(bounds);
216 } 223 }
217 } 224 }
218 225
219 SkIRect bounds(const NoOp&) { return SkIRect::MakeEmpty(); } // NoOps don't draw anywhere. 226 SkIRect bounds(const NoOp&) { return SkIRect::MakeEmpty(); } // NoOps don't draw anywhere.
220 227
221 SkAutoTMalloc<SkIRect> fBounds; // One for each op in the record. 228 SkAutoTMalloc<SkIRect> fBounds; // One for each op in the record.
229 SkMatrix fCTM;
222 unsigned fCurrentOp; 230 unsigned fCurrentOp;
223 SkTDArray<SaveBounds> fSaveStack; 231 SkTDArray<SaveBounds> fSaveStack;
224 SkTDArray<unsigned> fControlIndices; 232 SkTDArray<unsigned> fControlIndices;
225 }; 233 };
226 234
227 } // namespace SkRecords 235 } // namespace SkRecords
228 236
229 void SkRecordFillBounds(const SkRecord& record, SkBBoxHierarchy* bbh) { 237 void SkRecordFillBounds(const SkRecord& record, SkBBoxHierarchy* bbh) {
230 SkRecords::FillBounds(record, bbh); 238 SkRecords::FillBounds(record, bbh);
231 } 239 }
OLDNEW
« no previous file with comments | « src/core/SkCanvas.cpp ('k') | src/core/SkRecorder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698