blob: c56d92a06776f7b084a44cc0f959343abb5db3b4 [file] [log] [blame]
Lloyd Pique31cb2942018-10-19 17:23:03 -07001/*
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/RenderSurface.h>
22#include <compositionengine/mock/CompositionEngine.h>
23#include <compositionengine/mock/Display.h>
24#include <compositionengine/mock/DisplaySurface.h>
25#include <gtest/gtest.h>
26#include <renderengine/mock/RenderEngine.h>
27#include <system/window.h>
28#include <ui/ANativeObjectBase.h>
29
30#include "MockHWComposer.h"
31
32namespace android::compositionengine {
33namespace {
34
35/* ------------------------------------------------------------------------
36 * MockNativeWindow
37 *
38 * An intentionally simplified Mock which implements a minimal subset of the full
39 * ANativeWindow interface.
40 */
41
42class MockNativeWindow : public ANativeObjectBase<ANativeWindow, MockNativeWindow, RefBase> {
43public:
44 MockNativeWindow() {
45 ANativeWindow::setSwapInterval = &forwardSetSwapInterval;
46 ANativeWindow::dequeueBuffer = &forwardDequeueBuffer;
47 ANativeWindow::cancelBuffer = &forwardCancelBuffer;
48 ANativeWindow::queueBuffer = &forwardQueueBuffer;
49 ANativeWindow::query = &forwardQuery;
50 ANativeWindow::perform = &forwardPerform;
51
52 ANativeWindow::dequeueBuffer_DEPRECATED = &forwardDequeueBufferDeprecated;
53 ANativeWindow::cancelBuffer_DEPRECATED = &forwardCancelBufferDeprecated;
54 ANativeWindow::lockBuffer_DEPRECATED = &forwardLockBufferDeprecated;
55 ANativeWindow::queueBuffer_DEPRECATED = &forwardQueueBufferDeprecated;
56 }
57
58 MOCK_METHOD1(setSwapInterval, int(int));
59 MOCK_METHOD2(dequeueBuffer, int(struct ANativeWindowBuffer**, int*));
60 MOCK_METHOD2(cancelBuffer, int(struct ANativeWindowBuffer*, int));
61 MOCK_METHOD2(queueBuffer, int(struct ANativeWindowBuffer*, int));
62 MOCK_CONST_METHOD2(query, int(int, int*));
63 MOCK_METHOD1(connect, int(int));
64 MOCK_METHOD1(lockBuffer_DEPRECATED, int(struct ANativeWindowBuffer*));
65 MOCK_METHOD1(setBuffersFormat, int(PixelFormat));
66 MOCK_METHOD1(setBuffersDataSpace, int(ui::Dataspace));
67 MOCK_METHOD1(setUsage, int(uint64_t));
68
69 static void unexpectedCall(...) { LOG_ALWAYS_FATAL("Unexpected ANativeWindow API call"); }
70
71 static int forwardSetSwapInterval(ANativeWindow* window, int interval) {
72 return getSelf(window)->setSwapInterval(interval);
73 }
74
75 static int forwardDequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer,
76 int* fenceFd) {
77 return getSelf(window)->dequeueBuffer(buffer, fenceFd);
78 }
79
80 static int forwardCancelBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer,
81 int fenceFd) {
82 return getSelf(window)->cancelBuffer(buffer, fenceFd);
83 }
84
85 static int forwardQueueBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer, int fenceFd) {
86 return getSelf(window)->queueBuffer(buffer, fenceFd);
87 }
88
89 static int forwardQuery(const ANativeWindow* window, int what, int* value) {
90 return getSelf(window)->query(what, value);
91 }
92
93 static int forwardPerform(ANativeWindow* window, int operation, ...) {
94 va_list args;
95 va_start(args, operation);
96 int result = NO_ERROR;
97 switch (operation) {
98 case NATIVE_WINDOW_API_CONNECT: {
99 int api = va_arg(args, int);
100 result = getSelf(window)->connect(api);
101 break;
102 }
103 case NATIVE_WINDOW_SET_BUFFERS_FORMAT: {
104 PixelFormat format = va_arg(args, PixelFormat);
105 result = getSelf(window)->setBuffersFormat(format);
106 break;
107 }
108 case NATIVE_WINDOW_SET_BUFFERS_DATASPACE: {
109 ui::Dataspace dataspace = static_cast<ui::Dataspace>(va_arg(args, int));
110 result = getSelf(window)->setBuffersDataSpace(dataspace);
111 break;
112 }
113 case NATIVE_WINDOW_SET_USAGE: {
114 // Note: Intentionally widens usage from 32 to 64 bits so we
115 // just have one implementation.
116 uint64_t usage = va_arg(args, uint32_t);
117 result = getSelf(window)->setUsage(usage);
118 break;
119 }
120 case NATIVE_WINDOW_SET_USAGE64: {
121 uint64_t usage = va_arg(args, uint64_t);
122 result = getSelf(window)->setUsage(usage);
123 break;
124 }
125 default:
126 LOG_ALWAYS_FATAL("Unexpected operation %d", operation);
127 break;
128 }
129
130 va_end(args);
131 return result;
132 }
133
134 static int forwardDequeueBufferDeprecated(ANativeWindow* window, ANativeWindowBuffer** buffer) {
135 int ignoredFenceFd = -1;
136 return getSelf(window)->dequeueBuffer(buffer, &ignoredFenceFd);
137 }
138
139 static int forwardCancelBufferDeprecated(ANativeWindow* window, ANativeWindowBuffer* buffer) {
140 return getSelf(window)->cancelBuffer(buffer, -1);
141 }
142
143 static int forwardLockBufferDeprecated(ANativeWindow* window, ANativeWindowBuffer* buffer) {
144 return getSelf(window)->lockBuffer_DEPRECATED(buffer);
145 }
146
147 static int forwardQueueBufferDeprecated(ANativeWindow* window, ANativeWindowBuffer* buffer) {
148 return getSelf(window)->queueBuffer(buffer, -1);
149 }
150};
151
152/* ------------------------------------------------------------------------
153 * RenderSurfaceTest
154 */
155
156constexpr int32_t DEFAULT_DISPLAY_WIDTH = 1920;
157constexpr int32_t DEFAULT_DISPLAY_HEIGHT = 1080;
158constexpr std::optional<DisplayId> DEFAULT_DISPLAY_ID = std::make_optional(DisplayId{123u});
159const std::string DEFAULT_DISPLAY_NAME = "Mock Display";
160
161using testing::_;
162using testing::ByMove;
163using testing::DoAll;
164using testing::Ref;
165using testing::Return;
166using testing::ReturnRef;
167using testing::SetArgPointee;
168using testing::StrictMock;
169
170class RenderSurfaceTest : public testing::Test {
171public:
172 RenderSurfaceTest() {
173 EXPECT_CALL(mDisplay, getId()).WillRepeatedly(ReturnRef(DEFAULT_DISPLAY_ID));
174 EXPECT_CALL(mDisplay, getName()).WillRepeatedly(ReturnRef(DEFAULT_DISPLAY_NAME));
175 EXPECT_CALL(mCompositionEngine, getHwComposer).WillRepeatedly(ReturnRef(mHwComposer));
176 EXPECT_CALL(mCompositionEngine, getRenderEngine).WillRepeatedly(ReturnRef(mRenderEngine));
177 }
178 ~RenderSurfaceTest() override = default;
179
180 StrictMock<android::mock::HWComposer> mHwComposer;
181 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
182 StrictMock<mock::CompositionEngine> mCompositionEngine;
183 StrictMock<mock::Display> mDisplay;
184 sp<MockNativeWindow> mNativeWindow = new StrictMock<MockNativeWindow>();
185 sp<mock::DisplaySurface> mDisplaySurface = new StrictMock<mock::DisplaySurface>();
186 impl::RenderSurface mSurface{mCompositionEngine, mDisplay,
187 RenderSurfaceCreationArgs{DEFAULT_DISPLAY_WIDTH,
188 DEFAULT_DISPLAY_HEIGHT, mNativeWindow,
189 mDisplaySurface}};
190};
191
192/* ------------------------------------------------------------------------
193 * Basic construction
194 */
195
196TEST_F(RenderSurfaceTest, canInstantiate) {
197 EXPECT_TRUE(mSurface.isValid());
198}
199
200/* ------------------------------------------------------------------------
201 * RenderSurface::initialize()
202 */
203
204TEST_F(RenderSurfaceTest, initializeConfiguresNativeWindow) {
205 EXPECT_CALL(*mNativeWindow, connect(NATIVE_WINDOW_API_EGL)).WillOnce(Return(NO_ERROR));
206 EXPECT_CALL(*mNativeWindow, setBuffersFormat(HAL_PIXEL_FORMAT_RGBA_8888))
207 .WillOnce(Return(NO_ERROR));
208 EXPECT_CALL(*mNativeWindow, setUsage(GRALLOC_USAGE_HW_RENDER)).WillOnce(Return(NO_ERROR));
209
210 mSurface.initialize();
211}
212
213/* ------------------------------------------------------------------------
214 * RenderSurface::getSize()
215 */
216
217TEST_F(RenderSurfaceTest, sizeReturnsConstructedSize) {
218 const ui::Size expected{DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT};
219
220 EXPECT_EQ(expected, mSurface.getSize());
221}
222
223/* ------------------------------------------------------------------------
224 * RenderSurface::getClientTargetAcquireFence()
225 */
226
227TEST_F(RenderSurfaceTest, getClientTargetAcquireFenceForwardsCall) {
228 sp<Fence> fence = new Fence();
229
230 EXPECT_CALL(*mDisplaySurface, getClientTargetAcquireFence()).WillOnce(ReturnRef(fence));
231
232 EXPECT_EQ(fence.get(), mSurface.getClientTargetAcquireFence().get());
233}
234
235/* ------------------------------------------------------------------------
236 * RenderSurface::setDisplaySize()
237 */
238
239TEST_F(RenderSurfaceTest, setDisplaySizeAppliesChange) {
240 EXPECT_CALL(*mDisplaySurface, resizeBuffers(640, 480)).Times(1);
241
242 mSurface.setDisplaySize(ui::Size(640, 480));
243}
244
245/* ------------------------------------------------------------------------
246 * RenderSurface::setBufferDataspace()
247 */
248
249TEST_F(RenderSurfaceTest, setBufferDataspaceAppliesChange) {
250 EXPECT_CALL(*mNativeWindow, setBuffersDataSpace(ui::Dataspace::DISPLAY_P3))
251 .WillOnce(Return(NO_ERROR));
252
253 mSurface.setBufferDataspace(ui::Dataspace::DISPLAY_P3);
254}
255
256/* ------------------------------------------------------------------------
257 * RenderSurface::setProtected()
258 */
259
260TEST_F(RenderSurfaceTest, setProtectedTrueEnablesProtection) {
261 EXPECT_CALL(*mNativeWindow, setUsage(GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_PROTECTED))
262 .WillOnce(Return(NO_ERROR));
263
264 mSurface.setProtected(true);
265}
266
267TEST_F(RenderSurfaceTest, setProtectedFalseDisablesProtection) {
268 EXPECT_CALL(*mNativeWindow, setUsage(GRALLOC_USAGE_HW_RENDER)).WillOnce(Return(NO_ERROR));
269
270 mSurface.setProtected(false);
271}
272
273/* ------------------------------------------------------------------------
274 * RenderSurface::beginFrame()
275 */
276
277TEST_F(RenderSurfaceTest, beginFrameAppliesChange) {
278 EXPECT_CALL(*mDisplaySurface, beginFrame(true)).WillOnce(Return(NO_ERROR));
279
280 EXPECT_EQ(NO_ERROR, mSurface.beginFrame(true));
281}
282
283/* ------------------------------------------------------------------------
284 * RenderSurface::prepareFrame()
285 */
286
287TEST_F(RenderSurfaceTest, prepareFrameTakesEarlyOutOnHwcError) {
288 std::vector<CompositionInfo> data;
289
290 EXPECT_CALL(mHwComposer, prepare(*DEFAULT_DISPLAY_ID, Ref(data)))
291 .WillOnce(Return(INVALID_OPERATION));
292
293 EXPECT_EQ(INVALID_OPERATION, mSurface.prepareFrame(data));
294}
295
296TEST_F(RenderSurfaceTest, prepareFrameHandlesMixedComposition) {
297 std::vector<CompositionInfo> data;
298 EXPECT_CALL(mHwComposer, prepare(*DEFAULT_DISPLAY_ID, Ref(data))).WillOnce(Return(NO_ERROR));
299 EXPECT_CALL(mHwComposer, hasClientComposition(DEFAULT_DISPLAY_ID)).WillOnce(Return(true));
300 EXPECT_CALL(mHwComposer, hasDeviceComposition(DEFAULT_DISPLAY_ID)).WillOnce(Return(true));
301
302 EXPECT_CALL(*mDisplaySurface, prepareFrame(DisplaySurface::COMPOSITION_MIXED))
303 .WillOnce(Return(INVALID_OPERATION));
304
305 EXPECT_EQ(INVALID_OPERATION, mSurface.prepareFrame(data));
306}
307
308TEST_F(RenderSurfaceTest, prepareFrameHandlesOnlyGlesComposition) {
309 std::vector<CompositionInfo> data;
310
311 EXPECT_CALL(mHwComposer, prepare(*DEFAULT_DISPLAY_ID, Ref(data))).WillOnce(Return(NO_ERROR));
312 EXPECT_CALL(mHwComposer, hasClientComposition(DEFAULT_DISPLAY_ID)).WillOnce(Return(true));
313 EXPECT_CALL(mHwComposer, hasDeviceComposition(DEFAULT_DISPLAY_ID)).WillOnce(Return(false));
314
315 EXPECT_CALL(*mDisplaySurface, prepareFrame(DisplaySurface::COMPOSITION_GLES))
316 .WillOnce(Return(NO_ERROR));
317
318 EXPECT_EQ(NO_ERROR, mSurface.prepareFrame(data));
319}
320
321TEST_F(RenderSurfaceTest, prepareFrameHandlesOnlyHwcComposition) {
322 std::vector<CompositionInfo> data;
323
324 EXPECT_CALL(mHwComposer, prepare(*DEFAULT_DISPLAY_ID, Ref(data))).WillOnce(Return(NO_ERROR));
325 EXPECT_CALL(mHwComposer, hasClientComposition(DEFAULT_DISPLAY_ID)).WillOnce(Return(false));
326 EXPECT_CALL(mHwComposer, hasDeviceComposition(DEFAULT_DISPLAY_ID)).WillOnce(Return(true));
327
328 EXPECT_CALL(*mDisplaySurface, prepareFrame(DisplaySurface::COMPOSITION_HWC))
329 .WillOnce(Return(NO_ERROR));
330
331 EXPECT_EQ(NO_ERROR, mSurface.prepareFrame(data));
332}
333
334TEST_F(RenderSurfaceTest, prepareFrameHandlesNoComposition) {
335 std::vector<CompositionInfo> data;
336
337 EXPECT_CALL(mHwComposer, prepare(*DEFAULT_DISPLAY_ID, Ref(data))).WillOnce(Return(NO_ERROR));
338 EXPECT_CALL(mHwComposer, hasClientComposition(DEFAULT_DISPLAY_ID)).WillOnce(Return(false));
339 EXPECT_CALL(mHwComposer, hasDeviceComposition(DEFAULT_DISPLAY_ID)).WillOnce(Return(false));
340
341 EXPECT_CALL(*mDisplaySurface, prepareFrame(DisplaySurface::COMPOSITION_HWC))
342 .WillOnce(Return(NO_ERROR));
343
344 EXPECT_EQ(NO_ERROR, mSurface.prepareFrame(data));
345}
346
347/* ------------------------------------------------------------------------
348 * RenderSurface::dequeueBuffer()
349 */
350
351TEST_F(RenderSurfaceTest, dequeueBufferObtainsABuffer) {
352 sp<GraphicBuffer> buffer = new GraphicBuffer();
353
354 EXPECT_CALL(*mNativeWindow, dequeueBuffer(_, _))
355 .WillOnce(
356 DoAll(SetArgPointee<0>(buffer.get()), SetArgPointee<1>(-1), Return(NO_ERROR)));
357
358 EXPECT_EQ(buffer.get(), mSurface.dequeueBuffer().get());
359
360 EXPECT_EQ(buffer.get(), mSurface.mutableGraphicBufferForTest().get());
361}
362
363/* ------------------------------------------------------------------------
364 * RenderSurface::queueBuffer()
365 */
366
367TEST_F(RenderSurfaceTest, queueBufferHandlesNoClientComposition) {
368 sp<GraphicBuffer> buffer = new GraphicBuffer();
369 mSurface.mutableGraphicBufferForTest() = buffer;
370
371 EXPECT_CALL(mHwComposer, hasClientComposition(DEFAULT_DISPLAY_ID)).WillOnce(Return(false));
372 EXPECT_CALL(mHwComposer, hasFlipClientTargetRequest(DEFAULT_DISPLAY_ID))
373 .WillOnce(Return(false));
374 EXPECT_CALL(*mDisplaySurface, advanceFrame()).Times(1);
375
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000376 mSurface.queueBuffer(base::unique_fd());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700377
378 EXPECT_EQ(buffer.get(), mSurface.mutableGraphicBufferForTest().get());
379}
380
381TEST_F(RenderSurfaceTest, queueBufferHandlesClientComposition) {
382 sp<GraphicBuffer> buffer = new GraphicBuffer();
383 mSurface.mutableGraphicBufferForTest() = buffer;
384
385 EXPECT_CALL(mHwComposer, hasClientComposition(DEFAULT_DISPLAY_ID)).WillOnce(Return(true));
386 EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getNativeBuffer(), -1))
387 .WillOnce(Return(NO_ERROR));
388 EXPECT_CALL(*mDisplaySurface, advanceFrame()).Times(1);
389
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000390 mSurface.queueBuffer(base::unique_fd());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700391
392 EXPECT_EQ(nullptr, mSurface.mutableGraphicBufferForTest().get());
393}
394
395TEST_F(RenderSurfaceTest, queueBufferHandlesFlipClientTargetRequest) {
396 sp<GraphicBuffer> buffer = new GraphicBuffer();
397 mSurface.mutableGraphicBufferForTest() = buffer;
398
399 EXPECT_CALL(mHwComposer, hasClientComposition(DEFAULT_DISPLAY_ID)).WillOnce(Return(false));
400 EXPECT_CALL(mHwComposer, hasFlipClientTargetRequest(DEFAULT_DISPLAY_ID)).WillOnce(Return(true));
401 EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getNativeBuffer(), -1))
402 .WillOnce(Return(NO_ERROR));
403 EXPECT_CALL(*mDisplaySurface, advanceFrame()).Times(1);
404
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000405 mSurface.queueBuffer(base::unique_fd());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700406
407 EXPECT_EQ(nullptr, mSurface.mutableGraphicBufferForTest().get());
408}
409
410TEST_F(RenderSurfaceTest, queueBufferHandlesFlipClientTargetRequestWithNoBufferYetDequeued) {
411 sp<GraphicBuffer> buffer = new GraphicBuffer();
412
413 EXPECT_CALL(mHwComposer, hasClientComposition(DEFAULT_DISPLAY_ID)).WillOnce(Return(false));
414 EXPECT_CALL(mHwComposer, hasFlipClientTargetRequest(DEFAULT_DISPLAY_ID)).WillOnce(Return(true));
415 EXPECT_CALL(*mNativeWindow, dequeueBuffer(_, _))
416 .WillOnce(
417 DoAll(SetArgPointee<0>(buffer.get()), SetArgPointee<1>(-1), Return(NO_ERROR)));
418 EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getNativeBuffer(), -1))
419 .WillOnce(Return(NO_ERROR));
420 EXPECT_CALL(*mDisplaySurface, advanceFrame()).Times(1);
421
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000422 mSurface.queueBuffer(base::unique_fd());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700423
424 EXPECT_EQ(nullptr, mSurface.mutableGraphicBufferForTest().get());
425}
426
427TEST_F(RenderSurfaceTest, queueBufferHandlesNativeWindowQueueBufferFailureOnVirtualDisplay) {
428 sp<GraphicBuffer> buffer = new GraphicBuffer();
429 mSurface.mutableGraphicBufferForTest() = buffer;
430
431 EXPECT_CALL(mHwComposer, hasClientComposition(DEFAULT_DISPLAY_ID)).WillOnce(Return(true));
432 EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getNativeBuffer(), -1))
433 .WillOnce(Return(INVALID_OPERATION));
434 EXPECT_CALL(mDisplay, isVirtual()).WillOnce(Return(true));
435 EXPECT_CALL(*mNativeWindow, cancelBuffer(buffer->getNativeBuffer(), -1))
436 .WillOnce(Return(NO_ERROR));
437 EXPECT_CALL(*mDisplaySurface, advanceFrame()).Times(1);
438
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000439 mSurface.queueBuffer(base::unique_fd());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700440
441 EXPECT_EQ(nullptr, mSurface.mutableGraphicBufferForTest().get());
442}
443
444/* ------------------------------------------------------------------------
445 * RenderSurface::onPresentDisplayCompleted()
446 */
447
448TEST_F(RenderSurfaceTest, onPresentDisplayCompletedForwardsSignal) {
449 EXPECT_CALL(*mDisplaySurface, onFrameCommitted()).Times(1);
450
451 mSurface.onPresentDisplayCompleted();
452}
453
454/* ------------------------------------------------------------------------
Lloyd Pique31cb2942018-10-19 17:23:03 -0700455 * RenderSurface::setViewportAndProjection()
456 */
457
458TEST_F(RenderSurfaceTest, setViewportAndProjectionAppliesChang) {
459 mSurface.setSizeForTest(ui::Size(100, 200));
460
461 EXPECT_CALL(mRenderEngine,
462 setViewportAndProjection(100, 200, Rect(100, 200), ui::Transform::ROT_0))
463 .Times(1);
464
465 mSurface.setViewportAndProjection();
466}
467
468/* ------------------------------------------------------------------------
469 * RenderSurface::flip()
470 */
471
472TEST_F(RenderSurfaceTest, flipForwardsSignal) {
473 mSurface.setPageFlipCountForTest(500);
474
475 mSurface.flip();
476
477 EXPECT_EQ(501, mSurface.getPageFlipCount());
478}
479
480} // namespace
481} // namespace android::compositionengine