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_METHOD2(onVsync, bool(hal::HWDisplayId, int64_t)); MOCK_METHOD(std::optional<PhysicalDisplayId>, onVsync, (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 +12 −10 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ #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 @@ -148,16 +149,17 @@ bool HWComposer::updatesDeviceProductInfoOnHotplugReconnect() const { return mUpdateDeviceProductInfoOnHotplugReconnect; } bool HWComposer::onVsync(hal::HWDisplayId hwcDisplayId, nsecs_t timestamp) { const auto displayId = toPhysicalDisplayId(hwcDisplayId); if (!displayId) { std::optional<PhysicalDisplayId> HWComposer::onVsync(hal::HWDisplayId hwcDisplayId, nsecs_t timestamp) { const auto displayIdOpt = toPhysicalDisplayId(hwcDisplayId); if (!displayIdOpt) { LOG_HWC_DISPLAY_ERROR(hwcDisplayId, "Invalid HWC display"); return false; return {}; } RETURN_IF_INVALID_DISPLAY(*displayId, false); RETURN_IF_INVALID_DISPLAY(*displayIdOpt, {}); auto& displayData = mDisplayData[*displayId]; auto& displayData = mDisplayData[*displayIdOpt]; { // There have been reports of HWCs that signal several vsync events Loading @@ -166,18 +168,18 @@ bool HWComposer::onVsync(hal::HWDisplayId hwcDisplayId, nsecs_t timestamp) { // 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(*displayId).c_str(), timestamp); return false; to_string(*displayIdOpt).c_str(), timestamp); return {}; } displayData.lastPresentTimestamp = timestamp; } const auto tag = "HW_VSYNC_" + to_string(*displayId); const ftl::Concat tag("HW_VSYNC_", displayIdOpt->value); ATRACE_INT(tag.c_str(), displayData.vsyncTraceToggle); displayData.vsyncTraceToggle = !displayData.vsyncTraceToggle; return true; return displayIdOpt; } size_t HWComposer::getMaxVirtualDisplayCount() const { Loading services/surfaceflinger/DisplayHardware/HWComposer.h +5 −2 Original line number Diff line number Diff line Loading @@ -221,7 +221,10 @@ public: // TODO(b/157555476): Remove when the framework has proper support for headless mode virtual bool updatesDeviceProductInfoOnHotplugReconnect() const = 0; virtual bool onVsync(hal::HWDisplayId, nsecs_t timestamp) = 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 void setVsyncEnabled(PhysicalDisplayId, hal::Vsync enabled) = 0; virtual bool isConnected(PhysicalDisplayId) const = 0; Loading Loading @@ -402,7 +405,7 @@ public: bool updatesDeviceProductInfoOnHotplugReconnect() const override; bool onVsync(hal::HWDisplayId, nsecs_t timestamp) override; std::optional<PhysicalDisplayId> 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 +40 −26 Original line number Diff line number Diff line Loading @@ -238,29 +238,19 @@ EventThread::~EventThread() = default; namespace impl { EventThread::EventThread(const char* name, scheduler::VsyncSchedule& vsyncSchedule, EventThread::EventThread(const char* name, std::shared_ptr<scheduler::VsyncSchedule> vsyncSchedule, IEventThreadCallback& eventThreadCallback, 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(vsyncSchedule), mVsyncRegistration( vsyncSchedule.getDispatch(), [this](nsecs_t vsyncTime, nsecs_t wakeupTime, nsecs_t readyTime) { onVsync(vsyncTime, wakeupTime, readyTime); }, name), mVsyncSchedule(std::move(vsyncSchedule)), mVsyncRegistration(mVsyncSchedule->getDispatch(), createDispatchCallback(), name), mTokenManager(tokenManager), mThrottleVsyncCallback(std::move(throttleVsyncCallback)), mGetVsyncPeriodFunction(std::move(getVsyncPeriodFunction)) { LOG_ALWAYS_FATAL_IF(getVsyncPeriodFunction == nullptr, "getVsyncPeriodFunction must not be null"); mEventThreadCallback(eventThreadCallback) { mThread = std::thread([this]() NO_THREAD_SAFETY_ANALYSIS { std::unique_lock<std::mutex> lock(mMutex); threadMain(lock); Loading Loading @@ -371,16 +361,16 @@ VsyncEventData EventThread::getLatestVsyncEventData( } VsyncEventData vsyncEventData; nsecs_t frameInterval = mGetVsyncPeriodFunction(connection->mOwnerUid); vsyncEventData.frameInterval = frameInterval; const Fps frameInterval = mEventThreadCallback.getLeaderRenderFrameRate(connection->mOwnerUid); vsyncEventData.frameInterval = frameInterval.getPeriodNsecs(); 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, systemTime(SYSTEM_TIME_MONOTONIC), presentTime, deadline); generateFrameTimeline(vsyncEventData, frameInterval.getPeriodNsecs(), systemTime(SYSTEM_TIME_MONOTONIC), presentTime, deadline); return vsyncEventData; } Loading Loading @@ -541,8 +531,10 @@ void EventThread::threadMain(std::unique_lock<std::mutex>& lock) { bool EventThread::shouldConsumeEvent(const DisplayEventReceiver::Event& event, const sp<EventThreadConnection>& connection) const { const auto throttleVsync = [&] { return mThrottleVsyncCallback && mThrottleVsyncCallback(event.vsync.vsyncData.preferredExpectedPresentationTime(), const auto& vsyncData = event.vsync.vsyncData; const auto expectedPresentTime = TimePoint::fromNs(vsyncData.preferredExpectedPresentationTime()); return !mEventThreadCallback.isVsyncTargetForUid(expectedPresentTime, connection->mOwnerUid); }; Loading Loading @@ -631,9 +623,11 @@ 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 int64_t frameInterval = mGetVsyncPeriodFunction(consumer->mOwnerUid); copy.vsync.vsyncData.frameInterval = frameInterval; generateFrameTimeline(copy.vsync.vsyncData, frameInterval, copy.header.timestamp, const Fps frameInterval = mEventThreadCallback.getLeaderRenderFrameRate(consumer->mOwnerUid); copy.vsync.vsyncData.frameInterval = frameInterval.getPeriodNsecs(); generateFrameTimeline(copy.vsync.vsyncData, frameInterval.getPeriodNsecs(), copy.header.timestamp, event.vsync.vsyncData.preferredExpectedPresentationTime(), event.vsync.vsyncData.preferredDeadlineTimestamp()); } Loading Loading @@ -699,6 +693,26 @@ 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 +22 −9 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <sys/types.h> #include <utils/Errors.h> #include <scheduler/Fps.h> #include <scheduler/FrameRateMode.h> #include <condition_variable> #include <cstdint> Loading Loading @@ -67,6 +68,15 @@ 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 @@ -133,18 +143,17 @@ 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: 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(const char* name, std::shared_ptr<scheduler::VsyncSchedule>, IEventThreadCallback&, frametimeline::TokenManager*, std::chrono::nanoseconds workDuration, std::chrono::nanoseconds readyDuration); ~EventThread(); sp<EventThreadConnection> createEventConnection( Loading Loading @@ -176,6 +185,8 @@ public: size_t getEventThreadConnectionCount() override; void onNewVsyncSchedule(std::shared_ptr<scheduler::VsyncSchedule>) override; private: friend EventThreadTest; Loading @@ -199,17 +210,19 @@ 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); scheduler::VsyncSchedule& mVsyncSchedule; std::shared_ptr<scheduler::VsyncSchedule> mVsyncSchedule; TimePoint mLastVsyncCallbackTime GUARDED_BY(mMutex) = TimePoint::now(); scheduler::VSyncCallbackRegistration mVsyncRegistration GUARDED_BY(mMutex); frametimeline::TokenManager* const mTokenManager; const ThrottleVsyncCallback mThrottleVsyncCallback; const GetVsyncPeriodFunction mGetVsyncPeriodFunction; // mEventThreadCallback will outlive the EventThread. IEventThreadCallback& mEventThreadCallback; 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_METHOD2(onVsync, bool(hal::HWDisplayId, int64_t)); MOCK_METHOD(std::optional<PhysicalDisplayId>, onVsync, (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 +12 −10 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ #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 @@ -148,16 +149,17 @@ bool HWComposer::updatesDeviceProductInfoOnHotplugReconnect() const { return mUpdateDeviceProductInfoOnHotplugReconnect; } bool HWComposer::onVsync(hal::HWDisplayId hwcDisplayId, nsecs_t timestamp) { const auto displayId = toPhysicalDisplayId(hwcDisplayId); if (!displayId) { std::optional<PhysicalDisplayId> HWComposer::onVsync(hal::HWDisplayId hwcDisplayId, nsecs_t timestamp) { const auto displayIdOpt = toPhysicalDisplayId(hwcDisplayId); if (!displayIdOpt) { LOG_HWC_DISPLAY_ERROR(hwcDisplayId, "Invalid HWC display"); return false; return {}; } RETURN_IF_INVALID_DISPLAY(*displayId, false); RETURN_IF_INVALID_DISPLAY(*displayIdOpt, {}); auto& displayData = mDisplayData[*displayId]; auto& displayData = mDisplayData[*displayIdOpt]; { // There have been reports of HWCs that signal several vsync events Loading @@ -166,18 +168,18 @@ bool HWComposer::onVsync(hal::HWDisplayId hwcDisplayId, nsecs_t timestamp) { // 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(*displayId).c_str(), timestamp); return false; to_string(*displayIdOpt).c_str(), timestamp); return {}; } displayData.lastPresentTimestamp = timestamp; } const auto tag = "HW_VSYNC_" + to_string(*displayId); const ftl::Concat tag("HW_VSYNC_", displayIdOpt->value); ATRACE_INT(tag.c_str(), displayData.vsyncTraceToggle); displayData.vsyncTraceToggle = !displayData.vsyncTraceToggle; return true; return displayIdOpt; } size_t HWComposer::getMaxVirtualDisplayCount() const { Loading
services/surfaceflinger/DisplayHardware/HWComposer.h +5 −2 Original line number Diff line number Diff line Loading @@ -221,7 +221,10 @@ public: // TODO(b/157555476): Remove when the framework has proper support for headless mode virtual bool updatesDeviceProductInfoOnHotplugReconnect() const = 0; virtual bool onVsync(hal::HWDisplayId, nsecs_t timestamp) = 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 void setVsyncEnabled(PhysicalDisplayId, hal::Vsync enabled) = 0; virtual bool isConnected(PhysicalDisplayId) const = 0; Loading Loading @@ -402,7 +405,7 @@ public: bool updatesDeviceProductInfoOnHotplugReconnect() const override; bool onVsync(hal::HWDisplayId, nsecs_t timestamp) override; std::optional<PhysicalDisplayId> 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 +40 −26 Original line number Diff line number Diff line Loading @@ -238,29 +238,19 @@ EventThread::~EventThread() = default; namespace impl { EventThread::EventThread(const char* name, scheduler::VsyncSchedule& vsyncSchedule, EventThread::EventThread(const char* name, std::shared_ptr<scheduler::VsyncSchedule> vsyncSchedule, IEventThreadCallback& eventThreadCallback, 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(vsyncSchedule), mVsyncRegistration( vsyncSchedule.getDispatch(), [this](nsecs_t vsyncTime, nsecs_t wakeupTime, nsecs_t readyTime) { onVsync(vsyncTime, wakeupTime, readyTime); }, name), mVsyncSchedule(std::move(vsyncSchedule)), mVsyncRegistration(mVsyncSchedule->getDispatch(), createDispatchCallback(), name), mTokenManager(tokenManager), mThrottleVsyncCallback(std::move(throttleVsyncCallback)), mGetVsyncPeriodFunction(std::move(getVsyncPeriodFunction)) { LOG_ALWAYS_FATAL_IF(getVsyncPeriodFunction == nullptr, "getVsyncPeriodFunction must not be null"); mEventThreadCallback(eventThreadCallback) { mThread = std::thread([this]() NO_THREAD_SAFETY_ANALYSIS { std::unique_lock<std::mutex> lock(mMutex); threadMain(lock); Loading Loading @@ -371,16 +361,16 @@ VsyncEventData EventThread::getLatestVsyncEventData( } VsyncEventData vsyncEventData; nsecs_t frameInterval = mGetVsyncPeriodFunction(connection->mOwnerUid); vsyncEventData.frameInterval = frameInterval; const Fps frameInterval = mEventThreadCallback.getLeaderRenderFrameRate(connection->mOwnerUid); vsyncEventData.frameInterval = frameInterval.getPeriodNsecs(); 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, systemTime(SYSTEM_TIME_MONOTONIC), presentTime, deadline); generateFrameTimeline(vsyncEventData, frameInterval.getPeriodNsecs(), systemTime(SYSTEM_TIME_MONOTONIC), presentTime, deadline); return vsyncEventData; } Loading Loading @@ -541,8 +531,10 @@ void EventThread::threadMain(std::unique_lock<std::mutex>& lock) { bool EventThread::shouldConsumeEvent(const DisplayEventReceiver::Event& event, const sp<EventThreadConnection>& connection) const { const auto throttleVsync = [&] { return mThrottleVsyncCallback && mThrottleVsyncCallback(event.vsync.vsyncData.preferredExpectedPresentationTime(), const auto& vsyncData = event.vsync.vsyncData; const auto expectedPresentTime = TimePoint::fromNs(vsyncData.preferredExpectedPresentationTime()); return !mEventThreadCallback.isVsyncTargetForUid(expectedPresentTime, connection->mOwnerUid); }; Loading Loading @@ -631,9 +623,11 @@ 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 int64_t frameInterval = mGetVsyncPeriodFunction(consumer->mOwnerUid); copy.vsync.vsyncData.frameInterval = frameInterval; generateFrameTimeline(copy.vsync.vsyncData, frameInterval, copy.header.timestamp, const Fps frameInterval = mEventThreadCallback.getLeaderRenderFrameRate(consumer->mOwnerUid); copy.vsync.vsyncData.frameInterval = frameInterval.getPeriodNsecs(); generateFrameTimeline(copy.vsync.vsyncData, frameInterval.getPeriodNsecs(), copy.header.timestamp, event.vsync.vsyncData.preferredExpectedPresentationTime(), event.vsync.vsyncData.preferredDeadlineTimestamp()); } Loading Loading @@ -699,6 +693,26 @@ 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 +22 −9 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <sys/types.h> #include <utils/Errors.h> #include <scheduler/Fps.h> #include <scheduler/FrameRateMode.h> #include <condition_variable> #include <cstdint> Loading Loading @@ -67,6 +68,15 @@ 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 @@ -133,18 +143,17 @@ 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: 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(const char* name, std::shared_ptr<scheduler::VsyncSchedule>, IEventThreadCallback&, frametimeline::TokenManager*, std::chrono::nanoseconds workDuration, std::chrono::nanoseconds readyDuration); ~EventThread(); sp<EventThreadConnection> createEventConnection( Loading Loading @@ -176,6 +185,8 @@ public: size_t getEventThreadConnectionCount() override; void onNewVsyncSchedule(std::shared_ptr<scheduler::VsyncSchedule>) override; private: friend EventThreadTest; Loading @@ -199,17 +210,19 @@ 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); scheduler::VsyncSchedule& mVsyncSchedule; std::shared_ptr<scheduler::VsyncSchedule> mVsyncSchedule; TimePoint mLastVsyncCallbackTime GUARDED_BY(mMutex) = TimePoint::now(); scheduler::VSyncCallbackRegistration mVsyncRegistration GUARDED_BY(mMutex); frametimeline::TokenManager* const mTokenManager; const ThrottleVsyncCallback mThrottleVsyncCallback; const GetVsyncPeriodFunction mGetVsyncPeriodFunction; // mEventThreadCallback will outlive the EventThread. IEventThreadCallback& mEventThreadCallback; std::thread mThread; mutable std::mutex mMutex; Loading