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