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