blob: 43386b2ae7387b6145c009d5cd61ef395255938d [file] [log] [blame]
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001/*
2 * Copyright (C) 2019 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 */
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -080016
17#pragma once
Valerie Hau9cfc6d82019-09-23 13:54:07 -070018
Marin Shalamanov30b0b3c2020-10-13 19:15:06 +020019// TODO(b/129481165): remove the #pragma below and fix conversion issues
20#pragma clang diagnostic push
21#pragma clang diagnostic ignored "-Wconversion"
Marin Shalamanovbed7fd32020-12-21 20:02:20 +010022#pragma clang diagnostic ignored "-Wextra"
Marin Shalamanov30b0b3c2020-10-13 19:15:06 +020023
Galia Peycheva561d05c2021-03-08 15:14:05 +010024#include <cutils/properties.h>
Valerie Hau9cfc6d82019-09-23 13:54:07 -070025#include <gtest/gtest.h>
Valerie Hau9cfc6d82019-09-23 13:54:07 -070026#include <gui/ISurfaceComposer.h>
27#include <gui/SurfaceComposerClient.h>
Valerie Hau9cfc6d82019-09-23 13:54:07 -070028#include <private/gui/ComposerService.h>
Huihong Luo05539a12022-02-23 10:29:40 -080029#include <private/gui/ComposerServiceAIDL.h>
Marin Shalamanova7fe3042021-01-29 21:02:08 +010030#include <ui/DisplayMode.h>
Valerie Hau9cfc6d82019-09-23 13:54:07 -070031
32#include "BufferGenerator.h"
33#include "utils/ScreenshotUtils.h"
34#include "utils/TransactionUtils.h"
35
36namespace android {
37
38using android::hardware::graphics::common::V1_1::BufferUsage;
39
40class LayerTransactionTest : public ::testing::Test {
41protected:
42 void SetUp() override {
43 mClient = new SurfaceComposerClient;
44 ASSERT_EQ(NO_ERROR, mClient->initCheck()) << "failed to create SurfaceComposerClient";
45
46 ASSERT_NO_FATAL_FAILURE(SetUpDisplay());
47
Huihong Luo05539a12022-02-23 10:29:40 -080048 sp<gui::ISurfaceComposer> sf(ComposerServiceAIDL::getComposerService());
49 binder::Status status = sf->getColorManagement(&mColorManagementUsed);
50 ASSERT_NO_FATAL_FAILURE(status.transactionError());
chaviwd2432892020-07-24 17:42:39 -070051
52 mCaptureArgs.displayToken = mDisplay;
Valerie Hau9cfc6d82019-09-23 13:54:07 -070053 }
54
55 virtual void TearDown() {
56 mBlackBgSurface = 0;
57 mClient->dispose();
58 mClient = 0;
59 }
60
61 virtual sp<SurfaceControl> createLayer(const sp<SurfaceComposerClient>& client,
62 const char* name, uint32_t width, uint32_t height,
Valerie Hau1acd6962019-10-28 16:35:48 -070063 uint32_t flags = 0, SurfaceControl* parent = nullptr,
chaviwdebadb82020-03-26 14:57:24 -070064 uint32_t* outTransformHint = nullptr,
65 PixelFormat format = PIXEL_FORMAT_RGBA_8888) {
66 auto layer =
67 createSurface(client, name, width, height, format, flags, parent, outTransformHint);
Valerie Hau9cfc6d82019-09-23 13:54:07 -070068
69 Transaction t;
70 t.setLayerStack(layer, mDisplayLayerStack).setLayer(layer, mLayerZBase);
71
72 status_t error = t.apply();
73 if (error != NO_ERROR) {
74 ADD_FAILURE() << "failed to initialize SurfaceControl";
75 layer.clear();
76 }
77
78 return layer;
79 }
80
81 virtual sp<SurfaceControl> createSurface(const sp<SurfaceComposerClient>& client,
82 const char* name, uint32_t width, uint32_t height,
83 PixelFormat format, uint32_t flags,
Valerie Hau1acd6962019-10-28 16:35:48 -070084 SurfaceControl* parent = nullptr,
85 uint32_t* outTransformHint = nullptr) {
Vishnu Nair992496b2020-10-22 17:27:21 -070086 sp<IBinder> parentHandle = (parent) ? parent->getHandle() : nullptr;
87 auto layer = client->createSurface(String8(name), width, height, format, flags,
88 parentHandle, LayerMetadata(), outTransformHint);
Valerie Hau9cfc6d82019-09-23 13:54:07 -070089 EXPECT_NE(nullptr, layer.get()) << "failed to create SurfaceControl";
90 return layer;
91 }
92
93 virtual sp<SurfaceControl> createLayer(const char* name, uint32_t width, uint32_t height,
Valerie Hau1acd6962019-10-28 16:35:48 -070094 uint32_t flags = 0, SurfaceControl* parent = nullptr,
chaviwdebadb82020-03-26 14:57:24 -070095 uint32_t* outTransformHint = nullptr,
96 PixelFormat format = PIXEL_FORMAT_RGBA_8888) {
97 return createLayer(mClient, name, width, height, flags, parent, outTransformHint, format);
Valerie Hau9cfc6d82019-09-23 13:54:07 -070098 }
99
100 sp<SurfaceControl> createColorLayer(const char* name, const Color& color,
101 SurfaceControl* parent = nullptr) {
102 auto colorLayer = createSurface(mClient, name, 0 /* buffer width */, 0 /* buffer height */,
103 PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800104 ISurfaceComposerClient::eFXSurfaceEffect, parent);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700105 asTransaction([&](Transaction& t) {
106 t.setColor(colorLayer, half3{color.r / 255.0f, color.g / 255.0f, color.b / 255.0f});
107 t.setAlpha(colorLayer, color.a / 255.0f);
108 });
109 return colorLayer;
110 }
111
112 ANativeWindow_Buffer getBufferQueueLayerBuffer(const sp<SurfaceControl>& layer) {
113 // wait for previous transactions (such as setSize) to complete
114 Transaction().apply(true);
115
116 ANativeWindow_Buffer buffer = {};
117 EXPECT_EQ(NO_ERROR, layer->getSurface()->lock(&buffer, nullptr));
118
119 return buffer;
120 }
121
122 void postBufferQueueLayerBuffer(const sp<SurfaceControl>& layer) {
123 ASSERT_EQ(NO_ERROR, layer->getSurface()->unlockAndPost());
124
125 // wait for the newly posted buffer to be latched
126 waitForLayerBuffers();
127 }
128
129 virtual void fillBufferQueueLayerColor(const sp<SurfaceControl>& layer, const Color& color,
Marin Shalamanov46084422020-10-13 12:33:42 +0200130 uint32_t bufferWidth, uint32_t bufferHeight) {
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700131 ANativeWindow_Buffer buffer;
132 ASSERT_NO_FATAL_FAILURE(buffer = getBufferQueueLayerBuffer(layer));
133 TransactionUtils::fillANativeWindowBufferColor(buffer,
134 Rect(0, 0, bufferWidth, bufferHeight),
135 color);
136 postBufferQueueLayerBuffer(layer);
137 }
138
139 virtual void fillBufferStateLayerColor(const sp<SurfaceControl>& layer, const Color& color,
140 int32_t bufferWidth, int32_t bufferHeight) {
141 sp<GraphicBuffer> buffer =
142 new GraphicBuffer(bufferWidth, bufferHeight, PIXEL_FORMAT_RGBA_8888, 1,
143 BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
Ady Abraham193426d2021-02-18 14:01:53 -0800144 BufferUsage::COMPOSER_OVERLAY | BufferUsage::GPU_TEXTURE,
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700145 "test");
146 TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, 0, bufferWidth, bufferHeight),
147 color);
148 Transaction().setBuffer(layer, buffer).apply();
149 }
150
151 void fillLayerColor(uint32_t mLayerType, const sp<SurfaceControl>& layer, const Color& color,
Marin Shalamanov46084422020-10-13 12:33:42 +0200152 uint32_t bufferWidth, uint32_t bufferHeight) {
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700153 switch (mLayerType) {
154 case ISurfaceComposerClient::eFXSurfaceBufferQueue:
155 fillBufferQueueLayerColor(layer, color, bufferWidth, bufferHeight);
156 break;
157 case ISurfaceComposerClient::eFXSurfaceBufferState:
158 fillBufferStateLayerColor(layer, color, bufferWidth, bufferHeight);
159 break;
160 default:
161 ASSERT_TRUE(false) << "unsupported layer type: " << mLayerType;
162 }
163 }
164
165 void fillLayerQuadrant(uint32_t mLayerType, const sp<SurfaceControl>& layer,
166 int32_t bufferWidth, int32_t bufferHeight, const Color& topLeft,
167 const Color& topRight, const Color& bottomLeft,
168 const Color& bottomRight) {
169 switch (mLayerType) {
170 case ISurfaceComposerClient::eFXSurfaceBufferQueue:
171 fillBufferQueueLayerQuadrant(layer, bufferWidth, bufferHeight, topLeft, topRight,
172 bottomLeft, bottomRight);
173 break;
174 case ISurfaceComposerClient::eFXSurfaceBufferState:
175 fillBufferStateLayerQuadrant(layer, bufferWidth, bufferHeight, topLeft, topRight,
176 bottomLeft, bottomRight);
177 break;
178 default:
179 ASSERT_TRUE(false) << "unsupported layer type: " << mLayerType;
180 }
181 }
182
183 virtual void fillBufferQueueLayerQuadrant(const sp<SurfaceControl>& layer, int32_t bufferWidth,
184 int32_t bufferHeight, const Color& topLeft,
185 const Color& topRight, const Color& bottomLeft,
186 const Color& bottomRight) {
187 ANativeWindow_Buffer buffer;
188 ASSERT_NO_FATAL_FAILURE(buffer = getBufferQueueLayerBuffer(layer));
189 ASSERT_TRUE(bufferWidth % 2 == 0 && bufferHeight % 2 == 0);
190
191 const int32_t halfW = bufferWidth / 2;
192 const int32_t halfH = bufferHeight / 2;
193 TransactionUtils::fillANativeWindowBufferColor(buffer, Rect(0, 0, halfW, halfH), topLeft);
194 TransactionUtils::fillANativeWindowBufferColor(buffer, Rect(halfW, 0, bufferWidth, halfH),
195 topRight);
196 TransactionUtils::fillANativeWindowBufferColor(buffer, Rect(0, halfH, halfW, bufferHeight),
197 bottomLeft);
198 TransactionUtils::fillANativeWindowBufferColor(buffer,
199 Rect(halfW, halfH, bufferWidth,
200 bufferHeight),
201 bottomRight);
202
203 postBufferQueueLayerBuffer(layer);
204 }
205
206 virtual void fillBufferStateLayerQuadrant(const sp<SurfaceControl>& layer, int32_t bufferWidth,
207 int32_t bufferHeight, const Color& topLeft,
208 const Color& topRight, const Color& bottomLeft,
209 const Color& bottomRight) {
210 sp<GraphicBuffer> buffer =
211 new GraphicBuffer(bufferWidth, bufferHeight, PIXEL_FORMAT_RGBA_8888, 1,
212 BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
Ady Abraham193426d2021-02-18 14:01:53 -0800213 BufferUsage::COMPOSER_OVERLAY | BufferUsage::GPU_TEXTURE,
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700214 "test");
215
216 ASSERT_TRUE(bufferWidth % 2 == 0 && bufferHeight % 2 == 0);
217
218 const int32_t halfW = bufferWidth / 2;
219 const int32_t halfH = bufferHeight / 2;
220 TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, 0, halfW, halfH), topLeft);
221 TransactionUtils::fillGraphicBufferColor(buffer, Rect(halfW, 0, bufferWidth, halfH),
222 topRight);
223 TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, halfH, halfW, bufferHeight),
224 bottomLeft);
225 TransactionUtils::fillGraphicBufferColor(buffer,
226 Rect(halfW, halfH, bufferWidth, bufferHeight),
227 bottomRight);
228
229 Transaction().setBuffer(layer, buffer).setSize(layer, bufferWidth, bufferHeight).apply();
230 }
231
232 std::unique_ptr<ScreenCapture> screenshot() {
233 std::unique_ptr<ScreenCapture> screenshot;
234 ScreenCapture::captureScreen(&screenshot);
235 return screenshot;
236 }
237
238 void asTransaction(const std::function<void(Transaction&)>& exec) {
239 Transaction t;
240 exec(t);
241 t.apply(true);
242 }
243
244 static status_t getBuffer(sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence) {
245 static BufferGenerator bufferGenerator;
246 return bufferGenerator.get(outBuffer, outFence);
247 }
248
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000249 static ui::Size getBufferSize() {
250 static BufferGenerator bufferGenerator;
251 return bufferGenerator.getSize();
252 }
253
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700254 sp<SurfaceComposerClient> mClient;
255
Galia Peycheva561d05c2021-03-08 15:14:05 +0100256 bool deviceSupportsBlurs() {
257 char value[PROPERTY_VALUE_MAX];
258 property_get("ro.surface_flinger.supports_background_blur", value, "0");
259 return atoi(value);
260 }
261
262 bool deviceUsesSkiaRenderEngine() {
263 char value[PROPERTY_VALUE_MAX];
264 property_get("debug.renderengine.backend", value, "default");
265 return strstr(value, "skia") != nullptr;
266 }
267
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700268 sp<IBinder> mDisplay;
269 uint32_t mDisplayWidth;
270 uint32_t mDisplayHeight;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700271 ui::LayerStack mDisplayLayerStack = ui::DEFAULT_LAYER_STACK;
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700272 Rect mDisplayRect = Rect::INVALID_RECT;
273
274 // leave room for ~256 layers
275 const int32_t mLayerZBase = std::numeric_limits<int32_t>::max() - 256;
276
277 sp<SurfaceControl> mBlackBgSurface;
278 bool mColorManagementUsed;
279
chaviwd2432892020-07-24 17:42:39 -0700280 DisplayCaptureArgs mCaptureArgs;
281 ScreenCaptureResults mCaptureResults;
282
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700283private:
284 void SetUpDisplay() {
285 mDisplay = mClient->getInternalDisplayToken();
286 ASSERT_FALSE(mDisplay == nullptr) << "failed to get display";
287
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100288 ui::DisplayMode mode;
289 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(mDisplay, &mode));
290 mDisplayRect = Rect(mode.resolution);
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -0800291 mDisplayWidth = mDisplayRect.getWidth();
292 mDisplayHeight = mDisplayRect.getHeight();
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700293
294 // After a new buffer is queued, SurfaceFlinger is notified and will
295 // latch the new buffer on next vsync. Let's heuristically wait for 3
296 // vsyncs.
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100297 mBufferPostDelay = static_cast<int32_t>(1e6 / mode.refreshRate) * 3;
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700298
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700299 mBlackBgSurface =
300 createSurface(mClient, "BaseSurface", 0 /* buffer width */, 0 /* buffer height */,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800301 PIXEL_FORMAT_RGBA_8888, ISurfaceComposerClient::eFXSurfaceEffect);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700302
303 // set layer stack (b/68888219)
304 Transaction t;
305 t.setDisplayLayerStack(mDisplay, mDisplayLayerStack);
chaviw25714502021-02-11 10:01:08 -0800306 t.setCrop(mBlackBgSurface, Rect(0, 0, mDisplayWidth, mDisplayHeight));
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700307 t.setLayerStack(mBlackBgSurface, mDisplayLayerStack);
308 t.setColor(mBlackBgSurface, half3{0, 0, 0});
309 t.setLayer(mBlackBgSurface, mLayerZBase);
310 t.apply();
311 }
312
313 void waitForLayerBuffers() {
314 // Request an empty transaction to get applied synchronously to ensure the buffer is
315 // latched.
316 Transaction().apply(true);
317 usleep(mBufferPostDelay);
318 }
319
320 int32_t mBufferPostDelay;
321
322 friend class LayerRenderPathTestHarness;
323};
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700324
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -0800325} // namespace android
Marin Shalamanov30b0b3c2020-10-13 19:15:06 +0200326
327// TODO(b/129481165): remove the #pragma below and fix conversion issues
Galia Peycheva561d05c2021-03-08 15:14:05 +0100328#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"