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

Commit f22e6acb authored by Marin Shalamanov's avatar Marin Shalamanov
Browse files

SF: Sequential display mode IDs

If the supported display modes differ after a hotplug
assing the new modes new IDs. This way the old IDs will
self invalidate.

This breaks the assumption that the modes IDs are
equivalent to indices in the array of supported modes.

Bug: 159590486
Test: manually 0. device boots in 60hz mode
               1. switch to 50hz from app
               2. disconnect display
               3. reconnect display
      dumpsys SurfaceFlinger after each step to
      verify mode IDs change as expected
Change-Id: I44c90e8151f31e998b43649dad73c51d6948195d
parent 60254672
Loading
Loading
Loading
Loading
+8 −7
Original line number Diff line number Diff line
@@ -145,9 +145,9 @@ bool DisplayDevice::isPoweredOn() const {
}

void DisplayDevice::setActiveMode(DisplayModeId id) {
    LOG_FATAL_IF(id.value() >= mSupportedModes.size(),
                 "Cannot set active mode which is not supported.");
    mActiveModeId = id;
    const auto mode = getMode(id);
    LOG_FATAL_IF(!mode, "Cannot set active mode which is not supported.");
    mActiveMode = mode;
}

status_t DisplayDevice::initiateModeChange(DisplayModeId modeId,
@@ -164,7 +164,7 @@ status_t DisplayDevice::initiateModeChange(DisplayModeId modeId,
}

const DisplayModePtr& DisplayDevice::getActiveMode() const {
    return mSupportedModes[mActiveModeId.value()];
    return mActiveMode;
}

const DisplayModes& DisplayDevice::getSupportedModes() const {
@@ -172,9 +172,10 @@ const DisplayModes& DisplayDevice::getSupportedModes() const {
}

DisplayModePtr DisplayDevice::getMode(DisplayModeId modeId) const {
    const auto id = modeId.value();
    if (static_cast<size_t>(id) < mSupportedModes.size()) {
        return mSupportedModes[id];
    const auto it = std::find_if(mSupportedModes.begin(), mSupportedModes.end(),
                                 [&](DisplayModePtr mode) { return mode->getId() == modeId; });
    if (it != mSupportedModes.end()) {
        return *it;
    }
    return nullptr;
}
+1 −1
Original line number Diff line number Diff line
@@ -208,7 +208,7 @@ private:

    hardware::graphics::composer::hal::PowerMode mPowerMode =
            hardware::graphics::composer::hal::PowerMode::OFF;
    DisplayModeId mActiveModeId;
    DisplayModePtr mActiveMode;
    const DisplayModes mSupportedModes;

    std::atomic<nsecs_t> mLastHwVsync = 0;
+6 −0
Original line number Diff line number Diff line
@@ -125,6 +125,12 @@ public:
    // without visual interruptions such as a black screen.
    int32_t getGroup() const { return mGroup; }

    bool equalsExceptDisplayModeId(const DisplayModePtr& other) const {
        return mHwcId == other->mHwcId && mWidth == other->mWidth && mHeight == other->mHeight &&
                getVsyncPeriod() == other->getVsyncPeriod() && mDpiX == other->mDpiX &&
                mDpiY == other->mDpiY && mGroup == other->mGroup;
    }

private:
    explicit DisplayMode(hal::HWConfigId id) : mHwcId(id) {}

+5 −4
Original line number Diff line number Diff line
@@ -610,15 +610,16 @@ RefreshRateConfigs::RefreshRateConfigs(const DisplayModes& modes, DisplayModeId
void RefreshRateConfigs::updateDisplayModes(const DisplayModes& modes,
                                            DisplayModeId currentModeId) {
    std::lock_guard lock(mLock);
    LOG_ALWAYS_FATAL_IF(modes.empty());
    LOG_ALWAYS_FATAL_IF(currentModeId.value() >= modes.size());
    // The current mode should be supported
    LOG_ALWAYS_FATAL_IF(std::none_of(modes.begin(), modes.end(), [&](DisplayModePtr mode) {
        return mode->getId() == currentModeId;
    }));

    mRefreshRates.clear();
    for (const auto& mode : modes) {
        const auto modeId = mode->getId();
        const auto fps = Fps::fromPeriodNsecs(mode->getVsyncPeriod());
        mRefreshRates.emplace(modeId,
                              std::make_unique<RefreshRate>(modeId, mode, fps,
                              std::make_unique<RefreshRate>(modeId, mode, mode->getFps(),
                                                            RefreshRate::ConstructorTag(0)));
        if (modeId == currentModeId) {
            mCurrentRefreshRate = mRefreshRates.at(modeId).get();
+39 −13
Original line number Diff line number Diff line
@@ -2308,10 +2308,25 @@ void SurfaceFlinger::handleTransaction(uint32_t transactionFlags) {

DisplayModes SurfaceFlinger::loadSupportedDisplayModes(PhysicalDisplayId displayId) const {
    const auto hwcModes = getHwComposer().getModes(displayId);
    DisplayModes modes;
    int32_t nextModeId = 0;

    DisplayModes oldModes;

    if (const auto token = getPhysicalDisplayTokenLocked(displayId)) {
        oldModes = getDisplayDeviceLocked(token)->getSupportedModes();
    }

    int largestUsedModeId = -1; // Use int instead of DisplayModeId for signedness
    for (const auto& mode : oldModes) {
        const auto id = static_cast<int>(mode->getId().value());
        if (id > largestUsedModeId) {
            largestUsedModeId = id;
        }
    }

    DisplayModes newModes;
    int32_t nextModeId = largestUsedModeId + 1;
    for (const auto& hwcMode : hwcModes) {
        modes.push_back(DisplayMode::Builder(hwcMode.hwcId)
        newModes.push_back(DisplayMode::Builder(hwcMode.hwcId)
                                   .setId(DisplayModeId{nextModeId++})
                                   .setWidth(hwcMode.width)
                                   .setHeight(hwcMode.height)
@@ -2321,7 +2336,19 @@ DisplayModes SurfaceFlinger::loadSupportedDisplayModes(PhysicalDisplayId display
                                   .setGroup(hwcMode.configGroup)
                                   .build());
    }
    return modes;

    const bool modesAreSame =
            std::equal(newModes.begin(), newModes.end(), oldModes.begin(), oldModes.end(),
                       [](DisplayModePtr left, DisplayModePtr right) {
                           return left->equalsExceptDisplayModeId(right);
                       });

    if (modesAreSame) {
        // The supported modes have not changed, keep the old IDs.
        return oldModes;
    }

    return newModes;
}

void SurfaceFlinger::processDisplayHotplugEventsLocked() {
@@ -2414,7 +2441,6 @@ sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(
        const sp<IGraphicBufferProducer>& producer) {
    DisplayDeviceCreationArgs creationArgs(this, getHwComposer(), displayToken, compositionDisplay);
    creationArgs.sequenceId = state.sequenceId;
    creationArgs.hwComposer = getHwComposer();
    creationArgs.isSecure = state.isSecure;
    creationArgs.displaySurface = displaySurface;
    creationArgs.hasWideColorGamut = false;
Loading