xref: /third_party/skia/tests/PictureBBHTest.cpp (revision cb93a386)
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
17class PictureBBHTestBase {
18public:
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
27    virtual ~PictureBBHTestBase() { }
28
29    virtual void doTest(SkCanvas& playbackCanvas, SkCanvas& recordingCanvas) = 0;
30
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
40private:
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//
60class DrawEmptyPictureBBHTest : public PictureBBHTestBase {
61public:
62    DrawEmptyPictureBBHTest()
63        : PictureBBHTestBase(2, 2, 1, 1) {}
64    ~DrawEmptyPictureBBHTest() override {}
65
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//
72class EmptyClipPictureBBHTest : public PictureBBHTestBase {
73public:
74    EmptyClipPictureBBHTest()
75        : PictureBBHTestBase(2, 2, 3, 3) {}
76
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
84    ~EmptyClipPictureBBHTest() override {}
85};
86
87DEF_TEST(PictureBBH, reporter) {
88
89    DrawEmptyPictureBBHTest emptyPictureTest;
90    emptyPictureTest.run(reporter);
91
92    EmptyClipPictureBBHTest emptyClipPictureTest;
93    emptyClipPictureTest.run(reporter);
94}
95
96DEF_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