Index: src/gpu/instanced/GLInstancedRendering.cpp |
diff --git a/src/gpu/instanced/GLInstancedRendering.cpp b/src/gpu/instanced/GLInstancedRendering.cpp |
index 440796e19a16da6a0a24a66c256493ab59faf2c4..3af1aa7ab319880e2518ddf2d8cc590a33aecbf5 100644 |
--- a/src/gpu/instanced/GLInstancedRendering.cpp |
+++ b/src/gpu/instanced/GLInstancedRendering.cpp |
@@ -34,7 +34,8 @@ private: |
GrCaps::InstancedSupport GLInstancedRendering::CheckSupport(const GrGLCaps& glCaps) { |
// This method is only intended to be used for initializing fInstancedSupport in the caps. |
SkASSERT(GrCaps::InstancedSupport::kNone == glCaps.instancedSupport()); |
- if (!glCaps.vertexArrayObjectSupport() || !glCaps.drawIndirectSupport()) { |
+ if (!glCaps.vertexArrayObjectSupport() || |
+ (!glCaps.drawIndirectSupport() && !glCaps.drawInstancedSupport())) { |
return GrCaps::InstancedSupport::kNone; |
} |
return InstanceProcessor::CheckSupport(*glCaps.glslCaps(), glCaps); |
@@ -118,23 +119,32 @@ void GLInstancedRendering::onBeginFlush(GrResourceProvider* rp) { |
} |
SkASSERT(!fDrawIndirectBuffer); |
- fDrawIndirectBuffer.reset( |
- rp->createBuffer(sizeof(GrGLDrawElementsIndirectCommand) * numGLDrawCmds, |
- kDrawIndirect_GrBufferType, kDynamic_GrAccessPattern, |
- GrResourceProvider::kNoPendingIO_Flag | |
- GrResourceProvider::kRequireGpuMemory_Flag)); |
- if (!fDrawIndirectBuffer) { |
- return; |
+ if (this->glGpu()->glCaps().drawIndirectSupport()) { |
+ fDrawIndirectBuffer.reset( |
+ rp->createBuffer(sizeof(GrGLDrawElementsIndirectCommand) * numGLDrawCmds, |
+ kDrawIndirect_GrBufferType, kDynamic_GrAccessPattern, |
+ GrResourceProvider::kNoPendingIO_Flag | |
+ GrResourceProvider::kRequireGpuMemory_Flag)); |
+ if (!fDrawIndirectBuffer) { |
+ return; |
+ } |
} |
Instance* glMappedInstances = static_cast<Instance*>(fInstanceBuffer->map()); |
+ SkASSERT(glMappedInstances); |
int glInstancesIdx = 0; |
- auto* glMappedCmds = static_cast<GrGLDrawElementsIndirectCommand*>(fDrawIndirectBuffer->map()); |
+ GrGLDrawElementsIndirectCommand* glMappedCmds = nullptr; |
int glDrawCmdsIdx = 0; |
+ if (fDrawIndirectBuffer) { |
+ glMappedCmds = static_cast<GrGLDrawElementsIndirectCommand*>(fDrawIndirectBuffer->map()); |
+ SkASSERT(glMappedCmds); |
+ } |
bool baseInstanceSupport = this->glGpu()->glCaps().baseInstanceSupport(); |
+ SkASSERT(!baseInstanceSupport || fDrawIndirectBuffer); |
+ SkASSERT(!fGLDrawCmdsInfo); |
if (GR_GL_LOG_INSTANCED_BATCHES || !baseInstanceSupport) { |
fGLDrawCmdsInfo.reset(numGLDrawCmds); |
} |
@@ -160,18 +170,19 @@ void GLInstancedRendering::onBeginFlush(GrResourceProvider* rp) { |
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 (fDrawIndirectBuffer) { |
+ 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 |
+ GLDrawCmdInfo& cmdInfo = fGLDrawCmdsInfo[glDrawCmdsIdx]; |
+ cmdInfo.fGeometry = geometry; |
+ cmdInfo.fInstanceCount = instanceCount; |
} |
glInstancesIdx += instanceCount; |
@@ -180,7 +191,9 @@ void GLInstancedRendering::onBeginFlush(GrResourceProvider* rp) { |
} |
SkASSERT(glDrawCmdsIdx == numGLDrawCmds); |
- fDrawIndirectBuffer->unmap(); |
+ if (fDrawIndirectBuffer) { |
+ fDrawIndirectBuffer->unmap(); |
+ } |
SkASSERT(glInstancesIdx == numGLInstances); |
fInstanceBuffer->unmap(); |
@@ -188,14 +201,16 @@ void GLInstancedRendering::onBeginFlush(GrResourceProvider* rp) { |
void GLInstancedRendering::onDraw(const GrPipeline& pipeline, const InstanceProcessor& instProc, |
const Batch* baseBatch) { |
- if (!fDrawIndirectBuffer) { |
+ if (!fDrawIndirectBuffer && !fGLDrawCmdsInfo) { |
return; // beginFlush was not successful. |
} |
if (!this->glGpu()->flushGLState(pipeline, instProc)) { |
return; |
} |
- this->glGpu()->bindBuffer(kDrawIndirect_GrBufferType, fDrawIndirectBuffer.get()); |
+ if (fDrawIndirectBuffer) { |
+ this->glGpu()->bindBuffer(kDrawIndirect_GrBufferType, fDrawIndirectBuffer.get()); |
+ } |
const GrGLCaps& glCaps = this->glGpu()->glCaps(); |
const GLBatch* batch = static_cast<const GLBatch*>(baseBatch); |
@@ -214,23 +229,33 @@ void GLInstancedRendering::onDraw(const GrPipeline& pipeline, const InstanceProc |
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 { |
+ if (numCommands > 1 && glCaps.multiDrawIndirectSupport() && glCaps.baseInstanceSupport()) { |
+ SkASSERT(fDrawIndirectBuffer); |
int glCmdsIdx = batch->fGLDrawCmdsIdx; |
this->flushInstanceAttribs(batch->fEmulatedBaseInstance); |
GL_CALL(MultiDrawElementsIndirect(GR_GL_TRIANGLES, GR_GL_UNSIGNED_BYTE, |
(GrGLDrawElementsIndirectCommand*) nullptr + glCmdsIdx, |
numCommands, 0)); |
+ return; |
+ } |
+ |
+ int emulatedBaseInstance = batch->fEmulatedBaseInstance; |
+ for (int i = 0; i < numCommands; ++i) { |
+ int glCmdIdx = batch->fGLDrawCmdsIdx + i; |
+ const GLDrawCmdInfo& cmdInfo = fGLDrawCmdsInfo[glCmdIdx]; |
+ this->flushInstanceAttribs(emulatedBaseInstance); |
+ if (fDrawIndirectBuffer) { |
+ GL_CALL(DrawElementsIndirect(GR_GL_TRIANGLES, GR_GL_UNSIGNED_BYTE, |
+ (GrGLDrawElementsIndirectCommand*) nullptr + glCmdIdx)); |
+ } else { |
+ GL_CALL(DrawElementsInstanced(GR_GL_TRIANGLES, cmdInfo.fGeometry.fCount, |
+ GR_GL_UNSIGNED_BYTE, |
+ (GrGLubyte*) nullptr + cmdInfo.fGeometry.fStart, |
+ cmdInfo.fInstanceCount)); |
+ } |
+ if (!glCaps.baseInstanceSupport()) { |
+ emulatedBaseInstance += cmdInfo.fInstanceCount; |
+ } |
} |
} |