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 | 7 |
8 #include "SkLayerInfo.h" | 8 #include "SkLayerInfo.h" |
9 #include "SkRecordDraw.h" | 9 #include "SkRecordDraw.h" |
10 #include "SkPatchUtils.h" | 10 #include "SkPatchUtils.h" |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 namespace SkRecords { | 73 namespace SkRecords { |
74 | 74 |
75 // NoOps draw nothing. | 75 // NoOps draw nothing. |
76 template <> void Draw::draw(const NoOp&) {} | 76 template <> void Draw::draw(const NoOp&) {} |
77 | 77 |
78 #define DRAW(T, call) template <> void Draw::draw(const T& r) { fCanvas->call; } | 78 #define DRAW(T, call) template <> void Draw::draw(const T& r) { fCanvas->call; } |
79 DRAW(Restore, restore()); | 79 DRAW(Restore, restore()); |
80 DRAW(Save, save()); | 80 DRAW(Save, save()); |
81 DRAW(SaveLayer, saveLayer(r.bounds, r.paint, r.flags)); | 81 DRAW(SaveLayer, saveLayer(r.bounds, r.paint, r.flags)); |
82 DRAW(SetMatrix, setMatrix(SkMatrix::Concat(fInitialCTM, r.matrix))); | 82 DRAW(SetMatrix, setMatrix(SkMatrix::Concat(fInitialCTM, r.matrix))); |
| 83 DRAW(Concat, concat(r.matrix)); |
83 | 84 |
84 DRAW(ClipPath, clipPath(r.path, r.opAA.op, r.opAA.aa)); | 85 DRAW(ClipPath, clipPath(r.path, r.opAA.op, r.opAA.aa)); |
85 DRAW(ClipRRect, clipRRect(r.rrect, r.opAA.op, r.opAA.aa)); | 86 DRAW(ClipRRect, clipRRect(r.rrect, r.opAA.op, r.opAA.aa)); |
86 DRAW(ClipRect, clipRect(r.rect, r.opAA.op, r.opAA.aa)); | 87 DRAW(ClipRect, clipRect(r.rect, r.opAA.op, r.opAA.aa)); |
87 DRAW(ClipRegion, clipRegion(r.region, r.op)); | 88 DRAW(ClipRegion, clipRegion(r.region, r.op)); |
88 | 89 |
89 DRAW(DrawBitmap, drawBitmap(r.bitmap.shallowCopy(), r.left, r.top, r.paint)); | 90 DRAW(DrawBitmap, drawBitmap(r.bitmap.shallowCopy(), r.left, r.top, r.paint)); |
90 DRAW(DrawBitmapNine, drawBitmapNine(r.bitmap.shallowCopy(), r.center, r.dst, r.p
aint)); | 91 DRAW(DrawBitmapNine, drawBitmapNine(r.bitmap.shallowCopy(), r.center, r.dst, r.p
aint)); |
91 DRAW(DrawBitmapRect, | 92 DRAW(DrawBitmapRect, |
92 legacy_drawBitmapRect(r.bitmap.shallowCopy(), r.src, r.dst, r.paint, | 93 legacy_drawBitmapRect(r.bitmap.shallowCopy(), r.src, r.dst, r.paint, |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 // inside the Save/Restore block, drawing ops are unioned with the bounds of | 148 // inside the Save/Restore block, drawing ops are unioned with the bounds of |
148 // the block, and control ops are stashed away for later. When we finish the | 149 // the block, and control ops are stashed away for later. When we finish the |
149 // block with a Restore, our bounds are complete, and we go back and fill them | 150 // block with a Restore, our bounds are complete, and we go back and fill them |
150 // in for all the control ops we stashed away. | 151 // in for all the control ops we stashed away. |
151 class FillBounds : SkNoncopyable { | 152 class FillBounds : SkNoncopyable { |
152 public: | 153 public: |
153 FillBounds(const SkRect& cullRect, const SkRecord& record, SkRect bounds[]) | 154 FillBounds(const SkRect& cullRect, const SkRecord& record, SkRect bounds[]) |
154 : fNumRecords(record.count()) | 155 : fNumRecords(record.count()) |
155 , fCullRect(cullRect) | 156 , fCullRect(cullRect) |
156 , fBounds(bounds) { | 157 , fBounds(bounds) { |
157 fCTM = &SkMatrix::I(); | 158 fCTM = SkMatrix::I(); |
158 fCurrentClipBounds = fCullRect; | 159 fCurrentClipBounds = fCullRect; |
159 } | 160 } |
160 | 161 |
161 void cleanUp() { | 162 void cleanUp() { |
162 // If we have any lingering unpaired Saves, simulate restores to make | 163 // If we have any lingering unpaired Saves, simulate restores to make |
163 // sure all ops in those Save blocks have their bounds calculated. | 164 // sure all ops in those Save blocks have their bounds calculated. |
164 while (!fSaveStack.isEmpty()) { | 165 while (!fSaveStack.isEmpty()) { |
165 this->popSaveBlock(); | 166 this->popSaveBlock(); |
166 } | 167 } |
167 | 168 |
168 // Any control ops not part of any Save/Restore block draw everywhere. | 169 // Any control ops not part of any Save/Restore block draw everywhere. |
169 while (!fControlIndices.isEmpty()) { | 170 while (!fControlIndices.isEmpty()) { |
170 this->popControl(fCullRect); | 171 this->popControl(fCullRect); |
171 } | 172 } |
172 } | 173 } |
173 | 174 |
174 void setCurrentOp(int currentOp) { fCurrentOp = currentOp; } | 175 void setCurrentOp(int currentOp) { fCurrentOp = currentOp; } |
175 | 176 |
176 | 177 |
177 template <typename T> void operator()(const T& op) { | 178 template <typename T> void operator()(const T& op) { |
178 this->updateCTM(op); | 179 this->updateCTM(op); |
179 this->updateClipBounds(op); | 180 this->updateClipBounds(op); |
180 this->trackBounds(op); | 181 this->trackBounds(op); |
181 } | 182 } |
182 | 183 |
183 // In this file, SkRect are in local coordinates, Bounds are translated back
to identity space. | 184 // In this file, SkRect are in local coordinates, Bounds are translated back
to identity space. |
184 typedef SkRect Bounds; | 185 typedef SkRect Bounds; |
185 | 186 |
186 int currentOp() const { return fCurrentOp; } | 187 int currentOp() const { return fCurrentOp; } |
187 const SkMatrix& ctm() const { return *fCTM; } | 188 const SkMatrix& ctm() const { return fCTM; } |
188 const Bounds& getBounds(int index) const { return fBounds[index]; } | 189 const Bounds& getBounds(int index) const { return fBounds[index]; } |
189 | 190 |
190 // Adjust rect for all paints that may affect its geometry, then map it to i
dentity space. | 191 // Adjust rect for all paints that may affect its geometry, then map it to i
dentity space. |
191 Bounds adjustAndMap(SkRect rect, const SkPaint* paint) const { | 192 Bounds adjustAndMap(SkRect rect, const SkPaint* paint) const { |
192 // Inverted rectangles really confuse our BBHs. | 193 // Inverted rectangles really confuse our BBHs. |
193 rect.sort(); | 194 rect.sort(); |
194 | 195 |
195 // Adjust the rect for its own paint. | 196 // Adjust the rect for its own paint. |
196 if (!AdjustForPaint(paint, &rect)) { | 197 if (!AdjustForPaint(paint, &rect)) { |
197 // The paint could do anything to our bounds. The only safe answer
is the current clip. | 198 // The paint could do anything to our bounds. The only safe answer
is the current clip. |
198 return fCurrentClipBounds; | 199 return fCurrentClipBounds; |
199 } | 200 } |
200 | 201 |
201 // Adjust rect for all the paints from the SaveLayers we're inside. | 202 // Adjust rect for all the paints from the SaveLayers we're inside. |
202 if (!this->adjustForSaveLayerPaints(&rect)) { | 203 if (!this->adjustForSaveLayerPaints(&rect)) { |
203 // Same deal as above. | 204 // Same deal as above. |
204 return fCurrentClipBounds; | 205 return fCurrentClipBounds; |
205 } | 206 } |
206 | 207 |
207 // Map the rect back to identity space. | 208 // Map the rect back to identity space. |
208 fCTM->mapRect(&rect); | 209 fCTM.mapRect(&rect); |
209 | 210 |
210 // Nothing can draw outside the current clip. | 211 // Nothing can draw outside the current clip. |
211 if (!rect.intersect(fCurrentClipBounds)) { | 212 if (!rect.intersect(fCurrentClipBounds)) { |
212 return Bounds::MakeEmpty(); | 213 return Bounds::MakeEmpty(); |
213 } | 214 } |
214 | 215 |
215 return rect; | 216 return rect; |
216 } | 217 } |
217 | 218 |
218 private: | 219 private: |
219 struct SaveBounds { | 220 struct SaveBounds { |
220 int controlOps; // Number of control ops in this Save block, incl
uding the Save. | 221 int controlOps; // Number of control ops in this Save block, incl
uding the Save. |
221 Bounds bounds; // Bounds of everything in the block. | 222 Bounds bounds; // Bounds of everything in the block. |
222 const SkPaint* paint; // Unowned. If set, adjusts the bounds of all op
s in this block. | 223 const SkPaint* paint; // Unowned. If set, adjusts the bounds of all op
s in this block. |
223 }; | 224 }; |
224 | 225 |
225 // Only Restore and SetMatrix change the CTM. | 226 // Only Restore, SetMatrix, and Concat change the CTM. |
226 template <typename T> void updateCTM(const T&) {} | 227 template <typename T> void updateCTM(const T&) {} |
227 void updateCTM(const Restore& op) { fCTM = &op.matrix; } | 228 void updateCTM(const Restore& op) { fCTM = op.matrix; } |
228 void updateCTM(const SetMatrix& op) { fCTM = &op.matrix; } | 229 void updateCTM(const SetMatrix& op) { fCTM = op.matrix; } |
| 230 void updateCTM(const Concat& op) { fCTM.preConcat(op.matrix); } |
229 | 231 |
230 // Most ops don't change the clip. | 232 // Most ops don't change the clip. |
231 template <typename T> void updateClipBounds(const T&) {} | 233 template <typename T> void updateClipBounds(const T&) {} |
232 | 234 |
233 // Clip{Path,RRect,Rect,Region} obviously change the clip. They all know th
eir bounds already. | 235 // Clip{Path,RRect,Rect,Region} obviously change the clip. They all know th
eir bounds already. |
234 void updateClipBounds(const ClipPath& op) { this->updateClipBoundsForClipO
p(op.devBounds); } | 236 void updateClipBounds(const ClipPath& op) { this->updateClipBoundsForClipO
p(op.devBounds); } |
235 void updateClipBounds(const ClipRRect& op) { this->updateClipBoundsForClipO
p(op.devBounds); } | 237 void updateClipBounds(const ClipRRect& op) { this->updateClipBoundsForClipO
p(op.devBounds); } |
236 void updateClipBounds(const ClipRect& op) { this->updateClipBoundsForClipO
p(op.devBounds); } | 238 void updateClipBounds(const ClipRect& op) { this->updateClipBoundsForClipO
p(op.devBounds); } |
237 void updateClipBounds(const ClipRegion& op) { this->updateClipBoundsForClipO
p(op.devBounds); } | 239 void updateClipBounds(const ClipRegion& op) { this->updateClipBoundsForClipO
p(op.devBounds); } |
238 | 240 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 } | 273 } |
272 } | 274 } |
273 | 275 |
274 // The bounds of these ops must be calculated when we hit the Restore | 276 // The bounds of these ops must be calculated when we hit the Restore |
275 // from the bounds of the ops in the same Save block. | 277 // from the bounds of the ops in the same Save block. |
276 void trackBounds(const Save&) { this->pushSaveBlock(nullptr); } | 278 void trackBounds(const Save&) { this->pushSaveBlock(nullptr); } |
277 void trackBounds(const SaveLayer& op) { this->pushSaveBlock(op.paint); } | 279 void trackBounds(const SaveLayer& op) { this->pushSaveBlock(op.paint); } |
278 void trackBounds(const Restore&) { fBounds[fCurrentOp] = this->popSaveBlock(
); } | 280 void trackBounds(const Restore&) { fBounds[fCurrentOp] = this->popSaveBlock(
); } |
279 | 281 |
280 void trackBounds(const SetMatrix&) { this->pushControl(); } | 282 void trackBounds(const SetMatrix&) { this->pushControl(); } |
| 283 void trackBounds(const Concat&) { this->pushControl(); } |
281 void trackBounds(const ClipRect&) { this->pushControl(); } | 284 void trackBounds(const ClipRect&) { this->pushControl(); } |
282 void trackBounds(const ClipRRect&) { this->pushControl(); } | 285 void trackBounds(const ClipRRect&) { this->pushControl(); } |
283 void trackBounds(const ClipPath&) { this->pushControl(); } | 286 void trackBounds(const ClipPath&) { this->pushControl(); } |
284 void trackBounds(const ClipRegion&) { this->pushControl(); } | 287 void trackBounds(const ClipRegion&) { this->pushControl(); } |
285 | 288 |
286 // For all other ops, we can calculate and store the bounds directly now. | 289 // For all other ops, we can calculate and store the bounds directly now. |
287 template <typename T> void trackBounds(const T& op) { | 290 template <typename T> void trackBounds(const T& op) { |
288 fBounds[fCurrentOp] = this->bounds(op); | 291 fBounds[fCurrentOp] = this->bounds(op); |
289 this->updateSaveBounds(fBounds[fCurrentOp]); | 292 this->updateSaveBounds(fBounds[fCurrentOp]); |
290 } | 293 } |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
572 // We do not guarantee anything for operations outside of the cull rect | 575 // We do not guarantee anything for operations outside of the cull rect |
573 const SkRect fCullRect; | 576 const SkRect fCullRect; |
574 | 577 |
575 // Conservative identity-space bounds for each op in the SkRecord. | 578 // Conservative identity-space bounds for each op in the SkRecord. |
576 Bounds* fBounds; | 579 Bounds* fBounds; |
577 | 580 |
578 // We walk fCurrentOp through the SkRecord, as we go using updateCTM() | 581 // We walk fCurrentOp through the SkRecord, as we go using updateCTM() |
579 // and updateClipBounds() to maintain the exact CTM (fCTM) and conservative | 582 // and updateClipBounds() to maintain the exact CTM (fCTM) and conservative |
580 // identity-space bounds of the current clip (fCurrentClipBounds). | 583 // identity-space bounds of the current clip (fCurrentClipBounds). |
581 int fCurrentOp; | 584 int fCurrentOp; |
582 const SkMatrix* fCTM; | 585 SkMatrix fCTM; |
583 Bounds fCurrentClipBounds; | 586 Bounds fCurrentClipBounds; |
584 | 587 |
585 // Used to track the bounds of Save/Restore blocks and the control ops insid
e them. | 588 // Used to track the bounds of Save/Restore blocks and the control ops insid
e them. |
586 SkTDArray<SaveBounds> fSaveStack; | 589 SkTDArray<SaveBounds> fSaveStack; |
587 SkTDArray<int> fControlIndices; | 590 SkTDArray<int> fControlIndices; |
588 }; | 591 }; |
589 | 592 |
590 // SkRecord visitor to gather saveLayer/restore information. | 593 // SkRecord visitor to gather saveLayer/restore information. |
591 class CollectLayers : SkNoncopyable { | 594 class CollectLayers : SkNoncopyable { |
592 public: | 595 public: |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
797 void SkRecordComputeLayers(const SkRect& cullRect, const SkRecord& record, SkRec
t bounds[], | 800 void SkRecordComputeLayers(const SkRect& cullRect, const SkRecord& record, SkRec
t bounds[], |
798 const SkBigPicture::SnapshotArray* pictList, SkLayerI
nfo* data) { | 801 const SkBigPicture::SnapshotArray* pictList, SkLayerI
nfo* data) { |
799 SkRecords::CollectLayers visitor(cullRect, record, bounds, pictList, data); | 802 SkRecords::CollectLayers visitor(cullRect, record, bounds, pictList, data); |
800 for (int curOp = 0; curOp < record.count(); curOp++) { | 803 for (int curOp = 0; curOp < record.count(); curOp++) { |
801 visitor.setCurrentOp(curOp); | 804 visitor.setCurrentOp(curOp); |
802 record.visit<void>(curOp, visitor); | 805 record.visit<void>(curOp, visitor); |
803 } | 806 } |
804 visitor.cleanUp(); | 807 visitor.cleanUp(); |
805 } | 808 } |
806 | 809 |
OLD | NEW |