blob: b0360a2ad28059ff4f3cd7a936a874ead14d2167 [file] [log] [blame]
Jamie Gennis23c2c5d2011-10-11 19:22:19 -07001/*
2 * Copyright (C) 2011 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
Chia-I Wu718daf82017-10-20 11:57:17 -070017#include <algorithm>
Marissa Wallfda30bb2018-10-12 11:34:28 -070018#include <chrono>
19#include <cinttypes>
Chia-I Wu718daf82017-10-20 11:57:17 -070020#include <functional>
21#include <limits>
22#include <ostream>
Marissa Wallfda30bb2018-10-12 11:34:28 -070023#include <thread>
Chia-I Wu718daf82017-10-20 11:57:17 -070024
Jamie Gennis23c2c5d2011-10-11 19:22:19 -070025#include <gtest/gtest.h>
26
Michael Lentine5a16a622015-05-21 13:48:24 -070027#include <android/native_window.h>
28
Mathias Agopian90ac7992012-02-25 18:48:35 -080029#include <gui/ISurfaceComposer.h>
Robert Carr4cdc58f2017-08-23 14:22:20 -070030#include <gui/LayerState.h>
31
Mathias Agopian90ac7992012-02-25 18:48:35 -080032#include <gui/Surface.h>
33#include <gui/SurfaceComposerClient.h>
34#include <private/gui/ComposerService.h>
35
Ady Abraham2a6ab2a2018-10-26 14:25:30 -070036#include <ui/ColorSpace.h>
Mathias Agopianc666cae2012-07-25 18:56:13 -070037#include <ui/DisplayInfo.h>
Chia-I Wu718daf82017-10-20 11:57:17 -070038#include <ui/Rect.h>
Chia-I Wu1078bbb2017-10-20 11:29:02 -070039#include <utils/String8.h>
Jamie Gennis23c2c5d2011-10-11 19:22:19 -070040
Pablo Ceballos5e4fcbe2015-09-02 09:53:16 -070041#include <math.h>
chaviw13fdc492017-06-27 12:40:18 -070042#include <math/vec3.h>
Pablo Ceballos5e4fcbe2015-09-02 09:53:16 -070043
Jamie Gennis23c2c5d2011-10-11 19:22:19 -070044namespace android {
45
Chia-I Wu718daf82017-10-20 11:57:17 -070046namespace {
47
48struct Color {
49 uint8_t r;
50 uint8_t g;
51 uint8_t b;
52 uint8_t a;
53
54 static const Color RED;
Chia-I Wu0ea0f822017-10-31 10:14:40 -070055 static const Color GREEN;
Chia-I Wu49313302017-10-31 10:14:40 -070056 static const Color BLUE;
Chia-I Wu93853fe2017-11-02 08:30:27 -070057 static const Color WHITE;
Chia-I Wu718daf82017-10-20 11:57:17 -070058 static const Color BLACK;
Chia-I Wu2113bdd2017-11-01 15:16:35 -070059 static const Color TRANSPARENT;
Chia-I Wu718daf82017-10-20 11:57:17 -070060};
61
62const Color Color::RED{255, 0, 0, 255};
Chia-I Wu0ea0f822017-10-31 10:14:40 -070063const Color Color::GREEN{0, 255, 0, 255};
Chia-I Wu49313302017-10-31 10:14:40 -070064const Color Color::BLUE{0, 0, 255, 255};
Chia-I Wu93853fe2017-11-02 08:30:27 -070065const Color Color::WHITE{255, 255, 255, 255};
Chia-I Wu718daf82017-10-20 11:57:17 -070066const Color Color::BLACK{0, 0, 0, 255};
Chia-I Wu2113bdd2017-11-01 15:16:35 -070067const Color Color::TRANSPARENT{0, 0, 0, 0};
Chia-I Wu718daf82017-10-20 11:57:17 -070068
Marissa Wall61c58622018-07-18 10:12:20 -070069using android::hardware::graphics::common::V1_1::BufferUsage;
Marissa Wallfda30bb2018-10-12 11:34:28 -070070using namespace std::chrono_literals;
Marissa Wall61c58622018-07-18 10:12:20 -070071
Chia-I Wu718daf82017-10-20 11:57:17 -070072std::ostream& operator<<(std::ostream& os, const Color& color) {
73 os << int(color.r) << ", " << int(color.g) << ", " << int(color.b) << ", " << int(color.a);
74 return os;
75}
76
77// Fill a region with the specified color.
Marissa Wall61c58622018-07-18 10:12:20 -070078void fillANativeWindowBufferColor(const ANativeWindow_Buffer& buffer, const Rect& rect,
79 const Color& color) {
80 Rect r(0, 0, buffer.width, buffer.height);
81 if (!r.intersect(rect, &r)) {
82 return;
Chia-I Wu718daf82017-10-20 11:57:17 -070083 }
84
Marissa Wall61c58622018-07-18 10:12:20 -070085 int32_t width = r.right - r.left;
86 int32_t height = r.bottom - r.top;
87
88 for (int32_t row = 0; row < height; row++) {
89 uint8_t* dst =
90 static_cast<uint8_t*>(buffer.bits) + (buffer.stride * (r.top + row) + r.left) * 4;
91 for (int32_t column = 0; column < width; column++) {
Chia-I Wu718daf82017-10-20 11:57:17 -070092 dst[0] = color.r;
93 dst[1] = color.g;
94 dst[2] = color.b;
95 dst[3] = color.a;
96 dst += 4;
97 }
98 }
99}
100
Marissa Wall61c58622018-07-18 10:12:20 -0700101// Fill a region with the specified color.
102void fillGraphicBufferColor(const sp<GraphicBuffer>& buffer, const Rect& rect, const Color& color) {
103 Rect r(0, 0, buffer->width, buffer->height);
104 if (!r.intersect(rect, &r)) {
105 return;
106 }
107
108 int32_t width = r.right - r.left;
109 int32_t height = r.bottom - r.top;
110
111 uint8_t* pixels;
112 buffer->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
113 reinterpret_cast<void**>(&pixels));
114
115 for (int32_t row = 0; row < height; row++) {
116 uint8_t* dst = pixels + (buffer->getStride() * (r.top + row) + r.left) * 4;
117 for (int32_t column = 0; column < width; column++) {
118 dst[0] = color.r;
119 dst[1] = color.g;
120 dst[2] = color.b;
121 dst[3] = color.a;
122 dst += 4;
123 }
124 }
125 buffer->unlock();
126}
127
Chia-I Wu718daf82017-10-20 11:57:17 -0700128// Check if a region has the specified color.
Chavi Weingarten40482ff2017-11-30 01:51:40 +0000129void expectBufferColor(const sp<GraphicBuffer>& outBuffer, uint8_t* pixels, const Rect& rect,
Chia-I Wu718daf82017-10-20 11:57:17 -0700130 const Color& color, uint8_t tolerance) {
131 int32_t x = rect.left;
132 int32_t y = rect.top;
133 int32_t width = rect.right - rect.left;
134 int32_t height = rect.bottom - rect.top;
135
Chavi Weingarten40482ff2017-11-30 01:51:40 +0000136 int32_t bufferWidth = int32_t(outBuffer->getWidth());
137 int32_t bufferHeight = int32_t(outBuffer->getHeight());
138 if (x + width > bufferWidth) {
139 x = std::min(x, bufferWidth);
140 width = bufferWidth - x;
Chia-I Wu718daf82017-10-20 11:57:17 -0700141 }
Chavi Weingarten40482ff2017-11-30 01:51:40 +0000142 if (y + height > bufferHeight) {
143 y = std::min(y, bufferHeight);
144 height = bufferHeight - y;
Chia-I Wu718daf82017-10-20 11:57:17 -0700145 }
146
147 auto colorCompare = [tolerance](uint8_t a, uint8_t b) {
148 uint8_t tmp = a >= b ? a - b : b - a;
149 return tmp <= tolerance;
150 };
151 for (int32_t j = 0; j < height; j++) {
Chavi Weingarten40482ff2017-11-30 01:51:40 +0000152 const uint8_t* src = pixels + (outBuffer->getStride() * (y + j) + x) * 4;
Chia-I Wu718daf82017-10-20 11:57:17 -0700153 for (int32_t i = 0; i < width; i++) {
154 const uint8_t expected[4] = {color.r, color.g, color.b, color.a};
155 EXPECT_TRUE(std::equal(src, src + 4, expected, colorCompare))
156 << "pixel @ (" << x + i << ", " << y + j << "): "
157 << "expected (" << color << "), "
158 << "got (" << Color{src[0], src[1], src[2], src[3]} << ")";
159 src += 4;
160 }
161 }
162}
163
164} // anonymous namespace
165
Robert Carr4cdc58f2017-08-23 14:22:20 -0700166using Transaction = SurfaceComposerClient::Transaction;
167
Jamie Gennis23c2c5d2011-10-11 19:22:19 -0700168// Fill an RGBA_8888 formatted surface with a single color.
Chia-I Wu1078bbb2017-10-20 11:29:02 -0700169static void fillSurfaceRGBA8(const sp<SurfaceControl>& sc, uint8_t r, uint8_t g, uint8_t b,
170 bool unlock = true) {
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800171 ANativeWindow_Buffer outBuffer;
Jamie Gennis23c2c5d2011-10-11 19:22:19 -0700172 sp<Surface> s = sc->getSurface();
Peiyong Lin566a3b42018-01-09 18:22:43 -0800173 ASSERT_TRUE(s != nullptr);
174 ASSERT_EQ(NO_ERROR, s->lock(&outBuffer, nullptr));
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800175 uint8_t* img = reinterpret_cast<uint8_t*>(outBuffer.bits);
Pablo Ceballos5e4fcbe2015-09-02 09:53:16 -0700176 for (int y = 0; y < outBuffer.height; y++) {
177 for (int x = 0; x < outBuffer.width; x++) {
Chia-I Wu1078bbb2017-10-20 11:29:02 -0700178 uint8_t* pixel = img + (4 * (y * outBuffer.stride + x));
Jamie Gennis23c2c5d2011-10-11 19:22:19 -0700179 pixel[0] = r;
180 pixel[1] = g;
181 pixel[2] = b;
182 pixel[3] = 255;
183 }
184 }
Robert Carr7bf247e2017-05-18 14:02:49 -0700185 if (unlock) {
186 ASSERT_EQ(NO_ERROR, s->unlockAndPost());
187 }
Jamie Gennis23c2c5d2011-10-11 19:22:19 -0700188}
189
190// A ScreenCapture is a screenshot from SurfaceFlinger that can be used to check
191// individual pixel values for testing purposes.
192class ScreenCapture : public RefBase {
193public:
chaviw0e3479f2018-09-10 16:49:30 -0700194 static void captureScreen(std::unique_ptr<ScreenCapture>* sc) {
Jamie Gennis23c2c5d2011-10-11 19:22:19 -0700195 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
Chia-I Wu1078bbb2017-10-20 11:29:02 -0700196 sp<IBinder> display(sf->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
Robert Carr4cdc58f2017-08-23 14:22:20 -0700197 SurfaceComposerClient::Transaction().apply(true);
198
Chavi Weingarten40482ff2017-11-30 01:51:40 +0000199 sp<GraphicBuffer> outBuffer;
Chia-I Wu718daf82017-10-20 11:57:17 -0700200 ASSERT_EQ(NO_ERROR,
chaviw0e3479f2018-09-10 16:49:30 -0700201 sf->captureScreen(display, &outBuffer, Rect(), 0, 0, false));
202 *sc = std::make_unique<ScreenCapture>(outBuffer);
Chavi Weingarten40482ff2017-11-30 01:51:40 +0000203 }
204
205 static void captureLayers(std::unique_ptr<ScreenCapture>* sc, sp<IBinder>& parentHandle,
206 Rect crop = Rect::EMPTY_RECT, float frameScale = 1.0) {
207 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
208 SurfaceComposerClient::Transaction().apply(true);
209
210 sp<GraphicBuffer> outBuffer;
211 ASSERT_EQ(NO_ERROR, sf->captureLayers(parentHandle, &outBuffer, crop, frameScale));
212 *sc = std::make_unique<ScreenCapture>(outBuffer);
Jamie Gennis23c2c5d2011-10-11 19:22:19 -0700213 }
214
Robert Carr578038f2018-03-09 12:25:24 -0800215 static void captureChildLayers(std::unique_ptr<ScreenCapture>* sc, sp<IBinder>& parentHandle,
216 Rect crop = Rect::EMPTY_RECT, float frameScale = 1.0) {
217 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
218 SurfaceComposerClient::Transaction().apply(true);
219
220 sp<GraphicBuffer> outBuffer;
221 ASSERT_EQ(NO_ERROR, sf->captureLayers(parentHandle, &outBuffer, crop, frameScale, true));
222 *sc = std::make_unique<ScreenCapture>(outBuffer);
223 }
224
Chia-I Wu718daf82017-10-20 11:57:17 -0700225 void expectColor(const Rect& rect, const Color& color, uint8_t tolerance = 0) {
Chavi Weingarten40482ff2017-11-30 01:51:40 +0000226 ASSERT_EQ(HAL_PIXEL_FORMAT_RGBA_8888, mOutBuffer->getPixelFormat());
227 expectBufferColor(mOutBuffer, mPixels, rect, color, tolerance);
Chia-I Wu718daf82017-10-20 11:57:17 -0700228 }
229
230 void expectBorder(const Rect& rect, const Color& color, uint8_t tolerance = 0) {
Chavi Weingarten40482ff2017-11-30 01:51:40 +0000231 ASSERT_EQ(HAL_PIXEL_FORMAT_RGBA_8888, mOutBuffer->getPixelFormat());
Chia-I Wu718daf82017-10-20 11:57:17 -0700232 const bool leftBorder = rect.left > 0;
233 const bool topBorder = rect.top > 0;
Chavi Weingarten40482ff2017-11-30 01:51:40 +0000234 const bool rightBorder = rect.right < int32_t(mOutBuffer->getWidth());
235 const bool bottomBorder = rect.bottom < int32_t(mOutBuffer->getHeight());
Chia-I Wu718daf82017-10-20 11:57:17 -0700236
237 if (topBorder) {
238 Rect top(rect.left, rect.top - 1, rect.right, rect.top);
239 if (leftBorder) {
240 top.left -= 1;
241 }
242 if (rightBorder) {
243 top.right += 1;
244 }
245 expectColor(top, color, tolerance);
246 }
247 if (leftBorder) {
248 Rect left(rect.left - 1, rect.top, rect.left, rect.bottom);
249 expectColor(left, color, tolerance);
250 }
251 if (rightBorder) {
252 Rect right(rect.right, rect.top, rect.right + 1, rect.bottom);
253 expectColor(right, color, tolerance);
254 }
255 if (bottomBorder) {
256 Rect bottom(rect.left, rect.bottom, rect.right, rect.bottom + 1);
257 if (leftBorder) {
258 bottom.left -= 1;
259 }
260 if (rightBorder) {
261 bottom.right += 1;
262 }
263 expectColor(bottom, color, tolerance);
264 }
265 }
266
Chia-I Wu93853fe2017-11-02 08:30:27 -0700267 void expectQuadrant(const Rect& rect, const Color& topLeft, const Color& topRight,
268 const Color& bottomLeft, const Color& bottomRight, bool filtered = false,
269 uint8_t tolerance = 0) {
270 ASSERT_TRUE((rect.right - rect.left) % 2 == 0 && (rect.bottom - rect.top) % 2 == 0);
271
272 const int32_t centerX = rect.left + (rect.right - rect.left) / 2;
273 const int32_t centerY = rect.top + (rect.bottom - rect.top) / 2;
274 // avoid checking borders due to unspecified filtering behavior
275 const int32_t offsetX = filtered ? 2 : 0;
276 const int32_t offsetY = filtered ? 2 : 0;
277 expectColor(Rect(rect.left, rect.top, centerX - offsetX, centerY - offsetY), topLeft,
278 tolerance);
279 expectColor(Rect(centerX + offsetX, rect.top, rect.right, centerY - offsetY), topRight,
280 tolerance);
281 expectColor(Rect(rect.left, centerY + offsetY, centerX - offsetX, rect.bottom), bottomLeft,
282 tolerance);
283 expectColor(Rect(centerX + offsetX, centerY + offsetY, rect.right, rect.bottom),
284 bottomRight, tolerance);
285 }
286
Jamie Gennis23c2c5d2011-10-11 19:22:19 -0700287 void checkPixel(uint32_t x, uint32_t y, uint8_t r, uint8_t g, uint8_t b) {
Chavi Weingarten40482ff2017-11-30 01:51:40 +0000288 ASSERT_EQ(HAL_PIXEL_FORMAT_RGBA_8888, mOutBuffer->getPixelFormat());
289 const uint8_t* pixel = mPixels + (4 * (y * mOutBuffer->getStride() + x));
Jamie Gennis23c2c5d2011-10-11 19:22:19 -0700290 if (r != pixel[0] || g != pixel[1] || b != pixel[2]) {
291 String8 err(String8::format("pixel @ (%3d, %3d): "
Chia-I Wu1078bbb2017-10-20 11:29:02 -0700292 "expected [%3d, %3d, %3d], got [%3d, %3d, %3d]",
293 x, y, r, g, b, pixel[0], pixel[1], pixel[2]));
Pablo Ceballos5e4fcbe2015-09-02 09:53:16 -0700294 EXPECT_EQ(String8(), err) << err.string();
Jamie Gennis23c2c5d2011-10-11 19:22:19 -0700295 }
296 }
297
Chia-I Wu1078bbb2017-10-20 11:29:02 -0700298 void expectFGColor(uint32_t x, uint32_t y) { checkPixel(x, y, 195, 63, 63); }
Robert Carr1f0a16a2016-10-24 16:27:39 -0700299
Chia-I Wu1078bbb2017-10-20 11:29:02 -0700300 void expectBGColor(uint32_t x, uint32_t y) { checkPixel(x, y, 63, 63, 195); }
Robert Carr1f0a16a2016-10-24 16:27:39 -0700301
Chia-I Wu1078bbb2017-10-20 11:29:02 -0700302 void expectChildColor(uint32_t x, uint32_t y) { checkPixel(x, y, 200, 200, 200); }
Robert Carr1f0a16a2016-10-24 16:27:39 -0700303
Chavi Weingarten40482ff2017-11-30 01:51:40 +0000304 ScreenCapture(const sp<GraphicBuffer>& outBuffer) : mOutBuffer(outBuffer) {
305 mOutBuffer->lock(GRALLOC_USAGE_SW_READ_OFTEN, reinterpret_cast<void**>(&mPixels));
Michael Lentine5a16a622015-05-21 13:48:24 -0700306 }
Jamie Gennis23c2c5d2011-10-11 19:22:19 -0700307
Chavi Weingarten40482ff2017-11-30 01:51:40 +0000308 ~ScreenCapture() { mOutBuffer->unlock(); }
chaviwa76b2712017-09-20 12:02:26 -0700309
310private:
Chavi Weingarten40482ff2017-11-30 01:51:40 +0000311 sp<GraphicBuffer> mOutBuffer;
Peiyong Lin566a3b42018-01-09 18:22:43 -0800312 uint8_t* mPixels = nullptr;
chaviwa76b2712017-09-20 12:02:26 -0700313};
314
Chia-I Wu718daf82017-10-20 11:57:17 -0700315class LayerTransactionTest : public ::testing::Test {
316protected:
317 void SetUp() override {
318 mClient = new SurfaceComposerClient;
319 ASSERT_EQ(NO_ERROR, mClient->initCheck()) << "failed to create SurfaceComposerClient";
320
321 ASSERT_NO_FATAL_FAILURE(SetUpDisplay());
Ady Abraham2a6ab2a2018-10-26 14:25:30 -0700322
323 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
324 sp<IBinder> binder = sf->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain);
Ady Abraham37965d42018-11-01 13:43:32 -0700325 ASSERT_NO_FATAL_FAILURE(sf->getColorManagement(&mColorManagementUsed));
Chia-I Wu718daf82017-10-20 11:57:17 -0700326 }
327
chaviw0e3479f2018-09-10 16:49:30 -0700328 virtual void TearDown() {
329 mBlackBgSurface = 0;
330 mClient->dispose();
331 mClient = 0;
332 }
333
Marissa Wallfda30bb2018-10-12 11:34:28 -0700334 virtual sp<SurfaceControl> createLayer(const sp<SurfaceComposerClient>& client,
335 const char* name, uint32_t width, uint32_t height,
chaviwf66724d2018-11-28 16:35:21 -0800336 uint32_t flags = 0, SurfaceControl* parent = nullptr) {
337 auto layer =
338 createSurface(client, name, width, height, PIXEL_FORMAT_RGBA_8888, flags, parent);
Chia-I Wu718daf82017-10-20 11:57:17 -0700339
Vishnu Nair60356342018-11-13 13:00:45 -0800340 Transaction t;
341 t.setLayerStack(layer, mDisplayLayerStack).setLayer(layer, mLayerZBase);
Vishnu Nair60356342018-11-13 13:00:45 -0800342
343 status_t error = t.apply();
Chia-I Wu718daf82017-10-20 11:57:17 -0700344 if (error != NO_ERROR) {
345 ADD_FAILURE() << "failed to initialize SurfaceControl";
346 layer.clear();
347 }
348
349 return layer;
350 }
351
Vishnu Nair88a11f22018-11-28 18:30:57 -0800352 virtual sp<SurfaceControl> createSurface(const sp<SurfaceComposerClient>& client,
353 const char* name, uint32_t width, uint32_t height,
354 PixelFormat format, uint32_t flags,
355 SurfaceControl* parent = nullptr) {
356 auto layer = client->createSurface(String8(name), width, height, format, flags, parent);
357 EXPECT_NE(nullptr, layer.get()) << "failed to create SurfaceControl";
358 return layer;
359 }
360
Marissa Wallfda30bb2018-10-12 11:34:28 -0700361 virtual sp<SurfaceControl> createLayer(const char* name, uint32_t width, uint32_t height,
chaviwf66724d2018-11-28 16:35:21 -0800362 uint32_t flags = 0, SurfaceControl* parent = nullptr) {
363 return createLayer(mClient, name, width, height, flags, parent);
Marissa Wallfda30bb2018-10-12 11:34:28 -0700364 }
365
Marissa Wall61c58622018-07-18 10:12:20 -0700366 ANativeWindow_Buffer getBufferQueueLayerBuffer(const sp<SurfaceControl>& layer) {
Chia-I Wu718daf82017-10-20 11:57:17 -0700367 // wait for previous transactions (such as setSize) to complete
368 Transaction().apply(true);
369
370 ANativeWindow_Buffer buffer = {};
371 EXPECT_EQ(NO_ERROR, layer->getSurface()->lock(&buffer, nullptr));
372
373 return buffer;
374 }
375
Marissa Wall61c58622018-07-18 10:12:20 -0700376 void postBufferQueueLayerBuffer(const sp<SurfaceControl>& layer) {
Chia-I Wu718daf82017-10-20 11:57:17 -0700377 ASSERT_EQ(NO_ERROR, layer->getSurface()->unlockAndPost());
378
379 // wait for the newly posted buffer to be latched
380 waitForLayerBuffers();
381 }
382
Marissa Wall61c58622018-07-18 10:12:20 -0700383 virtual void fillBufferQueueLayerColor(const sp<SurfaceControl>& layer, const Color& color,
384 int32_t bufferWidth, int32_t bufferHeight) {
Chia-I Wu718daf82017-10-20 11:57:17 -0700385 ANativeWindow_Buffer buffer;
Marissa Wall61c58622018-07-18 10:12:20 -0700386 ASSERT_NO_FATAL_FAILURE(buffer = getBufferQueueLayerBuffer(layer));
387 fillANativeWindowBufferColor(buffer, Rect(0, 0, bufferWidth, bufferHeight), color);
388 postBufferQueueLayerBuffer(layer);
Chia-I Wu718daf82017-10-20 11:57:17 -0700389 }
390
Marissa Wall61c58622018-07-18 10:12:20 -0700391 virtual void fillBufferStateLayerColor(const sp<SurfaceControl>& layer, const Color& color,
392 int32_t bufferWidth, int32_t bufferHeight) {
393 sp<GraphicBuffer> buffer =
394 new GraphicBuffer(bufferWidth, bufferHeight, PIXEL_FORMAT_RGBA_8888, 1,
395 BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
396 BufferUsage::COMPOSER_OVERLAY,
397 "test");
398 fillGraphicBufferColor(buffer, Rect(0, 0, bufferWidth, bufferHeight), color);
399 Transaction().setBuffer(layer, buffer).setSize(layer, bufferWidth, bufferHeight).apply();
400 }
401
402 void fillLayerColor(uint32_t mLayerType, const sp<SurfaceControl>& layer, const Color& color,
403 int32_t bufferWidth, int32_t bufferHeight) {
404 switch (mLayerType) {
405 case ISurfaceComposerClient::eFXSurfaceBufferQueue:
406 fillBufferQueueLayerColor(layer, color, bufferWidth, bufferHeight);
407 break;
408 case ISurfaceComposerClient::eFXSurfaceBufferState:
409 fillBufferStateLayerColor(layer, color, bufferWidth, bufferHeight);
410 break;
411 default:
412 ASSERT_TRUE(false) << "unsupported layer type: " << mLayerType;
413 }
414 }
415
416 void fillLayerQuadrant(uint32_t mLayerType, const sp<SurfaceControl>& layer,
417 int32_t bufferWidth, int32_t bufferHeight, const Color& topLeft,
Chia-I Wu93853fe2017-11-02 08:30:27 -0700418 const Color& topRight, const Color& bottomLeft,
419 const Color& bottomRight) {
Marissa Wall61c58622018-07-18 10:12:20 -0700420 switch (mLayerType) {
421 case ISurfaceComposerClient::eFXSurfaceBufferQueue:
422 fillBufferQueueLayerQuadrant(layer, bufferWidth, bufferHeight, topLeft, topRight,
423 bottomLeft, bottomRight);
424 break;
425 case ISurfaceComposerClient::eFXSurfaceBufferState:
426 fillBufferStateLayerQuadrant(layer, bufferWidth, bufferHeight, topLeft, topRight,
427 bottomLeft, bottomRight);
428 break;
429 default:
430 ASSERT_TRUE(false) << "unsupported layer type: " << mLayerType;
431 }
432 }
433
434 virtual void fillBufferQueueLayerQuadrant(const sp<SurfaceControl>& layer, int32_t bufferWidth,
435 int32_t bufferHeight, const Color& topLeft,
436 const Color& topRight, const Color& bottomLeft,
437 const Color& bottomRight) {
Chia-I Wu93853fe2017-11-02 08:30:27 -0700438 ANativeWindow_Buffer buffer;
Marissa Wall61c58622018-07-18 10:12:20 -0700439 ASSERT_NO_FATAL_FAILURE(buffer = getBufferQueueLayerBuffer(layer));
440 ASSERT_TRUE(bufferWidth % 2 == 0 && bufferHeight % 2 == 0);
Chia-I Wu93853fe2017-11-02 08:30:27 -0700441
Marissa Wall61c58622018-07-18 10:12:20 -0700442 const int32_t halfW = bufferWidth / 2;
443 const int32_t halfH = bufferHeight / 2;
444 fillANativeWindowBufferColor(buffer, Rect(0, 0, halfW, halfH), topLeft);
445 fillANativeWindowBufferColor(buffer, Rect(halfW, 0, bufferWidth, halfH), topRight);
446 fillANativeWindowBufferColor(buffer, Rect(0, halfH, halfW, bufferHeight), bottomLeft);
447 fillANativeWindowBufferColor(buffer, Rect(halfW, halfH, bufferWidth, bufferHeight),
448 bottomRight);
Chia-I Wu93853fe2017-11-02 08:30:27 -0700449
Marissa Wall61c58622018-07-18 10:12:20 -0700450 postBufferQueueLayerBuffer(layer);
451 }
452
453 virtual void fillBufferStateLayerQuadrant(const sp<SurfaceControl>& layer, int32_t bufferWidth,
454 int32_t bufferHeight, const Color& topLeft,
455 const Color& topRight, const Color& bottomLeft,
456 const Color& bottomRight) {
457 sp<GraphicBuffer> buffer =
458 new GraphicBuffer(bufferWidth, bufferHeight, PIXEL_FORMAT_RGBA_8888, 1,
459 BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
460 BufferUsage::COMPOSER_OVERLAY,
461 "test");
462
463 ASSERT_TRUE(bufferWidth % 2 == 0 && bufferHeight % 2 == 0);
464
465 const int32_t halfW = bufferWidth / 2;
466 const int32_t halfH = bufferHeight / 2;
467 fillGraphicBufferColor(buffer, Rect(0, 0, halfW, halfH), topLeft);
468 fillGraphicBufferColor(buffer, Rect(halfW, 0, bufferWidth, halfH), topRight);
469 fillGraphicBufferColor(buffer, Rect(0, halfH, halfW, bufferHeight), bottomLeft);
470 fillGraphicBufferColor(buffer, Rect(halfW, halfH, bufferWidth, bufferHeight), bottomRight);
471
472 Transaction().setBuffer(layer, buffer).setSize(layer, bufferWidth, bufferHeight).apply();
Chia-I Wu93853fe2017-11-02 08:30:27 -0700473 }
474
chaviw0e3479f2018-09-10 16:49:30 -0700475 std::unique_ptr<ScreenCapture> screenshot() {
476 std::unique_ptr<ScreenCapture> screenshot;
477 ScreenCapture::captureScreen(&screenshot);
Chia-I Wu718daf82017-10-20 11:57:17 -0700478 return screenshot;
479 }
480
481 sp<SurfaceComposerClient> mClient;
482
483 sp<IBinder> mDisplay;
484 uint32_t mDisplayWidth;
485 uint32_t mDisplayHeight;
486 uint32_t mDisplayLayerStack;
487
488 // leave room for ~256 layers
489 const int32_t mLayerZBase = std::numeric_limits<int32_t>::max() - 256;
490
Marissa Wall61c58622018-07-18 10:12:20 -0700491 void setPositionWithResizeHelper(uint32_t layerType);
492 void setSizeBasicHelper(uint32_t layerType);
493 void setMatrixWithResizeHelper(uint32_t layerType);
494
chaviw0e3479f2018-09-10 16:49:30 -0700495 sp<SurfaceControl> mBlackBgSurface;
Ady Abraham2a6ab2a2018-10-26 14:25:30 -0700496 bool mColorManagementUsed;
497
Chia-I Wu718daf82017-10-20 11:57:17 -0700498private:
499 void SetUpDisplay() {
500 mDisplay = mClient->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain);
501 ASSERT_NE(nullptr, mDisplay.get()) << "failed to get built-in display";
502
503 // get display width/height
504 DisplayInfo info;
505 SurfaceComposerClient::getDisplayInfo(mDisplay, &info);
506 mDisplayWidth = info.w;
507 mDisplayHeight = info.h;
508
509 // After a new buffer is queued, SurfaceFlinger is notified and will
510 // latch the new buffer on next vsync. Let's heuristically wait for 3
511 // vsyncs.
512 mBufferPostDelay = int32_t(1e6 / info.fps) * 3;
513
514 mDisplayLayerStack = 0;
chaviw0e3479f2018-09-10 16:49:30 -0700515
Vishnu Nair88a11f22018-11-28 18:30:57 -0800516 mBlackBgSurface =
517 createSurface(mClient, "BaseSurface", 0 /* buffer width */, 0 /* buffer height */,
518 PIXEL_FORMAT_RGBA_8888, ISurfaceComposerClient::eFXSurfaceColor);
chaviw0e3479f2018-09-10 16:49:30 -0700519
Chia-I Wu718daf82017-10-20 11:57:17 -0700520 // set layer stack (b/68888219)
521 Transaction t;
522 t.setDisplayLayerStack(mDisplay, mDisplayLayerStack);
Vishnu Nair60356342018-11-13 13:00:45 -0800523 t.setCrop_legacy(mBlackBgSurface, Rect(0, 0, mDisplayWidth, mDisplayHeight));
chaviw0e3479f2018-09-10 16:49:30 -0700524 t.setLayerStack(mBlackBgSurface, mDisplayLayerStack);
525 t.setColor(mBlackBgSurface, half3{0, 0, 0});
526 t.setLayer(mBlackBgSurface, mLayerZBase);
Chia-I Wu718daf82017-10-20 11:57:17 -0700527 t.apply();
528 }
529
chaviw0e3479f2018-09-10 16:49:30 -0700530 void waitForLayerBuffers() {
531 // Request an empty transaction to get applied synchronously to ensure the buffer is
532 // latched.
533 Transaction().apply(true);
534 usleep(mBufferPostDelay);
535 }
Chia-I Wu718daf82017-10-20 11:57:17 -0700536
537 int32_t mBufferPostDelay;
538};
539
Marissa Wall61c58622018-07-18 10:12:20 -0700540class LayerTypeTransactionTest : public LayerTransactionTest,
541 public ::testing::WithParamInterface<uint32_t> {
542public:
543 LayerTypeTransactionTest() { mLayerType = GetParam(); }
544
545 sp<SurfaceControl> createLayer(const char* name, uint32_t width, uint32_t height,
chaviwf66724d2018-11-28 16:35:21 -0800546 uint32_t flags = 0, SurfaceControl* parent = nullptr) override {
Marissa Wall61c58622018-07-18 10:12:20 -0700547 // if the flags already have a layer type specified, return an error
548 if (flags & ISurfaceComposerClient::eFXSurfaceMask) {
549 return nullptr;
550 }
chaviwf66724d2018-11-28 16:35:21 -0800551 return LayerTransactionTest::createLayer(name, width, height, flags | mLayerType, parent);
Marissa Wall61c58622018-07-18 10:12:20 -0700552 }
553
554 void fillLayerColor(const sp<SurfaceControl>& layer, const Color& color, int32_t bufferWidth,
555 int32_t bufferHeight) {
556 ASSERT_NO_FATAL_FAILURE(LayerTransactionTest::fillLayerColor(mLayerType, layer, color,
557 bufferWidth, bufferHeight));
558 }
559
560 void fillLayerQuadrant(const sp<SurfaceControl>& layer, int32_t bufferWidth,
561 int32_t bufferHeight, const Color& topLeft, const Color& topRight,
562 const Color& bottomLeft, const Color& bottomRight) {
563 ASSERT_NO_FATAL_FAILURE(LayerTransactionTest::fillLayerQuadrant(mLayerType, layer,
564 bufferWidth, bufferHeight,
565 topLeft, topRight,
566 bottomLeft, bottomRight));
567 }
568
569protected:
570 uint32_t mLayerType;
571};
572
573INSTANTIATE_TEST_CASE_P(
574 LayerTypeTransactionTests, LayerTypeTransactionTest,
575 ::testing::Values(static_cast<uint32_t>(ISurfaceComposerClient::eFXSurfaceBufferQueue),
576 static_cast<uint32_t>(ISurfaceComposerClient::eFXSurfaceBufferState)));
577
578TEST_P(LayerTypeTransactionTest, SetPositionBasic) {
Chia-I Wu718daf82017-10-20 11:57:17 -0700579 sp<SurfaceControl> layer;
580 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -0700581 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED, 32, 32));
Chia-I Wu718daf82017-10-20 11:57:17 -0700582
583 {
584 SCOPED_TRACE("default position");
585 auto shot = screenshot();
586 shot->expectColor(Rect(0, 0, 32, 32), Color::RED);
587 shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
588 }
589
590 Transaction().setPosition(layer, 5, 10).apply();
591 {
592 SCOPED_TRACE("new position");
593 auto shot = screenshot();
594 shot->expectColor(Rect(5, 10, 37, 42), Color::RED);
595 shot->expectBorder(Rect(5, 10, 37, 42), Color::BLACK);
596 }
597}
598
Marissa Wall61c58622018-07-18 10:12:20 -0700599TEST_P(LayerTypeTransactionTest, SetPositionRounding) {
Chia-I Wu718daf82017-10-20 11:57:17 -0700600 sp<SurfaceControl> layer;
601 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -0700602 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED, 32, 32));
Chia-I Wu718daf82017-10-20 11:57:17 -0700603
604 // GLES requires only 4 bits of subpixel precision during rasterization
605 // XXX GLES composition does not match HWC composition due to precision
606 // loss (b/69315223)
607 const float epsilon = 1.0f / 16.0f;
608 Transaction().setPosition(layer, 0.5f - epsilon, 0.5f - epsilon).apply();
609 {
610 SCOPED_TRACE("rounding down");
611 screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
612 }
613
614 Transaction().setPosition(layer, 0.5f + epsilon, 0.5f + epsilon).apply();
615 {
616 SCOPED_TRACE("rounding up");
617 screenshot()->expectColor(Rect(1, 1, 33, 33), Color::RED);
618 }
619}
620
Marissa Wall61c58622018-07-18 10:12:20 -0700621TEST_P(LayerTypeTransactionTest, SetPositionOutOfBounds) {
Chia-I Wu718daf82017-10-20 11:57:17 -0700622 sp<SurfaceControl> layer;
623 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -0700624 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED, 32, 32));
Chia-I Wu718daf82017-10-20 11:57:17 -0700625
626 Transaction().setPosition(layer, -32, -32).apply();
627 {
628 SCOPED_TRACE("negative coordinates");
629 screenshot()->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK);
630 }
631
632 Transaction().setPosition(layer, mDisplayWidth, mDisplayHeight).apply();
633 {
634 SCOPED_TRACE("positive coordinates");
635 screenshot()->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK);
636 }
637}
638
Marissa Wall61c58622018-07-18 10:12:20 -0700639TEST_P(LayerTypeTransactionTest, SetPositionPartiallyOutOfBounds) {
Chia-I Wu718daf82017-10-20 11:57:17 -0700640 sp<SurfaceControl> layer;
641 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -0700642 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED, 32, 32));
Chia-I Wu718daf82017-10-20 11:57:17 -0700643
644 // partially out of bounds
645 Transaction().setPosition(layer, -30, -30).apply();
646 {
647 SCOPED_TRACE("negative coordinates");
648 screenshot()->expectColor(Rect(0, 0, 2, 2), Color::RED);
649 }
650
651 Transaction().setPosition(layer, mDisplayWidth - 2, mDisplayHeight - 2).apply();
652 {
653 SCOPED_TRACE("positive coordinates");
654 screenshot()->expectColor(Rect(mDisplayWidth - 2, mDisplayHeight - 2, mDisplayWidth,
655 mDisplayHeight),
656 Color::RED);
657 }
658}
659
Marissa Wall61c58622018-07-18 10:12:20 -0700660void LayerTransactionTest::setPositionWithResizeHelper(uint32_t layerType) {
Chia-I Wu718daf82017-10-20 11:57:17 -0700661 sp<SurfaceControl> layer;
Marissa Wall61c58622018-07-18 10:12:20 -0700662 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32, layerType));
663 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerType, layer, Color::RED, 32, 32));
Chia-I Wu718daf82017-10-20 11:57:17 -0700664
665 // setPosition is applied immediately by default, with or without resize
666 // pending
667 Transaction().setPosition(layer, 5, 10).setSize(layer, 64, 64).apply();
668 {
669 SCOPED_TRACE("resize pending");
670 auto shot = screenshot();
Marissa Wall61c58622018-07-18 10:12:20 -0700671 Rect rect;
672 switch (layerType) {
673 case ISurfaceComposerClient::eFXSurfaceBufferQueue:
674 rect = {5, 10, 37, 42};
675 break;
676 case ISurfaceComposerClient::eFXSurfaceBufferState:
677 rect = {5, 10, 69, 74};
678 break;
679 default:
680 ASSERT_FALSE(true) << "Unsupported layer type";
681 }
682
683 shot->expectColor(rect, Color::RED);
684 shot->expectBorder(rect, Color::BLACK);
Chia-I Wu718daf82017-10-20 11:57:17 -0700685 }
686
Marissa Wall61c58622018-07-18 10:12:20 -0700687 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerType, layer, Color::RED, 64, 64));
Chia-I Wu718daf82017-10-20 11:57:17 -0700688 {
689 SCOPED_TRACE("resize applied");
690 screenshot()->expectColor(Rect(5, 10, 69, 74), Color::RED);
691 }
692}
693
Marissa Wall61c58622018-07-18 10:12:20 -0700694TEST_F(LayerTransactionTest, SetPositionWithResize_BufferQueue) {
695 ASSERT_NO_FATAL_FAILURE(
696 setPositionWithResizeHelper(ISurfaceComposerClient::eFXSurfaceBufferQueue));
697}
698
699TEST_F(LayerTransactionTest, SetPositionWithResize_BufferState) {
700 ASSERT_NO_FATAL_FAILURE(
701 setPositionWithResizeHelper(ISurfaceComposerClient::eFXSurfaceBufferState));
702}
703
704TEST_F(LayerTransactionTest, SetPositionWithNextResize_BufferQueue) {
Chia-I Wu718daf82017-10-20 11:57:17 -0700705 sp<SurfaceControl> layer;
706 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -0700707 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32));
Chia-I Wu718daf82017-10-20 11:57:17 -0700708
709 // request setPosition to be applied with the next resize
710 Transaction().setPosition(layer, 5, 10).setGeometryAppliesWithResize(layer).apply();
711 {
712 SCOPED_TRACE("new position pending");
713 screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
714 }
715
716 Transaction().setPosition(layer, 15, 20).apply();
717 {
718 SCOPED_TRACE("pending new position modified");
719 screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
720 }
721
722 Transaction().setSize(layer, 64, 64).apply();
723 {
724 SCOPED_TRACE("resize pending");
725 screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
726 }
727
728 // finally resize and latch the buffer
Marissa Wall61c58622018-07-18 10:12:20 -0700729 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 64, 64));
Chia-I Wu718daf82017-10-20 11:57:17 -0700730 {
731 SCOPED_TRACE("new position applied");
732 screenshot()->expectColor(Rect(15, 20, 79, 84), Color::RED);
733 }
734}
735
Marissa Wall61c58622018-07-18 10:12:20 -0700736TEST_F(LayerTransactionTest, SetPositionWithNextResizeScaleToWindow_BufferQueue) {
Chia-I Wu718daf82017-10-20 11:57:17 -0700737 sp<SurfaceControl> layer;
738 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -0700739 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32));
Chia-I Wu718daf82017-10-20 11:57:17 -0700740
741 // setPosition is not immediate even with SCALE_TO_WINDOW override
742 Transaction()
743 .setPosition(layer, 5, 10)
744 .setSize(layer, 64, 64)
745 .setOverrideScalingMode(layer, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW)
746 .setGeometryAppliesWithResize(layer)
747 .apply();
748 {
749 SCOPED_TRACE("new position pending");
750 screenshot()->expectColor(Rect(0, 0, 64, 64), Color::RED);
751 }
752
Marissa Wall61c58622018-07-18 10:12:20 -0700753 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 64, 64));
Chia-I Wu718daf82017-10-20 11:57:17 -0700754 {
755 SCOPED_TRACE("new position applied");
756 screenshot()->expectColor(Rect(5, 10, 69, 74), Color::RED);
757 }
758}
759
Marissa Wall61c58622018-07-18 10:12:20 -0700760void LayerTransactionTest::setSizeBasicHelper(uint32_t layerType) {
Chia-I Wu0eaea312017-10-31 10:14:40 -0700761 sp<SurfaceControl> layer;
Marissa Wall61c58622018-07-18 10:12:20 -0700762 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32, layerType));
763 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerType, layer, Color::RED, 32, 32));
Chia-I Wu0eaea312017-10-31 10:14:40 -0700764
765 Transaction().setSize(layer, 64, 64).apply();
766 {
767 SCOPED_TRACE("resize pending");
768 auto shot = screenshot();
Marissa Wall61c58622018-07-18 10:12:20 -0700769 Rect rect;
770 switch (layerType) {
771 case ISurfaceComposerClient::eFXSurfaceBufferQueue:
772 rect = {0, 0, 32, 32};
773 break;
774 case ISurfaceComposerClient::eFXSurfaceBufferState:
775 rect = {0, 0, 64, 64};
776 break;
777 default:
778 ASSERT_FALSE(true) << "Unsupported layer type";
779 }
780 shot->expectColor(rect, Color::RED);
781 shot->expectBorder(rect, Color::BLACK);
Chia-I Wu0eaea312017-10-31 10:14:40 -0700782 }
783
Marissa Wall61c58622018-07-18 10:12:20 -0700784 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerType, layer, Color::RED, 64, 64));
Chia-I Wu0eaea312017-10-31 10:14:40 -0700785 {
786 SCOPED_TRACE("resize applied");
787 auto shot = screenshot();
788 shot->expectColor(Rect(0, 0, 64, 64), Color::RED);
789 shot->expectBorder(Rect(0, 0, 64, 64), Color::BLACK);
790 }
791}
792
Marissa Wall61c58622018-07-18 10:12:20 -0700793TEST_F(LayerTransactionTest, SetSizeBasic_BufferQueue) {
794 setSizeBasicHelper(ISurfaceComposerClient::eFXSurfaceBufferQueue);
795}
796
797TEST_F(LayerTransactionTest, SetSizeBasic_BufferState) {
798 setSizeBasicHelper(ISurfaceComposerClient::eFXSurfaceBufferState);
799}
800
801TEST_P(LayerTypeTransactionTest, SetSizeInvalid) {
Chia-I Wu0eaea312017-10-31 10:14:40 -0700802 // cannot test robustness against invalid sizes (zero or really huge)
803}
804
Marissa Wall61c58622018-07-18 10:12:20 -0700805TEST_P(LayerTypeTransactionTest, SetSizeWithScaleToWindow) {
Chia-I Wu0eaea312017-10-31 10:14:40 -0700806 sp<SurfaceControl> layer;
807 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -0700808 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED, 32, 32));
Chia-I Wu0eaea312017-10-31 10:14:40 -0700809
810 // setSize is immediate with SCALE_TO_WINDOW, unlike setPosition
811 Transaction()
812 .setSize(layer, 64, 64)
813 .setOverrideScalingMode(layer, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW)
814 .apply();
815 screenshot()->expectColor(Rect(0, 0, 64, 64), Color::RED);
816}
817
Marissa Wall61c58622018-07-18 10:12:20 -0700818TEST_P(LayerTypeTransactionTest, SetZBasic) {
Chia-I Wu0ea0f822017-10-31 10:14:40 -0700819 sp<SurfaceControl> layerR;
820 sp<SurfaceControl> layerG;
821 ASSERT_NO_FATAL_FAILURE(layerR = createLayer("test R", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -0700822 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerR, Color::RED, 32, 32));
Chia-I Wu0ea0f822017-10-31 10:14:40 -0700823 ASSERT_NO_FATAL_FAILURE(layerG = createLayer("test G", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -0700824 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerG, Color::GREEN, 32, 32));
Chia-I Wu0ea0f822017-10-31 10:14:40 -0700825
826 Transaction().setLayer(layerR, mLayerZBase + 1).apply();
827 {
828 SCOPED_TRACE("layerR");
829 screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
830 }
831
832 Transaction().setLayer(layerG, mLayerZBase + 2).apply();
833 {
834 SCOPED_TRACE("layerG");
835 screenshot()->expectColor(Rect(0, 0, 32, 32), Color::GREEN);
836 }
837}
838
Marissa Wall61c58622018-07-18 10:12:20 -0700839TEST_P(LayerTypeTransactionTest, SetZNegative) {
chaviw0e3479f2018-09-10 16:49:30 -0700840 sp<SurfaceControl> parent =
Vishnu Nair88a11f22018-11-28 18:30:57 -0800841 LayerTransactionTest::createLayer("Parent", 0 /* buffer width */, 0 /* buffer height */,
chaviw0e3479f2018-09-10 16:49:30 -0700842 ISurfaceComposerClient::eFXSurfaceContainer);
Vishnu Nair88a11f22018-11-28 18:30:57 -0800843 Transaction().setCrop_legacy(parent, Rect(0, 0, mDisplayWidth, mDisplayHeight)).apply();
Chia-I Wu0ea0f822017-10-31 10:14:40 -0700844 sp<SurfaceControl> layerR;
845 sp<SurfaceControl> layerG;
846 ASSERT_NO_FATAL_FAILURE(layerR = createLayer("test R", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -0700847 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerR, Color::RED, 32, 32));
Chia-I Wu0ea0f822017-10-31 10:14:40 -0700848 ASSERT_NO_FATAL_FAILURE(layerG = createLayer("test G", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -0700849 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerG, Color::GREEN, 32, 32));
Chia-I Wu0ea0f822017-10-31 10:14:40 -0700850
chaviw0e3479f2018-09-10 16:49:30 -0700851 Transaction()
852 .reparent(layerR, parent->getHandle())
853 .reparent(layerG, parent->getHandle())
854 .apply();
Chia-I Wu0ea0f822017-10-31 10:14:40 -0700855 Transaction().setLayer(layerR, -1).setLayer(layerG, -2).apply();
856 {
857 SCOPED_TRACE("layerR");
chaviw0e3479f2018-09-10 16:49:30 -0700858 auto shot = screenshot();
859 shot->expectColor(Rect(0, 0, 32, 32), Color::RED);
Chia-I Wu0ea0f822017-10-31 10:14:40 -0700860 }
861
862 Transaction().setLayer(layerR, -3).apply();
863 {
864 SCOPED_TRACE("layerG");
chaviw0e3479f2018-09-10 16:49:30 -0700865 auto shot = screenshot();
866 shot->expectColor(Rect(0, 0, 32, 32), Color::GREEN);
Chia-I Wu0ea0f822017-10-31 10:14:40 -0700867 }
868}
869
Marissa Wall61c58622018-07-18 10:12:20 -0700870TEST_P(LayerTypeTransactionTest, SetRelativeZBasic) {
Chia-I Wu49313302017-10-31 10:14:40 -0700871 sp<SurfaceControl> layerR;
872 sp<SurfaceControl> layerG;
873 ASSERT_NO_FATAL_FAILURE(layerR = createLayer("test R", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -0700874 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerR, Color::RED, 32, 32));
Chia-I Wu49313302017-10-31 10:14:40 -0700875 ASSERT_NO_FATAL_FAILURE(layerG = createLayer("test G", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -0700876 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerG, Color::GREEN, 32, 32));
Chia-I Wu49313302017-10-31 10:14:40 -0700877
878 Transaction()
879 .setPosition(layerG, 16, 16)
880 .setRelativeLayer(layerG, layerR->getHandle(), 1)
881 .apply();
882 {
883 SCOPED_TRACE("layerG above");
884 auto shot = screenshot();
885 shot->expectColor(Rect(0, 0, 16, 16), Color::RED);
886 shot->expectColor(Rect(16, 16, 48, 48), Color::GREEN);
887 }
888
889 Transaction().setRelativeLayer(layerG, layerR->getHandle(), -1).apply();
890 {
891 SCOPED_TRACE("layerG below");
892 auto shot = screenshot();
893 shot->expectColor(Rect(0, 0, 32, 32), Color::RED);
894 shot->expectColor(Rect(32, 32, 48, 48), Color::GREEN);
895 }
896}
897
Marissa Wall61c58622018-07-18 10:12:20 -0700898TEST_P(LayerTypeTransactionTest, SetRelativeZNegative) {
chaviw0e3479f2018-09-10 16:49:30 -0700899 sp<SurfaceControl> parent =
Vishnu Nair88a11f22018-11-28 18:30:57 -0800900 LayerTransactionTest::createLayer("Parent", 0 /* buffer width */, 0 /* buffer height */,
chaviw0e3479f2018-09-10 16:49:30 -0700901 ISurfaceComposerClient::eFXSurfaceContainer);
Vishnu Nair88a11f22018-11-28 18:30:57 -0800902 Transaction().setCrop_legacy(parent, Rect(0, 0, mDisplayWidth, mDisplayHeight)).apply();
Chia-I Wuec2d9852017-11-21 09:21:01 -0800903 sp<SurfaceControl> layerR;
904 sp<SurfaceControl> layerG;
905 sp<SurfaceControl> layerB;
906 ASSERT_NO_FATAL_FAILURE(layerR = createLayer("test R", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -0700907 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerR, Color::RED, 32, 32));
Chia-I Wuec2d9852017-11-21 09:21:01 -0800908 ASSERT_NO_FATAL_FAILURE(layerG = createLayer("test G", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -0700909 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerG, Color::GREEN, 32, 32));
Chia-I Wuec2d9852017-11-21 09:21:01 -0800910 ASSERT_NO_FATAL_FAILURE(layerB = createLayer("test B", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -0700911 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerB, Color::BLUE, 32, 32));
Chia-I Wuec2d9852017-11-21 09:21:01 -0800912
chaviw0e3479f2018-09-10 16:49:30 -0700913 Transaction()
914 .reparent(layerB, parent->getHandle())
915 .apply();
916
Chia-I Wuec2d9852017-11-21 09:21:01 -0800917 // layerR = mLayerZBase, layerG = layerR - 1, layerB = -2
918 Transaction().setRelativeLayer(layerG, layerR->getHandle(), -1).setLayer(layerB, -2).apply();
919
chaviw0e3479f2018-09-10 16:49:30 -0700920 std::unique_ptr<ScreenCapture> screenshot;
Chia-I Wuec2d9852017-11-21 09:21:01 -0800921 // only layerB is in this range
chaviw0e3479f2018-09-10 16:49:30 -0700922 sp<IBinder> parentHandle = parent->getHandle();
923 ScreenCapture::captureLayers(&screenshot, parentHandle);
Chia-I Wuec2d9852017-11-21 09:21:01 -0800924 screenshot->expectColor(Rect(0, 0, 32, 32), Color::BLUE);
925}
926
Marissa Wall61c58622018-07-18 10:12:20 -0700927TEST_P(LayerTypeTransactionTest, SetRelativeZGroup) {
Chia-I Wu49313302017-10-31 10:14:40 -0700928 sp<SurfaceControl> layerR;
929 sp<SurfaceControl> layerG;
930 sp<SurfaceControl> layerB;
931 ASSERT_NO_FATAL_FAILURE(layerR = createLayer("test R", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -0700932 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerR, Color::RED, 32, 32));
Chia-I Wu49313302017-10-31 10:14:40 -0700933 ASSERT_NO_FATAL_FAILURE(layerG = createLayer("test G", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -0700934 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerG, Color::GREEN, 32, 32));
Chia-I Wu49313302017-10-31 10:14:40 -0700935 ASSERT_NO_FATAL_FAILURE(layerB = createLayer("test B", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -0700936 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerB, Color::BLUE, 32, 32));
Chia-I Wu49313302017-10-31 10:14:40 -0700937
938 // layerR = 0, layerG = layerR + 3, layerB = 2
939 Transaction()
940 .setPosition(layerG, 8, 8)
941 .setRelativeLayer(layerG, layerR->getHandle(), 3)
942 .setPosition(layerB, 16, 16)
943 .setLayer(layerB, mLayerZBase + 2)
944 .apply();
945 {
946 SCOPED_TRACE("(layerR < layerG) < layerB");
947 auto shot = screenshot();
948 shot->expectColor(Rect(0, 0, 8, 8), Color::RED);
949 shot->expectColor(Rect(8, 8, 16, 16), Color::GREEN);
950 shot->expectColor(Rect(16, 16, 48, 48), Color::BLUE);
951 }
952
953 // layerR = 4, layerG = layerR + 3, layerB = 2
954 Transaction().setLayer(layerR, mLayerZBase + 4).apply();
955 {
956 SCOPED_TRACE("layerB < (layerR < layerG)");
957 auto shot = screenshot();
958 shot->expectColor(Rect(0, 0, 8, 8), Color::RED);
959 shot->expectColor(Rect(8, 8, 40, 40), Color::GREEN);
960 shot->expectColor(Rect(40, 40, 48, 48), Color::BLUE);
961 }
962
963 // layerR = 4, layerG = layerR - 3, layerB = 2
964 Transaction().setRelativeLayer(layerG, layerR->getHandle(), -3).apply();
965 {
966 SCOPED_TRACE("layerB < (layerG < layerR)");
967 auto shot = screenshot();
968 shot->expectColor(Rect(0, 0, 32, 32), Color::RED);
969 shot->expectColor(Rect(32, 32, 40, 40), Color::GREEN);
970 shot->expectColor(Rect(40, 40, 48, 48), Color::BLUE);
971 }
972
973 // restore to absolute z
974 // layerR = 4, layerG = 0, layerB = 2
975 Transaction().setLayer(layerG, mLayerZBase).apply();
976 {
977 SCOPED_TRACE("layerG < layerB < layerR");
978 auto shot = screenshot();
979 shot->expectColor(Rect(0, 0, 32, 32), Color::RED);
980 shot->expectColor(Rect(32, 32, 48, 48), Color::BLUE);
981 }
982
983 // layerR should not affect layerG anymore
984 // layerR = 1, layerG = 0, layerB = 2
985 Transaction().setLayer(layerR, mLayerZBase + 1).apply();
986 {
987 SCOPED_TRACE("layerG < layerR < layerB");
988 auto shot = screenshot();
989 shot->expectColor(Rect(0, 0, 16, 16), Color::RED);
990 shot->expectColor(Rect(16, 16, 48, 48), Color::BLUE);
991 }
992}
993
Marissa Wall61c58622018-07-18 10:12:20 -0700994TEST_P(LayerTypeTransactionTest, SetRelativeZBug64572777) {
Chia-I Wu49313302017-10-31 10:14:40 -0700995 sp<SurfaceControl> layerR;
996 sp<SurfaceControl> layerG;
997
998 ASSERT_NO_FATAL_FAILURE(layerR = createLayer("test R", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -0700999 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerR, Color::RED, 32, 32));
Chia-I Wu49313302017-10-31 10:14:40 -07001000 ASSERT_NO_FATAL_FAILURE(layerG = createLayer("test G", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -07001001 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerG, Color::GREEN, 32, 32));
Chia-I Wu49313302017-10-31 10:14:40 -07001002
1003 Transaction()
1004 .setPosition(layerG, 16, 16)
1005 .setRelativeLayer(layerG, layerR->getHandle(), 1)
1006 .apply();
1007
1008 mClient->destroySurface(layerG->getHandle());
1009 // layerG should have been removed
1010 screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
1011}
1012
Marissa Wall61c58622018-07-18 10:12:20 -07001013TEST_P(LayerTypeTransactionTest, SetFlagsHidden) {
Chia-I Wu57b27502017-10-31 10:14:40 -07001014 sp<SurfaceControl> layer;
1015 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -07001016 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED, 32, 32));
Chia-I Wu57b27502017-10-31 10:14:40 -07001017
1018 Transaction().setFlags(layer, layer_state_t::eLayerHidden, layer_state_t::eLayerHidden).apply();
1019 {
1020 SCOPED_TRACE("layer hidden");
1021 screenshot()->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK);
1022 }
1023
1024 Transaction().setFlags(layer, 0, layer_state_t::eLayerHidden).apply();
1025 {
1026 SCOPED_TRACE("layer shown");
1027 screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
1028 }
1029}
1030
Marissa Wall61c58622018-07-18 10:12:20 -07001031TEST_P(LayerTypeTransactionTest, SetFlagsOpaque) {
Chia-I Wu57b27502017-10-31 10:14:40 -07001032 const Color translucentRed = {100, 0, 0, 100};
1033 sp<SurfaceControl> layerR;
1034 sp<SurfaceControl> layerG;
1035 ASSERT_NO_FATAL_FAILURE(layerR = createLayer("test R", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -07001036 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerR, translucentRed, 32, 32));
Chia-I Wu57b27502017-10-31 10:14:40 -07001037 ASSERT_NO_FATAL_FAILURE(layerG = createLayer("test G", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -07001038 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerG, Color::GREEN, 32, 32));
Chia-I Wu57b27502017-10-31 10:14:40 -07001039
1040 Transaction()
1041 .setLayer(layerR, mLayerZBase + 1)
1042 .setFlags(layerR, layer_state_t::eLayerOpaque, layer_state_t::eLayerOpaque)
1043 .apply();
1044 {
1045 SCOPED_TRACE("layerR opaque");
1046 screenshot()->expectColor(Rect(0, 0, 32, 32), {100, 0, 0, 255});
1047 }
1048
1049 Transaction().setFlags(layerR, 0, layer_state_t::eLayerOpaque).apply();
1050 {
1051 SCOPED_TRACE("layerR translucent");
1052 const uint8_t g = uint8_t(255 - translucentRed.a);
1053 screenshot()->expectColor(Rect(0, 0, 32, 32), {100, g, 0, 255});
1054 }
1055}
1056
Marissa Wall61c58622018-07-18 10:12:20 -07001057TEST_P(LayerTypeTransactionTest, SetFlagsSecure) {
Chia-I Wu57b27502017-10-31 10:14:40 -07001058 sp<SurfaceControl> layer;
1059 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -07001060 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED, 32, 32));
Chia-I Wu57b27502017-10-31 10:14:40 -07001061
1062 sp<ISurfaceComposer> composer = ComposerService::getComposerService();
Chavi Weingarten40482ff2017-11-30 01:51:40 +00001063 sp<GraphicBuffer> outBuffer;
Chia-I Wu57b27502017-10-31 10:14:40 -07001064 Transaction()
1065 .setFlags(layer, layer_state_t::eLayerSecure, layer_state_t::eLayerSecure)
1066 .apply(true);
1067 ASSERT_EQ(PERMISSION_DENIED,
chaviw0e3479f2018-09-10 16:49:30 -07001068 composer->captureScreen(mDisplay, &outBuffer, Rect(), 0, 0, false));
Chia-I Wu57b27502017-10-31 10:14:40 -07001069
1070 Transaction().setFlags(layer, 0, layer_state_t::eLayerSecure).apply(true);
1071 ASSERT_EQ(NO_ERROR,
chaviw0e3479f2018-09-10 16:49:30 -07001072 composer->captureScreen(mDisplay, &outBuffer, Rect(), 0, 0, false));
Chia-I Wu57b27502017-10-31 10:14:40 -07001073}
1074
Marissa Wall61c58622018-07-18 10:12:20 -07001075TEST_F(LayerTransactionTest, SetTransparentRegionHintBasic_BufferQueue) {
Chia-I Wu2113bdd2017-11-01 15:16:35 -07001076 const Rect top(0, 0, 32, 16);
1077 const Rect bottom(0, 16, 32, 32);
1078 sp<SurfaceControl> layer;
1079 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
1080
1081 ANativeWindow_Buffer buffer;
Marissa Wall61c58622018-07-18 10:12:20 -07001082 ASSERT_NO_FATAL_FAILURE(buffer = getBufferQueueLayerBuffer(layer));
1083 ASSERT_NO_FATAL_FAILURE(fillANativeWindowBufferColor(buffer, top, Color::TRANSPARENT));
1084 ASSERT_NO_FATAL_FAILURE(fillANativeWindowBufferColor(buffer, bottom, Color::RED));
Chia-I Wu2113bdd2017-11-01 15:16:35 -07001085 // setTransparentRegionHint always applies to the following buffer
1086 Transaction().setTransparentRegionHint(layer, Region(top)).apply();
Marissa Wall61c58622018-07-18 10:12:20 -07001087 ASSERT_NO_FATAL_FAILURE(postBufferQueueLayerBuffer(layer));
Chia-I Wu2113bdd2017-11-01 15:16:35 -07001088 {
1089 SCOPED_TRACE("top transparent");
1090 auto shot = screenshot();
1091 shot->expectColor(top, Color::BLACK);
1092 shot->expectColor(bottom, Color::RED);
1093 }
1094
1095 Transaction().setTransparentRegionHint(layer, Region(bottom)).apply();
1096 {
1097 SCOPED_TRACE("transparent region hint pending");
1098 auto shot = screenshot();
1099 shot->expectColor(top, Color::BLACK);
1100 shot->expectColor(bottom, Color::RED);
1101 }
1102
Marissa Wall61c58622018-07-18 10:12:20 -07001103 ASSERT_NO_FATAL_FAILURE(buffer = getBufferQueueLayerBuffer(layer));
1104 ASSERT_NO_FATAL_FAILURE(fillANativeWindowBufferColor(buffer, top, Color::RED));
1105 ASSERT_NO_FATAL_FAILURE(fillANativeWindowBufferColor(buffer, bottom, Color::TRANSPARENT));
1106 ASSERT_NO_FATAL_FAILURE(postBufferQueueLayerBuffer(layer));
Chia-I Wu2113bdd2017-11-01 15:16:35 -07001107 {
1108 SCOPED_TRACE("bottom transparent");
1109 auto shot = screenshot();
1110 shot->expectColor(top, Color::RED);
1111 shot->expectColor(bottom, Color::BLACK);
1112 }
1113}
1114
Marissa Wall61c58622018-07-18 10:12:20 -07001115TEST_F(LayerTransactionTest, SetTransparentRegionHintBasic_BufferState) {
1116 const Rect top(0, 0, 32, 16);
1117 const Rect bottom(0, 16, 32, 32);
1118 sp<SurfaceControl> layer;
1119 ASSERT_NO_FATAL_FAILURE(
1120 layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
1121
1122 sp<GraphicBuffer> buffer =
1123 new GraphicBuffer(32, 32, PIXEL_FORMAT_RGBA_8888, 1,
1124 BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
1125 BufferUsage::COMPOSER_OVERLAY,
1126 "test");
1127
1128 ASSERT_NO_FATAL_FAILURE(fillGraphicBufferColor(buffer, top, Color::TRANSPARENT));
1129 ASSERT_NO_FATAL_FAILURE(fillGraphicBufferColor(buffer, bottom, Color::RED));
1130 Transaction()
1131 .setTransparentRegionHint(layer, Region(top))
1132 .setBuffer(layer, buffer)
1133 .setSize(layer, 32, 32)
1134 .apply();
1135 {
1136 SCOPED_TRACE("top transparent");
1137 auto shot = screenshot();
1138 shot->expectColor(top, Color::BLACK);
1139 shot->expectColor(bottom, Color::RED);
1140 }
1141
1142 Transaction().setTransparentRegionHint(layer, Region(bottom)).apply();
1143 {
1144 SCOPED_TRACE("transparent region hint intermediate");
1145 auto shot = screenshot();
1146 shot->expectColor(top, Color::BLACK);
1147 shot->expectColor(bottom, Color::BLACK);
1148 }
1149
1150 buffer = new GraphicBuffer(32, 32, PIXEL_FORMAT_RGBA_8888, 1,
1151 BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
1152 BufferUsage::COMPOSER_OVERLAY,
1153 "test");
1154
1155 ASSERT_NO_FATAL_FAILURE(fillGraphicBufferColor(buffer, top, Color::RED));
1156 ASSERT_NO_FATAL_FAILURE(fillGraphicBufferColor(buffer, bottom, Color::TRANSPARENT));
1157 Transaction().setBuffer(layer, buffer).setSize(layer, 32, 32).apply();
1158 {
1159 SCOPED_TRACE("bottom transparent");
1160 auto shot = screenshot();
1161 shot->expectColor(top, Color::RED);
1162 shot->expectColor(bottom, Color::BLACK);
1163 }
1164}
1165
1166TEST_P(LayerTypeTransactionTest, SetTransparentRegionHintOutOfBounds) {
Chia-I Wu2113bdd2017-11-01 15:16:35 -07001167 sp<SurfaceControl> layerTransparent;
1168 sp<SurfaceControl> layerR;
1169 ASSERT_NO_FATAL_FAILURE(layerTransparent = createLayer("test transparent", 32, 32));
1170 ASSERT_NO_FATAL_FAILURE(layerR = createLayer("test R", 32, 32));
1171
1172 // check that transparent region hint is bound by the layer size
1173 Transaction()
1174 .setTransparentRegionHint(layerTransparent,
1175 Region(Rect(0, 0, mDisplayWidth, mDisplayHeight)))
1176 .setPosition(layerR, 16, 16)
1177 .setLayer(layerR, mLayerZBase + 1)
1178 .apply();
Marissa Wall61c58622018-07-18 10:12:20 -07001179 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerTransparent, Color::TRANSPARENT, 32, 32));
1180 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerR, Color::RED, 32, 32));
Chia-I Wu2113bdd2017-11-01 15:16:35 -07001181 screenshot()->expectColor(Rect(16, 16, 48, 48), Color::RED);
1182}
1183
Marissa Wall61c58622018-07-18 10:12:20 -07001184TEST_P(LayerTypeTransactionTest, SetAlphaBasic) {
Chia-I Wua8a515e2017-11-01 15:16:35 -07001185 sp<SurfaceControl> layer1;
1186 sp<SurfaceControl> layer2;
1187 ASSERT_NO_FATAL_FAILURE(layer1 = createLayer("test 1", 32, 32));
1188 ASSERT_NO_FATAL_FAILURE(layer2 = createLayer("test 2", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -07001189 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer1, {64, 0, 0, 255}, 32, 32));
1190 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer2, {0, 64, 0, 255}, 32, 32));
Chia-I Wua8a515e2017-11-01 15:16:35 -07001191
1192 Transaction()
1193 .setAlpha(layer1, 0.25f)
1194 .setAlpha(layer2, 0.75f)
1195 .setPosition(layer2, 16, 0)
1196 .setLayer(layer2, mLayerZBase + 1)
1197 .apply();
1198 {
1199 auto shot = screenshot();
1200 uint8_t r = 16; // 64 * 0.25f
1201 uint8_t g = 48; // 64 * 0.75f
1202 shot->expectColor(Rect(0, 0, 16, 32), {r, 0, 0, 255});
1203 shot->expectColor(Rect(32, 0, 48, 32), {0, g, 0, 255});
1204
1205 r /= 4; // r * (1.0f - 0.75f)
1206 shot->expectColor(Rect(16, 0, 32, 32), {r, g, 0, 255});
1207 }
1208}
1209
Marissa Wall61c58622018-07-18 10:12:20 -07001210TEST_P(LayerTypeTransactionTest, SetAlphaClamped) {
Chia-I Wua8a515e2017-11-01 15:16:35 -07001211 const Color color = {64, 0, 0, 255};
1212 sp<SurfaceControl> layer;
1213 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -07001214 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, color, 32, 32));
Chia-I Wua8a515e2017-11-01 15:16:35 -07001215
1216 Transaction().setAlpha(layer, 2.0f).apply();
1217 {
1218 SCOPED_TRACE("clamped to 1.0f");
1219 screenshot()->expectColor(Rect(0, 0, 32, 32), color);
1220 }
1221
1222 Transaction().setAlpha(layer, -1.0f).apply();
1223 {
1224 SCOPED_TRACE("clamped to 0.0f");
1225 screenshot()->expectColor(Rect(0, 0, 32, 32), Color::BLACK);
1226 }
1227}
1228
Lucas Dupin1b6531c2018-07-05 17:18:21 -07001229TEST_P(LayerTypeTransactionTest, SetCornerRadius) {
1230 sp<SurfaceControl> layer;
1231 const uint8_t size = 64;
1232 const uint8_t testArea = 4;
1233 const float cornerRadius = 16.0f;
1234 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", size, size));
1235 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED, size, size));
1236
1237 Transaction()
1238 .setCornerRadius(layer, cornerRadius)
1239 .apply();
1240 {
1241 auto shot = screenshot();
1242 // Transparent corners
1243 shot->expectColor(Rect(0, 0, testArea, testArea), Color::BLACK);
1244 shot->expectColor(Rect(0, size - testArea, testArea, testArea), Color::BLACK);
1245 shot->expectColor(Rect(size - testArea, 0, testArea, testArea), Color::BLACK);
1246 shot->expectColor(Rect(size - testArea, size - testArea, testArea, testArea),
1247 Color::BLACK);
1248 }
1249}
1250
Chia-I Wue4ef6102017-11-01 15:16:35 -07001251TEST_F(LayerTransactionTest, SetColorBasic) {
1252 sp<SurfaceControl> bufferLayer;
1253 sp<SurfaceControl> colorLayer;
1254 ASSERT_NO_FATAL_FAILURE(bufferLayer = createLayer("test bg", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -07001255 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(bufferLayer, Color::RED, 32, 32));
Vishnu Nair88a11f22018-11-28 18:30:57 -08001256 ASSERT_NO_FATAL_FAILURE(colorLayer =
1257 createLayer("test", 0 /* buffer width */, 0 /* buffer height */,
1258 ISurfaceComposerClient::eFXSurfaceColor));
Chia-I Wue4ef6102017-11-01 15:16:35 -07001259
Vishnu Nair88a11f22018-11-28 18:30:57 -08001260 Transaction()
1261 .setCrop_legacy(colorLayer, Rect(0, 0, 32, 32))
1262 .setLayer(colorLayer, mLayerZBase + 1)
1263 .apply();
1264
Chia-I Wue4ef6102017-11-01 15:16:35 -07001265 {
1266 SCOPED_TRACE("default color");
1267 screenshot()->expectColor(Rect(0, 0, 32, 32), Color::BLACK);
1268 }
1269
1270 const half3 color(15.0f / 255.0f, 51.0f / 255.0f, 85.0f / 255.0f);
1271 const Color expected = {15, 51, 85, 255};
1272 // this is handwavy, but the precison loss scaled by 255 (8-bit per
1273 // channel) should be less than one
1274 const uint8_t tolerance = 1;
1275 Transaction().setColor(colorLayer, color).apply();
1276 {
1277 SCOPED_TRACE("new color");
1278 screenshot()->expectColor(Rect(0, 0, 32, 32), expected, tolerance);
1279 }
1280}
1281
1282TEST_F(LayerTransactionTest, SetColorClamped) {
1283 sp<SurfaceControl> colorLayer;
Vishnu Nair88a11f22018-11-28 18:30:57 -08001284 ASSERT_NO_FATAL_FAILURE(colorLayer =
1285 createLayer("test", 0 /* buffer width */, 0 /* buffer height */,
1286 ISurfaceComposerClient::eFXSurfaceColor));
1287 Transaction()
1288 .setCrop_legacy(colorLayer, Rect(0, 0, 32, 32))
1289 .setColor(colorLayer, half3(2.0f, -1.0f, 0.0f))
1290 .apply();
Chia-I Wue4ef6102017-11-01 15:16:35 -07001291
Chia-I Wue4ef6102017-11-01 15:16:35 -07001292 screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
1293}
1294
1295TEST_F(LayerTransactionTest, SetColorWithAlpha) {
1296 sp<SurfaceControl> bufferLayer;
1297 sp<SurfaceControl> colorLayer;
1298 ASSERT_NO_FATAL_FAILURE(bufferLayer = createLayer("test bg", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -07001299 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(bufferLayer, Color::RED, 32, 32));
Vishnu Nair88a11f22018-11-28 18:30:57 -08001300 ASSERT_NO_FATAL_FAILURE(colorLayer =
1301 createLayer("test", 0 /* buffer width */, 0 /* buffer height */,
1302 ISurfaceComposerClient::eFXSurfaceColor));
1303 Transaction().setCrop_legacy(colorLayer, Rect(0, 0, 32, 32)).apply();
Chia-I Wue4ef6102017-11-01 15:16:35 -07001304
1305 const half3 color(15.0f / 255.0f, 51.0f / 255.0f, 85.0f / 255.0f);
1306 const float alpha = 0.25f;
1307 const ubyte3 expected((vec3(color) * alpha + vec3(1.0f, 0.0f, 0.0f) * (1.0f - alpha)) * 255.0f);
1308 // this is handwavy, but the precison loss scaled by 255 (8-bit per
1309 // channel) should be less than one
1310 const uint8_t tolerance = 1;
1311 Transaction()
1312 .setColor(colorLayer, color)
1313 .setAlpha(colorLayer, alpha)
1314 .setLayer(colorLayer, mLayerZBase + 1)
1315 .apply();
1316 screenshot()->expectColor(Rect(0, 0, 32, 32), {expected.r, expected.g, expected.b, 255},
1317 tolerance);
1318}
1319
Adrian Roosb7a96502018-04-08 11:38:55 -07001320TEST_F(LayerTransactionTest, SetColorWithParentAlpha_Bug74220420) {
1321 sp<SurfaceControl> bufferLayer;
1322 sp<SurfaceControl> parentLayer;
1323 sp<SurfaceControl> colorLayer;
1324 ASSERT_NO_FATAL_FAILURE(bufferLayer = createLayer("test bg", 32, 32));
1325 ASSERT_NO_FATAL_FAILURE(parentLayer = createLayer("parentWithAlpha", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -07001326 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(bufferLayer, Color::RED, 32, 32));
Vishnu Nair88a11f22018-11-28 18:30:57 -08001327 ASSERT_NO_FATAL_FAILURE(colorLayer = createLayer("childWithColor", 0 /* buffer width */,
1328 0 /* buffer height */,
1329 ISurfaceComposerClient::eFXSurfaceColor));
1330 Transaction().setCrop_legacy(colorLayer, Rect(0, 0, 32, 32)).apply();
Adrian Roosb7a96502018-04-08 11:38:55 -07001331 const half3 color(15.0f / 255.0f, 51.0f / 255.0f, 85.0f / 255.0f);
1332 const float alpha = 0.25f;
1333 const ubyte3 expected((vec3(color) * alpha + vec3(1.0f, 0.0f, 0.0f) * (1.0f - alpha)) * 255.0f);
1334 // this is handwavy, but the precision loss scaled by 255 (8-bit per
1335 // channel) should be less than one
1336 const uint8_t tolerance = 1;
1337 Transaction()
1338 .reparent(colorLayer, parentLayer->getHandle())
1339 .setColor(colorLayer, color)
1340 .setAlpha(parentLayer, alpha)
1341 .setLayer(parentLayer, mLayerZBase + 1)
1342 .apply();
1343 screenshot()->expectColor(Rect(0, 0, 32, 32), {expected.r, expected.g, expected.b, 255},
1344 tolerance);
1345}
1346
Marissa Wall61c58622018-07-18 10:12:20 -07001347TEST_P(LayerTypeTransactionTest, SetColorWithBuffer) {
Chia-I Wue4ef6102017-11-01 15:16:35 -07001348 sp<SurfaceControl> bufferLayer;
1349 ASSERT_NO_FATAL_FAILURE(bufferLayer = createLayer("test", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -07001350 ASSERT_NO_FATAL_FAILURE(fillLayerColor(bufferLayer, Color::RED, 32, 32));
Chia-I Wue4ef6102017-11-01 15:16:35 -07001351
1352 // color is ignored
1353 Transaction().setColor(bufferLayer, half3(0.0f, 1.0f, 0.0f)).apply();
1354 screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
1355}
1356
Marissa Wall61c58622018-07-18 10:12:20 -07001357TEST_P(LayerTypeTransactionTest, SetLayerStackBasic) {
Chia-I Wu3d22f3a2017-11-02 08:30:27 -07001358 sp<SurfaceControl> layer;
1359 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -07001360 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED, 32, 32));
Chia-I Wu3d22f3a2017-11-02 08:30:27 -07001361
1362 Transaction().setLayerStack(layer, mDisplayLayerStack + 1).apply();
1363 {
1364 SCOPED_TRACE("non-existing layer stack");
1365 screenshot()->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK);
1366 }
1367
1368 Transaction().setLayerStack(layer, mDisplayLayerStack).apply();
1369 {
1370 SCOPED_TRACE("original layer stack");
1371 screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
1372 }
1373}
1374
Marissa Wall61c58622018-07-18 10:12:20 -07001375TEST_P(LayerTypeTransactionTest, SetMatrixBasic) {
Chia-I Wu93853fe2017-11-02 08:30:27 -07001376 sp<SurfaceControl> layer;
1377 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
1378 ASSERT_NO_FATAL_FAILURE(
Marissa Wall61c58622018-07-18 10:12:20 -07001379 fillLayerQuadrant(layer, 32, 32, Color::RED, Color::GREEN, Color::BLUE, Color::WHITE));
Chia-I Wu93853fe2017-11-02 08:30:27 -07001380
1381 Transaction().setMatrix(layer, 1.0f, 0.0f, 0.0f, 1.0f).setPosition(layer, 0, 0).apply();
1382 {
1383 SCOPED_TRACE("IDENTITY");
1384 screenshot()->expectQuadrant(Rect(0, 0, 32, 32), Color::RED, Color::GREEN, Color::BLUE,
1385 Color::WHITE);
1386 }
1387
1388 Transaction().setMatrix(layer, -1.0f, 0.0f, 0.0f, 1.0f).setPosition(layer, 32, 0).apply();
1389 {
1390 SCOPED_TRACE("FLIP_H");
1391 screenshot()->expectQuadrant(Rect(0, 0, 32, 32), Color::GREEN, Color::RED, Color::WHITE,
1392 Color::BLUE);
1393 }
1394
1395 Transaction().setMatrix(layer, 1.0f, 0.0f, 0.0f, -1.0f).setPosition(layer, 0, 32).apply();
1396 {
1397 SCOPED_TRACE("FLIP_V");
1398 screenshot()->expectQuadrant(Rect(0, 0, 32, 32), Color::BLUE, Color::WHITE, Color::RED,
1399 Color::GREEN);
1400 }
1401
1402 Transaction().setMatrix(layer, 0.0f, 1.0f, -1.0f, 0.0f).setPosition(layer, 32, 0).apply();
1403 {
1404 SCOPED_TRACE("ROT_90");
1405 screenshot()->expectQuadrant(Rect(0, 0, 32, 32), Color::BLUE, Color::RED, Color::WHITE,
1406 Color::GREEN);
1407 }
1408
1409 Transaction().setMatrix(layer, 2.0f, 0.0f, 0.0f, 2.0f).setPosition(layer, 0, 0).apply();
1410 {
1411 SCOPED_TRACE("SCALE");
1412 screenshot()->expectQuadrant(Rect(0, 0, 64, 64), Color::RED, Color::GREEN, Color::BLUE,
1413 Color::WHITE, true /* filtered */);
1414 }
1415}
1416
Marissa Wall61c58622018-07-18 10:12:20 -07001417TEST_P(LayerTypeTransactionTest, SetMatrixRot45) {
Chia-I Wu93853fe2017-11-02 08:30:27 -07001418 sp<SurfaceControl> layer;
1419 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
1420 ASSERT_NO_FATAL_FAILURE(
Marissa Wall61c58622018-07-18 10:12:20 -07001421 fillLayerQuadrant(layer, 32, 32, Color::RED, Color::GREEN, Color::BLUE, Color::WHITE));
Chia-I Wu93853fe2017-11-02 08:30:27 -07001422
1423 const float rot = M_SQRT1_2; // 45 degrees
1424 const float trans = M_SQRT2 * 16.0f;
1425 Transaction().setMatrix(layer, rot, rot, -rot, rot).setPosition(layer, trans, 0).apply();
1426
1427 auto shot = screenshot();
1428 // check a 8x8 region inside each color
1429 auto get8x8Rect = [](int32_t centerX, int32_t centerY) {
1430 const int32_t halfL = 4;
1431 return Rect(centerX - halfL, centerY - halfL, centerX + halfL, centerY + halfL);
1432 };
1433 const int32_t unit = int32_t(trans / 2);
1434 shot->expectColor(get8x8Rect(2 * unit, 1 * unit), Color::RED);
1435 shot->expectColor(get8x8Rect(3 * unit, 2 * unit), Color::GREEN);
1436 shot->expectColor(get8x8Rect(1 * unit, 2 * unit), Color::BLUE);
1437 shot->expectColor(get8x8Rect(2 * unit, 3 * unit), Color::WHITE);
1438}
1439
Marissa Wall61c58622018-07-18 10:12:20 -07001440void LayerTransactionTest::setMatrixWithResizeHelper(uint32_t layerType) {
Chia-I Wu93853fe2017-11-02 08:30:27 -07001441 sp<SurfaceControl> layer;
Marissa Wall61c58622018-07-18 10:12:20 -07001442 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32, layerType));
1443 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerType, layer, Color::RED, 32, 32));
Chia-I Wu93853fe2017-11-02 08:30:27 -07001444
1445 // setMatrix is applied after any pending resize, unlike setPosition
1446 Transaction().setMatrix(layer, 2.0f, 0.0f, 0.0f, 2.0f).setSize(layer, 64, 64).apply();
1447 {
1448 SCOPED_TRACE("resize pending");
1449 auto shot = screenshot();
Marissa Wall61c58622018-07-18 10:12:20 -07001450 Rect rect;
1451 switch (layerType) {
1452 case ISurfaceComposerClient::eFXSurfaceBufferQueue:
1453 rect = {0, 0, 32, 32};
1454 break;
1455 case ISurfaceComposerClient::eFXSurfaceBufferState:
1456 rect = {0, 0, 128, 128};
1457 break;
1458 default:
1459 ASSERT_FALSE(true) << "Unsupported layer type";
1460 }
1461 shot->expectColor(rect, Color::RED);
1462 shot->expectBorder(rect, Color::BLACK);
Chia-I Wu93853fe2017-11-02 08:30:27 -07001463 }
1464
Marissa Wall61c58622018-07-18 10:12:20 -07001465 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerType, layer, Color::RED, 64, 64));
Chia-I Wu93853fe2017-11-02 08:30:27 -07001466 {
1467 SCOPED_TRACE("resize applied");
1468 screenshot()->expectColor(Rect(0, 0, 128, 128), Color::RED);
1469 }
1470}
1471
Marissa Wall61c58622018-07-18 10:12:20 -07001472TEST_F(LayerTransactionTest, SetMatrixWithResize_BufferQueue) {
1473 ASSERT_NO_FATAL_FAILURE(
1474 setMatrixWithResizeHelper(ISurfaceComposerClient::eFXSurfaceBufferQueue));
1475}
1476
1477TEST_F(LayerTransactionTest, SetMatrixWithResize_BufferState) {
1478 ASSERT_NO_FATAL_FAILURE(
1479 setMatrixWithResizeHelper(ISurfaceComposerClient::eFXSurfaceBufferState));
1480}
1481
1482TEST_P(LayerTypeTransactionTest, SetMatrixWithScaleToWindow) {
Chia-I Wu93853fe2017-11-02 08:30:27 -07001483 sp<SurfaceControl> layer;
1484 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -07001485 ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED, 32, 32));
Chia-I Wu93853fe2017-11-02 08:30:27 -07001486
1487 // setMatrix is immediate with SCALE_TO_WINDOW, unlike setPosition
1488 Transaction()
1489 .setMatrix(layer, 2.0f, 0.0f, 0.0f, 2.0f)
1490 .setSize(layer, 64, 64)
1491 .setOverrideScalingMode(layer, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW)
1492 .apply();
1493 screenshot()->expectColor(Rect(0, 0, 128, 128), Color::RED);
1494}
1495
Marissa Wall61c58622018-07-18 10:12:20 -07001496TEST_P(LayerTypeTransactionTest, SetOverrideScalingModeBasic) {
Chia-I Wua56b2042017-11-01 15:16:35 -07001497 sp<SurfaceControl> layer;
1498 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
1499 ASSERT_NO_FATAL_FAILURE(
Marissa Wall61c58622018-07-18 10:12:20 -07001500 fillLayerQuadrant(layer, 32, 32, Color::RED, Color::GREEN, Color::BLUE, Color::WHITE));
Chia-I Wua56b2042017-11-01 15:16:35 -07001501
1502 // XXX SCALE_CROP is not respected; calling setSize and
1503 // setOverrideScalingMode in separate transactions does not work
1504 // (b/69315456)
1505 Transaction()
1506 .setSize(layer, 64, 16)
1507 .setOverrideScalingMode(layer, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW)
1508 .apply();
1509 {
1510 SCOPED_TRACE("SCALE_TO_WINDOW");
1511 screenshot()->expectQuadrant(Rect(0, 0, 64, 16), Color::RED, Color::GREEN, Color::BLUE,
1512 Color::WHITE, true /* filtered */);
1513 }
1514}
1515
Dan Stoza000dd012018-08-01 13:31:52 -07001516TEST_P(LayerTypeTransactionTest, RefreshRateIsInitialized) {
1517 sp<SurfaceControl> layer;
1518 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
1519
1520 sp<IBinder> handle = layer->getHandle();
1521 ASSERT_TRUE(handle != nullptr);
1522
1523 FrameStats frameStats;
1524 mClient->getLayerFrameStats(handle, &frameStats);
1525
1526 ASSERT_GT(frameStats.refreshPeriodNano, static_cast<nsecs_t>(0));
1527}
1528
Marissa Wall61c58622018-07-18 10:12:20 -07001529TEST_F(LayerTransactionTest, SetCropBasic_BufferQueue) {
Chia-I Wu04dcca82017-11-02 08:30:27 -07001530 sp<SurfaceControl> layer;
1531 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -07001532 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32));
Chia-I Wu04dcca82017-11-02 08:30:27 -07001533 const Rect crop(8, 8, 24, 24);
1534
Marissa Wallf58c14b2018-07-24 10:50:43 -07001535 Transaction().setCrop_legacy(layer, crop).apply();
Chia-I Wu04dcca82017-11-02 08:30:27 -07001536 auto shot = screenshot();
1537 shot->expectColor(crop, Color::RED);
1538 shot->expectBorder(crop, Color::BLACK);
1539}
1540
Marissa Wall61c58622018-07-18 10:12:20 -07001541TEST_F(LayerTransactionTest, SetCropBasic_BufferState) {
1542 sp<SurfaceControl> layer;
1543 ASSERT_NO_FATAL_FAILURE(
1544 layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
1545 ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32));
1546 const Rect crop(8, 8, 24, 24);
1547
1548 Transaction().setCrop(layer, crop).apply();
1549 auto shot = screenshot();
1550 shot->expectColor(crop, Color::RED);
1551 shot->expectBorder(crop, Color::BLACK);
1552}
1553
1554TEST_F(LayerTransactionTest, SetCropEmpty_BufferQueue) {
Chia-I Wu04dcca82017-11-02 08:30:27 -07001555 sp<SurfaceControl> layer;
1556 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -07001557 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32));
Chia-I Wu04dcca82017-11-02 08:30:27 -07001558
1559 {
1560 SCOPED_TRACE("empty rect");
Marissa Wallf58c14b2018-07-24 10:50:43 -07001561 Transaction().setCrop_legacy(layer, Rect(8, 8, 8, 8)).apply();
Chia-I Wu04dcca82017-11-02 08:30:27 -07001562 screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
1563 }
1564
1565 {
1566 SCOPED_TRACE("negative rect");
Marissa Wallf58c14b2018-07-24 10:50:43 -07001567 Transaction().setCrop_legacy(layer, Rect(8, 8, 0, 0)).apply();
Chia-I Wu04dcca82017-11-02 08:30:27 -07001568 screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
1569 }
1570}
1571
Marissa Wall61c58622018-07-18 10:12:20 -07001572TEST_F(LayerTransactionTest, SetCropEmpty_BufferState) {
1573 sp<SurfaceControl> layer;
1574 ASSERT_NO_FATAL_FAILURE(
1575 layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
1576 ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32));
1577
1578 {
1579 SCOPED_TRACE("empty rect");
1580 Transaction().setCrop(layer, Rect(8, 8, 8, 8)).apply();
1581 screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
1582 }
1583
1584 {
1585 SCOPED_TRACE("negative rect");
1586 Transaction().setCrop(layer, Rect(8, 8, 0, 0)).apply();
1587 screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
1588 }
1589}
1590
1591TEST_F(LayerTransactionTest, SetCropOutOfBounds_BufferQueue) {
Chia-I Wu04dcca82017-11-02 08:30:27 -07001592 sp<SurfaceControl> layer;
1593 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -07001594 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32));
Chia-I Wu04dcca82017-11-02 08:30:27 -07001595
Marissa Wallf58c14b2018-07-24 10:50:43 -07001596 Transaction().setCrop_legacy(layer, Rect(-128, -64, 128, 64)).apply();
Chia-I Wu04dcca82017-11-02 08:30:27 -07001597 auto shot = screenshot();
1598 shot->expectColor(Rect(0, 0, 32, 32), Color::RED);
1599 shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
1600}
1601
Marissa Wall61c58622018-07-18 10:12:20 -07001602TEST_F(LayerTransactionTest, SetCropOutOfBounds_BufferState) {
1603 sp<SurfaceControl> layer;
1604 ASSERT_NO_FATAL_FAILURE(
1605 layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
1606 ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32));
1607
1608 Transaction().setCrop(layer, Rect(-128, -64, 128, 64)).apply();
1609 auto shot = screenshot();
1610 shot->expectColor(Rect(0, 0, 32, 32), Color::RED);
1611 shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
1612}
1613
1614TEST_F(LayerTransactionTest, SetCropWithTranslation_BufferQueue) {
Chia-I Wu04dcca82017-11-02 08:30:27 -07001615 sp<SurfaceControl> layer;
1616 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -07001617 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32));
Chia-I Wu04dcca82017-11-02 08:30:27 -07001618
1619 const Point position(32, 32);
1620 const Rect crop(8, 8, 24, 24);
Marissa Wallf58c14b2018-07-24 10:50:43 -07001621 Transaction().setPosition(layer, position.x, position.y).setCrop_legacy(layer, crop).apply();
Chia-I Wu04dcca82017-11-02 08:30:27 -07001622 auto shot = screenshot();
1623 shot->expectColor(crop + position, Color::RED);
1624 shot->expectBorder(crop + position, Color::BLACK);
1625}
1626
Marissa Wall61c58622018-07-18 10:12:20 -07001627TEST_F(LayerTransactionTest, SetCropWithTranslation_BufferState) {
1628 sp<SurfaceControl> layer;
1629 ASSERT_NO_FATAL_FAILURE(
1630 layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
1631 ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32));
1632
1633 const Point position(32, 32);
1634 const Rect crop(8, 8, 24, 24);
1635 Transaction().setPosition(layer, position.x, position.y).setCrop(layer, crop).apply();
1636 auto shot = screenshot();
1637 shot->expectColor(crop + position, Color::RED);
1638 shot->expectBorder(crop + position, Color::BLACK);
1639}
1640
1641TEST_F(LayerTransactionTest, SetCropWithScale_BufferQueue) {
Chia-I Wu04dcca82017-11-02 08:30:27 -07001642 sp<SurfaceControl> layer;
1643 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -07001644 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32));
Chia-I Wu04dcca82017-11-02 08:30:27 -07001645
1646 // crop is affected by matrix
1647 Transaction()
1648 .setMatrix(layer, 2.0f, 0.0f, 0.0f, 2.0f)
Marissa Wallf58c14b2018-07-24 10:50:43 -07001649 .setCrop_legacy(layer, Rect(8, 8, 24, 24))
Chia-I Wu04dcca82017-11-02 08:30:27 -07001650 .apply();
1651 auto shot = screenshot();
1652 shot->expectColor(Rect(16, 16, 48, 48), Color::RED);
1653 shot->expectBorder(Rect(16, 16, 48, 48), Color::BLACK);
1654}
1655
Marissa Wall61c58622018-07-18 10:12:20 -07001656TEST_F(LayerTransactionTest, SetCropWithScale_BufferState) {
1657 sp<SurfaceControl> layer;
1658 ASSERT_NO_FATAL_FAILURE(
1659 layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
1660 ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32));
1661
1662 // crop is affected by matrix
1663 Transaction()
1664 .setMatrix(layer, 2.0f, 0.0f, 0.0f, 2.0f)
1665 .setCrop(layer, Rect(8, 8, 24, 24))
1666 .apply();
1667 auto shot = screenshot();
1668 shot->expectColor(Rect(16, 16, 48, 48), Color::RED);
1669 shot->expectBorder(Rect(16, 16, 48, 48), Color::BLACK);
1670}
1671
1672TEST_F(LayerTransactionTest, SetCropWithResize_BufferQueue) {
Chia-I Wu04dcca82017-11-02 08:30:27 -07001673 sp<SurfaceControl> layer;
1674 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -07001675 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32));
Chia-I Wu04dcca82017-11-02 08:30:27 -07001676
Marissa Wallf58c14b2018-07-24 10:50:43 -07001677 // setCrop_legacy is applied immediately by default, with or without resize pending
1678 Transaction().setCrop_legacy(layer, Rect(8, 8, 24, 24)).setSize(layer, 16, 16).apply();
Chia-I Wu04dcca82017-11-02 08:30:27 -07001679 {
1680 SCOPED_TRACE("resize pending");
1681 auto shot = screenshot();
1682 shot->expectColor(Rect(8, 8, 24, 24), Color::RED);
1683 shot->expectBorder(Rect(8, 8, 24, 24), Color::BLACK);
1684 }
1685
Marissa Wall61c58622018-07-18 10:12:20 -07001686 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 16, 16));
Chia-I Wu04dcca82017-11-02 08:30:27 -07001687 {
1688 SCOPED_TRACE("resize applied");
1689 auto shot = screenshot();
1690 shot->expectColor(Rect(8, 8, 16, 16), Color::RED);
1691 shot->expectBorder(Rect(8, 8, 16, 16), Color::BLACK);
1692 }
1693}
1694
Marissa Wall61c58622018-07-18 10:12:20 -07001695TEST_F(LayerTransactionTest, SetCropWithResize_BufferState) {
1696 sp<SurfaceControl> layer;
1697 ASSERT_NO_FATAL_FAILURE(
1698 layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
1699 ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32));
1700
1701 // setCrop_legacy is applied immediately by default, with or without resize pending
1702 Transaction().setCrop(layer, Rect(8, 8, 24, 24)).setSize(layer, 16, 16).apply();
1703 {
1704 SCOPED_TRACE("new buffer pending");
1705 auto shot = screenshot();
1706 shot->expectColor(Rect(8, 8, 16, 16), Color::RED);
1707 shot->expectBorder(Rect(8, 8, 16, 16), Color::BLACK);
1708 }
1709
1710 ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 16, 16));
1711 {
1712 SCOPED_TRACE("new buffer");
1713 auto shot = screenshot();
1714 shot->expectColor(Rect(8, 8, 16, 16), Color::RED);
1715 shot->expectBorder(Rect(8, 8, 16, 16), Color::BLACK);
1716 }
1717}
1718
1719TEST_F(LayerTransactionTest, SetCropWithNextResize_BufferQueue) {
Chia-I Wu04dcca82017-11-02 08:30:27 -07001720 sp<SurfaceControl> layer;
1721 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -07001722 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32));
Chia-I Wu04dcca82017-11-02 08:30:27 -07001723
Marissa Wallf58c14b2018-07-24 10:50:43 -07001724 // request setCrop_legacy to be applied with the next resize
1725 Transaction()
1726 .setCrop_legacy(layer, Rect(8, 8, 24, 24))
1727 .setGeometryAppliesWithResize(layer)
1728 .apply();
Chia-I Wu04dcca82017-11-02 08:30:27 -07001729 {
1730 SCOPED_TRACE("waiting for next resize");
1731 screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
1732 }
1733
Marissa Wallf58c14b2018-07-24 10:50:43 -07001734 Transaction().setCrop_legacy(layer, Rect(4, 4, 12, 12)).apply();
Chia-I Wu04dcca82017-11-02 08:30:27 -07001735 {
1736 SCOPED_TRACE("pending crop modified");
1737 screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
1738 }
1739
1740 Transaction().setSize(layer, 16, 16).apply();
1741 {
1742 SCOPED_TRACE("resize pending");
1743 screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
1744 }
1745
1746 // finally resize
Marissa Wall61c58622018-07-18 10:12:20 -07001747 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 16, 16));
Chia-I Wu04dcca82017-11-02 08:30:27 -07001748 {
1749 SCOPED_TRACE("new crop applied");
1750 auto shot = screenshot();
1751 shot->expectColor(Rect(4, 4, 12, 12), Color::RED);
1752 shot->expectBorder(Rect(4, 4, 12, 12), Color::BLACK);
1753 }
1754}
1755
Marissa Wall61c58622018-07-18 10:12:20 -07001756TEST_F(LayerTransactionTest, SetCropWithNextResize_BufferState) {
1757 sp<SurfaceControl> layer;
1758 ASSERT_NO_FATAL_FAILURE(
1759 layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
1760 ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32));
1761
1762 // request setCrop_legacy to be applied with the next resize
1763 Transaction().setCrop(layer, Rect(8, 8, 24, 24)).setGeometryAppliesWithResize(layer).apply();
1764 {
1765 SCOPED_TRACE("set crop 1");
1766 screenshot()->expectColor(Rect(8, 8, 24, 24), Color::RED);
1767 }
1768
1769 Transaction().setCrop(layer, Rect(4, 4, 12, 12)).apply();
1770 {
1771 SCOPED_TRACE("set crop 2");
1772 screenshot()->expectColor(Rect(4, 4, 12, 12), Color::RED);
1773 }
1774
1775 Transaction().setSize(layer, 16, 16).apply();
1776 {
1777 SCOPED_TRACE("resize");
1778 screenshot()->expectColor(Rect(4, 4, 12, 12), Color::RED);
1779 }
1780
1781 // finally resize
1782 ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 16, 16));
1783 {
1784 SCOPED_TRACE("new buffer");
1785 auto shot = screenshot();
1786 shot->expectColor(Rect(4, 4, 12, 12), Color::RED);
1787 shot->expectBorder(Rect(4, 4, 12, 12), Color::BLACK);
1788 }
1789}
1790
1791TEST_F(LayerTransactionTest, SetCropWithNextResizeScaleToWindow_BufferQueue) {
Chia-I Wu04dcca82017-11-02 08:30:27 -07001792 sp<SurfaceControl> layer;
1793 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
Marissa Wall61c58622018-07-18 10:12:20 -07001794 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32));
Chia-I Wu04dcca82017-11-02 08:30:27 -07001795
Marissa Wallf58c14b2018-07-24 10:50:43 -07001796 // setCrop_legacy is not immediate even with SCALE_TO_WINDOW override
Chia-I Wu04dcca82017-11-02 08:30:27 -07001797 Transaction()
Marissa Wallf58c14b2018-07-24 10:50:43 -07001798 .setCrop_legacy(layer, Rect(4, 4, 12, 12))
Chia-I Wu04dcca82017-11-02 08:30:27 -07001799 .setSize(layer, 16, 16)
1800 .setOverrideScalingMode(layer, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW)
1801 .setGeometryAppliesWithResize(layer)
1802 .apply();
1803 {
1804 SCOPED_TRACE("new crop pending");
1805 auto shot = screenshot();
1806 shot->expectColor(Rect(0, 0, 16, 16), Color::RED);
1807 shot->expectBorder(Rect(0, 0, 16, 16), Color::BLACK);
1808 }
1809
1810 // XXX crop is never latched without other geometry change (b/69315677)
1811 Transaction().setPosition(layer, 1, 0).setGeometryAppliesWithResize(layer).apply();
Marissa Wall61c58622018-07-18 10:12:20 -07001812 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 16, 16));
Chia-I Wu04dcca82017-11-02 08:30:27 -07001813 Transaction().setPosition(layer, 0, 0).apply();
1814 {
1815 SCOPED_TRACE("new crop applied");
1816 auto shot = screenshot();
1817 shot->expectColor(Rect(4, 4, 12, 12), Color::RED);
1818 shot->expectBorder(Rect(4, 4, 12, 12), Color::BLACK);
1819 }
1820}
1821
Marissa Wall61c58622018-07-18 10:12:20 -07001822TEST_F(LayerTransactionTest, SetCropWithNextResizeScaleToWindow_BufferState) {
1823 sp<SurfaceControl> layer;
1824 ASSERT_NO_FATAL_FAILURE(
1825 layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
1826 ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32));
1827
1828 // all properties are applied immediate so setGeometryAppliesWithResize has no effect
1829 Transaction()
1830 .setCrop(layer, Rect(4, 4, 12, 12))
1831 .setSize(layer, 16, 16)
1832 .setOverrideScalingMode(layer, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW)
1833 .setGeometryAppliesWithResize(layer)
1834 .apply();
1835 {
1836 SCOPED_TRACE("new crop pending");
1837 auto shot = screenshot();
1838 shot->expectColor(Rect(4, 4, 12, 12), Color::RED);
1839 shot->expectBorder(Rect(4, 4, 12, 12), Color::BLACK);
1840 }
1841
1842 Transaction().setPosition(layer, 1, 0).setGeometryAppliesWithResize(layer).apply();
1843 ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 16, 16));
1844 Transaction().setPosition(layer, 0, 0).apply();
1845 {
1846 SCOPED_TRACE("new crop applied");
1847 auto shot = screenshot();
1848 shot->expectColor(Rect(4, 4, 12, 12), Color::RED);
1849 shot->expectBorder(Rect(4, 4, 12, 12), Color::BLACK);
1850 }
1851}
1852
Marissa Wall61c58622018-07-18 10:12:20 -07001853TEST_F(LayerTransactionTest, SetBufferBasic_BufferState) {
1854 sp<SurfaceControl> layer;
1855 ASSERT_NO_FATAL_FAILURE(
1856 layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
1857
1858 ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32));
1859
1860 auto shot = screenshot();
1861 shot->expectColor(Rect(0, 0, 32, 32), Color::RED);
1862 shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
1863}
1864
1865TEST_F(LayerTransactionTest, SetBufferMultipleBuffers_BufferState) {
1866 sp<SurfaceControl> layer;
1867 ASSERT_NO_FATAL_FAILURE(
1868 layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
1869
1870 ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32));
1871
1872 {
1873 SCOPED_TRACE("set buffer 1");
1874 auto shot = screenshot();
1875 shot->expectColor(Rect(0, 0, 32, 32), Color::RED);
1876 shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
1877 }
1878
1879 ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::BLUE, 32, 32));
1880
1881 {
1882 SCOPED_TRACE("set buffer 2");
1883 auto shot = screenshot();
1884 shot->expectColor(Rect(0, 0, 32, 32), Color::BLUE);
1885 shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
1886 }
1887
1888 ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32));
1889
1890 {
1891 SCOPED_TRACE("set buffer 3");
1892 auto shot = screenshot();
1893 shot->expectColor(Rect(0, 0, 32, 32), Color::RED);
1894 shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
1895 }
1896}
1897
1898TEST_F(LayerTransactionTest, SetBufferMultipleLayers_BufferState) {
1899 sp<SurfaceControl> layer1;
1900 ASSERT_NO_FATAL_FAILURE(
1901 layer1 = createLayer("test", 64, 64, ISurfaceComposerClient::eFXSurfaceBufferState));
1902
1903 sp<SurfaceControl> layer2;
1904 ASSERT_NO_FATAL_FAILURE(
1905 layer2 = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
1906
1907 ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer1, Color::RED, 64, 64));
1908
1909 {
1910 SCOPED_TRACE("set layer 1 buffer red");
1911 auto shot = screenshot();
1912 shot->expectColor(Rect(0, 0, 64, 64), Color::RED);
1913 }
1914
1915 ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer2, Color::BLUE, 32, 32));
1916
1917 {
1918 SCOPED_TRACE("set layer 2 buffer blue");
1919 auto shot = screenshot();
1920 shot->expectColor(Rect(0, 0, 32, 32), Color::BLUE);
1921 shot->expectColor(Rect(0, 32, 64, 64), Color::RED);
1922 shot->expectColor(Rect(0, 32, 32, 64), Color::RED);
1923 }
1924
1925 ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer1, Color::GREEN, 64, 64));
1926 {
1927 SCOPED_TRACE("set layer 1 buffer green");
1928 auto shot = screenshot();
1929 shot->expectColor(Rect(0, 0, 32, 32), Color::BLUE);
1930 shot->expectColor(Rect(0, 32, 64, 64), Color::GREEN);
1931 shot->expectColor(Rect(0, 32, 32, 64), Color::GREEN);
1932 }
1933
1934 ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer2, Color::WHITE, 32, 32));
1935
1936 {
1937 SCOPED_TRACE("set layer 2 buffer white");
1938 auto shot = screenshot();
1939 shot->expectColor(Rect(0, 0, 32, 32), Color::WHITE);
1940 shot->expectColor(Rect(0, 32, 64, 64), Color::GREEN);
1941 shot->expectColor(Rect(0, 32, 32, 64), Color::GREEN);
1942 }
1943}
1944
1945TEST_F(LayerTransactionTest, SetTransformRotate90_BufferState) {
1946 sp<SurfaceControl> layer;
1947 ASSERT_NO_FATAL_FAILURE(
1948 layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
1949
1950 ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerQuadrant(layer, 32, 32, Color::RED, Color::GREEN,
1951 Color::BLUE, Color::WHITE));
1952
1953 Transaction().setTransform(layer, NATIVE_WINDOW_TRANSFORM_ROT_90).apply();
1954
1955 screenshot()->expectQuadrant(Rect(0, 0, 32, 32), Color::BLUE, Color::RED, Color::WHITE,
1956 Color::GREEN, true /* filtered */);
1957}
1958
1959TEST_F(LayerTransactionTest, SetTransformFlipH_BufferState) {
1960 sp<SurfaceControl> layer;
1961 ASSERT_NO_FATAL_FAILURE(
1962 layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
1963
1964 ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerQuadrant(layer, 32, 32, Color::RED, Color::GREEN,
1965 Color::BLUE, Color::WHITE));
1966
1967 Transaction().setTransform(layer, NATIVE_WINDOW_TRANSFORM_FLIP_H).apply();
1968
1969 screenshot()->expectQuadrant(Rect(0, 0, 32, 32), Color::GREEN, Color::RED, Color::WHITE,
1970 Color::BLUE, true /* filtered */);
1971}
1972
1973TEST_F(LayerTransactionTest, SetTransformFlipV_BufferState) {
1974 sp<SurfaceControl> layer;
1975 ASSERT_NO_FATAL_FAILURE(
1976 layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
1977
1978 ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerQuadrant(layer, 32, 32, Color::RED, Color::GREEN,
1979 Color::BLUE, Color::WHITE));
1980
1981 Transaction().setTransform(layer, NATIVE_WINDOW_TRANSFORM_FLIP_V).apply();
1982
1983 screenshot()->expectQuadrant(Rect(0, 0, 32, 32), Color::BLUE, Color::WHITE, Color::RED,
1984 Color::GREEN, true /* filtered */);
1985}
1986
1987TEST_F(LayerTransactionTest, SetTransformToDisplayInverse_BufferState) {
1988 sp<SurfaceControl> layer;
1989 ASSERT_NO_FATAL_FAILURE(
1990 layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
1991
1992 Transaction().setTransformToDisplayInverse(layer, false).apply();
1993
1994 ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::GREEN, 32, 32));
1995
1996 Transaction().setTransformToDisplayInverse(layer, true).apply();
1997}
1998
1999TEST_F(LayerTransactionTest, SetFenceBasic_BufferState) {
2000 sp<SurfaceControl> layer;
2001 ASSERT_NO_FATAL_FAILURE(
2002 layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
2003
2004 sp<GraphicBuffer> buffer =
2005 new GraphicBuffer(32, 32, PIXEL_FORMAT_RGBA_8888, 1,
2006 BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
2007 BufferUsage::COMPOSER_OVERLAY,
2008 "test");
2009 fillGraphicBufferColor(buffer, Rect(0, 0, 32, 32), Color::RED);
2010
Marissa Wallfda30bb2018-10-12 11:34:28 -07002011 sp<Fence> fence = Fence::NO_FENCE;
Marissa Wall61c58622018-07-18 10:12:20 -07002012
2013 Transaction()
2014 .setBuffer(layer, buffer)
2015 .setAcquireFence(layer, fence)
2016 .setSize(layer, 32, 32)
2017 .apply();
2018
2019 auto shot = screenshot();
2020 shot->expectColor(Rect(0, 0, 32, 32), Color::RED);
2021 shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
2022}
2023
2024TEST_F(LayerTransactionTest, SetDataspaceBasic_BufferState) {
2025 sp<SurfaceControl> layer;
2026 ASSERT_NO_FATAL_FAILURE(
2027 layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
2028
2029 sp<GraphicBuffer> buffer =
2030 new GraphicBuffer(32, 32, PIXEL_FORMAT_RGBA_8888, 1,
2031 BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
2032 BufferUsage::COMPOSER_OVERLAY,
2033 "test");
2034 fillGraphicBufferColor(buffer, Rect(0, 0, 32, 32), Color::RED);
2035
2036 Transaction()
2037 .setBuffer(layer, buffer)
2038 .setDataspace(layer, ui::Dataspace::UNKNOWN)
2039 .setSize(layer, 32, 32)
2040 .apply();
2041
2042 auto shot = screenshot();
2043 shot->expectColor(Rect(0, 0, 32, 32), Color::RED);
2044 shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
2045}
2046
2047TEST_F(LayerTransactionTest, SetHdrMetadataBasic_BufferState) {
2048 sp<SurfaceControl> layer;
2049 ASSERT_NO_FATAL_FAILURE(
2050 layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
2051
2052 sp<GraphicBuffer> buffer =
2053 new GraphicBuffer(32, 32, PIXEL_FORMAT_RGBA_8888, 1,
2054 BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
2055 BufferUsage::COMPOSER_OVERLAY,
2056 "test");
2057 fillGraphicBufferColor(buffer, Rect(0, 0, 32, 32), Color::RED);
2058
2059 HdrMetadata hdrMetadata;
2060 hdrMetadata.validTypes = 0;
2061 Transaction()
2062 .setBuffer(layer, buffer)
2063 .setHdrMetadata(layer, hdrMetadata)
2064 .setSize(layer, 32, 32)
2065 .apply();
2066
2067 auto shot = screenshot();
2068 shot->expectColor(Rect(0, 0, 32, 32), Color::RED);
2069 shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
2070}
2071
2072TEST_F(LayerTransactionTest, SetSurfaceDamageRegionBasic_BufferState) {
2073 sp<SurfaceControl> layer;
2074 ASSERT_NO_FATAL_FAILURE(
2075 layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
2076
2077 sp<GraphicBuffer> buffer =
2078 new GraphicBuffer(32, 32, PIXEL_FORMAT_RGBA_8888, 1,
2079 BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
2080 BufferUsage::COMPOSER_OVERLAY,
2081 "test");
2082 fillGraphicBufferColor(buffer, Rect(0, 0, 32, 32), Color::RED);
2083
2084 Region region;
2085 region.set(32, 32);
2086 Transaction()
2087 .setBuffer(layer, buffer)
2088 .setSurfaceDamageRegion(layer, region)
2089 .setSize(layer, 32, 32)
2090 .apply();
2091
2092 auto shot = screenshot();
2093 shot->expectColor(Rect(0, 0, 32, 32), Color::RED);
2094 shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
2095}
2096
2097TEST_F(LayerTransactionTest, SetApiBasic_BufferState) {
2098 sp<SurfaceControl> layer;
2099 ASSERT_NO_FATAL_FAILURE(
2100 layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
2101
2102 sp<GraphicBuffer> buffer =
2103 new GraphicBuffer(32, 32, PIXEL_FORMAT_RGBA_8888, 1,
2104 BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
2105 BufferUsage::COMPOSER_OVERLAY,
2106 "test");
2107 fillGraphicBufferColor(buffer, Rect(0, 0, 32, 32), Color::RED);
2108
2109 Transaction()
2110 .setBuffer(layer, buffer)
2111 .setApi(layer, NATIVE_WINDOW_API_CPU)
2112 .setSize(layer, 32, 32)
2113 .apply();
2114
2115 auto shot = screenshot();
2116 shot->expectColor(Rect(0, 0, 32, 32), Color::RED);
2117 shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
2118}
2119
2120TEST_F(LayerTransactionTest, SetSidebandStreamNull_BufferState) {
2121 sp<SurfaceControl> layer;
2122 ASSERT_NO_FATAL_FAILURE(
2123 layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
2124
2125 // verify this doesn't cause a crash
2126 Transaction().setSidebandStream(layer, nullptr).apply();
2127}
2128
Ady Abraham2a6ab2a2018-10-26 14:25:30 -07002129class ColorTransformHelper {
2130public:
2131 static void DegammaColorSingle(half& s) {
2132 if (s <= 0.03928f)
2133 s = s / 12.92f;
2134 else
2135 s = pow((s + 0.055f) / 1.055f, 2.4f);
2136 }
2137
2138 static void DegammaColor(half3& color) {
2139 DegammaColorSingle(color.r);
2140 DegammaColorSingle(color.g);
2141 DegammaColorSingle(color.b);
2142 }
2143
2144 static void GammaColorSingle(half& s) {
2145 if (s <= 0.0031308f) {
2146 s = s * 12.92f;
2147 } else {
2148 s = 1.055f * pow(s, (1.0f / 2.4f)) - 0.055f;
2149 }
2150 }
2151
2152 static void GammaColor(half3& color) {
2153 GammaColorSingle(color.r);
2154 GammaColorSingle(color.g);
2155 GammaColorSingle(color.b);
2156 }
2157
2158 static void applyMatrix(half3& color, const mat3& mat) {
2159 half3 ret = half3(0);
2160
2161 for (int i = 0; i < 3; i++) {
2162 for (int j = 0; j < 3; j++) {
2163 ret[i] = ret[i] + color[j] * mat[j][i];
2164 }
2165 }
2166 color = ret;
2167 }
2168};
2169
Peiyong Lind3788632018-09-18 16:01:31 -07002170TEST_F(LayerTransactionTest, SetColorTransformBasic) {
2171 sp<SurfaceControl> colorLayer;
Vishnu Nair88a11f22018-11-28 18:30:57 -08002172 ASSERT_NO_FATAL_FAILURE(colorLayer =
2173 createLayer("test", 0 /* buffer width */, 0 /* buffer height */,
2174 ISurfaceComposerClient::eFXSurfaceColor));
2175 Transaction()
2176 .setCrop_legacy(colorLayer, Rect(0, 0, 32, 32))
2177 .setLayer(colorLayer, mLayerZBase + 1)
2178 .apply();
Peiyong Lind3788632018-09-18 16:01:31 -07002179 {
2180 SCOPED_TRACE("default color");
2181 screenshot()->expectColor(Rect(0, 0, 32, 32), Color::BLACK);
2182 }
2183
2184 const half3 color(50.0f / 255.0f, 100.0f / 255.0f, 150.0f / 255.0f);
Ady Abraham2a6ab2a2018-10-26 14:25:30 -07002185 half3 expected = color;
Peiyong Lind3788632018-09-18 16:01:31 -07002186 mat3 matrix;
2187 matrix[0][0] = 0.3; matrix[1][0] = 0.59; matrix[2][0] = 0.11;
2188 matrix[0][1] = 0.3; matrix[1][1] = 0.59; matrix[2][1] = 0.11;
2189 matrix[0][2] = 0.3; matrix[1][2] = 0.59; matrix[2][2] = 0.11;
Ady Abraham2a6ab2a2018-10-26 14:25:30 -07002190
2191 // degamma before applying the matrix
2192 if (mColorManagementUsed) {
2193 ColorTransformHelper::DegammaColor(expected);
2194 }
2195
2196 ColorTransformHelper::applyMatrix(expected, matrix);
2197
2198 if (mColorManagementUsed) {
2199 ColorTransformHelper::GammaColor(expected);
2200 }
2201
2202 const Color expectedColor = {uint8_t(expected.r * 255), uint8_t(expected.g * 255),
2203 uint8_t(expected.b * 255), 255};
2204
2205 // this is handwavy, but the precison loss scaled by 255 (8-bit per
2206 // channel) should be less than one
2207 const uint8_t tolerance = 1;
2208
Peiyong Lind3788632018-09-18 16:01:31 -07002209 Transaction().setColor(colorLayer, color)
2210 .setColorTransform(colorLayer, matrix, vec3()).apply();
2211 {
2212 SCOPED_TRACE("new color");
Ady Abraham2a6ab2a2018-10-26 14:25:30 -07002213 screenshot()->expectColor(Rect(0, 0, 32, 32), expectedColor, tolerance);
Peiyong Lind3788632018-09-18 16:01:31 -07002214 }
2215}
2216
chaviwf66724d2018-11-28 16:35:21 -08002217TEST_F(LayerTransactionTest, SetColorTransformOnParent) {
2218 sp<SurfaceControl> parentLayer;
2219 sp<SurfaceControl> colorLayer;
2220 ASSERT_NO_FATAL_FAILURE(parentLayer = createLayer("parent", 0 /* buffer width */,
2221 0 /* buffer height */,
2222 ISurfaceComposerClient::eFXSurfaceContainer));
2223 ASSERT_NO_FATAL_FAILURE(
2224 colorLayer = createLayer("test", 0 /* buffer width */, 0 /* buffer height */,
2225 ISurfaceComposerClient::eFXSurfaceColor, parentLayer.get()));
2226
2227 Transaction()
2228 .setCrop_legacy(parentLayer, Rect(0, 0, 100, 100))
2229 .setCrop_legacy(colorLayer, Rect(0, 0, 32, 32))
2230 .setLayer(parentLayer, mLayerZBase + 1)
2231 .apply();
2232 {
2233 SCOPED_TRACE("default color");
2234 screenshot()->expectColor(Rect(0, 0, 32, 32), Color::BLACK);
2235 }
2236
2237 const half3 color(50.0f / 255.0f, 100.0f / 255.0f, 150.0f / 255.0f);
2238 half3 expected = color;
2239 mat3 matrix;
2240 matrix[0][0] = 0.3; matrix[1][0] = 0.59; matrix[2][0] = 0.11;
2241 matrix[0][1] = 0.3; matrix[1][1] = 0.59; matrix[2][1] = 0.11;
2242 matrix[0][2] = 0.3; matrix[1][2] = 0.59; matrix[2][2] = 0.11;
2243
2244 // degamma before applying the matrix
2245 if (mColorManagementUsed) {
2246 ColorTransformHelper::DegammaColor(expected);
2247 }
2248
2249 ColorTransformHelper::applyMatrix(expected, matrix);
2250
2251 if (mColorManagementUsed) {
2252 ColorTransformHelper::GammaColor(expected);
2253 }
2254
2255 const Color expectedColor = {uint8_t(expected.r * 255), uint8_t(expected.g * 255),
2256 uint8_t(expected.b * 255), 255};
2257
2258 // this is handwavy, but the precison loss scaled by 255 (8-bit per
2259 // channel) should be less than one
2260 const uint8_t tolerance = 1;
2261
2262 Transaction()
2263 .setColor(colorLayer, color)
2264 .setColorTransform(parentLayer, matrix, vec3())
2265 .apply();
2266 {
2267 SCOPED_TRACE("new color");
2268 screenshot()->expectColor(Rect(0, 0, 32, 32), expectedColor, tolerance);
2269 }
2270}
2271
2272TEST_F(LayerTransactionTest, SetColorTransformOnChildAndParent) {
2273 sp<SurfaceControl> parentLayer;
2274 sp<SurfaceControl> colorLayer;
2275 ASSERT_NO_FATAL_FAILURE(parentLayer = createLayer("parent", 0 /* buffer width */,
2276 0 /* buffer height */,
2277 ISurfaceComposerClient::eFXSurfaceContainer));
2278 ASSERT_NO_FATAL_FAILURE(
2279 colorLayer = createLayer("test", 0 /* buffer width */, 0 /* buffer height */,
2280 ISurfaceComposerClient::eFXSurfaceColor, parentLayer.get()));
2281
2282 Transaction()
2283 .setCrop_legacy(parentLayer, Rect(0, 0, 100, 100))
2284 .setCrop_legacy(colorLayer, Rect(0, 0, 32, 32))
2285 .setLayer(parentLayer, mLayerZBase + 1)
2286 .apply();
2287 {
2288 SCOPED_TRACE("default color");
2289 screenshot()->expectColor(Rect(0, 0, 32, 32), Color::BLACK);
2290 }
2291
2292 const half3 color(50.0f / 255.0f, 100.0f / 255.0f, 150.0f / 255.0f);
2293 half3 expected = color;
2294 mat3 matrixChild;
2295 matrixChild[0][0] = 0.3; matrixChild[1][0] = 0.59; matrixChild[2][0] = 0.11;
2296 matrixChild[0][1] = 0.3; matrixChild[1][1] = 0.59; matrixChild[2][1] = 0.11;
2297 matrixChild[0][2] = 0.3; matrixChild[1][2] = 0.59; matrixChild[2][2] = 0.11;
2298 mat3 matrixParent;
2299 matrixParent[0][0] = 0.2; matrixParent[1][0] = 0.4; matrixParent[2][0] = 0.10;
2300 matrixParent[0][1] = 0.2; matrixParent[1][1] = 0.4; matrixParent[2][1] = 0.10;
2301 matrixParent[0][2] = 0.2; matrixParent[1][2] = 0.4; matrixParent[2][2] = 0.10;
2302
2303 // degamma before applying the matrix
2304 if (mColorManagementUsed) {
2305 ColorTransformHelper::DegammaColor(expected);
2306 }
2307
2308 ColorTransformHelper::applyMatrix(expected, matrixChild);
2309 ColorTransformHelper::applyMatrix(expected, matrixParent);
2310
2311 if (mColorManagementUsed) {
2312 ColorTransformHelper::GammaColor(expected);
2313 }
2314
2315 const Color expectedColor = {uint8_t(expected.r * 255), uint8_t(expected.g * 255),
2316 uint8_t(expected.b * 255), 255};
2317
2318 // this is handwavy, but the precison loss scaled by 255 (8-bit per
2319 // channel) should be less than one
2320 const uint8_t tolerance = 1;
2321
2322 Transaction()
2323 .setColor(colorLayer, color)
2324 .setColorTransform(parentLayer, matrixParent, vec3())
2325 .setColorTransform(colorLayer, matrixChild, vec3())
2326 .apply();
2327 {
2328 SCOPED_TRACE("new color");
2329 screenshot()->expectColor(Rect(0, 0, 32, 32), expectedColor, tolerance);
2330 }
2331}
2332
Marissa Wallfda30bb2018-10-12 11:34:28 -07002333class ExpectedResult {
2334public:
2335 enum Transaction {
2336 NOT_PRESENTED = 0,
2337 PRESENTED,
2338 };
2339
2340 enum Buffer {
2341 NOT_ACQUIRED = 0,
2342 ACQUIRED,
2343 };
2344
2345 enum PreviousBuffer {
2346 NOT_RELEASED = 0,
2347 RELEASED,
2348 };
2349
2350 void reset() {
2351 mTransactionResult = ExpectedResult::Transaction::NOT_PRESENTED;
2352 mExpectedSurfaceResults.clear();
2353 }
2354
2355 void addSurface(ExpectedResult::Transaction transactionResult, const sp<SurfaceControl>& layer,
2356 ExpectedResult::Buffer bufferResult = NOT_ACQUIRED,
2357 ExpectedResult::PreviousBuffer previousBufferResult = NOT_RELEASED) {
2358 mTransactionResult = transactionResult;
2359 mExpectedSurfaceResults.emplace(std::piecewise_construct,
2360 std::forward_as_tuple(layer->getHandle()),
2361 std::forward_as_tuple(bufferResult, previousBufferResult));
2362 }
2363
2364 void addSurfaces(ExpectedResult::Transaction transactionResult,
2365 const std::vector<sp<SurfaceControl>>& layers,
2366 ExpectedResult::Buffer bufferResult = NOT_ACQUIRED,
2367 ExpectedResult::PreviousBuffer previousBufferResult = NOT_RELEASED) {
2368 for (const auto& layer : layers) {
2369 addSurface(transactionResult, layer, bufferResult, previousBufferResult);
2370 }
2371 }
2372
2373 void verifyTransactionStats(const TransactionStats& transactionStats) const {
2374 const auto& [latchTime, presentTime, surfaceStats] = transactionStats;
2375 if (mTransactionResult == ExpectedResult::Transaction::PRESENTED) {
2376 ASSERT_GE(latchTime, 0) << "bad latch time";
2377 ASSERT_GE(presentTime, 0) << "bad present time";
2378 } else {
2379 ASSERT_EQ(presentTime, -1) << "transaction shouldn't have been presented";
2380 ASSERT_EQ(latchTime, -1) << "unpresented transactions shouldn't be latched";
2381 }
2382
2383 ASSERT_EQ(surfaceStats.size(), mExpectedSurfaceResults.size())
2384 << "wrong number of surfaces";
2385
2386 for (const auto& stats : surfaceStats) {
2387 const auto& expectedSurfaceResult = mExpectedSurfaceResults.find(stats.surfaceControl);
2388 ASSERT_NE(expectedSurfaceResult, mExpectedSurfaceResults.end())
2389 << "unexpected surface control";
2390 expectedSurfaceResult->second.verifySurfaceStats(stats, latchTime);
2391 }
2392 }
2393
2394private:
2395 class ExpectedSurfaceResult {
2396 public:
2397 ExpectedSurfaceResult(ExpectedResult::Buffer bufferResult,
2398 ExpectedResult::PreviousBuffer previousBufferResult)
2399 : mBufferResult(bufferResult), mPreviousBufferResult(previousBufferResult) {}
2400
2401 void verifySurfaceStats(const SurfaceStats& surfaceStats, nsecs_t latchTime) const {
2402 const auto& [surfaceControl, acquireTime, releasePreviousBuffer] = surfaceStats;
2403
2404 ASSERT_EQ(acquireTime > 0, mBufferResult == ExpectedResult::Buffer::ACQUIRED)
2405 << "bad acquire time";
2406 ASSERT_LE(acquireTime, latchTime) << "acquire time should be <= latch time";
2407 ASSERT_EQ(releasePreviousBuffer,
2408 mPreviousBufferResult == ExpectedResult::PreviousBuffer::RELEASED)
2409 << "bad previous buffer released";
2410 }
2411
2412 private:
2413 ExpectedResult::Buffer mBufferResult;
2414 ExpectedResult::PreviousBuffer mPreviousBufferResult;
2415 };
2416
2417 struct IBinderHash {
2418 std::size_t operator()(const sp<IBinder>& strongPointer) const {
2419 return std::hash<IBinder*>{}(strongPointer.get());
2420 }
2421 };
2422 ExpectedResult::Transaction mTransactionResult = ExpectedResult::Transaction::NOT_PRESENTED;
2423 std::unordered_map<sp<IBinder>, ExpectedSurfaceResult, IBinderHash> mExpectedSurfaceResults;
2424};
2425
2426class CallbackHelper {
2427public:
2428 static void function(void* callbackContext, const TransactionStats& transactionStats) {
2429 if (!callbackContext) {
2430 ALOGE("failed to get callback context");
2431 }
2432 CallbackHelper* helper = static_cast<CallbackHelper*>(callbackContext);
2433 std::lock_guard lock(helper->mMutex);
2434 helper->mTransactionStatsQueue.push(transactionStats);
2435 helper->mConditionVariable.notify_all();
2436 }
2437
2438 void getTransactionStats(TransactionStats* outStats) {
2439 std::unique_lock lock(mMutex);
2440
2441 if (mTransactionStatsQueue.empty()) {
2442 ASSERT_NE(mConditionVariable.wait_for(lock, std::chrono::seconds(3)),
2443 std::cv_status::timeout)
2444 << "did not receive callback";
2445 }
2446
2447 *outStats = std::move(mTransactionStatsQueue.front());
2448 mTransactionStatsQueue.pop();
2449 }
2450
2451 void verifyFinalState() {
2452 // Wait to see if there are extra callbacks
2453 std::this_thread::sleep_for(500ms);
2454
2455 std::lock_guard lock(mMutex);
2456 EXPECT_EQ(mTransactionStatsQueue.size(), 0) << "extra callbacks received";
2457 mTransactionStatsQueue = {};
2458 }
2459
2460 void* getContext() { return static_cast<void*>(this); }
2461
2462 std::mutex mMutex;
2463 std::condition_variable mConditionVariable;
2464 std::queue<TransactionStats> mTransactionStatsQueue;
2465};
2466
2467class LayerCallbackTest : public LayerTransactionTest {
2468protected:
2469 virtual sp<SurfaceControl> createBufferStateLayer() {
2470 return createLayer(mClient, "test", mWidth, mHeight,
2471 ISurfaceComposerClient::eFXSurfaceBufferState);
2472 }
2473
2474 virtual void fillTransaction(Transaction& transaction, CallbackHelper* callbackHelper,
2475 const sp<SurfaceControl>& layer = nullptr) {
2476 if (layer) {
2477 sp<GraphicBuffer> buffer =
2478 new GraphicBuffer(mWidth, mHeight, PIXEL_FORMAT_RGBA_8888, 1,
2479 BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
2480 BufferUsage::COMPOSER_OVERLAY |
2481 BufferUsage::GPU_TEXTURE,
2482 "test");
2483 fillGraphicBufferColor(buffer, Rect(0, 0, mWidth, mHeight), Color::RED);
2484
2485 sp<Fence> fence = new Fence(-1);
2486
2487 transaction.setBuffer(layer, buffer)
2488 .setAcquireFence(layer, fence)
2489 .setSize(layer, mWidth, mHeight);
2490 }
2491
2492 transaction.addTransactionCompletedCallback(callbackHelper->function,
2493 callbackHelper->getContext());
2494 }
2495
2496 void waitForCallback(CallbackHelper& helper, const ExpectedResult& expectedResult,
2497 bool finalState = false) {
2498 TransactionStats transactionStats;
2499 ASSERT_NO_FATAL_FAILURE(helper.getTransactionStats(&transactionStats));
2500 EXPECT_NO_FATAL_FAILURE(expectedResult.verifyTransactionStats(transactionStats));
2501
2502 if (finalState) {
2503 ASSERT_NO_FATAL_FAILURE(helper.verifyFinalState());
2504 }
2505 }
2506
2507 void waitForCallbacks(CallbackHelper& helper,
2508 const std::vector<ExpectedResult>& expectedResults,
2509 bool finalState = false) {
2510 for (const auto& expectedResult : expectedResults) {
2511 waitForCallback(helper, expectedResult);
2512 }
2513 if (finalState) {
2514 ASSERT_NO_FATAL_FAILURE(helper.verifyFinalState());
2515 }
2516 }
2517
2518 uint32_t mWidth = 32;
2519 uint32_t mHeight = 32;
2520};
2521
2522TEST_F(LayerCallbackTest, Basic) {
2523 sp<SurfaceControl> layer;
2524 ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
2525
2526 Transaction transaction;
2527 CallbackHelper callback;
2528 fillTransaction(transaction, &callback, layer);
2529
2530 transaction.apply();
2531
2532 ExpectedResult expected;
2533 expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer);
2534 EXPECT_NO_FATAL_FAILURE(waitForCallback(callback, expected, true));
2535}
2536
2537TEST_F(LayerCallbackTest, NoBuffer) {
2538 sp<SurfaceControl> layer;
2539 ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
2540
2541 Transaction transaction;
2542 CallbackHelper callback;
2543 fillTransaction(transaction, &callback);
2544
2545 transaction.setPosition(layer, mWidth, mHeight).apply();
2546
2547 ExpectedResult expected;
2548 expected.addSurface(ExpectedResult::Transaction::NOT_PRESENTED, layer);
2549 EXPECT_NO_FATAL_FAILURE(waitForCallback(callback, expected, true));
2550}
2551
2552TEST_F(LayerCallbackTest, NoStateChange) {
2553 Transaction transaction;
2554 CallbackHelper callback;
2555 fillTransaction(transaction, &callback);
2556
2557 transaction.apply();
2558
2559 ExpectedResult expected;
2560 EXPECT_NO_FATAL_FAILURE(waitForCallback(callback, expected, true));
2561}
2562
2563TEST_F(LayerCallbackTest, OffScreen) {
2564 sp<SurfaceControl> layer;
2565 ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
2566
2567 Transaction transaction;
2568 CallbackHelper callback;
2569 fillTransaction(transaction, &callback, layer);
2570
2571 transaction.setPosition(layer, -100, -100).apply();
2572
2573 ExpectedResult expected;
2574 expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer);
2575 EXPECT_NO_FATAL_FAILURE(waitForCallback(callback, expected, true));
2576}
2577
2578TEST_F(LayerCallbackTest, Merge) {
2579 sp<SurfaceControl> layer1, layer2;
2580 ASSERT_NO_FATAL_FAILURE(layer1 = createBufferStateLayer());
2581 ASSERT_NO_FATAL_FAILURE(layer2 = createBufferStateLayer());
2582
2583 Transaction transaction1, transaction2;
2584 CallbackHelper callback1, callback2;
2585 fillTransaction(transaction1, &callback1, layer1);
2586 fillTransaction(transaction2, &callback2, layer2);
2587
2588 transaction2.setPosition(layer2, mWidth, mHeight).merge(std::move(transaction1)).apply();
2589
2590 ExpectedResult expected;
2591 expected.addSurfaces(ExpectedResult::Transaction::PRESENTED, {layer1, layer2});
2592 EXPECT_NO_FATAL_FAILURE(waitForCallback(callback1, expected, true));
2593 EXPECT_NO_FATAL_FAILURE(waitForCallback(callback2, expected, true));
2594}
2595
2596TEST_F(LayerCallbackTest, Merge_SameCallback) {
2597 sp<SurfaceControl> layer1, layer2;
2598 ASSERT_NO_FATAL_FAILURE(layer1 = createBufferStateLayer());
2599 ASSERT_NO_FATAL_FAILURE(layer2 = createBufferStateLayer());
2600
2601 Transaction transaction1, transaction2;
2602 CallbackHelper callback;
2603 fillTransaction(transaction1, &callback, layer1);
2604 fillTransaction(transaction2, &callback, layer2);
2605
2606 transaction2.merge(std::move(transaction1)).apply();
2607
2608 ExpectedResult expected;
2609 expected.addSurfaces(ExpectedResult::Transaction::PRESENTED, {layer1, layer2});
2610 EXPECT_NO_FATAL_FAILURE(waitForCallback(callback, expected));
2611 EXPECT_NO_FATAL_FAILURE(waitForCallback(callback, expected, true));
2612}
2613
2614TEST_F(LayerCallbackTest, Merge_SameLayer) {
2615 sp<SurfaceControl> layer;
2616 ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
2617
2618 Transaction transaction1, transaction2;
2619 CallbackHelper callback1, callback2;
2620 fillTransaction(transaction1, &callback1, layer);
2621 fillTransaction(transaction2, &callback2, layer);
2622
2623 transaction2.merge(std::move(transaction1)).apply();
2624
2625 ExpectedResult expected;
2626 expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer);
2627 EXPECT_NO_FATAL_FAILURE(waitForCallback(callback1, expected, true));
2628 EXPECT_NO_FATAL_FAILURE(waitForCallback(callback2, expected, true));
2629}
2630
2631TEST_F(LayerCallbackTest, Merge_SingleBuffer) {
2632 sp<SurfaceControl> layer1, layer2;
2633 ASSERT_NO_FATAL_FAILURE(layer1 = createBufferStateLayer());
2634 ASSERT_NO_FATAL_FAILURE(layer2 = createBufferStateLayer());
2635
2636 Transaction transaction1, transaction2;
2637 CallbackHelper callback1, callback2;
2638 fillTransaction(transaction1, &callback1, layer1);
2639 fillTransaction(transaction2, &callback2);
2640
2641 transaction2.setPosition(layer2, mWidth, mHeight).merge(std::move(transaction1)).apply();
2642
2643 ExpectedResult expected;
2644 expected.addSurfaces(ExpectedResult::Transaction::PRESENTED, {layer1, layer2});
2645 EXPECT_NO_FATAL_FAILURE(waitForCallback(callback1, expected, true));
2646 EXPECT_NO_FATAL_FAILURE(waitForCallback(callback2, expected, true));
2647}
2648
2649TEST_F(LayerCallbackTest, Merge_DifferentClients) {
2650 sp<SurfaceComposerClient> client1(new SurfaceComposerClient),
2651 client2(new SurfaceComposerClient);
2652
2653 ASSERT_EQ(NO_ERROR, client1->initCheck()) << "failed to create SurfaceComposerClient";
2654 ASSERT_EQ(NO_ERROR, client2->initCheck()) << "failed to create SurfaceComposerClient";
2655
2656 sp<SurfaceControl> layer1, layer2;
2657 ASSERT_NO_FATAL_FAILURE(layer1 = createLayer(client1, "test", mWidth, mHeight,
2658 ISurfaceComposerClient::eFXSurfaceBufferState));
2659 ASSERT_NO_FATAL_FAILURE(layer2 = createLayer(client2, "test", mWidth, mHeight,
2660 ISurfaceComposerClient::eFXSurfaceBufferState));
2661
2662 Transaction transaction1, transaction2;
2663 CallbackHelper callback1, callback2;
2664 fillTransaction(transaction1, &callback1, layer1);
2665 fillTransaction(transaction2, &callback2, layer2);
2666
2667 transaction2.setPosition(layer2, mWidth, mHeight).merge(std::move(transaction1)).apply();
2668
2669 ExpectedResult expected;
2670 expected.addSurfaces(ExpectedResult::Transaction::PRESENTED, {layer1, layer2});
2671 EXPECT_NO_FATAL_FAILURE(waitForCallback(callback1, expected, true));
2672 EXPECT_NO_FATAL_FAILURE(waitForCallback(callback2, expected, true));
2673}
2674
2675TEST_F(LayerCallbackTest, MultipleTransactions) {
2676 sp<SurfaceControl> layer;
2677 ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
2678
2679 Transaction transaction;
2680 CallbackHelper callback;
2681 for (size_t i = 0; i < 10; i++) {
2682 fillTransaction(transaction, &callback, layer);
2683
2684 transaction.apply();
2685
2686 ExpectedResult expected;
2687 expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
2688 ExpectedResult::Buffer::NOT_ACQUIRED,
2689 (i == 0) ? ExpectedResult::PreviousBuffer::NOT_RELEASED
2690 : ExpectedResult::PreviousBuffer::RELEASED);
2691 EXPECT_NO_FATAL_FAILURE(waitForCallback(callback, expected));
2692 }
2693 ASSERT_NO_FATAL_FAILURE(callback.verifyFinalState());
2694}
2695
2696TEST_F(LayerCallbackTest, MultipleTransactions_NoStateChange) {
2697 sp<SurfaceControl> layer;
2698 ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
2699
2700 Transaction transaction;
2701 CallbackHelper callback;
2702 for (size_t i = 0; i < 10; i++) {
2703 ExpectedResult expected;
2704
2705 if (i == 0) {
2706 fillTransaction(transaction, &callback, layer);
2707 expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer);
2708 } else {
2709 fillTransaction(transaction, &callback);
2710 }
2711
2712 transaction.apply();
2713
2714 EXPECT_NO_FATAL_FAILURE(waitForCallback(callback, expected));
2715 }
2716 ASSERT_NO_FATAL_FAILURE(callback.verifyFinalState());
2717}
2718
2719TEST_F(LayerCallbackTest, MultipleTransactions_SameStateChange) {
2720 sp<SurfaceControl> layer;
2721 ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
2722
2723 Transaction transaction;
2724 CallbackHelper callback;
2725 for (size_t i = 0; i < 10; i++) {
2726 if (i == 0) {
2727 fillTransaction(transaction, &callback, layer);
2728 } else {
2729 fillTransaction(transaction, &callback);
2730 }
2731
2732 transaction.setPosition(layer, mWidth, mHeight).apply();
2733
2734 ExpectedResult expected;
2735 expected.addSurface((i == 0) ? ExpectedResult::Transaction::PRESENTED
2736 : ExpectedResult::Transaction::NOT_PRESENTED,
2737 layer);
2738 EXPECT_NO_FATAL_FAILURE(waitForCallback(callback, expected, i == 0));
2739 }
2740 ASSERT_NO_FATAL_FAILURE(callback.verifyFinalState());
2741}
2742
2743TEST_F(LayerCallbackTest, MultipleTransactions_Merge) {
2744 sp<SurfaceControl> layer1, layer2;
2745 ASSERT_NO_FATAL_FAILURE(layer1 = createBufferStateLayer());
2746 ASSERT_NO_FATAL_FAILURE(layer2 = createBufferStateLayer());
2747
2748 Transaction transaction1, transaction2;
2749 CallbackHelper callback1, callback2;
2750 for (size_t i = 0; i < 10; i++) {
2751 fillTransaction(transaction1, &callback1, layer1);
2752 fillTransaction(transaction2, &callback2, layer2);
2753
2754 transaction2.setPosition(layer2, mWidth, mHeight).merge(std::move(transaction1)).apply();
2755
2756 ExpectedResult expected;
2757 expected.addSurfaces(ExpectedResult::Transaction::PRESENTED, {layer1, layer2},
2758 ExpectedResult::Buffer::NOT_ACQUIRED,
2759 (i == 0) ? ExpectedResult::PreviousBuffer::NOT_RELEASED
2760 : ExpectedResult::PreviousBuffer::RELEASED);
2761 EXPECT_NO_FATAL_FAILURE(waitForCallback(callback1, expected));
2762 EXPECT_NO_FATAL_FAILURE(waitForCallback(callback2, expected));
2763 }
2764 ASSERT_NO_FATAL_FAILURE(callback1.verifyFinalState());
2765 ASSERT_NO_FATAL_FAILURE(callback2.verifyFinalState());
2766}
2767
2768TEST_F(LayerCallbackTest, MultipleTransactions_Merge_DifferentClients) {
2769 sp<SurfaceComposerClient> client1(new SurfaceComposerClient),
2770 client2(new SurfaceComposerClient);
2771 ASSERT_EQ(NO_ERROR, client1->initCheck()) << "failed to create SurfaceComposerClient";
2772 ASSERT_EQ(NO_ERROR, client2->initCheck()) << "failed to create SurfaceComposerClient";
2773
2774 sp<SurfaceControl> layer1, layer2;
2775 ASSERT_NO_FATAL_FAILURE(layer1 = createLayer(client1, "test", mWidth, mHeight,
2776 ISurfaceComposerClient::eFXSurfaceBufferState));
2777 ASSERT_NO_FATAL_FAILURE(layer2 = createLayer(client2, "test", mWidth, mHeight,
2778 ISurfaceComposerClient::eFXSurfaceBufferState));
2779
2780 Transaction transaction1, transaction2;
2781 CallbackHelper callback1, callback2;
2782 for (size_t i = 0; i < 10; i++) {
2783 fillTransaction(transaction1, &callback1, layer1);
2784 fillTransaction(transaction2, &callback2, layer2);
2785
2786 transaction2.setPosition(layer2, mWidth, mHeight).merge(std::move(transaction1)).apply();
2787
2788 ExpectedResult expected;
2789 expected.addSurfaces(ExpectedResult::Transaction::PRESENTED, {layer1, layer2},
2790 ExpectedResult::Buffer::NOT_ACQUIRED,
2791 (i == 0) ? ExpectedResult::PreviousBuffer::NOT_RELEASED
2792 : ExpectedResult::PreviousBuffer::RELEASED);
2793 EXPECT_NO_FATAL_FAILURE(waitForCallback(callback1, expected));
2794 EXPECT_NO_FATAL_FAILURE(waitForCallback(callback2, expected));
2795 }
2796 ASSERT_NO_FATAL_FAILURE(callback1.verifyFinalState());
2797 ASSERT_NO_FATAL_FAILURE(callback2.verifyFinalState());
2798}
2799
2800TEST_F(LayerCallbackTest, MultipleTransactions_Merge_DifferentClients_NoStateChange) {
2801 sp<SurfaceComposerClient> client1(new SurfaceComposerClient),
2802 client2(new SurfaceComposerClient);
2803 ASSERT_EQ(NO_ERROR, client1->initCheck()) << "failed to create SurfaceComposerClient";
2804 ASSERT_EQ(NO_ERROR, client2->initCheck()) << "failed to create SurfaceComposerClient";
2805
2806 sp<SurfaceControl> layer1, layer2;
2807 ASSERT_NO_FATAL_FAILURE(layer1 = createLayer(client1, "test", mWidth, mHeight,
2808 ISurfaceComposerClient::eFXSurfaceBufferState));
2809 ASSERT_NO_FATAL_FAILURE(layer2 = createLayer(client2, "test", mWidth, mHeight,
2810 ISurfaceComposerClient::eFXSurfaceBufferState));
2811
2812 Transaction transaction1, transaction2;
2813 CallbackHelper callback1, callback2;
2814
2815 // Normal call to set up test
2816 fillTransaction(transaction1, &callback1, layer1);
2817 fillTransaction(transaction2, &callback2, layer2);
2818
2819 transaction2.setPosition(layer2, mWidth, mHeight).merge(std::move(transaction1)).apply();
2820
2821 ExpectedResult expected;
2822 expected.addSurfaces(ExpectedResult::Transaction::PRESENTED, {layer1, layer2});
2823 EXPECT_NO_FATAL_FAILURE(waitForCallback(callback1, expected, true));
2824 EXPECT_NO_FATAL_FAILURE(waitForCallback(callback2, expected, true));
2825 expected.reset();
2826
2827 // Test
2828 fillTransaction(transaction1, &callback1);
2829 fillTransaction(transaction2, &callback2);
2830
2831 transaction2.merge(std::move(transaction1)).apply();
2832
2833 EXPECT_NO_FATAL_FAILURE(waitForCallback(callback1, expected, true));
2834 EXPECT_NO_FATAL_FAILURE(waitForCallback(callback2, expected, true));
2835}
2836
2837TEST_F(LayerCallbackTest, MultipleTransactions_Merge_DifferentClients_SameStateChange) {
2838 sp<SurfaceComposerClient> client1(new SurfaceComposerClient),
2839 client2(new SurfaceComposerClient);
2840
2841 ASSERT_EQ(NO_ERROR, client1->initCheck()) << "failed to create SurfaceComposerClient";
2842 ASSERT_EQ(NO_ERROR, client2->initCheck()) << "failed to create SurfaceComposerClient";
2843
2844 sp<SurfaceControl> layer1, layer2;
2845 ASSERT_NO_FATAL_FAILURE(layer1 = createLayer(client1, "test", mWidth, mHeight,
2846 ISurfaceComposerClient::eFXSurfaceBufferState));
2847 ASSERT_NO_FATAL_FAILURE(layer2 = createLayer(client2, "test", mWidth, mHeight,
2848 ISurfaceComposerClient::eFXSurfaceBufferState));
2849
2850 Transaction transaction1, transaction2;
2851 CallbackHelper callback1, callback2;
2852
2853 // Normal call to set up test
2854 fillTransaction(transaction1, &callback1, layer1);
2855 fillTransaction(transaction2, &callback2, layer2);
2856
2857 transaction2.setPosition(layer2, mWidth, mHeight).merge(std::move(transaction1)).apply();
2858
2859 ExpectedResult expected;
2860 expected.addSurfaces(ExpectedResult::Transaction::PRESENTED, {layer1, layer2});
2861 EXPECT_NO_FATAL_FAILURE(waitForCallback(callback1, expected, true));
2862 EXPECT_NO_FATAL_FAILURE(waitForCallback(callback2, expected, true));
2863 expected.reset();
2864
2865 // Test
2866 fillTransaction(transaction1, &callback1);
2867 fillTransaction(transaction2, &callback2);
2868
2869 transaction2.setPosition(layer2, mWidth, mHeight).merge(std::move(transaction1)).apply();
2870
2871 expected.addSurface(ExpectedResult::Transaction::NOT_PRESENTED, layer2);
2872 EXPECT_NO_FATAL_FAILURE(waitForCallback(callback1, expected, true));
2873 EXPECT_NO_FATAL_FAILURE(waitForCallback(callback2, expected, true));
2874}
2875
2876TEST_F(LayerCallbackTest, MultipleTransactions_SingleFrame) {
2877 sp<SurfaceControl> layer;
2878 ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
2879
2880 Transaction transaction;
2881 CallbackHelper callback;
2882 std::vector<ExpectedResult> expectedResults(50);
2883 ExpectedResult::PreviousBuffer previousBufferResult =
2884 ExpectedResult::PreviousBuffer::NOT_RELEASED;
2885 for (auto& expected : expectedResults) {
2886 expected.reset();
2887 expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
2888 ExpectedResult::Buffer::NOT_ACQUIRED, previousBufferResult);
2889 previousBufferResult = ExpectedResult::PreviousBuffer::RELEASED;
2890
2891 fillTransaction(transaction, &callback, layer);
2892
2893 transaction.apply();
2894 std::this_thread::sleep_for(200ms);
2895 }
2896 EXPECT_NO_FATAL_FAILURE(waitForCallbacks(callback, expectedResults, true));
2897}
2898
2899TEST_F(LayerCallbackTest, MultipleTransactions_SingleFrame_NoStateChange) {
2900 sp<SurfaceControl> layer;
2901 ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
2902
2903 Transaction transaction;
2904 CallbackHelper callback;
2905 std::vector<ExpectedResult> expectedResults(50);
2906 bool first = true;
2907 for (auto& expected : expectedResults) {
2908 expected.reset();
2909
2910 if (first) {
2911 fillTransaction(transaction, &callback, layer);
2912 expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer);
2913 first = false;
2914 } else {
2915 fillTransaction(transaction, &callback);
2916 }
2917
2918 transaction.apply();
2919 std::this_thread::sleep_for(200ms);
2920 }
2921 EXPECT_NO_FATAL_FAILURE(waitForCallbacks(callback, expectedResults, true));
2922}
2923
2924TEST_F(LayerCallbackTest, MultipleTransactions_SingleFrame_SameStateChange) {
2925 sp<SurfaceControl> layer;
2926 ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
2927
2928 // Normal call to set up test
2929 Transaction transaction;
2930 CallbackHelper callback;
2931 fillTransaction(transaction, &callback, layer);
2932
2933 transaction.setPosition(layer, mWidth, mHeight).apply();
2934
2935 ExpectedResult expectedResult;
2936 expectedResult.addSurface(ExpectedResult::Transaction::PRESENTED, layer);
2937 EXPECT_NO_FATAL_FAILURE(waitForCallback(callback, expectedResult, true));
2938
2939 // Test
2940 std::vector<ExpectedResult> expectedResults(50);
2941 for (auto& expected : expectedResults) {
2942 expected.reset();
2943 expected.addSurface(ExpectedResult::Transaction::NOT_PRESENTED, layer);
2944
2945 fillTransaction(transaction, &callback);
2946
2947 transaction.setPosition(layer, mWidth, mHeight).apply();
2948
2949 std::this_thread::sleep_for(200ms);
2950 }
2951 EXPECT_NO_FATAL_FAILURE(waitForCallbacks(callback, expectedResults, true));
2952}
2953
Chavi Weingarten40482ff2017-11-30 01:51:40 +00002954class LayerUpdateTest : public LayerTransactionTest {
Jamie Gennis23c2c5d2011-10-11 19:22:19 -07002955protected:
2956 virtual void SetUp() {
chaviw0e3479f2018-09-10 16:49:30 -07002957 LayerTransactionTest::SetUp();
2958 ASSERT_EQ(NO_ERROR, mClient->initCheck());
Jamie Gennis23c2c5d2011-10-11 19:22:19 -07002959
Chia-I Wu1078bbb2017-10-20 11:29:02 -07002960 sp<IBinder> display(
2961 SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
Mathias Agopianc666cae2012-07-25 18:56:13 -07002962 DisplayInfo info;
Jeff Brown9d4e3d22012-08-24 20:00:51 -07002963 SurfaceComposerClient::getDisplayInfo(display, &info);
Mathias Agopianc666cae2012-07-25 18:56:13 -07002964
2965 ssize_t displayWidth = info.w;
2966 ssize_t displayHeight = info.h;
Jamie Gennis23c2c5d2011-10-11 19:22:19 -07002967
2968 // Background surface
chaviw0e3479f2018-09-10 16:49:30 -07002969 mBGSurfaceControl = createLayer(String8("BG Test Surface"), displayWidth,
2970 displayHeight, 0);
Peiyong Lin566a3b42018-01-09 18:22:43 -08002971 ASSERT_TRUE(mBGSurfaceControl != nullptr);
Jamie Gennis23c2c5d2011-10-11 19:22:19 -07002972 ASSERT_TRUE(mBGSurfaceControl->isValid());
2973 fillSurfaceRGBA8(mBGSurfaceControl, 63, 63, 195);
2974
2975 // Foreground surface
chaviw0e3479f2018-09-10 16:49:30 -07002976 mFGSurfaceControl = createLayer(String8("FG Test Surface"), 64, 64, 0);
2977
Peiyong Lin566a3b42018-01-09 18:22:43 -08002978 ASSERT_TRUE(mFGSurfaceControl != nullptr);
Jamie Gennis23c2c5d2011-10-11 19:22:19 -07002979 ASSERT_TRUE(mFGSurfaceControl->isValid());
2980
2981 fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
2982
2983 // Synchronization surface
chaviw0e3479f2018-09-10 16:49:30 -07002984 mSyncSurfaceControl = createLayer(String8("Sync Test Surface"), 1, 1, 0);
Peiyong Lin566a3b42018-01-09 18:22:43 -08002985 ASSERT_TRUE(mSyncSurfaceControl != nullptr);
Jamie Gennis23c2c5d2011-10-11 19:22:19 -07002986 ASSERT_TRUE(mSyncSurfaceControl->isValid());
2987
2988 fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
2989
Robert Carr4cdc58f2017-08-23 14:22:20 -07002990 asTransaction([&](Transaction& t) {
2991 t.setDisplayLayerStack(display, 0);
Jamie Gennis23c2c5d2011-10-11 19:22:19 -07002992
Chia-I Wu1078bbb2017-10-20 11:29:02 -07002993 t.setLayer(mBGSurfaceControl, INT32_MAX - 2).show(mBGSurfaceControl);
Pablo Ceballos5e4fcbe2015-09-02 09:53:16 -07002994
Chia-I Wu1078bbb2017-10-20 11:29:02 -07002995 t.setLayer(mFGSurfaceControl, INT32_MAX - 1)
2996 .setPosition(mFGSurfaceControl, 64, 64)
2997 .show(mFGSurfaceControl);
Jamie Gennis23c2c5d2011-10-11 19:22:19 -07002998
Chia-I Wu1078bbb2017-10-20 11:29:02 -07002999 t.setLayer(mSyncSurfaceControl, INT32_MAX - 1)
3000 .setPosition(mSyncSurfaceControl, displayWidth - 2, displayHeight - 2)
3001 .show(mSyncSurfaceControl);
Robert Carr4cdc58f2017-08-23 14:22:20 -07003002 });
Jamie Gennis23c2c5d2011-10-11 19:22:19 -07003003 }
3004
3005 virtual void TearDown() {
chaviw0e3479f2018-09-10 16:49:30 -07003006 LayerTransactionTest::TearDown();
Jamie Gennis23c2c5d2011-10-11 19:22:19 -07003007 mBGSurfaceControl = 0;
3008 mFGSurfaceControl = 0;
3009 mSyncSurfaceControl = 0;
Jamie Gennis23c2c5d2011-10-11 19:22:19 -07003010 }
3011
3012 void waitForPostedBuffers() {
3013 // Since the sync surface is in synchronous mode (i.e. double buffered)
3014 // posting three buffers to it should ensure that at least two
3015 // SurfaceFlinger::handlePageFlip calls have been made, which should
3016 // guaranteed that a buffer posted to another Surface has been retired.
3017 fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
3018 fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
3019 fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
3020 }
3021
Robert Carr4cdc58f2017-08-23 14:22:20 -07003022 void asTransaction(const std::function<void(Transaction&)>& exec) {
3023 Transaction t;
3024 exec(t);
3025 t.apply(true);
3026 }
3027
Jamie Gennis23c2c5d2011-10-11 19:22:19 -07003028 sp<SurfaceControl> mBGSurfaceControl;
3029 sp<SurfaceControl> mFGSurfaceControl;
3030
3031 // This surface is used to ensure that the buffers posted to
3032 // mFGSurfaceControl have been picked up by SurfaceFlinger.
3033 sp<SurfaceControl> mSyncSurfaceControl;
3034};
3035
Robert Carr7f619b22017-11-06 12:56:35 -08003036TEST_F(LayerUpdateTest, RelativesAreNotDetached) {
Robert Carr7f619b22017-11-06 12:56:35 -08003037
chaviw0e3479f2018-09-10 16:49:30 -07003038 std::unique_ptr<ScreenCapture> sc;
3039
3040 sp<SurfaceControl> relative = createLayer(String8("relativeTestSurface"), 10, 10, 0);
Robert Carr7f619b22017-11-06 12:56:35 -08003041 fillSurfaceRGBA8(relative, 10, 10, 10);
3042 waitForPostedBuffers();
3043
Chia-I Wu1078bbb2017-10-20 11:29:02 -07003044 Transaction{}
3045 .setRelativeLayer(relative, mFGSurfaceControl->getHandle(), 1)
Robert Carr7f619b22017-11-06 12:56:35 -08003046 .setPosition(relative, 64, 64)
3047 .apply();
3048
3049 {
3050 // The relative should be on top of the FG control.
3051 ScreenCapture::captureScreen(&sc);
3052 sc->checkPixel(64, 64, 10, 10, 10);
3053 }
Chia-I Wu1078bbb2017-10-20 11:29:02 -07003054 Transaction{}.detachChildren(mFGSurfaceControl).apply();
Robert Carr7f619b22017-11-06 12:56:35 -08003055
3056 {
3057 // Nothing should change at this point.
3058 ScreenCapture::captureScreen(&sc);
3059 sc->checkPixel(64, 64, 10, 10, 10);
3060 }
3061
Chia-I Wu1078bbb2017-10-20 11:29:02 -07003062 Transaction{}.hide(relative).apply();
Robert Carr7f619b22017-11-06 12:56:35 -08003063
3064 {
3065 // Ensure that the relative was actually hidden, rather than
3066 // being left in the detached but visible state.
3067 ScreenCapture::captureScreen(&sc);
3068 sc->expectFGColor(64, 64);
3069 }
3070}
3071
Robert Carr8d5227b2017-03-16 15:41:03 -07003072class GeometryLatchingTest : public LayerUpdateTest {
3073protected:
Chia-I Wu1078bbb2017-10-20 11:29:02 -07003074 void EXPECT_INITIAL_STATE(const char* trace) {
Robert Carr8d5227b2017-03-16 15:41:03 -07003075 SCOPED_TRACE(trace);
3076 ScreenCapture::captureScreen(&sc);
3077 // We find the leading edge of the FG surface.
3078 sc->expectFGColor(127, 127);
3079 sc->expectBGColor(128, 128);
3080 }
Robert Carr7bf247e2017-05-18 14:02:49 -07003081
Chia-I Wu1078bbb2017-10-20 11:29:02 -07003082 void lockAndFillFGBuffer() { fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63, false); }
Robert Carr7bf247e2017-05-18 14:02:49 -07003083
3084 void unlockFGBuffer() {
3085 sp<Surface> s = mFGSurfaceControl->getSurface();
3086 ASSERT_EQ(NO_ERROR, s->unlockAndPost());
3087 waitForPostedBuffers();
3088 }
3089
Robert Carr8d5227b2017-03-16 15:41:03 -07003090 void completeFGResize() {
3091 fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
3092 waitForPostedBuffers();
3093 }
3094 void restoreInitialState() {
Robert Carr4cdc58f2017-08-23 14:22:20 -07003095 asTransaction([&](Transaction& t) {
3096 t.setSize(mFGSurfaceControl, 64, 64);
3097 t.setPosition(mFGSurfaceControl, 64, 64);
Marissa Wallf58c14b2018-07-24 10:50:43 -07003098 t.setCrop_legacy(mFGSurfaceControl, Rect(0, 0, 64, 64));
Robert Carr4cdc58f2017-08-23 14:22:20 -07003099 });
Robert Carr8d5227b2017-03-16 15:41:03 -07003100
3101 EXPECT_INITIAL_STATE("After restoring initial state");
3102 }
chaviw0e3479f2018-09-10 16:49:30 -07003103 std::unique_ptr<ScreenCapture> sc;
Robert Carr8d5227b2017-03-16 15:41:03 -07003104};
3105
Robert Carr8d5227b2017-03-16 15:41:03 -07003106class CropLatchingTest : public GeometryLatchingTest {
3107protected:
3108 void EXPECT_CROPPED_STATE(const char* trace) {
3109 SCOPED_TRACE(trace);
3110 ScreenCapture::captureScreen(&sc);
3111 // The edge should be moved back one pixel by our crop.
3112 sc->expectFGColor(126, 126);
3113 sc->expectBGColor(127, 127);
3114 sc->expectBGColor(128, 128);
3115 }
chaviw59f5c562017-06-28 16:39:06 -07003116
3117 void EXPECT_RESIZE_STATE(const char* trace) {
3118 SCOPED_TRACE(trace);
3119 ScreenCapture::captureScreen(&sc);
3120 // The FG is now resized too 128,128 at 64,64
3121 sc->expectFGColor(64, 64);
3122 sc->expectFGColor(191, 191);
3123 sc->expectBGColor(192, 192);
3124 }
Robert Carr8d5227b2017-03-16 15:41:03 -07003125};
3126
Pablo Ceballos05289c22016-04-14 15:49:55 -07003127TEST_F(LayerUpdateTest, DeferredTransactionTest) {
chaviw0e3479f2018-09-10 16:49:30 -07003128 std::unique_ptr<ScreenCapture> sc;
Pablo Ceballos05289c22016-04-14 15:49:55 -07003129 {
3130 SCOPED_TRACE("before anything");
3131 ScreenCapture::captureScreen(&sc);
Robert Carr2b91c822017-02-21 19:41:24 -08003132 sc->expectBGColor(32, 32);
3133 sc->expectFGColor(96, 96);
3134 sc->expectBGColor(160, 160);
Pablo Ceballos05289c22016-04-14 15:49:55 -07003135 }
3136
3137 // set up two deferred transactions on different frames
Robert Carr4cdc58f2017-08-23 14:22:20 -07003138 asTransaction([&](Transaction& t) {
3139 t.setAlpha(mFGSurfaceControl, 0.75);
Marissa Wallf58c14b2018-07-24 10:50:43 -07003140 t.deferTransactionUntil_legacy(mFGSurfaceControl, mSyncSurfaceControl->getHandle(),
3141 mSyncSurfaceControl->getSurface()->getNextFrameNumber());
Robert Carr4cdc58f2017-08-23 14:22:20 -07003142 });
Pablo Ceballos05289c22016-04-14 15:49:55 -07003143
Robert Carr4cdc58f2017-08-23 14:22:20 -07003144 asTransaction([&](Transaction& t) {
Chia-I Wu1078bbb2017-10-20 11:29:02 -07003145 t.setPosition(mFGSurfaceControl, 128, 128);
Marissa Wallf58c14b2018-07-24 10:50:43 -07003146 t.deferTransactionUntil_legacy(mFGSurfaceControl, mSyncSurfaceControl->getHandle(),
3147 mSyncSurfaceControl->getSurface()->getNextFrameNumber() + 1);
Robert Carr4cdc58f2017-08-23 14:22:20 -07003148 });
Pablo Ceballos05289c22016-04-14 15:49:55 -07003149
3150 {
3151 SCOPED_TRACE("before any trigger");
3152 ScreenCapture::captureScreen(&sc);
Robert Carr2b91c822017-02-21 19:41:24 -08003153 sc->expectBGColor(32, 32);
3154 sc->expectFGColor(96, 96);
3155 sc->expectBGColor(160, 160);
Pablo Ceballos05289c22016-04-14 15:49:55 -07003156 }
3157
3158 // should trigger the first deferred transaction, but not the second one
3159 fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
3160 {
3161 SCOPED_TRACE("after first trigger");
3162 ScreenCapture::captureScreen(&sc);
Robert Carr2b91c822017-02-21 19:41:24 -08003163 sc->expectBGColor(32, 32);
3164 sc->checkPixel(96, 96, 162, 63, 96);
3165 sc->expectBGColor(160, 160);
Pablo Ceballos05289c22016-04-14 15:49:55 -07003166 }
3167
3168 // should show up immediately since it's not deferred
Chia-I Wu1078bbb2017-10-20 11:29:02 -07003169 asTransaction([&](Transaction& t) { t.setAlpha(mFGSurfaceControl, 1.0); });
Pablo Ceballos05289c22016-04-14 15:49:55 -07003170
3171 // trigger the second deferred transaction
3172 fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
3173 {
3174 SCOPED_TRACE("after second trigger");
3175 ScreenCapture::captureScreen(&sc);
Robert Carr2b91c822017-02-21 19:41:24 -08003176 sc->expectBGColor(32, 32);
3177 sc->expectBGColor(96, 96);
3178 sc->expectFGColor(160, 160);
Pablo Ceballos05289c22016-04-14 15:49:55 -07003179 }
3180}
3181
Robert Carre392b552017-09-19 12:16:05 -07003182TEST_F(LayerUpdateTest, LayerWithNoBuffersResizesImmediately) {
chaviw0e3479f2018-09-10 16:49:30 -07003183 std::unique_ptr<ScreenCapture> sc;
Robert Carre392b552017-09-19 12:16:05 -07003184
3185 sp<SurfaceControl> childNoBuffer =
Vishnu Nair88a11f22018-11-28 18:30:57 -08003186 createSurface(mClient, "Bufferless child", 0 /* buffer width */, 0 /* buffer height */,
3187 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
3188 sp<SurfaceControl> childBuffer = createSurface(mClient, "Buffered child", 20, 20,
3189 PIXEL_FORMAT_RGBA_8888, 0, childNoBuffer.get());
Robert Carre392b552017-09-19 12:16:05 -07003190 fillSurfaceRGBA8(childBuffer, 200, 200, 200);
Vishnu Nair60356342018-11-13 13:00:45 -08003191 SurfaceComposerClient::Transaction{}
3192 .setCrop_legacy(childNoBuffer, Rect(0, 0, 10, 10))
3193 .show(childNoBuffer)
3194 .show(childBuffer)
3195 .apply(true);
Robert Carre392b552017-09-19 12:16:05 -07003196 {
3197 ScreenCapture::captureScreen(&sc);
3198 sc->expectChildColor(73, 73);
3199 sc->expectFGColor(74, 74);
3200 }
Vishnu Nair60356342018-11-13 13:00:45 -08003201 SurfaceComposerClient::Transaction{}
3202 .setCrop_legacy(childNoBuffer, Rect(0, 0, 20, 20))
3203 .apply(true);
Robert Carre392b552017-09-19 12:16:05 -07003204 {
3205 ScreenCapture::captureScreen(&sc);
3206 sc->expectChildColor(73, 73);
3207 sc->expectChildColor(74, 74);
3208 }
3209}
3210
Robert Carr2c5f6d22017-09-26 12:30:35 -07003211TEST_F(LayerUpdateTest, MergingTransactions) {
chaviw0e3479f2018-09-10 16:49:30 -07003212 std::unique_ptr<ScreenCapture> sc;
Robert Carr2c5f6d22017-09-26 12:30:35 -07003213 {
3214 SCOPED_TRACE("before move");
3215 ScreenCapture::captureScreen(&sc);
3216 sc->expectBGColor(0, 12);
3217 sc->expectFGColor(75, 75);
3218 sc->expectBGColor(145, 145);
3219 }
3220
3221 Transaction t1, t2;
3222 t1.setPosition(mFGSurfaceControl, 128, 128);
3223 t2.setPosition(mFGSurfaceControl, 0, 0);
3224 // We expect that the position update from t2 now
3225 // overwrites the position update from t1.
3226 t1.merge(std::move(t2));
3227 t1.apply();
3228
3229 {
3230 ScreenCapture::captureScreen(&sc);
3231 sc->expectFGColor(1, 1);
3232 }
3233}
3234
Robert Carr1f0a16a2016-10-24 16:27:39 -07003235class ChildLayerTest : public LayerUpdateTest {
3236protected:
3237 void SetUp() override {
3238 LayerUpdateTest::SetUp();
Vishnu Nair88a11f22018-11-28 18:30:57 -08003239 mChild = createSurface(mClient, "Child surface", 10, 10, PIXEL_FORMAT_RGBA_8888, 0,
3240 mFGSurfaceControl.get());
Robert Carr1f0a16a2016-10-24 16:27:39 -07003241 fillSurfaceRGBA8(mChild, 200, 200, 200);
3242
3243 {
3244 SCOPED_TRACE("before anything");
chaviw0e3479f2018-09-10 16:49:30 -07003245 mCapture = screenshot();
Robert Carr1f0a16a2016-10-24 16:27:39 -07003246 mCapture->expectChildColor(64, 64);
3247 }
3248 }
3249 void TearDown() override {
3250 LayerUpdateTest::TearDown();
3251 mChild = 0;
3252 }
3253
3254 sp<SurfaceControl> mChild;
chaviw0e3479f2018-09-10 16:49:30 -07003255 std::unique_ptr<ScreenCapture> mCapture;
Robert Carr1f0a16a2016-10-24 16:27:39 -07003256};
3257
3258TEST_F(ChildLayerTest, ChildLayerPositioning) {
Robert Carr4cdc58f2017-08-23 14:22:20 -07003259 asTransaction([&](Transaction& t) {
3260 t.show(mChild);
3261 t.setPosition(mChild, 10, 10);
3262 t.setPosition(mFGSurfaceControl, 64, 64);
3263 });
Robert Carr1f0a16a2016-10-24 16:27:39 -07003264
3265 {
chaviw0e3479f2018-09-10 16:49:30 -07003266 mCapture = screenshot();
Robert Carr1f0a16a2016-10-24 16:27:39 -07003267 // Top left of foreground must now be visible
3268 mCapture->expectFGColor(64, 64);
3269 // But 10 pixels in we should see the child surface
3270 mCapture->expectChildColor(74, 74);
3271 // And 10 more pixels we should be back to the foreground surface
3272 mCapture->expectFGColor(84, 84);
3273 }
3274
Chia-I Wu1078bbb2017-10-20 11:29:02 -07003275 asTransaction([&](Transaction& t) { t.setPosition(mFGSurfaceControl, 0, 0); });
Robert Carr1f0a16a2016-10-24 16:27:39 -07003276
3277 {
chaviw0e3479f2018-09-10 16:49:30 -07003278 mCapture = screenshot();
Robert Carr1f0a16a2016-10-24 16:27:39 -07003279 // Top left of foreground should now be at 0, 0
3280 mCapture->expectFGColor(0, 0);
3281 // But 10 pixels in we should see the child surface
3282 mCapture->expectChildColor(10, 10);
3283 // And 10 more pixels we should be back to the foreground surface
3284 mCapture->expectFGColor(20, 20);
3285 }
3286}
3287
Robert Carr41b08b52017-06-01 16:11:34 -07003288TEST_F(ChildLayerTest, ChildLayerCropping) {
Robert Carr4cdc58f2017-08-23 14:22:20 -07003289 asTransaction([&](Transaction& t) {
3290 t.show(mChild);
3291 t.setPosition(mChild, 0, 0);
3292 t.setPosition(mFGSurfaceControl, 0, 0);
Marissa Wallf58c14b2018-07-24 10:50:43 -07003293 t.setCrop_legacy(mFGSurfaceControl, Rect(0, 0, 5, 5));
Robert Carr4cdc58f2017-08-23 14:22:20 -07003294 });
Robert Carr41b08b52017-06-01 16:11:34 -07003295
3296 {
chaviw0e3479f2018-09-10 16:49:30 -07003297 mCapture = screenshot();
Robert Carr41b08b52017-06-01 16:11:34 -07003298 mCapture->expectChildColor(0, 0);
3299 mCapture->expectChildColor(4, 4);
3300 mCapture->expectBGColor(5, 5);
3301 }
3302}
3303
Robert Carr1f0a16a2016-10-24 16:27:39 -07003304TEST_F(ChildLayerTest, ChildLayerConstraints) {
Robert Carr4cdc58f2017-08-23 14:22:20 -07003305 asTransaction([&](Transaction& t) {
3306 t.show(mChild);
3307 t.setPosition(mFGSurfaceControl, 0, 0);
3308 t.setPosition(mChild, 63, 63);
3309 });
Robert Carr1f0a16a2016-10-24 16:27:39 -07003310
3311 {
chaviw0e3479f2018-09-10 16:49:30 -07003312 mCapture = screenshot();
Robert Carr1f0a16a2016-10-24 16:27:39 -07003313 mCapture->expectFGColor(0, 0);
3314 // Last pixel in foreground should now be the child.
3315 mCapture->expectChildColor(63, 63);
3316 // But the child should be constrained and the next pixel
3317 // must be the background
3318 mCapture->expectBGColor(64, 64);
3319 }
3320}
3321
3322TEST_F(ChildLayerTest, ChildLayerScaling) {
Chia-I Wu1078bbb2017-10-20 11:29:02 -07003323 asTransaction([&](Transaction& t) { t.setPosition(mFGSurfaceControl, 0, 0); });
Robert Carr1f0a16a2016-10-24 16:27:39 -07003324
3325 // Find the boundary between the parent and child
3326 {
chaviw0e3479f2018-09-10 16:49:30 -07003327 mCapture = screenshot();
Robert Carr1f0a16a2016-10-24 16:27:39 -07003328 mCapture->expectChildColor(9, 9);
3329 mCapture->expectFGColor(10, 10);
3330 }
3331
Chia-I Wu1078bbb2017-10-20 11:29:02 -07003332 asTransaction([&](Transaction& t) { t.setMatrix(mFGSurfaceControl, 2.0, 0, 0, 2.0); });
Robert Carr1f0a16a2016-10-24 16:27:39 -07003333
3334 // The boundary should be twice as far from the origin now.
3335 // The pixels from the last test should all be child now
3336 {
chaviw0e3479f2018-09-10 16:49:30 -07003337 mCapture = screenshot();
Robert Carr1f0a16a2016-10-24 16:27:39 -07003338 mCapture->expectChildColor(9, 9);
3339 mCapture->expectChildColor(10, 10);
3340 mCapture->expectChildColor(19, 19);
3341 mCapture->expectFGColor(20, 20);
3342 }
3343}
Robert Carr9524cb32017-02-13 11:32:32 -08003344
Robert Carr6452f122017-03-21 10:41:29 -07003345TEST_F(ChildLayerTest, ChildLayerAlpha) {
3346 fillSurfaceRGBA8(mBGSurfaceControl, 0, 0, 254);
3347 fillSurfaceRGBA8(mFGSurfaceControl, 254, 0, 0);
3348 fillSurfaceRGBA8(mChild, 0, 254, 0);
3349 waitForPostedBuffers();
3350
Robert Carr4cdc58f2017-08-23 14:22:20 -07003351 asTransaction([&](Transaction& t) {
3352 t.show(mChild);
3353 t.setPosition(mChild, 0, 0);
3354 t.setPosition(mFGSurfaceControl, 0, 0);
3355 });
Robert Carr6452f122017-03-21 10:41:29 -07003356
3357 {
chaviw0e3479f2018-09-10 16:49:30 -07003358 mCapture = screenshot();
Robert Carr6452f122017-03-21 10:41:29 -07003359 // Unblended child color
3360 mCapture->checkPixel(0, 0, 0, 254, 0);
3361 }
3362
Chia-I Wu1078bbb2017-10-20 11:29:02 -07003363 asTransaction([&](Transaction& t) { t.setAlpha(mChild, 0.5); });
Robert Carr6452f122017-03-21 10:41:29 -07003364
3365 {
chaviw0e3479f2018-09-10 16:49:30 -07003366 mCapture = screenshot();
Robert Carr6452f122017-03-21 10:41:29 -07003367 // Child and BG blended.
3368 mCapture->checkPixel(0, 0, 127, 127, 0);
3369 }
3370
Chia-I Wu1078bbb2017-10-20 11:29:02 -07003371 asTransaction([&](Transaction& t) { t.setAlpha(mFGSurfaceControl, 0.5); });
Robert Carr6452f122017-03-21 10:41:29 -07003372
3373 {
chaviw0e3479f2018-09-10 16:49:30 -07003374 mCapture = screenshot();
Robert Carr6452f122017-03-21 10:41:29 -07003375 // Child and BG blended.
3376 mCapture->checkPixel(0, 0, 95, 64, 95);
3377 }
3378}
3379
Robert Carr9524cb32017-02-13 11:32:32 -08003380TEST_F(ChildLayerTest, ReparentChildren) {
Robert Carr4cdc58f2017-08-23 14:22:20 -07003381 asTransaction([&](Transaction& t) {
3382 t.show(mChild);
3383 t.setPosition(mChild, 10, 10);
3384 t.setPosition(mFGSurfaceControl, 64, 64);
3385 });
Robert Carr9524cb32017-02-13 11:32:32 -08003386
3387 {
chaviw0e3479f2018-09-10 16:49:30 -07003388 mCapture = screenshot();
Robert Carr9524cb32017-02-13 11:32:32 -08003389 // Top left of foreground must now be visible
3390 mCapture->expectFGColor(64, 64);
3391 // But 10 pixels in we should see the child surface
3392 mCapture->expectChildColor(74, 74);
3393 // And 10 more pixels we should be back to the foreground surface
3394 mCapture->expectFGColor(84, 84);
3395 }
Robert Carr4cdc58f2017-08-23 14:22:20 -07003396
3397 asTransaction([&](Transaction& t) {
3398 t.reparentChildren(mFGSurfaceControl, mBGSurfaceControl->getHandle());
3399 });
3400
Robert Carr9524cb32017-02-13 11:32:32 -08003401 {
chaviw0e3479f2018-09-10 16:49:30 -07003402 mCapture = screenshot();
Robert Carr9524cb32017-02-13 11:32:32 -08003403 mCapture->expectFGColor(64, 64);
3404 // In reparenting we should have exposed the entire foreground surface.
3405 mCapture->expectFGColor(74, 74);
3406 // And the child layer should now begin at 10, 10 (since the BG
3407 // layer is at (0, 0)).
3408 mCapture->expectBGColor(9, 9);
3409 mCapture->expectChildColor(10, 10);
3410 }
3411}
3412
Robert Carr2e102c92018-10-23 12:11:15 -07003413TEST_F(ChildLayerTest, ChildrenSurviveParentDestruction) {
3414 sp<SurfaceControl> mGrandChild =
Vishnu Nair88a11f22018-11-28 18:30:57 -08003415 createSurface(mClient, "Grand Child", 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
Robert Carr2e102c92018-10-23 12:11:15 -07003416 fillSurfaceRGBA8(mGrandChild, 111, 111, 111);
3417
3418 {
3419 SCOPED_TRACE("Grandchild visible");
3420 ScreenCapture::captureScreen(&mCapture);
3421 mCapture->checkPixel(64, 64, 111, 111, 111);
3422 }
3423
3424 mChild->clear();
3425
3426 {
3427 SCOPED_TRACE("After destroying child");
3428 ScreenCapture::captureScreen(&mCapture);
3429 mCapture->expectFGColor(64, 64);
3430 }
3431
3432 asTransaction([&](Transaction& t) {
3433 t.reparent(mGrandChild, mFGSurfaceControl->getHandle());
3434 });
3435
3436 {
3437 SCOPED_TRACE("After reparenting grandchild");
3438 ScreenCapture::captureScreen(&mCapture);
3439 mCapture->checkPixel(64, 64, 111, 111, 111);
3440 }
3441}
3442
chaviw161410b02017-07-27 10:46:08 -07003443TEST_F(ChildLayerTest, DetachChildrenSameClient) {
Robert Carr4cdc58f2017-08-23 14:22:20 -07003444 asTransaction([&](Transaction& t) {
3445 t.show(mChild);
3446 t.setPosition(mChild, 10, 10);
3447 t.setPosition(mFGSurfaceControl, 64, 64);
3448 });
Robert Carr9524cb32017-02-13 11:32:32 -08003449
3450 {
chaviw0e3479f2018-09-10 16:49:30 -07003451 mCapture = screenshot();
Robert Carr9524cb32017-02-13 11:32:32 -08003452 // Top left of foreground must now be visible
3453 mCapture->expectFGColor(64, 64);
3454 // But 10 pixels in we should see the child surface
3455 mCapture->expectChildColor(74, 74);
3456 // And 10 more pixels we should be back to the foreground surface
3457 mCapture->expectFGColor(84, 84);
3458 }
3459
chaviw0e3479f2018-09-10 16:49:30 -07003460
Chia-I Wu1078bbb2017-10-20 11:29:02 -07003461 asTransaction([&](Transaction& t) { t.detachChildren(mFGSurfaceControl); });
Robert Carr9524cb32017-02-13 11:32:32 -08003462
Chia-I Wu1078bbb2017-10-20 11:29:02 -07003463 asTransaction([&](Transaction& t) { t.hide(mChild); });
Robert Carr9524cb32017-02-13 11:32:32 -08003464
chaviw161410b02017-07-27 10:46:08 -07003465 // Since the child has the same client as the parent, it will not get
3466 // detached and will be hidden.
3467 {
chaviw0e3479f2018-09-10 16:49:30 -07003468 mCapture = screenshot();
chaviw161410b02017-07-27 10:46:08 -07003469 mCapture->expectFGColor(64, 64);
3470 mCapture->expectFGColor(74, 74);
3471 mCapture->expectFGColor(84, 84);
3472 }
3473}
3474
3475TEST_F(ChildLayerTest, DetachChildrenDifferentClient) {
3476 sp<SurfaceComposerClient> mNewComposerClient = new SurfaceComposerClient;
Chia-I Wu1078bbb2017-10-20 11:29:02 -07003477 sp<SurfaceControl> mChildNewClient =
Vishnu Nair88a11f22018-11-28 18:30:57 -08003478 createSurface(mNewComposerClient, "New Child Test Surface", 10, 10,
3479 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
chaviw161410b02017-07-27 10:46:08 -07003480
chaviw161410b02017-07-27 10:46:08 -07003481 ASSERT_TRUE(mChildNewClient->isValid());
3482
3483 fillSurfaceRGBA8(mChildNewClient, 200, 200, 200);
3484
Robert Carr4cdc58f2017-08-23 14:22:20 -07003485 asTransaction([&](Transaction& t) {
3486 t.hide(mChild);
3487 t.show(mChildNewClient);
3488 t.setPosition(mChildNewClient, 10, 10);
3489 t.setPosition(mFGSurfaceControl, 64, 64);
3490 });
chaviw161410b02017-07-27 10:46:08 -07003491
3492 {
chaviw0e3479f2018-09-10 16:49:30 -07003493 mCapture = screenshot();
chaviw161410b02017-07-27 10:46:08 -07003494 // Top left of foreground must now be visible
3495 mCapture->expectFGColor(64, 64);
3496 // But 10 pixels in we should see the child surface
3497 mCapture->expectChildColor(74, 74);
3498 // And 10 more pixels we should be back to the foreground surface
3499 mCapture->expectFGColor(84, 84);
3500 }
3501
Chia-I Wu1078bbb2017-10-20 11:29:02 -07003502 asTransaction([&](Transaction& t) { t.detachChildren(mFGSurfaceControl); });
chaviw161410b02017-07-27 10:46:08 -07003503
Chia-I Wu1078bbb2017-10-20 11:29:02 -07003504 asTransaction([&](Transaction& t) { t.hide(mChildNewClient); });
chaviw161410b02017-07-27 10:46:08 -07003505
Robert Carr9524cb32017-02-13 11:32:32 -08003506 // Nothing should have changed.
3507 {
chaviw0e3479f2018-09-10 16:49:30 -07003508 mCapture = screenshot();
Robert Carr9524cb32017-02-13 11:32:32 -08003509 mCapture->expectFGColor(64, 64);
3510 mCapture->expectChildColor(74, 74);
3511 mCapture->expectFGColor(84, 84);
3512 }
3513}
3514
chaviw5aedec92018-10-22 10:40:38 -07003515TEST_F(ChildLayerTest, DetachChildrenThenAttach) {
3516 sp<SurfaceComposerClient> newComposerClient = new SurfaceComposerClient;
3517 sp<SurfaceControl> childNewClient =
3518 newComposerClient->createSurface(String8("New Child Test Surface"), 10, 10,
3519 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
3520
3521 ASSERT_TRUE(childNewClient != nullptr);
3522 ASSERT_TRUE(childNewClient->isValid());
3523
3524 fillSurfaceRGBA8(childNewClient, 200, 200, 200);
3525
3526 Transaction()
3527 .hide(mChild)
3528 .show(childNewClient)
3529 .setPosition(childNewClient, 10, 10)
3530 .setPosition(mFGSurfaceControl, 64, 64)
3531 .apply();
3532
3533 {
3534 mCapture = screenshot();
3535 // Top left of foreground must now be visible
3536 mCapture->expectFGColor(64, 64);
3537 // But 10 pixels in we should see the child surface
3538 mCapture->expectChildColor(74, 74);
3539 // And 10 more pixels we should be back to the foreground surface
3540 mCapture->expectFGColor(84, 84);
3541 }
3542
3543 Transaction().detachChildren(mFGSurfaceControl).apply();
3544 Transaction().hide(childNewClient).apply();
3545
3546 // Nothing should have changed.
3547 {
3548 mCapture = screenshot();
3549 mCapture->expectFGColor(64, 64);
3550 mCapture->expectChildColor(74, 74);
3551 mCapture->expectFGColor(84, 84);
3552 }
3553
3554 sp<SurfaceControl> newParentSurface = createLayer(String8("New Parent Surface"), 32, 32, 0);
3555 fillLayerColor(ISurfaceComposerClient::eFXSurfaceBufferQueue, newParentSurface, Color::RED, 32,
3556 32);
3557 Transaction()
3558 .setLayer(newParentSurface, INT32_MAX - 1)
3559 .show(newParentSurface)
3560 .setPosition(newParentSurface, 20, 20)
3561 .reparent(childNewClient, newParentSurface->getHandle())
3562 .apply();
3563 {
3564 mCapture = screenshot();
3565 // Child is now hidden.
3566 mCapture->expectColor(Rect(20, 20, 52, 52), Color::RED);
3567 }
3568}
3569
Robert Carr9b429f42017-04-17 14:56:57 -07003570TEST_F(ChildLayerTest, ChildrenInheritNonTransformScalingFromParent) {
Robert Carr4cdc58f2017-08-23 14:22:20 -07003571 asTransaction([&](Transaction& t) {
3572 t.show(mChild);
3573 t.setPosition(mChild, 0, 0);
3574 t.setPosition(mFGSurfaceControl, 0, 0);
3575 });
Robert Carr9b429f42017-04-17 14:56:57 -07003576
3577 {
chaviw0e3479f2018-09-10 16:49:30 -07003578 mCapture = screenshot();
Robert Carr9b429f42017-04-17 14:56:57 -07003579 // We've positioned the child in the top left.
3580 mCapture->expectChildColor(0, 0);
3581 // But it's only 10x10.
3582 mCapture->expectFGColor(10, 10);
3583 }
3584
Robert Carr4cdc58f2017-08-23 14:22:20 -07003585 asTransaction([&](Transaction& t) {
3586 t.setOverrideScalingMode(mFGSurfaceControl, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
3587 // We cause scaling by 2.
3588 t.setSize(mFGSurfaceControl, 128, 128);
3589 });
Robert Carr9b429f42017-04-17 14:56:57 -07003590
3591 {
chaviw0e3479f2018-09-10 16:49:30 -07003592 mCapture = screenshot();
Robert Carr9b429f42017-04-17 14:56:57 -07003593 // We've positioned the child in the top left.
3594 mCapture->expectChildColor(0, 0);
3595 mCapture->expectChildColor(10, 10);
3596 mCapture->expectChildColor(19, 19);
3597 // And now it should be scaled all the way to 20x20
3598 mCapture->expectFGColor(20, 20);
3599 }
3600}
3601
Robert Carr1725eee2017-04-26 18:32:15 -07003602// Regression test for b/37673612
3603TEST_F(ChildLayerTest, ChildrenWithParentBufferTransform) {
Robert Carr4cdc58f2017-08-23 14:22:20 -07003604 asTransaction([&](Transaction& t) {
3605 t.show(mChild);
3606 t.setPosition(mChild, 0, 0);
3607 t.setPosition(mFGSurfaceControl, 0, 0);
3608 });
Robert Carr1725eee2017-04-26 18:32:15 -07003609
3610 {
chaviw0e3479f2018-09-10 16:49:30 -07003611 mCapture = screenshot();
Robert Carr1725eee2017-04-26 18:32:15 -07003612 // We've positioned the child in the top left.
3613 mCapture->expectChildColor(0, 0);
3614 // But it's only 10x10.
3615 mCapture->expectFGColor(10, 10);
3616 }
Robert Carr1725eee2017-04-26 18:32:15 -07003617 // We set things up as in b/37673612 so that there is a mismatch between the buffer size and
3618 // the WM specified state size.
Chia-I Wu1078bbb2017-10-20 11:29:02 -07003619 asTransaction([&](Transaction& t) { t.setSize(mFGSurfaceControl, 128, 64); });
Robert Carr1725eee2017-04-26 18:32:15 -07003620 sp<Surface> s = mFGSurfaceControl->getSurface();
3621 auto anw = static_cast<ANativeWindow*>(s.get());
3622 native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90);
3623 native_window_set_buffers_dimensions(anw, 64, 128);
3624 fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
3625 waitForPostedBuffers();
3626
3627 {
3628 // The child should still be in the same place and not have any strange scaling as in
3629 // b/37673612.
chaviw0e3479f2018-09-10 16:49:30 -07003630 mCapture = screenshot();
Robert Carr1725eee2017-04-26 18:32:15 -07003631 mCapture->expectChildColor(0, 0);
3632 mCapture->expectFGColor(10, 10);
3633 }
3634}
3635
Dan Stoza412903f2017-04-27 13:42:17 -07003636TEST_F(ChildLayerTest, Bug36858924) {
3637 // Destroy the child layer
3638 mChild.clear();
3639
3640 // Now recreate it as hidden
Vishnu Nair88a11f22018-11-28 18:30:57 -08003641 mChild = createSurface(mClient, "Child surface", 10, 10, PIXEL_FORMAT_RGBA_8888,
3642 ISurfaceComposerClient::eHidden, mFGSurfaceControl.get());
Dan Stoza412903f2017-04-27 13:42:17 -07003643
3644 // Show the child layer in a deferred transaction
Robert Carr4cdc58f2017-08-23 14:22:20 -07003645 asTransaction([&](Transaction& t) {
Marissa Wallf58c14b2018-07-24 10:50:43 -07003646 t.deferTransactionUntil_legacy(mChild, mFGSurfaceControl->getHandle(),
3647 mFGSurfaceControl->getSurface()->getNextFrameNumber());
Robert Carr4cdc58f2017-08-23 14:22:20 -07003648 t.show(mChild);
3649 });
Dan Stoza412903f2017-04-27 13:42:17 -07003650
3651 // Render the foreground surface a few times
3652 //
3653 // Prior to the bugfix for b/36858924, this would usually hang while trying to fill the third
3654 // frame because SurfaceFlinger would never process the deferred transaction and would therefore
3655 // never acquire/release the first buffer
3656 ALOGI("Filling 1");
3657 fillSurfaceRGBA8(mFGSurfaceControl, 0, 255, 0);
3658 ALOGI("Filling 2");
3659 fillSurfaceRGBA8(mFGSurfaceControl, 0, 0, 255);
3660 ALOGI("Filling 3");
3661 fillSurfaceRGBA8(mFGSurfaceControl, 255, 0, 0);
3662 ALOGI("Filling 4");
3663 fillSurfaceRGBA8(mFGSurfaceControl, 0, 255, 0);
3664}
3665
chaviwf1961f72017-09-18 16:41:07 -07003666TEST_F(ChildLayerTest, Reparent) {
Robert Carr4cdc58f2017-08-23 14:22:20 -07003667 asTransaction([&](Transaction& t) {
3668 t.show(mChild);
3669 t.setPosition(mChild, 10, 10);
3670 t.setPosition(mFGSurfaceControl, 64, 64);
3671 });
chaviw06178942017-07-27 10:25:59 -07003672
3673 {
chaviw0e3479f2018-09-10 16:49:30 -07003674 mCapture = screenshot();
chaviw06178942017-07-27 10:25:59 -07003675 // Top left of foreground must now be visible
3676 mCapture->expectFGColor(64, 64);
3677 // But 10 pixels in we should see the child surface
3678 mCapture->expectChildColor(74, 74);
3679 // And 10 more pixels we should be back to the foreground surface
3680 mCapture->expectFGColor(84, 84);
3681 }
Robert Carr4cdc58f2017-08-23 14:22:20 -07003682
Chia-I Wu1078bbb2017-10-20 11:29:02 -07003683 asTransaction([&](Transaction& t) { t.reparent(mChild, mBGSurfaceControl->getHandle()); });
Robert Carr4cdc58f2017-08-23 14:22:20 -07003684
chaviw06178942017-07-27 10:25:59 -07003685 {
chaviw0e3479f2018-09-10 16:49:30 -07003686 mCapture = screenshot();
chaviw06178942017-07-27 10:25:59 -07003687 mCapture->expectFGColor(64, 64);
3688 // In reparenting we should have exposed the entire foreground surface.
3689 mCapture->expectFGColor(74, 74);
3690 // And the child layer should now begin at 10, 10 (since the BG
3691 // layer is at (0, 0)).
3692 mCapture->expectBGColor(9, 9);
3693 mCapture->expectChildColor(10, 10);
3694 }
3695}
3696
chaviwf1961f72017-09-18 16:41:07 -07003697TEST_F(ChildLayerTest, ReparentToNoParent) {
Robert Carr4cdc58f2017-08-23 14:22:20 -07003698 asTransaction([&](Transaction& t) {
3699 t.show(mChild);
3700 t.setPosition(mChild, 10, 10);
3701 t.setPosition(mFGSurfaceControl, 64, 64);
3702 });
chaviwf1961f72017-09-18 16:41:07 -07003703
3704 {
chaviw0e3479f2018-09-10 16:49:30 -07003705 mCapture = screenshot();
chaviwf1961f72017-09-18 16:41:07 -07003706 // Top left of foreground must now be visible
3707 mCapture->expectFGColor(64, 64);
3708 // But 10 pixels in we should see the child surface
3709 mCapture->expectChildColor(74, 74);
3710 // And 10 more pixels we should be back to the foreground surface
3711 mCapture->expectFGColor(84, 84);
3712 }
Chia-I Wu1078bbb2017-10-20 11:29:02 -07003713 asTransaction([&](Transaction& t) { t.reparent(mChild, nullptr); });
chaviwf1961f72017-09-18 16:41:07 -07003714 {
chaviw0e3479f2018-09-10 16:49:30 -07003715 mCapture = screenshot();
chaviwf1961f72017-09-18 16:41:07 -07003716 // Nothing should have changed.
3717 mCapture->expectFGColor(64, 64);
3718 mCapture->expectChildColor(74, 74);
3719 mCapture->expectFGColor(84, 84);
3720 }
3721}
3722
3723TEST_F(ChildLayerTest, ReparentFromNoParent) {
chaviw0e3479f2018-09-10 16:49:30 -07003724 sp<SurfaceControl> newSurface = createLayer(String8("New Surface"), 10, 10, 0);
Peiyong Lin566a3b42018-01-09 18:22:43 -08003725 ASSERT_TRUE(newSurface != nullptr);
chaviwf1961f72017-09-18 16:41:07 -07003726 ASSERT_TRUE(newSurface->isValid());
3727
3728 fillSurfaceRGBA8(newSurface, 63, 195, 63);
Robert Carr4cdc58f2017-08-23 14:22:20 -07003729 asTransaction([&](Transaction& t) {
3730 t.hide(mChild);
3731 t.show(newSurface);
3732 t.setPosition(newSurface, 10, 10);
Chia-I Wu1078bbb2017-10-20 11:29:02 -07003733 t.setLayer(newSurface, INT32_MAX - 2);
Robert Carr4cdc58f2017-08-23 14:22:20 -07003734 t.setPosition(mFGSurfaceControl, 64, 64);
3735 });
chaviwf1961f72017-09-18 16:41:07 -07003736
3737 {
chaviw0e3479f2018-09-10 16:49:30 -07003738 mCapture = screenshot();
chaviwf1961f72017-09-18 16:41:07 -07003739 // Top left of foreground must now be visible
3740 mCapture->expectFGColor(64, 64);
3741 // At 10, 10 we should see the new surface
3742 mCapture->checkPixel(10, 10, 63, 195, 63);
3743 }
3744
Chia-I Wu1078bbb2017-10-20 11:29:02 -07003745 asTransaction([&](Transaction& t) { t.reparent(newSurface, mFGSurfaceControl->getHandle()); });
chaviwf1961f72017-09-18 16:41:07 -07003746
3747 {
chaviw0e3479f2018-09-10 16:49:30 -07003748 mCapture = screenshot();
chaviwf1961f72017-09-18 16:41:07 -07003749 // newSurface will now be a child of mFGSurface so it will be 10, 10 offset from
3750 // mFGSurface, putting it at 74, 74.
3751 mCapture->expectFGColor(64, 64);
3752 mCapture->checkPixel(74, 74, 63, 195, 63);
3753 mCapture->expectFGColor(84, 84);
3754 }
3755}
3756
chaviwc9674332017-08-28 12:32:18 -07003757TEST_F(ChildLayerTest, NestedChildren) {
Vishnu Nair88a11f22018-11-28 18:30:57 -08003758 sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 10, 10,
3759 PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
chaviwc9674332017-08-28 12:32:18 -07003760 fillSurfaceRGBA8(grandchild, 50, 50, 50);
3761
3762 {
chaviw0e3479f2018-09-10 16:49:30 -07003763 mCapture = screenshot();
chaviwc9674332017-08-28 12:32:18 -07003764 // Expect the grandchild to begin at 64, 64 because it's a child of mChild layer
3765 // which begins at 64, 64
3766 mCapture->checkPixel(64, 64, 50, 50, 50);
3767 }
3768}
3769
Robert Carr503c7042017-09-27 15:06:08 -07003770TEST_F(ChildLayerTest, ChildLayerRelativeLayer) {
chaviw0e3479f2018-09-10 16:49:30 -07003771 sp<SurfaceControl> relative = createLayer(String8("Relative surface"), 128, 128, 0);
Robert Carr503c7042017-09-27 15:06:08 -07003772 fillSurfaceRGBA8(relative, 255, 255, 255);
3773
3774 Transaction t;
3775 t.setLayer(relative, INT32_MAX)
3776 .setRelativeLayer(mChild, relative->getHandle(), 1)
3777 .setPosition(mFGSurfaceControl, 0, 0)
3778 .apply(true);
3779
3780 // We expect that the child should have been elevated above our
3781 // INT_MAX layer even though it's not a child of it.
3782 {
chaviw0e3479f2018-09-10 16:49:30 -07003783 mCapture = screenshot();
Robert Carr503c7042017-09-27 15:06:08 -07003784 mCapture->expectChildColor(0, 0);
3785 mCapture->expectChildColor(9, 9);
3786 mCapture->checkPixel(10, 10, 255, 255, 255);
3787 }
3788}
Vishnu Nair60356342018-11-13 13:00:45 -08003789class BoundlessLayerTest : public LayerUpdateTest {
3790protected:
3791 std::unique_ptr<ScreenCapture> mCapture;
3792};
3793
3794// Verify setting a size on a buffer layer has no effect.
3795TEST_F(BoundlessLayerTest, BufferLayerIgnoresSize) {
3796 sp<SurfaceControl> bufferLayer =
Vishnu Nair88a11f22018-11-28 18:30:57 -08003797 createSurface(mClient, "BufferLayer", 45, 45, PIXEL_FORMAT_RGBA_8888, 0,
3798 mFGSurfaceControl.get());
Vishnu Nair60356342018-11-13 13:00:45 -08003799 ASSERT_TRUE(bufferLayer->isValid());
3800 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(bufferLayer, Color::BLACK, 30, 30));
3801 asTransaction([&](Transaction& t) { t.show(bufferLayer); });
3802 {
3803 mCapture = screenshot();
3804 // Top left of background must now be visible
3805 mCapture->expectBGColor(0, 0);
3806 // Foreground Surface bounds must be color layer
3807 mCapture->expectColor(Rect(64, 64, 94, 94), Color::BLACK);
3808 // Buffer layer should not extend past buffer bounds
3809 mCapture->expectFGColor(95, 95);
3810 }
3811}
3812
3813// Verify a boundless color layer will fill its parent bounds. The parent has a buffer size
3814// which will crop the color layer.
3815TEST_F(BoundlessLayerTest, BoundlessColorLayerFillsParentBufferBounds) {
3816 sp<SurfaceControl> colorLayer =
Vishnu Nair88a11f22018-11-28 18:30:57 -08003817 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
3818 ISurfaceComposerClient::eFXSurfaceColor, mFGSurfaceControl.get());
Vishnu Nair60356342018-11-13 13:00:45 -08003819 ASSERT_TRUE(colorLayer->isValid());
3820 asTransaction([&](Transaction& t) {
3821 t.setColor(colorLayer, half3{0, 0, 0});
3822 t.show(colorLayer);
3823 });
3824 {
3825 mCapture = screenshot();
3826 // Top left of background must now be visible
3827 mCapture->expectBGColor(0, 0);
3828 // Foreground Surface bounds must be color layer
3829 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
3830 // Color layer should not extend past foreground bounds
3831 mCapture->expectBGColor(129, 129);
3832 }
3833}
3834
3835// Verify a boundless color layer will fill its parent bounds. The parent has no buffer but has
3836// a crop which will be used to crop the color layer.
3837TEST_F(BoundlessLayerTest, BoundlessColorLayerFillsParentCropBounds) {
Vishnu Nair88a11f22018-11-28 18:30:57 -08003838 sp<SurfaceControl> cropLayer = createSurface(mClient, "CropLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
3839 0 /* flags */, mFGSurfaceControl.get());
Vishnu Nair60356342018-11-13 13:00:45 -08003840 ASSERT_TRUE(cropLayer->isValid());
3841 sp<SurfaceControl> colorLayer =
Vishnu Nair88a11f22018-11-28 18:30:57 -08003842 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
3843 ISurfaceComposerClient::eFXSurfaceColor, cropLayer.get());
Vishnu Nair60356342018-11-13 13:00:45 -08003844 ASSERT_TRUE(colorLayer->isValid());
3845 asTransaction([&](Transaction& t) {
3846 t.setCrop_legacy(cropLayer, Rect(5, 5, 10, 10));
3847 t.setColor(colorLayer, half3{0, 0, 0});
3848 t.show(cropLayer);
3849 t.show(colorLayer);
3850 });
3851 {
3852 mCapture = screenshot();
3853 // Top left of background must now be visible
3854 mCapture->expectBGColor(0, 0);
3855 // Top left of foreground must now be visible
3856 mCapture->expectFGColor(64, 64);
3857 // 5 pixels from the foreground we should see the child surface
3858 mCapture->expectColor(Rect(69, 69, 74, 74), Color::BLACK);
3859 // 10 pixels from the foreground we should be back to the foreground surface
3860 mCapture->expectFGColor(74, 74);
3861 }
3862}
3863
3864// Verify for boundless layer with no children, their transforms have no effect.
3865TEST_F(BoundlessLayerTest, BoundlessColorLayerTransformHasNoEffect) {
3866 sp<SurfaceControl> colorLayer =
Vishnu Nair88a11f22018-11-28 18:30:57 -08003867 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
3868 ISurfaceComposerClient::eFXSurfaceColor, mFGSurfaceControl.get());
Vishnu Nair60356342018-11-13 13:00:45 -08003869 ASSERT_TRUE(colorLayer->isValid());
3870 asTransaction([&](Transaction& t) {
3871 t.setPosition(colorLayer, 320, 320);
3872 t.setMatrix(colorLayer, 2, 0, 0, 2);
3873 t.setColor(colorLayer, half3{0, 0, 0});
3874 t.show(colorLayer);
3875 });
3876 {
3877 mCapture = screenshot();
3878 // Top left of background must now be visible
3879 mCapture->expectBGColor(0, 0);
3880 // Foreground Surface bounds must be color layer
3881 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
3882 // Color layer should not extend past foreground bounds
3883 mCapture->expectBGColor(129, 129);
3884 }
3885}
3886
3887// Verify for boundless layer with children, their transforms have an effect.
3888TEST_F(BoundlessLayerTest, IntermediateBoundlessLayerCanSetTransform) {
3889 sp<SurfaceControl> boundlessLayerRightShift =
Vishnu Nair88a11f22018-11-28 18:30:57 -08003890 createSurface(mClient, "BoundlessLayerRightShift", 0, 0, PIXEL_FORMAT_RGBA_8888,
3891 0 /* flags */, mFGSurfaceControl.get());
Vishnu Nair60356342018-11-13 13:00:45 -08003892 ASSERT_TRUE(boundlessLayerRightShift->isValid());
3893 sp<SurfaceControl> boundlessLayerDownShift =
Vishnu Nair88a11f22018-11-28 18:30:57 -08003894 createSurface(mClient, "BoundlessLayerLeftShift", 0, 0, PIXEL_FORMAT_RGBA_8888,
3895 0 /* flags */, boundlessLayerRightShift.get());
Vishnu Nair60356342018-11-13 13:00:45 -08003896 ASSERT_TRUE(boundlessLayerDownShift->isValid());
3897 sp<SurfaceControl> colorLayer =
Vishnu Nair88a11f22018-11-28 18:30:57 -08003898 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
3899 ISurfaceComposerClient::eFXSurfaceColor, boundlessLayerDownShift.get());
Vishnu Nair60356342018-11-13 13:00:45 -08003900 ASSERT_TRUE(colorLayer->isValid());
3901 asTransaction([&](Transaction& t) {
3902 t.setPosition(boundlessLayerRightShift, 32, 0);
3903 t.show(boundlessLayerRightShift);
3904 t.setPosition(boundlessLayerDownShift, 0, 32);
3905 t.show(boundlessLayerDownShift);
3906 t.setCrop_legacy(colorLayer, Rect(0, 0, 64, 64));
3907 t.setColor(colorLayer, half3{0, 0, 0});
3908 t.show(colorLayer);
3909 });
3910 {
3911 mCapture = screenshot();
3912 // Top left of background must now be visible
3913 mCapture->expectBGColor(0, 0);
3914 // Top left of foreground must now be visible
3915 mCapture->expectFGColor(64, 64);
3916 // Foreground Surface bounds must be color layer
3917 mCapture->expectColor(Rect(96, 96, 128, 128), Color::BLACK);
3918 // Color layer should not extend past foreground bounds
3919 mCapture->expectBGColor(129, 129);
3920 }
3921}
3922
3923// Verify child layers do not get clipped if they temporarily move into the negative
3924// coordinate space as the result of an intermediate transformation.
3925TEST_F(BoundlessLayerTest, IntermediateBoundlessLayerDoNotCrop) {
3926 sp<SurfaceControl> boundlessLayer =
3927 mClient->createSurface(String8("BoundlessLayer"), 0, 0, PIXEL_FORMAT_RGBA_8888,
3928 0 /* flags */, mFGSurfaceControl.get());
3929 ASSERT_TRUE(boundlessLayer != nullptr);
3930 ASSERT_TRUE(boundlessLayer->isValid());
3931 sp<SurfaceControl> colorLayer =
3932 mClient->createSurface(String8("ColorLayer"), 0, 0, PIXEL_FORMAT_RGBA_8888,
3933 ISurfaceComposerClient::eFXSurfaceColor, boundlessLayer.get());
3934 ASSERT_TRUE(colorLayer != nullptr);
3935 ASSERT_TRUE(colorLayer->isValid());
3936 asTransaction([&](Transaction& t) {
3937 // shift child layer off bounds. If this layer was not boundless, we will
3938 // expect the child layer to be cropped.
3939 t.setPosition(boundlessLayer, 32, 32);
3940 t.show(boundlessLayer);
3941 t.setCrop_legacy(colorLayer, Rect(0, 0, 64, 64));
3942 // undo shift by parent
3943 t.setPosition(colorLayer, -32, -32);
3944 t.setColor(colorLayer, half3{0, 0, 0});
3945 t.show(colorLayer);
3946 });
3947 {
3948 mCapture = screenshot();
3949 // Top left of background must now be visible
3950 mCapture->expectBGColor(0, 0);
3951 // Foreground Surface bounds must be color layer
3952 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
3953 // Color layer should not extend past foreground bounds
3954 mCapture->expectBGColor(129, 129);
3955 }
3956}
3957
3958// Verify for boundless root layers with children, their transforms have an effect.
3959TEST_F(BoundlessLayerTest, RootBoundlessLayerCanSetTransform) {
Vishnu Nair88a11f22018-11-28 18:30:57 -08003960 sp<SurfaceControl> rootBoundlessLayer = createSurface(mClient, "RootBoundlessLayer", 0, 0,
3961 PIXEL_FORMAT_RGBA_8888, 0 /* flags */);
Vishnu Nair60356342018-11-13 13:00:45 -08003962 ASSERT_TRUE(rootBoundlessLayer->isValid());
3963 sp<SurfaceControl> colorLayer =
Vishnu Nair88a11f22018-11-28 18:30:57 -08003964 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
3965 ISurfaceComposerClient::eFXSurfaceColor, rootBoundlessLayer.get());
3966
Vishnu Nair60356342018-11-13 13:00:45 -08003967 ASSERT_TRUE(colorLayer->isValid());
3968 asTransaction([&](Transaction& t) {
3969 t.setLayer(rootBoundlessLayer, INT32_MAX - 1);
3970 t.setPosition(rootBoundlessLayer, 32, 32);
3971 t.show(rootBoundlessLayer);
3972 t.setCrop_legacy(colorLayer, Rect(0, 0, 64, 64));
3973 t.setColor(colorLayer, half3{0, 0, 0});
3974 t.show(colorLayer);
3975 t.hide(mFGSurfaceControl);
3976 });
3977 {
3978 mCapture = screenshot();
3979 // Top left of background must now be visible
3980 mCapture->expectBGColor(0, 0);
3981 // Top left of foreground must now be visible
3982 mCapture->expectBGColor(31, 31);
3983 // Foreground Surface bounds must be color layer
3984 mCapture->expectColor(Rect(32, 32, 96, 96), Color::BLACK);
3985 // Color layer should not extend past foreground bounds
3986 mCapture->expectBGColor(97, 97);
3987 }
3988}
Robert Carr503c7042017-09-27 15:06:08 -07003989
chaviwa76b2712017-09-20 12:02:26 -07003990class ScreenCaptureTest : public LayerUpdateTest {
3991protected:
Chavi Weingarten40482ff2017-11-30 01:51:40 +00003992 std::unique_ptr<ScreenCapture> mCapture;
chaviwa76b2712017-09-20 12:02:26 -07003993};
3994
3995TEST_F(ScreenCaptureTest, CaptureSingleLayer) {
3996 auto bgHandle = mBGSurfaceControl->getHandle();
Chavi Weingarten40482ff2017-11-30 01:51:40 +00003997 ScreenCapture::captureLayers(&mCapture, bgHandle);
chaviwa76b2712017-09-20 12:02:26 -07003998 mCapture->expectBGColor(0, 0);
3999 // Doesn't capture FG layer which is at 64, 64
4000 mCapture->expectBGColor(64, 64);
4001}
4002
4003TEST_F(ScreenCaptureTest, CaptureLayerWithChild) {
4004 auto fgHandle = mFGSurfaceControl->getHandle();
4005
Vishnu Nair88a11f22018-11-28 18:30:57 -08004006 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
4007 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
chaviwa76b2712017-09-20 12:02:26 -07004008 fillSurfaceRGBA8(child, 200, 200, 200);
4009
Chia-I Wu1078bbb2017-10-20 11:29:02 -07004010 SurfaceComposerClient::Transaction().show(child).apply(true);
chaviwa76b2712017-09-20 12:02:26 -07004011
4012 // Captures mFGSurfaceControl layer and its child.
Chavi Weingarten40482ff2017-11-30 01:51:40 +00004013 ScreenCapture::captureLayers(&mCapture, fgHandle);
chaviwa76b2712017-09-20 12:02:26 -07004014 mCapture->expectFGColor(10, 10);
4015 mCapture->expectChildColor(0, 0);
4016}
4017
Robert Carr578038f2018-03-09 12:25:24 -08004018TEST_F(ScreenCaptureTest, CaptureLayerChildOnly) {
4019 auto fgHandle = mFGSurfaceControl->getHandle();
4020
Vishnu Nair88a11f22018-11-28 18:30:57 -08004021 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
4022 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
Robert Carr578038f2018-03-09 12:25:24 -08004023 fillSurfaceRGBA8(child, 200, 200, 200);
4024
4025 SurfaceComposerClient::Transaction().show(child).apply(true);
4026
4027 // Captures mFGSurfaceControl's child
4028 ScreenCapture::captureChildLayers(&mCapture, fgHandle);
4029 mCapture->checkPixel(10, 10, 0, 0, 0);
4030 mCapture->expectChildColor(0, 0);
4031}
4032
chaviw50da5042018-04-09 13:49:37 -07004033TEST_F(ScreenCaptureTest, CaptureTransparent) {
Vishnu Nair88a11f22018-11-28 18:30:57 -08004034 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
4035 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
chaviw50da5042018-04-09 13:49:37 -07004036
4037 fillSurfaceRGBA8(child, 200, 200, 200);
4038
4039 SurfaceComposerClient::Transaction().show(child).apply(true);
4040
4041 auto childHandle = child->getHandle();
4042
4043 // Captures child
4044 ScreenCapture::captureLayers(&mCapture, childHandle, {0, 0, 10, 20});
4045 mCapture->expectColor(Rect(0, 0, 9, 9), {200, 200, 200, 255});
4046 // Area outside of child's bounds is transparent.
4047 mCapture->expectColor(Rect(0, 10, 9, 19), {0, 0, 0, 0});
4048}
4049
chaviw4b129c22018-04-09 16:19:43 -07004050TEST_F(ScreenCaptureTest, DontCaptureRelativeOutsideTree) {
4051 auto fgHandle = mFGSurfaceControl->getHandle();
4052
Vishnu Nair88a11f22018-11-28 18:30:57 -08004053 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
4054 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
4055 ASSERT_NE(nullptr, child.get()) << "failed to create surface";
chaviw0e3479f2018-09-10 16:49:30 -07004056 sp<SurfaceControl> relative = createLayer(String8("Relative surface"), 10, 10, 0);
chaviw4b129c22018-04-09 16:19:43 -07004057 fillSurfaceRGBA8(child, 200, 200, 200);
4058 fillSurfaceRGBA8(relative, 100, 100, 100);
4059
4060 SurfaceComposerClient::Transaction()
4061 .show(child)
4062 // Set relative layer above fg layer so should be shown above when computing all layers.
4063 .setRelativeLayer(relative, fgHandle, 1)
4064 .show(relative)
4065 .apply(true);
4066
4067 // Captures mFGSurfaceControl layer and its child. Relative layer shouldn't be captured.
4068 ScreenCapture::captureLayers(&mCapture, fgHandle);
4069 mCapture->expectFGColor(10, 10);
4070 mCapture->expectChildColor(0, 0);
4071}
4072
4073TEST_F(ScreenCaptureTest, CaptureRelativeInTree) {
4074 auto fgHandle = mFGSurfaceControl->getHandle();
4075
Vishnu Nair88a11f22018-11-28 18:30:57 -08004076 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
4077 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
4078 sp<SurfaceControl> relative = createSurface(mClient, "Relative surface", 10, 10,
4079 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
chaviw4b129c22018-04-09 16:19:43 -07004080 fillSurfaceRGBA8(child, 200, 200, 200);
4081 fillSurfaceRGBA8(relative, 100, 100, 100);
4082
4083 SurfaceComposerClient::Transaction()
4084 .show(child)
4085 // Set relative layer below fg layer but relative to child layer so it should be shown
4086 // above child layer.
4087 .setLayer(relative, -1)
4088 .setRelativeLayer(relative, child->getHandle(), 1)
4089 .show(relative)
4090 .apply(true);
4091
4092 // Captures mFGSurfaceControl layer and its children. Relative layer is a child of fg so its
4093 // relative value should be taken into account, placing it above child layer.
4094 ScreenCapture::captureLayers(&mCapture, fgHandle);
4095 mCapture->expectFGColor(10, 10);
4096 // Relative layer is showing on top of child layer
4097 mCapture->expectColor(Rect(0, 0, 9, 9), {100, 100, 100, 255});
4098}
Robert Carr578038f2018-03-09 12:25:24 -08004099
4100// In the following tests we verify successful skipping of a parent layer,
4101// so we use the same verification logic and only change how we mutate
4102// the parent layer to verify that various properties are ignored.
4103class ScreenCaptureChildOnlyTest : public LayerUpdateTest {
4104public:
4105 void SetUp() override {
4106 LayerUpdateTest::SetUp();
4107
Vishnu Nair88a11f22018-11-28 18:30:57 -08004108 mChild = createSurface(mClient, "Child surface", 10, 10, PIXEL_FORMAT_RGBA_8888, 0,
4109 mFGSurfaceControl.get());
Robert Carr578038f2018-03-09 12:25:24 -08004110 fillSurfaceRGBA8(mChild, 200, 200, 200);
4111
4112 SurfaceComposerClient::Transaction().show(mChild).apply(true);
4113 }
4114
4115 void verify() {
4116 auto fgHandle = mFGSurfaceControl->getHandle();
4117 ScreenCapture::captureChildLayers(&mCapture, fgHandle);
4118 mCapture->checkPixel(10, 10, 0, 0, 0);
4119 mCapture->expectChildColor(0, 0);
4120 }
4121
4122 std::unique_ptr<ScreenCapture> mCapture;
4123 sp<SurfaceControl> mChild;
4124};
4125
4126TEST_F(ScreenCaptureChildOnlyTest, CaptureLayerIgnoresParentVisibility) {
4127
4128 SurfaceComposerClient::Transaction().hide(mFGSurfaceControl).apply(true);
4129
4130 // Even though the parent is hidden we should still capture the child.
4131 verify();
4132}
4133
4134TEST_F(ScreenCaptureChildOnlyTest, CaptureLayerIgnoresParentCrop) {
Marissa Wallf58c14b2018-07-24 10:50:43 -07004135 SurfaceComposerClient::Transaction()
4136 .setCrop_legacy(mFGSurfaceControl, Rect(0, 0, 1, 1))
4137 .apply(true);
Robert Carr578038f2018-03-09 12:25:24 -08004138
4139 // Even though the parent is cropped out we should still capture the child.
4140 verify();
4141}
4142
4143TEST_F(ScreenCaptureChildOnlyTest, CaptureLayerIgnoresTransform) {
4144
4145 SurfaceComposerClient::Transaction().setMatrix(mFGSurfaceControl, 2, 0, 0, 2);
4146
4147 // We should not inherit the parent scaling.
4148 verify();
4149}
4150
Robert Carr15eae092018-03-23 13:43:53 -07004151TEST_F(ScreenCaptureChildOnlyTest, RegressionTest76099859) {
4152 SurfaceComposerClient::Transaction().hide(mFGSurfaceControl).apply(true);
4153
4154 // Even though the parent is hidden we should still capture the child.
4155 verify();
4156
4157 // Verify everything was properly hidden when rendering the full-screen.
4158 screenshot()->expectBGColor(0,0);
4159}
4160
4161
chaviwa76b2712017-09-20 12:02:26 -07004162TEST_F(ScreenCaptureTest, CaptureLayerWithGrandchild) {
4163 auto fgHandle = mFGSurfaceControl->getHandle();
4164
Vishnu Nair88a11f22018-11-28 18:30:57 -08004165 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
4166 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
chaviwa76b2712017-09-20 12:02:26 -07004167 fillSurfaceRGBA8(child, 200, 200, 200);
4168
Vishnu Nair88a11f22018-11-28 18:30:57 -08004169 sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 5, 5,
4170 PIXEL_FORMAT_RGBA_8888, 0, child.get());
chaviwa76b2712017-09-20 12:02:26 -07004171
4172 fillSurfaceRGBA8(grandchild, 50, 50, 50);
4173 SurfaceComposerClient::Transaction()
Chia-I Wu1078bbb2017-10-20 11:29:02 -07004174 .show(child)
4175 .setPosition(grandchild, 5, 5)
4176 .show(grandchild)
4177 .apply(true);
chaviwa76b2712017-09-20 12:02:26 -07004178
4179 // Captures mFGSurfaceControl, its child, and the grandchild.
Chavi Weingarten40482ff2017-11-30 01:51:40 +00004180 ScreenCapture::captureLayers(&mCapture, fgHandle);
chaviwa76b2712017-09-20 12:02:26 -07004181 mCapture->expectFGColor(10, 10);
4182 mCapture->expectChildColor(0, 0);
4183 mCapture->checkPixel(5, 5, 50, 50, 50);
4184}
4185
4186TEST_F(ScreenCaptureTest, CaptureChildOnly) {
Vishnu Nair88a11f22018-11-28 18:30:57 -08004187 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
4188 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
chaviwa76b2712017-09-20 12:02:26 -07004189 fillSurfaceRGBA8(child, 200, 200, 200);
4190 auto childHandle = child->getHandle();
4191
Chia-I Wu1078bbb2017-10-20 11:29:02 -07004192 SurfaceComposerClient::Transaction().setPosition(child, 5, 5).show(child).apply(true);
chaviwa76b2712017-09-20 12:02:26 -07004193
4194 // Captures only the child layer, and not the parent.
Chavi Weingarten40482ff2017-11-30 01:51:40 +00004195 ScreenCapture::captureLayers(&mCapture, childHandle);
chaviwa76b2712017-09-20 12:02:26 -07004196 mCapture->expectChildColor(0, 0);
4197 mCapture->expectChildColor(9, 9);
4198}
4199
4200TEST_F(ScreenCaptureTest, CaptureGrandchildOnly) {
Vishnu Nair88a11f22018-11-28 18:30:57 -08004201 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
4202 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
chaviwa76b2712017-09-20 12:02:26 -07004203 fillSurfaceRGBA8(child, 200, 200, 200);
4204 auto childHandle = child->getHandle();
4205
Vishnu Nair88a11f22018-11-28 18:30:57 -08004206 sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 5, 5,
4207 PIXEL_FORMAT_RGBA_8888, 0, child.get());
chaviwa76b2712017-09-20 12:02:26 -07004208 fillSurfaceRGBA8(grandchild, 50, 50, 50);
4209
4210 SurfaceComposerClient::Transaction()
Chia-I Wu1078bbb2017-10-20 11:29:02 -07004211 .show(child)
4212 .setPosition(grandchild, 5, 5)
4213 .show(grandchild)
4214 .apply(true);
chaviwa76b2712017-09-20 12:02:26 -07004215
4216 auto grandchildHandle = grandchild->getHandle();
4217
4218 // Captures only the grandchild.
Chavi Weingarten40482ff2017-11-30 01:51:40 +00004219 ScreenCapture::captureLayers(&mCapture, grandchildHandle);
chaviwa76b2712017-09-20 12:02:26 -07004220 mCapture->checkPixel(0, 0, 50, 50, 50);
4221 mCapture->checkPixel(4, 4, 50, 50, 50);
4222}
4223
chaviw7206d492017-11-10 16:16:12 -08004224TEST_F(ScreenCaptureTest, CaptureCrop) {
chaviw0e3479f2018-09-10 16:49:30 -07004225 sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60, 0);
Vishnu Nair88a11f22018-11-28 18:30:57 -08004226 sp<SurfaceControl> blueLayer = createSurface(mClient, "Blue surface", 30, 30,
4227 PIXEL_FORMAT_RGBA_8888, 0, redLayer.get());
chaviw7206d492017-11-10 16:16:12 -08004228
Marissa Wall61c58622018-07-18 10:12:20 -07004229 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60));
4230 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(blueLayer, Color::BLUE, 30, 30));
chaviw7206d492017-11-10 16:16:12 -08004231
4232 SurfaceComposerClient::Transaction()
Chavi Weingarten40482ff2017-11-30 01:51:40 +00004233 .setLayer(redLayer, INT32_MAX - 1)
4234 .show(redLayer)
4235 .show(blueLayer)
4236 .apply(true);
chaviw7206d492017-11-10 16:16:12 -08004237
4238 auto redLayerHandle = redLayer->getHandle();
4239
4240 // Capturing full screen should have both red and blue are visible.
Chavi Weingarten40482ff2017-11-30 01:51:40 +00004241 ScreenCapture::captureLayers(&mCapture, redLayerHandle);
4242 mCapture->expectColor(Rect(0, 0, 29, 29), Color::BLUE);
4243 // red area below the blue area
4244 mCapture->expectColor(Rect(0, 30, 59, 59), Color::RED);
4245 // red area to the right of the blue area
4246 mCapture->expectColor(Rect(30, 0, 59, 59), Color::RED);
chaviw7206d492017-11-10 16:16:12 -08004247
4248 Rect crop = Rect(0, 0, 30, 30);
Chavi Weingarten40482ff2017-11-30 01:51:40 +00004249 ScreenCapture::captureLayers(&mCapture, redLayerHandle, crop);
chaviw7206d492017-11-10 16:16:12 -08004250 // Capturing the cropped screen, cropping out the shown red area, should leave only the blue
4251 // area visible.
Chavi Weingarten40482ff2017-11-30 01:51:40 +00004252 mCapture->expectColor(Rect(0, 0, 29, 29), Color::BLUE);
chaviw7206d492017-11-10 16:16:12 -08004253 mCapture->checkPixel(30, 30, 0, 0, 0);
4254}
4255
4256TEST_F(ScreenCaptureTest, CaptureSize) {
chaviw0e3479f2018-09-10 16:49:30 -07004257 sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60, 0);
Vishnu Nair88a11f22018-11-28 18:30:57 -08004258 sp<SurfaceControl> blueLayer = createSurface(mClient, "Blue surface", 30, 30,
4259 PIXEL_FORMAT_RGBA_8888, 0, redLayer.get());
chaviw7206d492017-11-10 16:16:12 -08004260
Marissa Wall61c58622018-07-18 10:12:20 -07004261 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60));
4262 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(blueLayer, Color::BLUE, 30, 30));
chaviw7206d492017-11-10 16:16:12 -08004263
4264 SurfaceComposerClient::Transaction()
Chavi Weingarten40482ff2017-11-30 01:51:40 +00004265 .setLayer(redLayer, INT32_MAX - 1)
4266 .show(redLayer)
4267 .show(blueLayer)
4268 .apply(true);
chaviw7206d492017-11-10 16:16:12 -08004269
4270 auto redLayerHandle = redLayer->getHandle();
4271
4272 // Capturing full screen should have both red and blue are visible.
Chavi Weingarten40482ff2017-11-30 01:51:40 +00004273 ScreenCapture::captureLayers(&mCapture, redLayerHandle);
4274 mCapture->expectColor(Rect(0, 0, 29, 29), Color::BLUE);
4275 // red area below the blue area
4276 mCapture->expectColor(Rect(0, 30, 59, 59), Color::RED);
4277 // red area to the right of the blue area
4278 mCapture->expectColor(Rect(30, 0, 59, 59), Color::RED);
chaviw7206d492017-11-10 16:16:12 -08004279
Chavi Weingarten40482ff2017-11-30 01:51:40 +00004280 ScreenCapture::captureLayers(&mCapture, redLayerHandle, Rect::EMPTY_RECT, 0.5);
chaviw7206d492017-11-10 16:16:12 -08004281 // Capturing the downsized area (30x30) should leave both red and blue but in a smaller area.
Chavi Weingarten40482ff2017-11-30 01:51:40 +00004282 mCapture->expectColor(Rect(0, 0, 14, 14), Color::BLUE);
4283 // red area below the blue area
4284 mCapture->expectColor(Rect(0, 15, 29, 29), Color::RED);
4285 // red area to the right of the blue area
4286 mCapture->expectColor(Rect(15, 0, 29, 29), Color::RED);
chaviw7206d492017-11-10 16:16:12 -08004287 mCapture->checkPixel(30, 30, 0, 0, 0);
4288}
4289
4290TEST_F(ScreenCaptureTest, CaptureInvalidLayer) {
chaviw0e3479f2018-09-10 16:49:30 -07004291 sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60, 0);
chaviw7206d492017-11-10 16:16:12 -08004292
Marissa Wall61c58622018-07-18 10:12:20 -07004293 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60));
chaviw7206d492017-11-10 16:16:12 -08004294
4295 auto redLayerHandle = redLayer->getHandle();
chaviw0e3479f2018-09-10 16:49:30 -07004296 mClient->destroySurface(redLayerHandle);
chaviw7206d492017-11-10 16:16:12 -08004297 SurfaceComposerClient::Transaction().apply(true);
4298
Chavi Weingarten40482ff2017-11-30 01:51:40 +00004299 sp<GraphicBuffer> outBuffer;
chaviw7206d492017-11-10 16:16:12 -08004300
4301 // Layer was deleted so captureLayers should fail with NAME_NOT_FOUND
Chavi Weingarten40482ff2017-11-30 01:51:40 +00004302 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
4303 ASSERT_EQ(NAME_NOT_FOUND, sf->captureLayers(redLayerHandle, &outBuffer, Rect::EMPTY_RECT, 1.0));
chaviw7206d492017-11-10 16:16:12 -08004304}
4305
chaviw8e3fe5d2018-02-22 10:55:42 -08004306
4307class DereferenceSurfaceControlTest : public LayerTransactionTest {
4308protected:
4309 void SetUp() override {
4310 LayerTransactionTest::SetUp();
4311 bgLayer = createLayer("BG layer", 20, 20);
Marissa Wall61c58622018-07-18 10:12:20 -07004312 fillBufferQueueLayerColor(bgLayer, Color::RED, 20, 20);
chaviw8e3fe5d2018-02-22 10:55:42 -08004313 fgLayer = createLayer("FG layer", 20, 20);
Marissa Wall61c58622018-07-18 10:12:20 -07004314 fillBufferQueueLayerColor(fgLayer, Color::BLUE, 20, 20);
chaviw8e3fe5d2018-02-22 10:55:42 -08004315 Transaction().setLayer(fgLayer, mLayerZBase + 1).apply();
4316 {
4317 SCOPED_TRACE("before anything");
4318 auto shot = screenshot();
4319 shot->expectColor(Rect(0, 0, 20, 20), Color::BLUE);
4320 }
4321 }
4322 void TearDown() override {
4323 LayerTransactionTest::TearDown();
4324 bgLayer = 0;
4325 fgLayer = 0;
4326 }
4327
4328 sp<SurfaceControl> bgLayer;
4329 sp<SurfaceControl> fgLayer;
4330};
4331
4332TEST_F(DereferenceSurfaceControlTest, LayerNotInTransaction) {
4333 fgLayer = nullptr;
4334 {
4335 SCOPED_TRACE("after setting null");
4336 auto shot = screenshot();
4337 shot->expectColor(Rect(0, 0, 20, 20), Color::RED);
4338 }
4339}
4340
4341TEST_F(DereferenceSurfaceControlTest, LayerInTransaction) {
4342 auto transaction = Transaction().show(fgLayer);
4343 fgLayer = nullptr;
4344 {
4345 SCOPED_TRACE("after setting null");
4346 auto shot = screenshot();
4347 shot->expectColor(Rect(0, 0, 20, 20), Color::BLUE);
4348 }
4349}
4350
Chavi Weingarten40482ff2017-11-30 01:51:40 +00004351} // namespace android