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

Commit 091129a2 authored by Dominik Laskowski's avatar Dominik Laskowski
Browse files

SF: Move hotplug dispatch to Scheduler

Hide the Render/LastComposite details in Scheduler.

Also, dispatch hotplug errors to both EventThreads for consistency.

Bug: 241285191
Bug: 241285945
Test: Hotplug still works.
Change-Id: I425d997274c0272a2bfa352c138750d65d008da5
parent 674215c1
Loading
Loading
Loading
Loading
+11 −4
Original line number Diff line number Diff line
@@ -154,9 +154,13 @@ void Scheduler::registerDisplayInternal(PhysicalDisplayId displayId,
    if (isNew) {
        onHardwareVsyncRequest(displayId, false);
    }

    dispatchHotplug(displayId, Hotplug::Connected);
}

void Scheduler::unregisterDisplay(PhysicalDisplayId displayId) {
    dispatchHotplug(displayId, Hotplug::Disconnected);

    demotePacesetterDisplay();

    std::shared_ptr<VsyncSchedule> pacesetterVsyncSchedule;
@@ -375,15 +379,18 @@ sp<IDisplayEventConnection> Scheduler::createDisplayEventConnection(
    return connection;
}

void Scheduler::onHotplugReceived(Cycle cycle, PhysicalDisplayId displayId, bool connected) {
void Scheduler::dispatchHotplug(PhysicalDisplayId displayId, Hotplug hotplug) {
    if (hasEventThreads()) {
        eventThreadFor(cycle).onHotplugReceived(displayId, connected);
        const bool connected = hotplug == Hotplug::Connected;
        eventThreadFor(Cycle::Render).onHotplugReceived(displayId, connected);
        eventThreadFor(Cycle::LastComposite).onHotplugReceived(displayId, connected);
    }
}

void Scheduler::onHotplugConnectionError(Cycle cycle, int32_t errorCode) {
void Scheduler::dispatchHotplugError(int32_t errorCode) {
    if (hasEventThreads()) {
        eventThreadFor(cycle).onHotplugConnectionError(errorCode);
        eventThreadFor(Cycle::Render).onHotplugConnectionError(errorCode);
        eventThreadFor(Cycle::LastComposite).onHotplugConnectionError(errorCode);
    }
}

+4 −2
Original line number Diff line number Diff line
@@ -142,8 +142,10 @@ public:
        return cycle == Cycle::Render ? mRenderEventConnection : mLastCompositeEventConnection;
    }

    void onHotplugReceived(Cycle, PhysicalDisplayId, bool connected);
    void onHotplugConnectionError(Cycle, int32_t errorCode);
    enum class Hotplug { Connected, Disconnected };
    void dispatchHotplug(PhysicalDisplayId, Hotplug);

    void dispatchHotplugError(int32_t errorCode);

    void onPrimaryDisplayModeChanged(Cycle, const FrameRateMode&) EXCLUDES(mPolicyLock);
    void onNonPrimaryDisplayModeChanged(Cycle, const FrameRateMode&);
+17 −28
Original line number Diff line number Diff line
@@ -886,7 +886,6 @@ void SurfaceFlinger::init() FTL_FAKE_GUARD(kMainThreadContext) {
    // the DisplayDevice, hence the above commit of the primary display. Remove that special case by
    // initializing the Scheduler after configureLocked, once decoupled from DisplayDevice.
    initScheduler(display);
    dispatchDisplayHotplugEvent(display->getPhysicalId(), true);

    mLayerTracing.setTakeLayersSnapshotProtoFunction([&](uint32_t traceFlags) {
        auto snapshot = perfetto::protos::LayersSnapshotProto{};
@@ -1756,7 +1755,7 @@ status_t SurfaceFlinger::overrideHdrTypes(const sp<IBinder>& displayToken,
    }

    display->overrideHdrTypes(hdrTypes);
    dispatchDisplayHotplugEvent(display->getPhysicalId(), true /* connected */);
    mScheduler->dispatchHotplug(display->getPhysicalId(), scheduler::Scheduler::Hotplug::Connected);
    return NO_ERROR;
}

@@ -2128,10 +2127,9 @@ void SurfaceFlinger::onComposerHalVsync(hal::HWDisplayId hwcDisplayId, int64_t t
        vsyncPeriod.has_value()) {
        // use ~0 instead of -1 as AidlComposerHal.cpp passes the param as unsigned int32
        if (mIsHotplugErrViaNegVsync && vsyncPeriod.value() == ~0) {
            const int32_t hotplugErrorCode = static_cast<int32_t>(-timestamp);
            ALOGD("SurfaceFlinger got hotplugErrorCode=%d for display %" PRIu64, hotplugErrorCode,
                  hwcDisplayId);
            mScheduler->onHotplugConnectionError(scheduler::Cycle::Render, hotplugErrorCode);
            const auto errorCode = static_cast<int32_t>(-timestamp);
            ALOGD("%s: Hotplug error %d for display %" PRIu64, __func__, errorCode, hwcDisplayId);
            mScheduler->dispatchHotplugError(errorCode);
            return;
        }

@@ -2140,8 +2138,7 @@ void SurfaceFlinger::onComposerHalVsync(hal::HWDisplayId hwcDisplayId, int64_t t
            // one byte is good enough to encode android.hardware.drm.HdcpLevel
            const int32_t maxLevel = (value >> 8) & 0xFF;
            const int32_t connectedLevel = value & 0xFF;
            ALOGD("SurfaceFlinger got HDCP level changed: connected=%d, max=%d for "
                  "display=%" PRIu64,
            ALOGD("%s: HDCP levels changed (connected=%d, max=%d) for display %" PRIu64, __func__,
                  connectedLevel, maxLevel, hwcDisplayId);
            updateHdcpLevels(hwcDisplayId, connectedLevel, maxLevel);
            return;
@@ -2180,9 +2177,10 @@ void SurfaceFlinger::onComposerHalHotplugEvent(hal::HWDisplayId hwcDisplayId,
    }

    if (FlagManager::getInstance().hotplug2()) {
        ALOGD("SurfaceFlinger got hotplug event=%d", static_cast<int32_t>(event));
        // TODO(b/311403559): use enum type instead of int
        mScheduler->onHotplugConnectionError(scheduler::Cycle::Render, static_cast<int32_t>(event));
        const auto errorCode = static_cast<int32_t>(event);
        ALOGD("%s: Hotplug error %d for display %" PRIu64, __func__, errorCode, hwcDisplayId);
        mScheduler->dispatchHotplugError(errorCode);
    }
}

@@ -3472,9 +3470,8 @@ const char* SurfaceFlinger::processHotplug(PhysicalDisplayId displayId,
    if (!activeMode) {
        ALOGE("Failed to hotplug display %s", to_string(displayId).c_str());
        if (FlagManager::getInstance().hotplug2()) {
            mScheduler->onHotplugConnectionError(scheduler::Cycle::Render,
                                                 static_cast<int32_t>(
                                                         DisplayHotplugEvent::ERROR_UNKNOWN));
            mScheduler->dispatchHotplugError(
                    static_cast<int32_t>(DisplayHotplugEvent::ERROR_UNKNOWN));
        }
        getHwComposer().disconnectDisplay(displayId);
        return nullptr;
@@ -3524,11 +3521,6 @@ const char* SurfaceFlinger::processHotplug(PhysicalDisplayId displayId,
    return "Connecting";
}

void SurfaceFlinger::dispatchDisplayHotplugEvent(PhysicalDisplayId displayId, bool connected) {
    mScheduler->onHotplugReceived(scheduler::Cycle::Render, displayId, connected);
    mScheduler->onHotplugReceived(scheduler::Cycle::LastComposite, displayId, connected);
}

void SurfaceFlinger::dispatchDisplayModeChangeEvent(PhysicalDisplayId displayId,
                                                    const scheduler::FrameRateMode& mode) {
    // TODO(b/255635821): Merge code paths and move to Scheduler.
@@ -3717,16 +3709,11 @@ void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken,
                                                 displaySurface, producer);

    if (mScheduler && !display->isVirtual()) {
        const auto displayId = display->getPhysicalId();
        {
        // TODO(b/241285876): Annotate `processDisplayAdded` instead.
        ftl::FakeGuard guard(kMainThreadContext);

        // For hotplug reconnect, renew the registration since display modes have been reloaded.
            mScheduler->registerDisplay(displayId, display->holdRefreshRateSelector());
        }

        dispatchDisplayHotplugEvent(displayId, true);
        mScheduler->registerDisplay(display->getPhysicalId(), display->holdRefreshRateSelector());
    }

    if (display->isVirtual()) {
@@ -3765,7 +3752,6 @@ void SurfaceFlinger::processDisplayRemoved(const wp<IBinder>& displayToken) {
        if (display->isVirtual()) {
            releaseVirtualDisplay(display->getVirtualId());
        } else {
            dispatchDisplayHotplugEvent(display->getPhysicalId(), false);
            mScheduler->unregisterDisplay(display->getPhysicalId());
        }
    }
@@ -4370,6 +4356,9 @@ void SurfaceFlinger::initScheduler(const sp<const DisplayDevice>& display) {
                                  /* workDuration */ activeRefreshRate.getPeriod(),
                                  /* readyDuration */ configs.late.sfWorkDuration);

    // Dispatch after EventThread creation, since registerDisplay above skipped dispatch.
    mScheduler->dispatchHotplug(display->getPhysicalId(), scheduler::Scheduler::Hotplug::Connected);

    mScheduler->initVsync(*mFrameTimeline->getTokenManager(), configs.late.sfWorkDuration);

    mRegionSamplingThread =
+0 −1
Original line number Diff line number Diff line
@@ -1050,7 +1050,6 @@ private:
                               const DisplayDeviceState& drawingState)
            REQUIRES(mStateLock, kMainThreadContext);

    void dispatchDisplayHotplugEvent(PhysicalDisplayId, bool connected);
    void dispatchDisplayModeChangeEvent(PhysicalDisplayId, const scheduler::FrameRateMode&)
            REQUIRES(mStateLock);