OLD | NEW |
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 #include "SkBitmapDevice.h" | 8 #include "SkBitmapDevice.h" |
9 #include "SkCanvas.h" | 9 #include "SkCanvas.h" |
10 #include "SkCanvasPriv.h" | 10 #include "SkCanvasPriv.h" |
(...skipping 28 matching lines...) Expand all Loading... |
39 #include <new> | 39 #include <new> |
40 | 40 |
41 #if SK_SUPPORT_GPU | 41 #if SK_SUPPORT_GPU |
42 #include "GrContext.h" | 42 #include "GrContext.h" |
43 #include "GrRenderTarget.h" | 43 #include "GrRenderTarget.h" |
44 #include "SkGr.h" | 44 #include "SkGr.h" |
45 #endif | 45 #endif |
46 | 46 |
47 #define RETURN_ON_NULL(ptr) do { if (nullptr == (ptr)) return; } while (0) | 47 #define RETURN_ON_NULL(ptr) do { if (nullptr == (ptr)) return; } while (0) |
48 | 48 |
| 49 //#define SK_SUPPORT_PRECHECK_CLIPRECT |
| 50 |
49 /* | 51 /* |
50 * Return true if the drawing this rect would hit every pixels in the canvas. | 52 * Return true if the drawing this rect would hit every pixels in the canvas. |
51 * | 53 * |
52 * Returns false if | 54 * Returns false if |
53 * - rect does not contain the canvas' bounds | 55 * - rect does not contain the canvas' bounds |
54 * - paint is not fill | 56 * - paint is not fill |
55 * - paint would blur or otherwise change the coverage of the rect | 57 * - paint would blur or otherwise change the coverage of the rect |
56 */ | 58 */ |
57 bool SkCanvas::wouldOverwriteEntireSurface(const SkRect* rect, const SkPaint* pa
int, | 59 bool SkCanvas::wouldOverwriteEntireSurface(const SkRect* rect, const SkPaint* pa
int, |
58 ShaderOverrideOpacity overrideOpacity
) const { | 60 ShaderOverrideOpacity overrideOpacity
) const { |
(...skipping 1456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1515 this->didSetMatrix(matrix); | 1517 this->didSetMatrix(matrix); |
1516 } | 1518 } |
1517 | 1519 |
1518 void SkCanvas::resetMatrix() { | 1520 void SkCanvas::resetMatrix() { |
1519 this->setMatrix(SkMatrix::I()); | 1521 this->setMatrix(SkMatrix::I()); |
1520 } | 1522 } |
1521 | 1523 |
1522 ////////////////////////////////////////////////////////////////////////////// | 1524 ////////////////////////////////////////////////////////////////////////////// |
1523 | 1525 |
1524 void SkCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { | 1526 void SkCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { |
| 1527 if (!fAllowSoftClip) { |
| 1528 doAA = false; |
| 1529 } |
| 1530 |
| 1531 #ifdef SK_SUPPORT_PRECHECK_CLIPRECT |
| 1532 // Check if we can quick-accept the clip call (and do nothing) |
| 1533 // |
| 1534 if (SkRegion::kIntersect_Op == op && !doAA && fMCRec->fMatrix.rectStaysRect(
)) { |
| 1535 SkRect devR; |
| 1536 fMCRec->fMatrix.mapRect(&devR, rect); |
| 1537 // NOTE: this check is CTM specific, since we might round differently wi
th a different |
| 1538 // CTM. Thus this is only 100% reliable if there is not global CTM
scale to be |
| 1539 // applied later (i.e. if this is going into a picture). |
| 1540 if (devR.round().contains(fMCRec->fRasterClip.getBounds())) { |
| 1541 #if 0 |
| 1542 SkDebugf("ignored clipRect [%g %g %g %g]\n", |
| 1543 rect.left(), rect.top(), rect.right(), rect.bottom()); |
| 1544 #endif |
| 1545 return; |
| 1546 } |
| 1547 } |
| 1548 #endif |
| 1549 |
1525 this->checkForDeferredSave(); | 1550 this->checkForDeferredSave(); |
1526 ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; | 1551 ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; |
1527 this->onClipRect(rect, op, edgeStyle); | 1552 this->onClipRect(rect, op, edgeStyle); |
1528 } | 1553 } |
1529 | 1554 |
1530 void SkCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edg
eStyle) { | 1555 void SkCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edg
eStyle) { |
1531 #ifdef SK_ENABLE_CLIP_QUICKREJECT | 1556 #ifdef SK_ENABLE_CLIP_QUICKREJECT |
1532 if (SkRegion::kIntersect_Op == op) { | 1557 if (SkRegion::kIntersect_Op == op) { |
1533 if (fMCRec->fRasterClip.isEmpty()) { | 1558 if (fMCRec->fRasterClip.isEmpty()) { |
1534 return false; | 1559 return; |
1535 } | 1560 } |
1536 | 1561 |
1537 if (this->quickReject(rect)) { | 1562 if (this->quickReject(rect)) { |
1538 fDeviceCMDirty = true; | 1563 fDeviceCMDirty = true; |
1539 fCachedLocalClipBoundsDirty = true; | 1564 fCachedLocalClipBoundsDirty = true; |
1540 | 1565 |
1541 fClipStack->clipEmpty(); | 1566 fClipStack->clipEmpty(); |
1542 return fMCRec->fRasterClip.setEmpty(); | 1567 (void)fMCRec->fRasterClip.setEmpty(); |
| 1568 return; |
1543 } | 1569 } |
1544 } | 1570 } |
1545 #endif | 1571 #endif |
1546 | 1572 |
1547 if (!fAllowSoftClip) { | |
1548 edgeStyle = kHard_ClipEdgeStyle; | |
1549 } | |
1550 | |
1551 const bool rectStaysRect = fMCRec->fMatrix.rectStaysRect(); | 1573 const bool rectStaysRect = fMCRec->fMatrix.rectStaysRect(); |
1552 SkRect devR; | 1574 SkRect devR; |
1553 if (rectStaysRect) { | 1575 if (rectStaysRect) { |
1554 fMCRec->fMatrix.mapRect(&devR, rect); | 1576 fMCRec->fMatrix.mapRect(&devR, rect); |
1555 } | 1577 } |
1556 | 1578 |
1557 // Check if we can quick-accept the clip call (and do nothing) | 1579 #ifndef SK_SUPPORT_PRECHECK_CLIPRECT |
1558 // | |
1559 // TODO: investigate if a (conservative) version of this could be done in ::
clipRect, | |
1560 // so that subclasses (like PictureRecording) didn't see unnecessary c
lips, which in turn | |
1561 // might allow lazy save/restores to eliminate entire save/restore blo
cks. | |
1562 // | |
1563 if (SkRegion::kIntersect_Op == op && | 1580 if (SkRegion::kIntersect_Op == op && |
1564 kHard_ClipEdgeStyle == edgeStyle | 1581 kHard_ClipEdgeStyle == edgeStyle |
1565 && rectStaysRect) | 1582 && rectStaysRect) |
1566 { | 1583 { |
1567 if (devR.round().contains(fMCRec->fRasterClip.getBounds())) { | 1584 if (devR.round().contains(fMCRec->fRasterClip.getBounds())) { |
1568 #if 0 | 1585 #if 0 |
1569 SkDebugf("------- ignored clipRect [%g %g %g %g]\n", | 1586 SkDebugf("------- ignored clipRect [%g %g %g %g]\n", |
1570 rect.left(), rect.top(), rect.right(), rect.bottom()); | 1587 rect.left(), rect.top(), rect.right(), rect.bottom()); |
1571 #endif | 1588 #endif |
1572 return; | 1589 return; |
1573 } | 1590 } |
1574 } | 1591 } |
| 1592 #endif |
1575 | 1593 |
1576 AutoValidateClip avc(this); | 1594 AutoValidateClip avc(this); |
1577 | 1595 |
1578 fDeviceCMDirty = true; | 1596 fDeviceCMDirty = true; |
1579 fCachedLocalClipBoundsDirty = true; | 1597 fCachedLocalClipBoundsDirty = true; |
1580 | 1598 |
1581 if (rectStaysRect) { | 1599 if (rectStaysRect) { |
1582 const bool isAA = kSoft_ClipEdgeStyle == edgeStyle; | 1600 const bool isAA = kSoft_ClipEdgeStyle == edgeStyle; |
1583 fClipStack->clipDevRect(devR, op, isAA); | 1601 fClipStack->clipDevRect(devR, op, isAA); |
1584 fMCRec->fRasterClip.op(devR, this->getTopLayerBounds(), op, isAA); | 1602 fMCRec->fRasterClip.op(devR, this->getTopLayerBounds(), op, isAA); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1650 } | 1668 } |
1651 } | 1669 } |
1652 | 1670 |
1653 this->onClipPath(path, op, edgeStyle); | 1671 this->onClipPath(path, op, edgeStyle); |
1654 } | 1672 } |
1655 | 1673 |
1656 void SkCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edg
eStyle) { | 1674 void SkCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edg
eStyle) { |
1657 #ifdef SK_ENABLE_CLIP_QUICKREJECT | 1675 #ifdef SK_ENABLE_CLIP_QUICKREJECT |
1658 if (SkRegion::kIntersect_Op == op && !path.isInverseFillType()) { | 1676 if (SkRegion::kIntersect_Op == op && !path.isInverseFillType()) { |
1659 if (fMCRec->fRasterClip.isEmpty()) { | 1677 if (fMCRec->fRasterClip.isEmpty()) { |
1660 return false; | 1678 return; |
1661 } | 1679 } |
1662 | 1680 |
1663 if (this->quickReject(path.getBounds())) { | 1681 if (this->quickReject(path.getBounds())) { |
1664 fDeviceCMDirty = true; | 1682 fDeviceCMDirty = true; |
1665 fCachedLocalClipBoundsDirty = true; | 1683 fCachedLocalClipBoundsDirty = true; |
1666 | 1684 |
1667 fClipStack->clipEmpty(); | 1685 fClipStack->clipEmpty(); |
1668 return fMCRec->fRasterClip.setEmpty(); | 1686 (void)fMCRec->fRasterClip.setEmpty(); |
| 1687 return; |
1669 } | 1688 } |
1670 } | 1689 } |
1671 #endif | 1690 #endif |
1672 | 1691 |
1673 AutoValidateClip avc(this); | 1692 AutoValidateClip avc(this); |
1674 | 1693 |
1675 fDeviceCMDirty = true; | 1694 fDeviceCMDirty = true; |
1676 fCachedLocalClipBoundsDirty = true; | 1695 fCachedLocalClipBoundsDirty = true; |
1677 if (!fAllowSoftClip) { | 1696 if (!fAllowSoftClip) { |
1678 edgeStyle = kHard_ClipEdgeStyle; | 1697 edgeStyle = kHard_ClipEdgeStyle; |
(...skipping 1396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3075 | 3094 |
3076 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { | 3095 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { |
3077 fCanvas->restoreToCount(fSaveCount); | 3096 fCanvas->restoreToCount(fSaveCount); |
3078 } | 3097 } |
3079 | 3098 |
3080 #ifdef SK_SUPPORT_LEGACY_NEW_SURFACE_API | 3099 #ifdef SK_SUPPORT_LEGACY_NEW_SURFACE_API |
3081 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p
rops) { | 3100 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p
rops) { |
3082 return this->makeSurface(info, props).release(); | 3101 return this->makeSurface(info, props).release(); |
3083 } | 3102 } |
3084 #endif | 3103 #endif |
OLD | NEW |