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

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

Revert "Create a VsyncSchedule per display"

This reverts commit 31d41415.

Conflicts:
    services/surfaceflinger/Scheduler/EventThread.cpp
    services/surfaceflinger/SurfaceFlinger.cpp

Bug: 267562341
Test: ARC Regression Dashboard
Change-Id: I0757a7df540fad316b2db42e4c77f1c73bc49420
parent 6c94ce43
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -93,7 +93,7 @@ public:
    MOCK_METHOD2(onHotplug,
                 std::optional<DisplayIdentificationInfo>(hal::HWDisplayId, hal::Connection));
    MOCK_CONST_METHOD0(updatesDeviceProductInfoOnHotplugReconnect, bool());
    MOCK_METHOD(std::optional<PhysicalDisplayId>, onVsync, (hal::HWDisplayId, int64_t));
    MOCK_METHOD2(onVsync, bool(hal::HWDisplayId, int64_t));
    MOCK_METHOD2(setVsyncEnabled, void(PhysicalDisplayId, hal::Vsync));
    MOCK_CONST_METHOD1(isConnected, bool(PhysicalDisplayId));
    MOCK_CONST_METHOD1(getModes, std::vector<HWComposer::HWCDisplayMode>(PhysicalDisplayId));
+10 −12
Original line number Diff line number Diff line
@@ -30,7 +30,6 @@
#include <compositionengine/Output.h>
#include <compositionengine/OutputLayer.h>
#include <compositionengine/impl/OutputLayerCompositionState.h>
#include <ftl/concat.h>
#include <log/log.h>
#include <ui/DebugUtils.h>
#include <ui/GraphicBuffer.h>
@@ -149,17 +148,16 @@ bool HWComposer::updatesDeviceProductInfoOnHotplugReconnect() const {
    return mUpdateDeviceProductInfoOnHotplugReconnect;
}

std::optional<PhysicalDisplayId> HWComposer::onVsync(hal::HWDisplayId hwcDisplayId,
                                                     nsecs_t timestamp) {
    const auto displayIdOpt = toPhysicalDisplayId(hwcDisplayId);
    if (!displayIdOpt) {
bool HWComposer::onVsync(hal::HWDisplayId hwcDisplayId, nsecs_t timestamp) {
    const auto displayId = toPhysicalDisplayId(hwcDisplayId);
    if (!displayId) {
        LOG_HWC_DISPLAY_ERROR(hwcDisplayId, "Invalid HWC display");
        return {};
        return false;
    }

    RETURN_IF_INVALID_DISPLAY(*displayIdOpt, {});
    RETURN_IF_INVALID_DISPLAY(*displayId, false);

    auto& displayData = mDisplayData[*displayIdOpt];
    auto& displayData = mDisplayData[*displayId];

    {
        // There have been reports of HWCs that signal several vsync events
@@ -168,18 +166,18 @@ std::optional<PhysicalDisplayId> HWComposer::onVsync(hal::HWDisplayId hwcDisplay
        // out here so they don't cause havoc downstream.
        if (timestamp == displayData.lastPresentTimestamp) {
            ALOGW("Ignoring duplicate VSYNC event from HWC for display %s (t=%" PRId64 ")",
                  to_string(*displayIdOpt).c_str(), timestamp);
            return {};
                  to_string(*displayId).c_str(), timestamp);
            return false;
        }

        displayData.lastPresentTimestamp = timestamp;
    }

    const ftl::Concat tag("HW_VSYNC_", displayIdOpt->value);
    const auto tag = "HW_VSYNC_" + to_string(*displayId);
    ATRACE_INT(tag.c_str(), displayData.vsyncTraceToggle);
    displayData.vsyncTraceToggle = !displayData.vsyncTraceToggle;

    return displayIdOpt;
    return true;
}

size_t HWComposer::getMaxVirtualDisplayCount() const {
+2 −5
Original line number Diff line number Diff line
@@ -221,10 +221,7 @@ public:
    // TODO(b/157555476): Remove when the framework has proper support for headless mode
    virtual bool updatesDeviceProductInfoOnHotplugReconnect() const = 0;

    // Called when a vsync happens. If the vsync is valid, returns the
    // corresponding PhysicalDisplayId. Otherwise returns nullopt.
    virtual std::optional<PhysicalDisplayId> onVsync(hal::HWDisplayId, nsecs_t timestamp) = 0;

    virtual bool onVsync(hal::HWDisplayId, nsecs_t timestamp) = 0;
    virtual void setVsyncEnabled(PhysicalDisplayId, hal::Vsync enabled) = 0;

    virtual bool isConnected(PhysicalDisplayId) const = 0;
@@ -405,7 +402,7 @@ public:

    bool updatesDeviceProductInfoOnHotplugReconnect() const override;

    std::optional<PhysicalDisplayId> onVsync(hal::HWDisplayId, nsecs_t timestamp) override;
    bool onVsync(hal::HWDisplayId, nsecs_t timestamp) override;
    void setVsyncEnabled(PhysicalDisplayId, hal::Vsync enabled) override;

    bool isConnected(PhysicalDisplayId) const override;
+27 −40
Original line number Diff line number Diff line
@@ -238,19 +238,29 @@ EventThread::~EventThread() = default;

namespace impl {

EventThread::EventThread(const char* name, std::shared_ptr<scheduler::VsyncSchedule> vsyncSchedule,
                         IEventThreadCallback& eventThreadCallback,
EventThread::EventThread(const char* name, scheduler::VsyncSchedule& vsyncSchedule,
                         android::frametimeline::TokenManager* tokenManager,
                         ThrottleVsyncCallback throttleVsyncCallback,
                         GetVsyncPeriodFunction getVsyncPeriodFunction,
                         std::chrono::nanoseconds workDuration,
                         std::chrono::nanoseconds readyDuration)
      : mThreadName(name),
        mVsyncTracer(base::StringPrintf("VSYNC-%s", name), 0),
        mWorkDuration(base::StringPrintf("VsyncWorkDuration-%s", name), workDuration),
        mReadyDuration(readyDuration),
        mVsyncSchedule(std::move(vsyncSchedule)),
        mVsyncRegistration(mVsyncSchedule->getDispatch(), createDispatchCallback(), name),
        mVsyncSchedule(vsyncSchedule),
        mVsyncRegistration(
                vsyncSchedule.getDispatch(),
                [this](nsecs_t vsyncTime, nsecs_t wakeupTime, nsecs_t readyTime) {
                    onVsync(vsyncTime, wakeupTime, readyTime);
                },
                name),
        mTokenManager(tokenManager),
        mEventThreadCallback(eventThreadCallback) {
        mThrottleVsyncCallback(std::move(throttleVsyncCallback)),
        mGetVsyncPeriodFunction(std::move(getVsyncPeriodFunction)) {
    LOG_ALWAYS_FATAL_IF(getVsyncPeriodFunction == nullptr,
            "getVsyncPeriodFunction must not be null");

    mThread = std::thread([this]() NO_THREAD_SAFETY_ANALYSIS {
        std::unique_lock<std::mutex> lock(mMutex);
        threadMain(lock);
@@ -361,16 +371,16 @@ VsyncEventData EventThread::getLatestVsyncEventData(
    }

    VsyncEventData vsyncEventData;
    const Fps frameInterval = mEventThreadCallback.getLeaderRenderFrameRate(connection->mOwnerUid);
    vsyncEventData.frameInterval = frameInterval.getPeriodNsecs();
    nsecs_t frameInterval = mGetVsyncPeriodFunction(connection->mOwnerUid);
    vsyncEventData.frameInterval = frameInterval;
    const auto [presentTime, deadline] = [&]() -> std::pair<nsecs_t, nsecs_t> {
        std::lock_guard<std::mutex> lock(mMutex);
        const auto vsyncTime = mVsyncSchedule->getTracker().nextAnticipatedVSyncTimeFrom(
        const auto vsyncTime = mVsyncSchedule.getTracker().nextAnticipatedVSyncTimeFrom(
                systemTime() + mWorkDuration.get().count() + mReadyDuration.count());
        return {vsyncTime, vsyncTime - mReadyDuration.count()};
    }();
    generateFrameTimeline(vsyncEventData, frameInterval.getPeriodNsecs(),
                          systemTime(SYSTEM_TIME_MONOTONIC), presentTime, deadline);
    generateFrameTimeline(vsyncEventData, frameInterval, systemTime(SYSTEM_TIME_MONOTONIC),
                          presentTime, deadline);
    return vsyncEventData;
}

@@ -533,14 +543,13 @@ bool EventThread::shouldConsumeEvent(const DisplayEventReceiver::Event& event,
    const auto throttleVsync = [&] {
        const auto& vsyncData = event.vsync.vsyncData;
        if (connection->frameRate.isValid()) {
            return !mVsyncSchedule->getTracker()
            return !mVsyncSchedule.getTracker()
                            .isVSyncInPhase(vsyncData.preferredExpectedPresentationTime(),
                                            connection->frameRate);
        }

        const auto expectedPresentTime =
                TimePoint::fromNs(vsyncData.preferredExpectedPresentationTime());
        return !mEventThreadCallback.isVsyncTargetForUid(expectedPresentTime,
        return mThrottleVsyncCallback &&
                mThrottleVsyncCallback(event.vsync.vsyncData.preferredExpectedPresentationTime(),
                                       connection->mOwnerUid);
    };

@@ -629,11 +638,9 @@ void EventThread::dispatchEvent(const DisplayEventReceiver::Event& event,
    for (const auto& consumer : consumers) {
        DisplayEventReceiver::Event copy = event;
        if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
            const Fps frameInterval =
                    mEventThreadCallback.getLeaderRenderFrameRate(consumer->mOwnerUid);
            copy.vsync.vsyncData.frameInterval = frameInterval.getPeriodNsecs();
            generateFrameTimeline(copy.vsync.vsyncData, frameInterval.getPeriodNsecs(),
                                  copy.header.timestamp,
            const int64_t frameInterval = mGetVsyncPeriodFunction(consumer->mOwnerUid);
            copy.vsync.vsyncData.frameInterval = frameInterval;
            generateFrameTimeline(copy.vsync.vsyncData, frameInterval, copy.header.timestamp,
                                  event.vsync.vsyncData.preferredExpectedPresentationTime(),
                                  event.vsync.vsyncData.preferredDeadlineTimestamp());
        }
@@ -699,26 +706,6 @@ const char* EventThread::toCString(State state) {
    }
}

void EventThread::onNewVsyncSchedule(std::shared_ptr<scheduler::VsyncSchedule> schedule) {
    std::lock_guard<std::mutex> lock(mMutex);
    const bool reschedule = mVsyncRegistration.cancel() == scheduler::CancelResult::Cancelled;
    mVsyncSchedule = std::move(schedule);
    mVsyncRegistration =
            scheduler::VSyncCallbackRegistration(mVsyncSchedule->getDispatch(),
                                                 createDispatchCallback(), mThreadName);
    if (reschedule) {
        mVsyncRegistration.schedule({.workDuration = mWorkDuration.get().count(),
                                     .readyDuration = mReadyDuration.count(),
                                     .earliestVsync = mLastVsyncCallbackTime.ns()});
    }
}

scheduler::VSyncDispatch::Callback EventThread::createDispatchCallback() {
    return [this](nsecs_t vsyncTime, nsecs_t wakeupTime, nsecs_t readyTime) {
        onVsync(vsyncTime, wakeupTime, readyTime);
    };
}

} // namespace impl
} // namespace android

+9 −22
Original line number Diff line number Diff line
@@ -23,7 +23,6 @@
#include <sys/types.h>
#include <utils/Errors.h>

#include <scheduler/Fps.h>
#include <scheduler/FrameRateMode.h>
#include <condition_variable>
#include <cstdint>
@@ -68,15 +67,6 @@ enum class VSyncRequest {
    // Subsequent values are periods.
};

class IEventThreadCallback {
public:
    virtual ~IEventThreadCallback() = default;

    virtual bool isVsyncTargetForUid(TimePoint expectedVsyncTime, uid_t uid) const = 0;

    virtual Fps getLeaderRenderFrameRate(uid_t uid) const = 0;
};

class EventThreadConnection : public gui::BnDisplayEventConnection {
public:
    EventThreadConnection(EventThread*, uid_t callingUid, ResyncCallback,
@@ -146,17 +136,18 @@ public:

    // Retrieves the number of event connections tracked by this EventThread.
    virtual size_t getEventThreadConnectionCount() = 0;

    virtual void onNewVsyncSchedule(std::shared_ptr<scheduler::VsyncSchedule>) = 0;
};

namespace impl {

class EventThread : public android::EventThread {
public:
    EventThread(const char* name, std::shared_ptr<scheduler::VsyncSchedule>, IEventThreadCallback&,
                frametimeline::TokenManager*, std::chrono::nanoseconds workDuration,
                std::chrono::nanoseconds readyDuration);
    using ThrottleVsyncCallback = std::function<bool(nsecs_t, uid_t)>;
    using GetVsyncPeriodFunction = std::function<nsecs_t(uid_t)>;

    EventThread(const char* name, scheduler::VsyncSchedule&, frametimeline::TokenManager*,
                ThrottleVsyncCallback, GetVsyncPeriodFunction,
                std::chrono::nanoseconds workDuration, std::chrono::nanoseconds readyDuration);
    ~EventThread();

    sp<EventThreadConnection> createEventConnection(
@@ -188,8 +179,6 @@ public:

    size_t getEventThreadConnectionCount() override;

    void onNewVsyncSchedule(std::shared_ptr<scheduler::VsyncSchedule>) override;

private:
    friend EventThreadTest;

@@ -213,19 +202,17 @@ private:
                               nsecs_t timestamp, nsecs_t preferredExpectedPresentationTime,
                               nsecs_t preferredDeadlineTimestamp) const;

    scheduler::VSyncDispatch::Callback createDispatchCallback();

    const char* const mThreadName;
    TracedOrdinal<int> mVsyncTracer;
    TracedOrdinal<std::chrono::nanoseconds> mWorkDuration GUARDED_BY(mMutex);
    std::chrono::nanoseconds mReadyDuration GUARDED_BY(mMutex);
    std::shared_ptr<scheduler::VsyncSchedule> mVsyncSchedule;
    scheduler::VsyncSchedule& mVsyncSchedule;
    TimePoint mLastVsyncCallbackTime GUARDED_BY(mMutex) = TimePoint::now();
    scheduler::VSyncCallbackRegistration mVsyncRegistration GUARDED_BY(mMutex);
    frametimeline::TokenManager* const mTokenManager;

    // mEventThreadCallback will outlive the EventThread.
    IEventThreadCallback& mEventThreadCallback;
    const ThrottleVsyncCallback mThrottleVsyncCallback;
    const GetVsyncPeriodFunction mGetVsyncPeriodFunction;

    std::thread mThread;
    mutable std::mutex mMutex;
Loading