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

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

Issue 617403002: Merge to M39: Don't adjust the bounds after a restore with the restore's paired saveLayer's paint. (Closed) Base URL: https://skia.googlesource.com/skia.git@m39
Patch Set: Created 6 years, 2 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 | « no previous file | tests/RecordDrawTest.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 7
8 #include "SkRecordDraw.h" 8 #include "SkRecordDraw.h"
9 #include "SkPatchUtils.h" 9 #include "SkPatchUtils.h"
10 #include "SkTLogic.h"
11 10
12 void SkRecordDraw(const SkRecord& record, 11 void SkRecordDraw(const SkRecord& record,
13 SkCanvas* canvas, 12 SkCanvas* canvas,
14 const SkBBoxHierarchy* bbh, 13 const SkBBoxHierarchy* bbh,
15 SkDrawPictureCallback* callback) { 14 SkDrawPictureCallback* callback) {
16 SkAutoCanvasRestore saveRestore(canvas, true /*save now, restore at exit*/); 15 SkAutoCanvasRestore saveRestore(canvas, true /*save now, restore at exit*/);
17 16
18 if (bbh) { 17 if (bbh) {
19 // Draw only ops that affect pixels in the canvas's current clip. 18 // Draw only ops that affect pixels in the canvas's current clip.
20 // The SkRecord and BBH were recorded in identity space. This canvas 19 // The SkRecord and BBH were recorded in identity space. This canvas
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 private: 173 private:
175 // In this file, SkRect are in local coordinates, Bounds are translated back to identity space. 174 // In this file, SkRect are in local coordinates, Bounds are translated back to identity space.
176 typedef SkRect Bounds; 175 typedef SkRect Bounds;
177 176
178 struct SaveBounds { 177 struct SaveBounds {
179 int controlOps; // Number of control ops in this Save block, incl uding the Save. 178 int controlOps; // Number of control ops in this Save block, incl uding the Save.
180 Bounds bounds; // Bounds of everything in the block. 179 Bounds bounds; // Bounds of everything in the block.
181 const SkPaint* paint; // Unowned. If set, adjusts the bounds of all op s in this block. 180 const SkPaint* paint; // Unowned. If set, adjusts the bounds of all op s in this block.
182 }; 181 };
183 182
184 template <typename T> void updateCTM(const T&) { /* most ops don't change th e CTM */ } 183 // Only Restore and SetMatrix change the CTM.
184 template <typename T> void updateCTM(const T&) {}
185 void updateCTM(const Restore& op) { fCTM = &op.matrix; } 185 void updateCTM(const Restore& op) { fCTM = &op.matrix; }
186 void updateCTM(const SetMatrix& op) { fCTM = &op.matrix; } 186 void updateCTM(const SetMatrix& op) { fCTM = &op.matrix; }
187 187
188 // Most ops don't change the clip. Those that do generally have a field nam ed devBounds. 188 // Most ops don't change the clip.
189 SK_CREATE_MEMBER_DETECTOR(devBounds); 189 template <typename T> void updateClipBounds(const T&) {}
190 190
191 template <typename T> 191 // Clip{Path,RRect,Rect,Region} obviously change the clip. They all know th eir bounds already.
192 SK_WHEN(!HasMember_devBounds<T>, void) updateClipBounds(const T& op) {} 192 void updateClipBounds(const ClipPath& op) { this->updateClipBoundsForClipO p(op.devBounds); }
193 void updateClipBounds(const ClipRRect& op) { this->updateClipBoundsForClipO p(op.devBounds); }
194 void updateClipBounds(const ClipRect& op) { this->updateClipBoundsForClipO p(op.devBounds); }
195 void updateClipBounds(const ClipRegion& op) { this->updateClipBoundsForClipO p(op.devBounds); }
193 196
194 // Each of the devBounds fields holds the state of the device bounds after t he op. 197 // The bounds of clip ops need to be adjusted for the paints of saveLayers t hey're inside.
195 // (So Restore's devBounds are those bounds saved by its paired Save or Save Layer.) 198 void updateClipBoundsForClipOp(const SkIRect& devBounds) {
196 template <typename T> 199 Bounds clip = SkRect::Make(devBounds);
197 SK_WHEN(HasMember_devBounds<T>, void) updateClipBounds(const T& op) {
198 Bounds clip = SkRect::Make(op.devBounds);
199 // We don't call adjustAndMap() because as its last step it would inters ect the adjusted 200 // We don't call adjustAndMap() because as its last step it would inters ect the adjusted
200 // clip bounds with the previous clip, exactly what we can't do when the clip grows. 201 // clip bounds with the previous clip, exactly what we can't do when the clip grows.
201 fCurrentClipBounds = this->adjustForSaveLayerPaints(&clip) ? clip : Boun ds::MakeLargest(); 202 fCurrentClipBounds = this->adjustForSaveLayerPaints(&clip) ? clip : Boun ds::MakeLargest();
202 } 203 }
203 204
205 // Restore holds the devBounds for the clip after the {save,saveLayer}/resto re block completes.
206 void updateClipBounds(const Restore& op) {
207 // This is just like the clip ops above, but we need to skip the effects (if any) of our
208 // paired saveLayer (if it is one); it has not yet been popped off the s ave stack. Our
209 // devBounds reflect the state of the world after the saveLayer/restore block is done,
210 // so they are not affected by the saveLayer's paint.
211 const int kSavesToIgnore = 1;
212 Bounds clip = SkRect::Make(op.devBounds);
213 fCurrentClipBounds =
214 this->adjustForSaveLayerPaints(&clip, kSavesToIgnore) ? clip : Bound s::MakeLargest();
215 }
216
204 // We also take advantage of SaveLayer bounds when present to further cut th e clip down. 217 // We also take advantage of SaveLayer bounds when present to further cut th e clip down.
205 void updateClipBounds(const SaveLayer& op) { 218 void updateClipBounds(const SaveLayer& op) {
206 if (op.bounds) { 219 if (op.bounds) {
207 // adjustAndMap() intersects these layer bounds with the previous cl ip for us. 220 // adjustAndMap() intersects these layer bounds with the previous cl ip for us.
208 fCurrentClipBounds = this->adjustAndMap(*op.bounds, op.paint); 221 fCurrentClipBounds = this->adjustAndMap(*op.bounds, op.paint);
209 } 222 }
210 } 223 }
211 224
212 // The bounds of these ops must be calculated when we hit the Restore 225 // The bounds of these ops must be calculated when we hit the Restore
213 // from the bounds of the ops in the same Save block. 226 // from the bounds of the ops in the same Save block.
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 if (paint) { 484 if (paint) {
472 if (paint->canComputeFastBounds()) { 485 if (paint->canComputeFastBounds()) {
473 *rect = paint->computeFastBounds(*rect, rect); 486 *rect = paint->computeFastBounds(*rect, rect);
474 return true; 487 return true;
475 } 488 }
476 return false; 489 return false;
477 } 490 }
478 return true; 491 return true;
479 } 492 }
480 493
481 bool adjustForSaveLayerPaints(SkRect* rect) const { 494 bool adjustForSaveLayerPaints(SkRect* rect, int savesToIgnore = 0) const {
482 for (int i = fSaveStack.count() - 1; i >= 0; i--) { 495 for (int i = fSaveStack.count() - 1 - savesToIgnore; i >= 0; i--) {
483 if (!AdjustForPaint(fSaveStack[i].paint, rect)) { 496 if (!AdjustForPaint(fSaveStack[i].paint, rect)) {
484 return false; 497 return false;
485 } 498 }
486 } 499 }
487 return true; 500 return true;
488 } 501 }
489 502
490 // Adjust rect for all paints that may affect its geometry, then map it to i dentity space. 503 // Adjust rect for all paints that may affect its geometry, then map it to i dentity space.
491 Bounds adjustAndMap(SkRect rect, const SkPaint* paint) const { 504 Bounds adjustAndMap(SkRect rect, const SkPaint* paint) const {
492 // Inverted rectangles really confuse our BBHs. 505 // Inverted rectangles really confuse our BBHs.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 // Used to track the bounds of Save/Restore blocks and the control ops insid e them. 539 // Used to track the bounds of Save/Restore blocks and the control ops insid e them.
527 SkTDArray<SaveBounds> fSaveStack; 540 SkTDArray<SaveBounds> fSaveStack;
528 SkTDArray<unsigned> fControlIndices; 541 SkTDArray<unsigned> fControlIndices;
529 }; 542 };
530 543
531 } // namespace SkRecords 544 } // namespace SkRecords
532 545
533 void SkRecordFillBounds(const SkRecord& record, SkBBoxHierarchy* bbh) { 546 void SkRecordFillBounds(const SkRecord& record, SkBBoxHierarchy* bbh) {
534 SkRecords::FillBounds(record, bbh); 547 SkRecords::FillBounds(record, bbh);
535 } 548 }
OLDNEW
« no previous file with comments | « no previous file | tests/RecordDrawTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698