blob: eba2c250a59567ddecb3955f8b235736731a3f88 [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
Valerie Hau9cfc6d82019-09-23 13:54:07 -070024#include <gtest/gtest.h>
Valerie Hau9cfc6d82019-09-23 13:54:07 -070025#include <gui/ISurfaceComposer.h>
26#include <gui/SurfaceComposerClient.h>
Valerie Hau9cfc6d82019-09-23 13:54:07 -070027#include <private/gui/ComposerService.h>
Marin Shalamanova7fe3042021-01-29 21:02:08 +010028#include <ui/DisplayMode.h>
Valerie Hau9cfc6d82019-09-23 13:54:07 -070029
30#include "BufferGenerator.h"
31#include "utils/ScreenshotUtils.h"
32#include "utils/TransactionUtils.h"
33
34namespace android {
35
36using android::hardware::graphics::common::V1_1::BufferUsage;
37
38class LayerTransactionTest : public ::testing::Test {
39protected:
40 void SetUp() override {
41 mClient = new SurfaceComposerClient;
42 ASSERT_EQ(NO_ERROR, mClient->initCheck()) << "failed to create SurfaceComposerClient";
43
44 ASSERT_NO_FATAL_FAILURE(SetUpDisplay());
45
46 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
47 ASSERT_NO_FATAL_FAILURE(sf->getColorManagement(&mColorManagementUsed));
chaviwd2432892020-07-24 17:42:39 -070048
49 mCaptureArgs.displayToken = mDisplay;
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
109 ANativeWindow_Buffer getBufferQueueLayerBuffer(const sp<SurfaceControl>& layer) {
110 // wait for previous transactions (such as setSize) to complete
111 Transaction().apply(true);
112
113 ANativeWindow_Buffer buffer = {};
114 EXPECT_EQ(NO_ERROR, layer->getSurface()->lock(&buffer, nullptr));
115
116 return buffer;
117 }
118
119 void postBufferQueueLayerBuffer(const sp<SurfaceControl>& layer) {
120 ASSERT_EQ(NO_ERROR, layer->getSurface()->unlockAndPost());
121
122 // wait for the newly posted buffer to be latched
123 waitForLayerBuffers();
124 }
125
126 virtual void fillBufferQueueLayerColor(const sp<SurfaceControl>& layer, const Color& color,
Marin Shalamanov46084422020-10-13 12:33:42 +0200127 uint32_t bufferWidth, uint32_t bufferHeight) {
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700128 ANativeWindow_Buffer buffer;
129 ASSERT_NO_FATAL_FAILURE(buffer = getBufferQueueLayerBuffer(layer));
130 TransactionUtils::fillANativeWindowBufferColor(buffer,
131 Rect(0, 0, bufferWidth, bufferHeight),
132 color);
133 postBufferQueueLayerBuffer(layer);
134 }
135
136 virtual void fillBufferStateLayerColor(const sp<SurfaceControl>& layer, const Color& color,
137 int32_t bufferWidth, int32_t bufferHeight) {
138 sp<GraphicBuffer> buffer =
139 new GraphicBuffer(bufferWidth, bufferHeight, PIXEL_FORMAT_RGBA_8888, 1,
140 BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
141 BufferUsage::COMPOSER_OVERLAY,
142 "test");
143 TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, 0, bufferWidth, bufferHeight),
144 color);
145 Transaction().setBuffer(layer, buffer).apply();
146 }
147
148 void fillLayerColor(uint32_t mLayerType, const sp<SurfaceControl>& layer, const Color& color,
Marin Shalamanov46084422020-10-13 12:33:42 +0200149 uint32_t bufferWidth, uint32_t bufferHeight) {
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700150 switch (mLayerType) {
151 case ISurfaceComposerClient::eFXSurfaceBufferQueue:
152 fillBufferQueueLayerColor(layer, color, bufferWidth, bufferHeight);
153 break;
154 case ISurfaceComposerClient::eFXSurfaceBufferState:
155 fillBufferStateLayerColor(layer, color, bufferWidth, bufferHeight);
156 break;
157 default:
158 ASSERT_TRUE(false) << "unsupported layer type: " << mLayerType;
159 }
160 }
161
162 void fillLayerQuadrant(uint32_t mLayerType, const sp<SurfaceControl>& layer,
163 int32_t bufferWidth, int32_t bufferHeight, const Color& topLeft,
164 const Color& topRight, const Color& bottomLeft,
165 const Color& bottomRight) {
166 switch (mLayerType) {
167 case ISurfaceComposerClient::eFXSurfaceBufferQueue:
168 fillBufferQueueLayerQuadrant(layer, bufferWidth, bufferHeight, topLeft, topRight,
169 bottomLeft, bottomRight);
170 break;
171 case ISurfaceComposerClient::eFXSurfaceBufferState:
172 fillBufferStateLayerQuadrant(layer, bufferWidth, bufferHeight, topLeft, topRight,
173 bottomLeft, bottomRight);
174 break;
175 default:
176 ASSERT_TRUE(false) << "unsupported layer type: " << mLayerType;
177 }
178 }
179
180 virtual void fillBufferQueueLayerQuadrant(const sp<SurfaceControl>& layer, int32_t bufferWidth,
181 int32_t bufferHeight, const Color& topLeft,
182 const Color& topRight, const Color& bottomLeft,
183 const Color& bottomRight) {
184 ANativeWindow_Buffer buffer;
185 ASSERT_NO_FATAL_FAILURE(buffer = getBufferQueueLayerBuffer(layer));
186 ASSERT_TRUE(bufferWidth % 2 == 0 && bufferHeight % 2 == 0);
187
188 const int32_t halfW = bufferWidth / 2;
189 const int32_t halfH = bufferHeight / 2;
190 TransactionUtils::fillANativeWindowBufferColor(buffer, Rect(0, 0, halfW, halfH), topLeft);
191 TransactionUtils::fillANativeWindowBufferColor(buffer, Rect(halfW, 0, bufferWidth, halfH),
192 topRight);
193 TransactionUtils::fillANativeWindowBufferColor(buffer, Rect(0, halfH, halfW, bufferHeight),
194 bottomLeft);
195 TransactionUtils::fillANativeWindowBufferColor(buffer,
196 Rect(halfW, halfH, bufferWidth,
197 bufferHeight),
198 bottomRight);
199
200 postBufferQueueLayerBuffer(layer);
201 }
202
203 virtual void fillBufferStateLayerQuadrant(const sp<SurfaceControl>& layer, int32_t bufferWidth,
204 int32_t bufferHeight, const Color& topLeft,
205 const Color& topRight, const Color& bottomLeft,
206 const Color& bottomRight) {
207 sp<GraphicBuffer> buffer =
208 new GraphicBuffer(bufferWidth, bufferHeight, PIXEL_FORMAT_RGBA_8888, 1,
209 BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
210 BufferUsage::COMPOSER_OVERLAY,
211 "test");
212
213 ASSERT_TRUE(bufferWidth % 2 == 0 && bufferHeight % 2 == 0);
214
215 const int32_t halfW = bufferWidth / 2;
216 const int32_t halfH = bufferHeight / 2;
217 TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, 0, halfW, halfH), topLeft);
218 TransactionUtils::fillGraphicBufferColor(buffer, Rect(halfW, 0, bufferWidth, halfH),
219 topRight);
220 TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, halfH, halfW, bufferHeight),
221 bottomLeft);
222 TransactionUtils::fillGraphicBufferColor(buffer,
223 Rect(halfW, halfH, bufferWidth, bufferHeight),
224 bottomRight);
225
226 Transaction().setBuffer(layer, buffer).setSize(layer, bufferWidth, bufferHeight).apply();
227 }
228
229 std::unique_ptr<ScreenCapture> screenshot() {
230 std::unique_ptr<ScreenCapture> screenshot;
231 ScreenCapture::captureScreen(&screenshot);
232 return screenshot;
233 }
234
235 void asTransaction(const std::function<void(Transaction&)>& exec) {
236 Transaction t;
237 exec(t);
238 t.apply(true);
239 }
240
241 static status_t getBuffer(sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence) {
242 static BufferGenerator bufferGenerator;
243 return bufferGenerator.get(outBuffer, outFence);
244 }
245
246 sp<SurfaceComposerClient> mClient;
247
248 sp<IBinder> mDisplay;
249 uint32_t mDisplayWidth;
250 uint32_t mDisplayHeight;
251 uint32_t mDisplayLayerStack;
252 Rect mDisplayRect = Rect::INVALID_RECT;
253
254 // leave room for ~256 layers
255 const int32_t mLayerZBase = std::numeric_limits<int32_t>::max() - 256;
256
257 sp<SurfaceControl> mBlackBgSurface;
258 bool mColorManagementUsed;
259
chaviwd2432892020-07-24 17:42:39 -0700260 DisplayCaptureArgs mCaptureArgs;
261 ScreenCaptureResults mCaptureResults;
262
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700263private:
264 void SetUpDisplay() {
265 mDisplay = mClient->getInternalDisplayToken();
266 ASSERT_FALSE(mDisplay == nullptr) << "failed to get display";
267
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100268 ui::DisplayMode mode;
269 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(mDisplay, &mode));
270 mDisplayRect = Rect(mode.resolution);
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -0800271 mDisplayWidth = mDisplayRect.getWidth();
272 mDisplayHeight = mDisplayRect.getHeight();
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700273
274 // After a new buffer is queued, SurfaceFlinger is notified and will
275 // latch the new buffer on next vsync. Let's heuristically wait for 3
276 // vsyncs.
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100277 mBufferPostDelay = static_cast<int32_t>(1e6 / mode.refreshRate) * 3;
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700278
279 mDisplayLayerStack = 0;
280
281 mBlackBgSurface =
282 createSurface(mClient, "BaseSurface", 0 /* buffer width */, 0 /* buffer height */,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800283 PIXEL_FORMAT_RGBA_8888, ISurfaceComposerClient::eFXSurfaceEffect);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700284
285 // set layer stack (b/68888219)
286 Transaction t;
287 t.setDisplayLayerStack(mDisplay, mDisplayLayerStack);
288 t.setCrop_legacy(mBlackBgSurface, Rect(0, 0, mDisplayWidth, mDisplayHeight));
289 t.setLayerStack(mBlackBgSurface, mDisplayLayerStack);
290 t.setColor(mBlackBgSurface, half3{0, 0, 0});
291 t.setLayer(mBlackBgSurface, mLayerZBase);
292 t.apply();
293 }
294
295 void waitForLayerBuffers() {
296 // Request an empty transaction to get applied synchronously to ensure the buffer is
297 // latched.
298 Transaction().apply(true);
299 usleep(mBufferPostDelay);
300 }
301
302 int32_t mBufferPostDelay;
303
304 friend class LayerRenderPathTestHarness;
305};
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700306
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -0800307} // namespace android
Marin Shalamanov30b0b3c2020-10-13 19:15:06 +0200308
309// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +0100310#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"