
/*
 * 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 "SkDebugger.h"
#include "SkMakeUnique.h"
#include "SkPictureRecorder.h"
#include "SkString.h"


SkDebugger::SkDebugger()
    : fDebugCanvas(skstd::make_unique<SkDebugCanvas>(0, 0))
    , fIndex(-1) { }

SkDebugger::~SkDebugger() {}

void SkDebugger::loadPicture(SkPicture* picture) {
    fPicture = sk_ref_sp(picture);
    fDebugCanvas = skstd::make_unique<SkDebugCanvas>(
        SkScalarCeilToInt(this->pictureCull().width()),
        SkScalarCeilToInt(this->pictureCull().height()));
    fDebugCanvas->setPicture(picture);
    picture->playback(fDebugCanvas.get());
    fDebugCanvas->setPicture(nullptr);
    fIndex = fDebugCanvas->getSize() - 1;
}

sk_sp<SkPicture> SkDebugger::copyPicture() {
    // We can't just call clone here since we want to removed the "deleted"
    // commands. Playing back will strip those out.
    SkPictureRecorder recorder;
    SkCanvas* canvas = recorder.beginRecording(this->pictureCull().width(), 
                                               this->pictureCull().height());

    bool vizMode = fDebugCanvas->getMegaVizMode();
    fDebugCanvas->setMegaVizMode(false);
    bool overDraw = fDebugCanvas->getOverdrawViz();
    fDebugCanvas->setOverdrawViz(false);
    bool pathOps = fDebugCanvas->getAllowSimplifyClip();
    fDebugCanvas->setAllowSimplifyClip(false);

    fDebugCanvas->draw(canvas);

    fDebugCanvas->setMegaVizMode(vizMode);
    fDebugCanvas->setOverdrawViz(overDraw);
    fDebugCanvas->setAllowSimplifyClip(pathOps);

    return recorder.finishRecordingAsPicture();
}

void SkDebugger::getOverviewText(const SkTDArray<double>* typeTimes,
                                 double totTime,
                                 SkString* overview,
                                 int numRuns) {
    const SkTDArray<SkDrawCommand*>& commands = this->getDrawCommands();

    SkTDArray<int> counts;
    counts.setCount(SkDrawCommand::kOpTypeCount);
    for (int i = 0; i < SkDrawCommand::kOpTypeCount; ++i) {
        counts[i] = 0;
    }

    for (int i = 0; i < commands.count(); i++) {
        counts[commands[i]->getType()]++;
    }

    overview->reset();
    int total = 0;
#ifdef SK_DEBUG
    double totPercent = 0, tempSum = 0;
#endif
    for (int i = 0; i < SkDrawCommand::kOpTypeCount; ++i) {
        if (0 == counts[i]) {
            // if there were no commands of this type then they should've consumed no time
            SkASSERT(nullptr == typeTimes || 0.0 == (*typeTimes)[i]);
            continue;
        }

        overview->append(SkDrawCommand::GetCommandString((SkDrawCommand::OpType) i));
        overview->append(": ");
        overview->appendS32(counts[i]);
        if (typeTimes && totTime >= 0.0) {
            overview->append(" - ");
            overview->appendf("%.2f", (*typeTimes)[i]/(float)numRuns);
            overview->append("ms");
            overview->append(" - ");
            double percent = 100.0*(*typeTimes)[i]/totTime;
            overview->appendf("%.2f", percent);
            overview->append("%");
#ifdef SK_DEBUG
            totPercent += percent;
            tempSum += (*typeTimes)[i];
#endif
        }
        overview->append("<br/>");
        total += counts[i];
    }
#ifdef SK_DEBUG
    if (typeTimes) {
        SkASSERT(SkScalarNearlyEqual(SkDoubleToScalar(totPercent),
                                     SkDoubleToScalar(100.0)));
        SkASSERT(SkScalarNearlyEqual(SkDoubleToScalar(tempSum),
                                     SkDoubleToScalar(totTime)));
    }
#endif

    if (totTime > 0.0) {
        overview->append("Total Time: ");
        overview->appendf("%.2f", totTime/(float)numRuns);
        overview->append("ms");
#ifdef SK_DEBUG
        overview->append(" ");
        overview->appendScalar(SkDoubleToScalar(totPercent));
        overview->append("% ");
#endif
        overview->append("<br/>");
    }

    SkString totalStr;
    totalStr.append("Total Draw Commands: ");
    totalStr.appendScalar(SkDoubleToScalar(total));
    totalStr.append("<br/>");
    overview->insert(0, totalStr);

    overview->append("<br/>SkPicture L: ");
    overview->appendScalar(this->pictureCull().fLeft);
    overview->append(" T: ");
    overview->appendScalar(this->pictureCull().fTop);
    overview->append(" R: ");
    overview->appendScalar(this->pictureCull().fRight);
    overview->append(" B: ");
    overview->appendScalar(this->pictureCull().fBottom);
    overview->append("<br/>");
}

void SkDebugger::getClipStackText(SkString* clipStack) {
    clipStack->set(fDebugCanvas->clipStackData());
}
