| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 #include "SkPictureRecord.h" | 8 #include "SkPictureRecord.h" |
| 9 #include "SkTSearch.h" | 9 #include "SkTSearch.h" |
| 10 #include "SkPixelRef.h" | 10 #include "SkPixelRef.h" |
| (...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 749 size += kUInt32Size; | 749 size += kUInt32Size; |
| 750 } | 750 } |
| 751 uint32_t initialOffset = this->addDraw(CLIP_RRECT, &size); | 751 uint32_t initialOffset = this->addDraw(CLIP_RRECT, &size); |
| 752 addRRect(rrect); | 752 addRRect(rrect); |
| 753 addInt(ClipParams_pack(op, doAA)); | 753 addInt(ClipParams_pack(op, doAA)); |
| 754 recordRestoreOffsetPlaceholder(op); | 754 recordRestoreOffsetPlaceholder(op); |
| 755 | 755 |
| 756 validate(initialOffset, size); | 756 validate(initialOffset, size); |
| 757 | 757 |
| 758 if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) { | 758 if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) { |
| 759 return this->updateClipConservativelyUsingBounds(rrect.getBounds(), op,
doAA, false); | 759 return this->updateClipConservativelyUsingBounds(rrect.getBounds(), op,
false); |
| 760 } else { | 760 } else { |
| 761 return this->INHERITED::clipRRect(rrect, op, doAA); | 761 return this->INHERITED::clipRRect(rrect, op, doAA); |
| 762 } | 762 } |
| 763 } | 763 } |
| 764 | 764 |
| 765 bool SkPictureRecord::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { | 765 bool SkPictureRecord::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { |
| 766 | 766 |
| 767 SkRect r; | 767 SkRect r; |
| 768 if (!path.isInverseFillType() && path.isRect(&r)) { | 768 if (!path.isInverseFillType() && path.isRect(&r)) { |
| 769 return this->clipRect(r, op, doAA); | 769 return this->clipRect(r, op, doAA); |
| 770 } | 770 } |
| 771 | 771 |
| 772 // op + path index + clip params | 772 // op + path index + clip params |
| 773 uint32_t size = 3 * kUInt32Size; | 773 uint32_t size = 3 * kUInt32Size; |
| 774 // recordRestoreOffsetPlaceholder doesn't always write an offset | 774 // recordRestoreOffsetPlaceholder doesn't always write an offset |
| 775 if (!fRestoreOffsetStack.isEmpty()) { | 775 if (!fRestoreOffsetStack.isEmpty()) { |
| 776 // + restore offset | 776 // + restore offset |
| 777 size += kUInt32Size; | 777 size += kUInt32Size; |
| 778 } | 778 } |
| 779 uint32_t initialOffset = this->addDraw(CLIP_PATH, &size); | 779 uint32_t initialOffset = this->addDraw(CLIP_PATH, &size); |
| 780 addPath(path); | 780 addPath(path); |
| 781 addInt(ClipParams_pack(op, doAA)); | 781 addInt(ClipParams_pack(op, doAA)); |
| 782 recordRestoreOffsetPlaceholder(op); | 782 recordRestoreOffsetPlaceholder(op); |
| 783 | 783 |
| 784 validate(initialOffset, size); | 784 validate(initialOffset, size); |
| 785 | 785 |
| 786 if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) { | 786 if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) { |
| 787 return this->updateClipConservativelyUsingBounds(path.getBounds(), op, d
oAA, | 787 return this->updateClipConservativelyUsingBounds(path.getBounds(), op, |
| 788 path.isInverseFillType(
)); | 788 path.isInverseFillType(
)); |
| 789 } else { | 789 } else { |
| 790 return this->INHERITED::clipPath(path, op, doAA); | 790 return this->INHERITED::clipPath(path, op, doAA); |
| 791 } | 791 } |
| 792 } | 792 } |
| 793 | 793 |
| 794 bool SkPictureRecord::updateClipConservativelyUsingBounds(const SkRect& bounds,
SkRegion::Op op, | |
| 795 bool doAA, bool invers
eFilled) { | |
| 796 // This is for updating the clip when kUsePathBoundsForClip_RecordingFlag | |
| 797 // is set. The current clip of the recording canvas is used for quick | |
| 798 // culling of clipped-out primitives, which must not yield any false | |
| 799 // positives, while still rejecting as many as possible. | |
| 800 // Contract: | |
| 801 // The current clip must contain the true clip. The true | |
| 802 // clip is the clip that would have been computed with | |
| 803 // kUsePathBoundsForClip_RecordingFlag disabled. | |
| 804 // Objective: | |
| 805 // Keep the current clip as small as possible without | |
| 806 // breaking the contract, using only clip bounding rectangles | |
| 807 // (for performance). | |
| 808 if (inverseFilled) { | |
| 809 switch (op) { | |
| 810 case SkRegion::kIntersect_Op: | |
| 811 case SkRegion::kDifference_Op: | |
| 812 // These ops can only shrink the current clip. So leaving | |
| 813 // the clip unchanges conservatively respects the contract. | |
| 814 return this->getClipDeviceBounds(NULL); | |
| 815 case SkRegion::kUnion_Op: | |
| 816 case SkRegion::kReplace_Op: | |
| 817 case SkRegion::kReverseDifference_Op: | |
| 818 case SkRegion::kXOR_Op: | |
| 819 { | |
| 820 // These ops can grow the current clip up to the extents of | |
| 821 // the input clip, which is inverse filled, so we just set | |
| 822 // the current clip to the device bounds. | |
| 823 SkRect deviceBounds; | |
| 824 SkIRect deviceIBounds; | |
| 825 this->getDevice()->getGlobalBounds(&deviceIBounds); | |
| 826 deviceBounds = SkRect::MakeFromIRect(deviceIBounds); | |
| 827 this->INHERITED::save(SkCanvas::kMatrix_SaveFlag); | |
| 828 // set the clip in device space | |
| 829 this->INHERITED::setMatrix(SkMatrix::I()); | |
| 830 bool result = this->INHERITED::clipRect(deviceBounds, | |
| 831 SkRegion::kReplace_Op, doAA); | |
| 832 this->INHERITED::restore(); //pop the matrix, but keep the c
lip | |
| 833 return result; | |
| 834 } | |
| 835 default: | |
| 836 SkASSERT(0); // unhandled op? | |
| 837 } | |
| 838 } else { | |
| 839 // Not inverse filled | |
| 840 switch (op) { | |
| 841 case SkRegion::kIntersect_Op: | |
| 842 case SkRegion::kUnion_Op: | |
| 843 case SkRegion::kReplace_Op: | |
| 844 return this->INHERITED::clipRect(bounds, op, doAA); | |
| 845 case SkRegion::kDifference_Op: | |
| 846 // Difference can only shrink the current clip. | |
| 847 // Leaving clip unchanged conservatively fullfills the contract. | |
| 848 return this->getClipDeviceBounds(NULL); | |
| 849 case SkRegion::kReverseDifference_Op: | |
| 850 // To reverse, we swap in the bounds with a replace op. | |
| 851 // As with difference, leave it unchanged. | |
| 852 return this->INHERITED::clipRect(bounds, SkRegion::kReplace_Op,
doAA); | |
| 853 case SkRegion::kXOR_Op: | |
| 854 // Be conservative, based on (A XOR B) always included in (A uni
on B), | |
| 855 // which is always included in (bounds(A) union bounds(B)) | |
| 856 return this->INHERITED::clipRect(bounds, SkRegion::kUnion_Op, do
AA); | |
| 857 default: | |
| 858 SkASSERT(0); // unhandled op? | |
| 859 } | |
| 860 } | |
| 861 return true; | |
| 862 } | |
| 863 | |
| 864 bool SkPictureRecord::clipRegion(const SkRegion& region, SkRegion::Op op) { | 794 bool SkPictureRecord::clipRegion(const SkRegion& region, SkRegion::Op op) { |
| 865 // op + region index + clip params | 795 // op + region index + clip params |
| 866 uint32_t size = 3 * kUInt32Size; | 796 uint32_t size = 3 * kUInt32Size; |
| 867 // recordRestoreOffsetPlaceholder doesn't always write an offset | 797 // recordRestoreOffsetPlaceholder doesn't always write an offset |
| 868 if (!fRestoreOffsetStack.isEmpty()) { | 798 if (!fRestoreOffsetStack.isEmpty()) { |
| 869 // + restore offset | 799 // + restore offset |
| 870 size += kUInt32Size; | 800 size += kUInt32Size; |
| 871 } | 801 } |
| 872 uint32_t initialOffset = this->addDraw(CLIP_REGION, &size); | 802 uint32_t initialOffset = this->addDraw(CLIP_REGION, &size); |
| 873 addRegion(region); | 803 addRegion(region); |
| (...skipping 638 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1512 void SkPictureRecord::validateRegions() const { | 1442 void SkPictureRecord::validateRegions() const { |
| 1513 int count = fRegions.count(); | 1443 int count = fRegions.count(); |
| 1514 SkASSERT((unsigned) count < 0x1000); | 1444 SkASSERT((unsigned) count < 0x1000); |
| 1515 for (int index = 0; index < count; index++) { | 1445 for (int index = 0; index < count; index++) { |
| 1516 const SkFlatData* region = fRegions[index]; | 1446 const SkFlatData* region = fRegions[index]; |
| 1517 SkASSERT(region); | 1447 SkASSERT(region); |
| 1518 // region->validate(); | 1448 // region->validate(); |
| 1519 } | 1449 } |
| 1520 } | 1450 } |
| 1521 #endif | 1451 #endif |
| OLD | NEW |