blob: a0542dd0cddf52511715a344d61ddb21a1e309fc [file] [log] [blame]
Alec Mouri6e57f682018-09-29 20:45:08 -07001/*
2 * Copyright 2018 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
17#include <gtest/gtest.h>
18
19#include <renderengine/RenderEngine.h>
Alec Mouri1089aed2018-10-25 21:33:57 -070020#include <sync/sync.h>
Alec Mouri6e57f682018-09-29 20:45:08 -070021#include <ui/PixelFormat.h>
22
Alec Mouri1089aed2018-10-25 21:33:57 -070023constexpr int DEFAULT_DISPLAY_WIDTH = 128;
24constexpr int DEFAULT_DISPLAY_HEIGHT = 256;
25constexpr int DEFAULT_DISPLAY_OFFSET = 64;
26
Alec Mouri6e57f682018-09-29 20:45:08 -070027namespace android {
28
Alec Mouri1089aed2018-10-25 21:33:57 -070029struct RenderEngineTest : public ::testing::Test {
30 sp<GraphicBuffer> allocateDefaultBuffer() {
31 return new GraphicBuffer(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT,
32 HAL_PIXEL_FORMAT_RGBA_8888, 1,
33 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
34 "output");
Alec Mouri6e57f682018-09-29 20:45:08 -070035 }
36
Alec Mouri1089aed2018-10-25 21:33:57 -070037 RenderEngineTest() { mBuffer = allocateDefaultBuffer(); }
38
39 void expectBufferColor(const Rect& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
40 uint8_t tolerance = 0) {
41 uint8_t* pixels;
42 mBuffer->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
43 reinterpret_cast<void**>(&pixels));
44
45 auto colorCompare = [tolerance](uint8_t a, uint8_t b) {
46 uint8_t tmp = a >= b ? a - b : b - a;
47 return tmp <= tolerance;
48 };
49 int32_t maxFails = 10;
50 int32_t fails = 0;
51 for (int32_t j = 0; j < region.getHeight(); j++) {
52 const uint8_t* src =
53 pixels + (mBuffer->getStride() * (region.top + j) + region.left) * 4;
54 for (int32_t i = 0; i < region.getWidth(); i++) {
55 const uint8_t expected[4] = {r, g, b, a};
56 bool equal = std::equal(src, src + 4, expected, colorCompare);
57 EXPECT_TRUE(equal)
58 << "pixel @ (" << region.left + i << ", " << region.top + j << "): "
59 << "expected (" << static_cast<uint32_t>(r) << ", "
60 << static_cast<uint32_t>(g) << ", " << static_cast<uint32_t>(b) << ", "
61 << static_cast<uint32_t>(a) << "), "
62 << "got (" << static_cast<uint32_t>(src[0]) << ", "
63 << static_cast<uint32_t>(src[1]) << ", " << static_cast<uint32_t>(src[2])
64 << ", " << static_cast<uint32_t>(src[3]) << ")";
65 src += 4;
66 if (!equal && ++fails >= maxFails) {
67 break;
68 }
69 }
70 if (fails >= maxFails) {
71 break;
72 }
73 }
74 mBuffer->unlock();
75 }
76
77 static Rect fullscreenRect() { return Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT); }
78
79 static Rect offsetRect() {
80 return Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
81 DEFAULT_DISPLAY_HEIGHT);
82 }
83
84 static Rect offsetRectAtZero() {
85 return Rect(DEFAULT_DISPLAY_WIDTH - DEFAULT_DISPLAY_OFFSET,
86 DEFAULT_DISPLAY_HEIGHT - DEFAULT_DISPLAY_OFFSET);
87 }
88
89 static void invokeDraw(renderengine::DisplaySettings settings,
90 std::vector<renderengine::LayerSettings> layers,
91 sp<GraphicBuffer> buffer) {
92 base::unique_fd fence;
93 status_t status = sRE->drawLayers(settings, layers, buffer->getNativeBuffer(), &fence);
94
95 int fd = fence.release();
96 if (fd >= 0) {
97 sync_wait(fd, -1);
98 close(fd);
99 }
100
101 ASSERT_EQ(NO_ERROR, status);
102 }
103
104 static void drawEmptyLayers() {
Alec Mouri6e57f682018-09-29 20:45:08 -0700105 renderengine::DisplaySettings settings;
106 std::vector<renderengine::LayerSettings> layers;
107 // Meaningless buffer since we don't do any drawing
108 sp<GraphicBuffer> buffer = new GraphicBuffer();
Alec Mouri1089aed2018-10-25 21:33:57 -0700109 invokeDraw(settings, layers, buffer);
Alec Mouri6e57f682018-09-29 20:45:08 -0700110 }
111
Alec Mouri1089aed2018-10-25 21:33:57 -0700112 template <typename SourceVariant>
113 void fillBuffer(half r, half g, half b, half a);
114
115 template <typename SourceVariant>
116 void fillRedBuffer();
117
118 template <typename SourceVariant>
119 void fillGreenBuffer();
120
121 template <typename SourceVariant>
122 void fillBlueBuffer();
123
124 template <typename SourceVariant>
125 void fillRedTransparentBuffer();
126
127 template <typename SourceVariant>
128 void fillRedOffsetBuffer();
129
130 template <typename SourceVariant>
131 void fillBufferPhysicalOffset();
132
133 template <typename SourceVariant>
134 void fillBufferCheckers(mat4 transform);
135
136 template <typename SourceVariant>
137 void fillBufferCheckersRotate0();
138
139 template <typename SourceVariant>
140 void fillBufferCheckersRotate90();
141
142 template <typename SourceVariant>
143 void fillBufferCheckersRotate180();
144
145 template <typename SourceVariant>
146 void fillBufferCheckersRotate270();
147
148 template <typename SourceVariant>
149 void fillBufferLayerTransform();
150
151 template <typename SourceVariant>
152 void fillBufferColorTransform();
153
154 // Dumb hack to get aroud the fact that tear-down for renderengine isn't
155 // well defined right now, so we can't create multiple instances
156 static std::unique_ptr<renderengine::RenderEngine> sRE;
157
158 sp<GraphicBuffer> mBuffer;
Alec Mouri6e57f682018-09-29 20:45:08 -0700159};
160
Alec Mouri1089aed2018-10-25 21:33:57 -0700161std::unique_ptr<renderengine::RenderEngine> RenderEngineTest::sRE =
162 renderengine::RenderEngine::create(static_cast<int32_t>(ui::PixelFormat::RGBA_8888), 0);
163
164struct ColorSourceVariant {
165 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b) {
166 layer.source.solidColor = half3(r, g, b);
167 }
168};
169
170template <typename SourceVariant>
171void RenderEngineTest::fillBuffer(half r, half g, half b, half a) {
172 renderengine::DisplaySettings settings;
173 settings.physicalDisplay = fullscreenRect();
174 settings.clip = fullscreenRect();
175
176 std::vector<renderengine::LayerSettings> layers;
177
178 renderengine::LayerSettings layer;
179 layer.geometry.boundaries = fullscreenRect().toFloatRect();
180 SourceVariant::fillColor(layer, r, g, b);
181 layer.alpha = a;
182
183 layers.push_back(layer);
184
185 invokeDraw(settings, layers, mBuffer);
186}
187
188template <typename SourceVariant>
189void RenderEngineTest::fillRedBuffer() {
190 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, 1.0f);
191 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
192}
193
194template <typename SourceVariant>
195void RenderEngineTest::fillGreenBuffer() {
196 fillBuffer<SourceVariant>(0.0f, 1.0f, 0.0f, 1.0f);
197 expectBufferColor(fullscreenRect(), 0, 255, 0, 255);
198}
199
200template <typename SourceVariant>
201void RenderEngineTest::fillBlueBuffer() {
202 fillBuffer<SourceVariant>(0.0f, 0.0f, 1.0f, 1.0f);
203 expectBufferColor(fullscreenRect(), 0, 0, 255, 255);
204}
205
206template <typename SourceVariant>
207void RenderEngineTest::fillRedTransparentBuffer() {
208 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, .2f);
209 expectBufferColor(fullscreenRect(), 51, 0, 0, 51);
210}
211
212template <typename SourceVariant>
213void RenderEngineTest::fillRedOffsetBuffer() {
214 renderengine::DisplaySettings settings;
215 settings.physicalDisplay = offsetRect();
216 settings.clip = offsetRectAtZero();
217
218 std::vector<renderengine::LayerSettings> layers;
219
220 renderengine::LayerSettings layer;
221 layer.geometry.boundaries = offsetRectAtZero().toFloatRect();
222 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f);
223 layer.alpha = 1.0f;
224
225 layers.push_back(layer);
226 invokeDraw(settings, layers, mBuffer);
227}
228
229template <typename SourceVariant>
230void RenderEngineTest::fillBufferPhysicalOffset() {
231 fillRedOffsetBuffer<SourceVariant>();
232
233 expectBufferColor(Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
234 DEFAULT_DISPLAY_HEIGHT),
235 255, 0, 0, 255);
236 Rect offsetRegionLeft(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_HEIGHT);
237 Rect offsetRegionTop(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_OFFSET);
238
239 expectBufferColor(offsetRegionLeft, 0, 0, 0, 0);
240 expectBufferColor(offsetRegionTop, 0, 0, 0, 0);
241}
242
243template <typename SourceVariant>
244void RenderEngineTest::fillBufferCheckers(mat4 transform) {
245 renderengine::DisplaySettings settings;
246 settings.physicalDisplay = fullscreenRect();
247 // Here logical space is 2x2
248 settings.clip = Rect(2, 2);
249 settings.globalTransform = transform;
250
251 std::vector<renderengine::LayerSettings> layers;
252
253 renderengine::LayerSettings layerOne;
254 Rect rectOne(0, 0, 1, 1);
255 layerOne.geometry.boundaries = rectOne.toFloatRect();
256 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f);
257 layerOne.alpha = 1.0f;
258
259 renderengine::LayerSettings layerTwo;
260 Rect rectTwo(0, 1, 1, 2);
261 layerTwo.geometry.boundaries = rectTwo.toFloatRect();
262 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f);
263 layerTwo.alpha = 1.0f;
264
265 renderengine::LayerSettings layerThree;
266 Rect rectThree(1, 0, 2, 1);
267 layerThree.geometry.boundaries = rectThree.toFloatRect();
268 SourceVariant::fillColor(layerThree, 0.0f, 0.0f, 1.0f);
269 layerThree.alpha = 1.0f;
270
271 layers.push_back(layerOne);
272 layers.push_back(layerTwo);
273 layers.push_back(layerThree);
274
275 invokeDraw(settings, layers, mBuffer);
276}
277
278template <typename SourceVariant>
279void RenderEngineTest::fillBufferCheckersRotate0() {
280 fillBufferCheckers<SourceVariant>(mat4());
281 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0,
282 255);
283 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
284 DEFAULT_DISPLAY_HEIGHT / 2),
285 0, 0, 255, 255);
286 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
287 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
288 0, 0, 0, 0);
289 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
290 DEFAULT_DISPLAY_HEIGHT),
291 0, 255, 0, 255);
292}
293
294template <typename SourceVariant>
295void RenderEngineTest::fillBufferCheckersRotate90() {
296 mat4 matrix = mat4(0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 1);
297 fillBufferCheckers<SourceVariant>(matrix);
298 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 255, 0,
299 255);
300 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
301 DEFAULT_DISPLAY_HEIGHT / 2),
302 255, 0, 0, 255);
303 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
304 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
305 0, 0, 255, 255);
306 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
307 DEFAULT_DISPLAY_HEIGHT),
308 0, 0, 0, 0);
309}
310
311template <typename SourceVariant>
312void RenderEngineTest::fillBufferCheckersRotate180() {
313 mat4 matrix = mat4(-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 2, 2, 0, 1);
314 fillBufferCheckers<SourceVariant>(matrix);
315 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0,
316 0);
317 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
318 DEFAULT_DISPLAY_HEIGHT / 2),
319 0, 255, 0, 255);
320 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
321 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
322 255, 0, 0, 255);
323 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
324 DEFAULT_DISPLAY_HEIGHT),
325 0, 0, 255, 255);
326}
327
328template <typename SourceVariant>
329void RenderEngineTest::fillBufferCheckersRotate270() {
330 mat4 matrix = mat4(0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 1);
331 fillBufferCheckers<SourceVariant>(matrix);
332 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 255,
333 255);
334 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
335 DEFAULT_DISPLAY_HEIGHT / 2),
336 0, 0, 0, 0);
337 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
338 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
339 0, 255, 0, 255);
340 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
341 DEFAULT_DISPLAY_HEIGHT),
342 255, 0, 0, 255);
343}
344
345template <typename SourceVariant>
346void RenderEngineTest::fillBufferLayerTransform() {
347 renderengine::DisplaySettings settings;
348 settings.physicalDisplay = fullscreenRect();
349 // Here logical space is 2x2
350 settings.clip = Rect(2, 2);
351
352 std::vector<renderengine::LayerSettings> layers;
353
354 renderengine::LayerSettings layer;
355 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
356 // Translate one pixel diagonally
357 layer.geometry.positionTransform = mat4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1);
358 layer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
359 layer.alpha = 1.0f;
360
361 layers.push_back(layer);
362
363 invokeDraw(settings, layers, mBuffer);
364
365 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0, 0);
366 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
367 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
368 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
369 255, 0, 0, 255);
370}
371
372template <typename SourceVariant>
373void RenderEngineTest::fillBufferColorTransform() {
374 renderengine::DisplaySettings settings;
375 settings.physicalDisplay = fullscreenRect();
376 settings.clip = Rect(1, 1);
377
378 std::vector<renderengine::LayerSettings> layers;
379
380 renderengine::LayerSettings layer;
381 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
382 layer.source.solidColor = half3(0.5f, 0.25f, 0.125f);
383 layer.alpha = 1.0f;
384
385 // construct a fake color matrix
386 // annihilate green and blue channels
387 settings.colorTransform = mat4::scale(vec4(1, 0, 0, 1));
388 // set red channel to red + green
389 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
390
391 layers.push_back(layer);
392
393 invokeDraw(settings, layers, mBuffer);
394
395 expectBufferColor(fullscreenRect(), 191, 0, 0, 255);
396}
397
398TEST_F(RenderEngineTest, drawLayers_noLayersToDraw) {
399 drawEmptyLayers();
400}
401
402TEST_F(RenderEngineTest, drawLayers_fillRedBuffer_colorSource) {
403 fillRedBuffer<ColorSourceVariant>();
404}
405
406TEST_F(RenderEngineTest, drawLayers_fillGreenBuffer_colorSource) {
407 fillGreenBuffer<ColorSourceVariant>();
408}
409
410TEST_F(RenderEngineTest, drawLayers_fillBlueBuffer_colorSource) {
411 fillBlueBuffer<ColorSourceVariant>();
412}
413
414TEST_F(RenderEngineTest, drawLayers_fillRedTransparentBuffer_colorSource) {
415 fillRedTransparentBuffer<ColorSourceVariant>();
416}
417
418TEST_F(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_colorSource) {
419 fillBufferPhysicalOffset<ColorSourceVariant>();
420}
421
422TEST_F(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_colorSource) {
423 fillBufferCheckersRotate0<ColorSourceVariant>();
424}
425
426TEST_F(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_colorSource) {
427 fillBufferCheckersRotate90<ColorSourceVariant>();
428}
429
430TEST_F(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_colorSource) {
431 fillBufferCheckersRotate180<ColorSourceVariant>();
432}
433
434TEST_F(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_colorSource) {
435 fillBufferCheckersRotate270<ColorSourceVariant>();
436}
437
438TEST_F(RenderEngineTest, drawLayers_fillBufferLayerTransform_colorSource) {
439 fillBufferLayerTransform<ColorSourceVariant>();
440}
441
442TEST_F(RenderEngineTest, drawLayers_fillBufferColorTransform_colorSource) {
443 fillBufferLayerTransform<ColorSourceVariant>();
Alec Mouri6e57f682018-09-29 20:45:08 -0700444}
445
446} // namespace android