/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "JankTracker.h"

#include <algorithm>
#include <cstdio>
#include <inttypes.h>

namespace android {
namespace uirenderer {

static const char* JANK_TYPE_NAMES[] = {
        "Missed Vsync",
        "High input latency",
        "Slow UI thread",
        "Slow bitmap uploads",
        "Slow draw",
};

struct Comparison {
    FrameInfoIndex start;
    FrameInfoIndex end;
};

static const Comparison COMPARISONS[] = {
        {FrameInfoIndex::kIntendedVsync, FrameInfoIndex::kVsync},
        {FrameInfoIndex::kOldestInputEvent, FrameInfoIndex::kVsync},
        {FrameInfoIndex::kVsync, FrameInfoIndex::kSyncStart},
        {FrameInfoIndex::kSyncStart, FrameInfoIndex::kIssueDrawCommandsStart},
        {FrameInfoIndex::kIssueDrawCommandsStart, FrameInfoIndex::kFrameCompleted},
};

// If the event exceeds 10 seconds throw it away, this isn't a jank event
// it's an ANR and will be handled as such
static const int64_t IGNORE_EXCEEDING = seconds_to_nanoseconds(10);

/*
 * Frames that are exempt from jank metrics.
 * First-draw frames, for example, are expected to
 * be slow, this is hidden from the user with window animations and
 * other tricks
 *
 * Similarly, we don't track direct-drawing via Surface:lockHardwareCanvas()
 * for now
 *
 * TODO: kSurfaceCanvas can negatively impact other drawing by using up
 * time on the RenderThread, figure out how to attribute that as a jank-causer
 */
static const int64_t EXEMPT_FRAMES_FLAGS
        = FrameInfoFlags::kWindowLayoutChanged
        | FrameInfoFlags::kSurfaceCanvas;

JankTracker::JankTracker(nsecs_t frameIntervalNanos) {
    reset();
    setFrameInterval(frameIntervalNanos);
}

void JankTracker::setFrameInterval(nsecs_t frameInterval) {
    mFrameInterval = frameInterval;
    mThresholds[kMissedVsync] = 1;
    /*
     * Due to interpolation and sample rate differences between the touch
     * panel and the display (example, 85hz touch panel driving a 60hz display)
     * we call high latency 1.5 * frameinterval
     *
     * NOTE: Be careful when tuning this! A theoretical 1,000hz touch panel
     * on a 60hz display will show kOldestInputEvent - kIntendedVsync of being 15ms
     * Thus this must always be larger than frameInterval, or it will fail
     */
    mThresholds[kHighInputLatency] = static_cast<int64_t>(1.5 * frameInterval);

    // Note that these do not add up to 1. This is intentional. It's to deal
    // with variance in values, and should be sort of an upper-bound on what
    // is reasonable to expect.
    mThresholds[kSlowUI] = static_cast<int64_t>(.5 * frameInterval);
    mThresholds[kSlowSync] = static_cast<int64_t>(.2 * frameInterval);
    mThresholds[kSlowRT] = static_cast<int64_t>(.75 * frameInterval);

}

void JankTracker::addFrame(const FrameInfo& frame) {
    mTotalFrameCount++;
    // Fast-path for jank-free frames
    int64_t totalDuration =
            frame[FrameInfoIndex::kFrameCompleted] - frame[FrameInfoIndex::kIntendedVsync];
    uint32_t framebucket = std::min(
            static_cast<typeof sizeof(mFrameCounts)>(ns2ms(totalDuration)),
            sizeof(mFrameCounts) / sizeof(mFrameCounts[0]));
    // Keep the fast path as fast as possible.
    if (CC_LIKELY(totalDuration < mFrameInterval)) {
        mFrameCounts[framebucket]++;
        return;
    }

    if (frame[FrameInfoIndex::kFlags] & EXEMPT_FRAMES_FLAGS) {
        return;
    }

    mFrameCounts[framebucket]++;
    mJankFrameCount++;

    for (int i = 0; i < NUM_BUCKETS; i++) {
        int64_t delta = frame[COMPARISONS[i].end] - frame[COMPARISONS[i].start];
        if (delta >= mThresholds[i] && delta < IGNORE_EXCEEDING) {
            mBuckets[i].count++;
        }
    }
}

void JankTracker::dump(int fd) {
    FILE* file = fdopen(fd, "a");
    fprintf(file, "\nFrame stats:");
    fprintf(file, "\n  Total frames rendered: %u", mTotalFrameCount);
    fprintf(file, "\n  Janky frames: %u (%.2f%%)", mJankFrameCount,
            (float) mJankFrameCount / (float) mTotalFrameCount * 100.0f);
    fprintf(file, "\n  90th percentile: %ums", findPercentile(90));
    fprintf(file, "\n  95th percentile: %ums", findPercentile(95));
    fprintf(file, "\n  99th percentile: %ums", findPercentile(99));
    for (int i = 0; i < NUM_BUCKETS; i++) {
        fprintf(file, "\n   Number %s: %u", JANK_TYPE_NAMES[i], mBuckets[i].count);
    }
    fprintf(file, "\n");
    fflush(file);
}

void JankTracker::reset() {
    memset(mBuckets, 0, sizeof(mBuckets));
    memset(mFrameCounts, 0, sizeof(mFrameCounts));
    mTotalFrameCount = 0;
    mJankFrameCount = 0;
}

uint32_t JankTracker::findPercentile(int percentile) {
    int pos = percentile * mTotalFrameCount / 100;
    int remaining = mTotalFrameCount - pos;
    for (int i = sizeof(mFrameCounts) / sizeof(mFrameCounts[0]) - 1; i >= 0; i--) {
        remaining -= mFrameCounts[i];
        if (remaining <= 0) {
            return i;
        }
    }
    return 0;
}

} /* namespace uirenderer */
} /* namespace android */
