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

Commit 585d10e6 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "SF: Flatten display containers" into tm-dev

parents d0e15737 eb627318
Loading
Loading
Loading
Loading
+12 −12
Original line number Diff line number Diff line
@@ -2730,12 +2730,12 @@ void SurfaceFlinger::processDisplayHotplugEventsLocked() {
        }

        const auto displayId = info->id;
        const auto it = mPhysicalDisplayTokens.find(displayId);
        const auto token = mPhysicalDisplayTokens.get(displayId);

        if (event.connection == hal::Connection::CONNECTED) {
            auto [supportedModes, activeMode] = loadDisplayModes(displayId);

            if (it == mPhysicalDisplayTokens.end()) {
            if (!token) {
                ALOGV("Creating display %s", to_string(displayId).c_str());

                DisplayDeviceState state;
@@ -2750,14 +2750,13 @@ void SurfaceFlinger::processDisplayHotplugEventsLocked() {

                sp<IBinder> token = new BBinder();
                mCurrentState.displays.add(token, state);
                mPhysicalDisplayTokens.emplace(displayId, std::move(token));
                mPhysicalDisplayTokens.try_emplace(displayId, std::move(token));
                mInterceptor->saveDisplayCreation(state);
            } else {
                ALOGV("Recreating display %s", to_string(displayId).c_str());

                const auto token = it->second;
                auto& state = mCurrentState.displays.editValueFor(token);
                state.sequenceId = DisplayDeviceState{}.sequenceId; // Generate new sequenceId
                auto& state = mCurrentState.displays.editValueFor(token->get());
                state.sequenceId = DisplayDeviceState{}.sequenceId; // Generate new sequenceId.
                state.physical->supportedModes = std::move(supportedModes);
                state.physical->activeMode = std::move(activeMode);
                if (getHwComposer().updatesDeviceProductInfoOnHotplugReconnect()) {
@@ -2767,13 +2766,13 @@ void SurfaceFlinger::processDisplayHotplugEventsLocked() {
        } else {
            ALOGV("Removing display %s", to_string(displayId).c_str());

            const ssize_t index = mCurrentState.displays.indexOfKey(it->second);
            if (index >= 0) {
            if (const ssize_t index = mCurrentState.displays.indexOfKey(token->get()); index >= 0) {
                const DisplayDeviceState& state = mCurrentState.displays.valueAt(index);
                mInterceptor->saveDisplayDeletion(state.sequenceId);
                mCurrentState.displays.removeItemsAt(index);
            }
            mPhysicalDisplayTokens.erase(it);

            mPhysicalDisplayTokens.erase(displayId);
        }

        processDisplayChangesLocked();
@@ -2954,15 +2953,16 @@ void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken,
    }

    LOG_FATAL_IF(!displaySurface);
    const auto display = setupNewDisplayDeviceInternal(displayToken, std::move(compositionDisplay),
                                                       state, displaySurface, producer);
    mDisplays.emplace(displayToken, display);
    auto display = setupNewDisplayDeviceInternal(displayToken, std::move(compositionDisplay), state,
                                                 displaySurface, producer);
    if (display->isPrimary()) {
        initScheduler(display);
    }
    if (!state.isVirtual()) {
        dispatchDisplayHotplugEvent(display->getPhysicalId(), true);
    }

    mDisplays.try_emplace(displayToken, std::move(display));
}

void SurfaceFlinger::processDisplayRemoved(const wp<IBinder>& displayToken) {
+15 −12
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include <android/gui/DisplayState.h>
#include <cutils/atomic.h>
#include <cutils/compiler.h>
#include <ftl/small_map.h>
#include <gui/BufferQueue.h>
#include <gui/FrameTimestamps.h>
#include <gui/ISurfaceComposer.h>
@@ -905,8 +906,8 @@ private:
    }

    sp<DisplayDevice> getDisplayDeviceLocked(const wp<IBinder>& displayToken) REQUIRES(mStateLock) {
        const auto it = mDisplays.find(displayToken);
        return it == mDisplays.end() ? nullptr : it->second;
        const sp<DisplayDevice> nullDisplay;
        return mDisplays.get(displayToken).value_or(std::cref(nullDisplay));
    }

    sp<const DisplayDevice> getDisplayDeviceLocked(PhysicalDisplayId id) const
@@ -1051,8 +1052,8 @@ private:
     */
    sp<IBinder> getPhysicalDisplayTokenLocked(PhysicalDisplayId displayId) const
            REQUIRES(mStateLock) {
        const auto it = mPhysicalDisplayTokens.find(displayId);
        return it != mPhysicalDisplayTokens.end() ? it->second : nullptr;
        const sp<IBinder> nullToken;
        return mPhysicalDisplayTokens.get(displayId).value_or(std::cref(nullToken));
    }

    std::optional<PhysicalDisplayId> getPhysicalDisplayIdLocked(
@@ -1247,10 +1248,14 @@ private:

    std::vector<HotplugEvent> mPendingHotplugEvents GUARDED_BY(mStateLock);

    // this may only be written from the main thread with mStateLock held
    // it may be read from other threads with mStateLock held
    std::map<wp<IBinder>, sp<DisplayDevice>> mDisplays GUARDED_BY(mStateLock);
    std::unordered_map<PhysicalDisplayId, sp<IBinder>> mPhysicalDisplayTokens
    // Displays are composited in `mDisplays` order. Internal displays are inserted at boot and
    // never removed, so take precedence over external and virtual displays.
    //
    // The static capacities were chosen to exceed a typical number of physical/virtual displays.
    //
    // May be read from any thread, but must only be written from the main thread.
    ftl::SmallMap<wp<IBinder>, const sp<DisplayDevice>, 5> mDisplays GUARDED_BY(mStateLock);
    ftl::SmallMap<PhysicalDisplayId, const sp<IBinder>, 3> mPhysicalDisplayTokens
            GUARDED_BY(mStateLock);

    struct {
@@ -1423,10 +1428,8 @@ private:
    std::atomic<ui::Transform::RotationFlags> mActiveDisplayTransformHint;

    bool isRefreshRateOverlayEnabled() const REQUIRES(mStateLock) {
        return std::any_of(mDisplays.begin(), mDisplays.end(),
                           [](std::pair<wp<IBinder>, sp<DisplayDevice>> display) {
                               return display.second->isRefreshRateOverlayEnabled();
                           });
        return hasDisplay(
                [](const auto& display) { return display.isRefreshRateOverlayEnabled(); });
    }

    wp<IBinder> mActiveDisplayToken GUARDED_BY(mStateLock);
+19 −16
Original line number Diff line number Diff line
@@ -165,36 +165,39 @@ sp<DisplayDevice> DisplayTransactionTest::injectDefaultInternalDisplay(
    return displayDevice;
}

bool DisplayTransactionTest::hasPhysicalHwcDisplay(HWDisplayId hwcDisplayId) {
    return mFlinger.mutableHwcPhysicalDisplayIdMap().count(hwcDisplayId) == 1;
bool DisplayTransactionTest::hasPhysicalHwcDisplay(HWDisplayId hwcDisplayId) const {
    return mFlinger.hwcPhysicalDisplayIdMap().count(hwcDisplayId) == 1;
}

bool DisplayTransactionTest::hasTransactionFlagSet(int flag) {
    return mFlinger.mutableTransactionFlags() & flag;
bool DisplayTransactionTest::hasTransactionFlagSet(int32_t flag) const {
    return mFlinger.transactionFlags() & flag;
}

bool DisplayTransactionTest::hasDisplayDevice(sp<IBinder> displayToken) {
    return mFlinger.mutableDisplays().count(displayToken) == 1;
bool DisplayTransactionTest::hasDisplayDevice(const sp<IBinder>& displayToken) const {
    return mFlinger.displays().contains(displayToken);
}

sp<DisplayDevice> DisplayTransactionTest::getDisplayDevice(sp<IBinder> displayToken) {
    return mFlinger.mutableDisplays()[displayToken];
const DisplayDevice& DisplayTransactionTest::getDisplayDevice(
        const sp<IBinder>& displayToken) const {
    return *mFlinger.displays().get(displayToken)->get();
}

bool DisplayTransactionTest::hasCurrentDisplayState(sp<IBinder> displayToken) {
    return mFlinger.mutableCurrentState().displays.indexOfKey(displayToken) >= 0;
bool DisplayTransactionTest::hasCurrentDisplayState(const sp<IBinder>& displayToken) const {
    return mFlinger.currentState().displays.indexOfKey(displayToken) >= 0;
}

const DisplayDeviceState& DisplayTransactionTest::getCurrentDisplayState(sp<IBinder> displayToken) {
    return mFlinger.mutableCurrentState().displays.valueFor(displayToken);
const DisplayDeviceState& DisplayTransactionTest::getCurrentDisplayState(
        const sp<IBinder>& displayToken) const {
    return mFlinger.currentState().displays.valueFor(displayToken);
}

bool DisplayTransactionTest::hasDrawingDisplayState(sp<IBinder> displayToken) {
    return mFlinger.mutableDrawingState().displays.indexOfKey(displayToken) >= 0;
bool DisplayTransactionTest::hasDrawingDisplayState(const sp<IBinder>& displayToken) const {
    return mFlinger.drawingState().displays.indexOfKey(displayToken) >= 0;
}

const DisplayDeviceState& DisplayTransactionTest::getDrawingDisplayState(sp<IBinder> displayToken) {
    return mFlinger.mutableDrawingState().displays.valueFor(displayToken);
const DisplayDeviceState& DisplayTransactionTest::getDrawingDisplayState(
        const sp<IBinder>& displayToken) const {
    return mFlinger.drawingState().displays.valueFor(displayToken);
}

} // namespace android
+11 −8
Original line number Diff line number Diff line
@@ -95,14 +95,17 @@ public:
    // --------------------------------------------------------------------
    // Postcondition helpers

    bool hasPhysicalHwcDisplay(hal::HWDisplayId hwcDisplayId);
    bool hasTransactionFlagSet(int flag);
    bool hasDisplayDevice(sp<IBinder> displayToken);
    sp<DisplayDevice> getDisplayDevice(sp<IBinder> displayToken);
    bool hasCurrentDisplayState(sp<IBinder> displayToken);
    const DisplayDeviceState& getCurrentDisplayState(sp<IBinder> displayToken);
    bool hasDrawingDisplayState(sp<IBinder> displayToken);
    const DisplayDeviceState& getDrawingDisplayState(sp<IBinder> displayToken);
    bool hasPhysicalHwcDisplay(hal::HWDisplayId) const;
    bool hasTransactionFlagSet(int32_t flag) const;

    bool hasDisplayDevice(const sp<IBinder>& displayToken) const;
    const DisplayDevice& getDisplayDevice(const sp<IBinder>& displayToken) const;

    bool hasCurrentDisplayState(const sp<IBinder>& displayToken) const;
    const DisplayDeviceState& getCurrentDisplayState(const sp<IBinder>& displayToken) const;

    bool hasDrawingDisplayState(const sp<IBinder>& displayToken) const;
    const DisplayDeviceState& getDrawingDisplayState(const sp<IBinder>& displayToken) const;

    // --------------------------------------------------------------------
    // Test instances
+16 −13
Original line number Diff line number Diff line
@@ -107,9 +107,10 @@ template <typename Case>
void DisplayTransactionCommitTest::verifyDisplayIsConnected(const sp<IBinder>& displayToken) {
    // The display device should have been set up in the list of displays.
    ASSERT_TRUE(hasDisplayDevice(displayToken));
    const auto& device = getDisplayDevice(displayToken);
    EXPECT_EQ(static_cast<bool>(Case::Display::SECURE), device->isSecure());
    EXPECT_EQ(static_cast<bool>(Case::Display::PRIMARY), device->isPrimary());
    const auto& display = getDisplayDevice(displayToken);

    EXPECT_EQ(static_cast<bool>(Case::Display::SECURE), display.isSecure());
    EXPECT_EQ(static_cast<bool>(Case::Display::PRIMARY), display.isPrimary());

    std::optional<DisplayDeviceState::Physical> expectedPhysical;
    if (const auto connectionType = Case::Display::CONNECTION_TYPE::value) {
@@ -143,10 +144,11 @@ void DisplayTransactionCommitTest::verifyPhysicalDisplayIsConnected() {
    // SF should have a display token.
    const auto displayId = Case::Display::DISPLAY_ID::get();
    ASSERT_TRUE(PhysicalDisplayId::tryCast(displayId));
    ASSERT_EQ(mFlinger.mutablePhysicalDisplayTokens().count(displayId), 1);
    auto& displayToken = mFlinger.mutablePhysicalDisplayTokens()[displayId];

    verifyDisplayIsConnected<Case>(displayToken);
    const auto displayTokenOpt = mFlinger.mutablePhysicalDisplayTokens().get(displayId);
    ASSERT_TRUE(displayTokenOpt);

    verifyDisplayIsConnected<Case>(displayTokenOpt->get());
}

void DisplayTransactionCommitTest::verifyDisplayIsNotConnected(const sp<IBinder>& displayToken) {
@@ -248,9 +250,9 @@ void DisplayTransactionCommitTest::processesHotplugDisconnectCommon() {
    // SF should not have a display token.
    const auto displayId = Case::Display::DISPLAY_ID::get();
    ASSERT_TRUE(PhysicalDisplayId::tryCast(displayId));
    ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(displayId) == 0);
    ASSERT_FALSE(mFlinger.mutablePhysicalDisplayTokens().contains(displayId));

    // The existing token should have been removed
    // The existing token should have been removed.
    verifyDisplayIsNotConnected(existing.token());
}

@@ -330,7 +332,7 @@ TEST_F(DisplayTransactionCommitTest, processesHotplugConnectThenDisconnectPrimar
                // SF should not have a display token.
                const auto displayId = Case::Display::DISPLAY_ID::get();
                ASSERT_TRUE(PhysicalDisplayId::tryCast(displayId));
                ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(displayId) == 0);
                ASSERT_FALSE(mFlinger.mutablePhysicalDisplayTokens().contains(displayId));
            }(),
            testing::KilledBySignal(SIGABRT), "Primary display cannot be disconnected.");
}
@@ -369,15 +371,16 @@ TEST_F(DisplayTransactionCommitTest, processesHotplugDisconnectThenConnectPrimar
                // --------------------------------------------------------------------
                // Postconditions

                // The existing token should have been removed
                // The existing token should have been removed.
                verifyDisplayIsNotConnected(existing.token());
                const auto displayId = Case::Display::DISPLAY_ID::get();
                ASSERT_TRUE(PhysicalDisplayId::tryCast(displayId));
                ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(displayId) == 1);
                EXPECT_NE(existing.token(), mFlinger.mutablePhysicalDisplayTokens()[displayId]);

                // A new display should be connected in its place
                const auto displayTokenOpt = mFlinger.mutablePhysicalDisplayTokens().get(displayId);
                ASSERT_TRUE(displayTokenOpt);
                EXPECT_NE(existing.token(), displayTokenOpt->get());

                // A new display should be connected in its place.
                verifyPhysicalDisplayIsConnected<Case>();

                // --------------------------------------------------------------------
Loading