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