blob: 5e5d13485942c6be55cb563d651af9d5ce511aec [file] [log] [blame]
Stan Iliev500a0c32016-10-26 10:30:09 -04001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Stan Iliev500a0c32016-10-26 10:30:09 -040017#include <VectorDrawable.h>
John Reck1bcacfd2017-11-03 10:12:19 -070018#include <gtest/gtest.h>
Stan Iliev500a0c32016-10-26 10:30:09 -040019
Stan Iliev52771272016-11-17 09:54:38 -050020#include <SkClipStack.h>
Stan Iliev52771272016-11-17 09:54:38 -050021#include <SkSurface_Base.h>
Stan Iliev500a0c32016-10-26 10:30:09 -040022#include <string.h>
John Reck1bcacfd2017-11-03 10:12:19 -070023#include "AnimationContext.h"
24#include "DamageAccumulator.h"
25#include "IContextFactory.h"
26#include "SkiaCanvas.h"
27#include "pipeline/skia/SkiaDisplayList.h"
28#include "pipeline/skia/SkiaOpenGLPipeline.h"
29#include "pipeline/skia/SkiaRecordingCanvas.h"
30#include "renderthread/CanvasContext.h"
31#include "tests/common/TestUtils.h"
Stan Iliev500a0c32016-10-26 10:30:09 -040032
33using namespace android;
34using namespace android::uirenderer;
35using namespace android::uirenderer::renderthread;
36using namespace android::uirenderer::skiapipeline;
37
Greg Daniel98c78dad2017-01-04 14:45:56 -050038RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderFrame) {
John Reck1bcacfd2017-11-03 10:12:19 -070039 auto redNode = TestUtils::createSkiaNode(
40 0, 0, 1, 1, [](RenderProperties& props, SkiaRecordingCanvas& redCanvas) {
41 redCanvas.drawColor(SK_ColorRED, SkBlendMode::kSrcOver);
42 });
Stan Iliev500a0c32016-10-26 10:30:09 -040043 LayerUpdateQueue layerUpdateQueue;
44 SkRect dirty = SkRect::MakeLargest();
45 std::vector<sp<RenderNode>> renderNodes;
46 renderNodes.push_back(redNode);
47 bool opaque = true;
48 android::uirenderer::Rect contentDrawBounds(0, 0, 1, 1);
49 auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
50 auto surface = SkSurface::MakeRasterN32Premul(1, 1);
51 surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
52 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
Peiyong Lin1f6aa122018-09-10 16:28:08 -070053 pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds,
John Reck1bcacfd2017-11-03 10:12:19 -070054 surface);
Stan Iliev500a0c32016-10-26 10:30:09 -040055 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorRED);
56}
57
Stan Iliev47fed6ba2017-10-18 17:56:43 -040058RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, testOnPrepareTree) {
John Reck1bcacfd2017-11-03 10:12:19 -070059 auto redNode = TestUtils::createSkiaNode(
60 0, 0, 1, 1, [](RenderProperties& props, SkiaRecordingCanvas& redCanvas) {
61 redCanvas.drawColor(SK_ColorRED, SkBlendMode::kSrcOver);
62 });
Stan Iliev47fed6ba2017-10-18 17:56:43 -040063
64 LayerUpdateQueue layerUpdateQueue;
65 SkRect dirty = SkRect::MakeLargest();
66 std::vector<sp<RenderNode>> renderNodes;
67 renderNodes.push_back(redNode);
68 bool opaque = true;
69 android::uirenderer::Rect contentDrawBounds(0, 0, 1, 1);
70 auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
71 {
John Reck1bcacfd2017-11-03 10:12:19 -070072 // add a pointer to a deleted vector drawable object in the pipeline
Stan Iliev47fed6ba2017-10-18 17:56:43 -040073 sp<VectorDrawableRoot> dirtyVD(new VectorDrawableRoot(new VectorDrawable::Group()));
John Reck1bcacfd2017-11-03 10:12:19 -070074 dirtyVD->mutateProperties()->setScaledSize(5, 5);
Stan Iliev47fed6ba2017-10-18 17:56:43 -040075 pipeline->getVectorDrawables()->push_back(dirtyVD.get());
76 }
77
John Reck1bcacfd2017-11-03 10:12:19 -070078 // pipeline should clean list of dirty vector drawables before prepare tree
Stan Iliev47fed6ba2017-10-18 17:56:43 -040079 pipeline->onPrepareTree();
80
81 auto surface = SkSurface::MakeRasterN32Premul(1, 1);
82 surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
83 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
84
John Reck1bcacfd2017-11-03 10:12:19 -070085 // drawFrame will crash if "SkiaPipeline::onPrepareTree" did not clean invalid VD pointer
Peiyong Lin1f6aa122018-09-10 16:28:08 -070086 pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds,
John Reck1bcacfd2017-11-03 10:12:19 -070087 surface);
Stan Iliev47fed6ba2017-10-18 17:56:43 -040088 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorRED);
89}
90
Greg Daniel98c78dad2017-01-04 14:45:56 -050091RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderFrameCheckOpaque) {
John Reck1bcacfd2017-11-03 10:12:19 -070092 auto halfGreenNode = TestUtils::createSkiaNode(
93 0, 0, 2, 2, [](RenderProperties& props, SkiaRecordingCanvas& bottomHalfGreenCanvas) {
94 SkPaint greenPaint;
95 greenPaint.setColor(SK_ColorGREEN);
96 greenPaint.setStyle(SkPaint::kFill_Style);
97 bottomHalfGreenCanvas.drawRect(0, 1, 2, 2, greenPaint);
98 });
Stan Iliev500a0c32016-10-26 10:30:09 -040099 LayerUpdateQueue layerUpdateQueue;
100 SkRect dirty = SkRect::MakeLargest();
101 std::vector<sp<RenderNode>> renderNodes;
102 renderNodes.push_back(halfGreenNode);
103 android::uirenderer::Rect contentDrawBounds(0, 0, 2, 2);
104 auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
105 auto surface = SkSurface::MakeRasterN32Premul(2, 2);
106 surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
107 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
Peiyong Lin1f6aa122018-09-10 16:28:08 -0700108 pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, true, contentDrawBounds,
John Reck1bcacfd2017-11-03 10:12:19 -0700109 surface);
Stan Iliev500a0c32016-10-26 10:30:09 -0400110 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
111 ASSERT_EQ(TestUtils::getColor(surface, 0, 1), SK_ColorGREEN);
Peiyong Lin1f6aa122018-09-10 16:28:08 -0700112 pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, false, contentDrawBounds,
John Reck1bcacfd2017-11-03 10:12:19 -0700113 surface);
Stan Iliev500a0c32016-10-26 10:30:09 -0400114 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned int)SK_ColorTRANSPARENT);
115 ASSERT_EQ(TestUtils::getColor(surface, 0, 1), SK_ColorGREEN);
116}
117
Greg Daniel98c78dad2017-01-04 14:45:56 -0500118RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderFrameCheckDirtyRect) {
John Reck1bcacfd2017-11-03 10:12:19 -0700119 auto redNode = TestUtils::createSkiaNode(
120 0, 0, 2, 2, [](RenderProperties& props, SkiaRecordingCanvas& redCanvas) {
121 redCanvas.drawColor(SK_ColorRED, SkBlendMode::kSrcOver);
122 });
Stan Iliev500a0c32016-10-26 10:30:09 -0400123 LayerUpdateQueue layerUpdateQueue;
124 SkRect dirty = SkRect::MakeXYWH(0, 1, 2, 1);
125 std::vector<sp<RenderNode>> renderNodes;
126 renderNodes.push_back(redNode);
127 android::uirenderer::Rect contentDrawBounds(0, 0, 2, 2);
128 auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
129 auto surface = SkSurface::MakeRasterN32Premul(2, 2);
130 surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
131 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
Peiyong Lin1f6aa122018-09-10 16:28:08 -0700132 pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, true, contentDrawBounds,
John Reck1bcacfd2017-11-03 10:12:19 -0700133 surface);
Stan Iliev500a0c32016-10-26 10:30:09 -0400134 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
135 ASSERT_EQ(TestUtils::getColor(surface, 1, 0), SK_ColorBLUE);
136 ASSERT_EQ(TestUtils::getColor(surface, 0, 1), SK_ColorRED);
137 ASSERT_EQ(TestUtils::getColor(surface, 1, 1), SK_ColorRED);
138}
139
Greg Daniel98c78dad2017-01-04 14:45:56 -0500140RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderLayer) {
John Reck1bcacfd2017-11-03 10:12:19 -0700141 auto redNode = TestUtils::createSkiaNode(
142 0, 0, 1, 1, [](RenderProperties& props, SkiaRecordingCanvas& redCanvas) {
143 redCanvas.drawColor(SK_ColorRED, SkBlendMode::kSrcOver);
144 });
Stan Iliev500a0c32016-10-26 10:30:09 -0400145 auto surfaceLayer1 = SkSurface::MakeRasterN32Premul(1, 1);
146 surfaceLayer1->getCanvas()->drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver);
147 ASSERT_EQ(TestUtils::getColor(surfaceLayer1, 0, 0), SK_ColorWHITE);
148 redNode->setLayerSurface(surfaceLayer1);
149
John Reck1bcacfd2017-11-03 10:12:19 -0700150 // create a 2nd 2x2 layer and add it to the queue as well.
151 // make the layer's dirty area one half of the layer and verify only the dirty half is updated.
152 auto blueNode = TestUtils::createSkiaNode(
153 0, 0, 2, 2, [](RenderProperties& props, SkiaRecordingCanvas& blueCanvas) {
154 blueCanvas.drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
155 });
Stan Iliev500a0c32016-10-26 10:30:09 -0400156 auto surfaceLayer2 = SkSurface::MakeRasterN32Premul(2, 2);
157 surfaceLayer2->getCanvas()->drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver);
158 ASSERT_EQ(TestUtils::getColor(surfaceLayer2, 0, 0), SK_ColorWHITE);
159 blueNode->setLayerSurface(surfaceLayer2);
160
John Reck1bcacfd2017-11-03 10:12:19 -0700161 // attach both layers to the update queue
Stan Iliev500a0c32016-10-26 10:30:09 -0400162 LayerUpdateQueue layerUpdateQueue;
163 SkRect dirty = SkRect::MakeLargest();
164 layerUpdateQueue.enqueueLayerWithDamage(redNode.get(), dirty);
165 layerUpdateQueue.enqueueLayerWithDamage(blueNode.get(), SkRect::MakeWH(2, 1));
166 ASSERT_EQ(layerUpdateQueue.entries().size(), 2UL);
167
168 bool opaque = true;
John Reckd9d7f122018-05-03 14:40:56 -0700169 LightGeometry lightGeometry;
Stan Iliev500a0c32016-10-26 10:30:09 -0400170 lightGeometry.radius = 1.0f;
John Reck1bcacfd2017-11-03 10:12:19 -0700171 lightGeometry.center = {0.0f, 0.0f, 0.0f};
John Reckd9d7f122018-05-03 14:40:56 -0700172 LightInfo lightInfo;
Stan Iliev500a0c32016-10-26 10:30:09 -0400173 auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
Peiyong Lin1f6aa122018-09-10 16:28:08 -0700174 pipeline->renderLayers(lightGeometry, &layerUpdateQueue, opaque, lightInfo);
Stan Iliev500a0c32016-10-26 10:30:09 -0400175 ASSERT_EQ(TestUtils::getColor(surfaceLayer1, 0, 0), SK_ColorRED);
176 ASSERT_EQ(TestUtils::getColor(surfaceLayer2, 0, 0), SK_ColorBLUE);
177 ASSERT_EQ(TestUtils::getColor(surfaceLayer2, 0, 1), SK_ColorWHITE);
178 ASSERT_TRUE(layerUpdateQueue.entries().empty());
179 redNode->setLayerSurface(sk_sp<SkSurface>());
180 blueNode->setLayerSurface(sk_sp<SkSurface>());
181}
Matt Sarettf58cc922016-11-14 18:33:38 -0500182
Greg Daniel98c78dad2017-01-04 14:45:56 -0500183RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderOverdraw) {
Matt Sarettf58cc922016-11-14 18:33:38 -0500184 ScopedProperty<bool> prop(Properties::debugOverdraw, true);
185
John Reck1bcacfd2017-11-03 10:12:19 -0700186 auto whiteNode = TestUtils::createSkiaNode(
187 0, 0, 1, 1, [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
188 canvas.drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver);
189 });
Matt Sarettf58cc922016-11-14 18:33:38 -0500190 LayerUpdateQueue layerUpdateQueue;
191 SkRect dirty = SkRect::MakeXYWH(0, 0, 1, 1);
192 std::vector<sp<RenderNode>> renderNodes;
193 renderNodes.push_back(whiteNode);
194 bool opaque = true;
John Reck1bcacfd2017-11-03 10:12:19 -0700195 // empty contentDrawBounds is avoiding backdrop/content logic, which would lead to less overdraw
Stan Iliev52771272016-11-17 09:54:38 -0500196 android::uirenderer::Rect contentDrawBounds(0, 0, 0, 0);
Matt Sarettf58cc922016-11-14 18:33:38 -0500197 auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
198 auto surface = SkSurface::MakeRasterN32Premul(1, 1);
199
200 // Initialize the canvas to blue.
201 surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
202 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
203
204 // Single draw, should be white.
Peiyong Lin1f6aa122018-09-10 16:28:08 -0700205 pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds,
John Reck1bcacfd2017-11-03 10:12:19 -0700206 surface);
Matt Sarettf58cc922016-11-14 18:33:38 -0500207 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorWHITE);
208
209 // 1 Overdraw, should be blue blended onto white.
Matt Sarett341480b2017-01-23 19:45:42 -0500210 renderNodes.push_back(whiteNode);
Peiyong Lin1f6aa122018-09-10 16:28:08 -0700211 pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds,
John Reck1bcacfd2017-11-03 10:12:19 -0700212 surface);
213 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned)0xffd0d0ff);
Matt Sarettf58cc922016-11-14 18:33:38 -0500214
215 // 2 Overdraw, should be green blended onto white
216 renderNodes.push_back(whiteNode);
Peiyong Lin1f6aa122018-09-10 16:28:08 -0700217 pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds,
John Reck1bcacfd2017-11-03 10:12:19 -0700218 surface);
219 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned)0xffd0ffd0);
Matt Sarettf58cc922016-11-14 18:33:38 -0500220
221 // 3 Overdraw, should be pink blended onto white.
222 renderNodes.push_back(whiteNode);
Peiyong Lin1f6aa122018-09-10 16:28:08 -0700223 pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds,
John Reck1bcacfd2017-11-03 10:12:19 -0700224 surface);
225 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned)0xffffc0c0);
Matt Sarettf58cc922016-11-14 18:33:38 -0500226
227 // 4 Overdraw, should be red blended onto white.
228 renderNodes.push_back(whiteNode);
Peiyong Lin1f6aa122018-09-10 16:28:08 -0700229 pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds,
John Reck1bcacfd2017-11-03 10:12:19 -0700230 surface);
231 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned)0xffff8080);
Matt Sarettf58cc922016-11-14 18:33:38 -0500232
233 // 5 Overdraw, should be red blended onto white.
234 renderNodes.push_back(whiteNode);
Peiyong Lin1f6aa122018-09-10 16:28:08 -0700235 pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds,
John Reck1bcacfd2017-11-03 10:12:19 -0700236 surface);
237 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned)0xffff8080);
Matt Sarettf58cc922016-11-14 18:33:38 -0500238}
Stan Iliev52771272016-11-17 09:54:38 -0500239
240namespace {
241template <typename T>
242class DeferLayer : public SkSurface_Base {
243public:
Derek Sollenberger624ad832017-01-11 11:09:48 -0500244 DeferLayer() : SkSurface_Base(T().imageInfo(), nullptr) {}
245 virtual ~DeferLayer() {}
246
John Reck1bcacfd2017-11-03 10:12:19 -0700247 SkCanvas* onNewCanvas() override { return new T(); }
248 sk_sp<SkSurface> onNewSurface(const SkImageInfo&) override { return nullptr; }
249 sk_sp<SkImage> onNewImageSnapshot() override { return nullptr; }
Stan Ilieved4d58c2016-12-14 14:05:04 -0500250 T* canvas() { return static_cast<T*>(getCanvas()); }
Stan Iliev52771272016-11-17 09:54:38 -0500251 void onCopyOnWrite(ContentChangeMode) override {}
Leon Scroggins III71195ab2018-02-08 17:14:28 -0500252 void onWritePixels(const SkPixmap&, int x, int y) override {}
Stan Iliev52771272016-11-17 09:54:38 -0500253};
254}
255
Greg Daniel98c78dad2017-01-04 14:45:56 -0500256RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, deferRenderNodeScene) {
Stan Iliev52771272016-11-17 09:54:38 -0500257 class DeferTestCanvas : public SkCanvas {
258 public:
259 DeferTestCanvas() : SkCanvas(800, 600) {}
260 void onDrawRect(const SkRect& rect, const SkPaint& paint) override {
261 SkMatrix expected;
262 switch (mDrawCounter++) {
John Reck1bcacfd2017-11-03 10:12:19 -0700263 case 0:
264 // background - left side
265 EXPECT_EQ(SkRect::MakeLTRB(600, 100, 700, 500), TestUtils::getClipBounds(this));
266 expected.setTranslate(100, 100);
267 break;
268 case 1:
269 // background - top side
270 EXPECT_EQ(SkRect::MakeLTRB(100, 400, 600, 500), TestUtils::getClipBounds(this));
271 expected.setTranslate(100, 100);
272 break;
273 case 2:
274 // content
275 EXPECT_EQ(SkRect::MakeLTRB(100, 100, 700, 500), TestUtils::getClipBounds(this));
276 expected.setTranslate(-50, -50);
277 break;
278 case 3:
279 // overlay
280 EXPECT_EQ(SkRect::MakeLTRB(0, 0, 800, 600), TestUtils::getClipBounds(this));
281 expected.reset();
282 break;
283 default:
284 ADD_FAILURE() << "Too many rects observed";
Stan Iliev52771272016-11-17 09:54:38 -0500285 }
286 EXPECT_EQ(expected, getTotalMatrix());
287 }
288 int mDrawCounter = 0;
289 };
290
291 std::vector<sp<RenderNode>> nodes;
292 SkPaint transparentPaint;
293 transparentPaint.setAlpha(128);
294
295 // backdrop
John Reck1bcacfd2017-11-03 10:12:19 -0700296 nodes.push_back(TestUtils::createSkiaNode(
297 100, 100, 700, 500, // 600x400
Stan Iliev52771272016-11-17 09:54:38 -0500298 [&transparentPaint](RenderProperties& props, SkiaRecordingCanvas& canvas) {
John Reck1bcacfd2017-11-03 10:12:19 -0700299 canvas.drawRect(0, 0, 600, 400, transparentPaint);
300 }));
Stan Iliev52771272016-11-17 09:54:38 -0500301
302 // content
John Reck1bcacfd2017-11-03 10:12:19 -0700303 android::uirenderer::Rect contentDrawBounds(150, 150, 650, 450); // 500x300
304 nodes.push_back(TestUtils::createSkiaNode(
305 0, 0, 800, 600,
Stan Iliev52771272016-11-17 09:54:38 -0500306 [&transparentPaint](RenderProperties& props, SkiaRecordingCanvas& canvas) {
John Reck1bcacfd2017-11-03 10:12:19 -0700307 canvas.drawRect(0, 0, 800, 600, transparentPaint);
308 }));
Stan Iliev52771272016-11-17 09:54:38 -0500309
310 // overlay
John Reck1bcacfd2017-11-03 10:12:19 -0700311 nodes.push_back(TestUtils::createSkiaNode(
312 0, 0, 800, 600,
Stan Iliev52771272016-11-17 09:54:38 -0500313 [&transparentPaint](RenderProperties& props, SkiaRecordingCanvas& canvas) {
John Reck1bcacfd2017-11-03 10:12:19 -0700314 canvas.drawRect(0, 0, 800, 200, transparentPaint);
315 }));
Stan Iliev52771272016-11-17 09:54:38 -0500316
317 LayerUpdateQueue layerUpdateQueue;
318 SkRect dirty = SkRect::MakeWH(800, 600);
319 auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
Stan Ilieved4d58c2016-12-14 14:05:04 -0500320 sk_sp<DeferLayer<DeferTestCanvas>> surface(new DeferLayer<DeferTestCanvas>());
Peiyong Lin1f6aa122018-09-10 16:28:08 -0700321 pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true, contentDrawBounds, surface);
Stan Ilieved4d58c2016-12-14 14:05:04 -0500322 EXPECT_EQ(4, surface->canvas()->mDrawCounter);
Stan Iliev52771272016-11-17 09:54:38 -0500323}
324
Greg Daniel98c78dad2017-01-04 14:45:56 -0500325RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, clipped) {
Stan Iliev52771272016-11-17 09:54:38 -0500326 static const int CANVAS_WIDTH = 200;
327 static const int CANVAS_HEIGHT = 200;
328 class ClippedTestCanvas : public SkCanvas {
329 public:
John Reck1bcacfd2017-11-03 10:12:19 -0700330 ClippedTestCanvas() : SkCanvas(CANVAS_WIDTH, CANVAS_HEIGHT) {}
Stan Iliev52771272016-11-17 09:54:38 -0500331 void onDrawImage(const SkImage*, SkScalar dx, SkScalar dy, const SkPaint*) override {
332 EXPECT_EQ(0, mDrawCounter++);
333 EXPECT_EQ(SkRect::MakeLTRB(10, 20, 30, 40), TestUtils::getClipBounds(this));
334 EXPECT_TRUE(getTotalMatrix().isIdentity());
335 }
336 int mDrawCounter = 0;
337 };
338
339 std::vector<sp<RenderNode>> nodes;
John Reck1bcacfd2017-11-03 10:12:19 -0700340 nodes.push_back(TestUtils::createSkiaNode(
341 0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
Stan Iliev52771272016-11-17 09:54:38 -0500342 [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
John Reck1bcacfd2017-11-03 10:12:19 -0700343 sk_sp<Bitmap> bitmap(TestUtils::createBitmap(CANVAS_WIDTH, CANVAS_HEIGHT));
344 canvas.drawBitmap(*bitmap, 0, 0, nullptr);
345 }));
Stan Iliev52771272016-11-17 09:54:38 -0500346
347 LayerUpdateQueue layerUpdateQueue;
348 SkRect dirty = SkRect::MakeLTRB(10, 20, 30, 40);
349 auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
Stan Ilieved4d58c2016-12-14 14:05:04 -0500350 sk_sp<DeferLayer<ClippedTestCanvas>> surface(new DeferLayer<ClippedTestCanvas>());
Peiyong Lin1f6aa122018-09-10 16:28:08 -0700351 pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true,
John Reck1bcacfd2017-11-03 10:12:19 -0700352 SkRect::MakeWH(CANVAS_WIDTH, CANVAS_HEIGHT), surface);
Stan Ilieved4d58c2016-12-14 14:05:04 -0500353 EXPECT_EQ(1, surface->canvas()->mDrawCounter);
Stan Iliev52771272016-11-17 09:54:38 -0500354}
355
Greg Daniel98c78dad2017-01-04 14:45:56 -0500356RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, clip_replace) {
Stan Iliev52771272016-11-17 09:54:38 -0500357 static const int CANVAS_WIDTH = 50;
358 static const int CANVAS_HEIGHT = 50;
359 class ClipReplaceTestCanvas : public SkCanvas {
360 public:
John Reck1bcacfd2017-11-03 10:12:19 -0700361 ClipReplaceTestCanvas() : SkCanvas(CANVAS_WIDTH, CANVAS_HEIGHT) {}
Stan Iliev52771272016-11-17 09:54:38 -0500362 void onDrawPaint(const SkPaint&) {
363 EXPECT_EQ(0, mDrawCounter++);
Stan Ilievb66b8bb2016-12-15 18:17:42 -0500364 EXPECT_EQ(SkRect::MakeLTRB(20, 10, 30, 40), TestUtils::getClipBounds(this))
365 << "Expect resolved clip to be intersection of viewport clip and clip op";
Stan Iliev52771272016-11-17 09:54:38 -0500366 }
367 int mDrawCounter = 0;
368 };
369
370 std::vector<sp<RenderNode>> nodes;
John Reck1bcacfd2017-11-03 10:12:19 -0700371 nodes.push_back(TestUtils::createSkiaNode(
372 20, 20, 30, 30, [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
373 canvas.clipRect(0, -20, 10, 30, SkClipOp::kReplace_deprecated);
374 canvas.drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver);
375 }));
Stan Iliev52771272016-11-17 09:54:38 -0500376
377 LayerUpdateQueue layerUpdateQueue;
378 SkRect dirty = SkRect::MakeLTRB(10, 10, 40, 40);
379 auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
Stan Ilieved4d58c2016-12-14 14:05:04 -0500380 sk_sp<DeferLayer<ClipReplaceTestCanvas>> surface(new DeferLayer<ClipReplaceTestCanvas>());
Peiyong Lin1f6aa122018-09-10 16:28:08 -0700381 pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true,
John Reck1bcacfd2017-11-03 10:12:19 -0700382 SkRect::MakeWH(CANVAS_WIDTH, CANVAS_HEIGHT), surface);
Stan Ilieved4d58c2016-12-14 14:05:04 -0500383 EXPECT_EQ(1, surface->canvas()->mDrawCounter);
Stan Iliev52771272016-11-17 09:54:38 -0500384}