blob: 8fdbd99347bf4512bba7949e3a8150257d4e0ec1 [file] [log] [blame]
Marin Shalamanov07b1ff32020-10-07 16:57:22 +02001/*
2 * Copyright 2020 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"
Marin Shalamanovbed7fd32020-12-21 20:02:20 +010022#pragma clang diagnostic ignored "-Wextra"
Marin Shalamanov07b1ff32020-10-07 16:57:22 +020023
24#include <type_traits>
Alec Mouriff793872022-01-13 17:45:06 -080025#include "DisplayIdentificationTestHelpers.h"
Marin Shalamanov07b1ff32020-10-07 16:57:22 +020026
27#include <binder/IPCThreadState.h>
28#include <compositionengine/Display.h>
29#include <compositionengine/DisplayColorProfile.h>
30#include <compositionengine/impl/Display.h>
31#include <compositionengine/impl/OutputCompositionState.h>
32#include <compositionengine/mock/Display.h>
33#include <compositionengine/mock/DisplayColorProfile.h>
34#include <compositionengine/mock/DisplaySurface.h>
35#include <compositionengine/mock/RenderSurface.h>
36#include <gmock/gmock.h>
37#include <gtest/gtest.h>
38#include <gui/mock/GraphicBufferConsumer.h>
39#include <gui/mock/GraphicBufferProducer.h>
40#include <log/log.h>
41#include <private/android_filesystem_config.h>
42#include <renderengine/mock/RenderEngine.h>
43#include <ui/DebugUtils.h>
44
45#include "TestableScheduler.h"
46#include "TestableSurfaceFlinger.h"
47#include "mock/DisplayHardware/MockComposer.h"
48#include "mock/DisplayHardware/MockPowerAdvisor.h"
49#include "mock/MockEventThread.h"
Marin Shalamanov07b1ff32020-10-07 16:57:22 +020050#include "mock/MockNativeWindowSurface.h"
51#include "mock/MockSchedulerCallback.h"
52#include "mock/MockSurfaceInterceptor.h"
53#include "mock/MockVsyncController.h"
54#include "mock/system/window/MockNativeWindow.h"
55
56namespace android {
57
58// TODO: Do not polute the android namespace
59namespace hal = android::hardware::graphics::composer::hal;
60
61using testing::_;
62using testing::AnyNumber;
63using testing::DoAll;
64using testing::Mock;
65using testing::ResultOf;
66using testing::Return;
67using testing::SetArgPointee;
68
Leon Scroggins III5967aec2021-12-29 11:14:22 -050069using aidl::android::hardware::graphics::composer3::DisplayCapability;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +020070using hal::ColorMode;
71using hal::Connection;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +020072using hal::DisplayType;
73using hal::Error;
74using hal::Hdr;
75using hal::HWDisplayId;
76using hal::IComposer;
77using hal::IComposerClient;
78using hal::PerFrameMetadataKey;
79using hal::PowerMode;
80
81class DisplayTransactionTest : public testing::Test {
82public:
83 ~DisplayTransactionTest() override;
84
85 // --------------------------------------------------------------------
86 // Mock/Fake injection
87
88 void injectMockScheduler();
89 void injectMockComposer(int virtualDisplayCount);
90 void injectFakeBufferQueueFactory();
91 void injectFakeNativeWindowSurfaceFactory();
92 sp<DisplayDevice> injectDefaultInternalDisplay(
93 std::function<void(TestableSurfaceFlinger::FakeDisplayDeviceInjector&)>);
94
95 // --------------------------------------------------------------------
96 // Postcondition helpers
97
98 bool hasPhysicalHwcDisplay(hal::HWDisplayId hwcDisplayId);
99 bool hasTransactionFlagSet(int flag);
100 bool hasDisplayDevice(sp<IBinder> displayToken);
101 sp<DisplayDevice> getDisplayDevice(sp<IBinder> displayToken);
102 bool hasCurrentDisplayState(sp<IBinder> displayToken);
103 const DisplayDeviceState& getCurrentDisplayState(sp<IBinder> displayToken);
104 bool hasDrawingDisplayState(sp<IBinder> displayToken);
105 const DisplayDeviceState& getDrawingDisplayState(sp<IBinder> displayToken);
106
107 // --------------------------------------------------------------------
108 // Test instances
109
110 TestableSurfaceFlinger mFlinger;
111 sp<mock::NativeWindow> mNativeWindow = new mock::NativeWindow();
112 sp<GraphicBuffer> mBuffer = new GraphicBuffer();
113 Hwc2::mock::PowerAdvisor mPowerAdvisor;
114
115 // These mocks are created by the test, but are destroyed by SurfaceFlinger
116 // by virtue of being stored into a std::unique_ptr. However we still need
117 // to keep a reference to them for use in setting up call expectations.
118 renderengine::mock::RenderEngine* mRenderEngine = new renderengine::mock::RenderEngine();
119 Hwc2::mock::Composer* mComposer = nullptr;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200120 sp<mock::SurfaceInterceptor> mSurfaceInterceptor = new mock::SurfaceInterceptor;
121
122 mock::VsyncController* mVsyncController = new mock::VsyncController;
123 mock::VSyncTracker* mVSyncTracker = new mock::VSyncTracker;
Dominik Laskowski068173d2021-08-11 17:22:59 -0700124 scheduler::mock::SchedulerCallback mSchedulerCallback;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200125 mock::EventThread* mEventThread = new mock::EventThread;
126 mock::EventThread* mSFEventThread = new mock::EventThread;
127
128 // These mocks are created only when expected to be created via a factory.
129 sp<mock::GraphicBufferConsumer> mConsumer;
130 sp<mock::GraphicBufferProducer> mProducer;
131 surfaceflinger::mock::NativeWindowSurface* mNativeWindowSurface = nullptr;
132
133protected:
134 DisplayTransactionTest();
135};
136
Marin Shalamanova903d032020-12-29 20:35:13 +0100137constexpr int32_t DEFAULT_VSYNC_PERIOD = 16'666'667;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200138constexpr int32_t DEFAULT_DPI = 320;
139constexpr int DEFAULT_VIRTUAL_DISPLAY_SURFACE_FORMAT = HAL_PIXEL_FORMAT_RGB_565;
140
141constexpr int POWER_MODE_LEET = 1337; // An out of range power mode value
142
143/* ------------------------------------------------------------------------
144 * Boolean avoidance
145 *
146 * To make calls and template instantiations more readable, we define some
147 * local enums along with an implicit bool conversion.
148 */
149
150#define BOOL_SUBSTITUTE(TYPENAME) enum class TYPENAME : bool { FALSE = false, TRUE = true };
151
152BOOL_SUBSTITUTE(Async);
153BOOL_SUBSTITUTE(Critical);
154BOOL_SUBSTITUTE(Primary);
155BOOL_SUBSTITUTE(Secure);
156BOOL_SUBSTITUTE(Virtual);
157
158template <typename PhysicalDisplay>
159struct PhysicalDisplayIdType {};
160
161template <uint64_t displayId>
162using HalVirtualDisplayIdType = std::integral_constant<uint64_t, displayId>;
163
164struct GpuVirtualDisplayIdType {};
165
166template <typename>
167struct IsPhysicalDisplayId : std::bool_constant<false> {};
168
169template <typename PhysicalDisplay>
170struct IsPhysicalDisplayId<PhysicalDisplayIdType<PhysicalDisplay>> : std::bool_constant<true> {};
171
172template <typename>
173struct DisplayIdGetter;
174
175template <typename PhysicalDisplay>
176struct DisplayIdGetter<PhysicalDisplayIdType<PhysicalDisplay>> {
177 static PhysicalDisplayId get() {
178 if (!PhysicalDisplay::HAS_IDENTIFICATION_DATA) {
179 return PhysicalDisplayId::fromPort(static_cast<bool>(PhysicalDisplay::PRIMARY)
180 ? LEGACY_DISPLAY_TYPE_PRIMARY
181 : LEGACY_DISPLAY_TYPE_EXTERNAL);
182 }
183
184 const auto info =
185 parseDisplayIdentificationData(PhysicalDisplay::PORT,
186 PhysicalDisplay::GET_IDENTIFICATION_DATA());
187 return info ? info->id : PhysicalDisplayId::fromPort(PhysicalDisplay::PORT);
188 }
189};
190
191template <uint64_t displayId>
192struct DisplayIdGetter<HalVirtualDisplayIdType<displayId>> {
193 static HalVirtualDisplayId get() { return HalVirtualDisplayId(displayId); }
194};
195
196template <>
197struct DisplayIdGetter<GpuVirtualDisplayIdType> {
198 static GpuVirtualDisplayId get() { return GpuVirtualDisplayId(0); }
199};
200
201template <typename>
202struct DisplayConnectionTypeGetter {
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100203 static constexpr std::optional<ui::DisplayConnectionType> value;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200204};
205
206template <typename PhysicalDisplay>
207struct DisplayConnectionTypeGetter<PhysicalDisplayIdType<PhysicalDisplay>> {
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100208 static constexpr std::optional<ui::DisplayConnectionType> value =
209 PhysicalDisplay::CONNECTION_TYPE;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200210};
211
212template <typename>
213struct HwcDisplayIdGetter {
214 static constexpr std::optional<HWDisplayId> value;
215};
216
217constexpr HWDisplayId HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID = 1010;
218
219template <uint64_t displayId>
220struct HwcDisplayIdGetter<HalVirtualDisplayIdType<displayId>> {
221 static constexpr std::optional<HWDisplayId> value = HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID;
222};
223
224template <typename PhysicalDisplay>
225struct HwcDisplayIdGetter<PhysicalDisplayIdType<PhysicalDisplay>> {
226 static constexpr std::optional<HWDisplayId> value = PhysicalDisplay::HWC_DISPLAY_ID;
227};
228
229// DisplayIdType can be:
230// 1) PhysicalDisplayIdType<...> for generated ID of physical display backed by HWC.
231// 2) HalVirtualDisplayIdType<...> for hard-coded ID of virtual display backed by HWC.
232// 3) GpuVirtualDisplayIdType for virtual display without HWC backing.
233template <typename DisplayIdType, int width, int height, Critical critical, Async async,
Vishnu Naira119aaa2021-09-24 07:19:35 -0700234 Secure secure, Primary primary, int grallocUsage, int displayFlags>
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200235struct DisplayVariant {
236 using DISPLAY_ID = DisplayIdGetter<DisplayIdType>;
237 using CONNECTION_TYPE = DisplayConnectionTypeGetter<DisplayIdType>;
238 using HWC_DISPLAY_ID_OPT = HwcDisplayIdGetter<DisplayIdType>;
239
240 // The display width and height
241 static constexpr int WIDTH = width;
242 static constexpr int HEIGHT = height;
243
244 static constexpr int GRALLOC_USAGE = grallocUsage;
245
246 // Whether the display is virtual or physical
247 static constexpr Virtual VIRTUAL =
248 IsPhysicalDisplayId<DisplayIdType>{} ? Virtual::FALSE : Virtual::TRUE;
249
250 // When creating native window surfaces for the framebuffer, whether those should be critical
251 static constexpr Critical CRITICAL = critical;
252
253 // When creating native window surfaces for the framebuffer, whether those should be async
254 static constexpr Async ASYNC = async;
255
256 // Whether the display should be treated as secure
257 static constexpr Secure SECURE = secure;
258
259 // Whether the display is primary
260 static constexpr Primary PRIMARY = primary;
261
Vishnu Naira119aaa2021-09-24 07:19:35 -0700262 static constexpr int DISPLAY_FLAGS = displayFlags;
263
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200264 static auto makeFakeExistingDisplayInjector(DisplayTransactionTest* test) {
265 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder();
Dominik Laskowski13948602021-03-08 20:48:28 -0800266 ceDisplayArgs.setId(DISPLAY_ID::get())
267 .setPixels({WIDTH, HEIGHT})
268 .setPowerAdvisor(&test->mPowerAdvisor);
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200269
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200270 auto compositionDisplay =
271 compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
272 ceDisplayArgs.build());
273
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200274 auto injector =
275 TestableSurfaceFlinger::FakeDisplayDeviceInjector(test->mFlinger,
276 compositionDisplay,
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700277 CONNECTION_TYPE::value,
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200278 HWC_DISPLAY_ID_OPT::value,
279 static_cast<bool>(PRIMARY));
280
281 injector.setSecure(static_cast<bool>(SECURE));
282 injector.setNativeWindow(test->mNativeWindow);
283
284 // Creating a DisplayDevice requires getting default dimensions from the
285 // native window along with some other initial setup.
286 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_WIDTH, _))
287 .WillRepeatedly(DoAll(SetArgPointee<1>(WIDTH), Return(0)));
288 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
289 .WillRepeatedly(DoAll(SetArgPointee<1>(HEIGHT), Return(0)));
290 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT))
291 .WillRepeatedly(Return(0));
292 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT))
293 .WillRepeatedly(Return(0));
294 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64))
295 .WillRepeatedly(Return(0));
296 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT))
297 .WillRepeatedly(Return(0));
298
299 return injector;
300 }
301
302 // Called by tests to set up any native window creation call expectations.
303 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
304 EXPECT_CALL(*test->mNativeWindowSurface, getNativeWindow())
305 .WillOnce(Return(test->mNativeWindow));
306
307 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_WIDTH, _))
308 .WillRepeatedly(DoAll(SetArgPointee<1>(WIDTH), Return(0)));
309 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
310 .WillRepeatedly(DoAll(SetArgPointee<1>(HEIGHT), Return(0)));
311 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT))
312 .WillRepeatedly(Return(0));
313 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT))
314 .WillRepeatedly(Return(0));
315 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64))
316 .WillRepeatedly(Return(0));
317 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT))
318 .WillRepeatedly(Return(0));
319 }
320
321 static void setupFramebufferConsumerBufferQueueCallExpectations(DisplayTransactionTest* test) {
322 EXPECT_CALL(*test->mConsumer, consumerConnect(_, false)).WillOnce(Return(NO_ERROR));
323 EXPECT_CALL(*test->mConsumer, setConsumerName(_)).WillRepeatedly(Return(NO_ERROR));
324 EXPECT_CALL(*test->mConsumer, setConsumerUsageBits(GRALLOC_USAGE))
325 .WillRepeatedly(Return(NO_ERROR));
326 EXPECT_CALL(*test->mConsumer, setDefaultBufferSize(WIDTH, HEIGHT))
327 .WillRepeatedly(Return(NO_ERROR));
328 EXPECT_CALL(*test->mConsumer, setMaxAcquiredBufferCount(_))
329 .WillRepeatedly(Return(NO_ERROR));
330 }
331
332 static void setupFramebufferProducerBufferQueueCallExpectations(DisplayTransactionTest* test) {
333 EXPECT_CALL(*test->mProducer, allocateBuffers(0, 0, 0, 0)).WillRepeatedly(Return());
334 }
335};
336
337template <HWDisplayId hwcDisplayId, DisplayType hwcDisplayType, typename DisplayVariant,
338 typename PhysicalDisplay = void>
339struct HwcDisplayVariant {
340 // The display id supplied by the HWC
341 static constexpr HWDisplayId HWC_DISPLAY_ID = hwcDisplayId;
342
343 // The HWC display type
344 static constexpr DisplayType HWC_DISPLAY_TYPE = hwcDisplayType;
345
346 // The HWC active configuration id
Marin Shalamanov6e840172020-12-14 22:13:28 +0100347 static constexpr hal::HWConfigId HWC_ACTIVE_CONFIG_ID = 2001;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200348 static constexpr PowerMode INIT_POWER_MODE = hal::PowerMode::ON;
349
350 static void injectPendingHotplugEvent(DisplayTransactionTest* test, Connection connection) {
351 test->mFlinger.mutablePendingHotplugEvents().emplace_back(
352 TestableSurfaceFlinger::HotplugEvent{HWC_DISPLAY_ID, connection});
353 }
354
355 // Called by tests to inject a HWC display setup
356 static void injectHwcDisplayWithNoDefaultCapabilities(DisplayTransactionTest* test) {
357 const auto displayId = DisplayVariant::DISPLAY_ID::get();
358 ASSERT_FALSE(GpuVirtualDisplayId::tryCast(displayId));
359 TestableSurfaceFlinger::FakeHwcDisplayInjector(displayId, HWC_DISPLAY_TYPE,
360 static_cast<bool>(DisplayVariant::PRIMARY))
361 .setHwcDisplayId(HWC_DISPLAY_ID)
362 .setWidth(DisplayVariant::WIDTH)
363 .setHeight(DisplayVariant::HEIGHT)
364 .setActiveConfig(HWC_ACTIVE_CONFIG_ID)
365 .setPowerMode(INIT_POWER_MODE)
366 .inject(&test->mFlinger, test->mComposer);
367 }
368
369 // Called by tests to inject a HWC display setup
370 static void injectHwcDisplay(DisplayTransactionTest* test) {
371 EXPECT_CALL(*test->mComposer, getDisplayCapabilities(HWC_DISPLAY_ID, _))
372 .WillOnce(DoAll(SetArgPointee<1>(std::vector<DisplayCapability>({})),
373 Return(Error::NONE)));
374 EXPECT_CALL(*test->mComposer, setPowerMode(HWC_DISPLAY_ID, INIT_POWER_MODE))
375 .WillOnce(Return(Error::NONE));
376 injectHwcDisplayWithNoDefaultCapabilities(test);
377 }
378
379 static std::shared_ptr<compositionengine::Display> injectCompositionDisplay(
380 DisplayTransactionTest* test) {
381 const ::testing::TestInfo* const test_info =
382 ::testing::UnitTest::GetInstance()->current_test_info();
383
384 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
Dominik Laskowski13948602021-03-08 20:48:28 -0800385 .setId(DisplayVariant::DISPLAY_ID::get())
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200386 .setPixels({DisplayVariant::WIDTH, DisplayVariant::HEIGHT})
387 .setIsSecure(static_cast<bool>(DisplayVariant::SECURE))
388 .setPowerAdvisor(&test->mPowerAdvisor)
389 .setName(std::string("Injected display for ") +
390 test_info->test_case_name() + "." + test_info->name())
391 .build();
392
393 return compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
394 ceDisplayArgs);
395 }
396
Marin Shalamanov6e840172020-12-14 22:13:28 +0100397 static void setupHwcGetConfigsCallExpectations(DisplayTransactionTest* test) {
398 if (HWC_DISPLAY_TYPE == DisplayType::PHYSICAL) {
399 EXPECT_CALL(*test->mComposer, getDisplayConfigs(HWC_DISPLAY_ID, _))
400 .WillRepeatedly(DoAll(SetArgPointee<1>(std::vector<hal::HWConfigId>{
401 HWC_ACTIVE_CONFIG_ID}),
402 Return(Error::NONE)));
403 EXPECT_CALL(*test->mComposer,
404 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
405 IComposerClient::Attribute::WIDTH, _))
406 .WillRepeatedly(
407 DoAll(SetArgPointee<3>(DisplayVariant::WIDTH), Return(Error::NONE)));
408 EXPECT_CALL(*test->mComposer,
409 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
410 IComposerClient::Attribute::HEIGHT, _))
411 .WillRepeatedly(
412 DoAll(SetArgPointee<3>(DisplayVariant::HEIGHT), Return(Error::NONE)));
413 EXPECT_CALL(*test->mComposer,
414 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
415 IComposerClient::Attribute::VSYNC_PERIOD, _))
416 .WillRepeatedly(
Marin Shalamanova903d032020-12-29 20:35:13 +0100417 DoAll(SetArgPointee<3>(DEFAULT_VSYNC_PERIOD), Return(Error::NONE)));
Marin Shalamanov6e840172020-12-14 22:13:28 +0100418 EXPECT_CALL(*test->mComposer,
419 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
420 IComposerClient::Attribute::DPI_X, _))
421 .WillRepeatedly(DoAll(SetArgPointee<3>(DEFAULT_DPI), Return(Error::NONE)));
422 EXPECT_CALL(*test->mComposer,
423 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
424 IComposerClient::Attribute::DPI_Y, _))
425 .WillRepeatedly(DoAll(SetArgPointee<3>(DEFAULT_DPI), Return(Error::NONE)));
426 EXPECT_CALL(*test->mComposer,
427 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
428 IComposerClient::Attribute::CONFIG_GROUP, _))
429 .WillRepeatedly(DoAll(SetArgPointee<3>(-1), Return(Error::NONE)));
430 } else {
431 EXPECT_CALL(*test->mComposer, getDisplayConfigs(_, _)).Times(0);
432 EXPECT_CALL(*test->mComposer, getDisplayAttribute(_, _, _, _)).Times(0);
433 }
434 }
435
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200436 static void setupHwcHotplugCallExpectations(DisplayTransactionTest* test) {
437 constexpr auto CONNECTION_TYPE =
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100438 PhysicalDisplay::CONNECTION_TYPE == ui::DisplayConnectionType::Internal
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200439 ? IComposerClient::DisplayConnectionType::INTERNAL
440 : IComposerClient::DisplayConnectionType::EXTERNAL;
441
442 EXPECT_CALL(*test->mComposer, getDisplayConnectionType(HWC_DISPLAY_ID, _))
443 .WillOnce(DoAll(SetArgPointee<1>(CONNECTION_TYPE), Return(hal::V2_4::Error::NONE)));
444
445 EXPECT_CALL(*test->mComposer, setClientTargetSlotCount(_))
446 .WillOnce(Return(hal::Error::NONE));
Marin Shalamanov6e840172020-12-14 22:13:28 +0100447
448 setupHwcGetConfigsCallExpectations(test);
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200449
450 if (PhysicalDisplay::HAS_IDENTIFICATION_DATA) {
451 EXPECT_CALL(*test->mComposer, getDisplayIdentificationData(HWC_DISPLAY_ID, _, _))
452 .WillOnce(DoAll(SetArgPointee<1>(PhysicalDisplay::PORT),
453 SetArgPointee<2>(PhysicalDisplay::GET_IDENTIFICATION_DATA()),
454 Return(Error::NONE)));
455 } else {
456 EXPECT_CALL(*test->mComposer, getDisplayIdentificationData(HWC_DISPLAY_ID, _, _))
457 .WillOnce(Return(Error::UNSUPPORTED));
458 }
459 }
460
461 // Called by tests to set up HWC call expectations
462 static void setupHwcGetActiveConfigCallExpectations(DisplayTransactionTest* test) {
463 EXPECT_CALL(*test->mComposer, getActiveConfig(HWC_DISPLAY_ID, _))
464 .WillRepeatedly(DoAll(SetArgPointee<1>(HWC_ACTIVE_CONFIG_ID), Return(Error::NONE)));
465 }
466};
467
468// Physical displays are expected to be synchronous, secure, and have a HWC display for output.
469constexpr uint32_t GRALLOC_USAGE_PHYSICAL_DISPLAY =
470 GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_FB;
471
Vishnu Naira119aaa2021-09-24 07:19:35 -0700472constexpr int PHYSICAL_DISPLAY_FLAGS = 0x1;
473
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200474template <typename PhysicalDisplay, int width, int height, Critical critical>
475struct PhysicalDisplayVariant
476 : DisplayVariant<PhysicalDisplayIdType<PhysicalDisplay>, width, height, critical,
477 Async::FALSE, Secure::TRUE, PhysicalDisplay::PRIMARY,
Vishnu Naira119aaa2021-09-24 07:19:35 -0700478 GRALLOC_USAGE_PHYSICAL_DISPLAY, PHYSICAL_DISPLAY_FLAGS>,
479 HwcDisplayVariant<
480 PhysicalDisplay::HWC_DISPLAY_ID, DisplayType::PHYSICAL,
481 DisplayVariant<PhysicalDisplayIdType<PhysicalDisplay>, width, height, critical,
482 Async::FALSE, Secure::TRUE, PhysicalDisplay::PRIMARY,
483 GRALLOC_USAGE_PHYSICAL_DISPLAY, PHYSICAL_DISPLAY_FLAGS>,
484 PhysicalDisplay> {};
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200485
486template <bool hasIdentificationData>
487struct PrimaryDisplay {
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100488 static constexpr auto CONNECTION_TYPE = ui::DisplayConnectionType::Internal;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200489 static constexpr Primary PRIMARY = Primary::TRUE;
490 static constexpr uint8_t PORT = 255;
491 static constexpr HWDisplayId HWC_DISPLAY_ID = 1001;
492 static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData;
493 static constexpr auto GET_IDENTIFICATION_DATA = getInternalEdid;
494};
495
496template <bool hasIdentificationData>
497struct ExternalDisplay {
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100498 static constexpr auto CONNECTION_TYPE = ui::DisplayConnectionType::External;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200499 static constexpr Primary PRIMARY = Primary::FALSE;
500 static constexpr uint8_t PORT = 254;
501 static constexpr HWDisplayId HWC_DISPLAY_ID = 1002;
502 static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData;
503 static constexpr auto GET_IDENTIFICATION_DATA = getExternalEdid;
504};
505
506struct TertiaryDisplay {
507 static constexpr Primary PRIMARY = Primary::FALSE;
508 static constexpr uint8_t PORT = 253;
509 static constexpr HWDisplayId HWC_DISPLAY_ID = 1003;
510 static constexpr auto GET_IDENTIFICATION_DATA = getExternalEdid;
511};
512
513// A primary display is a physical display that is critical
514using PrimaryDisplayVariant =
515 PhysicalDisplayVariant<PrimaryDisplay<false>, 3840, 2160, Critical::TRUE>;
516
517// An external display is physical display that is not critical.
518using ExternalDisplayVariant =
519 PhysicalDisplayVariant<ExternalDisplay<false>, 1920, 1280, Critical::FALSE>;
520
521using TertiaryDisplayVariant = PhysicalDisplayVariant<TertiaryDisplay, 1600, 1200, Critical::FALSE>;
522
523// A virtual display not supported by the HWC.
524constexpr uint32_t GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY = 0;
525
Vishnu Naira119aaa2021-09-24 07:19:35 -0700526constexpr int VIRTUAL_DISPLAY_FLAGS = 0x0;
527
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200528template <int width, int height, Secure secure>
529struct NonHwcVirtualDisplayVariant
530 : DisplayVariant<GpuVirtualDisplayIdType, width, height, Critical::FALSE, Async::TRUE, secure,
Vishnu Naira119aaa2021-09-24 07:19:35 -0700531 Primary::FALSE, GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY,
532 VIRTUAL_DISPLAY_FLAGS> {
533 using Base = DisplayVariant<GpuVirtualDisplayIdType, width, height, Critical::FALSE,
534 Async::TRUE, secure, Primary::FALSE,
535 GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY, VIRTUAL_DISPLAY_FLAGS>;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200536
537 static void injectHwcDisplay(DisplayTransactionTest*) {}
538
539 static std::shared_ptr<compositionengine::Display> injectCompositionDisplay(
540 DisplayTransactionTest* test) {
541 const ::testing::TestInfo* const test_info =
542 ::testing::UnitTest::GetInstance()->current_test_info();
543
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200544 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
Dominik Laskowski13948602021-03-08 20:48:28 -0800545 .setId(Base::DISPLAY_ID::get())
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200546 .setPixels({Base::WIDTH, Base::HEIGHT})
547 .setIsSecure(static_cast<bool>(Base::SECURE))
548 .setPowerAdvisor(&test->mPowerAdvisor)
549 .setName(std::string("Injected display for ") +
550 test_info->test_case_name() + "." + test_info->name())
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200551 .build();
552
553 return compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
554 ceDisplayArgs);
555 }
556
Marin Shalamanov6e840172020-12-14 22:13:28 +0100557 static void setupHwcGetConfigsCallExpectations(DisplayTransactionTest* test) {
558 EXPECT_CALL(*test->mComposer, getDisplayConfigs(_, _)).Times(0);
559 EXPECT_CALL(*test->mComposer, getDisplayAttribute(_, _, _, _)).Times(0);
560 }
561
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200562 static void setupHwcGetActiveConfigCallExpectations(DisplayTransactionTest* test) {
563 EXPECT_CALL(*test->mComposer, getActiveConfig(_, _)).Times(0);
564 }
565
566 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
567 Base::setupNativeWindowSurfaceCreationCallExpectations(test);
568 EXPECT_CALL(*test->mNativeWindow, setSwapInterval(0)).Times(1);
569 }
570};
571
572// A virtual display supported by the HWC.
573constexpr uint32_t GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY = GRALLOC_USAGE_HW_COMPOSER;
574
575template <int width, int height, Secure secure>
576struct HwcVirtualDisplayVariant
577 : DisplayVariant<HalVirtualDisplayIdType<42>, width, height, Critical::FALSE, Async::TRUE,
Vishnu Naira119aaa2021-09-24 07:19:35 -0700578 secure, Primary::FALSE, GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY,
579 VIRTUAL_DISPLAY_FLAGS>,
580 HwcDisplayVariant<
581 HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID, DisplayType::VIRTUAL,
582 DisplayVariant<HalVirtualDisplayIdType<42>, width, height, Critical::FALSE,
583 Async::TRUE, secure, Primary::FALSE,
584 GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY, VIRTUAL_DISPLAY_FLAGS>> {
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200585 using Base = DisplayVariant<HalVirtualDisplayIdType<42>, width, height, Critical::FALSE,
Vishnu Naira119aaa2021-09-24 07:19:35 -0700586 Async::TRUE, secure, Primary::FALSE, GRALLOC_USAGE_HW_COMPOSER,
587 VIRTUAL_DISPLAY_FLAGS>;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200588 using Self = HwcVirtualDisplayVariant<width, height, secure>;
589
590 static std::shared_ptr<compositionengine::Display> injectCompositionDisplay(
591 DisplayTransactionTest* test) {
592 const ::testing::TestInfo* const test_info =
593 ::testing::UnitTest::GetInstance()->current_test_info();
594
Dominik Laskowski13948602021-03-08 20:48:28 -0800595 const auto displayId = Base::DISPLAY_ID::get();
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200596 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
Dominik Laskowski13948602021-03-08 20:48:28 -0800597 .setId(displayId)
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200598 .setPixels({Base::WIDTH, Base::HEIGHT})
599 .setIsSecure(static_cast<bool>(Base::SECURE))
600 .setPowerAdvisor(&test->mPowerAdvisor)
601 .setName(std::string("Injected display for ") +
602 test_info->test_case_name() + "." + test_info->name())
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200603 .build();
604
605 auto compositionDisplay =
606 compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
607 ceDisplayArgs);
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200608
609 // Insert display data so that the HWC thinks it created the virtual display.
Dominik Laskowski13948602021-03-08 20:48:28 -0800610 test->mFlinger.mutableHwcDisplayData().try_emplace(displayId);
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200611
612 return compositionDisplay;
613 }
614
615 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
616 Base::setupNativeWindowSurfaceCreationCallExpectations(test);
617 EXPECT_CALL(*test->mNativeWindow, setSwapInterval(0)).Times(1);
618 }
619
620 static void setupHwcVirtualDisplayCreationCallExpectations(DisplayTransactionTest* test) {
Dominik Laskowski263eec42021-07-21 23:13:24 -0700621 EXPECT_CALL(*test->mComposer, createVirtualDisplay(Base::WIDTH, Base::HEIGHT, _, _))
622 .WillOnce(DoAll(SetArgPointee<3>(Self::HWC_DISPLAY_ID), Return(Error::NONE)));
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200623 EXPECT_CALL(*test->mComposer, setClientTargetSlotCount(_)).WillOnce(Return(Error::NONE));
624 }
625};
626
627// For this variant, the display is not a HWC display, so no HDR support should
628// be configured.
629struct NonHwcDisplayHdrSupportVariant {
630 static constexpr bool HDR10_PLUS_SUPPORTED = false;
631 static constexpr bool HDR10_SUPPORTED = false;
632 static constexpr bool HDR_HLG_SUPPORTED = false;
633 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
634 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
635 EXPECT_CALL(*test->mComposer, getHdrCapabilities(_, _, _, _, _)).Times(0);
636 }
637};
638
639// For this variant, the composer should respond with am empty list of HDR
640// modes, so no HDR support should be configured.
641template <typename Display>
642struct HdrNotSupportedVariant {
643 static constexpr bool HDR10_PLUS_SUPPORTED = false;
644 static constexpr bool HDR10_SUPPORTED = false;
645 static constexpr bool HDR_HLG_SUPPORTED = false;
646 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
647 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
648 EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
649 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>()), Return(Error::NONE)));
650 }
651};
652
653struct NonHwcPerFrameMetadataSupportVariant {
654 static constexpr int PER_FRAME_METADATA_KEYS = 0;
655 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
656 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(_)).Times(0);
657 }
658};
659
660template <typename Display>
661struct NoPerFrameMetadataSupportVariant {
662 static constexpr int PER_FRAME_METADATA_KEYS = 0;
663 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
664 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(Display::HWC_DISPLAY_ID))
665 .WillOnce(Return(std::vector<PerFrameMetadataKey>()));
666 }
667};
668
669// For this variant, SurfaceFlinger should configure itself with wide display
670// support, but the display should respond with an empty list of supported color
671// modes. Wide-color support for the display should not be configured.
672template <typename Display>
673struct WideColorNotSupportedVariant {
674 static constexpr bool WIDE_COLOR_SUPPORTED = false;
675
676 static void injectConfigChange(DisplayTransactionTest* test) {
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200677 test->mFlinger.mutableHasWideColorDisplay() = true;
678 }
679
680 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
681 EXPECT_CALL(*test->mComposer, getColorModes(Display::HWC_DISPLAY_ID, _))
682 .WillOnce(DoAll(SetArgPointee<1>(std::vector<ColorMode>()), Return(Error::NONE)));
683 EXPECT_CALL(*test->mComposer, setColorMode(_, _, _)).Times(0);
684 }
685};
686
687// For this variant, SurfaceFlinger should not configure itself with wide
688// display support, so the display should not be configured for wide-color
689// support.
690struct WideColorSupportNotConfiguredVariant {
691 static constexpr bool WIDE_COLOR_SUPPORTED = false;
692
693 static void injectConfigChange(DisplayTransactionTest* test) {
694 test->mFlinger.mutableHasWideColorDisplay() = false;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200695 test->mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::kUnmanaged;
696 }
697
698 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
699 EXPECT_CALL(*test->mComposer, getColorModes(_, _)).Times(0);
700 EXPECT_CALL(*test->mComposer, getRenderIntents(_, _, _)).Times(0);
701 EXPECT_CALL(*test->mComposer, setColorMode(_, _, _)).Times(0);
702 }
703};
704
705/* ------------------------------------------------------------------------
706 * Typical display configurations to test
707 */
708
709template <typename DisplayPolicy, typename WideColorSupportPolicy, typename HdrSupportPolicy,
710 typename PerFrameMetadataSupportPolicy>
711struct Case {
712 using Display = DisplayPolicy;
713 using WideColorSupport = WideColorSupportPolicy;
714 using HdrSupport = HdrSupportPolicy;
715 using PerFrameMetadataSupport = PerFrameMetadataSupportPolicy;
716};
717
718using SimplePrimaryDisplayCase =
719 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
720 HdrNotSupportedVariant<PrimaryDisplayVariant>,
721 NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
722using SimpleExternalDisplayCase =
723 Case<ExternalDisplayVariant, WideColorNotSupportedVariant<ExternalDisplayVariant>,
724 HdrNotSupportedVariant<ExternalDisplayVariant>,
725 NoPerFrameMetadataSupportVariant<ExternalDisplayVariant>>;
726using SimpleTertiaryDisplayCase =
727 Case<TertiaryDisplayVariant, WideColorNotSupportedVariant<TertiaryDisplayVariant>,
728 HdrNotSupportedVariant<TertiaryDisplayVariant>,
729 NoPerFrameMetadataSupportVariant<TertiaryDisplayVariant>>;
730
731using NonHwcVirtualDisplayCase =
732 Case<NonHwcVirtualDisplayVariant<1024, 768, Secure::FALSE>,
733 WideColorSupportNotConfiguredVariant, NonHwcDisplayHdrSupportVariant,
734 NonHwcPerFrameMetadataSupportVariant>;
735using SimpleHwcVirtualDisplayVariant = HwcVirtualDisplayVariant<1024, 768, Secure::TRUE>;
736using HwcVirtualDisplayCase =
737 Case<SimpleHwcVirtualDisplayVariant, WideColorSupportNotConfiguredVariant,
738 HdrNotSupportedVariant<SimpleHwcVirtualDisplayVariant>,
739 NoPerFrameMetadataSupportVariant<SimpleHwcVirtualDisplayVariant>>;
740
741} // namespace android
742
743// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +0100744#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"