| 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;
|
| + }
|
| }
|
| }
|
|
|
|
|