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