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

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

Issue 364193005: with no save flag options, we can directly reference matrix and clip in MCRec (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 5 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 | no next file » | 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 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 "SkBitmapDevice.h" 10 #include "SkBitmapDevice.h"
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 182
183 /* This is the record we keep for each save/restore level in the stack. 183 /* This is the record we keep for each save/restore level in the stack.
184 Since a level optionally copies the matrix and/or stack, we have pointers 184 Since a level optionally copies the matrix and/or stack, we have pointers
185 for these fields. If the value is copied for this level, the copy is 185 for these fields. If the value is copied for this level, the copy is
186 stored in the ...Storage field, and the pointer points to that. If the 186 stored in the ...Storage field, and the pointer points to that. If the
187 value is not copied for this level, we ignore ...Storage, and just point 187 value is not copied for this level, we ignore ...Storage, and just point
188 at the corresponding value in the previous level in the stack. 188 at the corresponding value in the previous level in the stack.
189 */ 189 */
190 class SkCanvas::MCRec { 190 class SkCanvas::MCRec {
191 public: 191 public:
192 SkMatrix* fMatrix; // points to either fMatrixStorage or prev M CRec 192 SkMatrix fMatrix;
193 SkRasterClip* fRasterClip; // points to either fRegionStorage or prev M CRec 193 SkRasterClip fRasterClip;
194 SkDrawFilter* fFilter; // the current filter (or null) 194 SkDrawFilter* fFilter; // the current filter (or null)
195 195
196 DeviceCM* fLayer; 196 DeviceCM* fLayer;
197 /* If there are any layers in the stack, this points to the top-most 197 /* If there are any layers in the stack, this points to the top-most
198 one that is at or below this level in the stack (so we know what 198 one that is at or below this level in the stack (so we know what
199 bitmap/device to draw into from this level. This value is NOT 199 bitmap/device to draw into from this level. This value is NOT
200 reference counted, since the real owner is either our fLayer field, 200 reference counted, since the real owner is either our fLayer field,
201 or a previous one in a lower level.) 201 or a previous one in a lower level.)
202 */ 202 */
203 DeviceCM* fTopLayer; 203 DeviceCM* fTopLayer;
204 204
205 MCRec(const MCRec* prev) { 205 MCRec(const MCRec* prev) {
206 if (NULL != prev) { 206 if (NULL != prev) {
207 fMatrixStorage = *prev->fMatrix; 207 fMatrix = prev->fMatrix;
208 fMatrix = &fMatrixStorage; 208 fRasterClip = prev->fRasterClip;
209
210 fRasterClipStorage = *prev->fRasterClip;
211 fRasterClip = &fRasterClipStorage;
212 209
213 fFilter = prev->fFilter; 210 fFilter = prev->fFilter;
214 SkSafeRef(fFilter); 211 SkSafeRef(fFilter);
215 212
216 fTopLayer = prev->fTopLayer; 213 fTopLayer = prev->fTopLayer;
217 } else { // no prev 214 } else { // no prev
218 fMatrixStorage.reset(); 215 fMatrix.reset();
219
220 fMatrix = &fMatrixStorage;
221 fRasterClip = &fRasterClipStorage;
222 fFilter = NULL; 216 fFilter = NULL;
223 fTopLayer = NULL; 217 fTopLayer = NULL;
224 } 218 }
225 fLayer = NULL; 219 fLayer = NULL;
226 220
227 // don't bother initializing fNext 221 // don't bother initializing fNext
228 inc_rec(); 222 inc_rec();
229 } 223 }
230 ~MCRec() { 224 ~MCRec() {
231 SkSafeUnref(fFilter); 225 SkSafeUnref(fFilter);
232 SkDELETE(fLayer); 226 SkDELETE(fLayer);
233 dec_rec(); 227 dec_rec();
234 } 228 }
235
236 private:
237 SkMatrix fMatrixStorage;
238 SkRasterClip fRasterClipStorage;
239 }; 229 };
240 230
241 class SkDrawIter : public SkDraw { 231 class SkDrawIter : public SkDraw {
242 public: 232 public:
243 SkDrawIter(SkCanvas* canvas, bool skipEmptyClips = true) { 233 SkDrawIter(SkCanvas* canvas, bool skipEmptyClips = true) {
244 canvas = canvas->canvasForDrawIter(); 234 canvas = canvas->canvasForDrawIter();
245 fCanvas = canvas; 235 fCanvas = canvas;
246 canvas->updateDeviceCMCache(); 236 canvas->updateDeviceCMCache();
247 237
248 fClipStack = &canvas->fClipStack; 238 fClipStack = &canvas->fClipStack;
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
589 accurately take advantage of the new device bounds. 579 accurately take advantage of the new device bounds.
590 */ 580 */
591 581
592 SkIRect bounds; 582 SkIRect bounds;
593 if (device) { 583 if (device) {
594 bounds.set(0, 0, device->width(), device->height()); 584 bounds.set(0, 0, device->width(), device->height());
595 } else { 585 } else {
596 bounds.setEmpty(); 586 bounds.setEmpty();
597 } 587 }
598 // now jam our 1st clip to be bounds, and intersect the rest with that 588 // now jam our 1st clip to be bounds, and intersect the rest with that
599 rec->fRasterClip->setRect(bounds); 589 rec->fRasterClip.setRect(bounds);
600 while ((rec = (MCRec*)iter.next()) != NULL) { 590 while ((rec = (MCRec*)iter.next()) != NULL) {
601 (void)rec->fRasterClip->op(bounds, SkRegion::kIntersect_Op); 591 (void)rec->fRasterClip.op(bounds, SkRegion::kIntersect_Op);
602 } 592 }
603 593
604 return device; 594 return device;
605 } 595 }
606 596
607 bool SkCanvas::readPixels(SkBitmap* bitmap, int x, int y) { 597 bool SkCanvas::readPixels(SkBitmap* bitmap, int x, int y) {
608 if (kUnknown_SkColorType == bitmap->colorType() || bitmap->getTexture()) { 598 if (kUnknown_SkColorType == bitmap->colorType() || bitmap->getTexture()) {
609 return false; 599 return false;
610 } 600 }
611 601
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
753 743
754 SkCanvas* SkCanvas::canvasForDrawIter() { 744 SkCanvas* SkCanvas::canvasForDrawIter() {
755 return this; 745 return this;
756 } 746 }
757 747
758 ////////////////////////////////////////////////////////////////////////////// 748 //////////////////////////////////////////////////////////////////////////////
759 749
760 void SkCanvas::updateDeviceCMCache() { 750 void SkCanvas::updateDeviceCMCache() {
761 if (fDeviceCMDirty) { 751 if (fDeviceCMDirty) {
762 const SkMatrix& totalMatrix = this->getTotalMatrix(); 752 const SkMatrix& totalMatrix = this->getTotalMatrix();
763 const SkRasterClip& totalClip = *fMCRec->fRasterClip; 753 const SkRasterClip& totalClip = fMCRec->fRasterClip;
764 DeviceCM* layer = fMCRec->fTopLayer; 754 DeviceCM* layer = fMCRec->fTopLayer;
765 755
766 if (NULL == layer->fNext) { // only one layer 756 if (NULL == layer->fNext) { // only one layer
767 layer->updateMC(totalMatrix, totalClip, fClipStack, NULL); 757 layer->updateMC(totalMatrix, totalClip, fClipStack, NULL);
768 } else { 758 } else {
769 SkRasterClip clip(totalClip); 759 SkRasterClip clip(totalClip);
770 do { 760 do {
771 layer->updateMC(totalMatrix, clip, fClipStack, &clip); 761 layer->updateMC(totalMatrix, clip, fClipStack, &clip);
772 } while ((layer = layer->fNext) != NULL); 762 } while ((layer = layer->fNext) != NULL);
773 } 763 }
(...skipping 30 matching lines...) Expand all
804 794
805 bool SkCanvas::clipRectBounds(const SkRect* bounds, SaveFlags flags, 795 bool SkCanvas::clipRectBounds(const SkRect* bounds, SaveFlags flags,
806 SkIRect* intersection, const SkImageFilter* image Filter) { 796 SkIRect* intersection, const SkImageFilter* image Filter) {
807 SkIRect clipBounds; 797 SkIRect clipBounds;
808 SkRegion::Op op = SkRegion::kIntersect_Op; 798 SkRegion::Op op = SkRegion::kIntersect_Op;
809 if (!this->getClipDeviceBounds(&clipBounds)) { 799 if (!this->getClipDeviceBounds(&clipBounds)) {
810 return false; 800 return false;
811 } 801 }
812 802
813 if (imageFilter) { 803 if (imageFilter) {
814 imageFilter->filterBounds(clipBounds, *fMCRec->fMatrix, &clipBounds); 804 imageFilter->filterBounds(clipBounds, fMCRec->fMatrix, &clipBounds);
815 // Filters may grow the bounds beyond the device bounds. 805 // Filters may grow the bounds beyond the device bounds.
816 op = SkRegion::kReplace_Op; 806 op = SkRegion::kReplace_Op;
817 } 807 }
818 SkIRect ir; 808 SkIRect ir;
819 if (NULL != bounds) { 809 if (NULL != bounds) {
820 SkRect r; 810 SkRect r;
821 811
822 this->getTotalMatrix().mapRect(&r, *bounds); 812 this->getTotalMatrix().mapRect(&r, *bounds);
823 r.roundOut(&ir); 813 r.roundOut(&ir);
824 // early exit if the layer's bounds are clipped out 814 // early exit if the layer's bounds are clipped out
825 if (!ir.intersect(clipBounds)) { 815 if (!ir.intersect(clipBounds)) {
826 if (bounds_affects_clip(flags)) { 816 if (bounds_affects_clip(flags)) {
827 fMCRec->fRasterClip->setEmpty(); 817 fMCRec->fRasterClip.setEmpty();
828 } 818 }
829 return false; 819 return false;
830 } 820 }
831 } else { // no user bounds, so just use the clip 821 } else { // no user bounds, so just use the clip
832 ir = clipBounds; 822 ir = clipBounds;
833 } 823 }
834 824
835 if (bounds_affects_clip(flags)) { 825 if (bounds_affects_clip(flags)) {
836 fClipStack.clipDevRect(ir, op); 826 fClipStack.clipDevRect(ir, op);
837 // early exit if the clip is now empty 827 // early exit if the clip is now empty
838 if (!fMCRec->fRasterClip->op(ir, op)) { 828 if (!fMCRec->fRasterClip.op(ir, op)) {
839 return false; 829 return false;
840 } 830 }
841 } 831 }
842 832
843 if (intersection) { 833 if (intersection) {
844 *intersection = ir; 834 *intersection = ir;
845 } 835 }
846 return true; 836 return true;
847 } 837 }
848 838
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after
1277 this->concat(m); 1267 this->concat(m);
1278 } 1268 }
1279 1269
1280 void SkCanvas::concat(const SkMatrix& matrix) { 1270 void SkCanvas::concat(const SkMatrix& matrix) {
1281 if (matrix.isIdentity()) { 1271 if (matrix.isIdentity()) {
1282 return; 1272 return;
1283 } 1273 }
1284 1274
1285 fDeviceCMDirty = true; 1275 fDeviceCMDirty = true;
1286 fCachedLocalClipBoundsDirty = true; 1276 fCachedLocalClipBoundsDirty = true;
1287 fMCRec->fMatrix->preConcat(matrix); 1277 fMCRec->fMatrix.preConcat(matrix);
1288 1278
1289 this->didConcat(matrix); 1279 this->didConcat(matrix);
1290 } 1280 }
1291 1281
1292 void SkCanvas::setMatrix(const SkMatrix& matrix) { 1282 void SkCanvas::setMatrix(const SkMatrix& matrix) {
1293 fDeviceCMDirty = true; 1283 fDeviceCMDirty = true;
1294 fCachedLocalClipBoundsDirty = true; 1284 fCachedLocalClipBoundsDirty = true;
1295 *fMCRec->fMatrix = matrix; 1285 fMCRec->fMatrix = matrix;
1296 this->didSetMatrix(matrix); 1286 this->didSetMatrix(matrix);
1297 } 1287 }
1298 1288
1299 void SkCanvas::resetMatrix() { 1289 void SkCanvas::resetMatrix() {
1300 SkMatrix matrix; 1290 SkMatrix matrix;
1301 1291
1302 matrix.reset(); 1292 matrix.reset();
1303 this->setMatrix(matrix); 1293 this->setMatrix(matrix);
1304 } 1294 }
1305 1295
1306 ////////////////////////////////////////////////////////////////////////////// 1296 //////////////////////////////////////////////////////////////////////////////
1307 1297
1308 void SkCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { 1298 void SkCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) {
1309 ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 1299 ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle;
1310 this->onClipRect(rect, op, edgeStyle); 1300 this->onClipRect(rect, op, edgeStyle);
1311 } 1301 }
1312 1302
1313 void SkCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edg eStyle) { 1303 void SkCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edg eStyle) {
1314 #ifdef SK_ENABLE_CLIP_QUICKREJECT 1304 #ifdef SK_ENABLE_CLIP_QUICKREJECT
1315 if (SkRegion::kIntersect_Op == op) { 1305 if (SkRegion::kIntersect_Op == op) {
1316 if (fMCRec->fRasterClip->isEmpty()) { 1306 if (fMCRec->fRasterClip.isEmpty()) {
1317 return false; 1307 return false;
1318 } 1308 }
1319 1309
1320 if (this->quickReject(rect)) { 1310 if (this->quickReject(rect)) {
1321 fDeviceCMDirty = true; 1311 fDeviceCMDirty = true;
1322 fCachedLocalClipBoundsDirty = true; 1312 fCachedLocalClipBoundsDirty = true;
1323 1313
1324 fClipStack.clipEmpty(); 1314 fClipStack.clipEmpty();
1325 return fMCRec->fRasterClip->setEmpty(); 1315 return fMCRec->fRasterClip.setEmpty();
1326 } 1316 }
1327 } 1317 }
1328 #endif 1318 #endif
1329 1319
1330 AutoValidateClip avc(this); 1320 AutoValidateClip avc(this);
1331 1321
1332 fDeviceCMDirty = true; 1322 fDeviceCMDirty = true;
1333 fCachedLocalClipBoundsDirty = true; 1323 fCachedLocalClipBoundsDirty = true;
1334 if (!fAllowSoftClip) { 1324 if (!fAllowSoftClip) {
1335 edgeStyle = kHard_ClipEdgeStyle; 1325 edgeStyle = kHard_ClipEdgeStyle;
1336 } 1326 }
1337 1327
1338 if (fMCRec->fMatrix->rectStaysRect()) { 1328 if (fMCRec->fMatrix.rectStaysRect()) {
1339 // for these simpler matrices, we can stay a rect even after applying 1329 // for these simpler matrices, we can stay a rect even after applying
1340 // the matrix. This means we don't have to a) make a path, and b) tell 1330 // the matrix. This means we don't have to a) make a path, and b) tell
1341 // the region code to scan-convert the path, only to discover that it 1331 // the region code to scan-convert the path, only to discover that it
1342 // is really just a rect. 1332 // is really just a rect.
1343 SkRect r; 1333 SkRect r;
1344 1334
1345 fMCRec->fMatrix->mapRect(&r, rect); 1335 fMCRec->fMatrix.mapRect(&r, rect);
1346 fClipStack.clipDevRect(r, op, kSoft_ClipEdgeStyle == edgeStyle); 1336 fClipStack.clipDevRect(r, op, kSoft_ClipEdgeStyle == edgeStyle);
1347 fMCRec->fRasterClip->op(r, op, kSoft_ClipEdgeStyle == edgeStyle); 1337 fMCRec->fRasterClip.op(r, op, kSoft_ClipEdgeStyle == edgeStyle);
1348 } else { 1338 } else {
1349 // since we're rotated or some such thing, we convert the rect to a path 1339 // since we're rotated or some such thing, we convert the rect to a path
1350 // and clip against that, since it can handle any matrix. However, to 1340 // and clip against that, since it can handle any matrix. However, to
1351 // avoid recursion in the case where we are subclassed (e.g. Pictures) 1341 // avoid recursion in the case where we are subclassed (e.g. Pictures)
1352 // we explicitly call "our" version of clipPath. 1342 // we explicitly call "our" version of clipPath.
1353 SkPath path; 1343 SkPath path;
1354 1344
1355 path.addRect(rect); 1345 path.addRect(rect);
1356 this->SkCanvas::onClipPath(path, op, edgeStyle); 1346 this->SkCanvas::onClipPath(path, op, edgeStyle);
1357 } 1347 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1396 ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 1386 ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle;
1397 if (rrect.isRect()) { 1387 if (rrect.isRect()) {
1398 this->onClipRect(rrect.getBounds(), op, edgeStyle); 1388 this->onClipRect(rrect.getBounds(), op, edgeStyle);
1399 } else { 1389 } else {
1400 this->onClipRRect(rrect, op, edgeStyle); 1390 this->onClipRRect(rrect, op, edgeStyle);
1401 } 1391 }
1402 } 1392 }
1403 1393
1404 void SkCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 1394 void SkCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
1405 SkRRect transformedRRect; 1395 SkRRect transformedRRect;
1406 if (rrect.transform(*fMCRec->fMatrix, &transformedRRect)) { 1396 if (rrect.transform(fMCRec->fMatrix, &transformedRRect)) {
1407 AutoValidateClip avc(this); 1397 AutoValidateClip avc(this);
1408 1398
1409 fDeviceCMDirty = true; 1399 fDeviceCMDirty = true;
1410 fCachedLocalClipBoundsDirty = true; 1400 fCachedLocalClipBoundsDirty = true;
1411 if (!fAllowSoftClip) { 1401 if (!fAllowSoftClip) {
1412 edgeStyle = kHard_ClipEdgeStyle; 1402 edgeStyle = kHard_ClipEdgeStyle;
1413 } 1403 }
1414 1404
1415 fClipStack.clipDevRRect(transformedRRect, op, kSoft_ClipEdgeStyle == edg eStyle); 1405 fClipStack.clipDevRRect(transformedRRect, op, kSoft_ClipEdgeStyle == edg eStyle);
1416 1406
1417 SkPath devPath; 1407 SkPath devPath;
1418 devPath.addRRect(transformedRRect); 1408 devPath.addRRect(transformedRRect);
1419 1409
1420 clip_path_helper(this, fMCRec->fRasterClip, devPath, op, kSoft_ClipEdgeS tyle == edgeStyle); 1410 clip_path_helper(this, &fMCRec->fRasterClip, devPath, op, kSoft_ClipEdge Style == edgeStyle);
1421 return; 1411 return;
1422 } 1412 }
1423 1413
1424 SkPath path; 1414 SkPath path;
1425 path.addRRect(rrect); 1415 path.addRRect(rrect);
1426 // call the non-virtual version 1416 // call the non-virtual version
1427 this->SkCanvas::onClipPath(path, op, edgeStyle); 1417 this->SkCanvas::onClipPath(path, op, edgeStyle);
1428 } 1418 }
1429 1419
1430 void SkCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { 1420 void SkCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) {
1431 ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 1421 ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle;
1432 SkRect r; 1422 SkRect r;
1433 if (!path.isInverseFillType() && path.isRect(&r)) { 1423 if (!path.isInverseFillType() && path.isRect(&r)) {
1434 this->onClipRect(r, op, edgeStyle); 1424 this->onClipRect(r, op, edgeStyle);
1435 } else { 1425 } else {
1436 this->onClipPath(path, op, edgeStyle); 1426 this->onClipPath(path, op, edgeStyle);
1437 } 1427 }
1438 } 1428 }
1439 1429
1440 void SkCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edg eStyle) { 1430 void SkCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edg eStyle) {
1441 #ifdef SK_ENABLE_CLIP_QUICKREJECT 1431 #ifdef SK_ENABLE_CLIP_QUICKREJECT
1442 if (SkRegion::kIntersect_Op == op && !path.isInverseFillType()) { 1432 if (SkRegion::kIntersect_Op == op && !path.isInverseFillType()) {
1443 if (fMCRec->fRasterClip->isEmpty()) { 1433 if (fMCRec->fRasterClip.isEmpty()) {
1444 return false; 1434 return false;
1445 } 1435 }
1446 1436
1447 if (this->quickReject(path.getBounds())) { 1437 if (this->quickReject(path.getBounds())) {
1448 fDeviceCMDirty = true; 1438 fDeviceCMDirty = true;
1449 fCachedLocalClipBoundsDirty = true; 1439 fCachedLocalClipBoundsDirty = true;
1450 1440
1451 fClipStack.clipEmpty(); 1441 fClipStack.clipEmpty();
1452 return fMCRec->fRasterClip->setEmpty(); 1442 return fMCRec->fRasterClip.setEmpty();
1453 } 1443 }
1454 } 1444 }
1455 #endif 1445 #endif
1456 1446
1457 AutoValidateClip avc(this); 1447 AutoValidateClip avc(this);
1458 1448
1459 fDeviceCMDirty = true; 1449 fDeviceCMDirty = true;
1460 fCachedLocalClipBoundsDirty = true; 1450 fCachedLocalClipBoundsDirty = true;
1461 if (!fAllowSoftClip) { 1451 if (!fAllowSoftClip) {
1462 edgeStyle = kHard_ClipEdgeStyle; 1452 edgeStyle = kHard_ClipEdgeStyle;
1463 } 1453 }
1464 1454
1465 SkPath devPath; 1455 SkPath devPath;
1466 path.transform(*fMCRec->fMatrix, &devPath); 1456 path.transform(fMCRec->fMatrix, &devPath);
1467 1457
1468 // Check if the transfomation, or the original path itself 1458 // Check if the transfomation, or the original path itself
1469 // made us empty. Note this can also happen if we contained NaN 1459 // made us empty. Note this can also happen if we contained NaN
1470 // values. computing the bounds detects this, and will set our 1460 // values. computing the bounds detects this, and will set our
1471 // bounds to empty if that is the case. (see SkRect::set(pts, count)) 1461 // bounds to empty if that is the case. (see SkRect::set(pts, count))
1472 if (devPath.getBounds().isEmpty()) { 1462 if (devPath.getBounds().isEmpty()) {
1473 // resetting the path will remove any NaN or other wanky values 1463 // resetting the path will remove any NaN or other wanky values
1474 // that might upset our scan converter. 1464 // that might upset our scan converter.
1475 devPath.reset(); 1465 devPath.reset();
1476 } 1466 }
(...skipping 22 matching lines...) Expand all
1499 // if the prev and curr clips disagree about aa -vs- not, favor the aa request. 1489 // if the prev and curr clips disagree about aa -vs- not, favor the aa request.
1500 // perhaps we need an API change to avoid this sort of mixed-signals about 1490 // perhaps we need an API change to avoid this sort of mixed-signals about
1501 // clipping. 1491 // clipping.
1502 if (element->isAA()) { 1492 if (element->isAA()) {
1503 edgeStyle = kSoft_ClipEdgeStyle; 1493 edgeStyle = kSoft_ClipEdgeStyle;
1504 } 1494 }
1505 } 1495 }
1506 op = SkRegion::kReplace_Op; 1496 op = SkRegion::kReplace_Op;
1507 } 1497 }
1508 1498
1509 clip_path_helper(this, fMCRec->fRasterClip, devPath, op, edgeStyle); 1499 clip_path_helper(this, &fMCRec->fRasterClip, devPath, op, edgeStyle);
1510 } 1500 }
1511 1501
1512 void SkCanvas::updateClipConservativelyUsingBounds(const SkRect& bounds, SkRegio n::Op op, 1502 void SkCanvas::updateClipConservativelyUsingBounds(const SkRect& bounds, SkRegio n::Op op,
1513 bool inverseFilled) { 1503 bool inverseFilled) {
1514 // This is for updating the clip conservatively using only bounds 1504 // This is for updating the clip conservatively using only bounds
1515 // information. 1505 // information.
1516 // Contract: 1506 // Contract:
1517 // The current clip must contain the true clip. The true 1507 // The current clip must contain the true clip. The true
1518 // clip is the clip that would have normally been computed 1508 // clip is the clip that would have normally been computed
1519 // by calls to clipPath and clipRRect 1509 // by calls to clipPath and clipRRect
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1592 void SkCanvas::onClipRegion(const SkRegion& rgn, SkRegion::Op op) { 1582 void SkCanvas::onClipRegion(const SkRegion& rgn, SkRegion::Op op) {
1593 AutoValidateClip avc(this); 1583 AutoValidateClip avc(this);
1594 1584
1595 fDeviceCMDirty = true; 1585 fDeviceCMDirty = true;
1596 fCachedLocalClipBoundsDirty = true; 1586 fCachedLocalClipBoundsDirty = true;
1597 1587
1598 // todo: signal fClipStack that we have a region, and therefore (I guess) 1588 // todo: signal fClipStack that we have a region, and therefore (I guess)
1599 // we have to ignore it, and use the region directly? 1589 // we have to ignore it, and use the region directly?
1600 fClipStack.clipDevRect(rgn.getBounds(), op); 1590 fClipStack.clipDevRect(rgn.getBounds(), op);
1601 1591
1602 fMCRec->fRasterClip->op(rgn, op); 1592 fMCRec->fRasterClip.op(rgn, op);
1603 } 1593 }
1604 1594
1605 #ifdef SK_DEBUG 1595 #ifdef SK_DEBUG
1606 void SkCanvas::validateClip() const { 1596 void SkCanvas::validateClip() const {
1607 // construct clipRgn from the clipstack 1597 // construct clipRgn from the clipstack
1608 const SkBaseDevice* device = this->getDevice(); 1598 const SkBaseDevice* device = this->getDevice();
1609 if (!device) { 1599 if (!device) {
1610 SkASSERT(this->isClipEmpty()); 1600 SkASSERT(this->isClipEmpty());
1611 return; 1601 return;
1612 } 1602 }
(...skipping 29 matching lines...) Expand all
1642 const SkClipStack::Element* element; 1632 const SkClipStack::Element* element;
1643 1633
1644 while ((element = iter.next()) != NULL) { 1634 while ((element = iter.next()) != NULL) {
1645 element->replay(visitor); 1635 element->replay(visitor);
1646 } 1636 }
1647 } 1637 }
1648 1638
1649 /////////////////////////////////////////////////////////////////////////////// 1639 ///////////////////////////////////////////////////////////////////////////////
1650 1640
1651 bool SkCanvas::isClipEmpty() const { 1641 bool SkCanvas::isClipEmpty() const {
1652 return fMCRec->fRasterClip->isEmpty(); 1642 return fMCRec->fRasterClip.isEmpty();
1653 } 1643 }
1654 1644
1655 bool SkCanvas::isClipRect() const { 1645 bool SkCanvas::isClipRect() const {
1656 return fMCRec->fRasterClip->isRect(); 1646 return fMCRec->fRasterClip.isRect();
1657 } 1647 }
1658 1648
1659 bool SkCanvas::quickReject(const SkRect& rect) const { 1649 bool SkCanvas::quickReject(const SkRect& rect) const {
1660 1650
1661 if (!rect.isFinite()) 1651 if (!rect.isFinite())
1662 return true; 1652 return true;
1663 1653
1664 if (fMCRec->fRasterClip->isEmpty()) { 1654 if (fMCRec->fRasterClip.isEmpty()) {
1665 return true; 1655 return true;
1666 } 1656 }
1667 1657
1668 if (fMCRec->fMatrix->hasPerspective()) { 1658 if (fMCRec->fMatrix.hasPerspective()) {
1669 SkRect dst; 1659 SkRect dst;
1670 fMCRec->fMatrix->mapRect(&dst, rect); 1660 fMCRec->fMatrix.mapRect(&dst, rect);
1671 SkIRect idst; 1661 SkIRect idst;
1672 dst.roundOut(&idst); 1662 dst.roundOut(&idst);
1673 return !SkIRect::Intersects(idst, fMCRec->fRasterClip->getBounds()); 1663 return !SkIRect::Intersects(idst, fMCRec->fRasterClip.getBounds());
1674 } else { 1664 } else {
1675 const SkRect& clipR = this->getLocalClipBounds(); 1665 const SkRect& clipR = this->getLocalClipBounds();
1676 1666
1677 // for speed, do the most likely reject compares first 1667 // for speed, do the most likely reject compares first
1678 // TODO: should we use | instead, or compare all 4 at once? 1668 // TODO: should we use | instead, or compare all 4 at once?
1679 if (rect.fTop >= clipR.fBottom || rect.fBottom <= clipR.fTop) { 1669 if (rect.fTop >= clipR.fBottom || rect.fBottom <= clipR.fTop) {
1680 return true; 1670 return true;
1681 } 1671 }
1682 if (rect.fLeft >= clipR.fRight || rect.fRight <= clipR.fLeft) { 1672 if (rect.fLeft >= clipR.fRight || rect.fRight <= clipR.fLeft) {
1683 return true; 1673 return true;
1684 } 1674 }
1685 return false; 1675 return false;
1686 } 1676 }
1687 } 1677 }
1688 1678
1689 bool SkCanvas::quickReject(const SkPath& path) const { 1679 bool SkCanvas::quickReject(const SkPath& path) const {
1690 return path.isEmpty() || this->quickReject(path.getBounds()); 1680 return path.isEmpty() || this->quickReject(path.getBounds());
1691 } 1681 }
1692 1682
1693 bool SkCanvas::getClipBounds(SkRect* bounds) const { 1683 bool SkCanvas::getClipBounds(SkRect* bounds) const {
1694 SkIRect ibounds; 1684 SkIRect ibounds;
1695 if (!this->getClipDeviceBounds(&ibounds)) { 1685 if (!this->getClipDeviceBounds(&ibounds)) {
1696 return false; 1686 return false;
1697 } 1687 }
1698 1688
1699 SkMatrix inverse; 1689 SkMatrix inverse;
1700 // if we can't invert the CTM, we can't return local clip bounds 1690 // if we can't invert the CTM, we can't return local clip bounds
1701 if (!fMCRec->fMatrix->invert(&inverse)) { 1691 if (!fMCRec->fMatrix.invert(&inverse)) {
1702 if (bounds) { 1692 if (bounds) {
1703 bounds->setEmpty(); 1693 bounds->setEmpty();
1704 } 1694 }
1705 return false; 1695 return false;
1706 } 1696 }
1707 1697
1708 if (NULL != bounds) { 1698 if (NULL != bounds) {
1709 SkRect r; 1699 SkRect r;
1710 // adjust it outwards in case we are antialiasing 1700 // adjust it outwards in case we are antialiasing
1711 const int inset = 1; 1701 const int inset = 1;
1712 1702
1713 r.iset(ibounds.fLeft - inset, ibounds.fTop - inset, 1703 r.iset(ibounds.fLeft - inset, ibounds.fTop - inset,
1714 ibounds.fRight + inset, ibounds.fBottom + inset); 1704 ibounds.fRight + inset, ibounds.fBottom + inset);
1715 inverse.mapRect(bounds, r); 1705 inverse.mapRect(bounds, r);
1716 } 1706 }
1717 return true; 1707 return true;
1718 } 1708 }
1719 1709
1720 bool SkCanvas::getClipDeviceBounds(SkIRect* bounds) const { 1710 bool SkCanvas::getClipDeviceBounds(SkIRect* bounds) const {
1721 const SkRasterClip& clip = *fMCRec->fRasterClip; 1711 const SkRasterClip& clip = fMCRec->fRasterClip;
1722 if (clip.isEmpty()) { 1712 if (clip.isEmpty()) {
1723 if (bounds) { 1713 if (bounds) {
1724 bounds->setEmpty(); 1714 bounds->setEmpty();
1725 } 1715 }
1726 return false; 1716 return false;
1727 } 1717 }
1728 1718
1729 if (NULL != bounds) { 1719 if (NULL != bounds) {
1730 *bounds = clip.getBounds(); 1720 *bounds = clip.getBounds();
1731 } 1721 }
1732 return true; 1722 return true;
1733 } 1723 }
1734 1724
1735 const SkMatrix& SkCanvas::getTotalMatrix() const { 1725 const SkMatrix& SkCanvas::getTotalMatrix() const {
1736 return *fMCRec->fMatrix; 1726 return fMCRec->fMatrix;
1737 } 1727 }
1738 1728
1739 #ifdef SK_SUPPORT_LEGACY_GETCLIPTYPE 1729 #ifdef SK_SUPPORT_LEGACY_GETCLIPTYPE
1740 SkCanvas::ClipType SkCanvas::getClipType() const { 1730 SkCanvas::ClipType SkCanvas::getClipType() const {
1741 if (fMCRec->fRasterClip->isEmpty()) { 1731 if (fMCRec->fRasterClip.isEmpty()) {
1742 return kEmpty_ClipType; 1732 return kEmpty_ClipType;
1743 } 1733 }
1744 if (fMCRec->fRasterClip->isRect()) { 1734 if (fMCRec->fRasterClip.isRect()) {
1745 return kRect_ClipType; 1735 return kRect_ClipType;
1746 } 1736 }
1747 return kComplex_ClipType; 1737 return kComplex_ClipType;
1748 } 1738 }
1749 #endif 1739 #endif
1750 1740
1751 const SkRegion& SkCanvas::internal_private_getTotalClip() const { 1741 const SkRegion& SkCanvas::internal_private_getTotalClip() const {
1752 return fMCRec->fRasterClip->forceGetBW(); 1742 return fMCRec->fRasterClip.forceGetBW();
1753 } 1743 }
1754 1744
1755 void SkCanvas::internal_private_getTotalClipAsPath(SkPath* path) const { 1745 void SkCanvas::internal_private_getTotalClipAsPath(SkPath* path) const {
1756 path->reset(); 1746 path->reset();
1757 1747
1758 const SkRegion& rgn = fMCRec->fRasterClip->forceGetBW(); 1748 const SkRegion& rgn = fMCRec->fRasterClip.forceGetBW();
1759 if (rgn.isEmpty()) { 1749 if (rgn.isEmpty()) {
1760 return; 1750 return;
1761 } 1751 }
1762 (void)rgn.getBoundaryPath(path); 1752 (void)rgn.getBoundaryPath(path);
1763 } 1753 }
1764 1754
1765 GrRenderTarget* SkCanvas::internal_private_accessTopLayerRenderTarget() { 1755 GrRenderTarget* SkCanvas::internal_private_accessTopLayerRenderTarget() {
1766 SkBaseDevice* dev = this->getTopDevice(); 1756 SkBaseDevice* dev = this->getTopDevice();
1767 return dev ? dev->accessRenderTarget() : NULL; 1757 return dev ? dev->accessRenderTarget() : NULL;
1768 } 1758 }
(...skipping 788 matching lines...) Expand 10 before | Expand all | Expand 10 after
2557 if (!supported_for_raster_canvas(info)) { 2547 if (!supported_for_raster_canvas(info)) {
2558 return NULL; 2548 return NULL;
2559 } 2549 }
2560 2550
2561 SkBitmap bitmap; 2551 SkBitmap bitmap;
2562 if (!bitmap.installPixels(info, pixels, rowBytes)) { 2552 if (!bitmap.installPixels(info, pixels, rowBytes)) {
2563 return NULL; 2553 return NULL;
2564 } 2554 }
2565 return SkNEW_ARGS(SkCanvas, (bitmap)); 2555 return SkNEW_ARGS(SkCanvas, (bitmap));
2566 } 2556 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698