Loading libs/gui/ITransactionCompletedListener.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -111,12 +111,14 @@ JankData::JankData() status_t JankData::writeToParcel(Parcel* output) const { SAFE_PARCEL(output->writeInt64, frameVsyncId); SAFE_PARCEL(output->writeInt32, jankType); SAFE_PARCEL(output->writeInt64, frameIntervalNs); return NO_ERROR; } status_t JankData::readFromParcel(const Parcel* input) { SAFE_PARCEL(input->readInt64, &frameVsyncId); SAFE_PARCEL(input->readInt32, &jankType); SAFE_PARCEL(input->readInt64, &frameIntervalNs); return NO_ERROR; } Loading libs/gui/include/gui/ITransactionCompletedListener.h +5 −2 Original line number Diff line number Diff line Loading @@ -120,14 +120,17 @@ public: status_t readFromParcel(const Parcel* input) override; JankData(); JankData(int64_t frameVsyncId, int32_t jankType) : frameVsyncId(frameVsyncId), jankType(jankType) {} JankData(int64_t frameVsyncId, int32_t jankType, nsecs_t frameIntervalNs) : frameVsyncId(frameVsyncId), jankType(jankType), frameIntervalNs(frameIntervalNs) {} // Identifier for the frame submitted with Transaction.setFrameTimelineVsyncId int64_t frameVsyncId; // Bitmask of janks that occurred int32_t jankType; // Expected duration of the frame nsecs_t frameIntervalNs; }; class SurfaceStats : public Parcelable { Loading services/surfaceflinger/FrameTimeline/FrameTimeline.cpp +15 −5 Original line number Diff line number Diff line Loading @@ -366,6 +366,11 @@ void SurfaceFrame::setRenderRate(Fps renderRate) { mRenderRate = renderRate; } Fps SurfaceFrame::getRenderRate() const { std::lock_guard<std::mutex> lock(mMutex); return mRenderRate ? *mRenderRate : mDisplayFrameRenderRate; } void SurfaceFrame::setGpuComposition() { std::scoped_lock lock(mMutex); mGpuComposition = true; Loading Loading @@ -611,9 +616,11 @@ void SurfaceFrame::classifyJankLocked(int32_t displayFrameJankType, const Fps& r } void SurfaceFrame::onPresent(nsecs_t presentTime, int32_t displayFrameJankType, Fps refreshRate, nsecs_t displayDeadlineDelta, nsecs_t displayPresentDelta) { Fps displayFrameRenderRate, nsecs_t displayDeadlineDelta, nsecs_t displayPresentDelta) { std::scoped_lock lock(mMutex); mDisplayFrameRenderRate = displayFrameRenderRate; mActuals.presentTime = presentTime; nsecs_t deadlineDelta = 0; Loading Loading @@ -837,10 +844,11 @@ void FrameTimeline::addSurfaceFrame(std::shared_ptr<SurfaceFrame> surfaceFrame) mCurrentDisplayFrame->addSurfaceFrame(surfaceFrame); } void FrameTimeline::setSfWakeUp(int64_t token, nsecs_t wakeUpTime, Fps refreshRate) { void FrameTimeline::setSfWakeUp(int64_t token, nsecs_t wakeUpTime, Fps refreshRate, Fps renderRate) { ATRACE_CALL(); std::scoped_lock lock(mMutex); mCurrentDisplayFrame->onSfWakeUp(token, refreshRate, mCurrentDisplayFrame->onSfWakeUp(token, refreshRate, renderRate, mTokenManager.getPredictionsForToken(token), wakeUpTime); } Loading @@ -860,11 +868,12 @@ void FrameTimeline::DisplayFrame::addSurfaceFrame(std::shared_ptr<SurfaceFrame> mSurfaceFrames.push_back(surfaceFrame); } void FrameTimeline::DisplayFrame::onSfWakeUp(int64_t token, Fps refreshRate, void FrameTimeline::DisplayFrame::onSfWakeUp(int64_t token, Fps refreshRate, Fps renderRate, std::optional<TimelineItem> predictions, nsecs_t wakeUpTime) { mToken = token; mRefreshRate = refreshRate; mRenderRate = renderRate; if (!predictions) { mPredictionState = PredictionState::Expired; } else { Loading Loading @@ -1026,7 +1035,8 @@ void FrameTimeline::DisplayFrame::onPresent(nsecs_t signalTime, nsecs_t previous classifyJank(deadlineDelta, deltaToVsync, previousPresentTime); for (auto& surfaceFrame : mSurfaceFrames) { surfaceFrame->onPresent(signalTime, mJankType, mRefreshRate, deadlineDelta, deltaToVsync); surfaceFrame->onPresent(signalTime, mJankType, mRefreshRate, mRenderRate, deadlineDelta, deltaToVsync); } } Loading services/surfaceflinger/FrameTimeline/FrameTimeline.h +13 −5 Original line number Diff line number Diff line Loading @@ -183,6 +183,8 @@ public: void setDropTime(nsecs_t dropTime); void setPresentState(PresentState presentState, nsecs_t lastLatchTime = 0); void setRenderRate(Fps renderRate); // Return the render rate if it exists, otherwise returns the DisplayFrame's render rate. Fps getRenderRate() const; void setGpuComposition(); // When a bufferless SurfaceFrame is promoted to a buffer SurfaceFrame, we also have to update Loading @@ -197,7 +199,8 @@ public: // displayRefreshRate, displayDeadlineDelta, and displayPresentDelta are propagated from the // display frame. void onPresent(nsecs_t presentTime, int32_t displayFrameJankType, Fps refreshRate, nsecs_t displayDeadlineDelta, nsecs_t displayPresentDelta); Fps displayFrameRenderRate, nsecs_t displayDeadlineDelta, nsecs_t displayPresentDelta); // All the timestamps are dumped relative to the baseTime void dump(std::string& result, const std::string& indent, nsecs_t baseTime) const; // Dumps only the layer, token, is buffer, jank metadata, prediction and present states. Loading Loading @@ -251,6 +254,8 @@ private: int32_t mJankType GUARDED_BY(mMutex) = JankType::None; // Indicates if this frame was composited by the GPU or not bool mGpuComposition GUARDED_BY(mMutex) = false; // Refresh rate for this frame. Fps mDisplayFrameRenderRate GUARDED_BY(mMutex); // Rendering rate for this frame. std::optional<Fps> mRenderRate GUARDED_BY(mMutex); // Enum for the type of present Loading Loading @@ -298,7 +303,8 @@ public: // The first function called by SF for the current DisplayFrame. Fetches SF predictions based on // the token and sets the actualSfWakeTime for the current DisplayFrame. virtual void setSfWakeUp(int64_t token, nsecs_t wakeupTime, Fps refreshRate) = 0; virtual void setSfWakeUp(int64_t token, nsecs_t wakeupTime, Fps refreshRate, Fps renderRate) = 0; // Sets the sfPresentTime and finalizes the current DisplayFrame. Tracks the // given present fence until it's signaled, and updates the present timestamps of all presented Loading Loading @@ -374,8 +380,8 @@ public: // and SYSTEM_TIME_MONOTONIC. void trace(pid_t surfaceFlingerPid, nsecs_t monoBootOffset) const; // Sets the token, vsyncPeriod, predictions and SF start time. void onSfWakeUp(int64_t token, Fps refreshRate, std::optional<TimelineItem> predictions, nsecs_t wakeUpTime); void onSfWakeUp(int64_t token, Fps refreshRate, Fps renderRate, std::optional<TimelineItem> predictions, nsecs_t wakeUpTime); // Sets the appropriate metadata and classifies the jank. void onPresent(nsecs_t signalTime, nsecs_t previousPresentTime); // Adds the provided SurfaceFrame to the current display frame. Loading Loading @@ -437,6 +443,8 @@ public: // The refresh rate (vsync period) in nanoseconds as seen by SF during this DisplayFrame's // timeline Fps mRefreshRate; // The current render rate for this DisplayFrame. Fps mRenderRate; // TraceCookieCounter is used to obtain the cookie for sendig trace packets to perfetto. // Using a reference here because the counter is owned by FrameTimeline, which outlives // DisplayFrame. Loading @@ -453,7 +461,7 @@ public: int32_t layerId, std::string layerName, std::string debugName, bool isBuffer, GameMode) override; void addSurfaceFrame(std::shared_ptr<frametimeline::SurfaceFrame> surfaceFrame) override; void setSfWakeUp(int64_t token, nsecs_t wakeupTime, Fps refreshRate) override; void setSfWakeUp(int64_t token, nsecs_t wakeupTime, Fps refreshRate, Fps renderRate) override; void setSfPresent(nsecs_t sfPresentTime, const std::shared_ptr<FenceTime>& presentFence, const std::shared_ptr<FenceTime>& gpuFence = FenceTime::NO_FENCE) override; void parseArgs(const Vector<String16>& args, std::string& result) override; Loading services/surfaceflinger/Layer.cpp +3 −2 Original line number Diff line number Diff line Loading @@ -787,8 +787,9 @@ void Layer::transferAvailableJankData(const std::deque<sp<CallbackHandle>>& hand if (includeJankData) { std::shared_ptr<frametimeline::SurfaceFrame> surfaceFrame = mPendingJankClassifications.front(); jankData.emplace_back( JankData(surfaceFrame->getToken(), surfaceFrame->getJankType().value())); jankData.emplace_back(JankData(surfaceFrame->getToken(), surfaceFrame->getJankType().value(), surfaceFrame->getRenderRate().getPeriodNsecs())); } mPendingJankClassifications.pop_front(); } Loading Loading
libs/gui/ITransactionCompletedListener.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -111,12 +111,14 @@ JankData::JankData() status_t JankData::writeToParcel(Parcel* output) const { SAFE_PARCEL(output->writeInt64, frameVsyncId); SAFE_PARCEL(output->writeInt32, jankType); SAFE_PARCEL(output->writeInt64, frameIntervalNs); return NO_ERROR; } status_t JankData::readFromParcel(const Parcel* input) { SAFE_PARCEL(input->readInt64, &frameVsyncId); SAFE_PARCEL(input->readInt32, &jankType); SAFE_PARCEL(input->readInt64, &frameIntervalNs); return NO_ERROR; } Loading
libs/gui/include/gui/ITransactionCompletedListener.h +5 −2 Original line number Diff line number Diff line Loading @@ -120,14 +120,17 @@ public: status_t readFromParcel(const Parcel* input) override; JankData(); JankData(int64_t frameVsyncId, int32_t jankType) : frameVsyncId(frameVsyncId), jankType(jankType) {} JankData(int64_t frameVsyncId, int32_t jankType, nsecs_t frameIntervalNs) : frameVsyncId(frameVsyncId), jankType(jankType), frameIntervalNs(frameIntervalNs) {} // Identifier for the frame submitted with Transaction.setFrameTimelineVsyncId int64_t frameVsyncId; // Bitmask of janks that occurred int32_t jankType; // Expected duration of the frame nsecs_t frameIntervalNs; }; class SurfaceStats : public Parcelable { Loading
services/surfaceflinger/FrameTimeline/FrameTimeline.cpp +15 −5 Original line number Diff line number Diff line Loading @@ -366,6 +366,11 @@ void SurfaceFrame::setRenderRate(Fps renderRate) { mRenderRate = renderRate; } Fps SurfaceFrame::getRenderRate() const { std::lock_guard<std::mutex> lock(mMutex); return mRenderRate ? *mRenderRate : mDisplayFrameRenderRate; } void SurfaceFrame::setGpuComposition() { std::scoped_lock lock(mMutex); mGpuComposition = true; Loading Loading @@ -611,9 +616,11 @@ void SurfaceFrame::classifyJankLocked(int32_t displayFrameJankType, const Fps& r } void SurfaceFrame::onPresent(nsecs_t presentTime, int32_t displayFrameJankType, Fps refreshRate, nsecs_t displayDeadlineDelta, nsecs_t displayPresentDelta) { Fps displayFrameRenderRate, nsecs_t displayDeadlineDelta, nsecs_t displayPresentDelta) { std::scoped_lock lock(mMutex); mDisplayFrameRenderRate = displayFrameRenderRate; mActuals.presentTime = presentTime; nsecs_t deadlineDelta = 0; Loading Loading @@ -837,10 +844,11 @@ void FrameTimeline::addSurfaceFrame(std::shared_ptr<SurfaceFrame> surfaceFrame) mCurrentDisplayFrame->addSurfaceFrame(surfaceFrame); } void FrameTimeline::setSfWakeUp(int64_t token, nsecs_t wakeUpTime, Fps refreshRate) { void FrameTimeline::setSfWakeUp(int64_t token, nsecs_t wakeUpTime, Fps refreshRate, Fps renderRate) { ATRACE_CALL(); std::scoped_lock lock(mMutex); mCurrentDisplayFrame->onSfWakeUp(token, refreshRate, mCurrentDisplayFrame->onSfWakeUp(token, refreshRate, renderRate, mTokenManager.getPredictionsForToken(token), wakeUpTime); } Loading @@ -860,11 +868,12 @@ void FrameTimeline::DisplayFrame::addSurfaceFrame(std::shared_ptr<SurfaceFrame> mSurfaceFrames.push_back(surfaceFrame); } void FrameTimeline::DisplayFrame::onSfWakeUp(int64_t token, Fps refreshRate, void FrameTimeline::DisplayFrame::onSfWakeUp(int64_t token, Fps refreshRate, Fps renderRate, std::optional<TimelineItem> predictions, nsecs_t wakeUpTime) { mToken = token; mRefreshRate = refreshRate; mRenderRate = renderRate; if (!predictions) { mPredictionState = PredictionState::Expired; } else { Loading Loading @@ -1026,7 +1035,8 @@ void FrameTimeline::DisplayFrame::onPresent(nsecs_t signalTime, nsecs_t previous classifyJank(deadlineDelta, deltaToVsync, previousPresentTime); for (auto& surfaceFrame : mSurfaceFrames) { surfaceFrame->onPresent(signalTime, mJankType, mRefreshRate, deadlineDelta, deltaToVsync); surfaceFrame->onPresent(signalTime, mJankType, mRefreshRate, mRenderRate, deadlineDelta, deltaToVsync); } } Loading
services/surfaceflinger/FrameTimeline/FrameTimeline.h +13 −5 Original line number Diff line number Diff line Loading @@ -183,6 +183,8 @@ public: void setDropTime(nsecs_t dropTime); void setPresentState(PresentState presentState, nsecs_t lastLatchTime = 0); void setRenderRate(Fps renderRate); // Return the render rate if it exists, otherwise returns the DisplayFrame's render rate. Fps getRenderRate() const; void setGpuComposition(); // When a bufferless SurfaceFrame is promoted to a buffer SurfaceFrame, we also have to update Loading @@ -197,7 +199,8 @@ public: // displayRefreshRate, displayDeadlineDelta, and displayPresentDelta are propagated from the // display frame. void onPresent(nsecs_t presentTime, int32_t displayFrameJankType, Fps refreshRate, nsecs_t displayDeadlineDelta, nsecs_t displayPresentDelta); Fps displayFrameRenderRate, nsecs_t displayDeadlineDelta, nsecs_t displayPresentDelta); // All the timestamps are dumped relative to the baseTime void dump(std::string& result, const std::string& indent, nsecs_t baseTime) const; // Dumps only the layer, token, is buffer, jank metadata, prediction and present states. Loading Loading @@ -251,6 +254,8 @@ private: int32_t mJankType GUARDED_BY(mMutex) = JankType::None; // Indicates if this frame was composited by the GPU or not bool mGpuComposition GUARDED_BY(mMutex) = false; // Refresh rate for this frame. Fps mDisplayFrameRenderRate GUARDED_BY(mMutex); // Rendering rate for this frame. std::optional<Fps> mRenderRate GUARDED_BY(mMutex); // Enum for the type of present Loading Loading @@ -298,7 +303,8 @@ public: // The first function called by SF for the current DisplayFrame. Fetches SF predictions based on // the token and sets the actualSfWakeTime for the current DisplayFrame. virtual void setSfWakeUp(int64_t token, nsecs_t wakeupTime, Fps refreshRate) = 0; virtual void setSfWakeUp(int64_t token, nsecs_t wakeupTime, Fps refreshRate, Fps renderRate) = 0; // Sets the sfPresentTime and finalizes the current DisplayFrame. Tracks the // given present fence until it's signaled, and updates the present timestamps of all presented Loading Loading @@ -374,8 +380,8 @@ public: // and SYSTEM_TIME_MONOTONIC. void trace(pid_t surfaceFlingerPid, nsecs_t monoBootOffset) const; // Sets the token, vsyncPeriod, predictions and SF start time. void onSfWakeUp(int64_t token, Fps refreshRate, std::optional<TimelineItem> predictions, nsecs_t wakeUpTime); void onSfWakeUp(int64_t token, Fps refreshRate, Fps renderRate, std::optional<TimelineItem> predictions, nsecs_t wakeUpTime); // Sets the appropriate metadata and classifies the jank. void onPresent(nsecs_t signalTime, nsecs_t previousPresentTime); // Adds the provided SurfaceFrame to the current display frame. Loading Loading @@ -437,6 +443,8 @@ public: // The refresh rate (vsync period) in nanoseconds as seen by SF during this DisplayFrame's // timeline Fps mRefreshRate; // The current render rate for this DisplayFrame. Fps mRenderRate; // TraceCookieCounter is used to obtain the cookie for sendig trace packets to perfetto. // Using a reference here because the counter is owned by FrameTimeline, which outlives // DisplayFrame. Loading @@ -453,7 +461,7 @@ public: int32_t layerId, std::string layerName, std::string debugName, bool isBuffer, GameMode) override; void addSurfaceFrame(std::shared_ptr<frametimeline::SurfaceFrame> surfaceFrame) override; void setSfWakeUp(int64_t token, nsecs_t wakeupTime, Fps refreshRate) override; void setSfWakeUp(int64_t token, nsecs_t wakeupTime, Fps refreshRate, Fps renderRate) override; void setSfPresent(nsecs_t sfPresentTime, const std::shared_ptr<FenceTime>& presentFence, const std::shared_ptr<FenceTime>& gpuFence = FenceTime::NO_FENCE) override; void parseArgs(const Vector<String16>& args, std::string& result) override; Loading
services/surfaceflinger/Layer.cpp +3 −2 Original line number Diff line number Diff line Loading @@ -787,8 +787,9 @@ void Layer::transferAvailableJankData(const std::deque<sp<CallbackHandle>>& hand if (includeJankData) { std::shared_ptr<frametimeline::SurfaceFrame> surfaceFrame = mPendingJankClassifications.front(); jankData.emplace_back( JankData(surfaceFrame->getToken(), surfaceFrame->getJankType().value())); jankData.emplace_back(JankData(surfaceFrame->getToken(), surfaceFrame->getJankType().value(), surfaceFrame->getRenderRate().getPeriodNsecs())); } mPendingJankClassifications.pop_front(); } Loading