Loading services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h +1 −1 Original line number Diff line number Diff line Loading @@ -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)); Loading services/surfaceflinger/DisplayHardware/HWComposer.cpp +10 −12 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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 Loading @@ -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 { Loading services/surfaceflinger/DisplayHardware/HWComposer.h +2 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading services/surfaceflinger/Scheduler/EventThread.cpp +27 −40 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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; } Loading Loading @@ -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); }; Loading Loading @@ -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()); } Loading Loading @@ -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 Loading services/surfaceflinger/Scheduler/EventThread.h +9 −22 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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, Loading Loading @@ -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( Loading Loading @@ -188,8 +179,6 @@ public: size_t getEventThreadConnectionCount() override; void onNewVsyncSchedule(std::shared_ptr<scheduler::VsyncSchedule>) override; private: friend EventThreadTest; Loading @@ -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 Loading
services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h +1 −1 Original line number Diff line number Diff line Loading @@ -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)); Loading
services/surfaceflinger/DisplayHardware/HWComposer.cpp +10 −12 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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 Loading @@ -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 { Loading
services/surfaceflinger/DisplayHardware/HWComposer.h +2 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading
services/surfaceflinger/Scheduler/EventThread.cpp +27 −40 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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; } Loading Loading @@ -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); }; Loading Loading @@ -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()); } Loading Loading @@ -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 Loading
services/surfaceflinger/Scheduler/EventThread.h +9 −22 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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, Loading Loading @@ -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( Loading Loading @@ -188,8 +179,6 @@ public: size_t getEventThreadConnectionCount() override; void onNewVsyncSchedule(std::shared_ptr<scheduler::VsyncSchedule>) override; private: friend EventThreadTest; Loading @@ -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