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

Commit 695cb245 authored by Ady Abraham's avatar Ady Abraham Committed by Android (Google) Code Review
Browse files

Merge "SF: Add setFrameRate vote to TimeStats" into sc-dev

parents 028d91e3 8b9e612e
Loading
Loading
Loading
Loading
+37 −2
Original line number Original line Diff line number Diff line
@@ -329,6 +329,37 @@ bool BufferLayer::onPreComposition(nsecs_t refreshStartTime) {
    mRefreshPending = false;
    mRefreshPending = false;
    return hasReadyFrame();
    return hasReadyFrame();
}
}
namespace {
TimeStats::SetFrameRateVote frameRateToSetFrameRateVotePayload(Layer::FrameRate frameRate) {
    using FrameRateCompatibility = TimeStats::SetFrameRateVote::FrameRateCompatibility;
    using Seamlessness = TimeStats::SetFrameRateVote::Seamlessness;
    const auto frameRateCompatibility = [frameRate] {
        switch (frameRate.type) {
            case Layer::FrameRateCompatibility::Default:
                return FrameRateCompatibility::Default;
            case Layer::FrameRateCompatibility::ExactOrMultiple:
                return FrameRateCompatibility::ExactOrMultiple;
            default:
                return FrameRateCompatibility::Undefined;
        }
    }();

    const auto seamlessness = [frameRate] {
        switch (frameRate.seamlessness) {
            case scheduler::Seamlessness::OnlySeamless:
                return Seamlessness::ShouldBeSeamless;
            case scheduler::Seamlessness::SeamedAndSeamless:
                return Seamlessness::NotRequired;
            default:
                return Seamlessness::Undefined;
        }
    }();

    return TimeStats::SetFrameRateVote{.frameRate = frameRate.rate.getValue(),
                                       .frameRateCompatibility = frameRateCompatibility,
                                       .seamlessness = seamlessness};
}
} // namespace


bool BufferLayer::onPostComposition(const DisplayDevice* display,
bool BufferLayer::onPostComposition(const DisplayDevice* display,
                                    const std::shared_ptr<FenceTime>& glDoneFence,
                                    const std::shared_ptr<FenceTime>& glDoneFence,
@@ -381,7 +412,9 @@ bool BufferLayer::onPostComposition(const DisplayDevice* display,
    const std::optional<Fps> renderRate = mFlinger->mScheduler->getFrameRateOverride(getOwnerUid());
    const std::optional<Fps> renderRate = mFlinger->mScheduler->getFrameRateOverride(getOwnerUid());
    if (presentFence->isValid()) {
    if (presentFence->isValid()) {
        mFlinger->mTimeStats->setPresentFence(layerId, mCurrentFrameNumber, presentFence,
        mFlinger->mTimeStats->setPresentFence(layerId, mCurrentFrameNumber, presentFence,
                                              refreshRate, renderRate);
                                              refreshRate, renderRate,
                                              frameRateToSetFrameRateVotePayload(
                                                      mDrawingState.frameRate));
        mFlinger->mFrameTracer->traceFence(layerId, getCurrentBufferId(), mCurrentFrameNumber,
        mFlinger->mFrameTracer->traceFence(layerId, getCurrentBufferId(), mCurrentFrameNumber,
                                           presentFence, FrameTracer::FrameEvent::PRESENT_FENCE);
                                           presentFence, FrameTracer::FrameEvent::PRESENT_FENCE);
        mFrameTracker.setActualPresentFence(std::shared_ptr<FenceTime>(presentFence));
        mFrameTracker.setActualPresentFence(std::shared_ptr<FenceTime>(presentFence));
@@ -393,7 +426,9 @@ bool BufferLayer::onPostComposition(const DisplayDevice* display,
        // timestamp instead.
        // timestamp instead.
        const nsecs_t actualPresentTime = display->getRefreshTimestamp();
        const nsecs_t actualPresentTime = display->getRefreshTimestamp();
        mFlinger->mTimeStats->setPresentTime(layerId, mCurrentFrameNumber, actualPresentTime,
        mFlinger->mTimeStats->setPresentTime(layerId, mCurrentFrameNumber, actualPresentTime,
                                             refreshRate, renderRate);
                                             refreshRate, renderRate,
                                             frameRateToSetFrameRateVotePayload(
                                                     mDrawingState.frameRate));
        mFlinger->mFrameTracer->traceTimestamp(layerId, getCurrentBufferId(), mCurrentFrameNumber,
        mFlinger->mFrameTracer->traceTimestamp(layerId, getCurrentBufferId(), mCurrentFrameNumber,
                                               actualPresentTime,
                                               actualPresentTime,
                                               FrameTracer::FrameEvent::PRESENT_FENCE);
                                               FrameTracer::FrameEvent::PRESENT_FENCE);
+23 −10
Original line number Original line Diff line number Diff line
@@ -89,12 +89,15 @@ std::string histogramToProtoByteString(const std::unordered_map<int32_t, int32_t
    return byteString;
    return byteString;
}
}


std::string frameRateVoteToProtoByteString(float refreshRate, int frameRateCompatibility,
std::string frameRateVoteToProtoByteString(
                                           int seamlessness) {
        float refreshRate,
        TimeStats::SetFrameRateVote::FrameRateCompatibility frameRateCompatibility,
        TimeStats::SetFrameRateVote::Seamlessness seamlessness) {
    util::ProtoOutputStream proto;
    util::ProtoOutputStream proto;
    proto.write(android::util::FIELD_TYPE_FLOAT | 1 /* field id */, refreshRate);
    proto.write(android::util::FIELD_TYPE_FLOAT | 1 /* field id */, refreshRate);
    proto.write(android::util::FIELD_TYPE_ENUM | 2 /* field id */, frameRateCompatibility);
    proto.write(android::util::FIELD_TYPE_ENUM | 2 /* field id */,
    proto.write(android::util::FIELD_TYPE_ENUM | 3 /* field id */, seamlessness);
                static_cast<int>(frameRateCompatibility));
    proto.write(android::util::FIELD_TYPE_ENUM | 3 /* field id */, static_cast<int>(seamlessness));


    std::string byteString;
    std::string byteString;
    proto.serializeToString(&byteString);
    proto.serializeToString(&byteString);
@@ -229,7 +232,10 @@ AStatsManager_PullAtomCallbackReturn TimeStats::populateLayerAtom(AStatsEventLis
        mStatsDelegate->statsEventWriteInt32(
        mStatsDelegate->statsEventWriteInt32(
                event, layer->displayRefreshRateBucket); // display_refresh_rate_bucket
                event, layer->displayRefreshRateBucket); // display_refresh_rate_bucket
        mStatsDelegate->statsEventWriteInt32(event, layer->renderRateBucket); // render_rate_bucket
        mStatsDelegate->statsEventWriteInt32(event, layer->renderRateBucket); // render_rate_bucket
        std::string frameRateVoteBytes = frameRateVoteToProtoByteString(0.0, 0, 0);
        std::string frameRateVoteBytes =
                frameRateVoteToProtoByteString(layer->setFrameRateVote.frameRate,
                                               layer->setFrameRateVote.frameRateCompatibility,
                                               layer->setFrameRateVote.seamlessness);
        mStatsDelegate->statsEventWriteByteArray(event, (const uint8_t*)frameRateVoteBytes.c_str(),
        mStatsDelegate->statsEventWriteByteArray(event, (const uint8_t*)frameRateVoteBytes.c_str(),
                                                 frameRateVoteBytes.size()); // set_frame_rate_vote
                                                 frameRateVoteBytes.size()); // set_frame_rate_vote
        std::string appDeadlineMissedBytes =
        std::string appDeadlineMissedBytes =
@@ -468,8 +474,10 @@ static int32_t clampToSmallestBucket(Fps fps, size_t bucketWidth) {
}
}


void TimeStats::flushAvailableRecordsToStatsLocked(int32_t layerId, Fps displayRefreshRate,
void TimeStats::flushAvailableRecordsToStatsLocked(int32_t layerId, Fps displayRefreshRate,
                                                   std::optional<Fps> renderRate) {
                                                   std::optional<Fps> renderRate,
                                                   SetFrameRateVote frameRateVote) {
    ATRACE_CALL();
    ATRACE_CALL();
    ALOGV("[%d]-flushAvailableRecordsToStatsLocked", layerId);


    LayerRecord& layerRecord = mTimeStatsTracker[layerId];
    LayerRecord& layerRecord = mTimeStatsTracker[layerId];
    TimeRecord& prevTimeRecord = layerRecord.prevTimeRecord;
    TimeRecord& prevTimeRecord = layerRecord.prevTimeRecord;
@@ -501,6 +509,9 @@ void TimeStats::flushAvailableRecordsToStatsLocked(int32_t layerId, Fps displayR
                displayStats.stats[layerKey].uid = uid;
                displayStats.stats[layerKey].uid = uid;
                displayStats.stats[layerKey].layerName = layerName;
                displayStats.stats[layerKey].layerName = layerName;
            }
            }
            if (frameRateVote.frameRate > 0.0f) {
                displayStats.stats[layerKey].setFrameRateVote = frameRateVote;
            }
            TimeStatsHelper::TimeStatsLayer& timeStatsLayer = displayStats.stats[layerKey];
            TimeStatsHelper::TimeStatsLayer& timeStatsLayer = displayStats.stats[layerKey];
            timeStatsLayer.totalFrames++;
            timeStatsLayer.totalFrames++;
            timeStatsLayer.droppedFrames += layerRecord.droppedFrames;
            timeStatsLayer.droppedFrames += layerRecord.droppedFrames;
@@ -724,7 +735,8 @@ void TimeStats::setAcquireFence(int32_t layerId, uint64_t frameNumber,
}
}


void TimeStats::setPresentTime(int32_t layerId, uint64_t frameNumber, nsecs_t presentTime,
void TimeStats::setPresentTime(int32_t layerId, uint64_t frameNumber, nsecs_t presentTime,
                               Fps displayRefreshRate, std::optional<Fps> renderRate) {
                               Fps displayRefreshRate, std::optional<Fps> renderRate,
                               SetFrameRateVote frameRateVote) {
    if (!mEnabled.load()) return;
    if (!mEnabled.load()) return;


    ATRACE_CALL();
    ATRACE_CALL();
@@ -743,12 +755,13 @@ void TimeStats::setPresentTime(int32_t layerId, uint64_t frameNumber, nsecs_t pr
        layerRecord.waitData++;
        layerRecord.waitData++;
    }
    }


    flushAvailableRecordsToStatsLocked(layerId, displayRefreshRate, renderRate);
    flushAvailableRecordsToStatsLocked(layerId, displayRefreshRate, renderRate, frameRateVote);
}
}


void TimeStats::setPresentFence(int32_t layerId, uint64_t frameNumber,
void TimeStats::setPresentFence(int32_t layerId, uint64_t frameNumber,
                                const std::shared_ptr<FenceTime>& presentFence,
                                const std::shared_ptr<FenceTime>& presentFence,
                                Fps displayRefreshRate, std::optional<Fps> renderRate) {
                                Fps displayRefreshRate, std::optional<Fps> renderRate,
                                SetFrameRateVote frameRateVote) {
    if (!mEnabled.load()) return;
    if (!mEnabled.load()) return;


    ATRACE_CALL();
    ATRACE_CALL();
@@ -768,7 +781,7 @@ void TimeStats::setPresentFence(int32_t layerId, uint64_t frameNumber,
        layerRecord.waitData++;
        layerRecord.waitData++;
    }
    }


    flushAvailableRecordsToStatsLocked(layerId, displayRefreshRate, renderRate);
    flushAvailableRecordsToStatsLocked(layerId, displayRefreshRate, renderRate, frameRateVote);
}
}


static const constexpr int32_t kValidJankyReason = JankType::DisplayHAL |
static const constexpr int32_t kValidJankyReason = JankType::DisplayHAL |
+11 −5
Original line number Original line Diff line number Diff line
@@ -50,6 +50,8 @@ namespace android {


class TimeStats {
class TimeStats {
public:
public:
    using SetFrameRateVote = TimeStatsHelper::SetFrameRateVote;

    virtual ~TimeStats() = default;
    virtual ~TimeStats() = default;


    // Called once boot has been finished to perform additional capabilities,
    // Called once boot has been finished to perform additional capabilities,
@@ -110,10 +112,12 @@ public:
    // SetPresent{Time, Fence} are not expected to be called in the critical
    // SetPresent{Time, Fence} are not expected to be called in the critical
    // rendering path, as they flush prior fences if those fences have fired.
    // rendering path, as they flush prior fences if those fences have fired.
    virtual void setPresentTime(int32_t layerId, uint64_t frameNumber, nsecs_t presentTime,
    virtual void setPresentTime(int32_t layerId, uint64_t frameNumber, nsecs_t presentTime,
                                Fps displayRefreshRate, std::optional<Fps> renderRate) = 0;
                                Fps displayRefreshRate, std::optional<Fps> renderRate,
                                SetFrameRateVote frameRateVote) = 0;
    virtual void setPresentFence(int32_t layerId, uint64_t frameNumber,
    virtual void setPresentFence(int32_t layerId, uint64_t frameNumber,
                                 const std::shared_ptr<FenceTime>& presentFence,
                                 const std::shared_ptr<FenceTime>& presentFence,
                                 Fps displayRefreshRate, std::optional<Fps> renderRate) = 0;
                                 Fps displayRefreshRate, std::optional<Fps> renderRate,
                                 SetFrameRateVote frameRateVote) = 0;


    // Increments janky frames, blamed to the provided {refreshRate, renderRate, uid, layerName}
    // Increments janky frames, blamed to the provided {refreshRate, renderRate, uid, layerName}
    // key, with JankMetadata as supplementary reasons for the jank. Because FrameTimeline is the
    // key, with JankMetadata as supplementary reasons for the jank. Because FrameTimeline is the
@@ -307,10 +311,11 @@ public:
    void setAcquireFence(int32_t layerId, uint64_t frameNumber,
    void setAcquireFence(int32_t layerId, uint64_t frameNumber,
                         const std::shared_ptr<FenceTime>& acquireFence) override;
                         const std::shared_ptr<FenceTime>& acquireFence) override;
    void setPresentTime(int32_t layerId, uint64_t frameNumber, nsecs_t presentTime,
    void setPresentTime(int32_t layerId, uint64_t frameNumber, nsecs_t presentTime,
                        Fps displayRefreshRate, std::optional<Fps> renderRate) override;
                        Fps displayRefreshRate, std::optional<Fps> renderRate,
                        SetFrameRateVote frameRateVote) override;
    void setPresentFence(int32_t layerId, uint64_t frameNumber,
    void setPresentFence(int32_t layerId, uint64_t frameNumber,
                         const std::shared_ptr<FenceTime>& presentFence, Fps displayRefreshRate,
                         const std::shared_ptr<FenceTime>& presentFence, Fps displayRefreshRate,
                         std::optional<Fps> renderRate) override;
                         std::optional<Fps> renderRate, SetFrameRateVote frameRateVote) override;


    void incrementJankyFrames(const JankyFramesInfo& info) override;
    void incrementJankyFrames(const JankyFramesInfo& info) override;
    // Clean up the layer record
    // Clean up the layer record
@@ -334,7 +339,8 @@ private:
    AStatsManager_PullAtomCallbackReturn populateLayerAtom(AStatsEventList* data);
    AStatsManager_PullAtomCallbackReturn populateLayerAtom(AStatsEventList* data);
    bool recordReadyLocked(int32_t layerId, TimeRecord* timeRecord);
    bool recordReadyLocked(int32_t layerId, TimeRecord* timeRecord);
    void flushAvailableRecordsToStatsLocked(int32_t layerId, Fps displayRefreshRate,
    void flushAvailableRecordsToStatsLocked(int32_t layerId, Fps displayRefreshRate,
                                            std::optional<Fps> renderRate);
                                            std::optional<Fps> renderRate,
                                            SetFrameRateVote frameRateVote);
    void flushPowerTimeLocked();
    void flushPowerTimeLocked();
    void flushAvailableGlobalRecordsToStatsLocked();
    void flushAvailableGlobalRecordsToStatsLocked();
    bool canAddNewAggregatedStats(uid_t uid, const std::string& layerName);
    bool canAddNewAggregatedStats(uid_t uid, const std::string& layerName);
+33 −0
Original line number Original line Diff line number Diff line
@@ -91,6 +91,37 @@ std::string TimeStatsHelper::JankPayload::toString() const {
    return result;
    return result;
}
}


std::string TimeStatsHelper::SetFrameRateVote::toString(FrameRateCompatibility compatibility) {
    switch (compatibility) {
        case FrameRateCompatibility::Undefined:
            return "Undefined";
        case FrameRateCompatibility::Default:
            return "Default";
        case FrameRateCompatibility::ExactOrMultiple:
            return "ExactOrMultiple";
    }
}

std::string TimeStatsHelper::SetFrameRateVote::toString(Seamlessness seamlessness) {
    switch (seamlessness) {
        case Seamlessness::Undefined:
            return "Undefined";
        case Seamlessness::ShouldBeSeamless:
            return "ShouldBeSeamless";
        case Seamlessness::NotRequired:
            return "NotRequired";
    }
}

std::string TimeStatsHelper::SetFrameRateVote::toString() const {
    std::string result;
    StringAppendF(&result, "frameRate = %.2f\n", frameRate);
    StringAppendF(&result, "frameRateCompatibility = %s\n",
                  toString(frameRateCompatibility).c_str());
    StringAppendF(&result, "seamlessness = %s\n", toString(seamlessness).c_str());
    return result;
}

std::string TimeStatsHelper::TimeStatsLayer::toString() const {
std::string TimeStatsHelper::TimeStatsLayer::toString() const {
    std::string result = "\n";
    std::string result = "\n";
    StringAppendF(&result, "displayRefreshRate = %d fps\n", displayRefreshRateBucket);
    StringAppendF(&result, "displayRefreshRate = %d fps\n", displayRefreshRateBucket);
@@ -104,6 +135,8 @@ std::string TimeStatsHelper::TimeStatsLayer::toString() const {
    StringAppendF(&result, "badDesiredPresentFrames = %d\n", badDesiredPresentFrames);
    StringAppendF(&result, "badDesiredPresentFrames = %d\n", badDesiredPresentFrames);
    result.append("Jank payload for this layer:\n");
    result.append("Jank payload for this layer:\n");
    result.append(jankPayload.toString());
    result.append(jankPayload.toString());
    result.append("SetFrateRate vote for this layer:\n");
    result.append(setFrameRateVote.toString());
    const auto iter = deltas.find("present2present");
    const auto iter = deltas.find("present2present");
    if (iter != deltas.end()) {
    if (iter != deltas.end()) {
        const float averageTime = iter->second.averageTime();
        const float averageTime = iter->second.averageTime();
+23 −0
Original line number Original line Diff line number Diff line
@@ -55,6 +55,28 @@ public:
        std::string toString() const;
        std::string toString() const;
    };
    };


    struct SetFrameRateVote {
        float frameRate = 0;

        // Needs to be in sync with atoms.proto
        enum class FrameRateCompatibility {
            Undefined = 0,
            Default = 1,
            ExactOrMultiple = 2,
        } frameRateCompatibility = FrameRateCompatibility::Undefined;

        // Needs to be in sync with atoms.proto
        enum class Seamlessness {
            Undefined = 0,
            ShouldBeSeamless = 1,
            NotRequired = 2,
        } seamlessness = Seamlessness::Undefined;

        static std::string toString(FrameRateCompatibility);
        static std::string toString(Seamlessness);
        std::string toString() const;
    };

    class TimeStatsLayer {
    class TimeStatsLayer {
    public:
    public:
        uid_t uid;
        uid_t uid;
@@ -67,6 +89,7 @@ public:
        int32_t lateAcquireFrames = 0;
        int32_t lateAcquireFrames = 0;
        int32_t badDesiredPresentFrames = 0;
        int32_t badDesiredPresentFrames = 0;
        JankPayload jankPayload;
        JankPayload jankPayload;
        SetFrameRateVote setFrameRateVote;
        std::unordered_map<std::string, Histogram> deltas;
        std::unordered_map<std::string, Histogram> deltas;


        std::string toString() const;
        std::string toString() const;
Loading