OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 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 "SkBigPicture.h" | 8 #include "SkBigPicture.h" |
9 #include "SkBBoxHierarchy.h" | 9 #include "SkBBoxHierarchy.h" |
10 #include "SkBlurImageFilter.h" | 10 #include "SkBlurImageFilter.h" |
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
281 REPORTER_ASSERT(reporter, !SkPictureGpuAnalyzer(picture).suitableForGpuRaste
rization()); | 281 REPORTER_ASSERT(reporter, !SkPictureGpuAnalyzer(picture).suitableForGpuRaste
rization()); |
282 | 282 |
283 canvas = recorder.beginRecording(100, 100); | 283 canvas = recorder.beginRecording(100, 100); |
284 { | 284 { |
285 const SkPath convexClip = make_convex_path(); | 285 const SkPath convexClip = make_convex_path(); |
286 const SkPath concaveClip = make_concave_path(); | 286 const SkPath concaveClip = make_concave_path(); |
287 | 287 |
288 for (int i = 0; i < 50; ++i) { | 288 for (int i = 0; i < 50; ++i) { |
289 canvas->clipPath(convexClip); | 289 canvas->clipPath(convexClip); |
290 canvas->clipPath(concaveClip); | 290 canvas->clipPath(concaveClip); |
291 canvas->clipPath(convexClip, SkRegion::kIntersect_Op, true); | 291 canvas->clipPath(convexClip, SkCanvas::kIntersect_Op, true); |
292 canvas->drawRect(SkRect::MakeWH(100, 100), SkPaint()); | 292 canvas->drawRect(SkRect::MakeWH(100, 100), SkPaint()); |
293 } | 293 } |
294 } | 294 } |
295 picture = recorder.finishRecordingAsPicture(); | 295 picture = recorder.finishRecordingAsPicture(); |
296 // Convex clips and non-AA concave clips are fine on the GPU. | 296 // Convex clips and non-AA concave clips are fine on the GPU. |
297 REPORTER_ASSERT(reporter, SkPictureGpuAnalyzer(picture).suitableForGpuRaster
ization()); | 297 REPORTER_ASSERT(reporter, SkPictureGpuAnalyzer(picture).suitableForGpuRaster
ization()); |
298 | 298 |
299 canvas = recorder.beginRecording(100, 100); | 299 canvas = recorder.beginRecording(100, 100); |
300 { | 300 { |
301 const SkPath concaveClip = make_concave_path(); | 301 const SkPath concaveClip = make_concave_path(); |
302 for (int i = 0; i < 50; ++i) { | 302 for (int i = 0; i < 50; ++i) { |
303 canvas->clipPath(concaveClip, SkRegion::kIntersect_Op, true); | 303 canvas->clipPath(concaveClip, SkCanvas::kIntersect_Op, true); |
304 canvas->drawRect(SkRect::MakeWH(100, 100), SkPaint()); | 304 canvas->drawRect(SkRect::MakeWH(100, 100), SkPaint()); |
305 } | 305 } |
306 } | 306 } |
307 picture = recorder.finishRecordingAsPicture(); | 307 picture = recorder.finishRecordingAsPicture(); |
308 // ... but AA concave clips are not. | 308 // ... but AA concave clips are not. |
309 REPORTER_ASSERT(reporter, !SkPictureGpuAnalyzer(picture).suitableForGpuRaste
rization()); | 309 REPORTER_ASSERT(reporter, !SkPictureGpuAnalyzer(picture).suitableForGpuRaste
rization()); |
310 | 310 |
311 // Nest the previous picture inside a new one. | 311 // Nest the previous picture inside a new one. |
312 canvas = recorder.beginRecording(100, 100); | 312 canvas = recorder.beginRecording(100, 100); |
313 { | 313 { |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 recorder->partialReplay(canvas); | 392 recorder->partialReplay(canvas); |
393 | 393 |
394 return recorder2.finishRecordingAsPicture(); | 394 return recorder2.finishRecordingAsPicture(); |
395 } | 395 } |
396 }; | 396 }; |
397 | 397 |
398 static void create_imbalance(SkCanvas* canvas) { | 398 static void create_imbalance(SkCanvas* canvas) { |
399 SkRect clipRect = SkRect::MakeWH(2, 2); | 399 SkRect clipRect = SkRect::MakeWH(2, 2); |
400 SkRect drawRect = SkRect::MakeWH(10, 10); | 400 SkRect drawRect = SkRect::MakeWH(10, 10); |
401 canvas->save(); | 401 canvas->save(); |
402 canvas->clipRect(clipRect, SkRegion::kReplace_Op); | 402 canvas->clipRect(clipRect, SkCanvas::kReplace_Op); |
403 canvas->translate(1.0f, 1.0f); | 403 canvas->translate(1.0f, 1.0f); |
404 SkPaint p; | 404 SkPaint p; |
405 p.setColor(SK_ColorGREEN); | 405 p.setColor(SK_ColorGREEN); |
406 canvas->drawRect(drawRect, p); | 406 canvas->drawRect(drawRect, p); |
407 // no restore | 407 // no restore |
408 } | 408 } |
409 | 409 |
410 // This tests that replaying a potentially unbalanced picture into a canvas | 410 // This tests that replaying a potentially unbalanced picture into a canvas |
411 // doesn't affect the canvas' save count or matrix/clip state. | 411 // doesn't affect the canvas' save count or matrix/clip state. |
412 static void check_balance(skiatest::Reporter* reporter, SkPicture* picture) { | 412 static void check_balance(skiatest::Reporter* reporter, SkPicture* picture) { |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
730 SkPath path; | 730 SkPath path; |
731 path.addOval(rect2); | 731 path.addOval(rect2); |
732 SkPath path2; | 732 SkPath path2; |
733 path2.addOval(rect3); | 733 path2.addOval(rect3); |
734 SkIRect clipBounds; | 734 SkIRect clipBounds; |
735 SkPictureRecorder recorder; | 735 SkPictureRecorder recorder; |
736 | 736 |
737 // Testing conservative-raster-clip that is enabled by PictureRecord | 737 // Testing conservative-raster-clip that is enabled by PictureRecord |
738 { | 738 { |
739 SkCanvas* canvas = recorder.beginRecording(10, 10); | 739 SkCanvas* canvas = recorder.beginRecording(10, 10); |
740 canvas->clipPath(invPath, SkRegion::kIntersect_Op); | 740 canvas->clipPath(invPath); |
741 bool nonEmpty = canvas->getClipDeviceBounds(&clipBounds); | 741 bool nonEmpty = canvas->getClipDeviceBounds(&clipBounds); |
742 REPORTER_ASSERT(reporter, true == nonEmpty); | 742 REPORTER_ASSERT(reporter, true == nonEmpty); |
743 REPORTER_ASSERT(reporter, 0 == clipBounds.fLeft); | 743 REPORTER_ASSERT(reporter, 0 == clipBounds.fLeft); |
744 REPORTER_ASSERT(reporter, 0 == clipBounds.fTop); | 744 REPORTER_ASSERT(reporter, 0 == clipBounds.fTop); |
745 REPORTER_ASSERT(reporter, 10 == clipBounds.fBottom); | 745 REPORTER_ASSERT(reporter, 10 == clipBounds.fBottom); |
746 REPORTER_ASSERT(reporter, 10 == clipBounds.fRight); | 746 REPORTER_ASSERT(reporter, 10 == clipBounds.fRight); |
747 } | 747 } |
748 { | 748 { |
749 SkCanvas* canvas = recorder.beginRecording(10, 10); | 749 SkCanvas* canvas = recorder.beginRecording(10, 10); |
750 canvas->clipPath(path, SkRegion::kIntersect_Op); | 750 canvas->clipPath(path); |
751 canvas->clipPath(invPath, SkRegion::kIntersect_Op); | 751 canvas->clipPath(invPath); |
752 bool nonEmpty = canvas->getClipDeviceBounds(&clipBounds); | 752 bool nonEmpty = canvas->getClipDeviceBounds(&clipBounds); |
753 REPORTER_ASSERT(reporter, true == nonEmpty); | 753 REPORTER_ASSERT(reporter, true == nonEmpty); |
754 REPORTER_ASSERT(reporter, 7 == clipBounds.fLeft); | 754 REPORTER_ASSERT(reporter, 7 == clipBounds.fLeft); |
755 REPORTER_ASSERT(reporter, 7 == clipBounds.fTop); | 755 REPORTER_ASSERT(reporter, 7 == clipBounds.fTop); |
756 REPORTER_ASSERT(reporter, 8 == clipBounds.fBottom); | 756 REPORTER_ASSERT(reporter, 8 == clipBounds.fBottom); |
757 REPORTER_ASSERT(reporter, 8 == clipBounds.fRight); | 757 REPORTER_ASSERT(reporter, 8 == clipBounds.fRight); |
758 } | 758 } |
759 { | 759 { |
760 SkCanvas* canvas = recorder.beginRecording(10, 10); | 760 SkCanvas* canvas = recorder.beginRecording(10, 10); |
761 canvas->clipPath(path, SkRegion::kIntersect_Op); | 761 canvas->clipPath(path); |
762 canvas->clipPath(invPath, SkRegion::kUnion_Op); | 762 canvas->clipPath(invPath, SkCanvas::kUnion_Op); |
763 bool nonEmpty = canvas->getClipDeviceBounds(&clipBounds); | 763 bool nonEmpty = canvas->getClipDeviceBounds(&clipBounds); |
764 REPORTER_ASSERT(reporter, true == nonEmpty); | 764 REPORTER_ASSERT(reporter, true == nonEmpty); |
765 REPORTER_ASSERT(reporter, 0 == clipBounds.fLeft); | 765 REPORTER_ASSERT(reporter, 0 == clipBounds.fLeft); |
766 REPORTER_ASSERT(reporter, 0 == clipBounds.fTop); | 766 REPORTER_ASSERT(reporter, 0 == clipBounds.fTop); |
767 REPORTER_ASSERT(reporter, 10 == clipBounds.fBottom); | 767 REPORTER_ASSERT(reporter, 10 == clipBounds.fBottom); |
768 REPORTER_ASSERT(reporter, 10 == clipBounds.fRight); | 768 REPORTER_ASSERT(reporter, 10 == clipBounds.fRight); |
769 } | 769 } |
770 { | 770 { |
771 SkCanvas* canvas = recorder.beginRecording(10, 10); | 771 SkCanvas* canvas = recorder.beginRecording(10, 10); |
772 canvas->clipPath(path, SkRegion::kDifference_Op); | 772 canvas->clipPath(path, SkCanvas::kDifference_Op); |
773 bool nonEmpty = canvas->getClipDeviceBounds(&clipBounds); | 773 bool nonEmpty = canvas->getClipDeviceBounds(&clipBounds); |
774 REPORTER_ASSERT(reporter, true == nonEmpty); | 774 REPORTER_ASSERT(reporter, true == nonEmpty); |
775 REPORTER_ASSERT(reporter, 0 == clipBounds.fLeft); | 775 REPORTER_ASSERT(reporter, 0 == clipBounds.fLeft); |
776 REPORTER_ASSERT(reporter, 0 == clipBounds.fTop); | 776 REPORTER_ASSERT(reporter, 0 == clipBounds.fTop); |
777 REPORTER_ASSERT(reporter, 10 == clipBounds.fBottom); | 777 REPORTER_ASSERT(reporter, 10 == clipBounds.fBottom); |
778 REPORTER_ASSERT(reporter, 10 == clipBounds.fRight); | 778 REPORTER_ASSERT(reporter, 10 == clipBounds.fRight); |
779 } | 779 } |
780 { | 780 { |
781 SkCanvas* canvas = recorder.beginRecording(10, 10); | 781 SkCanvas* canvas = recorder.beginRecording(10, 10); |
782 canvas->clipPath(path, SkRegion::kReverseDifference_Op); | 782 canvas->clipPath(path, SkCanvas::kReverseDifference_Op); |
783 bool nonEmpty = canvas->getClipDeviceBounds(&clipBounds); | 783 bool nonEmpty = canvas->getClipDeviceBounds(&clipBounds); |
784 // True clip is actually empty in this case, but the best | 784 // True clip is actually empty in this case, but the best |
785 // determination we can make using only bounds as input is that the | 785 // determination we can make using only bounds as input is that the |
786 // clip is included in the bounds of 'path'. | 786 // clip is included in the bounds of 'path'. |
787 REPORTER_ASSERT(reporter, true == nonEmpty); | 787 REPORTER_ASSERT(reporter, true == nonEmpty); |
788 REPORTER_ASSERT(reporter, 7 == clipBounds.fLeft); | 788 REPORTER_ASSERT(reporter, 7 == clipBounds.fLeft); |
789 REPORTER_ASSERT(reporter, 7 == clipBounds.fTop); | 789 REPORTER_ASSERT(reporter, 7 == clipBounds.fTop); |
790 REPORTER_ASSERT(reporter, 8 == clipBounds.fBottom); | 790 REPORTER_ASSERT(reporter, 8 == clipBounds.fBottom); |
791 REPORTER_ASSERT(reporter, 8 == clipBounds.fRight); | 791 REPORTER_ASSERT(reporter, 8 == clipBounds.fRight); |
792 } | 792 } |
793 { | 793 { |
794 SkCanvas* canvas = recorder.beginRecording(10, 10); | 794 SkCanvas* canvas = recorder.beginRecording(10, 10); |
795 canvas->clipPath(path, SkRegion::kIntersect_Op); | 795 canvas->clipPath(path, SkCanvas::kIntersect_Op); |
796 canvas->clipPath(path2, SkRegion::kXOR_Op); | 796 canvas->clipPath(path2, SkCanvas::kXOR_Op); |
797 bool nonEmpty = canvas->getClipDeviceBounds(&clipBounds); | 797 bool nonEmpty = canvas->getClipDeviceBounds(&clipBounds); |
798 REPORTER_ASSERT(reporter, true == nonEmpty); | 798 REPORTER_ASSERT(reporter, true == nonEmpty); |
799 REPORTER_ASSERT(reporter, 6 == clipBounds.fLeft); | 799 REPORTER_ASSERT(reporter, 6 == clipBounds.fLeft); |
800 REPORTER_ASSERT(reporter, 6 == clipBounds.fTop); | 800 REPORTER_ASSERT(reporter, 6 == clipBounds.fTop); |
801 REPORTER_ASSERT(reporter, 8 == clipBounds.fBottom); | 801 REPORTER_ASSERT(reporter, 8 == clipBounds.fBottom); |
802 REPORTER_ASSERT(reporter, 8 == clipBounds.fRight); | 802 REPORTER_ASSERT(reporter, 8 == clipBounds.fRight); |
803 } | 803 } |
804 } | 804 } |
805 | 805 |
806 static void test_cull_rect_reset(skiatest::Reporter* reporter) { | 806 static void test_cull_rect_reset(skiatest::Reporter* reporter) { |
(...skipping 27 matching lines...) Expand all Loading... |
834 /** | 834 /** |
835 * A canvas that records the number of clip commands. | 835 * A canvas that records the number of clip commands. |
836 */ | 836 */ |
837 class ClipCountingCanvas : public SkCanvas { | 837 class ClipCountingCanvas : public SkCanvas { |
838 public: | 838 public: |
839 ClipCountingCanvas(int width, int height) | 839 ClipCountingCanvas(int width, int height) |
840 : INHERITED(width, height) | 840 : INHERITED(width, height) |
841 , fClipCount(0){ | 841 , fClipCount(0){ |
842 } | 842 } |
843 | 843 |
844 virtual void onClipRect(const SkRect& r, | 844 void onClipRect(const SkRect& r, ClipOp op, ClipEdgeStyle edgeStyle) overrid
e { |
845 SkRegion::Op op, | |
846 ClipEdgeStyle edgeStyle) override { | |
847 fClipCount += 1; | 845 fClipCount += 1; |
848 this->INHERITED::onClipRect(r, op, edgeStyle); | 846 this->INHERITED::onClipRect(r, op, edgeStyle); |
849 } | 847 } |
850 | 848 |
851 virtual void onClipRRect(const SkRRect& rrect, | 849 void onClipRRect(const SkRRect& rrect, ClipOp op, ClipEdgeStyle edgeStyle)ov
erride { |
852 SkRegion::Op op, | |
853 ClipEdgeStyle edgeStyle)override { | |
854 fClipCount += 1; | 850 fClipCount += 1; |
855 this->INHERITED::onClipRRect(rrect, op, edgeStyle); | 851 this->INHERITED::onClipRRect(rrect, op, edgeStyle); |
856 } | 852 } |
857 | 853 |
858 virtual void onClipPath(const SkPath& path, | 854 void onClipPath(const SkPath& path, ClipOp op, ClipEdgeStyle edgeStyle) over
ride { |
859 SkRegion::Op op, | |
860 ClipEdgeStyle edgeStyle) override { | |
861 fClipCount += 1; | 855 fClipCount += 1; |
862 this->INHERITED::onClipPath(path, op, edgeStyle); | 856 this->INHERITED::onClipPath(path, op, edgeStyle); |
863 } | 857 } |
864 | 858 |
865 void onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op) override { | 859 void onClipRegion(const SkRegion& deviceRgn, ClipOp op) override { |
866 fClipCount += 1; | 860 fClipCount += 1; |
867 this->INHERITED::onClipRegion(deviceRgn, op); | 861 this->INHERITED::onClipRegion(deviceRgn, op); |
868 } | 862 } |
869 | 863 |
870 unsigned getClipCount() const { return fClipCount; } | 864 unsigned getClipCount() const { return fClipCount; } |
871 | 865 |
872 private: | 866 private: |
873 unsigned fClipCount; | 867 unsigned fClipCount; |
874 | 868 |
875 typedef SkCanvas INHERITED; | 869 typedef SkCanvas INHERITED; |
876 }; | 870 }; |
877 | 871 |
878 static void test_clip_expansion(skiatest::Reporter* reporter) { | 872 static void test_clip_expansion(skiatest::Reporter* reporter) { |
879 SkPictureRecorder recorder; | 873 SkPictureRecorder recorder; |
880 SkCanvas* canvas = recorder.beginRecording(10, 10); | 874 SkCanvas* canvas = recorder.beginRecording(10, 10); |
881 | 875 |
882 canvas->clipRect(SkRect::MakeEmpty(), SkRegion::kReplace_Op); | 876 canvas->clipRect(SkRect::MakeEmpty(), SkCanvas::kReplace_Op); |
883 // The following expanding clip should not be skipped. | 877 // The following expanding clip should not be skipped. |
884 canvas->clipRect(SkRect::MakeXYWH(4, 4, 3, 3), SkRegion::kUnion_Op); | 878 canvas->clipRect(SkRect::MakeXYWH(4, 4, 3, 3), SkCanvas::kUnion_Op); |
885 // Draw something so the optimizer doesn't just fold the world. | 879 // Draw something so the optimizer doesn't just fold the world. |
886 SkPaint p; | 880 SkPaint p; |
887 p.setColor(SK_ColorBLUE); | 881 p.setColor(SK_ColorBLUE); |
888 canvas->drawPaint(p); | 882 canvas->drawPaint(p); |
889 sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture()); | 883 sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture()); |
890 | 884 |
891 ClipCountingCanvas testCanvas(10, 10); | 885 ClipCountingCanvas testCanvas(10, 10); |
892 picture->playback(&testCanvas); | 886 picture->playback(&testCanvas); |
893 | 887 |
894 // Both clips should be present on playback. | 888 // Both clips should be present on playback. |
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1228 sk_sp<SkPicture> nestedVetoPicture(recorder.finishRecordingAsPicture()); | 1222 sk_sp<SkPicture> nestedVetoPicture(recorder.finishRecordingAsPicture()); |
1229 | 1223 |
1230 analyzer.analyzePicture(nestedVetoPicture.get()); | 1224 analyzer.analyzePicture(nestedVetoPicture.get()); |
1231 REPORTER_ASSERT(r, !analyzer.suitableForGpuRasterization()); | 1225 REPORTER_ASSERT(r, !analyzer.suitableForGpuRasterization()); |
1232 | 1226 |
1233 analyzer.reset(); | 1227 analyzer.reset(); |
1234 | 1228 |
1235 const SkPath convexClip = make_convex_path(); | 1229 const SkPath convexClip = make_convex_path(); |
1236 const SkPath concaveClip = make_concave_path(); | 1230 const SkPath concaveClip = make_concave_path(); |
1237 for (int i = 0; i < 50; ++i) { | 1231 for (int i = 0; i < 50; ++i) { |
1238 analyzer.analyzeClipPath(convexClip, SkRegion::kIntersect_Op, false); | 1232 analyzer.analyzeClipPath(convexClip, SkCanvas::kIntersect_Op, false); |
1239 analyzer.analyzeClipPath(convexClip, SkRegion::kIntersect_Op, true); | 1233 analyzer.analyzeClipPath(convexClip, SkCanvas::kIntersect_Op, true); |
1240 analyzer.analyzeClipPath(concaveClip, SkRegion::kIntersect_Op, false); | 1234 analyzer.analyzeClipPath(concaveClip, SkCanvas::kIntersect_Op, false); |
1241 } | 1235 } |
1242 REPORTER_ASSERT(r, analyzer.suitableForGpuRasterization()); | 1236 REPORTER_ASSERT(r, analyzer.suitableForGpuRasterization()); |
1243 | 1237 |
1244 for (int i = 0; i < 50; ++i) { | 1238 for (int i = 0; i < 50; ++i) { |
1245 analyzer.analyzeClipPath(concaveClip, SkRegion::kIntersect_Op, true); | 1239 analyzer.analyzeClipPath(concaveClip, SkCanvas::kIntersect_Op, true); |
1246 } | 1240 } |
1247 REPORTER_ASSERT(r, !analyzer.suitableForGpuRasterization()); | 1241 REPORTER_ASSERT(r, !analyzer.suitableForGpuRasterization()); |
1248 } | 1242 } |
1249 | 1243 |
1250 #endif // SK_SUPPORT_GPU | 1244 #endif // SK_SUPPORT_GPU |
1251 | 1245 |
1252 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 1246 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
1253 | 1247 |
1254 // Disable until we properly fix https://bugs.chromium.org/p/skia/issues/detail?
id=5548 | 1248 // Disable until we properly fix https://bugs.chromium.org/p/skia/issues/detail?
id=5548 |
1255 #if 0 | 1249 #if 0 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1305 SkPictureRecorder rec; | 1299 SkPictureRecorder rec; |
1306 proc(rec.beginRecording(cull)); | 1300 proc(rec.beginRecording(cull)); |
1307 sk_sp<SkDrawable> dr = rec.finishRecordingAsDrawable( | 1301 sk_sp<SkDrawable> dr = rec.finishRecordingAsDrawable( |
1308 SkPictureRecorder::kReturnNullF
orEmpty_FinishFlag); | 1302 SkPictureRecorder::kReturnNullF
orEmpty_FinishFlag); |
1309 REPORTER_ASSERT(r, !dr.get()); | 1303 REPORTER_ASSERT(r, !dr.get()); |
1310 } | 1304 } |
1311 } | 1305 } |
1312 } | 1306 } |
1313 #endif | 1307 #endif |
1314 | 1308 |
OLD | NEW |