Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cbc929db authored by Leon Scroggins III's avatar Leon Scroggins III
Browse files

CompositionEngine: only offload when displays are enabled

When using multithreaded_present, only offload any displays if there are
more than one enabled display. If e.g. there are two displays, but one
is not enabled, there is not the same benefit of offloading it.

Bug: 241285491
Bug: 259132483
Test: libcompositionengine_test
Change-Id: Iad4a6fc47127b5ab945108f8c6ede1216755adbd
parent 4cd9cb2c
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -101,6 +101,9 @@ void offloadOutputs(Outputs& outputs) {
            // Not HWC-enabled, so it is always client-composited. No need to offload.
            continue;
        }
        if (!output->getState().isEnabled) {
            continue;
        }

        // Only run present in multiple threads if all HWC-enabled displays
        // being refreshed support it.
+50 −0
Original line number Diff line number Diff line
@@ -288,6 +288,8 @@ struct CompositionEngineOffloadTest : public testing::Test {
    static constexpr GpuVirtualDisplayId kGpuVirtualDisplayId{789u};
    static constexpr HalVirtualDisplayId kHalVirtualDisplayId{456u};

    std::array<impl::OutputCompositionState, 4> mOutputStates;

    void SetUp() override {
        EXPECT_CALL(*mDisplay1, getDisplayId)
                .WillRepeatedly(Return(std::make_optional<DisplayId>(kDisplayId1)));
@@ -297,6 +299,16 @@ struct CompositionEngineOffloadTest : public testing::Test {
                .WillRepeatedly(Return(std::make_optional<DisplayId>(kGpuVirtualDisplayId)));
        EXPECT_CALL(*mHalVirtualDisplay, getDisplayId)
                .WillRepeatedly(Return(std::make_optional<DisplayId>(kHalVirtualDisplayId)));

        // Most tests will depend on the outputs being enabled.
        for (auto& state : mOutputStates) {
            state.isEnabled = true;
        }

        EXPECT_CALL(*mDisplay1, getState).WillRepeatedly(ReturnRef(mOutputStates[0]));
        EXPECT_CALL(*mDisplay2, getState).WillRepeatedly(ReturnRef(mOutputStates[1]));
        EXPECT_CALL(*mVirtualDisplay, getState).WillRepeatedly(ReturnRef(mOutputStates[2]));
        EXPECT_CALL(*mHalVirtualDisplay, getState).WillRepeatedly(ReturnRef(mOutputStates[3]));
    }

    void setOutputs(std::initializer_list<std::shared_ptr<mock::Output>> outputs) {
@@ -433,5 +445,43 @@ TEST_F(CompositionEngineOffloadTest, ordering) {
    mEngine.present(mRefreshArgs);
}

TEST_F(CompositionEngineOffloadTest, dependsOnEnabled) {
    // Disable mDisplay2.
    mOutputStates[1].isEnabled = false;
    EXPECT_CALL(*mDisplay1, supportsOffloadPresent).WillOnce(Return(true));

    // This is not actually called, because it is not enabled, but this distinguishes
    // from the case where it did not return true.
    EXPECT_CALL(*mDisplay2, supportsOffloadPresent).WillRepeatedly(Return(true));

    EXPECT_CALL(*mDisplay1, offloadPresentNextFrame).Times(0);
    EXPECT_CALL(*mDisplay2, offloadPresentNextFrame).Times(0);

    SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
    setOutputs({mDisplay1, mDisplay2});

    mEngine.present(mRefreshArgs);
}

TEST_F(CompositionEngineOffloadTest, disabledDisplaysDoNotPreventOthersFromOffloading) {
    // Disable mDisplay2.
    mOutputStates[1].isEnabled = false;
    EXPECT_CALL(*mDisplay1, supportsOffloadPresent).WillOnce(Return(true));

    // This is not actually called, because it is not enabled, but this distinguishes
    // from the case where it did not return true.
    EXPECT_CALL(*mDisplay2, supportsOffloadPresent).WillRepeatedly(Return(true));
    EXPECT_CALL(*mHalVirtualDisplay, supportsOffloadPresent).WillOnce(Return(true));

    EXPECT_CALL(*mDisplay1, offloadPresentNextFrame).Times(1);
    EXPECT_CALL(*mDisplay2, offloadPresentNextFrame).Times(0);
    EXPECT_CALL(*mHalVirtualDisplay, offloadPresentNextFrame).Times(0);

    SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
    setOutputs({mDisplay1, mDisplay2, mHalVirtualDisplay});

    mEngine.present(mRefreshArgs);
}

} // namespace
} // namespace android::compositionengine