1 /*
2  * Copyright 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 #include <cstdarg>
18 #include <cstdint>
19 
20 #include <compositionengine/RenderSurfaceCreationArgs.h>
21 #include <compositionengine/impl/OutputCompositionState.h>
22 #include <compositionengine/impl/RenderSurface.h>
23 #include <compositionengine/mock/CompositionEngine.h>
24 #include <compositionengine/mock/Display.h>
25 #include <compositionengine/mock/DisplaySurface.h>
26 #include <compositionengine/mock/NativeWindow.h>
27 #include <compositionengine/mock/OutputLayer.h>
28 #include <gtest/gtest.h>
29 #include <renderengine/ExternalTexture.h>
30 #include <renderengine/impl/ExternalTexture.h>
31 #include <renderengine/mock/RenderEngine.h>
32 #include <ui/GraphicBuffer.h>
33 
34 namespace android::compositionengine {
35 namespace {
36 
37 constexpr int32_t DEFAULT_DISPLAY_WIDTH = 1920;
38 constexpr int32_t DEFAULT_DISPLAY_HEIGHT = 1080;
39 constexpr DisplayId DEFAULT_DISPLAY_ID = PhysicalDisplayId::fromPort(123u);
40 const std::string DEFAULT_DISPLAY_NAME = "Mock Display";
41 
42 using testing::_;
43 using testing::ByMove;
44 using testing::DoAll;
45 using testing::Ref;
46 using testing::Return;
47 using testing::ReturnRef;
48 using testing::SetArgPointee;
49 using testing::StrictMock;
50 
51 class RenderSurfaceTest : public testing::Test {
52 public:
RenderSurfaceTest()53     RenderSurfaceTest() {
54         EXPECT_CALL(mDisplay, getId()).WillRepeatedly(Return(DEFAULT_DISPLAY_ID));
55         EXPECT_CALL(mDisplay, getName()).WillRepeatedly(ReturnRef(DEFAULT_DISPLAY_NAME));
56         EXPECT_CALL(mCompositionEngine, getRenderEngine).WillRepeatedly(ReturnRef(mRenderEngine));
57         EXPECT_CALL(*mNativeWindow, disconnect(NATIVE_WINDOW_API_EGL))
58                 .WillRepeatedly(Return(NO_ERROR));
59     }
60 
61     StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
62     StrictMock<mock::CompositionEngine> mCompositionEngine;
63     StrictMock<mock::Display> mDisplay;
64     sp<mock::NativeWindow> mNativeWindow = sp<StrictMock<mock::NativeWindow>>::make();
65     sp<mock::DisplaySurface> mDisplaySurface = sp<StrictMock<mock::DisplaySurface>>::make();
66     impl::RenderSurface mSurface{mCompositionEngine, mDisplay,
67                                  RenderSurfaceCreationArgsBuilder()
68                                          .setDisplayWidth(DEFAULT_DISPLAY_WIDTH)
69                                          .setDisplayHeight(DEFAULT_DISPLAY_HEIGHT)
70                                          .setNativeWindow(mNativeWindow)
71                                          .setDisplaySurface(mDisplaySurface)
72                                          .build()};
73 };
74 
75 /*
76  * Basic construction
77  */
78 
TEST_F(RenderSurfaceTest,canInstantiate)79 TEST_F(RenderSurfaceTest, canInstantiate) {
80     EXPECT_TRUE(mSurface.isValid());
81 }
82 
83 /*
84  * RenderSurface::initialize()
85  */
86 
TEST_F(RenderSurfaceTest,initializeConfiguresNativeWindow)87 TEST_F(RenderSurfaceTest, initializeConfiguresNativeWindow) {
88     EXPECT_CALL(*mNativeWindow, connect(NATIVE_WINDOW_API_EGL)).WillOnce(Return(NO_ERROR));
89     EXPECT_CALL(*mNativeWindow, setBuffersFormat(HAL_PIXEL_FORMAT_RGBA_8888))
90             .WillOnce(Return(NO_ERROR));
91     EXPECT_CALL(*mNativeWindow, setUsage(GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE))
92             .WillOnce(Return(NO_ERROR));
93 
94     mSurface.initialize();
95 }
96 
97 /*
98  * RenderSurface::getSize()
99  */
100 
TEST_F(RenderSurfaceTest,sizeReturnsConstructedSize)101 TEST_F(RenderSurfaceTest, sizeReturnsConstructedSize) {
102     const ui::Size expected{DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT};
103 
104     EXPECT_EQ(expected, mSurface.getSize());
105 }
106 
107 /*
108  * RenderSurface::getClientTargetAcquireFence()
109  */
110 
TEST_F(RenderSurfaceTest,getClientTargetAcquireFenceForwardsCall)111 TEST_F(RenderSurfaceTest, getClientTargetAcquireFenceForwardsCall) {
112     sp<Fence> fence = sp<Fence>::make();
113 
114     EXPECT_CALL(*mDisplaySurface, getClientTargetAcquireFence()).WillOnce(ReturnRef(fence));
115 
116     EXPECT_EQ(fence.get(), mSurface.getClientTargetAcquireFence().get());
117 }
118 
119 /*
120  * RenderSurface::setDisplaySize()
121  */
122 
TEST_F(RenderSurfaceTest,setDisplaySizeAppliesChange)123 TEST_F(RenderSurfaceTest, setDisplaySizeAppliesChange) {
124     const ui::Size size(640, 480);
125     EXPECT_CALL(*mDisplaySurface, resizeBuffers(size)).Times(1);
126 
127     mSurface.setDisplaySize(size);
128 }
129 
130 /*
131  * RenderSurface::setBufferDataspace()
132  */
133 
TEST_F(RenderSurfaceTest,setBufferDataspaceAppliesChange)134 TEST_F(RenderSurfaceTest, setBufferDataspaceAppliesChange) {
135     EXPECT_CALL(*mNativeWindow, setBuffersDataSpace(ui::Dataspace::DISPLAY_P3))
136             .WillOnce(Return(NO_ERROR));
137 
138     mSurface.setBufferDataspace(ui::Dataspace::DISPLAY_P3);
139 }
140 
141 /*
142  * RenderSurface::setProtected()
143  */
144 
TEST_F(RenderSurfaceTest,setProtectedTrueEnablesProtection)145 TEST_F(RenderSurfaceTest, setProtectedTrueEnablesProtection) {
146     EXPECT_FALSE(mSurface.isProtected());
147     EXPECT_CALL(*mNativeWindow,
148                 setUsage(GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE |
149                          GRALLOC_USAGE_PROTECTED))
150             .WillOnce(Return(NO_ERROR));
151 
152     mSurface.setProtected(true);
153     EXPECT_TRUE(mSurface.isProtected());
154 }
155 
TEST_F(RenderSurfaceTest,setProtectedFalseDisablesProtection)156 TEST_F(RenderSurfaceTest, setProtectedFalseDisablesProtection) {
157     EXPECT_FALSE(mSurface.isProtected());
158     EXPECT_CALL(*mNativeWindow, setUsage(GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE))
159             .WillOnce(Return(NO_ERROR));
160 
161     mSurface.setProtected(false);
162     EXPECT_FALSE(mSurface.isProtected());
163 }
164 
TEST_F(RenderSurfaceTest,setProtectedEnableAndDisable)165 TEST_F(RenderSurfaceTest, setProtectedEnableAndDisable) {
166     EXPECT_FALSE(mSurface.isProtected());
167     EXPECT_CALL(*mNativeWindow,
168                 setUsage(GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE |
169                          GRALLOC_USAGE_PROTECTED))
170             .WillOnce(Return(NO_ERROR));
171     EXPECT_CALL(*mNativeWindow, setUsage(GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE))
172             .WillOnce(Return(NO_ERROR));
173 
174     mSurface.setProtected(true);
175     EXPECT_TRUE(mSurface.isProtected());
176     mSurface.setProtected(false);
177     EXPECT_FALSE(mSurface.isProtected());
178 }
179 
TEST_F(RenderSurfaceTest,setProtectedEnableWithError)180 TEST_F(RenderSurfaceTest, setProtectedEnableWithError) {
181     EXPECT_FALSE(mSurface.isProtected());
182     EXPECT_CALL(*mNativeWindow,
183                 setUsage(GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE |
184                          GRALLOC_USAGE_PROTECTED))
185             .WillOnce(Return(INVALID_OPERATION));
186     mSurface.setProtected(true);
187     EXPECT_FALSE(mSurface.isProtected());
188 }
189 
190 /*
191  * RenderSurface::beginFrame()
192  */
193 
TEST_F(RenderSurfaceTest,beginFrameAppliesChange)194 TEST_F(RenderSurfaceTest, beginFrameAppliesChange) {
195     EXPECT_CALL(*mDisplaySurface, beginFrame(true)).WillOnce(Return(NO_ERROR));
196 
197     EXPECT_EQ(NO_ERROR, mSurface.beginFrame(true));
198 }
199 
200 /*
201  * RenderSurface::prepareFrame()
202  */
203 
TEST_F(RenderSurfaceTest,prepareFrameHandlesMixedComposition)204 TEST_F(RenderSurfaceTest, prepareFrameHandlesMixedComposition) {
205     EXPECT_CALL(*mDisplaySurface, prepareFrame(DisplaySurface::CompositionType::Mixed))
206             .WillOnce(Return(NO_ERROR));
207 
208     mSurface.prepareFrame(true, true);
209 }
210 
TEST_F(RenderSurfaceTest,prepareFrameHandlesOnlyGpuComposition)211 TEST_F(RenderSurfaceTest, prepareFrameHandlesOnlyGpuComposition) {
212     EXPECT_CALL(*mDisplaySurface, prepareFrame(DisplaySurface::CompositionType::Gpu))
213             .WillOnce(Return(NO_ERROR));
214 
215     mSurface.prepareFrame(true, false);
216 }
217 
TEST_F(RenderSurfaceTest,prepareFrameHandlesOnlyHwcComposition)218 TEST_F(RenderSurfaceTest, prepareFrameHandlesOnlyHwcComposition) {
219     EXPECT_CALL(*mDisplaySurface, prepareFrame(DisplaySurface::CompositionType::Hwc))
220             .WillOnce(Return(NO_ERROR));
221 
222     mSurface.prepareFrame(false, true);
223 }
224 
TEST_F(RenderSurfaceTest,prepareFrameHandlesNoComposition)225 TEST_F(RenderSurfaceTest, prepareFrameHandlesNoComposition) {
226     EXPECT_CALL(*mDisplaySurface, prepareFrame(DisplaySurface::CompositionType::Hwc))
227             .WillOnce(Return(NO_ERROR));
228 
229     mSurface.prepareFrame(false, false);
230 }
231 
232 /*
233  * RenderSurface::dequeueBuffer()
234  */
235 
TEST_F(RenderSurfaceTest,dequeueBufferObtainsABuffer)236 TEST_F(RenderSurfaceTest, dequeueBufferObtainsABuffer) {
237     sp<GraphicBuffer> buffer = sp<GraphicBuffer>::make();
238 
239     EXPECT_CALL(*mNativeWindow, dequeueBuffer(_, _))
240             .WillOnce(
241                     DoAll(SetArgPointee<0>(buffer.get()), SetArgPointee<1>(-1), Return(NO_ERROR)));
242 
243     base::unique_fd fence;
244     EXPECT_EQ(buffer.get(), mSurface.dequeueBuffer(&fence)->getBuffer().get());
245 
246     EXPECT_EQ(buffer.get(), mSurface.mutableTextureForTest()->getBuffer().get());
247 }
248 
249 /*
250  * RenderSurface::queueBuffer()
251  */
252 
TEST_F(RenderSurfaceTest,queueBufferHandlesNoClientComposition)253 TEST_F(RenderSurfaceTest, queueBufferHandlesNoClientComposition) {
254     const auto buffer = std::make_shared<
255             renderengine::impl::
256                     ExternalTexture>(sp<GraphicBuffer>::make(), mRenderEngine,
257                                      renderengine::impl::ExternalTexture::Usage::READABLE |
258                                              renderengine::impl::ExternalTexture::Usage::WRITEABLE);
259     mSurface.mutableTextureForTest() = buffer;
260 
261     impl::OutputCompositionState state;
262     state.usesClientComposition = false;
263     state.flipClientTarget = false;
264 
265     EXPECT_CALL(mDisplay, getState()).WillOnce(ReturnRef(state));
266     EXPECT_CALL(*mDisplaySurface, advanceFrame(0.5f)).Times(1);
267 
268     mSurface.queueBuffer(base::unique_fd(), 0.5f);
269 
270     EXPECT_EQ(buffer.get(), mSurface.mutableTextureForTest().get());
271 }
272 
TEST_F(RenderSurfaceTest,queueBufferHandlesClientComposition)273 TEST_F(RenderSurfaceTest, queueBufferHandlesClientComposition) {
274     const auto buffer =
275             std::make_shared<renderengine::impl::ExternalTexture>(sp<GraphicBuffer>::make(),
276                                                                   mRenderEngine, false);
277     mSurface.mutableTextureForTest() = buffer;
278 
279     impl::OutputCompositionState state;
280     state.usesClientComposition = true;
281     state.flipClientTarget = false;
282 
283     EXPECT_CALL(mDisplay, getState()).WillOnce(ReturnRef(state));
284     EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getBuffer()->getNativeBuffer(), -1))
285             .WillOnce(Return(NO_ERROR));
286     EXPECT_CALL(*mDisplaySurface, advanceFrame(0.5f)).Times(1);
287 
288     mSurface.queueBuffer(base::unique_fd(), 0.5f);
289 
290     EXPECT_EQ(nullptr, mSurface.mutableTextureForTest().get());
291 }
292 
TEST_F(RenderSurfaceTest,queueBufferHandlesFlipClientTargetRequest)293 TEST_F(RenderSurfaceTest, queueBufferHandlesFlipClientTargetRequest) {
294     const auto buffer =
295             std::make_shared<renderengine::impl::ExternalTexture>(sp<GraphicBuffer>::make(),
296                                                                   mRenderEngine, false);
297     mSurface.mutableTextureForTest() = buffer;
298 
299     impl::OutputCompositionState state;
300     state.usesClientComposition = false;
301     state.flipClientTarget = true;
302 
303     EXPECT_CALL(mDisplay, getState()).WillOnce(ReturnRef(state));
304     EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getBuffer()->getNativeBuffer(), -1))
305             .WillOnce(Return(NO_ERROR));
306     EXPECT_CALL(*mDisplaySurface, advanceFrame(0.5f)).Times(1);
307 
308     mSurface.queueBuffer(base::unique_fd(), 0.5f);
309 
310     EXPECT_EQ(nullptr, mSurface.mutableTextureForTest().get());
311 }
312 
TEST_F(RenderSurfaceTest,queueBufferHandlesFlipClientTargetRequestWithNoBufferYetDequeued)313 TEST_F(RenderSurfaceTest, queueBufferHandlesFlipClientTargetRequestWithNoBufferYetDequeued) {
314     sp<GraphicBuffer> buffer = sp<GraphicBuffer>::make();
315 
316     impl::OutputCompositionState state;
317     state.usesClientComposition = false;
318     state.flipClientTarget = true;
319 
320     EXPECT_CALL(mDisplay, getState()).WillOnce(ReturnRef(state));
321     EXPECT_CALL(*mNativeWindow, dequeueBuffer(_, _))
322             .WillOnce(
323                     DoAll(SetArgPointee<0>(buffer.get()), SetArgPointee<1>(-1), Return(NO_ERROR)));
324     EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getNativeBuffer(), -1))
325             .WillOnce(Return(NO_ERROR));
326     EXPECT_CALL(*mDisplaySurface, advanceFrame(0.5f)).Times(1);
327 
328     mSurface.queueBuffer(base::unique_fd(), 0.5f);
329 
330     EXPECT_EQ(nullptr, mSurface.mutableTextureForTest().get());
331 }
332 
TEST_F(RenderSurfaceTest,queueBufferHandlesNativeWindowQueueBufferFailureOnVirtualDisplay)333 TEST_F(RenderSurfaceTest, queueBufferHandlesNativeWindowQueueBufferFailureOnVirtualDisplay) {
334     const auto buffer =
335             std::make_shared<renderengine::impl::ExternalTexture>(sp<GraphicBuffer>::make(),
336                                                                   mRenderEngine, false);
337     mSurface.mutableTextureForTest() = buffer;
338 
339     impl::OutputCompositionState state;
340     state.usesClientComposition = true;
341 
342     EXPECT_CALL(mDisplay, getState()).WillOnce(ReturnRef(state));
343     EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getBuffer()->getNativeBuffer(), -1))
344             .WillOnce(Return(INVALID_OPERATION));
345     EXPECT_CALL(mDisplay, isVirtual()).WillOnce(Return(true));
346     EXPECT_CALL(*mNativeWindow, cancelBuffer(buffer->getBuffer()->getNativeBuffer(), -1))
347             .WillOnce(Return(NO_ERROR));
348     EXPECT_CALL(*mDisplaySurface, advanceFrame(0.5f)).Times(1);
349 
350     mSurface.queueBuffer(base::unique_fd(), 0.5f);
351 
352     EXPECT_EQ(nullptr, mSurface.mutableTextureForTest().get());
353 }
354 
355 /*
356  * RenderSurface::onPresentDisplayCompleted()
357  */
358 
TEST_F(RenderSurfaceTest,onPresentDisplayCompletedForwardsSignal)359 TEST_F(RenderSurfaceTest, onPresentDisplayCompletedForwardsSignal) {
360     EXPECT_CALL(*mDisplaySurface, onFrameCommitted()).Times(1);
361 
362     mSurface.onPresentDisplayCompleted();
363 }
364 
365 } // namespace
366 } // namespace android::compositionengine
367