blob: 78acda79d52017c261341768ca40b8a3e58bd2a2 [file] [log] [blame]
junova41d3c32014-10-30 11:44:19 -07001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#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"
junova41d3c32014-10-30 11:44:19 -070015
Mike Kleinc0bd9f92019-04-23 12:05:21 -050016#include "tests/Test.h"
junova41d3c32014-10-30 11:44:19 -070017
18class PictureBBHTestBase {
19public:
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
28 virtual ~PictureBBHTestBase() { }
29
30 virtual void doTest(SkCanvas& playbackCanvas, SkCanvas& recordingCanvas) = 0;
31
32 void run(skiatest::Reporter* reporter) {
33 // No BBH
halcanary96fcdcc2015-08-27 07:41:13 -070034 this->run(nullptr, reporter);
junova41d3c32014-10-30 11:44:19 -070035
junova41d3c32014-10-30 11:44:19 -070036 // With an R-Tree
37 SkRTreeFactory RTreeFactory;
38 this->run(&RTreeFactory, reporter);
39 }
40
41private:
42 void run(SkBBHFactory* factory, skiatest::Reporter* reporter) {
43 SkCanvas playbackCanvas(fResultBitmap);
44 playbackCanvas.clear(SK_ColorGREEN);
45 SkPictureRecorder recorder;
mtklein7cc1a342014-11-20 08:01:09 -080046 SkCanvas* recordCanvas = recorder.beginRecording(SkIntToScalar(fPictureWidth),
47 SkIntToScalar(fPictureHeight),
48 factory);
junova41d3c32014-10-30 11:44:19 -070049 this->doTest(playbackCanvas, *recordCanvas);
reedca2622b2016-03-18 07:25:55 -070050 sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture());
junova41d3c32014-10-30 11:44:19 -070051 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
mtklein49aabde2015-01-05 07:02:45 -080060//
junova41d3c32014-10-30 11:44:19 -070061class DrawEmptyPictureBBHTest : public PictureBBHTestBase {
62public:
63 DrawEmptyPictureBBHTest()
Brian Salomond3b65972017-03-22 12:05:03 -040064 : PictureBBHTestBase(2, 2, 1, 1) {}
65 ~DrawEmptyPictureBBHTest() override {}
junova41d3c32014-10-30 11:44:19 -070066
Brian Salomond3b65972017-03-22 12:05:03 -040067 void doTest(SkCanvas&, SkCanvas&) override {}
junova41d3c32014-10-30 11:44:19 -070068};
69
70// Test to verify the playback of a picture into a canvas that has
71// an empty clip.
72//
73class EmptyClipPictureBBHTest : public PictureBBHTestBase {
74public:
mtklein49aabde2015-01-05 07:02:45 -080075 EmptyClipPictureBBHTest()
Brian Salomond3b65972017-03-22 12:05:03 -040076 : PictureBBHTestBase(2, 2, 3, 3) {}
junova41d3c32014-10-30 11:44:19 -070077
mtklein36352bf2015-03-25 18:17:31 -070078 void doTest(SkCanvas& playbackCanvas, SkCanvas& recordingCanvas) override {
junova41d3c32014-10-30 11:44:19 -070079 // intersect with out of bounds rect -> empty clip.
reed73603f32016-09-20 08:42:38 -070080 playbackCanvas.clipRect(SkRect::MakeXYWH(10, 10, 1, 1));
junova41d3c32014-10-30 11:44:19 -070081 SkPaint paint;
reed73603f32016-09-20 08:42:38 -070082 recordingCanvas.drawRect(SkRect::MakeWH(3, 3), paint);
junova41d3c32014-10-30 11:44:19 -070083 }
84
Brian Salomond3b65972017-03-22 12:05:03 -040085 ~EmptyClipPictureBBHTest() override {}
junova41d3c32014-10-30 11:44:19 -070086};
87
88DEF_TEST(PictureBBH, reporter) {
89
90 DrawEmptyPictureBBHTest emptyPictureTest;
91 emptyPictureTest.run(reporter);
92
93 EmptyClipPictureBBHTest emptyClipPictureTest;
94 emptyClipPictureTest.run(reporter);
95}
Mike Klein1dd161c2017-04-07 10:46:39 -040096
Mike Klein738b80d2018-05-04 13:51:11 -040097DEF_TEST(PictureNegativeSpace, r) {
98 SkRTreeFactory factory;
99 SkPictureRecorder recorder;
100
101 SkRect cull = {-200,-200,+200,+200};
102
103 {
Mike Klein196e9fb2020-01-21 10:48:46 -0600104 sk_sp<SkBBoxHierarchy> bbh = factory();
Mike Klein1feceb32020-01-21 11:16:37 -0600105 auto base = (SkBBoxHierarchy_Base*)bbh.get();
Mike Klein196e9fb2020-01-21 10:48:46 -0600106 auto canvas = recorder.beginRecording(cull, bbh);
Mike Klein738b80d2018-05-04 13:51:11 -0400107 canvas->save();
108 canvas->clipRect(cull);
109 canvas->drawRect({-20,-20,-10,-10}, SkPaint{});
110 canvas->drawRect({-20,-20,-10,-10}, SkPaint{});
111 canvas->restore();
112 auto pic = recorder.finishRecordingAsPicture();
113 REPORTER_ASSERT(r, pic->approximateOpCount() == 5);
114 REPORTER_ASSERT(r, pic->cullRect() == (SkRect{-20,-20,-10,-10}));
Mike Klein196e9fb2020-01-21 10:48:46 -0600115
Mike Klein1feceb32020-01-21 11:16:37 -0600116 REPORTER_ASSERT(r, base->getRootBound() == (SkRect{-20,-20,-10,-10}));
Mike Klein738b80d2018-05-04 13:51:11 -0400117 }
118
Mike Kleinad67c662018-05-07 10:56:40 -0400119 {
Mike Klein738b80d2018-05-04 13:51:11 -0400120 auto canvas = recorder.beginRecording(cull, &factory);
121 canvas->clipRect(cull);
122 canvas->drawRect({-20,-20,-10,-10}, SkPaint{});
123 canvas->drawRect({-20,-20,-10,-10}, SkPaint{});
124 auto pic = recorder.finishRecordingAsPicture();
125 REPORTER_ASSERT(r, pic->approximateOpCount() == 3);
126 REPORTER_ASSERT(r, pic->cullRect() == (SkRect{-20,-20,-10,-10}));
127 }
128}