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/SkBitmap.h"
9 #include "include/core/SkCanvas.h"
10 #include "include/core/SkPaint.h"
11 #include "include/core/SkPicture.h"
12 #include "include/core/SkPictureRecorder.h"
13 #include "src/core/SkBBoxHierarchy.h"
14 #include "src/core/SkRectPriv.h"
15
16 #include "tests/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(PictureNegativeSpace,r)97 DEF_TEST(PictureNegativeSpace, r) {
98 SkRTreeFactory factory;
99 SkPictureRecorder recorder;
100
101 SkRect cull = {-200,-200,+200,+200};
102
103 {
104 auto canvas = recorder.beginRecording(cull, &factory);
105 canvas->save();
106 canvas->clipRect(cull);
107 canvas->drawRect({-20,-20,-10,-10}, SkPaint{});
108 canvas->drawRect({-20,-20,-10,-10}, SkPaint{});
109 canvas->restore();
110 auto pic = recorder.finishRecordingAsPicture();
111 REPORTER_ASSERT(r, pic->approximateOpCount() == 5);
112 REPORTER_ASSERT(r, pic->cullRect() == (SkRect{-20,-20,-10,-10}));
113 }
114
115 {
116 auto canvas = recorder.beginRecording(cull, &factory);
117 canvas->clipRect(cull);
118 canvas->drawRect({-20,-20,-10,-10}, SkPaint{});
119 canvas->drawRect({-20,-20,-10,-10}, SkPaint{});
120 auto pic = recorder.finishRecordingAsPicture();
121 REPORTER_ASSERT(r, pic->approximateOpCount() == 3);
122 REPORTER_ASSERT(r, pic->cullRect() == (SkRect{-20,-20,-10,-10}));
123 }
124 }
125