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

#include "GrTextureOpList.h"

#include "GrAuditTrail.h"
#include "GrGpu.h"
#include "GrTextureProxy.h"

#include "batches/GrCopySurfaceBatch.h"

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

GrTextureOpList::GrTextureOpList(GrTextureProxy* tex, GrGpu* gpu, GrAuditTrail* auditTrail)
    : INHERITED(tex, auditTrail)
    , fGpu(SkRef(gpu)) {
}

GrTextureOpList::~GrTextureOpList() {
    fGpu->unref();
}

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

#ifdef SK_DEBUG
void GrTextureOpList::dump() const {
    INHERITED::dump();

    SkDebugf("batches (%d):\n", fRecordedBatches.count());
    for (int i = 0; i < fRecordedBatches.count(); ++i) {
        SkDebugf("*******************************\n");
        SkDebugf("%d: %s\n", i, fRecordedBatches[i]->name());
        SkString str = fRecordedBatches[i]->dumpInfo();
        SkDebugf("%s\n", str.c_str());
        const SkRect& clippedBounds = fRecordedBatches[i]->bounds();
        SkDebugf("ClippedBounds: [L: %.2f, T: %.2f, R: %.2f, B: %.2f]\n",
                    clippedBounds.fLeft, clippedBounds.fTop, clippedBounds.fRight,
                    clippedBounds.fBottom);
    }
}
#endif

void GrTextureOpList::prepareBatches(GrBatchFlushState* flushState) {
    // Semi-usually the GrOpLists are already closed at this point, but sometimes Ganesh
    // needs to flush mid-draw. In that case, the SkGpuDevice's GrOpLists won't be closed
    // but need to be flushed anyway. Closing such GrOpLists here will mean new
    // GrOpLists will be created to replace them if the SkGpuDevice(s) write to them again.
    this->makeClosed();

    // Loop over the batches that haven't yet generated their geometry
    for (int i = 0; i < fRecordedBatches.count(); ++i) {
        if (fRecordedBatches[i]) {
            fRecordedBatches[i]->prepare(flushState);
        }
    }
}

bool GrTextureOpList::drawBatches(GrBatchFlushState* flushState) {
    if (0 == fRecordedBatches.count()) {
        return false;
    }

    for (int i = 0; i < fRecordedBatches.count(); ++i) {
        fRecordedBatches[i]->draw(flushState, fRecordedBatches[i]->bounds());
    }

    fGpu->finishOpList();
    return true;
}

void GrTextureOpList::reset() {
    fRecordedBatches.reset();
}

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

bool GrTextureOpList::copySurface(GrSurface* dst,
                                  GrSurface* src,
                                  const SkIRect& srcRect,
                                  const SkIPoint& dstPoint) {
    GrBatch* batch = GrCopySurfaceBatch::Create(dst, src, srcRect, dstPoint);
    if (!batch) {
        return false;
    }
#ifdef ENABLE_MDB
    this->addDependency(src);
#endif

    this->recordBatch(batch);
    batch->unref();
    return true;
}

void GrTextureOpList::recordBatch(GrBatch* batch) {
    // A closed GrOpList should never receive new/more batches
    SkASSERT(!this->isClosed());

    GR_AUDIT_TRAIL_ADDBATCH(fAuditTrail, batch);
    GrBATCH_INFO("Re-Recording (%s, B%u)\n"
        "\tBounds LRTB (%f, %f, %f, %f)\n",
        batch->name(),
        batch->uniqueID(),
        batch->bounds().fLeft, batch->bounds().fRight,
        batch->bounds().fTop, batch->bounds().fBottom);
    GrBATCH_INFO(SkTabString(batch->dumpInfo(), 1).c_str());
    GR_AUDIT_TRAIL_BATCHING_RESULT_NEW(fAuditTrail, batch);

    fRecordedBatches.emplace_back(sk_ref_sp(batch));
}
