/*
 * Copyright (C) 2014 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 "FrameInfoVisualizer.h"

#include "IProfileRenderer.h"
#include "utils/Color.h"
#include "utils/TimeUtils.h"

#include <cutils/compiler.h>
#include <array>

#define RETURN_IF_PROFILING_DISABLED() \
    if (CC_LIKELY(mType == ProfileType::None)) return
#define RETURN_IF_DISABLED() \
    if (CC_LIKELY(mType == ProfileType::None && !mShowDirtyRegions)) return

namespace android {
namespace uirenderer {

static constexpr auto PROFILE_DRAW_THRESHOLD_STROKE_WIDTH = 2;
static constexpr auto PROFILE_DRAW_DP_PER_MS = 7;

struct Threshold {
    SkColor color;
    float percentFrametime;
};

static constexpr std::array<Threshold, 3> THRESHOLDS{
        Threshold{.color = Color::Green_500, .percentFrametime = 0.8f},
        Threshold{.color = Color::Lime_500, .percentFrametime = 1.0f},
        Threshold{.color = Color::Red_500, .percentFrametime = 1.5f},
};
static constexpr SkColor BAR_FAST_MASK = 0x8FFFFFFF;
static constexpr SkColor BAR_JANKY_MASK = 0xDFFFFFFF;

struct BarSegment {
    FrameInfoIndex start;
    FrameInfoIndex end;
    SkColor color;
};

static const std::array<BarSegment, 7> Bar{{
        {FrameInfoIndex::IntendedVsync, FrameInfoIndex::HandleInputStart, Color::Teal_700},
        {FrameInfoIndex::HandleInputStart, FrameInfoIndex::PerformTraversalsStart,
         Color::Green_700},
        {FrameInfoIndex::PerformTraversalsStart, FrameInfoIndex::DrawStart, Color::LightGreen_700},
        {FrameInfoIndex::DrawStart, FrameInfoIndex::SyncStart, Color::Blue_500},
        {FrameInfoIndex::SyncStart, FrameInfoIndex::IssueDrawCommandsStart, Color::LightBlue_300},
        {FrameInfoIndex::IssueDrawCommandsStart, FrameInfoIndex::SwapBuffers, Color::Red_500},
        {FrameInfoIndex::SwapBuffers, FrameInfoIndex::FrameCompleted, Color::Orange_500},
}};

static int dpToPx(int dp, float density) {
    return (int)(dp * density + 0.5f);
}

FrameInfoVisualizer::FrameInfoVisualizer(FrameInfoSource& source, nsecs_t frameInterval)
        : mFrameSource(source), mFrameInterval(frameInterval) {
    setDensity(1);
    consumeProperties();
}

FrameInfoVisualizer::~FrameInfoVisualizer() {
    destroyData();
}

void FrameInfoVisualizer::setDensity(float density) {
    if (CC_UNLIKELY(mDensity != density)) {
        mDensity = density;
        // We want the vertical units to scale height relative to a baseline 16ms.
        // This keeps the threshold lines consistent across varying refresh rates
        mVerticalUnit = static_cast<int>(dpToPx(PROFILE_DRAW_DP_PER_MS, density) * (float)16_ms /
                                         (float)mFrameInterval);
        mThresholdStroke = dpToPx(PROFILE_DRAW_THRESHOLD_STROKE_WIDTH, density);
    }
}

void FrameInfoVisualizer::unionDirty(SkRect* dirty) {
    RETURN_IF_DISABLED();
    // Not worth worrying about minimizing the dirty region for debugging, so just
    // dirty the entire viewport.
    if (dirty) {
        mDirtyRegion = *dirty;
        dirty->setEmpty();
    }
}

void FrameInfoVisualizer::draw(IProfileRenderer& renderer) {
    RETURN_IF_DISABLED();

    if (mShowDirtyRegions) {
        mFlashToggle = !mFlashToggle;
        if (mFlashToggle) {
            SkPaint paint;
            paint.setColor(0x7fff0000);
            renderer.drawRect(mDirtyRegion.fLeft, mDirtyRegion.fTop, mDirtyRegion.fRight,
                              mDirtyRegion.fBottom, paint);
        }
    }

    if (mType == ProfileType::Bars) {
        // Patch up the current frame to pretend we ended here. CanvasContext
        // will overwrite these values with the real ones after we return.
        // This is a bit nicer looking than the vague green bar, as we have
        // valid data for almost all the stages and a very good idea of what
        // the issue stage will look like, too
        FrameInfo& info = mFrameSource.back();
        info.markSwapBuffers();
        info.markFrameCompleted();

        initializeRects(renderer.getViewportHeight(), renderer.getViewportWidth());
        drawGraph(renderer);
        drawThreshold(renderer);
    }
}

void FrameInfoVisualizer::createData() {
    if (mFastRects.get()) return;

    mFastRects.reset(new float[mFrameSource.capacity() * 4]);
    mJankyRects.reset(new float[mFrameSource.capacity() * 4]);
}

void FrameInfoVisualizer::destroyData() {
    mFastRects.reset(nullptr);
    mJankyRects.reset(nullptr);
}

void FrameInfoVisualizer::initializeRects(const int baseline, const int width) {
    // Target the 95% mark for the current frame
    float right = width * .95;
    float baseLineWidth = right / mFrameSource.capacity();
    mNumFastRects = 0;
    mNumJankyRects = 0;
    int fast_i = 0, janky_i = 0;
    // Set the bottom of all the shapes to the baseline
    for (int fi = mFrameSource.size() - 1; fi >= 0; fi--) {
        if (mFrameSource[fi].getSkippedFrameReason()) {
            continue;
        }
        float lineWidth = baseLineWidth;
        float* rect;
        int ri;
        // Rects are LTRB
        if (mFrameSource[fi].totalDuration() <= mFrameInterval) {
            rect = mFastRects.get();
            ri = fast_i;
            fast_i += 4;
            mNumFastRects++;
        } else {
            rect = mJankyRects.get();
            ri = janky_i;
            janky_i += 4;
            mNumJankyRects++;
            lineWidth *= 2;
        }

        rect[ri + 0] = right - lineWidth;
        rect[ri + 1] = baseline;
        rect[ri + 2] = right;
        rect[ri + 3] = baseline;
        right -= lineWidth;
    }
}

void FrameInfoVisualizer::nextBarSegment(FrameInfoIndex start, FrameInfoIndex end) {
    int fast_i = (mNumFastRects - 1) * 4;
    int janky_i = (mNumJankyRects - 1) * 4;

    for (size_t fi = 0; fi < mFrameSource.size(); fi++) {
        if (mFrameSource[fi].getSkippedFrameReason()) {
            continue;
        }

        float* rect;
        int ri;
        // Rects are LTRB
        if (mFrameSource[fi].totalDuration() <= mFrameInterval) {
            rect = mFastRects.get();
            ri = fast_i;
            fast_i -= 4;
        } else {
            rect = mJankyRects.get();
            ri = janky_i;
            janky_i -= 4;
        }

        // Set the bottom to the old top (build upwards)
        rect[ri + 3] = rect[ri + 1];
        // Move the top up by the duration
        rect[ri + 1] -= mVerticalUnit * durationMS(fi, start, end);
    }
}

void FrameInfoVisualizer::drawGraph(IProfileRenderer& renderer) {
    SkPaint paint;
    for (size_t i = 0; i < Bar.size(); i++) {
        nextBarSegment(Bar[i].start, Bar[i].end);
        paint.setColor(Bar[i].color & BAR_FAST_MASK);
        renderer.drawRects(mFastRects.get(), mNumFastRects * 4, paint);
        paint.setColor(Bar[i].color & BAR_JANKY_MASK);
        renderer.drawRects(mJankyRects.get(), mNumJankyRects * 4, paint);
    }
}

void FrameInfoVisualizer::drawThreshold(IProfileRenderer& renderer) {
    SkPaint paint;
    for (auto& t : THRESHOLDS) {
        paint.setColor(t.color);
        float yLocation = renderer.getViewportHeight() -
                          (ns2ms(mFrameInterval) * t.percentFrametime * mVerticalUnit);
        renderer.drawRect(0.0f, yLocation - mThresholdStroke / 2, renderer.getViewportWidth(),
                          yLocation + mThresholdStroke / 2, paint);
    }
}

bool FrameInfoVisualizer::consumeProperties() {
    bool changed = false;
    ProfileType newType = Properties::getProfileType();
    if (newType != mType) {
        mType = newType;
        if (mType == ProfileType::None) {
            destroyData();
        } else {
            createData();
        }
        changed = true;
    }

    bool showDirty = Properties::showDirtyRegions;
    if (showDirty != mShowDirtyRegions) {
        mShowDirtyRegions = showDirty;
        changed = true;
    }
    return changed;
}

void FrameInfoVisualizer::dumpData(int fd) {
    RETURN_IF_PROFILING_DISABLED();

    // This method logs the last N frames (where N is <= mDataSize) since the
    // last call to dumpData(). In other words if there's a dumpData(), draw frame,
    // dumpData(), the last dumpData() should only log 1 frame.

    dprintf(fd, "\n\tDraw\tPrepare\tProcess\tExecute\n");

    for (size_t i = 0; i < mFrameSource.size(); i++) {
        if (mFrameSource[i][FrameInfoIndex::IntendedVsync] <= mLastFrameLogged) {
            continue;
        }
        mLastFrameLogged = mFrameSource[i][FrameInfoIndex::IntendedVsync];
        dprintf(fd, "\t%3.2f\t%3.2f\t%3.2f\t%3.2f\n",
                durationMS(i, FrameInfoIndex::IntendedVsync, FrameInfoIndex::SyncStart),
                durationMS(i, FrameInfoIndex::SyncStart, FrameInfoIndex::IssueDrawCommandsStart),
                durationMS(i, FrameInfoIndex::IssueDrawCommandsStart, FrameInfoIndex::SwapBuffers),
                durationMS(i, FrameInfoIndex::SwapBuffers, FrameInfoIndex::FrameCompleted));
    }
}

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