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

#include "GrTraceMarker.h"
#include "GrTracing.h"
#include "SkString.h"
#include "SkTSort.h"

////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////

GrTraceMarkerSet::GrTraceMarkerSet(const GrTraceMarkerSet& other) {
   this->addSet(other);
}

void GrTraceMarkerSet::add(const GrGpuTraceMarker& marker) {
    this->fMarkerArray.push(marker);
}

void GrTraceMarkerSet::addSet(const GrTraceMarkerSet& markerSet) {
    for (Iter iter = markerSet.begin(); iter != markerSet.end(); ++iter) {
        this->add(*iter);
    }
}

void GrTraceMarkerSet::remove(const GrGpuTraceMarker& marker) {
    SkASSERT(-1 != fMarkerArray.find(marker));
    int index = this->fMarkerArray.find(marker);
    this->fMarkerArray.remove(index);
}

int GrTraceMarkerSet::count() const {
    return this->fMarkerArray.count();
}

SkString GrTraceMarkerSet::toString() const {
    SkTQSort<GrGpuTraceMarker>(this->fMarkerArray.begin(), this->fMarkerArray.end() - 1);
    SkString marker_string;
    const char* prevMarkerName = "";
    int prevMarkerID = -1;
    int counter = 0;
    const int numMarkers = this->fMarkerArray.count();

    // check used for GrGpuGL device after we've already collapsed all markers
    if (1 == numMarkers && -1 == this->fMarkerArray[0].fID) {
        marker_string.append(this->fMarkerArray[0].fMarker);
        return marker_string;
    }

    for (int i = 0; i < numMarkers; ++i ) {
        GrGpuTraceMarker& currMarker = this->fMarkerArray[i];
        const char* currCmd = currMarker.fMarker;
        if (currCmd != prevMarkerName) {
            if (counter != 0) {
                marker_string.append(") ");
            }
            marker_string.append(currCmd);
            marker_string.append("(");
            marker_string.appendS32(currMarker.fID);
            prevMarkerName = currCmd;
        } else if (currMarker.fID != prevMarkerID) {
            marker_string.append(", ");
            marker_string.appendS32(currMarker.fID);
        }
        prevMarkerID = currMarker.fID;
        ++counter;
    }
    if (counter > 0) {
        marker_string.append(")");
    }
    return marker_string;
}

GrTraceMarkerSet::Iter GrTraceMarkerSet::begin() const {
    return Iter(this, 0);
}

GrTraceMarkerSet::Iter GrTraceMarkerSet::end() const {
    return Iter(this, this->fMarkerArray.count());
}

