blob: 5b056d07650404a7365abc280179793a14968a00 [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>
Huihong Luo3bdef862022-03-03 11:57:19 -080026#include <gui/AidlStatusUtil.h>
Valerie Hau9cfc6d82019-09-23 13:54:07 -070027#include <gui/ISurfaceComposer.h>
28#include <gui/SurfaceComposerClient.h>
Valerie Hau9cfc6d82019-09-23 13:54:07 -070029#include <private/gui/ComposerService.h>
Huihong Luo05539a12022-02-23 10:29:40 -080030#include <private/gui/ComposerServiceAIDL.h>
Marin Shalamanova7fe3042021-01-29 21:02:08 +010031#include <ui/DisplayMode.h>
Valerie Hau9cfc6d82019-09-23 13:54:07 -070032
33#include "BufferGenerator.h"
34#include "utils/ScreenshotUtils.h"
35#include "utils/TransactionUtils.h"
36
37namespace android {
38
39using android::hardware::graphics::common::V1_1::BufferUsage;
40
41class LayerTransactionTest : public ::testing::Test {
42protected:
43 void SetUp() override {
Ady Abrahamd11bade2022-08-01 16:18:03 -070044 mClient = sp<SurfaceComposerClient>::make();
Valerie Hau9cfc6d82019-09-23 13:54:07 -070045 ASSERT_EQ(NO_ERROR, mClient->initCheck()) << "failed to create SurfaceComposerClient";
46
47 ASSERT_NO_FATAL_FAILURE(SetUpDisplay());
48
Huihong Luo05539a12022-02-23 10:29:40 -080049 sp<gui::ISurfaceComposer> sf(ComposerServiceAIDL::getComposerService());
Valerie Hau9cfc6d82019-09-23 13:54:07 -070050 }
51
52 virtual void TearDown() {
53 mBlackBgSurface = 0;
54 mClient->dispose();
55 mClient = 0;
56 }
57
58 virtual sp<SurfaceControl> createLayer(const sp<SurfaceComposerClient>& client,
59 const char* name, uint32_t width, uint32_t height,
Valerie Hau1acd6962019-10-28 16:35:48 -070060 uint32_t flags = 0, SurfaceControl* parent = nullptr,
chaviwdebadb82020-03-26 14:57:24 -070061 uint32_t* outTransformHint = nullptr,
62 PixelFormat format = PIXEL_FORMAT_RGBA_8888) {
63 auto layer =
64 createSurface(client, name, width, height, format, flags, parent, outTransformHint);
Valerie Hau9cfc6d82019-09-23 13:54:07 -070065
66 Transaction t;
67 t.setLayerStack(layer, mDisplayLayerStack).setLayer(layer, mLayerZBase);
68
69 status_t error = t.apply();
70 if (error != NO_ERROR) {
71 ADD_FAILURE() << "failed to initialize SurfaceControl";
72 layer.clear();
73 }
74
75 return layer;
76 }
77
78 virtual sp<SurfaceControl> createSurface(const sp<SurfaceComposerClient>& client,
79 const char* name, uint32_t width, uint32_t height,
80 PixelFormat format, uint32_t flags,
Valerie Hau1acd6962019-10-28 16:35:48 -070081 SurfaceControl* parent = nullptr,
82 uint32_t* outTransformHint = nullptr) {
Vishnu Nair992496b2020-10-22 17:27:21 -070083 sp<IBinder> parentHandle = (parent) ? parent->getHandle() : nullptr;
84 auto layer = client->createSurface(String8(name), width, height, format, flags,
85 parentHandle, LayerMetadata(), outTransformHint);
Valerie Hau9cfc6d82019-09-23 13:54:07 -070086 EXPECT_NE(nullptr, layer.get()) << "failed to create SurfaceControl";
87 return layer;
88 }
89
90 virtual sp<SurfaceControl> createLayer(const char* name, uint32_t width, uint32_t height,
Valerie Hau1acd6962019-10-28 16:35:48 -070091 uint32_t flags = 0, SurfaceControl* parent = nullptr,
chaviwdebadb82020-03-26 14:57:24 -070092 uint32_t* outTransformHint = nullptr,
93 PixelFormat format = PIXEL_FORMAT_RGBA_8888) {
94 return createLayer(mClient, name, width, height, flags, parent, outTransformHint, format);
Valerie Hau9cfc6d82019-09-23 13:54:07 -070095 }
96
97 sp<SurfaceControl> createColorLayer(const char* name, const Color& color,
98 SurfaceControl* parent = nullptr) {
99 auto colorLayer = createSurface(mClient, name, 0 /* buffer width */, 0 /* buffer height */,
100 PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800101 ISurfaceComposerClient::eFXSurfaceEffect, parent);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700102 asTransaction([&](Transaction& t) {
103 t.setColor(colorLayer, half3{color.r / 255.0f, color.g / 255.0f, color.b / 255.0f});
104 t.setAlpha(colorLayer, color.a / 255.0f);
105 });
106 return colorLayer;
107 }
108
Melody Hsu70c2ee62024-03-29 21:58:45 +0000109 sp<SurfaceControl> mirrorSurface(SurfaceControl* mirrorFromSurface) {
110 return mClient->mirrorSurface(mirrorFromSurface);
111 }
112
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700113 ANativeWindow_Buffer getBufferQueueLayerBuffer(const sp<SurfaceControl>& layer) {
114 // wait for previous transactions (such as setSize) to complete
115 Transaction().apply(true);
116
117 ANativeWindow_Buffer buffer = {};
118 EXPECT_EQ(NO_ERROR, layer->getSurface()->lock(&buffer, nullptr));
119
120 return buffer;
121 }
122
123 void postBufferQueueLayerBuffer(const sp<SurfaceControl>& layer) {
124 ASSERT_EQ(NO_ERROR, layer->getSurface()->unlockAndPost());
125
126 // wait for the newly posted buffer to be latched
127 waitForLayerBuffers();
128 }
129
130 virtual void fillBufferQueueLayerColor(const sp<SurfaceControl>& layer, const Color& color,
Marin Shalamanov46084422020-10-13 12:33:42 +0200131 uint32_t bufferWidth, uint32_t bufferHeight) {
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700132 ANativeWindow_Buffer buffer;
133 ASSERT_NO_FATAL_FAILURE(buffer = getBufferQueueLayerBuffer(layer));
134 TransactionUtils::fillANativeWindowBufferColor(buffer,
135 Rect(0, 0, bufferWidth, bufferHeight),
136 color);
137 postBufferQueueLayerBuffer(layer);
138 }
139
Patrick Williams83f36b22022-09-14 17:57:35 +0000140 virtual void fillBufferLayerColor(const sp<SurfaceControl>& layer, const Color& color,
141 int32_t bufferWidth, int32_t bufferHeight) {
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700142 sp<GraphicBuffer> buffer =
Ady Abrahamd11bade2022-08-01 16:18:03 -0700143 sp<GraphicBuffer>::make(static_cast<uint32_t>(bufferWidth),
144 static_cast<uint32_t>(bufferHeight), PIXEL_FORMAT_RGBA_8888,
145 1u,
146 BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
147 BufferUsage::COMPOSER_OVERLAY |
148 BufferUsage::GPU_TEXTURE,
149 "test");
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700150 TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, 0, bufferWidth, bufferHeight),
151 color);
152 Transaction().setBuffer(layer, buffer).apply();
153 }
154
155 void fillLayerColor(uint32_t mLayerType, const sp<SurfaceControl>& layer, const Color& color,
Marin Shalamanov46084422020-10-13 12:33:42 +0200156 uint32_t bufferWidth, uint32_t bufferHeight) {
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700157 switch (mLayerType) {
158 case ISurfaceComposerClient::eFXSurfaceBufferQueue:
159 fillBufferQueueLayerColor(layer, color, bufferWidth, bufferHeight);
160 break;
161 case ISurfaceComposerClient::eFXSurfaceBufferState:
Patrick Williams83f36b22022-09-14 17:57:35 +0000162 fillBufferLayerColor(layer, color, bufferWidth, bufferHeight);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700163 break;
164 default:
165 ASSERT_TRUE(false) << "unsupported layer type: " << mLayerType;
166 }
167 }
168
169 void fillLayerQuadrant(uint32_t mLayerType, const sp<SurfaceControl>& layer,
170 int32_t bufferWidth, int32_t bufferHeight, const Color& topLeft,
171 const Color& topRight, const Color& bottomLeft,
172 const Color& bottomRight) {
173 switch (mLayerType) {
174 case ISurfaceComposerClient::eFXSurfaceBufferQueue:
175 fillBufferQueueLayerQuadrant(layer, bufferWidth, bufferHeight, topLeft, topRight,
176 bottomLeft, bottomRight);
177 break;
178 case ISurfaceComposerClient::eFXSurfaceBufferState:
179 fillBufferStateLayerQuadrant(layer, bufferWidth, bufferHeight, topLeft, topRight,
180 bottomLeft, bottomRight);
181 break;
182 default:
183 ASSERT_TRUE(false) << "unsupported layer type: " << mLayerType;
184 }
185 }
186
187 virtual void fillBufferQueueLayerQuadrant(const sp<SurfaceControl>& layer, int32_t bufferWidth,
188 int32_t bufferHeight, const Color& topLeft,
189 const Color& topRight, const Color& bottomLeft,
190 const Color& bottomRight) {
191 ANativeWindow_Buffer buffer;
192 ASSERT_NO_FATAL_FAILURE(buffer = getBufferQueueLayerBuffer(layer));
193 ASSERT_TRUE(bufferWidth % 2 == 0 && bufferHeight % 2 == 0);
194
195 const int32_t halfW = bufferWidth / 2;
196 const int32_t halfH = bufferHeight / 2;
197 TransactionUtils::fillANativeWindowBufferColor(buffer, Rect(0, 0, halfW, halfH), topLeft);
198 TransactionUtils::fillANativeWindowBufferColor(buffer, Rect(halfW, 0, bufferWidth, halfH),
199 topRight);
200 TransactionUtils::fillANativeWindowBufferColor(buffer, Rect(0, halfH, halfW, bufferHeight),
201 bottomLeft);
202 TransactionUtils::fillANativeWindowBufferColor(buffer,
203 Rect(halfW, halfH, bufferWidth,
204 bufferHeight),
205 bottomRight);
206
207 postBufferQueueLayerBuffer(layer);
208 }
209
210 virtual void fillBufferStateLayerQuadrant(const sp<SurfaceControl>& layer, int32_t bufferWidth,
211 int32_t bufferHeight, const Color& topLeft,
212 const Color& topRight, const Color& bottomLeft,
213 const Color& bottomRight) {
214 sp<GraphicBuffer> buffer =
Ady Abrahamd11bade2022-08-01 16:18:03 -0700215 sp<GraphicBuffer>::make(static_cast<uint32_t>(bufferWidth),
216 static_cast<uint32_t>(bufferHeight), PIXEL_FORMAT_RGBA_8888,
217 1u,
218 BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
219 BufferUsage::COMPOSER_OVERLAY |
220 BufferUsage::GPU_TEXTURE,
221 "test");
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700222
223 ASSERT_TRUE(bufferWidth % 2 == 0 && bufferHeight % 2 == 0);
224
225 const int32_t halfW = bufferWidth / 2;
226 const int32_t halfH = bufferHeight / 2;
227 TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, 0, halfW, halfH), topLeft);
228 TransactionUtils::fillGraphicBufferColor(buffer, Rect(halfW, 0, bufferWidth, halfH),
229 topRight);
230 TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, halfH, halfW, bufferHeight),
231 bottomLeft);
232 TransactionUtils::fillGraphicBufferColor(buffer,
233 Rect(halfW, halfH, bufferWidth, bufferHeight),
234 bottomRight);
235
Vishnu Nairea04b6f2022-08-19 21:28:17 +0000236 Transaction().setBuffer(layer, buffer).apply();
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700237 }
238
239 std::unique_ptr<ScreenCapture> screenshot() {
240 std::unique_ptr<ScreenCapture> screenshot;
241 ScreenCapture::captureScreen(&screenshot);
242 return screenshot;
243 }
244
245 void asTransaction(const std::function<void(Transaction&)>& exec) {
246 Transaction t;
247 exec(t);
248 t.apply(true);
249 }
250
251 static status_t getBuffer(sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence) {
252 static BufferGenerator bufferGenerator;
253 return bufferGenerator.get(outBuffer, outFence);
254 }
255
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000256 static ui::Size getBufferSize() {
257 static BufferGenerator bufferGenerator;
258 return bufferGenerator.getSize();
259 }
260
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700261 sp<SurfaceComposerClient> mClient;
262
Galia Peycheva561d05c2021-03-08 15:14:05 +0100263 bool deviceSupportsBlurs() {
264 char value[PROPERTY_VALUE_MAX];
265 property_get("ro.surface_flinger.supports_background_blur", value, "0");
266 return atoi(value);
267 }
268
269 bool deviceUsesSkiaRenderEngine() {
270 char value[PROPERTY_VALUE_MAX];
271 property_get("debug.renderengine.backend", value, "default");
272 return strstr(value, "skia") != nullptr;
273 }
274
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700275 sp<IBinder> mDisplay;
276 uint32_t mDisplayWidth;
277 uint32_t mDisplayHeight;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700278 ui::LayerStack mDisplayLayerStack = ui::DEFAULT_LAYER_STACK;
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700279 Rect mDisplayRect = Rect::INVALID_RECT;
280
281 // leave room for ~256 layers
282 const int32_t mLayerZBase = std::numeric_limits<int32_t>::max() - 256;
283
284 sp<SurfaceControl> mBlackBgSurface;
chaviwd2432892020-07-24 17:42:39 -0700285 ScreenCaptureResults mCaptureResults;
286
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700287private:
288 void SetUpDisplay() {
Huihong Luo31b5ac22022-08-15 20:38:10 -0700289 const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
290 ASSERT_FALSE(ids.empty());
291 mDisplay = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700292 ASSERT_FALSE(mDisplay == nullptr) << "failed to get display";
293
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100294 ui::DisplayMode mode;
295 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(mDisplay, &mode));
296 mDisplayRect = Rect(mode.resolution);
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -0800297 mDisplayWidth = mDisplayRect.getWidth();
298 mDisplayHeight = mDisplayRect.getHeight();
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700299
300 // After a new buffer is queued, SurfaceFlinger is notified and will
301 // latch the new buffer on next vsync. Let's heuristically wait for 3
302 // vsyncs.
Alec Mouri55e31032023-10-02 20:34:18 +0000303 mBufferPostDelay = static_cast<int32_t>(1e6 / mode.peakRefreshRate) * 3;
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700304
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700305 mBlackBgSurface =
306 createSurface(mClient, "BaseSurface", 0 /* buffer width */, 0 /* buffer height */,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800307 PIXEL_FORMAT_RGBA_8888, ISurfaceComposerClient::eFXSurfaceEffect);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700308
309 // set layer stack (b/68888219)
310 Transaction t;
311 t.setDisplayLayerStack(mDisplay, mDisplayLayerStack);
chaviw25714502021-02-11 10:01:08 -0800312 t.setCrop(mBlackBgSurface, Rect(0, 0, mDisplayWidth, mDisplayHeight));
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700313 t.setLayerStack(mBlackBgSurface, mDisplayLayerStack);
314 t.setColor(mBlackBgSurface, half3{0, 0, 0});
315 t.setLayer(mBlackBgSurface, mLayerZBase);
316 t.apply();
317 }
318
319 void waitForLayerBuffers() {
320 // Request an empty transaction to get applied synchronously to ensure the buffer is
321 // latched.
322 Transaction().apply(true);
323 usleep(mBufferPostDelay);
324 }
325
326 int32_t mBufferPostDelay;
327
328 friend class LayerRenderPathTestHarness;
329};
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700330
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -0800331} // namespace android
Marin Shalamanov30b0b3c2020-10-13 19:15:06 +0200332
333// TODO(b/129481165): remove the #pragma below and fix conversion issues
Galia Peycheva561d05c2021-03-08 15:14:05 +0100334#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"