blob: 90bcd1c0e370c64e61d01825aee2797873a31735 [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"
Mike Reedc2dbc032019-07-25 12:28:29 -040026#include "hwui/Paint.h"
John Reck1bcacfd2017-11-03 10:12:19 -070027#include "SkiaCanvas.h"
28#include "pipeline/skia/SkiaDisplayList.h"
29#include "pipeline/skia/SkiaOpenGLPipeline.h"
30#include "pipeline/skia/SkiaRecordingCanvas.h"
John Reck283bb462018-12-13 16:40:14 -080031#include "pipeline/skia/SkiaUtils.h"
John Reck1bcacfd2017-11-03 10:12:19 -070032#include "renderthread/CanvasContext.h"
John Reck23462d82019-05-29 16:55:06 -070033#include "tests/common/TestContext.h"
John Reck1bcacfd2017-11-03 10:12:19 -070034#include "tests/common/TestUtils.h"
Stan Iliev500a0c32016-10-26 10:30:09 -040035
John Reck0fa0cbc2019-04-05 16:57:46 -070036#include <gui/BufferItemConsumer.h>
37#include <gui/Surface.h>
38
Stan Iliev500a0c32016-10-26 10:30:09 -040039using namespace android;
40using namespace android::uirenderer;
41using namespace android::uirenderer::renderthread;
42using namespace android::uirenderer::skiapipeline;
43
Greg Daniel98c78dad2017-01-04 14:45:56 -050044RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderFrame) {
John Reck1bcacfd2017-11-03 10:12:19 -070045 auto redNode = TestUtils::createSkiaNode(
46 0, 0, 1, 1, [](RenderProperties& props, SkiaRecordingCanvas& redCanvas) {
47 redCanvas.drawColor(SK_ColorRED, SkBlendMode::kSrcOver);
48 });
Stan Iliev500a0c32016-10-26 10:30:09 -040049 LayerUpdateQueue layerUpdateQueue;
Mike Reedf3338bd2018-10-09 11:54:39 -040050 SkRect dirty = SkRectMakeLargest();
Stan Iliev500a0c32016-10-26 10:30:09 -040051 std::vector<sp<RenderNode>> renderNodes;
52 renderNodes.push_back(redNode);
53 bool opaque = true;
54 android::uirenderer::Rect contentDrawBounds(0, 0, 1, 1);
55 auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
56 auto surface = SkSurface::MakeRasterN32Premul(1, 1);
57 surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
58 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
Greg Danielc4076782019-01-08 16:01:18 -050059 pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface,
60 SkMatrix::I());
Stan Iliev500a0c32016-10-26 10:30:09 -040061 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorRED);
62}
63
Greg Daniel98c78dad2017-01-04 14:45:56 -050064RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderFrameCheckOpaque) {
John Reck1bcacfd2017-11-03 10:12:19 -070065 auto halfGreenNode = TestUtils::createSkiaNode(
66 0, 0, 2, 2, [](RenderProperties& props, SkiaRecordingCanvas& bottomHalfGreenCanvas) {
Mike Reedc2dbc032019-07-25 12:28:29 -040067 Paint greenPaint;
John Reck1bcacfd2017-11-03 10:12:19 -070068 greenPaint.setColor(SK_ColorGREEN);
69 greenPaint.setStyle(SkPaint::kFill_Style);
70 bottomHalfGreenCanvas.drawRect(0, 1, 2, 2, greenPaint);
71 });
Stan Iliev500a0c32016-10-26 10:30:09 -040072 LayerUpdateQueue layerUpdateQueue;
Mike Reedf3338bd2018-10-09 11:54:39 -040073 SkRect dirty = SkRectMakeLargest();
Stan Iliev500a0c32016-10-26 10:30:09 -040074 std::vector<sp<RenderNode>> renderNodes;
75 renderNodes.push_back(halfGreenNode);
76 android::uirenderer::Rect contentDrawBounds(0, 0, 2, 2);
77 auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
78 auto surface = SkSurface::MakeRasterN32Premul(2, 2);
79 surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
80 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
Greg Danielc4076782019-01-08 16:01:18 -050081 pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, true, contentDrawBounds, surface,
82 SkMatrix::I());
Stan Iliev500a0c32016-10-26 10:30:09 -040083 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
84 ASSERT_EQ(TestUtils::getColor(surface, 0, 1), SK_ColorGREEN);
Greg Danielc4076782019-01-08 16:01:18 -050085 pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, false, contentDrawBounds, surface,
86 SkMatrix::I());
Stan Iliev500a0c32016-10-26 10:30:09 -040087 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned int)SK_ColorTRANSPARENT);
88 ASSERT_EQ(TestUtils::getColor(surface, 0, 1), SK_ColorGREEN);
89}
90
Greg Daniel98c78dad2017-01-04 14:45:56 -050091RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderFrameCheckDirtyRect) {
John Reck1bcacfd2017-11-03 10:12:19 -070092 auto redNode = TestUtils::createSkiaNode(
93 0, 0, 2, 2, [](RenderProperties& props, SkiaRecordingCanvas& redCanvas) {
94 redCanvas.drawColor(SK_ColorRED, SkBlendMode::kSrcOver);
95 });
Stan Iliev500a0c32016-10-26 10:30:09 -040096 LayerUpdateQueue layerUpdateQueue;
97 SkRect dirty = SkRect::MakeXYWH(0, 1, 2, 1);
98 std::vector<sp<RenderNode>> renderNodes;
99 renderNodes.push_back(redNode);
100 android::uirenderer::Rect contentDrawBounds(0, 0, 2, 2);
101 auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
102 auto surface = SkSurface::MakeRasterN32Premul(2, 2);
103 surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
104 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
Greg Danielc4076782019-01-08 16:01:18 -0500105 pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, true, contentDrawBounds, surface,
106 SkMatrix::I());
Stan Iliev500a0c32016-10-26 10:30:09 -0400107 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
108 ASSERT_EQ(TestUtils::getColor(surface, 1, 0), SK_ColorBLUE);
109 ASSERT_EQ(TestUtils::getColor(surface, 0, 1), SK_ColorRED);
110 ASSERT_EQ(TestUtils::getColor(surface, 1, 1), SK_ColorRED);
111}
112
Greg Daniel98c78dad2017-01-04 14:45:56 -0500113RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderLayer) {
John Reck1bcacfd2017-11-03 10:12:19 -0700114 auto redNode = TestUtils::createSkiaNode(
115 0, 0, 1, 1, [](RenderProperties& props, SkiaRecordingCanvas& redCanvas) {
116 redCanvas.drawColor(SK_ColorRED, SkBlendMode::kSrcOver);
117 });
Stan Iliev500a0c32016-10-26 10:30:09 -0400118 auto surfaceLayer1 = SkSurface::MakeRasterN32Premul(1, 1);
119 surfaceLayer1->getCanvas()->drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver);
120 ASSERT_EQ(TestUtils::getColor(surfaceLayer1, 0, 0), SK_ColorWHITE);
121 redNode->setLayerSurface(surfaceLayer1);
122
John Reck1bcacfd2017-11-03 10:12:19 -0700123 // create a 2nd 2x2 layer and add it to the queue as well.
124 // make the layer's dirty area one half of the layer and verify only the dirty half is updated.
125 auto blueNode = TestUtils::createSkiaNode(
126 0, 0, 2, 2, [](RenderProperties& props, SkiaRecordingCanvas& blueCanvas) {
127 blueCanvas.drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
128 });
Stan Iliev500a0c32016-10-26 10:30:09 -0400129 auto surfaceLayer2 = SkSurface::MakeRasterN32Premul(2, 2);
130 surfaceLayer2->getCanvas()->drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver);
131 ASSERT_EQ(TestUtils::getColor(surfaceLayer2, 0, 0), SK_ColorWHITE);
132 blueNode->setLayerSurface(surfaceLayer2);
133
John Reck1bcacfd2017-11-03 10:12:19 -0700134 // attach both layers to the update queue
Stan Iliev500a0c32016-10-26 10:30:09 -0400135 LayerUpdateQueue layerUpdateQueue;
Mike Reedf3338bd2018-10-09 11:54:39 -0400136 SkRect dirty = SkRectMakeLargest();
Stan Iliev500a0c32016-10-26 10:30:09 -0400137 layerUpdateQueue.enqueueLayerWithDamage(redNode.get(), dirty);
138 layerUpdateQueue.enqueueLayerWithDamage(blueNode.get(), SkRect::MakeWH(2, 1));
139 ASSERT_EQ(layerUpdateQueue.entries().size(), 2UL);
140
141 bool opaque = true;
John Reckd9d7f122018-05-03 14:40:56 -0700142 LightGeometry lightGeometry;
Stan Iliev500a0c32016-10-26 10:30:09 -0400143 lightGeometry.radius = 1.0f;
John Reck1bcacfd2017-11-03 10:12:19 -0700144 lightGeometry.center = {0.0f, 0.0f, 0.0f};
John Reckd9d7f122018-05-03 14:40:56 -0700145 LightInfo lightInfo;
Stan Iliev500a0c32016-10-26 10:30:09 -0400146 auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
Peiyong Lin1f6aa122018-09-10 16:28:08 -0700147 pipeline->renderLayers(lightGeometry, &layerUpdateQueue, opaque, lightInfo);
Stan Iliev500a0c32016-10-26 10:30:09 -0400148 ASSERT_EQ(TestUtils::getColor(surfaceLayer1, 0, 0), SK_ColorRED);
149 ASSERT_EQ(TestUtils::getColor(surfaceLayer2, 0, 0), SK_ColorBLUE);
150 ASSERT_EQ(TestUtils::getColor(surfaceLayer2, 0, 1), SK_ColorWHITE);
151 ASSERT_TRUE(layerUpdateQueue.entries().empty());
152 redNode->setLayerSurface(sk_sp<SkSurface>());
153 blueNode->setLayerSurface(sk_sp<SkSurface>());
154}
Matt Sarettf58cc922016-11-14 18:33:38 -0500155
Greg Daniel98c78dad2017-01-04 14:45:56 -0500156RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderOverdraw) {
Matt Sarettf58cc922016-11-14 18:33:38 -0500157 ScopedProperty<bool> prop(Properties::debugOverdraw, true);
158
John Reck1bcacfd2017-11-03 10:12:19 -0700159 auto whiteNode = TestUtils::createSkiaNode(
160 0, 0, 1, 1, [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
161 canvas.drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver);
162 });
Matt Sarettf58cc922016-11-14 18:33:38 -0500163 LayerUpdateQueue layerUpdateQueue;
164 SkRect dirty = SkRect::MakeXYWH(0, 0, 1, 1);
165 std::vector<sp<RenderNode>> renderNodes;
166 renderNodes.push_back(whiteNode);
167 bool opaque = true;
John Reck1bcacfd2017-11-03 10:12:19 -0700168 // empty contentDrawBounds is avoiding backdrop/content logic, which would lead to less overdraw
Stan Iliev52771272016-11-17 09:54:38 -0500169 android::uirenderer::Rect contentDrawBounds(0, 0, 0, 0);
Matt Sarettf58cc922016-11-14 18:33:38 -0500170 auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
171 auto surface = SkSurface::MakeRasterN32Premul(1, 1);
172
173 // Initialize the canvas to blue.
174 surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
175 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
176
177 // Single draw, should be white.
Greg Danielc4076782019-01-08 16:01:18 -0500178 pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface,
179 SkMatrix::I());
Matt Sarettf58cc922016-11-14 18:33:38 -0500180 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorWHITE);
181
182 // 1 Overdraw, should be blue blended onto white.
Matt Sarett341480b2017-01-23 19:45:42 -0500183 renderNodes.push_back(whiteNode);
Greg Danielc4076782019-01-08 16:01:18 -0500184 pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface,
185 SkMatrix::I());
John Reck1bcacfd2017-11-03 10:12:19 -0700186 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned)0xffd0d0ff);
Matt Sarettf58cc922016-11-14 18:33:38 -0500187
188 // 2 Overdraw, should be green blended onto white
189 renderNodes.push_back(whiteNode);
Greg Danielc4076782019-01-08 16:01:18 -0500190 pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface,
191 SkMatrix::I());
John Reck1bcacfd2017-11-03 10:12:19 -0700192 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned)0xffd0ffd0);
Matt Sarettf58cc922016-11-14 18:33:38 -0500193
194 // 3 Overdraw, should be pink blended onto white.
195 renderNodes.push_back(whiteNode);
Greg Danielc4076782019-01-08 16:01:18 -0500196 pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface,
197 SkMatrix::I());
John Reck1bcacfd2017-11-03 10:12:19 -0700198 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned)0xffffc0c0);
Matt Sarettf58cc922016-11-14 18:33:38 -0500199
200 // 4 Overdraw, should be red blended onto white.
201 renderNodes.push_back(whiteNode);
Greg Danielc4076782019-01-08 16:01:18 -0500202 pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface,
203 SkMatrix::I());
John Reck1bcacfd2017-11-03 10:12:19 -0700204 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned)0xffff8080);
Matt Sarettf58cc922016-11-14 18:33:38 -0500205
206 // 5 Overdraw, should be red blended onto white.
207 renderNodes.push_back(whiteNode);
Greg Danielc4076782019-01-08 16:01:18 -0500208 pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface,
209 SkMatrix::I());
John Reck1bcacfd2017-11-03 10:12:19 -0700210 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned)0xffff8080);
Matt Sarettf58cc922016-11-14 18:33:38 -0500211}
Stan Iliev52771272016-11-17 09:54:38 -0500212
213namespace {
214template <typename T>
215class DeferLayer : public SkSurface_Base {
216public:
Derek Sollenberger624ad832017-01-11 11:09:48 -0500217 DeferLayer() : SkSurface_Base(T().imageInfo(), nullptr) {}
218 virtual ~DeferLayer() {}
219
John Reck1bcacfd2017-11-03 10:12:19 -0700220 SkCanvas* onNewCanvas() override { return new T(); }
221 sk_sp<SkSurface> onNewSurface(const SkImageInfo&) override { return nullptr; }
Derek Sollenbergerdbb4bc82018-11-21 08:47:31 -0500222 sk_sp<SkImage> onNewImageSnapshot(const SkIRect* bounds) override { return nullptr; }
Stan Ilieved4d58c2016-12-14 14:05:04 -0500223 T* canvas() { return static_cast<T*>(getCanvas()); }
Stan Iliev52771272016-11-17 09:54:38 -0500224 void onCopyOnWrite(ContentChangeMode) override {}
Leon Scroggins III71195ab2018-02-08 17:14:28 -0500225 void onWritePixels(const SkPixmap&, int x, int y) override {}
Stan Iliev52771272016-11-17 09:54:38 -0500226};
227}
228
Greg Daniel98c78dad2017-01-04 14:45:56 -0500229RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, deferRenderNodeScene) {
Stan Iliev52771272016-11-17 09:54:38 -0500230 class DeferTestCanvas : public SkCanvas {
231 public:
232 DeferTestCanvas() : SkCanvas(800, 600) {}
233 void onDrawRect(const SkRect& rect, const SkPaint& paint) override {
234 SkMatrix expected;
235 switch (mDrawCounter++) {
John Reck1bcacfd2017-11-03 10:12:19 -0700236 case 0:
237 // background - left side
238 EXPECT_EQ(SkRect::MakeLTRB(600, 100, 700, 500), TestUtils::getClipBounds(this));
239 expected.setTranslate(100, 100);
240 break;
241 case 1:
242 // background - top side
243 EXPECT_EQ(SkRect::MakeLTRB(100, 400, 600, 500), TestUtils::getClipBounds(this));
244 expected.setTranslate(100, 100);
245 break;
246 case 2:
247 // content
248 EXPECT_EQ(SkRect::MakeLTRB(100, 100, 700, 500), TestUtils::getClipBounds(this));
249 expected.setTranslate(-50, -50);
250 break;
251 case 3:
252 // overlay
253 EXPECT_EQ(SkRect::MakeLTRB(0, 0, 800, 600), TestUtils::getClipBounds(this));
254 expected.reset();
255 break;
256 default:
257 ADD_FAILURE() << "Too many rects observed";
Stan Iliev52771272016-11-17 09:54:38 -0500258 }
259 EXPECT_EQ(expected, getTotalMatrix());
260 }
261 int mDrawCounter = 0;
262 };
263
264 std::vector<sp<RenderNode>> nodes;
Mike Reedc2dbc032019-07-25 12:28:29 -0400265 Paint transparentPaint;
Stan Iliev52771272016-11-17 09:54:38 -0500266 transparentPaint.setAlpha(128);
267
268 // backdrop
John Reck1bcacfd2017-11-03 10:12:19 -0700269 nodes.push_back(TestUtils::createSkiaNode(
270 100, 100, 700, 500, // 600x400
Stan Iliev52771272016-11-17 09:54:38 -0500271 [&transparentPaint](RenderProperties& props, SkiaRecordingCanvas& canvas) {
John Reck1bcacfd2017-11-03 10:12:19 -0700272 canvas.drawRect(0, 0, 600, 400, transparentPaint);
273 }));
Stan Iliev52771272016-11-17 09:54:38 -0500274
275 // content
John Reck1bcacfd2017-11-03 10:12:19 -0700276 android::uirenderer::Rect contentDrawBounds(150, 150, 650, 450); // 500x300
277 nodes.push_back(TestUtils::createSkiaNode(
278 0, 0, 800, 600,
Stan Iliev52771272016-11-17 09:54:38 -0500279 [&transparentPaint](RenderProperties& props, SkiaRecordingCanvas& canvas) {
John Reck1bcacfd2017-11-03 10:12:19 -0700280 canvas.drawRect(0, 0, 800, 600, transparentPaint);
281 }));
Stan Iliev52771272016-11-17 09:54:38 -0500282
283 // overlay
John Reck1bcacfd2017-11-03 10:12:19 -0700284 nodes.push_back(TestUtils::createSkiaNode(
285 0, 0, 800, 600,
Stan Iliev52771272016-11-17 09:54:38 -0500286 [&transparentPaint](RenderProperties& props, SkiaRecordingCanvas& canvas) {
John Reck1bcacfd2017-11-03 10:12:19 -0700287 canvas.drawRect(0, 0, 800, 200, transparentPaint);
288 }));
Stan Iliev52771272016-11-17 09:54:38 -0500289
290 LayerUpdateQueue layerUpdateQueue;
291 SkRect dirty = SkRect::MakeWH(800, 600);
292 auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
Stan Ilieved4d58c2016-12-14 14:05:04 -0500293 sk_sp<DeferLayer<DeferTestCanvas>> surface(new DeferLayer<DeferTestCanvas>());
Greg Danielc4076782019-01-08 16:01:18 -0500294 pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true, contentDrawBounds, surface,
295 SkMatrix::I());
Stan Ilieved4d58c2016-12-14 14:05:04 -0500296 EXPECT_EQ(4, surface->canvas()->mDrawCounter);
Stan Iliev52771272016-11-17 09:54:38 -0500297}
298
Greg Daniel98c78dad2017-01-04 14:45:56 -0500299RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, clipped) {
Stan Iliev52771272016-11-17 09:54:38 -0500300 static const int CANVAS_WIDTH = 200;
301 static const int CANVAS_HEIGHT = 200;
302 class ClippedTestCanvas : public SkCanvas {
303 public:
John Reck1bcacfd2017-11-03 10:12:19 -0700304 ClippedTestCanvas() : SkCanvas(CANVAS_WIDTH, CANVAS_HEIGHT) {}
Stan Iliev52771272016-11-17 09:54:38 -0500305 void onDrawImage(const SkImage*, SkScalar dx, SkScalar dy, const SkPaint*) override {
306 EXPECT_EQ(0, mDrawCounter++);
307 EXPECT_EQ(SkRect::MakeLTRB(10, 20, 30, 40), TestUtils::getClipBounds(this));
308 EXPECT_TRUE(getTotalMatrix().isIdentity());
309 }
310 int mDrawCounter = 0;
311 };
312
313 std::vector<sp<RenderNode>> nodes;
John Reck1bcacfd2017-11-03 10:12:19 -0700314 nodes.push_back(TestUtils::createSkiaNode(
315 0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
Stan Iliev52771272016-11-17 09:54:38 -0500316 [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
John Reck1bcacfd2017-11-03 10:12:19 -0700317 sk_sp<Bitmap> bitmap(TestUtils::createBitmap(CANVAS_WIDTH, CANVAS_HEIGHT));
318 canvas.drawBitmap(*bitmap, 0, 0, nullptr);
319 }));
Stan Iliev52771272016-11-17 09:54:38 -0500320
321 LayerUpdateQueue layerUpdateQueue;
322 SkRect dirty = SkRect::MakeLTRB(10, 20, 30, 40);
323 auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
Stan Ilieved4d58c2016-12-14 14:05:04 -0500324 sk_sp<DeferLayer<ClippedTestCanvas>> surface(new DeferLayer<ClippedTestCanvas>());
Peiyong Lin1f6aa122018-09-10 16:28:08 -0700325 pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true,
Greg Danielc4076782019-01-08 16:01:18 -0500326 SkRect::MakeWH(CANVAS_WIDTH, CANVAS_HEIGHT), surface, SkMatrix::I());
327 EXPECT_EQ(1, surface->canvas()->mDrawCounter);
328}
329
330// Test renderFrame with a dirty clip and a pre-transform matrix.
331RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, clipped_rotated) {
332 static const int CANVAS_WIDTH = 200;
333 static const int CANVAS_HEIGHT = 100;
334 static const SkMatrix rotateMatrix = SkMatrix::MakeAll(0, -1, CANVAS_HEIGHT, 1, 0, 0, 0, 0, 1);
335 static const SkRect dirty = SkRect::MakeLTRB(10, 20, 20, 40);
336 class ClippedTestCanvas : public SkCanvas {
337 public:
338 ClippedTestCanvas() : SkCanvas(CANVAS_WIDTH, CANVAS_HEIGHT) {}
339 void onDrawImage(const SkImage*, SkScalar dx, SkScalar dy, const SkPaint*) override {
340 EXPECT_EQ(0, mDrawCounter++);
341 // Expect clip to be rotated.
342 EXPECT_EQ(SkRect::MakeLTRB(CANVAS_HEIGHT - dirty.fTop - dirty.height(), dirty.fLeft,
343 CANVAS_HEIGHT - dirty.fTop, dirty.fLeft + dirty.width()),
344 TestUtils::getClipBounds(this));
345 EXPECT_EQ(rotateMatrix, getTotalMatrix());
346 }
347 int mDrawCounter = 0;
348 };
349
350 std::vector<sp<RenderNode>> nodes;
351 nodes.push_back(TestUtils::createSkiaNode(
352 0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
353 [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
354 sk_sp<Bitmap> bitmap(TestUtils::createBitmap(CANVAS_WIDTH, CANVAS_HEIGHT));
355 canvas.drawBitmap(*bitmap, 0, 0, nullptr);
356 }));
357
358 LayerUpdateQueue layerUpdateQueue;
359 auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
360 sk_sp<DeferLayer<ClippedTestCanvas>> surface(new DeferLayer<ClippedTestCanvas>());
361 pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true,
362 SkRect::MakeWH(CANVAS_WIDTH, CANVAS_HEIGHT), surface, rotateMatrix);
Stan Ilieved4d58c2016-12-14 14:05:04 -0500363 EXPECT_EQ(1, surface->canvas()->mDrawCounter);
Stan Iliev52771272016-11-17 09:54:38 -0500364}
365
Greg Daniel98c78dad2017-01-04 14:45:56 -0500366RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, clip_replace) {
Stan Iliev52771272016-11-17 09:54:38 -0500367 static const int CANVAS_WIDTH = 50;
368 static const int CANVAS_HEIGHT = 50;
369 class ClipReplaceTestCanvas : public SkCanvas {
370 public:
John Reck1bcacfd2017-11-03 10:12:19 -0700371 ClipReplaceTestCanvas() : SkCanvas(CANVAS_WIDTH, CANVAS_HEIGHT) {}
Stan Iliev52771272016-11-17 09:54:38 -0500372 void onDrawPaint(const SkPaint&) {
373 EXPECT_EQ(0, mDrawCounter++);
Stan Ilievb66b8bb2016-12-15 18:17:42 -0500374 EXPECT_EQ(SkRect::MakeLTRB(20, 10, 30, 40), TestUtils::getClipBounds(this))
375 << "Expect resolved clip to be intersection of viewport clip and clip op";
Stan Iliev52771272016-11-17 09:54:38 -0500376 }
377 int mDrawCounter = 0;
378 };
379
380 std::vector<sp<RenderNode>> nodes;
John Reck1bcacfd2017-11-03 10:12:19 -0700381 nodes.push_back(TestUtils::createSkiaNode(
382 20, 20, 30, 30, [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
383 canvas.clipRect(0, -20, 10, 30, SkClipOp::kReplace_deprecated);
384 canvas.drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver);
385 }));
Stan Iliev52771272016-11-17 09:54:38 -0500386
387 LayerUpdateQueue layerUpdateQueue;
388 SkRect dirty = SkRect::MakeLTRB(10, 10, 40, 40);
389 auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
Stan Ilieved4d58c2016-12-14 14:05:04 -0500390 sk_sp<DeferLayer<ClipReplaceTestCanvas>> surface(new DeferLayer<ClipReplaceTestCanvas>());
Peiyong Lin1f6aa122018-09-10 16:28:08 -0700391 pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true,
Greg Danielc4076782019-01-08 16:01:18 -0500392 SkRect::MakeWH(CANVAS_WIDTH, CANVAS_HEIGHT), surface, SkMatrix::I());
Stan Ilieved4d58c2016-12-14 14:05:04 -0500393 EXPECT_EQ(1, surface->canvas()->mDrawCounter);
Stan Iliev52771272016-11-17 09:54:38 -0500394}
Derek Sollenberger5a5a6482018-09-19 13:52:13 -0400395
396RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, context_lost) {
John Reck23462d82019-05-29 16:55:06 -0700397 test::TestContext context;
398 auto surface = context.surface();
Derek Sollenberger5a5a6482018-09-19 13:52:13 -0400399 auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
400 EXPECT_FALSE(pipeline->isSurfaceReady());
Derek Sollenberger1863d942020-02-05 15:41:51 -0500401 EXPECT_TRUE(pipeline->setSurface(surface.get(), SwapBehavior::kSwap_default, 0));
Derek Sollenberger5a5a6482018-09-19 13:52:13 -0400402 EXPECT_TRUE(pipeline->isSurfaceReady());
John Reck283bb462018-12-13 16:40:14 -0800403 renderThread.destroyRenderingContext();
Derek Sollenberger5a5a6482018-09-19 13:52:13 -0400404 EXPECT_FALSE(pipeline->isSurfaceReady());
405}