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

Commit 34921ac1 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Teach JankTracker about new swap behaviors" into nyc-mr1-dev

parents 66e7752a 2d5b8d73
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -113,6 +113,10 @@ hwui_cflags := \
    -DATRACE_TAG=ATRACE_TAG_VIEW -DLOG_TAG=\"OpenGLRenderer\" \
    -Wall -Wno-unused-parameter -Wunreachable-code -Werror

ifeq ($(TARGET_USES_HWC2),true)
    hwui_cflags += -DUSE_HWC2
endif

# GCC false-positives on this warning, and since we -Werror that's
# a problem
hwui_cflags += -Wno-free-nonheap-object
+6 −0
Original line number Diff line number Diff line
@@ -35,8 +35,14 @@ const std::string FrameInfoNames[] = {
    "IssueDrawCommandsStart",
    "SwapBuffers",
    "FrameCompleted",
    "DequeueBufferDuration",
    "QueueBufferDuration",
};

static_assert((sizeof(FrameInfoNames)/sizeof(FrameInfoNames[0]))
        == static_cast<int>(FrameInfoIndex::NumIndexes),
        "size mismatch: FrameInfoNames doesn't match the enum!");

void FrameInfo::importUiThreadInfo(int64_t* info) {
    memcpy(mFrameInfo, info, UI_THREAD_FRAME_INFO_SIZE * sizeof(int64_t));
}
+3 −0
Original line number Diff line number Diff line
@@ -48,6 +48,9 @@ enum class FrameInfoIndex {
    SwapBuffers,
    FrameCompleted,

    DequeueBufferDuration,
    QueueBufferDuration,

    // Must be the last value!
    NumIndexes
};
+31 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#include "JankTracker.h"

#include "Properties.h"
#include "utils/TimeUtils.h"

#include <algorithm>
#include <cutils/ashmem.h>
@@ -119,11 +120,27 @@ static uint32_t frameTimeForFrameCountIndex(uint32_t index) {
    return index;
}

JankTracker::JankTracker(nsecs_t frameIntervalNanos) {
JankTracker::JankTracker(const DisplayInfo& displayInfo) {
    // By default this will use malloc memory. It may be moved later to ashmem
    // if there is shared space for it and a request comes in to do that.
    mData = new ProfileData;
    reset();
    nsecs_t frameIntervalNanos = static_cast<nsecs_t>(1_s / displayInfo.fps);
#if USE_HWC2
    nsecs_t sfOffset = frameIntervalNanos - (displayInfo.presentationDeadline - 1_ms);
    nsecs_t offsetDelta = sfOffset - displayInfo.appVsyncOffset;
    // There are two different offset cases. If the offsetDelta is positive
    // and small, then the intention is to give apps extra time by leveraging
    // pipelining between the UI & RT threads. If the offsetDelta is large or
    // negative, the intention is to subtract time from the total duration
    // in which case we can't afford to wait for dequeueBuffer blockage.
    if (offsetDelta <= 4_ms && offsetDelta >= 0) {
        // SF will begin composition at VSYNC-app + offsetDelta. If we are triple
        // buffered, this is the expected time at which dequeueBuffer will
        // return due to the staggering of VSYNC-app & VSYNC-sf.
        mDequeueTimeForgiveness = offsetDelta + 4_ms;
    }
#endif
    setFrameInterval(frameIntervalNanos);
}

@@ -213,6 +230,19 @@ void JankTracker::addFrame(const FrameInfo& frame) {
    mData->totalFrameCount++;
    // Fast-path for jank-free frames
    int64_t totalDuration = frame.duration(sFrameStart, FrameInfoIndex::FrameCompleted);
    if (mDequeueTimeForgiveness
            && frame[FrameInfoIndex::DequeueBufferDuration] > 500_us) {
        nsecs_t expectedDequeueDuration =
                mDequeueTimeForgiveness + frame[FrameInfoIndex::Vsync]
                - frame[FrameInfoIndex::IssueDrawCommandsStart];
        if (expectedDequeueDuration > 0) {
            // Forgive only up to the expected amount, but not more than
            // the actual time spent blocked.
            nsecs_t forgiveAmount = std::min(expectedDequeueDuration,
                    frame[FrameInfoIndex::DequeueBufferDuration]);
            totalDuration -= forgiveAmount;
        }
    }
    uint32_t framebucket = frameCountIndexForFrameTime(totalDuration);
    // Keep the fast path as fast as possible.
    if (CC_LIKELY(totalDuration < mFrameInterval)) {
+10 −1
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include "utils/RingBuffer.h"

#include <cutils/compiler.h>
#include <ui/DisplayInfo.h>

#include <array>
#include <memory>
@@ -56,7 +57,7 @@ struct ProfileData {
// TODO: Replace DrawProfiler with this
class JankTracker {
public:
    JankTracker(nsecs_t frameIntervalNanos);
    JankTracker(const DisplayInfo& displayInfo);
    ~JankTracker();

    void addFrame(const FrameInfo& frame);
@@ -79,6 +80,14 @@ private:

    std::array<int64_t, NUM_BUCKETS> mThresholds;
    int64_t mFrameInterval;
    // The amount of time we will erase from the total duration to account
    // for SF vsync offsets with HWC2 blocking dequeueBuffers.
    // (Vsync + mDequeueBlockTolerance) is the point at which we expect
    // SF to have released the buffer normally, so we will forgive up to that
    // point in time by comparing to (IssueDrawCommandsStart + DequeueDuration)
    // This is only used if we are in pipelined mode and are using HWC2,
    // otherwise it's 0.
    nsecs_t mDequeueTimeForgiveness = 0;
    ProfileData* mData;
    bool mIsMapped = false;
};
Loading