• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
PictureBBHTestBase(int playbackWidth,int playbackHeight,int recordWidth,int recordHeight)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 
~PictureBBHTestBase()28     virtual ~PictureBBHTestBase() { }
29 
30     virtual void doTest(SkCanvas& playbackCanvas, SkCanvas& recordingCanvas) = 0;
31 
run(skiatest::Reporter * reporter)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:
run(SkBBHFactory * factory,skiatest::Reporter * reporter)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:
DrawEmptyPictureBBHTest()63     DrawEmptyPictureBBHTest()
64         : PictureBBHTestBase(2, 2, 1, 1) {}
~DrawEmptyPictureBBHTest()65     ~DrawEmptyPictureBBHTest() override {}
66 
doTest(SkCanvas &,SkCanvas &)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:
EmptyClipPictureBBHTest()75     EmptyClipPictureBBHTest()
76         : PictureBBHTestBase(2, 2, 3, 3) {}
77 
doTest(SkCanvas & playbackCanvas,SkCanvas & recordingCanvas)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 
~EmptyClipPictureBBHTest()85     ~EmptyClipPictureBBHTest() override {}
86 };
87 
DEF_TEST(PictureBBH,reporter)88 DEF_TEST(PictureBBH, reporter) {
89 
90     DrawEmptyPictureBBHTest emptyPictureTest;
91     emptyPictureTest.run(reporter);
92 
93     EmptyClipPictureBBHTest emptyClipPictureTest;
94     emptyClipPictureTest.run(reporter);
95 }
96 
DEF_TEST(RTreeMakeLargest,r)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 
DEF_TEST(PictureNegativeSpace,r)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