Loading services/surfaceflinger/Scheduler/EventThread.cpp +12 −5 Original line number Diff line number Diff line Loading @@ -67,7 +67,13 @@ status_t EventThreadConnection::setVsyncRate(uint32_t count) { } void EventThreadConnection::requestNextVsync() { mEventThread->requestNextVsync(this); ATRACE_NAME("requestNextVsync"); mEventThread->requestNextVsync(this, true); } void EventThreadConnection::requestNextVsyncForHWC() { ATRACE_NAME("requestNextVsyncForHWC"); mEventThread->requestNextVsync(this, false); } status_t EventThreadConnection::postEvent(const DisplayEventReceiver::Event& event) { Loading Loading @@ -184,16 +190,17 @@ void EventThread::setVsyncRate(uint32_t count, const sp<EventThreadConnection>& } } void EventThread::requestNextVsync(const sp<EventThreadConnection>& connection) { std::lock_guard<std::mutex> lock(mMutex); if (mResetIdleTimer) { void EventThread::requestNextVsync(const sp<EventThreadConnection>& connection, bool reset) { if (mResetIdleTimer && reset) { ATRACE_NAME("resetIdleTimer"); mResetIdleTimer(); } if (mResyncWithRateLimitCallback) { mResyncWithRateLimitCallback(); } std::lock_guard<std::mutex> lock(mMutex); if (connection->count < 0) { connection->count = 0; mCondition.notify_all(); Loading services/surfaceflinger/Scheduler/EventThread.h +11 −2 Original line number Diff line number Diff line Loading @@ -68,6 +68,9 @@ public: status_t stealReceiveChannel(gui::BitTube* outChannel) override; status_t setVsyncRate(uint32_t count) override; void requestNextVsync() override; // asynchronous // Requesting Vsync for HWC does not reset the idle timer, since HWC requires a refresh // in order to update the configs. void requestNextVsyncForHWC(); // count >= 1 : continuous event. count is the vsync rate // count == 0 : one-shot event that has not fired Loading Loading @@ -105,7 +108,9 @@ public: virtual status_t registerDisplayEventConnection( const sp<EventThreadConnection>& connection) = 0; virtual void setVsyncRate(uint32_t count, const sp<EventThreadConnection>& connection) = 0; virtual void requestNextVsync(const sp<EventThreadConnection>& connection) = 0; // Requests the next vsync. If resetIdleTimer is set to true, it resets the idle timer. virtual void requestNextVsync(const sp<EventThreadConnection>& connection, bool resetIdleTimer) = 0; }; namespace impl { Loading @@ -129,7 +134,8 @@ public: status_t registerDisplayEventConnection(const sp<EventThreadConnection>& connection) override; void setVsyncRate(uint32_t count, const sp<EventThreadConnection>& connection) override; void requestNextVsync(const sp<EventThreadConnection>& connection) override; void requestNextVsync(const sp<EventThreadConnection>& connection, bool resetIdleTimer) override; // called before the screen is turned off from main thread void onScreenReleased() override; Loading Loading @@ -166,6 +172,9 @@ private: // Implements VSyncSource::Callback void onVSyncEvent(nsecs_t timestamp) override; // Acquires mutex and requests next vsync. void requestNextVsyncInternal(const sp<EventThreadConnection>& connection) EXCLUDES(mMutex); // TODO(b/113612090): Once the Scheduler is complete this pointer will become obsolete. VSyncSource* mVSyncSource GUARDED_BY(mMutex) = nullptr; std::unique_ptr<VSyncSource> mVSyncSourceUnique GUARDED_BY(mMutex) = nullptr; Loading services/surfaceflinger/Scheduler/MessageQueue.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -148,6 +148,10 @@ void MessageQueue::invalidate() { mEvents->requestNextVsync(); } void MessageQueue::invalidateForHWC() { mEvents->requestNextVsyncForHWC(); } void MessageQueue::refresh() { mHandler->dispatchRefresh(); } Loading services/surfaceflinger/Scheduler/MessageQueue.h +4 −0 Original line number Diff line number Diff line Loading @@ -91,6 +91,7 @@ public: virtual void waitMessage() = 0; virtual status_t postMessage(const sp<MessageBase>& message, nsecs_t reltime = 0) = 0; virtual void invalidate() = 0; virtual void invalidateForHWC() = 0; virtual void refresh() = 0; }; Loading Loading @@ -134,6 +135,9 @@ public: // sends INVALIDATE message at next VSYNC void invalidate() override; // sends INVALIDATE message at next VSYNC, without resetting the idle timer in the Scheduler void invalidateForHWC(); // sends REFRESH message at next VSYNC void refresh() override; }; Loading services/surfaceflinger/Scheduler/Scheduler.cpp +23 −7 Original line number Diff line number Diff line Loading @@ -238,6 +238,16 @@ void Scheduler::incrementFrameCounter() { mLayerHistory.incrementCounter(); } void Scheduler::setExpiredIdleTimerCallback(const ExpiredIdleTimerCallback& expiredTimerCallback) { std::lock_guard<std::mutex> lock(mCallbackLock); mExpiredTimerCallback = expiredTimerCallback; } void Scheduler::setResetIdleTimerCallback(const ResetIdleTimerCallback& resetTimerCallback) { std::lock_guard<std::mutex> lock(mCallbackLock); mResetTimerCallback = resetTimerCallback; } void Scheduler::updateFrameSkipping(const int64_t skipCount) { ATRACE_INT("FrameSkipCount", skipCount); if (mSkipCount != skipCount) { Loading Loading @@ -314,12 +324,12 @@ void Scheduler::determineTimestampAverage(bool isAutoTimestamp, const nsecs_t fr // TODO(b/113612090): This are current numbers from trial and error while running videos // from YouTube at 24, 30, and 60 fps. if (mean > 14 && mean < 18) { ATRACE_INT("FPS", 60); ATRACE_INT("MediaFPS", 60); } else if (mean > 31 && mean < 34) { ATRACE_INT("FPS", 30); ATRACE_INT("MediaFPS", 30); return; } else if (mean > 39 && mean < 42) { ATRACE_INT("FPS", 24); ATRACE_INT("MediaFPS", 24); } } Loading @@ -328,13 +338,19 @@ void Scheduler::resetIdleTimer() { mIdleTimer->reset(); ATRACE_INT("ExpiredIdleTimer", 0); } std::lock_guard<std::mutex> lock(mCallbackLock); if (mResetTimerCallback) { mResetTimerCallback(); } } void Scheduler::expiredTimerCallback() { // TODO(b/113612090): Each time a timer expired, we should record the information into // a circular buffer. Once this has happened a given amount (TBD) of times, we can comfortably // say that the device is sitting in idle. std::lock_guard<std::mutex> lock(mCallbackLock); if (mExpiredTimerCallback) { mExpiredTimerCallback(); ATRACE_INT("ExpiredIdleTimer", 1); } } } // namespace android Loading
services/surfaceflinger/Scheduler/EventThread.cpp +12 −5 Original line number Diff line number Diff line Loading @@ -67,7 +67,13 @@ status_t EventThreadConnection::setVsyncRate(uint32_t count) { } void EventThreadConnection::requestNextVsync() { mEventThread->requestNextVsync(this); ATRACE_NAME("requestNextVsync"); mEventThread->requestNextVsync(this, true); } void EventThreadConnection::requestNextVsyncForHWC() { ATRACE_NAME("requestNextVsyncForHWC"); mEventThread->requestNextVsync(this, false); } status_t EventThreadConnection::postEvent(const DisplayEventReceiver::Event& event) { Loading Loading @@ -184,16 +190,17 @@ void EventThread::setVsyncRate(uint32_t count, const sp<EventThreadConnection>& } } void EventThread::requestNextVsync(const sp<EventThreadConnection>& connection) { std::lock_guard<std::mutex> lock(mMutex); if (mResetIdleTimer) { void EventThread::requestNextVsync(const sp<EventThreadConnection>& connection, bool reset) { if (mResetIdleTimer && reset) { ATRACE_NAME("resetIdleTimer"); mResetIdleTimer(); } if (mResyncWithRateLimitCallback) { mResyncWithRateLimitCallback(); } std::lock_guard<std::mutex> lock(mMutex); if (connection->count < 0) { connection->count = 0; mCondition.notify_all(); Loading
services/surfaceflinger/Scheduler/EventThread.h +11 −2 Original line number Diff line number Diff line Loading @@ -68,6 +68,9 @@ public: status_t stealReceiveChannel(gui::BitTube* outChannel) override; status_t setVsyncRate(uint32_t count) override; void requestNextVsync() override; // asynchronous // Requesting Vsync for HWC does not reset the idle timer, since HWC requires a refresh // in order to update the configs. void requestNextVsyncForHWC(); // count >= 1 : continuous event. count is the vsync rate // count == 0 : one-shot event that has not fired Loading Loading @@ -105,7 +108,9 @@ public: virtual status_t registerDisplayEventConnection( const sp<EventThreadConnection>& connection) = 0; virtual void setVsyncRate(uint32_t count, const sp<EventThreadConnection>& connection) = 0; virtual void requestNextVsync(const sp<EventThreadConnection>& connection) = 0; // Requests the next vsync. If resetIdleTimer is set to true, it resets the idle timer. virtual void requestNextVsync(const sp<EventThreadConnection>& connection, bool resetIdleTimer) = 0; }; namespace impl { Loading @@ -129,7 +134,8 @@ public: status_t registerDisplayEventConnection(const sp<EventThreadConnection>& connection) override; void setVsyncRate(uint32_t count, const sp<EventThreadConnection>& connection) override; void requestNextVsync(const sp<EventThreadConnection>& connection) override; void requestNextVsync(const sp<EventThreadConnection>& connection, bool resetIdleTimer) override; // called before the screen is turned off from main thread void onScreenReleased() override; Loading Loading @@ -166,6 +172,9 @@ private: // Implements VSyncSource::Callback void onVSyncEvent(nsecs_t timestamp) override; // Acquires mutex and requests next vsync. void requestNextVsyncInternal(const sp<EventThreadConnection>& connection) EXCLUDES(mMutex); // TODO(b/113612090): Once the Scheduler is complete this pointer will become obsolete. VSyncSource* mVSyncSource GUARDED_BY(mMutex) = nullptr; std::unique_ptr<VSyncSource> mVSyncSourceUnique GUARDED_BY(mMutex) = nullptr; Loading
services/surfaceflinger/Scheduler/MessageQueue.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -148,6 +148,10 @@ void MessageQueue::invalidate() { mEvents->requestNextVsync(); } void MessageQueue::invalidateForHWC() { mEvents->requestNextVsyncForHWC(); } void MessageQueue::refresh() { mHandler->dispatchRefresh(); } Loading
services/surfaceflinger/Scheduler/MessageQueue.h +4 −0 Original line number Diff line number Diff line Loading @@ -91,6 +91,7 @@ public: virtual void waitMessage() = 0; virtual status_t postMessage(const sp<MessageBase>& message, nsecs_t reltime = 0) = 0; virtual void invalidate() = 0; virtual void invalidateForHWC() = 0; virtual void refresh() = 0; }; Loading Loading @@ -134,6 +135,9 @@ public: // sends INVALIDATE message at next VSYNC void invalidate() override; // sends INVALIDATE message at next VSYNC, without resetting the idle timer in the Scheduler void invalidateForHWC(); // sends REFRESH message at next VSYNC void refresh() override; }; Loading
services/surfaceflinger/Scheduler/Scheduler.cpp +23 −7 Original line number Diff line number Diff line Loading @@ -238,6 +238,16 @@ void Scheduler::incrementFrameCounter() { mLayerHistory.incrementCounter(); } void Scheduler::setExpiredIdleTimerCallback(const ExpiredIdleTimerCallback& expiredTimerCallback) { std::lock_guard<std::mutex> lock(mCallbackLock); mExpiredTimerCallback = expiredTimerCallback; } void Scheduler::setResetIdleTimerCallback(const ResetIdleTimerCallback& resetTimerCallback) { std::lock_guard<std::mutex> lock(mCallbackLock); mResetTimerCallback = resetTimerCallback; } void Scheduler::updateFrameSkipping(const int64_t skipCount) { ATRACE_INT("FrameSkipCount", skipCount); if (mSkipCount != skipCount) { Loading Loading @@ -314,12 +324,12 @@ void Scheduler::determineTimestampAverage(bool isAutoTimestamp, const nsecs_t fr // TODO(b/113612090): This are current numbers from trial and error while running videos // from YouTube at 24, 30, and 60 fps. if (mean > 14 && mean < 18) { ATRACE_INT("FPS", 60); ATRACE_INT("MediaFPS", 60); } else if (mean > 31 && mean < 34) { ATRACE_INT("FPS", 30); ATRACE_INT("MediaFPS", 30); return; } else if (mean > 39 && mean < 42) { ATRACE_INT("FPS", 24); ATRACE_INT("MediaFPS", 24); } } Loading @@ -328,13 +338,19 @@ void Scheduler::resetIdleTimer() { mIdleTimer->reset(); ATRACE_INT("ExpiredIdleTimer", 0); } std::lock_guard<std::mutex> lock(mCallbackLock); if (mResetTimerCallback) { mResetTimerCallback(); } } void Scheduler::expiredTimerCallback() { // TODO(b/113612090): Each time a timer expired, we should record the information into // a circular buffer. Once this has happened a given amount (TBD) of times, we can comfortably // say that the device is sitting in idle. std::lock_guard<std::mutex> lock(mCallbackLock); if (mExpiredTimerCallback) { mExpiredTimerCallback(); ATRACE_INT("ExpiredIdleTimer", 1); } } } // namespace android