blob: da71dad2d40e1458bcef712166dc03f743a993b0 [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"
22
Valerie Hau9cfc6d82019-09-23 13:54:07 -070023#include <gtest/gtest.h>
Valerie Hau9cfc6d82019-09-23 13:54:07 -070024#include <gui/ISurfaceComposer.h>
25#include <gui/SurfaceComposerClient.h>
Valerie Hau9cfc6d82019-09-23 13:54:07 -070026#include <private/gui/ComposerService.h>
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -080027#include <ui/DisplayConfig.h>
Valerie Hau9cfc6d82019-09-23 13:54:07 -070028
29#include "BufferGenerator.h"
30#include "utils/ScreenshotUtils.h"
31#include "utils/TransactionUtils.h"
32
33namespace android {
34
35using android::hardware::graphics::common::V1_1::BufferUsage;
36
37class LayerTransactionTest : public ::testing::Test {
38protected:
39 void SetUp() override {
40 mClient = new SurfaceComposerClient;
41 ASSERT_EQ(NO_ERROR, mClient->initCheck()) << "failed to create SurfaceComposerClient";
42
43 ASSERT_NO_FATAL_FAILURE(SetUpDisplay());
44
45 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
46 ASSERT_NO_FATAL_FAILURE(sf->getColorManagement(&mColorManagementUsed));
chaviwd2432892020-07-24 17:42:39 -070047
48 mCaptureArgs.displayToken = mDisplay;
Valerie Hau9cfc6d82019-09-23 13:54:07 -070049 }
50
51 virtual void TearDown() {
52 mBlackBgSurface = 0;
53 mClient->dispose();
54 mClient = 0;
55 }
56
57 virtual sp<SurfaceControl> createLayer(const sp<SurfaceComposerClient>& client,
58 const char* name, uint32_t width, uint32_t height,
Valerie Hau1acd6962019-10-28 16:35:48 -070059 uint32_t flags = 0, SurfaceControl* parent = nullptr,
chaviwdebadb82020-03-26 14:57:24 -070060 uint32_t* outTransformHint = nullptr,
61 PixelFormat format = PIXEL_FORMAT_RGBA_8888) {
62 auto layer =
63 createSurface(client, name, width, height, format, flags, parent, outTransformHint);
Valerie Hau9cfc6d82019-09-23 13:54:07 -070064
65 Transaction t;
66 t.setLayerStack(layer, mDisplayLayerStack).setLayer(layer, mLayerZBase);
67
68 status_t error = t.apply();
69 if (error != NO_ERROR) {
70 ADD_FAILURE() << "failed to initialize SurfaceControl";
71 layer.clear();
72 }
73
74 return layer;
75 }
76
77 virtual sp<SurfaceControl> createSurface(const sp<SurfaceComposerClient>& client,
78 const char* name, uint32_t width, uint32_t height,
79 PixelFormat format, uint32_t flags,
Valerie Hau1acd6962019-10-28 16:35:48 -070080 SurfaceControl* parent = nullptr,
81 uint32_t* outTransformHint = nullptr) {
Vishnu Nair992496b2020-10-22 17:27:21 -070082 sp<IBinder> parentHandle = (parent) ? parent->getHandle() : nullptr;
83 auto layer = client->createSurface(String8(name), width, height, format, flags,
84 parentHandle, LayerMetadata(), outTransformHint);
Valerie Hau9cfc6d82019-09-23 13:54:07 -070085 EXPECT_NE(nullptr, layer.get()) << "failed to create SurfaceControl";
86 return layer;
87 }
88
89 virtual sp<SurfaceControl> createLayer(const char* name, uint32_t width, uint32_t height,
Valerie Hau1acd6962019-10-28 16:35:48 -070090 uint32_t flags = 0, SurfaceControl* parent = nullptr,
chaviwdebadb82020-03-26 14:57:24 -070091 uint32_t* outTransformHint = nullptr,
92 PixelFormat format = PIXEL_FORMAT_RGBA_8888) {
93 return createLayer(mClient, name, width, height, flags, parent, outTransformHint, format);
Valerie Hau9cfc6d82019-09-23 13:54:07 -070094 }
95
96 sp<SurfaceControl> createColorLayer(const char* name, const Color& color,
97 SurfaceControl* parent = nullptr) {
98 auto colorLayer = createSurface(mClient, name, 0 /* buffer width */, 0 /* buffer height */,
99 PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800100 ISurfaceComposerClient::eFXSurfaceEffect, parent);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700101 asTransaction([&](Transaction& t) {
102 t.setColor(colorLayer, half3{color.r / 255.0f, color.g / 255.0f, color.b / 255.0f});
103 t.setAlpha(colorLayer, color.a / 255.0f);
104 });
105 return colorLayer;
106 }
107
108 ANativeWindow_Buffer getBufferQueueLayerBuffer(const sp<SurfaceControl>& layer) {
109 // wait for previous transactions (such as setSize) to complete
110 Transaction().apply(true);
111
112 ANativeWindow_Buffer buffer = {};
113 EXPECT_EQ(NO_ERROR, layer->getSurface()->lock(&buffer, nullptr));
114
115 return buffer;
116 }
117
118 void postBufferQueueLayerBuffer(const sp<SurfaceControl>& layer) {
119 ASSERT_EQ(NO_ERROR, layer->getSurface()->unlockAndPost());
120
121 // wait for the newly posted buffer to be latched
122 waitForLayerBuffers();
123 }
124
125 virtual void fillBufferQueueLayerColor(const sp<SurfaceControl>& layer, const Color& color,
126 int32_t bufferWidth, int32_t bufferHeight) {
127 ANativeWindow_Buffer buffer;
128 ASSERT_NO_FATAL_FAILURE(buffer = getBufferQueueLayerBuffer(layer));
129 TransactionUtils::fillANativeWindowBufferColor(buffer,
130 Rect(0, 0, bufferWidth, bufferHeight),
131 color);
132 postBufferQueueLayerBuffer(layer);
133 }
134
135 virtual void fillBufferStateLayerColor(const sp<SurfaceControl>& layer, const Color& color,
136 int32_t bufferWidth, int32_t bufferHeight) {
137 sp<GraphicBuffer> buffer =
138 new GraphicBuffer(bufferWidth, bufferHeight, PIXEL_FORMAT_RGBA_8888, 1,
139 BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
140 BufferUsage::COMPOSER_OVERLAY,
141 "test");
142 TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, 0, bufferWidth, bufferHeight),
143 color);
144 Transaction().setBuffer(layer, buffer).apply();
145 }
146
147 void fillLayerColor(uint32_t mLayerType, const sp<SurfaceControl>& layer, const Color& color,
148 int32_t bufferWidth, int32_t bufferHeight) {
149 switch (mLayerType) {
150 case ISurfaceComposerClient::eFXSurfaceBufferQueue:
151 fillBufferQueueLayerColor(layer, color, bufferWidth, bufferHeight);
152 break;
153 case ISurfaceComposerClient::eFXSurfaceBufferState:
154 fillBufferStateLayerColor(layer, color, bufferWidth, bufferHeight);
155 break;
156 default:
157 ASSERT_TRUE(false) << "unsupported layer type: " << mLayerType;
158 }
159 }
160
161 void fillLayerQuadrant(uint32_t mLayerType, const sp<SurfaceControl>& layer,
162 int32_t bufferWidth, int32_t bufferHeight, const Color& topLeft,
163 const Color& topRight, const Color& bottomLeft,
164 const Color& bottomRight) {
165 switch (mLayerType) {
166 case ISurfaceComposerClient::eFXSurfaceBufferQueue:
167 fillBufferQueueLayerQuadrant(layer, bufferWidth, bufferHeight, topLeft, topRight,
168 bottomLeft, bottomRight);
169 break;
170 case ISurfaceComposerClient::eFXSurfaceBufferState:
171 fillBufferStateLayerQuadrant(layer, bufferWidth, bufferHeight, topLeft, topRight,
172 bottomLeft, bottomRight);
173 break;
174 default:
175 ASSERT_TRUE(false) << "unsupported layer type: " << mLayerType;
176 }
177 }
178
179 virtual void fillBufferQueueLayerQuadrant(const sp<SurfaceControl>& layer, int32_t bufferWidth,
180 int32_t bufferHeight, const Color& topLeft,
181 const Color& topRight, const Color& bottomLeft,
182 const Color& bottomRight) {
183 ANativeWindow_Buffer buffer;
184 ASSERT_NO_FATAL_FAILURE(buffer = getBufferQueueLayerBuffer(layer));
185 ASSERT_TRUE(bufferWidth % 2 == 0 && bufferHeight % 2 == 0);
186
187 const int32_t halfW = bufferWidth / 2;
188 const int32_t halfH = bufferHeight / 2;
189 TransactionUtils::fillANativeWindowBufferColor(buffer, Rect(0, 0, halfW, halfH), topLeft);
190 TransactionUtils::fillANativeWindowBufferColor(buffer, Rect(halfW, 0, bufferWidth, halfH),
191 topRight);
192 TransactionUtils::fillANativeWindowBufferColor(buffer, Rect(0, halfH, halfW, bufferHeight),
193 bottomLeft);
194 TransactionUtils::fillANativeWindowBufferColor(buffer,
195 Rect(halfW, halfH, bufferWidth,
196 bufferHeight),
197 bottomRight);
198
199 postBufferQueueLayerBuffer(layer);
200 }
201
202 virtual void fillBufferStateLayerQuadrant(const sp<SurfaceControl>& layer, int32_t bufferWidth,
203 int32_t bufferHeight, const Color& topLeft,
204 const Color& topRight, const Color& bottomLeft,
205 const Color& bottomRight) {
206 sp<GraphicBuffer> buffer =
207 new GraphicBuffer(bufferWidth, bufferHeight, PIXEL_FORMAT_RGBA_8888, 1,
208 BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
209 BufferUsage::COMPOSER_OVERLAY,
210 "test");
211
212 ASSERT_TRUE(bufferWidth % 2 == 0 && bufferHeight % 2 == 0);
213
214 const int32_t halfW = bufferWidth / 2;
215 const int32_t halfH = bufferHeight / 2;
216 TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, 0, halfW, halfH), topLeft);
217 TransactionUtils::fillGraphicBufferColor(buffer, Rect(halfW, 0, bufferWidth, halfH),
218 topRight);
219 TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, halfH, halfW, bufferHeight),
220 bottomLeft);
221 TransactionUtils::fillGraphicBufferColor(buffer,
222 Rect(halfW, halfH, bufferWidth, bufferHeight),
223 bottomRight);
224
225 Transaction().setBuffer(layer, buffer).setSize(layer, bufferWidth, bufferHeight).apply();
226 }
227
228 std::unique_ptr<ScreenCapture> screenshot() {
229 std::unique_ptr<ScreenCapture> screenshot;
230 ScreenCapture::captureScreen(&screenshot);
231 return screenshot;
232 }
233
234 void asTransaction(const std::function<void(Transaction&)>& exec) {
235 Transaction t;
236 exec(t);
237 t.apply(true);
238 }
239
240 static status_t getBuffer(sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence) {
241 static BufferGenerator bufferGenerator;
242 return bufferGenerator.get(outBuffer, outFence);
243 }
244
245 sp<SurfaceComposerClient> mClient;
246
247 sp<IBinder> mDisplay;
248 uint32_t mDisplayWidth;
249 uint32_t mDisplayHeight;
250 uint32_t mDisplayLayerStack;
251 Rect mDisplayRect = Rect::INVALID_RECT;
252
253 // leave room for ~256 layers
254 const int32_t mLayerZBase = std::numeric_limits<int32_t>::max() - 256;
255
256 sp<SurfaceControl> mBlackBgSurface;
257 bool mColorManagementUsed;
258
chaviwd2432892020-07-24 17:42:39 -0700259 DisplayCaptureArgs mCaptureArgs;
260 ScreenCaptureResults mCaptureResults;
261
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700262private:
263 void SetUpDisplay() {
264 mDisplay = mClient->getInternalDisplayToken();
265 ASSERT_FALSE(mDisplay == nullptr) << "failed to get display";
266
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -0800267 DisplayConfig config;
268 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayConfig(mDisplay, &config));
269 mDisplayRect = Rect(config.resolution);
270 mDisplayWidth = mDisplayRect.getWidth();
271 mDisplayHeight = mDisplayRect.getHeight();
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700272
273 // After a new buffer is queued, SurfaceFlinger is notified and will
274 // latch the new buffer on next vsync. Let's heuristically wait for 3
275 // vsyncs.
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -0800276 mBufferPostDelay = static_cast<int32_t>(1e6 / config.refreshRate) * 3;
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700277
278 mDisplayLayerStack = 0;
279
280 mBlackBgSurface =
281 createSurface(mClient, "BaseSurface", 0 /* buffer width */, 0 /* buffer height */,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800282 PIXEL_FORMAT_RGBA_8888, ISurfaceComposerClient::eFXSurfaceEffect);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700283
284 // set layer stack (b/68888219)
285 Transaction t;
286 t.setDisplayLayerStack(mDisplay, mDisplayLayerStack);
287 t.setCrop_legacy(mBlackBgSurface, Rect(0, 0, mDisplayWidth, mDisplayHeight));
288 t.setLayerStack(mBlackBgSurface, mDisplayLayerStack);
289 t.setColor(mBlackBgSurface, half3{0, 0, 0});
290 t.setLayer(mBlackBgSurface, mLayerZBase);
291 t.apply();
292 }
293
294 void waitForLayerBuffers() {
295 // Request an empty transaction to get applied synchronously to ensure the buffer is
296 // latched.
297 Transaction().apply(true);
298 usleep(mBufferPostDelay);
299 }
300
301 int32_t mBufferPostDelay;
302
303 friend class LayerRenderPathTestHarness;
304};
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700305
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -0800306} // namespace android
Marin Shalamanov30b0b3c2020-10-13 19:15:06 +0200307
308// TODO(b/129481165): remove the #pragma below and fix conversion issues
309#pragma clang diagnostic pop // ignored "-Wconversion"