1 /*
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 
17 #pragma once
18 
19 #include <gtest/gtest.h>
20 #include <gui/ISurfaceComposer.h>
21 #include <gui/SurfaceComposerClient.h>
22 #include <private/gui/ComposerService.h>
23 #include <ui/DisplayConfig.h>
24 
25 #include "BufferGenerator.h"
26 #include "utils/ScreenshotUtils.h"
27 #include "utils/TransactionUtils.h"
28 
29 namespace android {
30 
31 using android::hardware::graphics::common::V1_1::BufferUsage;
32 
33 class LayerTransactionTest : public ::testing::Test {
34 protected:
SetUp()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 
TearDown()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,
53                                            uint32_t flags = 0, SurfaceControl* parent = nullptr,
54                                            uint32_t* outTransformHint = nullptr,
55                                            PixelFormat format = PIXEL_FORMAT_RGBA_8888) {
56         auto layer =
57                 createSurface(client, name, width, height, format, flags, parent, outTransformHint);
58 
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,
74                                              SurfaceControl* parent = nullptr,
75                                              uint32_t* outTransformHint = nullptr) {
76         auto layer = client->createSurface(String8(name), width, height, format, flags, parent,
77                                            LayerMetadata(), outTransformHint);
78         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,
83                                            uint32_t flags = 0, SurfaceControl* parent = nullptr,
84                                            uint32_t* outTransformHint = nullptr,
85                                            PixelFormat format = PIXEL_FORMAT_RGBA_8888) {
86         return createLayer(mClient, name, width, height, flags, parent, outTransformHint, format);
87     }
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,
93                                         ISurfaceComposerClient::eFXSurfaceEffect, parent);
94         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 
getBufferQueueLayerBuffer(const sp<SurfaceControl> & layer)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 
postBufferQueueLayerBuffer(const sp<SurfaceControl> & layer)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 
fillBufferQueueLayerColor(const sp<SurfaceControl> & layer,const Color & color,int32_t bufferWidth,int32_t bufferHeight)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 
fillBufferStateLayerColor(const sp<SurfaceControl> & layer,const Color & color,int32_t bufferWidth,int32_t bufferHeight)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 
fillLayerColor(uint32_t mLayerType,const sp<SurfaceControl> & layer,const Color & color,int32_t bufferWidth,int32_t bufferHeight)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 
fillLayerQuadrant(uint32_t mLayerType,const sp<SurfaceControl> & layer,int32_t bufferWidth,int32_t bufferHeight,const Color & topLeft,const Color & topRight,const Color & bottomLeft,const Color & bottomRight)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 
fillBufferQueueLayerQuadrant(const sp<SurfaceControl> & layer,int32_t bufferWidth,int32_t bufferHeight,const Color & topLeft,const Color & topRight,const Color & bottomLeft,const Color & bottomRight)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 
fillBufferStateLayerQuadrant(const sp<SurfaceControl> & layer,int32_t bufferWidth,int32_t bufferHeight,const Color & topLeft,const Color & topRight,const Color & bottomLeft,const Color & bottomRight)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 
screenshot()221     std::unique_ptr<ScreenCapture> screenshot() {
222         std::unique_ptr<ScreenCapture> screenshot;
223         ScreenCapture::captureScreen(&screenshot);
224         return screenshot;
225     }
226 
asTransaction(const std::function<void (Transaction &)> & exec)227     void asTransaction(const std::function<void(Transaction&)>& exec) {
228         Transaction t;
229         exec(t);
230         t.apply(true);
231     }
232 
getBuffer(sp<GraphicBuffer> * outBuffer,sp<Fence> * outFence)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 
252 private:
SetUpDisplay()253     void SetUpDisplay() {
254         mDisplay = mClient->getInternalDisplayToken();
255         ASSERT_FALSE(mDisplay == nullptr) << "failed to get display";
256 
257         DisplayConfig config;
258         ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayConfig(mDisplay, &config));
259         mDisplayRect = Rect(config.resolution);
260         mDisplayWidth = mDisplayRect.getWidth();
261         mDisplayHeight = mDisplayRect.getHeight();
262 
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.
266         mBufferPostDelay = static_cast<int32_t>(1e6 / config.refreshRate) * 3;
267 
268         mDisplayLayerStack = 0;
269 
270         mBlackBgSurface =
271                 createSurface(mClient, "BaseSurface", 0 /* buffer width */, 0 /* buffer height */,
272                               PIXEL_FORMAT_RGBA_8888, ISurfaceComposerClient::eFXSurfaceEffect);
273 
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 
waitForLayerBuffers()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 };
295 
296 } // namespace android
297