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

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

Issue 541593005: allow canvas to force conservative clips (for speed) (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 3 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
OLDNEW
1 /* 1 /*
2 * Copyright 2008 The Android Open Source Project 2 * Copyright 2008 The Android Open Source Project
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 8
9 #include "SkCanvas.h" 9 #include "SkCanvas.h"
10 #include "SkCanvasPriv.h" 10 #include "SkCanvasPriv.h"
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 values: they reflect the top of the save stack, but translated and clipped 74 values: they reflect the top of the save stack, but translated and clipped
75 by the device's XY offset and bitmap-bounds. 75 by the device's XY offset and bitmap-bounds.
76 */ 76 */
77 struct DeviceCM { 77 struct DeviceCM {
78 DeviceCM* fNext; 78 DeviceCM* fNext;
79 SkBaseDevice* fDevice; 79 SkBaseDevice* fDevice;
80 SkRasterClip fClip; 80 SkRasterClip fClip;
81 const SkMatrix* fMatrix; 81 const SkMatrix* fMatrix;
82 SkPaint* fPaint; // may be null (in the future) 82 SkPaint* fPaint; // may be null (in the future)
83 83
84 DeviceCM(SkBaseDevice* device, int x, int y, const SkPaint* paint, SkCanvas* canvas) 84 DeviceCM(SkBaseDevice* device, int x, int y, const SkPaint* paint, SkCanvas* canvas,
85 : fNext(NULL) { 85 bool conservativeRasterClip)
86 if (device) { 86 : fNext(NULL)
87 , fClip(conservativeRasterClip)
88 {
89 if (NULL != device) {
87 device->ref(); 90 device->ref();
88 device->onAttachToCanvas(canvas); 91 device->onAttachToCanvas(canvas);
89 } 92 }
90 fDevice = device; 93 fDevice = device;
91 fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL; 94 fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL;
92 } 95 }
93 96
94 ~DeviceCM() { 97 ~DeviceCM() {
95 if (fDevice) { 98 if (fDevice) {
96 fDevice->onDetachFromCanvas(); 99 fDevice->onDetachFromCanvas();
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 147
145 /* This is the record we keep for each save/restore level in the stack. 148 /* This is the record we keep for each save/restore level in the stack.
146 Since a level optionally copies the matrix and/or stack, we have pointers 149 Since a level optionally copies the matrix and/or stack, we have pointers
147 for these fields. If the value is copied for this level, the copy is 150 for these fields. If the value is copied for this level, the copy is
148 stored in the ...Storage field, and the pointer points to that. If the 151 stored in the ...Storage field, and the pointer points to that. If the
149 value is not copied for this level, we ignore ...Storage, and just point 152 value is not copied for this level, we ignore ...Storage, and just point
150 at the corresponding value in the previous level in the stack. 153 at the corresponding value in the previous level in the stack.
151 */ 154 */
152 class SkCanvas::MCRec { 155 class SkCanvas::MCRec {
153 public: 156 public:
157 SkRasterClip fRasterClip;
154 SkMatrix fMatrix; 158 SkMatrix fMatrix;
155 SkRasterClip fRasterClip;
156 SkDrawFilter* fFilter; // the current filter (or null) 159 SkDrawFilter* fFilter; // the current filter (or null)
157 160 DeviceCM* fLayer;
158 DeviceCM* fLayer;
159 /* If there are any layers in the stack, this points to the top-most 161 /* If there are any layers in the stack, this points to the top-most
160 one that is at or below this level in the stack (so we know what 162 one that is at or below this level in the stack (so we know what
161 bitmap/device to draw into from this level. This value is NOT 163 bitmap/device to draw into from this level. This value is NOT
162 reference counted, since the real owner is either our fLayer field, 164 reference counted, since the real owner is either our fLayer field,
163 or a previous one in a lower level.) 165 or a previous one in a lower level.)
164 */ 166 */
165 DeviceCM* fTopLayer; 167 DeviceCM* fTopLayer;
166 168
167 MCRec(const MCRec* prev) { 169 MCRec(bool conservativeRasterClip) : fRasterClip(conservativeRasterClip) {
168 if (prev) { 170 fMatrix.reset();
169 fMatrix = prev->fMatrix; 171 fFilter = NULL;
170 fRasterClip = prev->fRasterClip; 172 fLayer = NULL;
171 173 fTopLayer = NULL;
172 fFilter = prev->fFilter; 174
173 SkSafeRef(fFilter);
174
175 fTopLayer = prev->fTopLayer;
176 } else { // no prev
177 fMatrix.reset();
178 fFilter = NULL;
179 fTopLayer = NULL;
180 }
181 fLayer = NULL;
182
183 // don't bother initializing fNext 175 // don't bother initializing fNext
184 inc_rec(); 176 inc_rec();
185 } 177 }
178 MCRec(const MCRec& prev) : fRasterClip(prev.fRasterClip) {
179 fMatrix = prev.fMatrix;
180 fFilter = SkSafeRef(prev.fFilter);
181 fLayer = NULL;
182 fTopLayer = prev.fTopLayer;
183
184 // don't bother initializing fNext
185 inc_rec();
186 }
186 ~MCRec() { 187 ~MCRec() {
187 SkSafeUnref(fFilter); 188 SkSafeUnref(fFilter);
188 SkDELETE(fLayer); 189 SkDELETE(fLayer);
189 dec_rec(); 190 dec_rec();
190 } 191 }
191 }; 192 };
192 193
193 class SkDrawIter : public SkDraw { 194 class SkDrawIter : public SkDraw {
194 public: 195 public:
195 SkDrawIter(SkCanvas* canvas, bool skipEmptyClips = true) { 196 SkDrawIter(SkCanvas* canvas, bool skipEmptyClips = true) {
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 #define LOOPER_BEGIN(paint, type, bounds) \ 375 #define LOOPER_BEGIN(paint, type, bounds) \
375 this->predrawNotify(); \ 376 this->predrawNotify(); \
376 AutoDrawLooper looper(this, paint, false, bounds); \ 377 AutoDrawLooper looper(this, paint, false, bounds); \
377 while (looper.next(type)) { \ 378 while (looper.next(type)) { \
378 SkDrawIter iter(this); 379 SkDrawIter iter(this);
379 380
380 #define LOOPER_END } 381 #define LOOPER_END }
381 382
382 //////////////////////////////////////////////////////////////////////////// 383 ////////////////////////////////////////////////////////////////////////////
383 384
384 SkBaseDevice* SkCanvas::init(SkBaseDevice* device) { 385 SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) {
386 fConservativeRasterClip = SkToBool(flags & kConservativeRasterClip_InitFlag) ;
385 fCachedLocalClipBounds.setEmpty(); 387 fCachedLocalClipBounds.setEmpty();
386 fCachedLocalClipBoundsDirty = true; 388 fCachedLocalClipBoundsDirty = true;
387 fAllowSoftClip = true; 389 fAllowSoftClip = true;
388 fAllowSimplifyClip = false; 390 fAllowSimplifyClip = false;
389 fDeviceCMDirty = true; 391 fDeviceCMDirty = true;
390 fSaveLayerCount = 0; 392 fSaveLayerCount = 0;
391 fCullCount = 0; 393 fCullCount = 0;
392 fMetaData = NULL; 394 fMetaData = NULL;
393 395
396 if (device && device->forceConservativeRasterClip()) {
397 fConservativeRasterClip = true;
398 }
399
394 fMCRec = (MCRec*)fMCStack.push_back(); 400 fMCRec = (MCRec*)fMCStack.push_back();
395 new (fMCRec) MCRec(NULL); 401 new (fMCRec) MCRec(fConservativeRasterClip);
396 402
397 fMCRec->fLayer = SkNEW_ARGS(DeviceCM, (NULL, 0, 0, NULL, NULL)); 403 fMCRec->fLayer = SkNEW_ARGS(DeviceCM, (NULL, 0, 0, NULL, NULL, fConservative RasterClip));
398 fMCRec->fTopLayer = fMCRec->fLayer; 404 fMCRec->fTopLayer = fMCRec->fLayer;
399 405
400 fSurfaceBase = NULL; 406 fSurfaceBase = NULL;
401 407
402 if (device) { 408 if (device) {
403 device->onAttachToCanvas(this); 409 device->onAttachToCanvas(this);
404 fMCRec->fLayer->fDevice = SkRef(device); 410 fMCRec->fLayer->fDevice = SkRef(device);
405 fMCRec->fRasterClip.setRect(SkIRect::MakeWH(device->width(), device->hei ght())); 411 fMCRec->fRasterClip.setRect(SkIRect::MakeWH(device->width(), device->hei ght()));
406 } 412 }
407 return device; 413 return device;
408 } 414 }
409 415
410 SkCanvas::SkCanvas() 416 SkCanvas::SkCanvas()
411 : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 417 : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
412 { 418 {
413 inc_canvas(); 419 inc_canvas();
414 420
415 this->init(NULL); 421 this->init(NULL, kDefault_InitFlags);
416 } 422 }
417 423
424 static SkBitmap make_nopixels(int width, int height) {
425 SkBitmap bitmap;
426 bitmap.setInfo(SkImageInfo::MakeUnknown(width, height));
427 return bitmap;
428 }
429
430 class SkNoPixelsBitmapDevice : public SkBitmapDevice {
431 public:
432 SkNoPixelsBitmapDevice(int width, int height) : INHERITED(make_nopixels(widt h, height)) {}
433
434 private:
435
436 typedef SkBitmapDevice INHERITED;
437 };
438
418 SkCanvas::SkCanvas(int width, int height) 439 SkCanvas::SkCanvas(int width, int height)
419 : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 440 : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
420 { 441 {
421 inc_canvas(); 442 inc_canvas();
443
444 this->init(SkNEW_ARGS(SkNoPixelsBitmapDevice, (width, height)), kDefault_Ini tFlags)->unref();
445 }
422 446
423 SkBitmap bitmap; 447 SkCanvas::SkCanvas(int width, int height, InitFlags flags)
424 bitmap.setInfo(SkImageInfo::MakeUnknown(width, height)); 448 : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
425 this->init(SkNEW_ARGS(SkBitmapDevice, (bitmap)))->unref(); 449 {
450 inc_canvas();
451
452 this->init(SkNEW_ARGS(SkNoPixelsBitmapDevice, (width, height)), flags)->unre f();
453 }
454
455 SkCanvas::SkCanvas(SkBaseDevice* device, InitFlags flags)
456 : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
457 {
458 inc_canvas();
459
460 this->init(device, flags);
426 } 461 }
427 462
428 SkCanvas::SkCanvas(SkBaseDevice* device) 463 SkCanvas::SkCanvas(SkBaseDevice* device)
429 : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 464 : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
430 { 465 {
431 inc_canvas(); 466 inc_canvas();
432 467
433 this->init(device); 468 this->init(device, kDefault_InitFlags);
434 } 469 }
435 470
436 SkCanvas::SkCanvas(const SkBitmap& bitmap) 471 SkCanvas::SkCanvas(const SkBitmap& bitmap)
437 : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 472 : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
438 { 473 {
439 inc_canvas(); 474 inc_canvas();
440 475
441 this->init(SkNEW_ARGS(SkBitmapDevice, (bitmap)))->unref(); 476 this->init(SkNEW_ARGS(SkBitmapDevice, (bitmap)), kDefault_InitFlags)->unref( );
442 } 477 }
443 478
444 SkCanvas::~SkCanvas() { 479 SkCanvas::~SkCanvas() {
445 // free up the contents of our deque 480 // free up the contents of our deque
446 this->restoreToCount(1); // restore everything but the last 481 this->restoreToCount(1); // restore everything but the last
447 SkASSERT(0 == fSaveLayerCount); 482 SkASSERT(0 == fSaveLayerCount);
448 483
449 this->internalRestore(); // restore the last, since we're going away 484 this->internalRestore(); // restore the last, since we're going away
450 485
451 SkDELETE(fMetaData); 486 SkDELETE(fMetaData);
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 fDeviceCMDirty = false; 762 fDeviceCMDirty = false;
728 } 763 }
729 } 764 }
730 765
731 /////////////////////////////////////////////////////////////////////////////// 766 ///////////////////////////////////////////////////////////////////////////////
732 767
733 int SkCanvas::internalSave() { 768 int SkCanvas::internalSave() {
734 int saveCount = this->getSaveCount(); // record this before the actual save 769 int saveCount = this->getSaveCount(); // record this before the actual save
735 770
736 MCRec* newTop = (MCRec*)fMCStack.push_back(); 771 MCRec* newTop = (MCRec*)fMCStack.push_back();
737 new (newTop) MCRec(fMCRec); // balanced in restore() 772 new (newTop) MCRec(*fMCRec); // balanced in restore()
738 fMCRec = newTop; 773 fMCRec = newTop;
739 774
740 fClipStack.save(); 775 fClipStack.save();
741 776
742 return saveCount; 777 return saveCount;
743 } 778 }
744 779
745 int SkCanvas::save() { 780 int SkCanvas::save() {
746 this->willSave(); 781 this->willSave();
747 return this->internalSave(); 782 return this->internalSave();
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
859 } 894 }
860 } else { 895 } else {
861 device = this->createLayerDevice(info); 896 device = this->createLayerDevice(info);
862 } 897 }
863 if (NULL == device) { 898 if (NULL == device) {
864 SkDebugf("Unable to create device for layer."); 899 SkDebugf("Unable to create device for layer.");
865 return count; 900 return count;
866 } 901 }
867 902
868 device->setOrigin(ir.fLeft, ir.fTop); 903 device->setOrigin(ir.fLeft, ir.fTop);
869 DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, ir.fLeft, ir.fTop, paint, th is)); 904 DeviceCM* layer = SkNEW_ARGS(DeviceCM,
905 (device, ir.fLeft, ir.fTop, paint, this, fConse rvativeRasterClip));
870 device->unref(); 906 device->unref();
871 907
872 layer->fNext = fMCRec->fTopLayer; 908 layer->fNext = fMCRec->fTopLayer;
873 fMCRec->fLayer = layer; 909 fMCRec->fLayer = layer;
874 fMCRec->fTopLayer = layer; // this field is NOT an owner of layer 910 fMCRec->fTopLayer = layer; // this field is NOT an owner of layer
875 911
876 fSaveLayerCount += 1; 912 fSaveLayerCount += 1;
877 return count; 913 return count;
878 } 914 }
879 915
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after
1279 1315
1280 if (fMCRec->fMatrix.rectStaysRect()) { 1316 if (fMCRec->fMatrix.rectStaysRect()) {
1281 // for these simpler matrices, we can stay a rect even after applying 1317 // for these simpler matrices, we can stay a rect even after applying
1282 // the matrix. This means we don't have to a) make a path, and b) tell 1318 // the matrix. This means we don't have to a) make a path, and b) tell
1283 // the region code to scan-convert the path, only to discover that it 1319 // the region code to scan-convert the path, only to discover that it
1284 // is really just a rect. 1320 // is really just a rect.
1285 SkRect r; 1321 SkRect r;
1286 1322
1287 fMCRec->fMatrix.mapRect(&r, rect); 1323 fMCRec->fMatrix.mapRect(&r, rect);
1288 fClipStack.clipDevRect(r, op, kSoft_ClipEdgeStyle == edgeStyle); 1324 fClipStack.clipDevRect(r, op, kSoft_ClipEdgeStyle == edgeStyle);
1289 fMCRec->fRasterClip.op(r, op, kSoft_ClipEdgeStyle == edgeStyle); 1325 fMCRec->fRasterClip.op(r, this->getBaseLayerSize(), op, kSoft_ClipEdgeSt yle == edgeStyle);
1290 } else { 1326 } else {
1291 // since we're rotated or some such thing, we convert the rect to a path 1327 // since we're rotated or some such thing, we convert the rect to a path
1292 // and clip against that, since it can handle any matrix. However, to 1328 // and clip against that, since it can handle any matrix. However, to
1293 // avoid recursion in the case where we are subclassed (e.g. Pictures) 1329 // avoid recursion in the case where we are subclassed (e.g. Pictures)
1294 // we explicitly call "our" version of clipPath. 1330 // we explicitly call "our" version of clipPath.
1295 SkPath path; 1331 SkPath path;
1296 1332
1297 path.addRect(rect); 1333 path.addRect(rect);
1298 this->SkCanvas::onClipPath(path, op, edgeStyle); 1334 this->SkCanvas::onClipPath(path, op, edgeStyle);
1299 } 1335 }
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1414 if (element->isAA()) { 1450 if (element->isAA()) {
1415 edgeStyle = kSoft_ClipEdgeStyle; 1451 edgeStyle = kSoft_ClipEdgeStyle;
1416 } 1452 }
1417 } 1453 }
1418 op = SkRegion::kReplace_Op; 1454 op = SkRegion::kReplace_Op;
1419 } 1455 }
1420 1456
1421 rasterclip_path(&fMCRec->fRasterClip, this, devPath, op, edgeStyle); 1457 rasterclip_path(&fMCRec->fRasterClip, this, devPath, op, edgeStyle);
1422 } 1458 }
1423 1459
1424 void SkCanvas::updateClipConservativelyUsingBounds(const SkRect& bounds, SkRegio n::Op op,
1425 bool inverseFilled) {
1426 // This is for updating the clip conservatively using only bounds
1427 // information.
1428 // Contract:
1429 // The current clip must contain the true clip. The true
1430 // clip is the clip that would have normally been computed
1431 // by calls to clipPath and clipRRect
1432 // Objective:
1433 // Keep the current clip as small as possible without
1434 // breaking the contract, using only clip bounding rectangles
1435 // (for performance).
1436
1437 // N.B.: This *never* calls back through a virtual on canvas, so subclasses
1438 // don't have to worry about getting caught in a loop. Thus anywhere
1439 // we call a virtual method, we explicitly prefix it with
1440 // SkCanvas:: to be sure to call the base-class.
1441
1442 if (inverseFilled) {
1443 switch (op) {
1444 case SkRegion::kIntersect_Op:
1445 case SkRegion::kDifference_Op:
1446 // These ops can only shrink the current clip. So leaving
1447 // the clip unchanged conservatively respects the contract.
1448 break;
1449 case SkRegion::kUnion_Op:
1450 case SkRegion::kReplace_Op:
1451 case SkRegion::kReverseDifference_Op:
1452 case SkRegion::kXOR_Op: {
1453 // These ops can grow the current clip up to the extents of
1454 // the input clip, which is inverse filled, so we just set
1455 // the current clip to the device bounds.
1456 SkRect deviceBounds;
1457 SkIRect deviceIBounds;
1458 this->getDevice()->getGlobalBounds(&deviceIBounds);
1459 deviceBounds = SkRect::Make(deviceIBounds);
1460
1461 // set the clip in device space
1462 SkMatrix savedMatrix = this->getTotalMatrix();
1463 this->SkCanvas::setMatrix(SkMatrix::I());
1464 this->SkCanvas::onClipRect(deviceBounds, SkRegion::kReplace_ Op,
1465 kHard_ClipEdgeStyle);
1466 this->setMatrix(savedMatrix);
1467 break;
1468 }
1469 default:
1470 SkASSERT(0); // unhandled op?
1471 }
1472 } else {
1473 // Not inverse filled
1474 switch (op) {
1475 case SkRegion::kIntersect_Op:
1476 case SkRegion::kUnion_Op:
1477 case SkRegion::kReplace_Op:
1478 this->SkCanvas::onClipRect(bounds, op, kHard_ClipEdgeStyle);
1479 break;
1480 case SkRegion::kDifference_Op:
1481 // Difference can only shrink the current clip.
1482 // Leaving clip unchanged conservatively fullfills the contract.
1483 break;
1484 case SkRegion::kReverseDifference_Op:
1485 // To reverse, we swap in the bounds with a replace op.
1486 // As with difference, leave it unchanged.
1487 this->SkCanvas::onClipRect(bounds, SkRegion::kReplace_Op, kHard_ ClipEdgeStyle);
1488 break;
1489 case SkRegion::kXOR_Op:
1490 // Be conservative, based on (A XOR B) always included in (A uni on B),
1491 // which is always included in (bounds(A) union bounds(B))
1492 this->SkCanvas::onClipRect(bounds, SkRegion::kUnion_Op, kHard_Cl ipEdgeStyle);
1493 break;
1494 default:
1495 SkASSERT(0); // unhandled op?
1496 }
1497 }
1498 }
1499
1500 void SkCanvas::clipRegion(const SkRegion& rgn, SkRegion::Op op) { 1460 void SkCanvas::clipRegion(const SkRegion& rgn, SkRegion::Op op) {
1501 this->onClipRegion(rgn, op); 1461 this->onClipRegion(rgn, op);
1502 } 1462 }
1503 1463
1504 void SkCanvas::onClipRegion(const SkRegion& rgn, SkRegion::Op op) { 1464 void SkCanvas::onClipRegion(const SkRegion& rgn, SkRegion::Op op) {
1505 AutoValidateClip avc(this); 1465 AutoValidateClip avc(this);
1506 1466
1507 fDeviceCMDirty = true; 1467 fDeviceCMDirty = true;
1508 fCachedLocalClipBoundsDirty = true; 1468 fCachedLocalClipBoundsDirty = true;
1509 1469
1510 // todo: signal fClipStack that we have a region, and therefore (I guess) 1470 // todo: signal fClipStack that we have a region, and therefore (I guess)
1511 // we have to ignore it, and use the region directly? 1471 // we have to ignore it, and use the region directly?
1512 fClipStack.clipDevRect(rgn.getBounds(), op); 1472 fClipStack.clipDevRect(rgn.getBounds(), op);
1513 1473
1514 fMCRec->fRasterClip.op(rgn, op); 1474 fMCRec->fRasterClip.op(rgn, op);
1515 } 1475 }
1516 1476
1517 #ifdef SK_DEBUG 1477 #ifdef SK_DEBUG
1518 void SkCanvas::validateClip() const { 1478 void SkCanvas::validateClip() const {
1519 // construct clipRgn from the clipstack 1479 // construct clipRgn from the clipstack
1520 const SkBaseDevice* device = this->getDevice(); 1480 const SkBaseDevice* device = this->getDevice();
1521 if (!device) { 1481 if (!device) {
1522 SkASSERT(this->isClipEmpty()); 1482 SkASSERT(this->isClipEmpty());
1523 return; 1483 return;
1524 } 1484 }
1525 1485
1526 SkIRect ir; 1486 SkIRect ir;
1527 ir.set(0, 0, device->width(), device->height()); 1487 ir.set(0, 0, device->width(), device->height());
1528 SkRasterClip tmpClip(ir); 1488 SkRasterClip tmpClip(ir, fConservativeRasterClip);
1529 1489
1530 SkClipStack::B2TIter iter(fClipStack); 1490 SkClipStack::B2TIter iter(fClipStack);
1531 const SkClipStack::Element* element; 1491 const SkClipStack::Element* element;
1532 while ((element = iter.next()) != NULL) { 1492 while ((element = iter.next()) != NULL) {
1533 switch (element->getType()) { 1493 switch (element->getType()) {
1534 case SkClipStack::Element::kRect_Type: 1494 case SkClipStack::Element::kRect_Type:
1535 element->getRect().round(&ir); 1495 element->getRect().round(&ir);
1536 tmpClip.op(ir, element->getOp()); 1496 tmpClip.op(ir, element->getOp());
1537 break; 1497 break;
1538 case SkClipStack::Element::kEmpty_Type: 1498 case SkClipStack::Element::kEmpty_Type:
(...skipping 23 matching lines...) Expand all
1562 1522
1563 bool SkCanvas::isClipEmpty() const { 1523 bool SkCanvas::isClipEmpty() const {
1564 return fMCRec->fRasterClip.isEmpty(); 1524 return fMCRec->fRasterClip.isEmpty();
1565 } 1525 }
1566 1526
1567 bool SkCanvas::isClipRect() const { 1527 bool SkCanvas::isClipRect() const {
1568 return fMCRec->fRasterClip.isRect(); 1528 return fMCRec->fRasterClip.isRect();
1569 } 1529 }
1570 1530
1571 bool SkCanvas::quickReject(const SkRect& rect) const { 1531 bool SkCanvas::quickReject(const SkRect& rect) const {
1572
1573 if (!rect.isFinite()) 1532 if (!rect.isFinite())
1574 return true; 1533 return true;
1575 1534
1576 if (fMCRec->fRasterClip.isEmpty()) { 1535 if (fMCRec->fRasterClip.isEmpty()) {
1577 return true; 1536 return true;
1578 } 1537 }
1579 1538
1580 if (fMCRec->fMatrix.hasPerspective()) { 1539 if (fMCRec->fMatrix.hasPerspective()) {
1581 SkRect dst; 1540 SkRect dst;
1582 fMCRec->fMatrix.mapRect(&dst, rect); 1541 fMCRec->fMatrix.mapRect(&dst, rect);
(...skipping 949 matching lines...) Expand 10 before | Expand all | Expand 10 after
2532 } 2491 }
2533 2492
2534 if (matrix) { 2493 if (matrix) {
2535 canvas->concat(*matrix); 2494 canvas->concat(*matrix);
2536 } 2495 }
2537 } 2496 }
2538 2497
2539 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { 2498 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() {
2540 fCanvas->restoreToCount(fSaveCount); 2499 fCanvas->restoreToCount(fSaveCount);
2541 } 2500 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698