blob: 974ee9bc75b41aff79cea3514980aff1d50e8f2f [file] [log] [blame]
/*
* 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));
}