xref: /aosp_15_r20/external/skia/tests/PictureBBHTest.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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 "include/core/SkBBHFactory.h"
9 #include "include/core/SkBitmap.h"
10 #include "include/core/SkCanvas.h"
11 #include "include/core/SkColor.h"
12 #include "include/core/SkPaint.h"
13 #include "include/core/SkPicture.h"
14 #include "include/core/SkPictureRecorder.h"
15 #include "include/core/SkRect.h"
16 #include "include/core/SkRefCnt.h"
17 #include "include/core/SkScalar.h"
18 #include "tests/Test.h"
19 
20 class PictureBBHTestBase {
21 public:
PictureBBHTestBase(int playbackWidth,int playbackHeight,int recordWidth,int recordHeight)22     PictureBBHTestBase(int playbackWidth, int playbackHeight,
23         int recordWidth, int recordHeight) {
24 
25         fResultBitmap.allocN32Pixels(playbackWidth, playbackHeight);
26         fPictureWidth = recordWidth;
27         fPictureHeight = recordHeight;
28     }
29 
~PictureBBHTestBase()30     virtual ~PictureBBHTestBase() { }
31 
32     virtual void doTest(SkCanvas& playbackCanvas, SkCanvas& recordingCanvas) = 0;
33 
run(skiatest::Reporter * reporter)34     void run(skiatest::Reporter* reporter) {
35         // No BBH
36         this->run(nullptr, reporter);
37 
38         // With an R-Tree
39         SkRTreeFactory RTreeFactory;
40         this->run(&RTreeFactory, reporter);
41     }
42 
43 private:
run(SkBBHFactory * factory,skiatest::Reporter * reporter)44     void run(SkBBHFactory* factory, skiatest::Reporter* reporter) {
45         SkCanvas playbackCanvas(fResultBitmap);
46         playbackCanvas.clear(SK_ColorGREEN);
47         SkPictureRecorder recorder;
48         SkCanvas* recordCanvas = recorder.beginRecording(SkIntToScalar(fPictureWidth),
49                                                          SkIntToScalar(fPictureHeight),
50                                                          factory);
51         this->doTest(playbackCanvas, *recordCanvas);
52         sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture());
53         playbackCanvas.drawPicture(picture);
54         REPORTER_ASSERT(reporter, SK_ColorGREEN == fResultBitmap.getColor(0, 0));
55     }
56 
57     SkBitmap fResultBitmap;
58     int fPictureWidth, fPictureHeight;
59 };
60 
61 // Test to verify the playback of an empty picture
62 //
63 class DrawEmptyPictureBBHTest : public PictureBBHTestBase {
64 public:
DrawEmptyPictureBBHTest()65     DrawEmptyPictureBBHTest()
66         : PictureBBHTestBase(2, 2, 1, 1) {}
~DrawEmptyPictureBBHTest()67     ~DrawEmptyPictureBBHTest() override {}
68 
doTest(SkCanvas &,SkCanvas &)69     void doTest(SkCanvas&, SkCanvas&) override {}
70 };
71 
72 // Test to verify the playback of a picture into a canvas that has
73 // an empty clip.
74 //
75 class EmptyClipPictureBBHTest : public PictureBBHTestBase {
76 public:
EmptyClipPictureBBHTest()77     EmptyClipPictureBBHTest()
78         : PictureBBHTestBase(2, 2, 3, 3) {}
79 
doTest(SkCanvas & playbackCanvas,SkCanvas & recordingCanvas)80     void doTest(SkCanvas& playbackCanvas, SkCanvas& recordingCanvas) override {
81         // intersect with out of bounds rect -> empty clip.
82         playbackCanvas.clipRect(SkRect::MakeXYWH(10, 10, 1, 1));
83         SkPaint paint;
84         recordingCanvas.drawRect(SkRect::MakeWH(3, 3), paint);
85     }
86 
~EmptyClipPictureBBHTest()87     ~EmptyClipPictureBBHTest() override {}
88 };
89 
DEF_TEST(PictureBBH,reporter)90 DEF_TEST(PictureBBH, reporter) {
91 
92     DrawEmptyPictureBBHTest emptyPictureTest;
93     emptyPictureTest.run(reporter);
94 
95     EmptyClipPictureBBHTest emptyClipPictureTest;
96     emptyClipPictureTest.run(reporter);
97 }
98 
DEF_TEST(PictureNegativeSpace,r)99 DEF_TEST(PictureNegativeSpace, r) {
100     SkRTreeFactory factory;
101     SkPictureRecorder recorder;
102 
103     SkRect cull = {-200,-200,+200,+200};
104 
105     {
106         sk_sp<SkBBoxHierarchy> bbh = factory();
107         auto canvas = recorder.beginRecording(cull, bbh);
108             canvas->save();
109             canvas->clipRect(cull);
110             canvas->drawRect({-20,-20,-10,-10}, SkPaint{});
111             canvas->drawRect({-20,-20,-10,-10}, SkPaint{});
112             canvas->restore();
113         auto pic = recorder.finishRecordingAsPicture();
114         REPORTER_ASSERT(r, pic->approximateOpCount() == 5);
115         REPORTER_ASSERT(r, pic->cullRect() == (SkRect{-20,-20,-10,-10}));
116     }
117 
118     {
119         auto canvas = recorder.beginRecording(cull, &factory);
120             canvas->clipRect(cull);
121             canvas->drawRect({-20,-20,-10,-10}, SkPaint{});
122             canvas->drawRect({-20,-20,-10,-10}, SkPaint{});
123         auto pic = recorder.finishRecordingAsPicture();
124         REPORTER_ASSERT(r, pic->approximateOpCount() == 3);
125         REPORTER_ASSERT(r, pic->cullRect() == (SkRect{-20,-20,-10,-10}));
126     }
127 }
128