
/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "TimerData.h"

#include "BenchTimer.h"
#include <limits>

using namespace std;

TimerData::TimerData(int maxNumTimings)
: fMaxNumTimings(maxNumTimings)
, fCurrTiming(0)
, fWallTimes(maxNumTimings)
, fTruncatedWallTimes(maxNumTimings)
, fCpuTimes(maxNumTimings)
, fTruncatedCpuTimes(maxNumTimings)
, fGpuTimes(maxNumTimings){
}

bool TimerData::appendTimes(BenchTimer* timer) {
    SkASSERT(timer != NULL);
    if (fCurrTiming >= fMaxNumTimings) {
        return false;
    }

    fWallTimes[fCurrTiming] = timer->fWall;
    fTruncatedWallTimes[fCurrTiming] = timer->fTruncatedWall;
    fCpuTimes[fCurrTiming] = timer->fCpu;
    fTruncatedCpuTimes[fCurrTiming] = timer->fTruncatedCpu;
    fGpuTimes[fCurrTiming] = timer->fGpu;

    ++fCurrTiming;

    return true;
}

SkString TimerData::getResult(const char* doubleFormat,
                              Result result,
                              const char *configName,
                              uint32_t timerFlags,
                              int itersPerTiming) {
    SkASSERT(itersPerTiming >= 1);

    if (!fCurrTiming) {
        return SkString("");
    }

    int numTimings = fCurrTiming;

    SkString wallStr(" msecs = ");
    SkString truncWallStr(" Wmsecs = ");
    SkString cpuStr(" cmsecs = ");
    SkString truncCpuStr(" Cmsecs = ");
    SkString gpuStr(" gmsecs = ");

    double wallMin = std::numeric_limits<double>::max();
    double truncWallMin = std::numeric_limits<double>::max();
    double cpuMin = std::numeric_limits<double>::max();
    double truncCpuMin = std::numeric_limits<double>::max();
    double gpuMin = std::numeric_limits<double>::max();

    double wallSum = 0;
    double truncWallSum = 0;
    double cpuSum = 0;
    double truncCpuSum = 0;
    double gpuSum = 0;

    for (int i = 0; i < numTimings; ++i) {
        if (kPerIter_Result == result) {
            wallStr.appendf(doubleFormat, fWallTimes[i] / itersPerTiming);
            truncWallStr.appendf(doubleFormat, fTruncatedWallTimes[i] / itersPerTiming);
            cpuStr.appendf(doubleFormat, fCpuTimes[i] / itersPerTiming);
            truncCpuStr.appendf(doubleFormat, fTruncatedCpuTimes[i] / itersPerTiming);
            gpuStr.appendf(doubleFormat, fGpuTimes[i] / itersPerTiming);

            if (i != numTimings - 1) {
                static const char kSep[] = ", ";
                wallStr.append(kSep);
                truncWallStr.append(kSep);
                cpuStr.append(kSep);
                truncCpuStr.append(kSep);
                gpuStr.append(kSep);
            }
        } else if (kMin_Result == result) {
            wallMin = SkTMin(wallMin, fWallTimes[i]);
            truncWallMin = SkTMin(truncWallMin, fTruncatedWallTimes[i]);
            cpuMin = SkTMin(cpuMin, fCpuTimes[i]);
            truncCpuMin = SkTMin(truncCpuMin, fTruncatedCpuTimes[i]);
            gpuMin = SkTMin(gpuMin, fGpuTimes[i]);
        } else {
            SkASSERT(kAvg_Result == result);
            wallSum += fWallTimes[i];
            truncWallSum += fTruncatedWallTimes[i];
            cpuSum += fCpuTimes[i];
            truncCpuSum += fTruncatedCpuTimes[i];
        }

        // We always track the GPU sum because whether it is non-zero indicates if valid gpu times
        // were recorded at all.
        gpuSum += fGpuTimes[i];
    }

    if (kMin_Result == result) {
        wallStr.appendf(doubleFormat, wallMin / itersPerTiming);
        truncWallStr.appendf(doubleFormat, truncWallMin / itersPerTiming);
        cpuStr.appendf(doubleFormat, cpuMin / itersPerTiming);
        truncCpuStr.appendf(doubleFormat, truncCpuMin / itersPerTiming);
        gpuStr.appendf(doubleFormat, gpuMin / itersPerTiming);
    } else if (kAvg_Result == result) {
        int divisor = numTimings * itersPerTiming;
        wallStr.appendf(doubleFormat, wallSum / divisor);
        truncWallStr.appendf(doubleFormat, truncWallSum / divisor);
        cpuStr.appendf(doubleFormat, cpuSum / divisor);
        truncCpuStr.appendf(doubleFormat, truncCpuSum / divisor);
        gpuStr.appendf(doubleFormat, gpuSum / divisor);
    }

    SkString str;
    str.printf("  %4s:", configName);
    if (timerFlags & kWall_Flag) {
        str += wallStr;
    }
    if (timerFlags & kTruncatedWall_Flag) {
        str += truncWallStr;
    }
    if (timerFlags & kCpu_Flag) {
        str += cpuStr;
    }
    if (timerFlags & kTruncatedCpu_Flag) {
        str += truncCpuStr;
    }
    if ((timerFlags & kGpu_Flag) && gpuSum > 0) {
        str += gpuStr;
    }
    return str;
}
