blob: 65b4e26ab62fc198401fc34e530016a37198f325 [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"
Mike Reedf3338bd2018-10-09 11:54:39 -040027#include "pipeline/skia/SkiaUtils.h"
John Reck1bcacfd2017-11-03 10:12:19 -070028#include "pipeline/skia/SkiaDisplayList.h"
29#include "pipeline/skia/SkiaOpenGLPipeline.h"
30#include "pipeline/skia/SkiaRecordingCanvas.h"
31#include "renderthread/CanvasContext.h"
32#include "tests/common/TestUtils.h"
Stan Iliev500a0c32016-10-26 10:30:09 -040033
34using namespace android;
35using namespace android::uirenderer;
36using namespace android::uirenderer::renderthread;
37using namespace android::uirenderer::skiapipeline;
38
Greg Daniel98c78dad2017-01-04 14:45:56 -050039RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderFrame) {
John Reck1bcacfd2017-11-03 10:12:19 -070040 auto redNode = TestUtils::createSkiaNode(
41 0, 0, 1, 1, [](RenderProperties& props, SkiaRecordingCanvas& redCanvas) {
42 redCanvas.drawColor(SK_ColorRED, SkBlendMode::kSrcOver);
43 });
Stan Iliev500a0c32016-10-26 10:30:09 -040044 LayerUpdateQueue layerUpdateQueue;
Mike Reedf3338bd2018-10-09 11:54:39 -040045 SkRect dirty = SkRectMakeLargest();
Stan Iliev500a0c32016-10-26 10:30:09 -040046 std::vector<sp<RenderNode>> renderNodes;
47 renderNodes.push_back(redNode);
48 bool opaque = true;
49 android::uirenderer::Rect contentDrawBounds(0, 0, 1, 1);
50 auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
51 auto surface = SkSurface::MakeRasterN32Premul(1, 1);
52 surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
53 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
Peiyong Lin1f6aa122018-09-10 16:28:08 -070054 pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds,
John Reck1bcacfd2017-11-03 10:12:19 -070055 surface);
Stan Iliev500a0c32016-10-26 10:30:09 -040056 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorRED);
57}
58
Stan Iliev47fed6ba2017-10-18 17:56:43 -040059RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, testOnPrepareTree) {
John Reck1bcacfd2017-11-03 10:12:19 -070060 auto redNode = TestUtils::createSkiaNode(
61 0, 0, 1, 1, [](RenderProperties& props, SkiaRecordingCanvas& redCanvas) {
62 redCanvas.drawColor(SK_ColorRED, SkBlendMode::kSrcOver);
63 });
Stan Iliev47fed6ba2017-10-18 17:56:43 -040064
65 LayerUpdateQueue layerUpdateQueue;
Mike Reedf3338bd2018-10-09 11:54:39 -040066 SkRect dirty = SkRectMakeLargest();
Stan Iliev47fed6ba2017-10-18 17:56:43 -040067 std::vector<sp<RenderNode>> renderNodes;
68 renderNodes.push_back(redNode);
69 bool opaque = true;
70 android::uirenderer::Rect contentDrawBounds(0, 0, 1, 1);
71 auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
72 {
John Reck1bcacfd2017-11-03 10:12:19 -070073 // add a pointer to a deleted vector drawable object in the pipeline
Stan Iliev47fed6ba2017-10-18 17:56:43 -040074 sp<VectorDrawableRoot> dirtyVD(new VectorDrawableRoot(new VectorDrawable::Group()));
John Reck1bcacfd2017-11-03 10:12:19 -070075 dirtyVD->mutateProperties()->setScaledSize(5, 5);
Stan Iliev47fed6ba2017-10-18 17:56:43 -040076 pipeline->getVectorDrawables()->push_back(dirtyVD.get());
77 }
78
John Reck1bcacfd2017-11-03 10:12:19 -070079 // pipeline should clean list of dirty vector drawables before prepare tree
Stan Iliev47fed6ba2017-10-18 17:56:43 -040080 pipeline->onPrepareTree();
81
82 auto surface = SkSurface::MakeRasterN32Premul(1, 1);
83 surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
84 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
85
John Reck1bcacfd2017-11-03 10:12:19 -070086 // drawFrame will crash if "SkiaPipeline::onPrepareTree" did not clean invalid VD pointer
Peiyong Lin1f6aa122018-09-10 16:28:08 -070087 pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds,
John Reck1bcacfd2017-11-03 10:12:19 -070088 surface);
Stan Iliev47fed6ba2017-10-18 17:56:43 -040089 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorRED);
90}
91
Greg Daniel98c78dad2017-01-04 14:45:56 -050092RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderFrameCheckOpaque) {
John Reck1bcacfd2017-11-03 10:12:19 -070093 auto halfGreenNode = TestUtils::createSkiaNode(
94 0, 0, 2, 2, [](RenderProperties& props, SkiaRecordingCanvas& bottomHalfGreenCanvas) {
95 SkPaint greenPaint;
96 greenPaint.setColor(SK_ColorGREEN);
97 greenPaint.setStyle(SkPaint::kFill_Style);
98 bottomHalfGreenCanvas.drawRect(0, 1, 2, 2, greenPaint);
99 });
Stan Iliev500a0c32016-10-26 10:30:09 -0400100 LayerUpdateQueue layerUpdateQueue;
Mike Reedf3338bd2018-10-09 11:54:39 -0400101 SkRect dirty = SkRectMakeLargest();
Stan Iliev500a0c32016-10-26 10:30:09 -0400102 std::vector<sp<RenderNode>> renderNodes;
103 renderNodes.push_back(halfGreenNode);
104 android::uirenderer::Rect contentDrawBounds(0, 0, 2, 2);
105 auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
106 auto surface = SkSurface::MakeRasterN32Premul(2, 2);
107 surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
108 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
Peiyong Lin1f6aa122018-09-10 16:28:08 -0700109 pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, true, contentDrawBounds,
John Reck1bcacfd2017-11-03 10:12:19 -0700110 surface);
Stan Iliev500a0c32016-10-26 10:30:09 -0400111 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
112 ASSERT_EQ(TestUtils::getColor(surface, 0, 1), SK_ColorGREEN);
Peiyong Lin1f6aa122018-09-10 16:28:08 -0700113 pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, false, contentDrawBounds,
John Reck1bcacfd2017-11-03 10:12:19 -0700114 surface);
Stan Iliev500a0c32016-10-26 10:30:09 -0400115 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned int)SK_ColorTRANSPARENT);
116 ASSERT_EQ(TestUtils::getColor(surface, 0, 1), SK_ColorGREEN);
117}
118
Greg Daniel98c78dad2017-01-04 14:45:56 -0500119RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderFrameCheckDirtyRect) {
John Reck1bcacfd2017-11-03 10:12:19 -0700120 auto redNode = TestUtils::createSkiaNode(
121 0, 0, 2, 2, [](RenderProperties& props, SkiaRecordingCanvas& redCanvas) {
122 redCanvas.drawColor(SK_ColorRED, SkBlendMode::kSrcOver);
123 });
Stan Iliev500a0c32016-10-26 10:30:09 -0400124 LayerUpdateQueue layerUpdateQueue;
125 SkRect dirty = SkRect::MakeXYWH(0, 1, 2, 1);
126 std::vector<sp<RenderNode>> renderNodes;
127 renderNodes.push_back(redNode);
128 android::uirenderer::Rect contentDrawBounds(0, 0, 2, 2);
129 auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
130 auto surface = SkSurface::MakeRasterN32Premul(2, 2);
131 surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
132 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
Peiyong Lin1f6aa122018-09-10 16:28:08 -0700133 pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, true, contentDrawBounds,
John Reck1bcacfd2017-11-03 10:12:19 -0700134 surface);
Stan Iliev500a0c32016-10-26 10:30:09 -0400135 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
136 ASSERT_EQ(TestUtils::getColor(surface, 1, 0), SK_ColorBLUE);
137 ASSERT_EQ(TestUtils::getColor(surface, 0, 1), SK_ColorRED);
138 ASSERT_EQ(TestUtils::getColor(surface, 1, 1), SK_ColorRED);
139}
140
Greg Daniel98c78dad2017-01-04 14:45:56 -0500141RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderLayer) {
John Reck1bcacfd2017-11-03 10:12:19 -0700142 auto redNode = TestUtils::createSkiaNode(
143 0, 0, 1, 1, [](RenderProperties& props, SkiaRecordingCanvas& redCanvas) {
144 redCanvas.drawColor(SK_ColorRED, SkBlendMode::kSrcOver);
145 });
Stan Iliev500a0c32016-10-26 10:30:09 -0400146 auto surfaceLayer1 = SkSurface::MakeRasterN32Premul(1, 1);
147 surfaceLayer1->getCanvas()->drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver);
148 ASSERT_EQ(TestUtils::getColor(surfaceLayer1, 0, 0), SK_ColorWHITE);
149 redNode->setLayerSurface(surfaceLayer1);
150
John Reck1bcacfd2017-11-03 10:12:19 -0700151 // create a 2nd 2x2 layer and add it to the queue as well.
152 // make the layer's dirty area one half of the layer and verify only the dirty half is updated.
153 auto blueNode = TestUtils::createSkiaNode(
154 0, 0, 2, 2, [](RenderProperties& props, SkiaRecordingCanvas& blueCanvas) {
155 blueCanvas.drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
156 });
Stan Iliev500a0c32016-10-26 10:30:09 -0400157 auto surfaceLayer2 = SkSurface::MakeRasterN32Premul(2, 2);
158 surfaceLayer2->getCanvas()->drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver);
159 ASSERT_EQ(TestUtils::getColor(surfaceLayer2, 0, 0), SK_ColorWHITE);
160 blueNode->setLayerSurface(surfaceLayer2);
161
John Reck1bcacfd2017-11-03 10:12:19 -0700162 // attach both layers to the update queue
Stan Iliev500a0c32016-10-26 10:30:09 -0400163 LayerUpdateQueue layerUpdateQueue;
Mike Reedf3338bd2018-10-09 11:54:39 -0400164 SkRect dirty = SkRectMakeLargest();
Stan Iliev500a0c32016-10-26 10:30:09 -0400165 layerUpdateQueue.enqueueLayerWithDamage(redNode.get(), dirty);
166 layerUpdateQueue.enqueueLayerWithDamage(blueNode.get(), SkRect::MakeWH(2, 1));
167 ASSERT_EQ(layerUpdateQueue.entries().size(), 2UL);
168
169 bool opaque = true;
John Reckd9d7f122018-05-03 14:40:56 -0700170 LightGeometry lightGeometry;
Stan Iliev500a0c32016-10-26 10:30:09 -0400171 lightGeometry.radius = 1.0f;
John Reck1bcacfd2017-11-03 10:12:19 -0700172 lightGeometry.center = {0.0f, 0.0f, 0.0f};
John Reckd9d7f122018-05-03 14:40:56 -0700173 LightInfo lightInfo;
Stan Iliev500a0c32016-10-26 10:30:09 -0400174 auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
Peiyong Lin1f6aa122018-09-10 16:28:08 -0700175 pipeline->renderLayers(lightGeometry, &layerUpdateQueue, opaque, lightInfo);
Stan Iliev500a0c32016-10-26 10:30:09 -0400176 ASSERT_EQ(TestUtils::getColor(surfaceLayer1, 0, 0), SK_ColorRED);
177 ASSERT_EQ(TestUtils::getColor(surfaceLayer2, 0, 0), SK_ColorBLUE);
178 ASSERT_EQ(TestUtils::getColor(surfaceLayer2, 0, 1), SK_ColorWHITE);
179 ASSERT_TRUE(layerUpdateQueue.entries().empty());
180 redNode->setLayerSurface(sk_sp<SkSurface>());
181 blueNode->setLayerSurface(sk_sp<SkSurface>());
182}
Matt Sarettf58cc922016-11-14 18:33:38 -0500183
Greg Daniel98c78dad2017-01-04 14:45:56 -0500184RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderOverdraw) {
Matt Sarettf58cc922016-11-14 18:33:38 -0500185 ScopedProperty<bool> prop(Properties::debugOverdraw, true);
186
John Reck1bcacfd2017-11-03 10:12:19 -0700187 auto whiteNode = TestUtils::createSkiaNode(
188 0, 0, 1, 1, [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
189 canvas.drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver);
190 });
Matt Sarettf58cc922016-11-14 18:33:38 -0500191 LayerUpdateQueue layerUpdateQueue;
192 SkRect dirty = SkRect::MakeXYWH(0, 0, 1, 1);
193 std::vector<sp<RenderNode>> renderNodes;
194 renderNodes.push_back(whiteNode);
195 bool opaque = true;
John Reck1bcacfd2017-11-03 10:12:19 -0700196 // empty contentDrawBounds is avoiding backdrop/content logic, which would lead to less overdraw
Stan Iliev52771272016-11-17 09:54:38 -0500197 android::uirenderer::Rect contentDrawBounds(0, 0, 0, 0);
Matt Sarettf58cc922016-11-14 18:33:38 -0500198 auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
199 auto surface = SkSurface::MakeRasterN32Premul(1, 1);
200
201 // Initialize the canvas to blue.
202 surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
203 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
204
205 // Single draw, should be white.
Peiyong Lin1f6aa122018-09-10 16:28:08 -0700206 pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds,
John Reck1bcacfd2017-11-03 10:12:19 -0700207 surface);
Matt Sarettf58cc922016-11-14 18:33:38 -0500208 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorWHITE);
209
210 // 1 Overdraw, should be blue blended onto white.
Matt Sarett341480b2017-01-23 19:45:42 -0500211 renderNodes.push_back(whiteNode);
Peiyong Lin1f6aa122018-09-10 16:28:08 -0700212 pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds,
John Reck1bcacfd2017-11-03 10:12:19 -0700213 surface);
214 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned)0xffd0d0ff);
Matt Sarettf58cc922016-11-14 18:33:38 -0500215
216 // 2 Overdraw, should be green blended onto white
217 renderNodes.push_back(whiteNode);
Peiyong Lin1f6aa122018-09-10 16:28:08 -0700218 pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds,
John Reck1bcacfd2017-11-03 10:12:19 -0700219 surface);
220 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned)0xffd0ffd0);
Matt Sarettf58cc922016-11-14 18:33:38 -0500221
222 // 3 Overdraw, should be pink blended onto white.
223 renderNodes.push_back(whiteNode);
Peiyong Lin1f6aa122018-09-10 16:28:08 -0700224 pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds,
John Reck1bcacfd2017-11-03 10:12:19 -0700225 surface);
226 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned)0xffffc0c0);
Matt Sarettf58cc922016-11-14 18:33:38 -0500227
228 // 4 Overdraw, should be red blended onto white.
229 renderNodes.push_back(whiteNode);
Peiyong Lin1f6aa122018-09-10 16:28:08 -0700230 pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds,
John Reck1bcacfd2017-11-03 10:12:19 -0700231 surface);
232 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned)0xffff8080);
Matt Sarettf58cc922016-11-14 18:33:38 -0500233
234 // 5 Overdraw, should be red blended onto white.
235 renderNodes.push_back(whiteNode);
Peiyong Lin1f6aa122018-09-10 16:28:08 -0700236 pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds,
John Reck1bcacfd2017-11-03 10:12:19 -0700237 surface);
238 ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned)0xffff8080);
Matt Sarettf58cc922016-11-14 18:33:38 -0500239}
Stan Iliev52771272016-11-17 09:54:38 -0500240
241namespace {
242template <typename T>
243class DeferLayer : public SkSurface_Base {
244public:
Derek Sollenberger624ad832017-01-11 11:09:48 -0500245 DeferLayer() : SkSurface_Base(T().imageInfo(), nullptr) {}
246 virtual ~DeferLayer() {}
247
John Reck1bcacfd2017-11-03 10:12:19 -0700248 SkCanvas* onNewCanvas() override { return new T(); }
249 sk_sp<SkSurface> onNewSurface(const SkImageInfo&) override { return nullptr; }
250 sk_sp<SkImage> onNewImageSnapshot() override { return nullptr; }
Stan Ilieved4d58c2016-12-14 14:05:04 -0500251 T* canvas() { return static_cast<T*>(getCanvas()); }
Stan Iliev52771272016-11-17 09:54:38 -0500252 void onCopyOnWrite(ContentChangeMode) override {}
Leon Scroggins III71195ab2018-02-08 17:14:28 -0500253 void onWritePixels(const SkPixmap&, int x, int y) override {}
Stan Iliev52771272016-11-17 09:54:38 -0500254};
255}
256
Greg Daniel98c78dad2017-01-04 14:45:56 -0500257RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, deferRenderNodeScene) {
Stan Iliev52771272016-11-17 09:54:38 -0500258 class DeferTestCanvas : public SkCanvas {
259 public:
260 DeferTestCanvas() : SkCanvas(800, 600) {}
261 void onDrawRect(const SkRect& rect, const SkPaint& paint) override {
262 SkMatrix expected;
263 switch (mDrawCounter++) {
John Reck1bcacfd2017-11-03 10:12:19 -0700264 case 0:
265 // background - left side
266 EXPECT_EQ(SkRect::MakeLTRB(600, 100, 700, 500), TestUtils::getClipBounds(this));
267 expected.setTranslate(100, 100);
268 break;
269 case 1:
270 // background - top side
271 EXPECT_EQ(SkRect::MakeLTRB(100, 400, 600, 500), TestUtils::getClipBounds(this));
272 expected.setTranslate(100, 100);
273 break;
274 case 2:
275 // content
276 EXPECT_EQ(SkRect::MakeLTRB(100, 100, 700, 500), TestUtils::getClipBounds(this));
277 expected.setTranslate(-50, -50);
278 break;
279 case 3:
280 // overlay
281 EXPECT_EQ(SkRect::MakeLTRB(0, 0, 800, 600), TestUtils::getClipBounds(this));
282 expected.reset();
283 break;
284 default:
285 ADD_FAILURE() << "Too many rects observed";
Stan Iliev52771272016-11-17 09:54:38 -0500286 }
287 EXPECT_EQ(expected, getTotalMatrix());
288 }
289 int mDrawCounter = 0;
290 };
291
292 std::vector<sp<RenderNode>> nodes;
293 SkPaint transparentPaint;
294 transparentPaint.setAlpha(128);
295
296 // backdrop
John Reck1bcacfd2017-11-03 10:12:19 -0700297 nodes.push_back(TestUtils::createSkiaNode(
298 100, 100, 700, 500, // 600x400
Stan Iliev52771272016-11-17 09:54:38 -0500299 [&transparentPaint](RenderProperties& props, SkiaRecordingCanvas& canvas) {
John Reck1bcacfd2017-11-03 10:12:19 -0700300 canvas.drawRect(0, 0, 600, 400, transparentPaint);
301 }));
Stan Iliev52771272016-11-17 09:54:38 -0500302
303 // content
John Reck1bcacfd2017-11-03 10:12:19 -0700304 android::uirenderer::Rect contentDrawBounds(150, 150, 650, 450); // 500x300
305 nodes.push_back(TestUtils::createSkiaNode(
306 0, 0, 800, 600,
Stan Iliev52771272016-11-17 09:54:38 -0500307 [&transparentPaint](RenderProperties& props, SkiaRecordingCanvas& canvas) {
John Reck1bcacfd2017-11-03 10:12:19 -0700308 canvas.drawRect(0, 0, 800, 600, transparentPaint);
309 }));
Stan Iliev52771272016-11-17 09:54:38 -0500310
311 // overlay
John Reck1bcacfd2017-11-03 10:12:19 -0700312 nodes.push_back(TestUtils::createSkiaNode(
313 0, 0, 800, 600,
Stan Iliev52771272016-11-17 09:54:38 -0500314 [&transparentPaint](RenderProperties& props, SkiaRecordingCanvas& canvas) {
John Reck1bcacfd2017-11-03 10:12:19 -0700315 canvas.drawRect(0, 0, 800, 200, transparentPaint);
316 }));
Stan Iliev52771272016-11-17 09:54:38 -0500317
318 LayerUpdateQueue layerUpdateQueue;
319 SkRect dirty = SkRect::MakeWH(800, 600);
320 auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
Stan Ilieved4d58c2016-12-14 14:05:04 -0500321 sk_sp<DeferLayer<DeferTestCanvas>> surface(new DeferLayer<DeferTestCanvas>());
Peiyong Lin1f6aa122018-09-10 16:28:08 -0700322 pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true, contentDrawBounds, surface);
Stan Ilieved4d58c2016-12-14 14:05:04 -0500323 EXPECT_EQ(4, surface->canvas()->mDrawCounter);
Stan Iliev52771272016-11-17 09:54:38 -0500324}
325
Greg Daniel98c78dad2017-01-04 14:45:56 -0500326RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, clipped) {
Stan Iliev52771272016-11-17 09:54:38 -0500327 static const int CANVAS_WIDTH = 200;
328 static const int CANVAS_HEIGHT = 200;
329 class ClippedTestCanvas : public SkCanvas {
330 public:
John Reck1bcacfd2017-11-03 10:12:19 -0700331 ClippedTestCanvas() : SkCanvas(CANVAS_WIDTH, CANVAS_HEIGHT) {}
Stan Iliev52771272016-11-17 09:54:38 -0500332 void onDrawImage(const SkImage*, SkScalar dx, SkScalar dy, const SkPaint*) override {
333 EXPECT_EQ(0, mDrawCounter++);
334 EXPECT_EQ(SkRect::MakeLTRB(10, 20, 30, 40), TestUtils::getClipBounds(this));
335 EXPECT_TRUE(getTotalMatrix().isIdentity());
336 }
337 int mDrawCounter = 0;
338 };
339
340 std::vector<sp<RenderNode>> nodes;
John Reck1bcacfd2017-11-03 10:12:19 -0700341 nodes.push_back(TestUtils::createSkiaNode(
342 0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
Stan Iliev52771272016-11-17 09:54:38 -0500343 [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
John Reck1bcacfd2017-11-03 10:12:19 -0700344 sk_sp<Bitmap> bitmap(TestUtils::createBitmap(CANVAS_WIDTH, CANVAS_HEIGHT));
345 canvas.drawBitmap(*bitmap, 0, 0, nullptr);
346 }));
Stan Iliev52771272016-11-17 09:54:38 -0500347
348 LayerUpdateQueue layerUpdateQueue;
349 SkRect dirty = SkRect::MakeLTRB(10, 20, 30, 40);
350 auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
Stan Ilieved4d58c2016-12-14 14:05:04 -0500351 sk_sp<DeferLayer<ClippedTestCanvas>> surface(new DeferLayer<ClippedTestCanvas>());
Peiyong Lin1f6aa122018-09-10 16:28:08 -0700352 pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true,
John Reck1bcacfd2017-11-03 10:12:19 -0700353 SkRect::MakeWH(CANVAS_WIDTH, CANVAS_HEIGHT), surface);
Stan Ilieved4d58c2016-12-14 14:05:04 -0500354 EXPECT_EQ(1, surface->canvas()->mDrawCounter);
Stan Iliev52771272016-11-17 09:54:38 -0500355}
356
Greg Daniel98c78dad2017-01-04 14:45:56 -0500357RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, clip_replace) {
Stan Iliev52771272016-11-17 09:54:38 -0500358 static const int CANVAS_WIDTH = 50;
359 static const int CANVAS_HEIGHT = 50;
360 class ClipReplaceTestCanvas : public SkCanvas {
361 public:
John Reck1bcacfd2017-11-03 10:12:19 -0700362 ClipReplaceTestCanvas() : SkCanvas(CANVAS_WIDTH, CANVAS_HEIGHT) {}
Stan Iliev52771272016-11-17 09:54:38 -0500363 void onDrawPaint(const SkPaint&) {
364 EXPECT_EQ(0, mDrawCounter++);
Stan Ilievb66b8bb2016-12-15 18:17:42 -0500365 EXPECT_EQ(SkRect::MakeLTRB(20, 10, 30, 40), TestUtils::getClipBounds(this))
366 << "Expect resolved clip to be intersection of viewport clip and clip op";
Stan Iliev52771272016-11-17 09:54:38 -0500367 }
368 int mDrawCounter = 0;
369 };
370
371 std::vector<sp<RenderNode>> nodes;
John Reck1bcacfd2017-11-03 10:12:19 -0700372 nodes.push_back(TestUtils::createSkiaNode(
373 20, 20, 30, 30, [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
374 canvas.clipRect(0, -20, 10, 30, SkClipOp::kReplace_deprecated);
375 canvas.drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver);
376 }));
Stan Iliev52771272016-11-17 09:54:38 -0500377
378 LayerUpdateQueue layerUpdateQueue;
379 SkRect dirty = SkRect::MakeLTRB(10, 10, 40, 40);
380 auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
Stan Ilieved4d58c2016-12-14 14:05:04 -0500381 sk_sp<DeferLayer<ClipReplaceTestCanvas>> surface(new DeferLayer<ClipReplaceTestCanvas>());
Peiyong Lin1f6aa122018-09-10 16:28:08 -0700382 pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true,
John Reck1bcacfd2017-11-03 10:12:19 -0700383 SkRect::MakeWH(CANVAS_WIDTH, CANVAS_HEIGHT), surface);
Stan Ilieved4d58c2016-12-14 14:05:04 -0500384 EXPECT_EQ(1, surface->canvas()->mDrawCounter);
Stan Iliev52771272016-11-17 09:54:38 -0500385}
Derek Sollenberger5a5a6482018-09-19 13:52:13 -0400386
387RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, context_lost) {
388 auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
389 EXPECT_FALSE(pipeline->isSurfaceReady());
Peiyong Lin189021b2018-09-27 16:41:40 -0700390 EXPECT_TRUE(pipeline->setSurface((Surface*)0x01, SwapBehavior::kSwap_default, ColorMode::SRGB));
Derek Sollenberger5a5a6482018-09-19 13:52:13 -0400391 EXPECT_TRUE(pipeline->isSurfaceReady());
392 renderThread.destroyGlContext();
393 EXPECT_FALSE(pipeline->isSurfaceReady());
394}
395