| Index: src/gpu/instanced/GLInstancedRendering.cpp
|
| diff --git a/src/gpu/instanced/GLInstancedRendering.cpp b/src/gpu/instanced/GLInstancedRendering.cpp
|
| deleted file mode 100644
|
| index 7df39f07df15de889149110bb2889a9019764181..0000000000000000000000000000000000000000
|
| --- a/src/gpu/instanced/GLInstancedRendering.cpp
|
| +++ /dev/null
|
| @@ -1,301 +0,0 @@
|
| -/*
|
| - * 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 "GLInstancedRendering.h"
|
| -
|
| -#include "GrResourceProvider.h"
|
| -#include "gl/GrGLGpu.h"
|
| -#include "instanced/InstanceProcessor.h"
|
| -
|
| -#define GL_CALL(X) GR_GL_CALL(this->glGpu()->glInterface(), X)
|
| -
|
| -namespace gr_instanced {
|
| -
|
| -class GLInstancedRendering::GLBatch : public InstancedRendering::Batch {
|
| -public:
|
| - DEFINE_BATCH_CLASS_ID
|
| -
|
| - GLBatch(GLInstancedRendering* instRendering) : INHERITED(ClassID(), instRendering) {}
|
| - int numGLCommands() const { return 1 + fNumChangesInGeometry; }
|
| -
|
| -private:
|
| - int fEmulatedBaseInstance;
|
| - int fGLDrawCmdsIdx;
|
| -
|
| - friend class GLInstancedRendering;
|
| -
|
| - typedef Batch INHERITED;
|
| -};
|
| -
|
| -GLInstancedRendering* GLInstancedRendering::CreateIfSupported(GrGLGpu* gpu) {
|
| -#ifndef SK_BUILD_FOR_MAC
|
| - // Only whitelisting on Mac for now. Once we've been able to work through the various issues on
|
| - // other platforms we can enable more generally.
|
| - return nullptr;
|
| -#endif
|
| - const GrGLCaps& glCaps = gpu->glCaps();
|
| - AntialiasMode lastSupportedAAMode;
|
| - if (!glCaps.vertexArrayObjectSupport() ||
|
| - !glCaps.drawIndirectSupport() ||
|
| - !InstanceProcessor::IsSupported(*glCaps.glslCaps(), glCaps, &lastSupportedAAMode)) {
|
| - return nullptr;
|
| - }
|
| - return new GLInstancedRendering(gpu, lastSupportedAAMode);
|
| -}
|
| -
|
| -GLInstancedRendering::GLInstancedRendering(GrGLGpu* gpu, AntialiasMode lastSupportedAAMode)
|
| - : INHERITED(gpu, lastSupportedAAMode, gpu->glCaps().canDrawIndirectToFloat()),
|
| - fVertexArrayID(0),
|
| - fGLDrawCmdsInfo(0),
|
| - fInstanceAttribsBufferUniqueId(SK_InvalidUniqueID) {
|
| -}
|
| -
|
| -GLInstancedRendering::~GLInstancedRendering() {
|
| - if (fVertexArrayID) {
|
| - GL_CALL(DeleteVertexArrays(1, &fVertexArrayID));
|
| - this->glGpu()->notifyVertexArrayDelete(fVertexArrayID);
|
| - }
|
| -}
|
| -
|
| -inline GrGLGpu* GLInstancedRendering::glGpu() const {
|
| - return static_cast<GrGLGpu*>(this->gpu());
|
| -}
|
| -
|
| -InstancedRendering::Batch* GLInstancedRendering::createBatch() {
|
| - return new GLBatch(this);
|
| -}
|
| -
|
| -void GLInstancedRendering::onBeginFlush(GrResourceProvider* rp) {
|
| - // Count what there is to draw.
|
| - BatchList::Iter iter;
|
| - iter.init(this->trackedBatches(), BatchList::Iter::kHead_IterStart);
|
| - int numGLInstances = 0;
|
| - int numGLDrawCmds = 0;
|
| - while (Batch* b = iter.get()) {
|
| - GLBatch* batch = static_cast<GLBatch*>(b);
|
| - iter.next();
|
| -
|
| - numGLInstances += batch->fNumDraws;
|
| - numGLDrawCmds += batch->numGLCommands();
|
| - }
|
| - if (!numGLDrawCmds) {
|
| - return;
|
| - }
|
| - SkASSERT(numGLInstances);
|
| -
|
| - // Lazily create a vertex array object.
|
| - if (!fVertexArrayID) {
|
| - GL_CALL(GenVertexArrays(1, &fVertexArrayID));
|
| - if (!fVertexArrayID) {
|
| - return;
|
| - }
|
| - this->glGpu()->bindVertexArray(fVertexArrayID);
|
| -
|
| - // Attach our index buffer to the vertex array.
|
| - GL_CALL(BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER,
|
| - static_cast<const GrGLBuffer*>(this->indexBuffer())->bufferID()));
|
| -
|
| - // Set up the non-instanced attribs.
|
| - this->glGpu()->bindBuffer(kVertex_GrBufferType,
|
| - static_cast<const GrGLBuffer*>(this->vertexBuffer()));
|
| - GL_CALL(EnableVertexAttribArray((int)Attrib::kShapeCoords));
|
| - GL_CALL(VertexAttribPointer((int)Attrib::kShapeCoords, 2, GR_GL_FLOAT, GR_GL_FALSE,
|
| - sizeof(ShapeVertex), (void*) offsetof(ShapeVertex, fX)));
|
| - GL_CALL(EnableVertexAttribArray((int)Attrib::kVertexAttrs));
|
| - GL_CALL(VertexAttribIPointer((int)Attrib::kVertexAttrs, 1, GR_GL_INT, sizeof(ShapeVertex),
|
| - (void*) offsetof(ShapeVertex, fAttrs)));
|
| -
|
| - SkASSERT(SK_InvalidUniqueID == fInstanceAttribsBufferUniqueId);
|
| - }
|
| -
|
| - // Create and map instance and draw-indirect buffers.
|
| - SkASSERT(!fInstanceBuffer);
|
| - fInstanceBuffer.reset(static_cast<GrGLBuffer*>(
|
| - rp->createBuffer(sizeof(Instance) * numGLInstances, kVertex_GrBufferType,
|
| - kDynamic_GrAccessPattern, GrResourceProvider::kNoPendingIO_Flag)));
|
| - if (!fInstanceBuffer) {
|
| - return;
|
| - }
|
| -
|
| - SkASSERT(!fDrawIndirectBuffer);
|
| - fDrawIndirectBuffer.reset(static_cast<GrGLBuffer*>(
|
| - rp->createBuffer(sizeof(GrGLDrawElementsIndirectCommand) * numGLDrawCmds,
|
| - kDrawIndirect_GrBufferType, kDynamic_GrAccessPattern,
|
| - GrResourceProvider::kNoPendingIO_Flag)));
|
| - if (!fDrawIndirectBuffer) {
|
| - return;
|
| - }
|
| -
|
| - Instance* glMappedInstances = static_cast<Instance*>(fInstanceBuffer->map());
|
| - int glInstancesIdx = 0;
|
| -
|
| - auto* glMappedCmds = static_cast<GrGLDrawElementsIndirectCommand*>(fDrawIndirectBuffer->map());
|
| - int glDrawCmdsIdx = 0;
|
| -
|
| - bool baseInstanceSupport = this->glGpu()->glCaps().baseInstanceSupport();
|
| -
|
| - if (GR_GL_LOG_INSTANCED_BATCHES || !baseInstanceSupport) {
|
| - fGLDrawCmdsInfo.reset(numGLDrawCmds);
|
| - }
|
| -
|
| - // Generate the instance and draw-indirect buffer contents based on the tracked batches.
|
| - iter.init(this->trackedBatches(), BatchList::Iter::kHead_IterStart);
|
| - while (Batch* b = iter.get()) {
|
| - GLBatch* batch = static_cast<GLBatch*>(b);
|
| - iter.next();
|
| -
|
| - batch->fEmulatedBaseInstance = baseInstanceSupport ? 0 : glInstancesIdx;
|
| - batch->fGLDrawCmdsIdx = glDrawCmdsIdx;
|
| -
|
| - const Batch::Draw* draw = batch->fHeadDraw;
|
| - SkASSERT(draw);
|
| - do {
|
| - int instanceCount = 0;
|
| - IndexRange geometry = draw->fGeometry;
|
| - SkASSERT(!geometry.isEmpty());
|
| -
|
| - do {
|
| - glMappedInstances[glInstancesIdx + instanceCount++] = draw->fInstance;
|
| - draw = draw->fNext;
|
| - } while (draw && draw->fGeometry == geometry);
|
| -
|
| - GrGLDrawElementsIndirectCommand& glCmd = glMappedCmds[glDrawCmdsIdx];
|
| - glCmd.fCount = geometry.fCount;
|
| - glCmd.fInstanceCount = instanceCount;
|
| - glCmd.fFirstIndex = geometry.fStart;
|
| - glCmd.fBaseVertex = 0;
|
| - glCmd.fBaseInstance = baseInstanceSupport ? glInstancesIdx : 0;
|
| -
|
| - if (GR_GL_LOG_INSTANCED_BATCHES || !baseInstanceSupport) {
|
| - fGLDrawCmdsInfo[glDrawCmdsIdx].fInstanceCount = instanceCount;
|
| -#if GR_GL_LOG_INSTANCED_BATCHES
|
| - fGLDrawCmdsInfo[glDrawCmdsIdx].fGeometry = geometry;
|
| -#endif
|
| - }
|
| -
|
| - glInstancesIdx += instanceCount;
|
| - ++glDrawCmdsIdx;
|
| - } while (draw);
|
| - }
|
| -
|
| - SkASSERT(glDrawCmdsIdx == numGLDrawCmds);
|
| - fDrawIndirectBuffer->unmap();
|
| -
|
| - SkASSERT(glInstancesIdx == numGLInstances);
|
| - fInstanceBuffer->unmap();
|
| -}
|
| -
|
| -void GLInstancedRendering::onDraw(const GrPipeline& pipeline, const InstanceProcessor& instProc,
|
| - const Batch* baseBatch) {
|
| - if (!fDrawIndirectBuffer) {
|
| - return; // beginFlush was not successful.
|
| - }
|
| - if (!this->glGpu()->flushGLState(pipeline, instProc)) {
|
| - return;
|
| - }
|
| -
|
| - this->glGpu()->bindBuffer(kDrawIndirect_GrBufferType, fDrawIndirectBuffer.get());
|
| -
|
| - const GrGLCaps& glCaps = this->glGpu()->glCaps();
|
| - const GLBatch* batch = static_cast<const GLBatch*>(baseBatch);
|
| - int numCommands = batch->numGLCommands();
|
| -
|
| -#if GR_GL_LOG_INSTANCED_BATCHES
|
| - SkASSERT(fGLDrawCmdsInfo);
|
| - SkDebugf("Instanced batch: [");
|
| - for (int i = 0; i < numCommands; ++i) {
|
| - int glCmdIdx = batch->fGLDrawCmdsIdx + i;
|
| - SkDebugf("%s%i * %s", (i ? ", " : ""), fGLDrawCmdsInfo[glCmdIdx].fInstanceCount,
|
| - InstanceProcessor::GetNameOfIndexRange(fGLDrawCmdsInfo[glCmdIdx].fGeometry));
|
| - }
|
| - SkDebugf("]\n");
|
| -#else
|
| - SkASSERT(SkToBool(fGLDrawCmdsInfo) == !glCaps.baseInstanceSupport());
|
| -#endif
|
| -
|
| - if (1 == numCommands || !glCaps.baseInstanceSupport() || !glCaps.multiDrawIndirectSupport()) {
|
| - int emulatedBaseInstance = batch->fEmulatedBaseInstance;
|
| - for (int i = 0; i < numCommands; ++i) {
|
| - int glCmdIdx = batch->fGLDrawCmdsIdx + i;
|
| - this->flushInstanceAttribs(emulatedBaseInstance);
|
| - GL_CALL(DrawElementsIndirect(GR_GL_TRIANGLES, GR_GL_UNSIGNED_BYTE,
|
| - (GrGLDrawElementsIndirectCommand*) nullptr + glCmdIdx));
|
| - if (!glCaps.baseInstanceSupport()) {
|
| - emulatedBaseInstance += fGLDrawCmdsInfo[glCmdIdx].fInstanceCount;
|
| - }
|
| - }
|
| - } else {
|
| - int glCmdsIdx = batch->fGLDrawCmdsIdx;
|
| - this->flushInstanceAttribs(batch->fEmulatedBaseInstance);
|
| - GL_CALL(MultiDrawElementsIndirect(GR_GL_TRIANGLES, GR_GL_UNSIGNED_BYTE,
|
| - (GrGLDrawElementsIndirectCommand*) nullptr + glCmdsIdx,
|
| - numCommands, 0));
|
| - }
|
| -}
|
| -
|
| -void GLInstancedRendering::flushInstanceAttribs(int baseInstance) {
|
| - SkASSERT(fVertexArrayID);
|
| - this->glGpu()->bindVertexArray(fVertexArrayID);
|
| -
|
| - SkASSERT(fInstanceBuffer);
|
| - if (fInstanceAttribsBufferUniqueId != fInstanceBuffer->getUniqueID() ||
|
| - fInstanceAttribsBaseInstance != baseInstance) {
|
| - Instance* offsetInBuffer = (Instance*) nullptr + baseInstance;
|
| -
|
| - this->glGpu()->bindBuffer(kVertex_GrBufferType, fInstanceBuffer.get());
|
| -
|
| - // Info attrib.
|
| - GL_CALL(EnableVertexAttribArray((int)Attrib::kInstanceInfo));
|
| - GL_CALL(VertexAttribIPointer((int)Attrib::kInstanceInfo, 1, GR_GL_UNSIGNED_INT,
|
| - sizeof(Instance), &offsetInBuffer->fInfo));
|
| - GL_CALL(VertexAttribDivisor((int)Attrib::kInstanceInfo, 1));
|
| -
|
| - // Shape matrix attrib.
|
| - GL_CALL(EnableVertexAttribArray((int)Attrib::kShapeMatrixX));
|
| - GL_CALL(EnableVertexAttribArray((int)Attrib::kShapeMatrixY));
|
| - GL_CALL(VertexAttribPointer((int)Attrib::kShapeMatrixX, 3, GR_GL_FLOAT, GR_GL_FALSE,
|
| - sizeof(Instance), &offsetInBuffer->fShapeMatrix2x3[0]));
|
| - GL_CALL(VertexAttribPointer((int)Attrib::kShapeMatrixY, 3, GR_GL_FLOAT, GR_GL_FALSE,
|
| - sizeof(Instance), &offsetInBuffer->fShapeMatrix2x3[3]));
|
| - GL_CALL(VertexAttribDivisor((int)Attrib::kShapeMatrixX, 1));
|
| - GL_CALL(VertexAttribDivisor((int)Attrib::kShapeMatrixY, 1));
|
| -
|
| - // Color attrib.
|
| - GL_CALL(EnableVertexAttribArray((int)Attrib::kColor));
|
| - GL_CALL(VertexAttribPointer((int)Attrib::kColor, 4, GR_GL_UNSIGNED_BYTE, GR_GL_TRUE,
|
| - sizeof(Instance), &offsetInBuffer->fColor));
|
| - GL_CALL(VertexAttribDivisor((int)Attrib::kColor, 1));
|
| -
|
| - // Local rect attrib.
|
| - GL_CALL(EnableVertexAttribArray((int)Attrib::kLocalRect));
|
| - GL_CALL(VertexAttribPointer((int)Attrib::kLocalRect, 4, GR_GL_FLOAT, GR_GL_FALSE,
|
| - sizeof(Instance), &offsetInBuffer->fLocalRect));
|
| - GL_CALL(VertexAttribDivisor((int)Attrib::kLocalRect, 1));
|
| -
|
| - fInstanceAttribsBufferUniqueId = fInstanceBuffer->getUniqueID();
|
| - fInstanceAttribsBaseInstance = baseInstance;
|
| - }
|
| -}
|
| -
|
| -void GLInstancedRendering::onEndFlush() {
|
| - fInstanceBuffer.reset();
|
| - fDrawIndirectBuffer.reset();
|
| - fGLDrawCmdsInfo.reset(0);
|
| -}
|
| -
|
| -void GLInstancedRendering::onResetGpuResources(ResetType resetType) {
|
| - if (fVertexArrayID && ResetType::kDestroy == resetType) {
|
| - GL_CALL(DeleteVertexArrays(1, &fVertexArrayID));
|
| - this->glGpu()->notifyVertexArrayDelete(fVertexArrayID);
|
| - }
|
| - fVertexArrayID = 0;
|
| - fInstanceBuffer.reset();
|
| - fDrawIndirectBuffer.reset();
|
| - fInstanceAttribsBufferUniqueId = SK_InvalidUniqueID;
|
| -}
|
| -
|
| -}
|
|
|