/*
 * 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][FrameInfoIndex::Flags] & FrameInfoFlags::SkippedFrame) {
            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][FrameInfoIndex::Flags] & FrameInfoFlags::SkippedFrame) {
            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 */
