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