From aad4ebf31b49ce52ce16d81d74c331624e593e4a Mon Sep 17 00:00:00 2001 From: Lloyd Pique Date: Thu, 3 Oct 2019 17:58:30 -0700 Subject: SF: Start restructuring display creation Create the compositionengine::Display first thing, outside of DisplayDevice, and pass it in as part of creating the DisplayDevice, rather than creating it internal to DisplayDevice. Also to start, move the logic to allocate a DisplayId for a HWC backed virtual display into the CompositionEngine class. This is a first step to moving the internal setup of the display to CompositionEngine, and eventually eliminating DisplayDevice entirely, as it is but a thin wrapper around the other class. DisplayTransactionTest is adjusted so the dummy created DisplayDevices have an appropriate compositionengine::Display. Test: atest libsurfaceflinger_unittest libcompositionengine_test Bug: 142831417 Change-Id: I8417682f4ead7b550a8973d4716c627e31b07b6e Merged-In: I8417682f4ead7b550a8973d4716c627e31b07b6e (cherry picked from commit 9370a480fc0a99575a57500b03c9c45d9e52bc1d) --- .../surfaceflinger/CompositionEngine/Android.bp | 1 + .../compositionengine/DisplayCreationArgs.h | 78 ++- .../include/compositionengine/impl/Display.h | 33 +- .../CompositionEngine/src/Display.cpp | 35 +- .../CompositionEngine/tests/DisplayTest.cpp | 550 ++++++++++++++------- services/surfaceflinger/DisplayDevice.cpp | 14 +- services/surfaceflinger/DisplayDevice.h | 10 +- services/surfaceflinger/SurfaceFlinger.cpp | 94 ++-- services/surfaceflinger/SurfaceFlinger.h | 3 +- .../SurfaceFlingerDefaultFactory.cpp | 4 +- .../surfaceflinger/SurfaceFlingerDefaultFactory.h | 2 +- services/surfaceflinger/SurfaceFlingerFactory.h | 2 +- .../tests/unittests/CompositionTest.cpp | 71 ++- .../tests/unittests/DisplayTransactionTest.cpp | 200 +++++--- .../tests/unittests/TestableSurfaceFlinger.h | 35 +- 15 files changed, 772 insertions(+), 360 deletions(-) diff --git a/services/surfaceflinger/CompositionEngine/Android.bp b/services/surfaceflinger/CompositionEngine/Android.bp index 27922900cf..fda451bd9e 100644 --- a/services/surfaceflinger/CompositionEngine/Android.bp +++ b/services/surfaceflinger/CompositionEngine/Android.bp @@ -104,6 +104,7 @@ cc_test { static_libs: [ "libcompositionengine", "libcompositionengine_mocks", + "libgui_mocks", "librenderengine_mocks", "libgmock", "libgtest", diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h index ced4227b44..6bc677d432 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h @@ -18,6 +18,11 @@ #include #include +#include + +#include +#include +#include #include "DisplayHardware/DisplayIdentification.h" #include "DisplayHardware/PowerAdvisor.h" @@ -30,47 +35,86 @@ class CompositionEngine; * A parameter object for creating Display instances */ struct DisplayCreationArgs { - // True if this display is a virtual display - bool isVirtual = false; + struct Physical { + DisplayId id; + DisplayConnectionType type; + }; + + // Required for physical displays. Gives the HWC display id for the existing + // display along with the connection type. + std::optional physical; + + // Size of the display in pixels + ui::Size pixels = ui::Size::INVALID; + + // Pixel format of the display + ui::PixelFormat pixelFormat = static_cast(PIXEL_FORMAT_UNKNOWN); - // Identifies the display to the HWC, if composition is supported by it - std::optional displayId; + // True if virtual displays should be created with the HWC API if possible + bool useHwcVirtualDisplays = false; + + // True if this display should be considered secure + bool isSecure = false; + + // Gives the initial layer stack id to be used for the display + uint32_t layerStackId = ~0u; // Optional pointer to the power advisor interface, if one is needed for // this display. Hwc2::PowerAdvisor* powerAdvisor = nullptr; + + // Debugging. Human readable name for the display. + std::string name; }; /** * A helper for setting up a DisplayCreationArgs value in-line. * Prefer this builder over raw structure initialization. - * - * Instead of: - * - * DisplayCreationArgs{false, false, displayId} - * - * Prefer: - * - * DisplayCreationArgsBuilder().setIsVirtual(false) - * .setDisplayId(displayId).build(); */ class DisplayCreationArgsBuilder { public: DisplayCreationArgs build() { return std::move(mArgs); } - DisplayCreationArgsBuilder& setIsVirtual(bool isVirtual) { - mArgs.isVirtual = isVirtual; + DisplayCreationArgsBuilder& setPhysical(DisplayCreationArgs::Physical physical) { + mArgs.physical = physical; + return *this; + } + + DisplayCreationArgsBuilder& setPixels(ui::Size pixels) { + mArgs.pixels = pixels; return *this; } - DisplayCreationArgsBuilder& setDisplayId(std::optional displayId) { - mArgs.displayId = displayId; + + DisplayCreationArgsBuilder& setPixelFormat(ui::PixelFormat pixelFormat) { + mArgs.pixelFormat = pixelFormat; + return *this; + } + + DisplayCreationArgsBuilder& setUseHwcVirtualDisplays(bool useHwcVirtualDisplays) { + mArgs.useHwcVirtualDisplays = useHwcVirtualDisplays; + return *this; + } + + DisplayCreationArgsBuilder& setIsSecure(bool isSecure) { + mArgs.isSecure = isSecure; return *this; } + + DisplayCreationArgsBuilder& setLayerStackId(uint32_t layerStackId) { + mArgs.layerStackId = layerStackId; + return *this; + } + DisplayCreationArgsBuilder& setPowerAdvisor(Hwc2::PowerAdvisor* powerAdvisor) { mArgs.powerAdvisor = powerAdvisor; return *this; } + DisplayCreationArgsBuilder& setName(std::string name) { + mArgs.name = std::move(name); + return *this; + } + private: DisplayCreationArgs mArgs; }; diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h index fb597ce1ff..9ca7d2f9fb 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h @@ -16,11 +16,15 @@ #pragma once +#include + #include +#include #include +#include #include - -#include +#include +#include #include "DisplayHardware/DisplayIdentification.h" #include "DisplayHardware/HWComposer.h" @@ -36,11 +40,11 @@ namespace impl { // actually contain the final display state. class Display : public compositionengine::impl::Output, public virtual compositionengine::Display { public: - explicit Display(const compositionengine::DisplayCreationArgs&); virtual ~Display(); // compositionengine::Output overrides std::optional getDisplayId() const override; + bool isValid() const override; void dump(std::string&) const override; using compositionengine::impl::Output::setReleasedLayers; void setReleasedLayers(const CompositionRefreshArgs&) override; @@ -73,22 +77,33 @@ public: virtual void applyLayerRequestsToLayers(const LayerRequests&); // Internal + virtual void setConfiguration(const compositionengine::DisplayCreationArgs&); + virtual std::optional maybeAllocateDisplayIdForVirtualDisplay(ui::Size, + ui::PixelFormat) const; std::unique_ptr createOutputLayer(const sp&) const; + // Testing + void setDisplayIdForTesting(std::optional displayId); + private: - const bool mIsVirtual; + bool mIsVirtual = false; std::optional mId; - Hwc2::PowerAdvisor* const mPowerAdvisor{nullptr}; + Hwc2::PowerAdvisor* mPowerAdvisor = nullptr; }; // This template factory function standardizes the implementation details of the // final class using the types actually required by the implementation. This is // not possible to do in the base class as those types may not even be visible // to the base code. -template -std::shared_ptr createDisplayTemplated(const CompositionEngine& compositionEngine, - const DisplayCreationArgs& args) { - return createOutputTemplated(compositionEngine, args); +template +std::shared_ptr createDisplayTemplated( + const CompositionEngine& compositionEngine, + const compositionengine::DisplayCreationArgs& args) { + auto display = createOutputTemplated(compositionEngine); + + display->setConfiguration(args); + + return display; } std::shared_ptr createDisplay(const compositionengine::CompositionEngine&, diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp index 1d8a23f460..c3454059aa 100644 --- a/services/surfaceflinger/CompositionEngine/src/Display.cpp +++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp @@ -47,11 +47,36 @@ std::shared_ptr createDisplay( return createDisplayTemplated(compositionEngine, args); } -Display::Display(const DisplayCreationArgs& args) - : mIsVirtual(args.isVirtual), mId(args.displayId), mPowerAdvisor(args.powerAdvisor) {} - Display::~Display() = default; +void Display::setConfiguration(const compositionengine::DisplayCreationArgs& args) { + mIsVirtual = !args.physical; + mId = args.physical ? std::make_optional(args.physical->id) : std::nullopt; + mPowerAdvisor = args.powerAdvisor; + + editState().isSecure = args.isSecure; + + setLayerStackFilter(args.layerStackId, + args.physical ? args.physical->type == DisplayConnectionType::Internal + : false); + setName(args.name); + + if (!args.physical && args.useHwcVirtualDisplays) { + mId = maybeAllocateDisplayIdForVirtualDisplay(args.pixels, args.pixelFormat); + } +} + +std::optional Display::maybeAllocateDisplayIdForVirtualDisplay( + ui::Size pixels, ui::PixelFormat pixelFormat) const { + auto& hwc = getCompositionEngine().getHwComposer(); + return hwc.allocateVirtualDisplay(static_cast(pixels.width), + static_cast(pixels.height), &pixelFormat); +} + +bool Display::isValid() const { + return Output::isValid() && mPowerAdvisor; +} + const std::optional& Display::getId() const { return mId; } @@ -68,6 +93,10 @@ std::optional Display::getDisplayId() const { return mId; } +void Display::setDisplayIdForTesting(std::optional displayId) { + mId = displayId; +} + void Display::disconnect() { if (!mId) { return; diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp index 16f7a4ef46..88f2686aca 100644 --- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include "MockHWC2.h" #include "MockHWComposer.h" @@ -40,8 +42,11 @@ namespace { using testing::_; using testing::DoAll; +using testing::Eq; using testing::InSequence; using testing::NiceMock; +using testing::Pointee; +using testing::Ref; using testing::Return; using testing::ReturnRef; using testing::Sequence; @@ -49,8 +54,10 @@ using testing::SetArgPointee; using testing::StrictMock; constexpr DisplayId DEFAULT_DISPLAY_ID = DisplayId{42}; +constexpr DisplayId VIRTUAL_DISPLAY_ID = DisplayId{43}; constexpr int32_t DEFAULT_DISPLAY_WIDTH = 1920; constexpr int32_t DEFAULT_DISPLAY_HEIGHT = 1080; +constexpr int32_t DEFAULT_LAYER_STACK = 123; struct Layer { Layer() { @@ -73,25 +80,126 @@ struct LayerNoHWC2Layer { StrictMock* outputLayer = new StrictMock(); }; -struct DisplayTest : public testing::Test { - class Display : public impl::Display { +struct DisplayTestCommon : public testing::Test { + // Uses the full implementation of a display + class FullImplDisplay : public impl::Display { public: - explicit Display(const compositionengine::DisplayCreationArgs& args) - : impl::Display(args) {} - using impl::Display::injectOutputLayerForTest; virtual void injectOutputLayerForTest(std::unique_ptr) = 0; + + using impl::Display::maybeAllocateDisplayIdForVirtualDisplay; + }; + + // Uses a special implementation with key internal member functions set up + // as mock implementations, to allow for easier testing. + struct PartialMockDisplay : public impl::Display { + PartialMockDisplay(const compositionengine::CompositionEngine& compositionEngine) + : mCompositionEngine(compositionEngine) {} + + // compositionengine::Output overrides + const OutputCompositionState& getState() const override { return mState; } + OutputCompositionState& editState() override { return mState; } + + // compositionengine::impl::Output overrides + const CompositionEngine& getCompositionEngine() const override { + return mCompositionEngine; + }; + + // Mock implementation overrides + MOCK_CONST_METHOD0(getOutputLayerCount, size_t()); + MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, + compositionengine::OutputLayer*(size_t)); + MOCK_METHOD2(ensureOutputLayer, + compositionengine::OutputLayer*(std::optional, const sp&)); + MOCK_METHOD0(finalizePendingOutputLayers, void()); + MOCK_METHOD0(clearOutputLayers, void()); + MOCK_CONST_METHOD1(dumpState, void(std::string&)); + MOCK_METHOD1(injectOutputLayerForTest, compositionengine::OutputLayer*(const sp&)); + MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr)); + MOCK_CONST_METHOD0(anyLayersRequireClientComposition, bool()); + MOCK_CONST_METHOD0(allLayersRequireClientComposition, bool()); + MOCK_METHOD1(applyChangedTypesToLayers, void(const impl::Display::ChangedTypes&)); + MOCK_METHOD1(applyDisplayRequests, void(const impl::Display::DisplayRequests&)); + MOCK_METHOD1(applyLayerRequestsToLayers, void(const impl::Display::LayerRequests&)); + + const compositionengine::CompositionEngine& mCompositionEngine; + impl::OutputCompositionState mState; }; + static std::string getDisplayNameFromCurrentTest() { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + return std::string("display for ") + test_info->test_case_name() + "." + test_info->name(); + } + + template static std::shared_ptr createDisplay( const compositionengine::CompositionEngine& compositionEngine, - compositionengine::DisplayCreationArgs&& args) { + compositionengine::DisplayCreationArgs args) { + args.name = getDisplayNameFromCurrentTest(); return impl::createDisplayTemplated(compositionEngine, args); } - DisplayTest() { + template + static std::shared_ptr> createPartialMockDisplay( + const compositionengine::CompositionEngine& compositionEngine, + compositionengine::DisplayCreationArgs args) { + args.name = getDisplayNameFromCurrentTest(); + auto display = std::make_shared>(compositionEngine); + + display->setConfiguration(args); + + return display; + } + + DisplayTestCommon() { EXPECT_CALL(mCompositionEngine, getHwComposer()).WillRepeatedly(ReturnRef(mHwComposer)); + } + + DisplayCreationArgs getDisplayCreationArgsForPhysicalHWCDisplay() { + return DisplayCreationArgsBuilder() + .setPhysical({DEFAULT_DISPLAY_ID, DisplayConnectionType::Internal}) + .setPixels({DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT}) + .setPixelFormat(static_cast(PIXEL_FORMAT_RGBA_8888)) + .setIsSecure(true) + .setLayerStackId(DEFAULT_LAYER_STACK) + .setPowerAdvisor(&mPowerAdvisor) + .build(); + } + DisplayCreationArgs getDisplayCreationArgsForNonHWCVirtualDisplay() { + return DisplayCreationArgsBuilder() + .setUseHwcVirtualDisplays(false) + .setPixels({DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT}) + .setPixelFormat(static_cast(PIXEL_FORMAT_RGBA_8888)) + .setIsSecure(false) + .setLayerStackId(DEFAULT_LAYER_STACK) + .setPowerAdvisor(&mPowerAdvisor) + .build(); + } + + StrictMock mHwComposer; + StrictMock mPowerAdvisor; + StrictMock mCompositionEngine; + sp mNativeWindow = new StrictMock(); +}; + +struct PartialMockDisplayTestCommon : public DisplayTestCommon { + using Display = DisplayTestCommon::PartialMockDisplay; + std::shared_ptr mDisplay = + createPartialMockDisplay(mCompositionEngine, + getDisplayCreationArgsForPhysicalHWCDisplay()); +}; + +struct FullDisplayImplTestCommon : public DisplayTestCommon { + using Display = DisplayTestCommon::FullImplDisplay; + std::shared_ptr mDisplay = + createDisplay(mCompositionEngine, + getDisplayCreationArgsForPhysicalHWCDisplay()); +}; + +struct DisplayWithLayersTestCommon : public FullDisplayImplTestCommon { + DisplayWithLayersTestCommon() { mDisplay->injectOutputLayerForTest( std::unique_ptr(mLayer1.outputLayer)); mDisplay->injectOutputLayerForTest( @@ -100,65 +208,166 @@ struct DisplayTest : public testing::Test { std::unique_ptr(mLayer3.outputLayer)); } - StrictMock mHwComposer; - StrictMock mPowerAdvisor; - StrictMock mCompositionEngine; - sp mNativeWindow = new StrictMock(); Layer mLayer1; Layer mLayer2; LayerNoHWC2Layer mLayer3; StrictMock hwc2LayerUnknown; - - std::shared_ptr mDisplay = createDisplay(mCompositionEngine, - DisplayCreationArgsBuilder() - .setDisplayId(DEFAULT_DISPLAY_ID) - .setPowerAdvisor(&mPowerAdvisor) - .build()); + std::shared_ptr mDisplay = + createDisplay(mCompositionEngine, + getDisplayCreationArgsForPhysicalHWCDisplay()); }; /* * Basic construction */ -TEST_F(DisplayTest, canInstantiateDisplay) { - { - constexpr DisplayId display1 = DisplayId{123u}; - auto display = - impl::createDisplay(mCompositionEngine, - DisplayCreationArgsBuilder().setDisplayId(display1).build()); - EXPECT_FALSE(display->isSecure()); - EXPECT_FALSE(display->isVirtual()); - EXPECT_EQ(display1, display->getId()); - } +struct DisplayCreationTest : public DisplayTestCommon { + using Display = DisplayTestCommon::FullImplDisplay; +}; - { - constexpr DisplayId display2 = DisplayId{546u}; - auto display = - impl::createDisplay(mCompositionEngine, - DisplayCreationArgsBuilder().setDisplayId(display2).build()); - EXPECT_FALSE(display->isSecure()); - EXPECT_FALSE(display->isVirtual()); - EXPECT_EQ(display2, display->getId()); - } +TEST_F(DisplayCreationTest, createPhysicalInternalDisplay) { + auto display = + impl::createDisplay(mCompositionEngine, getDisplayCreationArgsForPhysicalHWCDisplay()); + EXPECT_TRUE(display->isSecure()); + EXPECT_FALSE(display->isVirtual()); + EXPECT_EQ(DEFAULT_DISPLAY_ID, display->getId()); +} - { - constexpr DisplayId display3 = DisplayId{789u}; - auto display = impl::createDisplay(mCompositionEngine, - DisplayCreationArgsBuilder() - .setIsVirtual(true) - .setDisplayId(display3) - .build()); - EXPECT_FALSE(display->isSecure()); - EXPECT_TRUE(display->isVirtual()); - EXPECT_EQ(display3, display->getId()); - } +TEST_F(DisplayCreationTest, createNonHwcVirtualDisplay) { + auto display = impl::createDisplay(mCompositionEngine, + getDisplayCreationArgsForNonHWCVirtualDisplay()); + EXPECT_FALSE(display->isSecure()); + EXPECT_TRUE(display->isVirtual()); + EXPECT_EQ(std::nullopt, display->getId()); +} + +/* + * Display::setConfiguration() + */ + +using DisplaySetConfigurationTest = PartialMockDisplayTestCommon; + +TEST_F(DisplaySetConfigurationTest, configuresInternalSecurePhysicalDisplay) { + mDisplay->setConfiguration( + DisplayCreationArgsBuilder() + .setUseHwcVirtualDisplays(true) + .setPhysical({DEFAULT_DISPLAY_ID, DisplayConnectionType::Internal}) + .setPixels(ui::Size(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_WIDTH)) + .setPixelFormat(static_cast(PIXEL_FORMAT_RGBA_8888)) + .setIsSecure(true) + .setLayerStackId(DEFAULT_LAYER_STACK) + .setPowerAdvisor(&mPowerAdvisor) + .setName(getDisplayNameFromCurrentTest()) + .build()); + + EXPECT_EQ(DEFAULT_DISPLAY_ID, mDisplay->getId()); + EXPECT_TRUE(mDisplay->isSecure()); + EXPECT_FALSE(mDisplay->isVirtual()); + EXPECT_EQ(DEFAULT_LAYER_STACK, mDisplay->getState().layerStackId); + EXPECT_TRUE(mDisplay->getState().layerStackInternal); + EXPECT_FALSE(mDisplay->isValid()); +} + +TEST_F(DisplaySetConfigurationTest, configuresExternalInsecurePhysicalDisplay) { + mDisplay->setConfiguration( + DisplayCreationArgsBuilder() + .setUseHwcVirtualDisplays(true) + .setPhysical({DEFAULT_DISPLAY_ID, DisplayConnectionType::External}) + .setPixels(ui::Size(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_WIDTH)) + .setPixelFormat(static_cast(PIXEL_FORMAT_RGBA_8888)) + .setIsSecure(false) + .setLayerStackId(DEFAULT_LAYER_STACK) + .setPowerAdvisor(&mPowerAdvisor) + .setName(getDisplayNameFromCurrentTest()) + .build()); + + EXPECT_EQ(DEFAULT_DISPLAY_ID, mDisplay->getId()); + EXPECT_FALSE(mDisplay->isSecure()); + EXPECT_FALSE(mDisplay->isVirtual()); + EXPECT_EQ(DEFAULT_LAYER_STACK, mDisplay->getState().layerStackId); + EXPECT_FALSE(mDisplay->getState().layerStackInternal); + EXPECT_FALSE(mDisplay->isValid()); +} + +TEST_F(DisplaySetConfigurationTest, configuresHwcBackedVirtualDisplay) { + EXPECT_CALL(mHwComposer, + allocateVirtualDisplay(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_WIDTH, + Pointee(Eq(static_cast( + PIXEL_FORMAT_RGBA_8888))))) + .WillOnce(Return(VIRTUAL_DISPLAY_ID)); + + mDisplay->setConfiguration( + DisplayCreationArgsBuilder() + .setUseHwcVirtualDisplays(true) + .setPixels(ui::Size(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_WIDTH)) + .setPixelFormat(static_cast(PIXEL_FORMAT_RGBA_8888)) + .setIsSecure(false) + .setLayerStackId(DEFAULT_LAYER_STACK) + .setPowerAdvisor(&mPowerAdvisor) + .setName(getDisplayNameFromCurrentTest()) + .build()); + + EXPECT_EQ(VIRTUAL_DISPLAY_ID, mDisplay->getId()); + EXPECT_FALSE(mDisplay->isSecure()); + EXPECT_TRUE(mDisplay->isVirtual()); + EXPECT_EQ(DEFAULT_LAYER_STACK, mDisplay->getState().layerStackId); + EXPECT_FALSE(mDisplay->getState().layerStackInternal); + EXPECT_FALSE(mDisplay->isValid()); +} + +TEST_F(DisplaySetConfigurationTest, configuresNonHwcBackedVirtualDisplayIfHwcAllocationFails) { + EXPECT_CALL(mHwComposer, + allocateVirtualDisplay(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_WIDTH, + Pointee(Eq(static_cast( + PIXEL_FORMAT_RGBA_8888))))) + .WillOnce(Return(std::nullopt)); + + mDisplay->setConfiguration( + DisplayCreationArgsBuilder() + .setUseHwcVirtualDisplays(true) + .setPixels(ui::Size(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_WIDTH)) + .setPixelFormat(static_cast(PIXEL_FORMAT_RGBA_8888)) + .setIsSecure(false) + .setLayerStackId(DEFAULT_LAYER_STACK) + .setPowerAdvisor(&mPowerAdvisor) + .setName(getDisplayNameFromCurrentTest()) + .build()); + + EXPECT_EQ(std::nullopt, mDisplay->getId()); + EXPECT_FALSE(mDisplay->isSecure()); + EXPECT_TRUE(mDisplay->isVirtual()); + EXPECT_EQ(DEFAULT_LAYER_STACK, mDisplay->getState().layerStackId); + EXPECT_FALSE(mDisplay->getState().layerStackInternal); + EXPECT_FALSE(mDisplay->isValid()); +} + +TEST_F(DisplaySetConfigurationTest, configuresNonHwcBackedVirtualDisplayIfShouldNotUseHwc) { + mDisplay->setConfiguration( + DisplayCreationArgsBuilder() + .setUseHwcVirtualDisplays(false) + .setPixels(ui::Size(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_WIDTH)) + .setPixelFormat(static_cast(PIXEL_FORMAT_RGBA_8888)) + .setIsSecure(false) + .setLayerStackId(DEFAULT_LAYER_STACK) + .setPowerAdvisor(&mPowerAdvisor) + .setName(getDisplayNameFromCurrentTest()) + .build()); + + EXPECT_EQ(std::nullopt, mDisplay->getId()); + EXPECT_FALSE(mDisplay->isSecure()); + EXPECT_TRUE(mDisplay->isVirtual()); + EXPECT_EQ(DEFAULT_LAYER_STACK, mDisplay->getState().layerStackId); + EXPECT_FALSE(mDisplay->getState().layerStackInternal); + EXPECT_FALSE(mDisplay->isValid()); } /* * Display::disconnect() */ -TEST_F(DisplayTest, disconnectDisconnectsDisplay) { +using DisplayDisconnectTest = PartialMockDisplayTestCommon; + +TEST_F(DisplayDisconnectTest, disconnectsDisplay) { // The first call to disconnect will disconnect the display with the HWC and // set mHwcId to -1. EXPECT_CALL(mHwComposer, disconnectDisplay(DEFAULT_DISPLAY_ID)).Times(1); @@ -175,7 +384,9 @@ TEST_F(DisplayTest, disconnectDisconnectsDisplay) { * Display::setColorTransform() */ -TEST_F(DisplayTest, setColorTransformSetsTransform) { +using DisplaySetColorTransformTest = PartialMockDisplayTestCommon; + +TEST_F(DisplaySetColorTransformTest, setsTransform) { // No change does nothing CompositionRefreshArgs refreshArgs; refreshArgs.colorTransformMatrix = std::nullopt; @@ -202,7 +413,9 @@ TEST_F(DisplayTest, setColorTransformSetsTransform) { * Display::setColorMode() */ -TEST_F(DisplayTest, setColorModeSetsModeUnlessNoChange) { +using DisplaySetColorModeTest = PartialMockDisplayTestCommon; + +TEST_F(DisplaySetColorModeTest, setsModeUnlessNoChange) { using ColorProfile = Output::ColorProfile; mock::RenderSurface* renderSurface = new StrictMock(); @@ -245,11 +458,11 @@ TEST_F(DisplayTest, setColorModeSetsModeUnlessNoChange) { EXPECT_EQ(ui::Dataspace::UNKNOWN, mDisplay->getState().targetDataspace); } -TEST_F(DisplayTest, setColorModeDoesNothingForVirtualDisplay) { +TEST_F(DisplaySetColorModeTest, doesNothingForVirtualDisplay) { using ColorProfile = Output::ColorProfile; - std::shared_ptr virtualDisplay{ - impl::createDisplay(mCompositionEngine, DisplayCreationArgs{true, DEFAULT_DISPLAY_ID})}; + auto args = getDisplayCreationArgsForNonHWCVirtualDisplay(); + std::shared_ptr virtualDisplay = impl::createDisplay(mCompositionEngine, args); mock::DisplayColorProfile* colorProfile = new StrictMock(); virtualDisplay->setDisplayColorProfileForTest( @@ -274,7 +487,9 @@ TEST_F(DisplayTest, setColorModeDoesNothingForVirtualDisplay) { * Display::createDisplayColorProfile() */ -TEST_F(DisplayTest, createDisplayColorProfileSetsDisplayColorProfile) { +using DisplayCreateColorProfileTest = PartialMockDisplayTestCommon; + +TEST_F(DisplayCreateColorProfileTest, setsDisplayColorProfile) { EXPECT_TRUE(mDisplay->getDisplayColorProfile() == nullptr); mDisplay->createDisplayColorProfile( DisplayColorProfileCreationArgs{false, HdrCapabilities(), 0, @@ -286,7 +501,9 @@ TEST_F(DisplayTest, createDisplayColorProfileSetsDisplayColorProfile) { * Display::createRenderSurface() */ -TEST_F(DisplayTest, createRenderSurfaceSetsRenderSurface) { +using DisplayCreateRenderSurfaceTest = PartialMockDisplayTestCommon; + +TEST_F(DisplayCreateRenderSurfaceTest, setsRenderSurface) { EXPECT_CALL(*mNativeWindow, disconnect(NATIVE_WINDOW_API_EGL)).WillRepeatedly(Return(NO_ERROR)); EXPECT_TRUE(mDisplay->getRenderSurface() == nullptr); mDisplay->createRenderSurface(RenderSurfaceCreationArgs{640, 480, mNativeWindow, nullptr}); @@ -297,7 +514,9 @@ TEST_F(DisplayTest, createRenderSurfaceSetsRenderSurface) { * Display::createOutputLayer() */ -TEST_F(DisplayTest, createOutputLayerSetsHwcLayer) { +using DisplayCreateOutputLayerTest = FullDisplayImplTestCommon; + +TEST_F(DisplayCreateOutputLayerTest, setsHwcLayer) { sp layerFE = new StrictMock(); StrictMock hwcLayer; @@ -315,9 +534,11 @@ TEST_F(DisplayTest, createOutputLayerSetsHwcLayer) { * Display::setReleasedLayers() */ -TEST_F(DisplayTest, setReleasedLayersDoesNothingIfNotHwcDisplay) { - std::shared_ptr nonHwcDisplay{ - impl::createDisplay(mCompositionEngine, DisplayCreationArgsBuilder().build())}; +using DisplaySetReleasedLayersTest = DisplayWithLayersTestCommon; + +TEST_F(DisplaySetReleasedLayersTest, doesNothingIfNotHwcDisplay) { + auto args = getDisplayCreationArgsForNonHWCVirtualDisplay(); + std::shared_ptr nonHwcDisplay = impl::createDisplay(mCompositionEngine, args); sp layerXLayerFE = new StrictMock(); @@ -336,7 +557,7 @@ TEST_F(DisplayTest, setReleasedLayersDoesNothingIfNotHwcDisplay) { ASSERT_EQ(1, releasedLayers.size()); } -TEST_F(DisplayTest, setReleasedLayersDoesNothingIfNoLayersWithQueuedFrames) { +TEST_F(DisplaySetReleasedLayersTest, doesNothingIfNoLayersWithQueuedFrames) { sp layerXLayerFE = new StrictMock(); { @@ -352,7 +573,7 @@ TEST_F(DisplayTest, setReleasedLayersDoesNothingIfNoLayersWithQueuedFrames) { ASSERT_EQ(1, releasedLayers.size()); } -TEST_F(DisplayTest, setReleasedLayers) { +TEST_F(DisplaySetReleasedLayersTest, setReleasedLayers) { sp unknownLayer = new StrictMock(); CompositionRefreshArgs refreshArgs; @@ -372,59 +593,12 @@ TEST_F(DisplayTest, setReleasedLayers) { * Display::chooseCompositionStrategy() */ -struct DisplayChooseCompositionStrategyTest : public testing::Test { - struct DisplayPartialMock : public impl::Display { - DisplayPartialMock(const compositionengine::CompositionEngine& compositionEngine, - const compositionengine::DisplayCreationArgs& args) - : impl::Display(args), mCompositionEngine(compositionEngine) {} - - // Sets up the helper functions called by chooseCompositionStrategy to - // use a mock implementations. - MOCK_CONST_METHOD0(anyLayersRequireClientComposition, bool()); - MOCK_CONST_METHOD0(allLayersRequireClientComposition, bool()); - MOCK_METHOD1(applyChangedTypesToLayers, void(const impl::Display::ChangedTypes&)); - MOCK_METHOD1(applyDisplayRequests, void(const impl::Display::DisplayRequests&)); - MOCK_METHOD1(applyLayerRequestsToLayers, void(const impl::Display::LayerRequests&)); - - // compositionengine::Output overrides - const OutputCompositionState& getState() const override { return mState; } - OutputCompositionState& editState() override { return mState; } - - // compositionengine::impl::Output overrides - const CompositionEngine& getCompositionEngine() const override { - return mCompositionEngine; - }; - - // These need implementations though are not expected to be called. - MOCK_CONST_METHOD0(getOutputLayerCount, size_t()); - MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, - compositionengine::OutputLayer*(size_t)); - MOCK_METHOD2(ensureOutputLayer, - compositionengine::OutputLayer*(std::optional, const sp&)); - MOCK_METHOD0(finalizePendingOutputLayers, void()); - MOCK_METHOD0(clearOutputLayers, void()); - MOCK_CONST_METHOD1(dumpState, void(std::string&)); - MOCK_METHOD1(injectOutputLayerForTest, compositionengine::OutputLayer*(const sp&)); - MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr)); - - const compositionengine::CompositionEngine& mCompositionEngine; - impl::OutputCompositionState mState; - }; - - DisplayChooseCompositionStrategyTest() { - EXPECT_CALL(mCompositionEngine, getHwComposer()).WillRepeatedly(ReturnRef(mHwComposer)); - } - - StrictMock mHwComposer; - StrictMock mCompositionEngine; - StrictMock - mDisplay{mCompositionEngine, - DisplayCreationArgsBuilder().setDisplayId(DEFAULT_DISPLAY_ID).build()}; -}; +using DisplayChooseCompositionStrategyTest = PartialMockDisplayTestCommon; TEST_F(DisplayChooseCompositionStrategyTest, takesEarlyOutIfNotAHwcDisplay) { - std::shared_ptr nonHwcDisplay{ - impl::createDisplay(mCompositionEngine, DisplayCreationArgsBuilder().build())}; + auto args = getDisplayCreationArgsForNonHWCVirtualDisplay(); + std::shared_ptr nonHwcDisplay = + createPartialMockDisplay(mCompositionEngine, args); EXPECT_FALSE(nonHwcDisplay->getId()); nonHwcDisplay->chooseCompositionStrategy(); @@ -435,33 +609,36 @@ TEST_F(DisplayChooseCompositionStrategyTest, takesEarlyOutIfNotAHwcDisplay) { } TEST_F(DisplayChooseCompositionStrategyTest, takesEarlyOutOnHwcError) { - EXPECT_CALL(mDisplay, anyLayersRequireClientComposition()).WillOnce(Return(false)); + EXPECT_CALL(*mDisplay, anyLayersRequireClientComposition()).WillOnce(Return(false)); EXPECT_CALL(mHwComposer, getDeviceCompositionChanges(DEFAULT_DISPLAY_ID, false, _)) .WillOnce(Return(INVALID_OPERATION)); - mDisplay.chooseCompositionStrategy(); + mDisplay->chooseCompositionStrategy(); - auto& state = mDisplay.getState(); + auto& state = mDisplay->getState(); EXPECT_TRUE(state.usesClientComposition); EXPECT_FALSE(state.usesDeviceComposition); } TEST_F(DisplayChooseCompositionStrategyTest, normalOperation) { - // Since two calls are made to anyLayersRequireClientComposition with different return values, - // use a Sequence to control the matching so the values are returned in a known order. + // Since two calls are made to anyLayersRequireClientComposition with different return + // values, use a Sequence to control the matching so the values are returned in a known + // order. Sequence s; - EXPECT_CALL(mDisplay, anyLayersRequireClientComposition()).InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(mDisplay, anyLayersRequireClientComposition()) + EXPECT_CALL(*mDisplay, anyLayersRequireClientComposition()) + .InSequence(s) + .WillOnce(Return(true)); + EXPECT_CALL(*mDisplay, anyLayersRequireClientComposition()) .InSequence(s) .WillOnce(Return(false)); EXPECT_CALL(mHwComposer, getDeviceCompositionChanges(DEFAULT_DISPLAY_ID, true, _)) .WillOnce(Return(NO_ERROR)); - EXPECT_CALL(mDisplay, allLayersRequireClientComposition()).WillOnce(Return(false)); + EXPECT_CALL(*mDisplay, allLayersRequireClientComposition()).WillOnce(Return(false)); - mDisplay.chooseCompositionStrategy(); + mDisplay->chooseCompositionStrategy(); - auto& state = mDisplay.getState(); + auto& state = mDisplay->getState(); EXPECT_FALSE(state.usesClientComposition); EXPECT_TRUE(state.usesDeviceComposition); } @@ -473,24 +650,27 @@ TEST_F(DisplayChooseCompositionStrategyTest, normalOperationWithChanges) { {{nullptr, HWC2::LayerRequest::ClearClientTarget}}, }; - // Since two calls are made to anyLayersRequireClientComposition with different return values, - // use a Sequence to control the matching so the values are returned in a known order. + // Since two calls are made to anyLayersRequireClientComposition with different return + // values, use a Sequence to control the matching so the values are returned in a known + // order. Sequence s; - EXPECT_CALL(mDisplay, anyLayersRequireClientComposition()).InSequence(s).WillOnce(Return(true)); - EXPECT_CALL(mDisplay, anyLayersRequireClientComposition()) + EXPECT_CALL(*mDisplay, anyLayersRequireClientComposition()) + .InSequence(s) + .WillOnce(Return(true)); + EXPECT_CALL(*mDisplay, anyLayersRequireClientComposition()) .InSequence(s) .WillOnce(Return(false)); EXPECT_CALL(mHwComposer, getDeviceCompositionChanges(DEFAULT_DISPLAY_ID, true, _)) .WillOnce(DoAll(SetArgPointee<2>(changes), Return(NO_ERROR))); - EXPECT_CALL(mDisplay, applyChangedTypesToLayers(changes.changedTypes)).Times(1); - EXPECT_CALL(mDisplay, applyDisplayRequests(changes.displayRequests)).Times(1); - EXPECT_CALL(mDisplay, applyLayerRequestsToLayers(changes.layerRequests)).Times(1); - EXPECT_CALL(mDisplay, allLayersRequireClientComposition()).WillOnce(Return(false)); + EXPECT_CALL(*mDisplay, applyChangedTypesToLayers(changes.changedTypes)).Times(1); + EXPECT_CALL(*mDisplay, applyDisplayRequests(changes.displayRequests)).Times(1); + EXPECT_CALL(*mDisplay, applyLayerRequestsToLayers(changes.layerRequests)).Times(1); + EXPECT_CALL(*mDisplay, allLayersRequireClientComposition()).WillOnce(Return(false)); - mDisplay.chooseCompositionStrategy(); + mDisplay->chooseCompositionStrategy(); - auto& state = mDisplay.getState(); + auto& state = mDisplay->getState(); EXPECT_FALSE(state.usesClientComposition); EXPECT_TRUE(state.usesDeviceComposition); } @@ -499,13 +679,15 @@ TEST_F(DisplayChooseCompositionStrategyTest, normalOperationWithChanges) { * Display::getSkipColorTransform() */ -TEST_F(DisplayTest, getSkipColorTransformDoesNothingIfNonHwcDisplay) { - auto nonHwcDisplay{ - impl::createDisplay(mCompositionEngine, DisplayCreationArgsBuilder().build())}; +using DisplayGetSkipColorTransformTest = DisplayWithLayersTestCommon; + +TEST_F(DisplayGetSkipColorTransformTest, doesNothingIfNonHwcDisplay) { + auto args = getDisplayCreationArgsForNonHWCVirtualDisplay(); + auto nonHwcDisplay{impl::createDisplay(mCompositionEngine, args)}; EXPECT_FALSE(nonHwcDisplay->getSkipColorTransform()); } -TEST_F(DisplayTest, getSkipColorTransformChecksHwcCapability) { +TEST_F(DisplayGetSkipColorTransformTest, checksHwcCapability) { EXPECT_CALL(mHwComposer, hasDisplayCapability(std::make_optional(DEFAULT_DISPLAY_ID), HWC2::DisplayCapability::SkipClientColorTransform)) @@ -517,7 +699,9 @@ TEST_F(DisplayTest, getSkipColorTransformChecksHwcCapability) { * Display::anyLayersRequireClientComposition() */ -TEST_F(DisplayTest, anyLayersRequireClientCompositionReturnsFalse) { +using DisplayAnyLayersRequireClientCompositionTest = DisplayWithLayersTestCommon; + +TEST_F(DisplayAnyLayersRequireClientCompositionTest, returnsFalse) { EXPECT_CALL(*mLayer1.outputLayer, requiresClientComposition()).WillOnce(Return(false)); EXPECT_CALL(*mLayer2.outputLayer, requiresClientComposition()).WillOnce(Return(false)); EXPECT_CALL(*mLayer3.outputLayer, requiresClientComposition()).WillOnce(Return(false)); @@ -525,7 +709,7 @@ TEST_F(DisplayTest, anyLayersRequireClientCompositionReturnsFalse) { EXPECT_FALSE(mDisplay->anyLayersRequireClientComposition()); } -TEST_F(DisplayTest, anyLayersRequireClientCompositionReturnsTrue) { +TEST_F(DisplayAnyLayersRequireClientCompositionTest, returnsTrue) { EXPECT_CALL(*mLayer1.outputLayer, requiresClientComposition()).WillOnce(Return(false)); EXPECT_CALL(*mLayer2.outputLayer, requiresClientComposition()).WillOnce(Return(true)); @@ -536,7 +720,9 @@ TEST_F(DisplayTest, anyLayersRequireClientCompositionReturnsTrue) { * Display::allLayersRequireClientComposition() */ -TEST_F(DisplayTest, allLayersRequireClientCompositionReturnsTrue) { +using DisplayAllLayersRequireClientCompositionTest = DisplayWithLayersTestCommon; + +TEST_F(DisplayAllLayersRequireClientCompositionTest, returnsTrue) { EXPECT_CALL(*mLayer1.outputLayer, requiresClientComposition()).WillOnce(Return(true)); EXPECT_CALL(*mLayer2.outputLayer, requiresClientComposition()).WillOnce(Return(true)); EXPECT_CALL(*mLayer3.outputLayer, requiresClientComposition()).WillOnce(Return(true)); @@ -544,7 +730,7 @@ TEST_F(DisplayTest, allLayersRequireClientCompositionReturnsTrue) { EXPECT_TRUE(mDisplay->allLayersRequireClientComposition()); } -TEST_F(DisplayTest, allLayersRequireClientCompositionReturnsFalse) { +TEST_F(DisplayAllLayersRequireClientCompositionTest, returnsFalse) { EXPECT_CALL(*mLayer1.outputLayer, requiresClientComposition()).WillOnce(Return(true)); EXPECT_CALL(*mLayer2.outputLayer, requiresClientComposition()).WillOnce(Return(false)); @@ -555,11 +741,13 @@ TEST_F(DisplayTest, allLayersRequireClientCompositionReturnsFalse) { * Display::applyChangedTypesToLayers() */ -TEST_F(DisplayTest, applyChangedTypesToLayersTakesEarlyOutIfNoChangedLayers) { +using DisplayApplyChangedTypesToLayersTest = DisplayWithLayersTestCommon; + +TEST_F(DisplayApplyChangedTypesToLayersTest, takesEarlyOutIfNoChangedLayers) { mDisplay->applyChangedTypesToLayers(impl::Display::ChangedTypes()); } -TEST_F(DisplayTest, applyChangedTypesToLayersAppliesChanges) { +TEST_F(DisplayApplyChangedTypesToLayersTest, appliesChanges) { EXPECT_CALL(*mLayer1.outputLayer, applyDeviceCompositionTypeChange(Hwc2::IComposerClient::Composition::CLIENT)) .Times(1); @@ -578,28 +766,30 @@ TEST_F(DisplayTest, applyChangedTypesToLayersAppliesChanges) { * Display::applyDisplayRequests() */ -TEST_F(DisplayTest, applyDisplayRequestsToLayersHandlesNoRequests) { +using DisplayApplyDisplayRequestsTest = DisplayWithLayersTestCommon; + +TEST_F(DisplayApplyDisplayRequestsTest, handlesNoRequests) { mDisplay->applyDisplayRequests(static_cast(0)); auto& state = mDisplay->getState(); EXPECT_FALSE(state.flipClientTarget); } -TEST_F(DisplayTest, applyDisplayRequestsToLayersHandlesFlipClientTarget) { +TEST_F(DisplayApplyDisplayRequestsTest, handlesFlipClientTarget) { mDisplay->applyDisplayRequests(HWC2::DisplayRequest::FlipClientTarget); auto& state = mDisplay->getState(); EXPECT_TRUE(state.flipClientTarget); } -TEST_F(DisplayTest, applyDisplayRequestsToLayersHandlesWriteClientTargetToOutput) { +TEST_F(DisplayApplyDisplayRequestsTest, handlesWriteClientTargetToOutput) { mDisplay->applyDisplayRequests(HWC2::DisplayRequest::WriteClientTargetToOutput); auto& state = mDisplay->getState(); EXPECT_FALSE(state.flipClientTarget); } -TEST_F(DisplayTest, applyDisplayRequestsToLayersHandlesAllRequestFlagsSet) { +TEST_F(DisplayApplyDisplayRequestsTest, handlesAllRequestFlagsSet) { mDisplay->applyDisplayRequests(static_cast(~0)); auto& state = mDisplay->getState(); @@ -610,7 +800,9 @@ TEST_F(DisplayTest, applyDisplayRequestsToLayersHandlesAllRequestFlagsSet) { * Display::applyLayerRequestsToLayers() */ -TEST_F(DisplayTest, applyLayerRequestsToLayersPreparesAllLayers) { +using DisplayApplyLayerRequestsToLayersTest = DisplayWithLayersTestCommon; + +TEST_F(DisplayApplyLayerRequestsToLayersTest, preparesAllLayers) { EXPECT_CALL(*mLayer1.outputLayer, prepareForDeviceLayerRequests()).Times(1); EXPECT_CALL(*mLayer2.outputLayer, prepareForDeviceLayerRequests()).Times(1); EXPECT_CALL(*mLayer3.outputLayer, prepareForDeviceLayerRequests()).Times(1); @@ -618,7 +810,7 @@ TEST_F(DisplayTest, applyLayerRequestsToLayersPreparesAllLayers) { mDisplay->applyLayerRequestsToLayers(impl::Display::LayerRequests()); } -TEST_F(DisplayTest, applyLayerRequestsToLayers2) { +TEST_F(DisplayApplyLayerRequestsToLayersTest, appliesDeviceLayerRequests) { EXPECT_CALL(*mLayer1.outputLayer, prepareForDeviceLayerRequests()).Times(1); EXPECT_CALL(*mLayer2.outputLayer, prepareForDeviceLayerRequests()).Times(1); EXPECT_CALL(*mLayer3.outputLayer, prepareForDeviceLayerRequests()).Times(1); @@ -637,9 +829,11 @@ TEST_F(DisplayTest, applyLayerRequestsToLayers2) { * Display::presentAndGetFrameFences() */ -TEST_F(DisplayTest, presentAndGetFrameFencesReturnsNoFencesOnNonHwcDisplay) { - auto nonHwcDisplay{ - impl::createDisplay(mCompositionEngine, DisplayCreationArgsBuilder().build())}; +using DisplayPresentAndGetFrameFencesTest = DisplayWithLayersTestCommon; + +TEST_F(DisplayPresentAndGetFrameFencesTest, returnsNoFencesOnNonHwcDisplay) { + auto args = getDisplayCreationArgsForNonHWCVirtualDisplay(); + auto nonHwcDisplay{impl::createDisplay(mCompositionEngine, args)}; auto result = nonHwcDisplay->presentAndGetFrameFences(); @@ -648,7 +842,7 @@ TEST_F(DisplayTest, presentAndGetFrameFencesReturnsNoFencesOnNonHwcDisplay) { EXPECT_EQ(0u, result.layerFences.size()); } -TEST_F(DisplayTest, presentAndGetFrameFencesReturnsPresentAndLayerFences) { +TEST_F(DisplayPresentAndGetFrameFencesTest, returnsPresentAndLayerFences) { sp presentFence = new Fence(); sp layer1Fence = new Fence(); sp layer2Fence = new Fence(); @@ -676,7 +870,9 @@ TEST_F(DisplayTest, presentAndGetFrameFencesReturnsPresentAndLayerFences) { * Display::setExpensiveRenderingExpected() */ -TEST_F(DisplayTest, setExpensiveRenderingExpectedForwardsToPowerAdvisor) { +using DisplaySetExpensiveRenderingExpectedTest = DisplayWithLayersTestCommon; + +TEST_F(DisplaySetExpensiveRenderingExpectedTest, forwardsToPowerAdvisor) { EXPECT_CALL(mPowerAdvisor, setExpensiveRenderingExpected(DEFAULT_DISPLAY_ID, true)).Times(1); mDisplay->setExpensiveRenderingExpected(true); @@ -688,7 +884,9 @@ TEST_F(DisplayTest, setExpensiveRenderingExpectedForwardsToPowerAdvisor) { * Display::finishFrame() */ -TEST_F(DisplayTest, finishFrameDoesNotSkipCompositionIfNotDirtyOnHwcDisplay) { +using DisplayFinishFrameTest = DisplayWithLayersTestCommon; + +TEST_F(DisplayFinishFrameTest, doesNotSkipCompositionIfNotDirtyOnHwcDisplay) { mock::RenderSurface* renderSurface = new StrictMock(); mDisplay->setRenderSurfaceForTest(std::unique_ptr(renderSurface)); @@ -709,9 +907,9 @@ TEST_F(DisplayTest, finishFrameDoesNotSkipCompositionIfNotDirtyOnHwcDisplay) { mDisplay->finishFrame(refreshArgs); } -TEST_F(DisplayTest, finishFrameSkipsCompositionIfNotDirty) { - std::shared_ptr nonHwcDisplay{ - impl::createDisplay(mCompositionEngine, DisplayCreationArgsBuilder().build())}; +TEST_F(DisplayFinishFrameTest, skipsCompositionIfNotDirty) { + auto args = getDisplayCreationArgsForNonHWCVirtualDisplay(); + std::shared_ptr nonHwcDisplay = impl::createDisplay(mCompositionEngine, args); mock::RenderSurface* renderSurface = new StrictMock(); nonHwcDisplay->setRenderSurfaceForTest(std::unique_ptr(renderSurface)); @@ -730,9 +928,9 @@ TEST_F(DisplayTest, finishFrameSkipsCompositionIfNotDirty) { nonHwcDisplay->finishFrame(refreshArgs); } -TEST_F(DisplayTest, finishFramePerformsCompositionIfDirty) { - std::shared_ptr nonHwcDisplay{ - impl::createDisplay(mCompositionEngine, DisplayCreationArgsBuilder().build())}; +TEST_F(DisplayFinishFrameTest, performsCompositionIfDirty) { + auto args = getDisplayCreationArgsForNonHWCVirtualDisplay(); + std::shared_ptr nonHwcDisplay = impl::createDisplay(mCompositionEngine, args); mock::RenderSurface* renderSurface = new StrictMock(); nonHwcDisplay->setRenderSurfaceForTest(std::unique_ptr(renderSurface)); @@ -751,9 +949,9 @@ TEST_F(DisplayTest, finishFramePerformsCompositionIfDirty) { nonHwcDisplay->finishFrame(refreshArgs); } -TEST_F(DisplayTest, finishFramePerformsCompositionIfRepaintEverything) { - std::shared_ptr nonHwcDisplay{ - impl::createDisplay(mCompositionEngine, DisplayCreationArgsBuilder().build())}; +TEST_F(DisplayFinishFrameTest, performsCompositionIfRepaintEverything) { + auto args = getDisplayCreationArgsForNonHWCVirtualDisplay(); + std::shared_ptr nonHwcDisplay = impl::createDisplay(mCompositionEngine, args); mock::RenderSurface* renderSurface = new StrictMock(); nonHwcDisplay->setRenderSurfaceForTest(std::unique_ptr(renderSurface)); @@ -779,19 +977,10 @@ TEST_F(DisplayTest, finishFramePerformsCompositionIfRepaintEverything) { struct DisplayFunctionalTest : public testing::Test { class Display : public impl::Display { public: - explicit Display(const compositionengine::DisplayCreationArgs& args) - : impl::Display(args) {} - using impl::Display::injectOutputLayerForTest; virtual void injectOutputLayerForTest(std::unique_ptr) = 0; }; - static std::shared_ptr createDisplay( - const compositionengine::CompositionEngine& compositionEngine, - compositionengine::DisplayCreationArgs&& args) { - return impl::createDisplayTemplated(compositionEngine, args); - } - DisplayFunctionalTest() { EXPECT_CALL(mCompositionEngine, getHwComposer()).WillRepeatedly(ReturnRef(mHwComposer)); @@ -803,11 +992,18 @@ struct DisplayFunctionalTest : public testing::Test { NiceMock mCompositionEngine; sp mNativeWindow = new NiceMock(); sp mDisplaySurface = new NiceMock(); - std::shared_ptr mDisplay = createDisplay(mCompositionEngine, - DisplayCreationArgsBuilder() - .setDisplayId(DEFAULT_DISPLAY_ID) - .setPowerAdvisor(&mPowerAdvisor) - .build()); + std::shared_ptr mDisplay = impl::createDisplayTemplated< + Display>(mCompositionEngine, + DisplayCreationArgsBuilder() + .setPhysical({DEFAULT_DISPLAY_ID, DisplayConnectionType::Internal}) + .setPixels({DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT}) + .setPixelFormat(static_cast(PIXEL_FORMAT_RGBA_8888)) + .setIsSecure(true) + .setLayerStackId(DEFAULT_LAYER_STACK) + .setPowerAdvisor(&mPowerAdvisor) + .build() + + ); impl::RenderSurface* mRenderSurface = new impl::RenderSurface{mCompositionEngine, *mDisplay, RenderSurfaceCreationArgs{DEFAULT_DISPLAY_WIDTH, diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index cd6bbd1716..b72214d307 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -47,19 +47,17 @@ using android::base::StringAppendF; ui::Transform::RotationFlags DisplayDevice::sPrimaryDisplayRotationFlags = ui::Transform::ROT_0; -DisplayDeviceCreationArgs::DisplayDeviceCreationArgs(const sp& flinger, - const wp& displayToken, - std::optional displayId) - : flinger(flinger), displayToken(displayToken), displayId(displayId) {} +DisplayDeviceCreationArgs::DisplayDeviceCreationArgs( + const sp& flinger, const wp& displayToken, + std::shared_ptr compositionDisplay) + : flinger(flinger), displayToken(displayToken), compositionDisplay(compositionDisplay) {} -DisplayDevice::DisplayDevice(DisplayDeviceCreationArgs&& args) +DisplayDevice::DisplayDevice(DisplayDeviceCreationArgs& args) : mFlinger(args.flinger), mDisplayToken(args.displayToken), mSequenceId(args.sequenceId), mConnectionType(args.connectionType), - mCompositionDisplay{mFlinger->getCompositionEngine().createDisplay( - compositionengine::DisplayCreationArgs{args.isVirtual(), args.displayId, - args.powerAdvisor})}, + mCompositionDisplay{args.compositionDisplay}, mPhysicalOrientation(args.physicalOrientation), mIsPrimary(args.isPrimary) { mCompositionDisplay->editState().isSecure = args.isSecure; diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h index d970b821e8..fb6c817133 100644 --- a/services/surfaceflinger/DisplayDevice.h +++ b/services/surfaceflinger/DisplayDevice.h @@ -64,7 +64,7 @@ public: constexpr static float sDefaultMinLumiance = 0.0; constexpr static float sDefaultMaxLumiance = 500.0; - explicit DisplayDevice(DisplayDeviceCreationArgs&& args); + explicit DisplayDevice(DisplayDeviceCreationArgs& args); virtual ~DisplayDevice(); std::shared_ptr getCompositionDisplay() const { @@ -211,13 +211,10 @@ struct DisplayDeviceCreationArgs { // We use a constructor to ensure some of the values are set, without // assuming a default value. DisplayDeviceCreationArgs(const sp&, const wp& displayToken, - std::optional); - - bool isVirtual() const { return !connectionType; } - + std::shared_ptr); const sp flinger; const wp displayToken; - const std::optional displayId; + const std::shared_ptr compositionDisplay; int32_t sequenceId{0}; std::optional connectionType; @@ -231,7 +228,6 @@ struct DisplayDeviceCreationArgs { std::unordered_map> hwcColorModes; int initialPowerMode{HWC_POWER_MODE_NORMAL}; bool isPrimary{false}; - Hwc2::PowerAdvisor* powerAdvisor{nullptr}; }; class DisplayRenderArea : public RenderArea { diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index ce0a8a1ac0..236a30f65d 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -2325,16 +2326,17 @@ void SurfaceFlinger::dispatchDisplayHotplugEvent(PhysicalDisplayId displayId, bo } sp SurfaceFlinger::setupNewDisplayDeviceInternal( - const wp& displayToken, const std::optional& displayId, + const wp& displayToken, + std::shared_ptr compositionDisplay, const DisplayDeviceState& state, const sp& dispSurface, const sp& producer) { - DisplayDeviceCreationArgs creationArgs(this, displayToken, displayId); + auto displayId = compositionDisplay->getDisplayId(); + DisplayDeviceCreationArgs creationArgs(this, displayToken, compositionDisplay); creationArgs.sequenceId = state.sequenceId; creationArgs.isSecure = state.isSecure; creationArgs.displaySurface = dispSurface; creationArgs.hasWideColorGamut = false; creationArgs.supportedPerFrameMetadata = 0; - creationArgs.powerAdvisor = displayId ? &mPowerAdvisor : nullptr; if (const auto& physical = state.physical) { creationArgs.connectionType = physical->type; @@ -2379,7 +2381,7 @@ sp SurfaceFlinger::setupNewDisplayDeviceInternal( // virtual displays are always considered enabled creationArgs.initialPowerMode = state.isVirtual() ? HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF; - sp display = getFactory().createDisplayDevice(std::move(creationArgs)); + sp display = getFactory().createDisplayDevice(creationArgs); if (maxFrameBufferAcquiredBuffers >= 3) { nativeWindowSurface->preallocateBuffers(); @@ -2485,53 +2487,68 @@ void SurfaceFlinger::processDisplayChangesLocked() { if (draw.indexOfKey(curr.keyAt(i)) < 0) { const DisplayDeviceState& state(curr[i]); + int width = 0; + int height = 0; + ui::PixelFormat pixelFormat = static_cast(PIXEL_FORMAT_UNKNOWN); + if (state.physical) { + const auto& activeConfig = + getCompositionEngine().getHwComposer().getActiveConfig( + state.physical->id); + width = activeConfig->getWidth(); + height = activeConfig->getHeight(); + pixelFormat = static_cast(PIXEL_FORMAT_RGBA_8888); + } else if (state.surface != nullptr) { + int status = state.surface->query(NATIVE_WINDOW_WIDTH, &width); + ALOGE_IF(status != NO_ERROR, "Unable to query width (%d)", status); + status = state.surface->query(NATIVE_WINDOW_HEIGHT, &height); + ALOGE_IF(status != NO_ERROR, "Unable to query height (%d)", status); + int intPixelFormat; + status = state.surface->query(NATIVE_WINDOW_FORMAT, &intPixelFormat); + ALOGE_IF(status != NO_ERROR, "Unable to query format (%d)", status); + pixelFormat = static_cast(intPixelFormat); + } else { + // Virtual displays without a surface are dormant: + // they have external state (layer stack, projection, + // etc.) but no internal state (i.e. a DisplayDevice). + continue; + } + + compositionengine::DisplayCreationArgsBuilder builder; + if (const auto& physical = state.physical) { + builder.setPhysical({physical->id, physical->type}); + } + builder.setPixels(ui::Size(width, height)); + builder.setPixelFormat(pixelFormat); + builder.setIsSecure(state.isSecure); + builder.setLayerStackId(state.layerStack); + builder.setPowerAdvisor(&mPowerAdvisor); + builder.setUseHwcVirtualDisplays(mUseHwcVirtualDisplays || + getHwComposer().isUsingVrComposer()); + builder.setName(state.displayName); + auto compositionDisplay = getCompositionEngine().createDisplay(builder.build()); + sp dispSurface; sp producer; sp bqProducer; sp bqConsumer; getFactory().createBufferQueue(&bqProducer, &bqConsumer, false); - std::optional displayId; - if (state.isVirtual()) { - // Virtual displays without a surface are dormant: - // they have external state (layer stack, projection, - // etc.) but no internal state (i.e. a DisplayDevice). - if (state.surface != nullptr) { - // Allow VR composer to use virtual displays. - if (mUseHwcVirtualDisplays || getHwComposer().isUsingVrComposer()) { - int width = 0; - int status = state.surface->query(NATIVE_WINDOW_WIDTH, &width); - ALOGE_IF(status != NO_ERROR, "Unable to query width (%d)", status); - int height = 0; - status = state.surface->query(NATIVE_WINDOW_HEIGHT, &height); - ALOGE_IF(status != NO_ERROR, "Unable to query height (%d)", status); - int intFormat = 0; - status = state.surface->query(NATIVE_WINDOW_FORMAT, &intFormat); - ALOGE_IF(status != NO_ERROR, "Unable to query format (%d)", status); - auto format = static_cast(intFormat); - - displayId = - getHwComposer().allocateVirtualDisplay(width, height, &format); - } - - // TODO: Plumb requested format back up to consumer + std::optional displayId = compositionDisplay->getId(); - sp vds = - new VirtualDisplaySurface(getHwComposer(), displayId, state.surface, - bqProducer, bqConsumer, - state.displayName); + if (state.isVirtual()) { + sp vds = + new VirtualDisplaySurface(getHwComposer(), displayId, state.surface, + bqProducer, bqConsumer, state.displayName); - dispSurface = vds; - producer = vds; - } + dispSurface = vds; + producer = vds; } else { ALOGE_IF(state.surface != nullptr, "adding a supported display, but rendering " "surface is provided (%p), ignoring it", state.surface.get()); - LOG_FATAL_IF(!state.physical); - displayId = state.physical->id; + LOG_ALWAYS_FATAL_IF(!displayId); dispSurface = new FramebufferSurface(getHwComposer(), *displayId, bqConsumer); producer = bqProducer; } @@ -2539,7 +2556,8 @@ void SurfaceFlinger::processDisplayChangesLocked() { const wp& displayToken = curr.keyAt(i); if (dispSurface != nullptr) { mDisplays.emplace(displayToken, - setupNewDisplayDeviceInternal(displayToken, displayId, state, + setupNewDisplayDeviceInternal(displayToken, + compositionDisplay, state, dispSurface, producer)); if (!state.isVirtual()) { LOG_ALWAYS_FATAL_IF(!displayId); diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index c79621b1fa..9b16a28f7c 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -810,7 +810,8 @@ private: * Display management */ sp setupNewDisplayDeviceInternal( - const wp& displayToken, const std::optional& displayId, + const wp& displayToken, + std::shared_ptr compositionDisplay, const DisplayDeviceState& state, const sp& dispSurface, const sp& producer); diff --git a/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp b/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp index d49133d1fc..033e54232d 100644 --- a/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp +++ b/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp @@ -90,8 +90,8 @@ sp DefaultFactory::createStartPropertySetThread( return new StartPropertySetThread(timestampPropertyValue); } -sp DefaultFactory::createDisplayDevice(DisplayDeviceCreationArgs&& creationArgs) { - return new DisplayDevice(std::move(creationArgs)); +sp DefaultFactory::createDisplayDevice(DisplayDeviceCreationArgs& creationArgs) { + return new DisplayDevice(creationArgs); } sp DefaultFactory::createGraphicBuffer(uint32_t width, uint32_t height, diff --git a/services/surfaceflinger/SurfaceFlingerDefaultFactory.h b/services/surfaceflinger/SurfaceFlingerDefaultFactory.h index 89194c7ad1..bd40cfbcf2 100644 --- a/services/surfaceflinger/SurfaceFlingerDefaultFactory.h +++ b/services/surfaceflinger/SurfaceFlingerDefaultFactory.h @@ -37,7 +37,7 @@ public: ISchedulerCallback&) override; std::unique_ptr createSurfaceInterceptor(SurfaceFlinger*) override; sp createStartPropertySetThread(bool timestampPropertyValue) override; - sp createDisplayDevice(DisplayDeviceCreationArgs&&) override; + sp createDisplayDevice(DisplayDeviceCreationArgs&) override; sp createGraphicBuffer(uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount, uint64_t usage, std::string requestorName) override; diff --git a/services/surfaceflinger/SurfaceFlingerFactory.h b/services/surfaceflinger/SurfaceFlingerFactory.h index 209bd0caba..6f4fcc6900 100644 --- a/services/surfaceflinger/SurfaceFlingerFactory.h +++ b/services/surfaceflinger/SurfaceFlingerFactory.h @@ -83,7 +83,7 @@ public: virtual sp createStartPropertySetThread( bool timestampPropertyValue) = 0; - virtual sp createDisplayDevice(DisplayDeviceCreationArgs&&) = 0; + virtual sp createDisplayDevice(DisplayDeviceCreationArgs&) = 0; virtual sp createGraphicBuffer(uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount, uint64_t usage, std::string requestorName) = 0; diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp index 06ef8e78c2..680b0a038e 100644 --- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp +++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp @@ -39,6 +39,7 @@ #include "Layer.h" #include "TestableSurfaceFlinger.h" #include "mock/DisplayHardware/MockComposer.h" +#include "mock/DisplayHardware/MockPowerAdvisor.h" #include "mock/MockDispSync.h" #include "mock/MockEventControlThread.h" #include "mock/MockEventThread.h" @@ -186,6 +187,7 @@ public: renderengine::mock::RenderEngine* mRenderEngine = new renderengine::mock::RenderEngine(); mock::TimeStats* mTimeStats = new mock::TimeStats(); mock::MessageQueue* mMessageQueue = new mock::MessageQueue(); + Hwc2::mock::PowerAdvisor mPowerAdvisor; sp mClientTargetAcquireFence = Fence::NO_FENCE; @@ -284,8 +286,27 @@ struct BaseDisplayVariant { EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT)).Times(1); EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT)).Times(1); EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64)).Times(1); + + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + + auto ceDisplayArgs = + compositionengine::DisplayCreationArgsBuilder() + .setPhysical({DEFAULT_DISPLAY_ID, DisplayConnectionType::Internal}) + .setPixels({DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT}) + .setIsSecure(Derived::IS_SECURE) + .setLayerStackId(DEFAULT_LAYER_STACK) + .setPowerAdvisor(&test->mPowerAdvisor) + .setName(std::string("Injected display for ") + + test_info->test_case_name() + "." + test_info->name()) + .build(); + + auto compositionDisplay = + compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(), + ceDisplayArgs); + test->mDisplay = - FakeDisplayDeviceInjector(test->mFlinger, DEFAULT_DISPLAY_ID, + FakeDisplayDeviceInjector(test->mFlinger, compositionDisplay, DisplayConnectionType::Internal, true /* isPrimary */) .setDisplaySurface(test->mDisplaySurface) .setNativeWindow(test->mNativeWindow) @@ -325,18 +346,17 @@ struct BaseDisplayVariant { template static void setupCommonScreensCaptureCallExpectations(CompositionTest* test) { EXPECT_CALL(*test->mRenderEngine, drawLayers) - .WillRepeatedly( - [](const renderengine::DisplaySettings& displaySettings, - const std::vector&, - ANativeWindowBuffer*, const bool, base::unique_fd&&, - base::unique_fd*) -> status_t { - EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance); - EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), - displaySettings.physicalDisplay); - EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), - displaySettings.clip); - return NO_ERROR; - }); + .WillRepeatedly([](const renderengine::DisplaySettings& displaySettings, + const std::vector&, + ANativeWindowBuffer*, const bool, base::unique_fd&&, + base::unique_fd*) -> status_t { + EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance); + EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), + displaySettings.physicalDisplay); + EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), + displaySettings.clip); + return NO_ERROR; + }); } static void setupNonEmptyFrameCompositionCallExpectations(CompositionTest* test) { @@ -375,19 +395,18 @@ struct BaseDisplayVariant { .WillOnce(DoAll(SetArgPointee<0>(test->mNativeWindowBuffer), SetArgPointee<1>(-1), Return(0))); EXPECT_CALL(*test->mRenderEngine, drawLayers) - .WillRepeatedly( - [](const renderengine::DisplaySettings& displaySettings, - const std::vector&, - ANativeWindowBuffer*, const bool, base::unique_fd&&, - base::unique_fd*) -> status_t { - EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance); - EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), - displaySettings.physicalDisplay); - EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), - displaySettings.clip); - EXPECT_EQ(ui::Dataspace::UNKNOWN, displaySettings.outputDataspace); - return NO_ERROR; - }); + .WillRepeatedly([](const renderengine::DisplaySettings& displaySettings, + const std::vector&, + ANativeWindowBuffer*, const bool, base::unique_fd&&, + base::unique_fd*) -> status_t { + EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance); + EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), + displaySettings.physicalDisplay); + EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), + displaySettings.clip); + EXPECT_EQ(ui::Dataspace::UNKNOWN, displaySettings.outputDataspace); + return NO_ERROR; + }); } template diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp index 4da064766c..6d00cccb48 100644 --- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp +++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp @@ -25,8 +25,12 @@ #include #include +#include #include +#include +#include #include +#include #include #include #include @@ -39,6 +43,7 @@ #include "TestableScheduler.h" #include "TestableSurfaceFlinger.h" #include "mock/DisplayHardware/MockComposer.h" +#include "mock/DisplayHardware/MockPowerAdvisor.h" #include "mock/MockDispSync.h" #include "mock/MockEventControlThread.h" #include "mock/MockEventThread.h" @@ -51,11 +56,14 @@ namespace android { namespace { using testing::_; +using testing::AnyNumber; using testing::DoAll; using testing::Mock; using testing::ResultOf; using testing::Return; +using testing::ReturnRefOfCopy; using testing::SetArgPointee; +using testing::StrictMock; using android::Hwc2::ColorMode; using android::Hwc2::Error; @@ -107,6 +115,7 @@ public: void injectMockComposer(int virtualDisplayCount); void injectFakeBufferQueueFactory(); void injectFakeNativeWindowSurfaceFactory(); + sp injectDefaultInternalDisplay(std::function); // -------------------------------------------------------------------- // Postcondition helpers @@ -126,6 +135,7 @@ public: TestableSurfaceFlinger mFlinger; sp mNativeWindow = new mock::NativeWindow(); sp mBuffer = new GraphicBuffer(); + Hwc2::mock::PowerAdvisor mPowerAdvisor; // These mocks are created by the test, but are destroyed by SurfaceFlinger // by virtue of being stored into a std::unique_ptr. However we still need @@ -231,6 +241,49 @@ void DisplayTransactionTest::injectFakeNativeWindowSurfaceFactory() { }); } +sp DisplayTransactionTest::injectDefaultInternalDisplay( + std::function injectExtra) { + constexpr DisplayId DEFAULT_DISPLAY_ID = DisplayId{777}; + constexpr int DEFAULT_DISPLAY_WIDTH = 1080; + constexpr int DEFAULT_DISPLAY_HEIGHT = 1920; + + // The DisplayDevice is required to have a framebuffer (behind the + // ANativeWindow interface) which uses the actual hardware display + // size. + EXPECT_CALL(*mNativeWindow, query(NATIVE_WINDOW_WIDTH, _)) + .WillRepeatedly(DoAll(SetArgPointee<1>(DEFAULT_DISPLAY_WIDTH), Return(0))); + EXPECT_CALL(*mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _)) + .WillRepeatedly(DoAll(SetArgPointee<1>(DEFAULT_DISPLAY_HEIGHT), Return(0))); + EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT)); + EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT)); + EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64)); + EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT)).Times(AnyNumber()); + + auto compositionDisplay = compositionengine::impl:: + createDisplay(mFlinger.getCompositionEngine(), + compositionengine::DisplayCreationArgsBuilder() + .setPhysical( + {DEFAULT_DISPLAY_ID, DisplayConnectionType::Internal}) + .setPixels({DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT}) + .setPowerAdvisor(&mPowerAdvisor) + .build()); + + auto injector = + FakeDisplayDeviceInjector(mFlinger, compositionDisplay, DisplayConnectionType::Internal, + true /* isPrimary */); + + injector.setNativeWindow(mNativeWindow); + if (injectExtra) { + injectExtra(injector); + } + + auto displayDevice = injector.inject(); + + Mock::VerifyAndClear(mNativeWindow.get()); + + return displayDevice; +} + bool DisplayTransactionTest::hasPhysicalHwcDisplay(hwc2_display_t hwcDisplayId) { return mFlinger.mutableHwcPhysicalDisplayIdMap().count(hwcDisplayId) == 1; } @@ -353,9 +406,21 @@ struct DisplayVariant { static constexpr Primary PRIMARY = primary; static auto makeFakeExistingDisplayInjector(DisplayTransactionTest* test) { + auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder(); + if (auto displayId = DISPLAY_ID::get()) { + ceDisplayArgs.setPhysical({*displayId, DisplayConnectionType::Internal}); + } else { + ceDisplayArgs.setUseHwcVirtualDisplays(false); + } + ceDisplayArgs.setPixels({WIDTH, HEIGHT}).setPowerAdvisor(&test->mPowerAdvisor).build(); + + auto compositionDisplay = + compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(), + ceDisplayArgs.build()); + auto injector = - FakeDisplayDeviceInjector(test->mFlinger, DISPLAY_ID::get(), CONNECTION_TYPE::value, - static_cast(PRIMARY)); + FakeDisplayDeviceInjector(test->mFlinger, compositionDisplay, + CONNECTION_TYPE::value, static_cast(PRIMARY)); injector.setSecure(static_cast(SECURE)); injector.setNativeWindow(test->mNativeWindow); @@ -458,6 +523,25 @@ struct HwcDisplayVariant { injectHwcDisplayWithNoDefaultCapabilities(test); } + static std::shared_ptr injectCompositionDisplay( + DisplayTransactionTest* test) { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + + auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder() + .setPhysical({*DisplayVariant::DISPLAY_ID::get(), + PhysicalDisplay::CONNECTION_TYPE}) + .setPixels({DisplayVariant::WIDTH, DisplayVariant::HEIGHT}) + .setIsSecure(static_cast(DisplayVariant::SECURE)) + .setPowerAdvisor(&test->mPowerAdvisor) + .setName(std::string("Injected display for ") + + test_info->test_case_name() + "." + test_info->name()) + .build(); + + return compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(), + ceDisplayArgs); + } + static void setupHwcHotplugCallExpectations(DisplayTransactionTest* test) { constexpr auto CONNECTION_TYPE = PhysicalDisplay::CONNECTION_TYPE == DisplayConnectionType::Internal @@ -577,6 +661,23 @@ struct NonHwcVirtualDisplayVariant static void injectHwcDisplay(DisplayTransactionTest*) {} + static std::shared_ptr injectCompositionDisplay( + DisplayTransactionTest* test) { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + + auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder() + .setPixels({Base::WIDTH, Base::HEIGHT}) + .setIsSecure(static_cast(Base::SECURE)) + .setPowerAdvisor(&test->mPowerAdvisor) + .setName(std::string("Injected display for ") + + test_info->test_case_name() + "." + test_info->name()) + .build(); + + return compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(), + ceDisplayArgs); + } + static void setupHwcGetActiveConfigCallExpectations(DisplayTransactionTest* test) { EXPECT_CALL(*test->mComposer, getActiveConfig(_, _)).Times(0); } @@ -602,6 +703,33 @@ struct HwcVirtualDisplayVariant secure, Primary::FALSE, GRALLOC_USAGE_HW_COMPOSER>; using Self = HwcVirtualDisplayVariant; + static std::shared_ptr injectCompositionDisplay( + DisplayTransactionTest* test) { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + + auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder() + .setUseHwcVirtualDisplays(false) + .setPixels({Base::WIDTH, Base::HEIGHT}) + .setIsSecure(static_cast(Base::SECURE)) + .setPowerAdvisor(&test->mPowerAdvisor) + .setName(std::string("Injected display for ") + + test_info->test_case_name() + "." + test_info->name()) + .build(); + + auto compositionDisplay = + compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(), + ceDisplayArgs); + compositionDisplay->setDisplayIdForTesting(Base::DISPLAY_ID::get()); + + // Insert display data so that the HWC thinks it created the virtual display. + if (const auto displayId = Base::DISPLAY_ID::get()) { + test->mFlinger.mutableHwcDisplayData().try_emplace(*displayId); + } + + return compositionDisplay; + } + static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) { Base::setupNativeWindowSurfaceCreationCallExpectations(test); EXPECT_CALL(*test->mNativeWindow, setSwapInterval(0)).Times(1); @@ -1199,14 +1327,6 @@ TEST_F(DisplayTransactionTest, resetDisplayStateClearsState) { */ class GetBestColorModeTest : public DisplayTransactionTest { public: - static constexpr DisplayId DEFAULT_DISPLAY_ID = DisplayId{777}; - - GetBestColorModeTest() - : DisplayTransactionTest(), - mInjector(FakeDisplayDeviceInjector(mFlinger, DEFAULT_DISPLAY_ID, - DisplayConnectionType::Internal, - true /* isPrimary */)) {} - void setHasWideColorGamut(bool hasWideColorGamut) { mHasWideColorGamut = hasWideColorGamut; } void addHwcColorModesMapping(ui::ColorMode colorMode, @@ -1219,21 +1339,12 @@ public: void setInputRenderIntent(ui::RenderIntent renderIntent) { mInputRenderIntent = renderIntent; } void getBestColorMode() { - mInjector.setHwcColorModes(mHwcColorModes); - mInjector.setHasWideColorGamut(mHasWideColorGamut); - mInjector.setNativeWindow(mNativeWindow); - - // Creating a DisplayDevice requires getting default dimensions from the - // native window. - EXPECT_CALL(*mNativeWindow, query(NATIVE_WINDOW_WIDTH, _)) - .WillRepeatedly(DoAll(SetArgPointee<1>(1080 /* arbitrary */), Return(0))); - EXPECT_CALL(*mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _)) - .WillRepeatedly(DoAll(SetArgPointee<1>(1920 /* arbitrary */), Return(0))); - EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT)).Times(1); - EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT)).Times(1); - EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64)).Times(1); - EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT)).Times(1); - auto displayDevice = mInjector.inject(); + auto displayDevice = + injectDefaultInternalDisplay([this](FakeDisplayDeviceInjector& injector) { + injector.setHwcColorModes(mHwcColorModes); + injector.setHasWideColorGamut(mHasWideColorGamut); + injector.setNativeWindow(mNativeWindow); + }); displayDevice->getCompositionDisplay() ->getDisplayColorProfile() @@ -1250,7 +1361,6 @@ private: ui::RenderIntent mInputRenderIntent; bool mHasWideColorGamut = false; std::unordered_map> mHwcColorModes; - FakeDisplayDeviceInjector mInjector; }; TEST_F(GetBestColorModeTest, DataspaceDisplayP3_ColorModeSRGB) { @@ -1305,7 +1415,6 @@ TEST_F(GetBestColorModeTest, DataspaceDisplayP3_ColorModeDISPLAY_BT2020) { class DisplayDeviceSetProjectionTest : public DisplayTransactionTest { public: - static constexpr DisplayId DEFAULT_DISPLAY_ID = DisplayId{777}; static constexpr int32_t DEFAULT_DISPLAY_WIDTH = 1080; // arbitrary static constexpr int32_t DEFAULT_DISPLAY_HEIGHT = 1920; // arbitrary @@ -1323,23 +1432,9 @@ public: mDisplayDevice(createDisplayDevice()) {} sp createDisplayDevice() { - // The DisplayDevice is required to have a framebuffer (behind the - // ANativeWindow interface) which uses the actual hardware display - // size. - EXPECT_CALL(*mNativeWindow, query(NATIVE_WINDOW_WIDTH, _)) - .WillRepeatedly(DoAll(SetArgPointee<1>(mHardwareDisplaySize.width), Return(0))); - EXPECT_CALL(*mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _)) - .WillRepeatedly(DoAll(SetArgPointee<1>(mHardwareDisplaySize.height), Return(0))); - EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT)); - EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT)); - EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64)); - EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT)); - - return FakeDisplayDeviceInjector(mFlinger, DEFAULT_DISPLAY_ID, - DisplayConnectionType::Internal, true /* isPrimary */) - .setNativeWindow(mNativeWindow) - .setPhysicalOrientation(mPhysicalOrientation) - .inject(); + return injectDefaultInternalDisplay([this](FakeDisplayDeviceInjector& injector) { + injector.setPhysicalOrientation(mPhysicalOrientation); + }); } ui::Size SwapWH(const ui::Size size) const { return ui::Size(size.height, size.width); } @@ -1652,6 +1747,9 @@ void SetupNewDisplayDeviceInternalTest::setupNewDisplayDeviceInternalTest() { // surfaces. injectFakeNativeWindowSurfaceFactory(); + // A compositionengine::Display has already been created + auto compositionDisplay = Case::Display::injectCompositionDisplay(this); + // -------------------------------------------------------------------- // Call Expectations @@ -1674,9 +1772,8 @@ void SetupNewDisplayDeviceInternalTest::setupNewDisplayDeviceInternalTest() { state.isSecure = static_cast(Case::Display::SECURE); - auto device = - mFlinger.setupNewDisplayDeviceInternal(displayToken, Case::Display::DISPLAY_ID::get(), - state, displaySurface, producer); + auto device = mFlinger.setupNewDisplayDeviceInternal(displayToken, compositionDisplay, state, + displaySurface, producer); // -------------------------------------------------------------------- // Postconditions @@ -1715,14 +1812,7 @@ TEST_F(SetupNewDisplayDeviceInternalTest, createNonHwcVirtualDisplay) { } TEST_F(SetupNewDisplayDeviceInternalTest, createHwcVirtualDisplay) { - using Case = HwcVirtualDisplayCase; - - // Insert display data so that the HWC thinks it created the virtual display. - const auto displayId = Case::Display::DISPLAY_ID::get(); - ASSERT_TRUE(displayId); - mFlinger.mutableHwcDisplayData().try_emplace(*displayId); - - setupNewDisplayDeviceInternalTest(); + setupNewDisplayDeviceInternalTest(); } TEST_F(SetupNewDisplayDeviceInternalTest, createWideColorP3Display) { diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h index 3a4f349d45..84e55ae07c 100644 --- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h +++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -97,8 +98,8 @@ public: return new StartPropertySetThread(timestampPropertyValue); } - sp createDisplayDevice(DisplayDeviceCreationArgs&& creationArgs) override { - return new DisplayDevice(std::move(creationArgs)); + sp createDisplayDevice(DisplayDeviceCreationArgs& creationArgs) override { + return new DisplayDevice(creationArgs); } sp createGraphicBuffer(uint32_t width, uint32_t height, PixelFormat format, @@ -277,13 +278,14 @@ public: auto resetDisplayState() { return mFlinger->resetDisplayState(); } - auto setupNewDisplayDeviceInternal(const wp& displayToken, - const std::optional& displayId, - const DisplayDeviceState& state, - const sp& dispSurface, - const sp& producer) { - return mFlinger->setupNewDisplayDeviceInternal(displayToken, displayId, state, dispSurface, - producer); + auto setupNewDisplayDeviceInternal( + const wp& displayToken, + std::shared_ptr compositionDisplay, + const DisplayDeviceState& state, + const sp& dispSurface, + const sp& producer) { + return mFlinger->setupNewDisplayDeviceInternal(displayToken, compositionDisplay, state, + dispSurface, producer); } auto handleTransactionLocked(uint32_t transactionFlags) { @@ -359,6 +361,7 @@ public: auto& getHwComposer() const { return static_cast(mFlinger->getHwComposer()); } + auto& getCompositionEngine() const { return mFlinger->getCompositionEngine(); } const auto& getCompositorTiming() const { return mFlinger->getBE().mCompositorTiming; } @@ -543,10 +546,11 @@ public: class FakeDisplayDeviceInjector { public: FakeDisplayDeviceInjector(TestableSurfaceFlinger& flinger, - std::optional displayId, + std::shared_ptr compositionDisplay, std::optional connectionType, bool isPrimary) - : mFlinger(flinger), mCreationArgs(flinger.mFlinger.get(), mDisplayToken, displayId) { + : mFlinger(flinger), + mCreationArgs(flinger.mFlinger.get(), mDisplayToken, compositionDisplay) { mCreationArgs.connectionType = connectionType; mCreationArgs.isPrimary = isPrimary; } @@ -609,16 +613,17 @@ public: } sp inject() { + const auto displayId = mCreationArgs.compositionDisplay->getDisplayId(); + DisplayDeviceState state; if (const auto type = mCreationArgs.connectionType) { - const auto id = mCreationArgs.displayId; - LOG_ALWAYS_FATAL_IF(!id); - state.physical = {*id, *type}; + LOG_ALWAYS_FATAL_IF(!displayId); + state.physical = {*displayId, *type}; } state.isSecure = mCreationArgs.isSecure; - sp device = new DisplayDevice(std::move(mCreationArgs)); + sp device = new DisplayDevice(mCreationArgs); mFlinger.mutableDisplays().emplace(mDisplayToken, device); mFlinger.mutableCurrentState().displays.add(mDisplayToken, state); mFlinger.mutableDrawingState().displays.add(mDisplayToken, state); -- cgit v1.2.3-59-g8ed1b