blob: 87c7b7d829880709013042e84aa16fdc31832d2d [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>
Marin Shalamanova7fe3042021-01-29 21:02:08 +010029#include <ui/DisplayMode.h>
Valerie Hau9cfc6d82019-09-23 13:54:07 -070030
31#include "BufferGenerator.h"
32#include "utils/ScreenshotUtils.h"
33#include "utils/TransactionUtils.h"
34
35namespace android {
36
37using android::hardware::graphics::common::V1_1::BufferUsage;
38
39class LayerTransactionTest : public ::testing::Test {
40protected:
41 void SetUp() override {
42 mClient = new SurfaceComposerClient;
43 ASSERT_EQ(NO_ERROR, mClient->initCheck()) << "failed to create SurfaceComposerClient";
44
45 ASSERT_NO_FATAL_FAILURE(SetUpDisplay());
46
47 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
48 ASSERT_NO_FATAL_FAILURE(sf->getColorManagement(&mColorManagementUsed));
chaviwd2432892020-07-24 17:42:39 -070049
50 mCaptureArgs.displayToken = mDisplay;
Valerie Hau9cfc6d82019-09-23 13:54:07 -070051 }
52
53 virtual void TearDown() {
54 mBlackBgSurface = 0;
55 mClient->dispose();
56 mClient = 0;
57 }
58
59 virtual sp<SurfaceControl> createLayer(const sp<SurfaceComposerClient>& client,
60 const char* name, uint32_t width, uint32_t height,
Valerie Hau1acd6962019-10-28 16:35:48 -070061 uint32_t flags = 0, SurfaceControl* parent = nullptr,
chaviwdebadb82020-03-26 14:57:24 -070062 uint32_t* outTransformHint = nullptr,
63 PixelFormat format = PIXEL_FORMAT_RGBA_8888) {
64 auto layer =
65 createSurface(client, name, width, height, format, flags, parent, outTransformHint);
Valerie Hau9cfc6d82019-09-23 13:54:07 -070066
67 Transaction t;
68 t.setLayerStack(layer, mDisplayLayerStack).setLayer(layer, mLayerZBase);
69
70 status_t error = t.apply();
71 if (error != NO_ERROR) {
72 ADD_FAILURE() << "failed to initialize SurfaceControl";
73 layer.clear();
74 }
75
76 return layer;
77 }
78
79 virtual sp<SurfaceControl> createSurface(const sp<SurfaceComposerClient>& client,
80 const char* name, uint32_t width, uint32_t height,
81 PixelFormat format, uint32_t flags,
Valerie Hau1acd6962019-10-28 16:35:48 -070082 SurfaceControl* parent = nullptr,
83 uint32_t* outTransformHint = nullptr) {
Vishnu Nair992496b2020-10-22 17:27:21 -070084 sp<IBinder> parentHandle = (parent) ? parent->getHandle() : nullptr;
85 auto layer = client->createSurface(String8(name), width, height, format, flags,
86 parentHandle, LayerMetadata(), outTransformHint);
Valerie Hau9cfc6d82019-09-23 13:54:07 -070087 EXPECT_NE(nullptr, layer.get()) << "failed to create SurfaceControl";
88 return layer;
89 }
90
91 virtual sp<SurfaceControl> createLayer(const char* name, uint32_t width, uint32_t height,
Valerie Hau1acd6962019-10-28 16:35:48 -070092 uint32_t flags = 0, SurfaceControl* parent = nullptr,
chaviwdebadb82020-03-26 14:57:24 -070093 uint32_t* outTransformHint = nullptr,
94 PixelFormat format = PIXEL_FORMAT_RGBA_8888) {
95 return createLayer(mClient, name, width, height, flags, parent, outTransformHint, format);
Valerie Hau9cfc6d82019-09-23 13:54:07 -070096 }
97
98 sp<SurfaceControl> createColorLayer(const char* name, const Color& color,
99 SurfaceControl* parent = nullptr) {
100 auto colorLayer = createSurface(mClient, name, 0 /* buffer width */, 0 /* buffer height */,
101 PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800102 ISurfaceComposerClient::eFXSurfaceEffect, parent);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700103 asTransaction([&](Transaction& t) {
104 t.setColor(colorLayer, half3{color.r / 255.0f, color.g / 255.0f, color.b / 255.0f});
105 t.setAlpha(colorLayer, color.a / 255.0f);
106 });
107 return colorLayer;
108 }
109
110 ANativeWindow_Buffer getBufferQueueLayerBuffer(const sp<SurfaceControl>& layer) {
111 // wait for previous transactions (such as setSize) to complete
112 Transaction().apply(true);
113
114 ANativeWindow_Buffer buffer = {};
115 EXPECT_EQ(NO_ERROR, layer->getSurface()->lock(&buffer, nullptr));
116
117 return buffer;
118 }
119
120 void postBufferQueueLayerBuffer(const sp<SurfaceControl>& layer) {
121 ASSERT_EQ(NO_ERROR, layer->getSurface()->unlockAndPost());
122
123 // wait for the newly posted buffer to be latched
124 waitForLayerBuffers();
125 }
126
127 virtual void fillBufferQueueLayerColor(const sp<SurfaceControl>& layer, const Color& color,
Marin Shalamanov46084422020-10-13 12:33:42 +0200128 uint32_t bufferWidth, uint32_t bufferHeight) {
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700129 ANativeWindow_Buffer buffer;
130 ASSERT_NO_FATAL_FAILURE(buffer = getBufferQueueLayerBuffer(layer));
131 TransactionUtils::fillANativeWindowBufferColor(buffer,
132 Rect(0, 0, bufferWidth, bufferHeight),
133 color);
134 postBufferQueueLayerBuffer(layer);
135 }
136
137 virtual void fillBufferStateLayerColor(const sp<SurfaceControl>& layer, const Color& color,
138 int32_t bufferWidth, int32_t bufferHeight) {
139 sp<GraphicBuffer> buffer =
140 new GraphicBuffer(bufferWidth, bufferHeight, PIXEL_FORMAT_RGBA_8888, 1,
141 BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
Ady Abraham193426d2021-02-18 14:01:53 -0800142 BufferUsage::COMPOSER_OVERLAY | BufferUsage::GPU_TEXTURE,
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700143 "test");
144 TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, 0, bufferWidth, bufferHeight),
145 color);
146 Transaction().setBuffer(layer, buffer).apply();
147 }
148
149 void fillLayerColor(uint32_t mLayerType, const sp<SurfaceControl>& layer, const Color& color,
Marin Shalamanov46084422020-10-13 12:33:42 +0200150 uint32_t bufferWidth, uint32_t bufferHeight) {
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700151 switch (mLayerType) {
152 case ISurfaceComposerClient::eFXSurfaceBufferQueue:
153 fillBufferQueueLayerColor(layer, color, bufferWidth, bufferHeight);
154 break;
155 case ISurfaceComposerClient::eFXSurfaceBufferState:
156 fillBufferStateLayerColor(layer, color, bufferWidth, bufferHeight);
157 break;
158 default:
159 ASSERT_TRUE(false) << "unsupported layer type: " << mLayerType;
160 }
161 }
162
163 void fillLayerQuadrant(uint32_t mLayerType, const sp<SurfaceControl>& layer,
164 int32_t bufferWidth, int32_t bufferHeight, const Color& topLeft,
165 const Color& topRight, const Color& bottomLeft,
166 const Color& bottomRight) {
167 switch (mLayerType) {
168 case ISurfaceComposerClient::eFXSurfaceBufferQueue:
169 fillBufferQueueLayerQuadrant(layer, bufferWidth, bufferHeight, topLeft, topRight,
170 bottomLeft, bottomRight);
171 break;
172 case ISurfaceComposerClient::eFXSurfaceBufferState:
173 fillBufferStateLayerQuadrant(layer, bufferWidth, bufferHeight, topLeft, topRight,
174 bottomLeft, bottomRight);
175 break;
176 default:
177 ASSERT_TRUE(false) << "unsupported layer type: " << mLayerType;
178 }
179 }
180
181 virtual void fillBufferQueueLayerQuadrant(const sp<SurfaceControl>& layer, int32_t bufferWidth,
182 int32_t bufferHeight, const Color& topLeft,
183 const Color& topRight, const Color& bottomLeft,
184 const Color& bottomRight) {
185 ANativeWindow_Buffer buffer;
186 ASSERT_NO_FATAL_FAILURE(buffer = getBufferQueueLayerBuffer(layer));
187 ASSERT_TRUE(bufferWidth % 2 == 0 && bufferHeight % 2 == 0);
188
189 const int32_t halfW = bufferWidth / 2;
190 const int32_t halfH = bufferHeight / 2;
191 TransactionUtils::fillANativeWindowBufferColor(buffer, Rect(0, 0, halfW, halfH), topLeft);
192 TransactionUtils::fillANativeWindowBufferColor(buffer, Rect(halfW, 0, bufferWidth, halfH),
193 topRight);
194 TransactionUtils::fillANativeWindowBufferColor(buffer, Rect(0, halfH, halfW, bufferHeight),
195 bottomLeft);
196 TransactionUtils::fillANativeWindowBufferColor(buffer,
197 Rect(halfW, halfH, bufferWidth,
198 bufferHeight),
199 bottomRight);
200
201 postBufferQueueLayerBuffer(layer);
202 }
203
204 virtual void fillBufferStateLayerQuadrant(const sp<SurfaceControl>& layer, int32_t bufferWidth,
205 int32_t bufferHeight, const Color& topLeft,
206 const Color& topRight, const Color& bottomLeft,
207 const Color& bottomRight) {
208 sp<GraphicBuffer> buffer =
209 new GraphicBuffer(bufferWidth, bufferHeight, PIXEL_FORMAT_RGBA_8888, 1,
210 BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
Ady Abraham193426d2021-02-18 14:01:53 -0800211 BufferUsage::COMPOSER_OVERLAY | BufferUsage::GPU_TEXTURE,
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700212 "test");
213
214 ASSERT_TRUE(bufferWidth % 2 == 0 && bufferHeight % 2 == 0);
215
216 const int32_t halfW = bufferWidth / 2;
217 const int32_t halfH = bufferHeight / 2;
218 TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, 0, halfW, halfH), topLeft);
219 TransactionUtils::fillGraphicBufferColor(buffer, Rect(halfW, 0, bufferWidth, halfH),
220 topRight);
221 TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, halfH, halfW, bufferHeight),
222 bottomLeft);
223 TransactionUtils::fillGraphicBufferColor(buffer,
224 Rect(halfW, halfH, bufferWidth, bufferHeight),
225 bottomRight);
226
227 Transaction().setBuffer(layer, buffer).setSize(layer, bufferWidth, bufferHeight).apply();
228 }
229
230 std::unique_ptr<ScreenCapture> screenshot() {
231 std::unique_ptr<ScreenCapture> screenshot;
232 ScreenCapture::captureScreen(&screenshot);
233 return screenshot;
234 }
235
236 void asTransaction(const std::function<void(Transaction&)>& exec) {
237 Transaction t;
238 exec(t);
239 t.apply(true);
240 }
241
242 static status_t getBuffer(sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence) {
243 static BufferGenerator bufferGenerator;
244 return bufferGenerator.get(outBuffer, outFence);
245 }
246
247 sp<SurfaceComposerClient> mClient;
248
Galia Peycheva561d05c2021-03-08 15:14:05 +0100249 bool deviceSupportsBlurs() {
250 char value[PROPERTY_VALUE_MAX];
251 property_get("ro.surface_flinger.supports_background_blur", value, "0");
252 return atoi(value);
253 }
254
255 bool deviceUsesSkiaRenderEngine() {
256 char value[PROPERTY_VALUE_MAX];
257 property_get("debug.renderengine.backend", value, "default");
258 return strstr(value, "skia") != nullptr;
259 }
260
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700261 sp<IBinder> mDisplay;
262 uint32_t mDisplayWidth;
263 uint32_t mDisplayHeight;
264 uint32_t mDisplayLayerStack;
265 Rect mDisplayRect = Rect::INVALID_RECT;
266
267 // leave room for ~256 layers
268 const int32_t mLayerZBase = std::numeric_limits<int32_t>::max() - 256;
269
270 sp<SurfaceControl> mBlackBgSurface;
271 bool mColorManagementUsed;
272
chaviwd2432892020-07-24 17:42:39 -0700273 DisplayCaptureArgs mCaptureArgs;
274 ScreenCaptureResults mCaptureResults;
275
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700276private:
277 void SetUpDisplay() {
278 mDisplay = mClient->getInternalDisplayToken();
279 ASSERT_FALSE(mDisplay == nullptr) << "failed to get display";
280
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100281 ui::DisplayMode mode;
282 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(mDisplay, &mode));
283 mDisplayRect = Rect(mode.resolution);
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -0800284 mDisplayWidth = mDisplayRect.getWidth();
285 mDisplayHeight = mDisplayRect.getHeight();
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700286
287 // After a new buffer is queued, SurfaceFlinger is notified and will
288 // latch the new buffer on next vsync. Let's heuristically wait for 3
289 // vsyncs.
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100290 mBufferPostDelay = static_cast<int32_t>(1e6 / mode.refreshRate) * 3;
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700291
292 mDisplayLayerStack = 0;
293
294 mBlackBgSurface =
295 createSurface(mClient, "BaseSurface", 0 /* buffer width */, 0 /* buffer height */,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800296 PIXEL_FORMAT_RGBA_8888, ISurfaceComposerClient::eFXSurfaceEffect);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700297
298 // set layer stack (b/68888219)
299 Transaction t;
300 t.setDisplayLayerStack(mDisplay, mDisplayLayerStack);
chaviw25714502021-02-11 10:01:08 -0800301 t.setCrop(mBlackBgSurface, Rect(0, 0, mDisplayWidth, mDisplayHeight));
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700302 t.setLayerStack(mBlackBgSurface, mDisplayLayerStack);
303 t.setColor(mBlackBgSurface, half3{0, 0, 0});
304 t.setLayer(mBlackBgSurface, mLayerZBase);
305 t.apply();
306 }
307
308 void waitForLayerBuffers() {
309 // Request an empty transaction to get applied synchronously to ensure the buffer is
310 // latched.
311 Transaction().apply(true);
312 usleep(mBufferPostDelay);
313 }
314
315 int32_t mBufferPostDelay;
316
317 friend class LayerRenderPathTestHarness;
318};
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700319
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -0800320} // namespace android
Marin Shalamanov30b0b3c2020-10-13 19:15:06 +0200321
322// TODO(b/129481165): remove the #pragma below and fix conversion issues
Galia Peycheva561d05c2021-03-08 15:14:05 +0100323#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"