1 /* 2 * Copyright 2014 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "SkBitmap.h" 9 #include "SkCanvas.h" 10 #include "SkBBoxHierarchy.h" 11 #include "SkPaint.h" 12 #include "SkPicture.h" 13 #include "SkPictureRecorder.h" 14 #include "SkRectPriv.h" 15 16 #include "Test.h" 17 18 class PictureBBHTestBase { 19 public: 20 PictureBBHTestBase(int playbackWidth, int playbackHeight, 21 int recordWidth, int recordHeight) { 22 23 fResultBitmap.allocN32Pixels(playbackWidth, playbackHeight); 24 fPictureWidth = recordWidth; 25 fPictureHeight = recordHeight; 26 } 27 28 virtual ~PictureBBHTestBase() { } 29 30 virtual void doTest(SkCanvas& playbackCanvas, SkCanvas& recordingCanvas) = 0; 31 32 void run(skiatest::Reporter* reporter) { 33 // No BBH 34 this->run(nullptr, reporter); 35 36 // With an R-Tree 37 SkRTreeFactory RTreeFactory; 38 this->run(&RTreeFactory, reporter); 39 } 40 41 private: 42 void run(SkBBHFactory* factory, skiatest::Reporter* reporter) { 43 SkCanvas playbackCanvas(fResultBitmap); 44 playbackCanvas.clear(SK_ColorGREEN); 45 SkPictureRecorder recorder; 46 SkCanvas* recordCanvas = recorder.beginRecording(SkIntToScalar(fPictureWidth), 47 SkIntToScalar(fPictureHeight), 48 factory); 49 this->doTest(playbackCanvas, *recordCanvas); 50 sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture()); 51 playbackCanvas.drawPicture(picture); 52 REPORTER_ASSERT(reporter, SK_ColorGREEN == fResultBitmap.getColor(0, 0)); 53 } 54 55 SkBitmap fResultBitmap; 56 int fPictureWidth, fPictureHeight; 57 }; 58 59 // Test to verify the playback of an empty picture 60 // 61 class DrawEmptyPictureBBHTest : public PictureBBHTestBase { 62 public: 63 DrawEmptyPictureBBHTest() 64 : PictureBBHTestBase(2, 2, 1, 1) {} 65 ~DrawEmptyPictureBBHTest() override {} 66 67 void doTest(SkCanvas&, SkCanvas&) override {} 68 }; 69 70 // Test to verify the playback of a picture into a canvas that has 71 // an empty clip. 72 // 73 class EmptyClipPictureBBHTest : public PictureBBHTestBase { 74 public: 75 EmptyClipPictureBBHTest() 76 : PictureBBHTestBase(2, 2, 3, 3) {} 77 78 void doTest(SkCanvas& playbackCanvas, SkCanvas& recordingCanvas) override { 79 // intersect with out of bounds rect -> empty clip. 80 playbackCanvas.clipRect(SkRect::MakeXYWH(10, 10, 1, 1)); 81 SkPaint paint; 82 recordingCanvas.drawRect(SkRect::MakeWH(3, 3), paint); 83 } 84 85 ~EmptyClipPictureBBHTest() override {} 86 }; 87 88 DEF_TEST(PictureBBH, reporter) { 89 90 DrawEmptyPictureBBHTest emptyPictureTest; 91 emptyPictureTest.run(reporter); 92 93 EmptyClipPictureBBHTest emptyClipPictureTest; 94 emptyClipPictureTest.run(reporter); 95 } 96 97 DEF_TEST(RTreeMakeLargest, r) { 98 // A call to insert() with 2 or more rects and a bounds of SkRect::MakeLargest() 99 // used to fall into an infinite loop. 100 101 SkRTreeFactory factory; 102 std::unique_ptr<SkBBoxHierarchy> bbh{ factory(SkRectPriv::MakeLargest()) }; 103 104 SkRect rects[] = { {0,0, 10,10}, {5,5,15,15} }; 105 bbh->insert(rects, SK_ARRAY_COUNT(rects)); 106 REPORTER_ASSERT(r, bbh->getRootBound() == SkRect::MakeWH(15,15)); 107 } 108 109 DEF_TEST(PictureNegativeSpace, r) { 110 SkRTreeFactory factory; 111 SkPictureRecorder recorder; 112 113 SkRect cull = {-200,-200,+200,+200}; 114 115 { 116 auto canvas = recorder.beginRecording(cull, &factory); 117 canvas->save(); 118 canvas->clipRect(cull); 119 canvas->drawRect({-20,-20,-10,-10}, SkPaint{}); 120 canvas->drawRect({-20,-20,-10,-10}, SkPaint{}); 121 canvas->restore(); 122 auto pic = recorder.finishRecordingAsPicture(); 123 REPORTER_ASSERT(r, pic->approximateOpCount() == 5); 124 REPORTER_ASSERT(r, pic->cullRect() == (SkRect{-20,-20,-10,-10})); 125 } 126 127 { 128 auto canvas = recorder.beginRecording(cull, &factory); 129 canvas->clipRect(cull); 130 canvas->drawRect({-20,-20,-10,-10}, SkPaint{}); 131 canvas->drawRect({-20,-20,-10,-10}, SkPaint{}); 132 auto pic = recorder.finishRecordingAsPicture(); 133 REPORTER_ASSERT(r, pic->approximateOpCount() == 3); 134 REPORTER_ASSERT(r, pic->cullRect() == (SkRect{-20,-20,-10,-10})); 135 } 136 } 137