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

Commit ac7bcd98 authored by Pascal Muetschard's avatar Pascal Muetschard
Browse files

Include the frame's expected duration in the jank data.

Bug: b/261839034
Test: atest libsurfaceflinger_unittest
Change-Id: I65c85be8825e36671612a47000261c04f0289551
parent 102d39db
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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;
}

+5 −2
Original line number Diff line number Diff line
@@ -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 {
+15 −5
Original line number Diff line number Diff line
@@ -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;
@@ -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;

@@ -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);
}

@@ -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 {
@@ -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);
    }
}

+13 −5
Original line number Diff line number Diff line
@@ -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
@@ -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.
@@ -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
@@ -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
@@ -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.
@@ -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.
@@ -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;
+3 −2
Original line number Diff line number Diff line
@@ -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