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