• 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         binder::Status status = sf->getColorManagement(&mColorManagementUsed);
51         ASSERT_NO_FATAL_FAILURE(gui::aidl_utils::statusTFromBinderStatus(status));
52 
53         mCaptureArgs.displayToken = mDisplay;
54     }
55 
TearDown()56     virtual void TearDown() {
57         mBlackBgSurface = 0;
58         mClient->dispose();
59         mClient = 0;
60     }
61 
62     virtual sp<SurfaceControl> createLayer(const sp<SurfaceComposerClient>& client,
63                                            const char* name, uint32_t width, uint32_t height,
64                                            uint32_t flags = 0, SurfaceControl* parent = nullptr,
65                                            uint32_t* outTransformHint = nullptr,
66                                            PixelFormat format = PIXEL_FORMAT_RGBA_8888) {
67         auto layer =
68                 createSurface(client, name, width, height, format, flags, parent, outTransformHint);
69 
70         Transaction t;
71         t.setLayerStack(layer, mDisplayLayerStack).setLayer(layer, mLayerZBase);
72 
73         status_t error = t.apply();
74         if (error != NO_ERROR) {
75             ADD_FAILURE() << "failed to initialize SurfaceControl";
76             layer.clear();
77         }
78 
79         return layer;
80     }
81 
82     virtual sp<SurfaceControl> createSurface(const sp<SurfaceComposerClient>& client,
83                                              const char* name, uint32_t width, uint32_t height,
84                                              PixelFormat format, uint32_t flags,
85                                              SurfaceControl* parent = nullptr,
86                                              uint32_t* outTransformHint = nullptr) {
87         sp<IBinder> parentHandle = (parent) ? parent->getHandle() : nullptr;
88         auto layer = client->createSurface(String8(name), width, height, format, flags,
89                                            parentHandle, LayerMetadata(), outTransformHint);
90         EXPECT_NE(nullptr, layer.get()) << "failed to create SurfaceControl";
91         return layer;
92     }
93 
94     virtual sp<SurfaceControl> createLayer(const char* name, uint32_t width, uint32_t height,
95                                            uint32_t flags = 0, SurfaceControl* parent = nullptr,
96                                            uint32_t* outTransformHint = nullptr,
97                                            PixelFormat format = PIXEL_FORMAT_RGBA_8888) {
98         return createLayer(mClient, name, width, height, flags, parent, outTransformHint, format);
99     }
100 
101     sp<SurfaceControl> createColorLayer(const char* name, const Color& color,
102                                         SurfaceControl* parent = nullptr) {
103         auto colorLayer = createSurface(mClient, name, 0 /* buffer width */, 0 /* buffer height */,
104                                         PIXEL_FORMAT_RGBA_8888,
105                                         ISurfaceComposerClient::eFXSurfaceEffect, parent);
106         asTransaction([&](Transaction& t) {
107             t.setColor(colorLayer, half3{color.r / 255.0f, color.g / 255.0f, color.b / 255.0f});
108             t.setAlpha(colorLayer, color.a / 255.0f);
109         });
110         return colorLayer;
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     bool mColorManagementUsed;
286 
287     DisplayCaptureArgs mCaptureArgs;
288     ScreenCaptureResults mCaptureResults;
289 
290 private:
SetUpDisplay()291     void SetUpDisplay() {
292         const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
293         ASSERT_FALSE(ids.empty());
294         mDisplay = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
295         ASSERT_FALSE(mDisplay == nullptr) << "failed to get display";
296 
297         ui::DisplayMode mode;
298         ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(mDisplay, &mode));
299         mDisplayRect = Rect(mode.resolution);
300         mDisplayWidth = mDisplayRect.getWidth();
301         mDisplayHeight = mDisplayRect.getHeight();
302 
303         // After a new buffer is queued, SurfaceFlinger is notified and will
304         // latch the new buffer on next vsync.  Let's heuristically wait for 3
305         // vsyncs.
306         mBufferPostDelay = static_cast<int32_t>(1e6 / mode.refreshRate) * 3;
307 
308         mBlackBgSurface =
309                 createSurface(mClient, "BaseSurface", 0 /* buffer width */, 0 /* buffer height */,
310                               PIXEL_FORMAT_RGBA_8888, ISurfaceComposerClient::eFXSurfaceEffect);
311 
312         // set layer stack (b/68888219)
313         Transaction t;
314         t.setDisplayLayerStack(mDisplay, mDisplayLayerStack);
315         t.setCrop(mBlackBgSurface, Rect(0, 0, mDisplayWidth, mDisplayHeight));
316         t.setLayerStack(mBlackBgSurface, mDisplayLayerStack);
317         t.setColor(mBlackBgSurface, half3{0, 0, 0});
318         t.setLayer(mBlackBgSurface, mLayerZBase);
319         t.apply();
320     }
321 
waitForLayerBuffers()322     void waitForLayerBuffers() {
323         // Request an empty transaction to get applied synchronously to ensure the buffer is
324         // latched.
325         Transaction().apply(true);
326         usleep(mBufferPostDelay);
327     }
328 
329     int32_t mBufferPostDelay;
330 
331     friend class LayerRenderPathTestHarness;
332 };
333 
334 } // namespace android
335 
336 // TODO(b/129481165): remove the #pragma below and fix conversion issues
337 #pragma clang diagnostic pop // ignored "-Wconversion -Wextra"
338