@@ -232,6 +232,8 @@ static const void* buffer_offset_to_gl_address(const GrBuffer* drawIndirectBuffe
232232
233233void GrGLOpsRenderPass::onDrawIndirect (const GrBuffer* drawIndirectBuffer, size_t offset,
234234 int drawCount) {
235+ using MultiDrawType = GrGLCaps::MultiDrawType;
236+
235237 SkASSERT (fGpu ->caps ()->nativeDrawIndirectSupport ());
236238 SkASSERT (fGpu ->glCaps ().baseVertexBaseInstanceSupport ());
237239 SkASSERT (fDidBindVertexBuffer || fGpu ->glCaps ().drawArraysBaseVertexIsBroken ());
@@ -242,14 +244,15 @@ void GrGLOpsRenderPass::onDrawIndirect(const GrBuffer* drawIndirectBuffer, size_
242244 this ->bindVertexBuffer (fActiveVertexBuffer .get (), 0 );
243245 }
244246
245- if (fGpu ->glCaps ().ANGLEMultiDrawSupport ()) {
246- this ->multiDrawArraysANGLE (drawIndirectBuffer, offset, drawCount);
247+ if (fGpu ->glCaps ().multiDrawType () == MultiDrawType::kANGLEOrWebGL ) {
248+ // ANGLE and WebGL don't support glDrawElementsIndirect. We draw everything as a multi draw.
249+ this ->multiDrawArraysANGLEOrWebGL (drawIndirectBuffer, offset, drawCount);
247250 return ;
248251 }
249252
250253 fGpu ->bindBuffer (GrGpuBufferType::kDrawIndirect , drawIndirectBuffer);
251254
252- if (fGpu ->glCaps ().multiDrawIndirectSupport () && drawCount > 1 ) {
255+ if (drawCount > 1 && fGpu ->glCaps ().multiDrawType () == MultiDrawType:: kMultiDrawIndirect ) {
253256 GrGLenum glPrimType = fGpu ->prepareToDraw (fPrimitiveType );
254257 GL_CALL (MultiDrawArraysIndirect (glPrimType,
255258 buffer_offset_to_gl_address (drawIndirectBuffer, offset),
@@ -265,9 +268,9 @@ void GrGLOpsRenderPass::onDrawIndirect(const GrBuffer* drawIndirectBuffer, size_
265268 }
266269}
267270
268- void GrGLOpsRenderPass::multiDrawArraysANGLE (const GrBuffer* drawIndirectBuffer, size_t offset ,
269- int drawCount) {
270- SkASSERT (fGpu ->glCaps ().ANGLEMultiDrawSupport () );
271+ void GrGLOpsRenderPass::multiDrawArraysANGLEOrWebGL (const GrBuffer* drawIndirectBuffer,
272+ size_t offset, int drawCount) {
273+ SkASSERT (fGpu ->glCaps ().multiDrawType () == GrGLCaps::MultiDrawType:: kANGLEOrWebGL );
271274 SkASSERT (drawIndirectBuffer->isCpuBuffer ());
272275
273276 constexpr static int kMaxDrawCountPerBatch = 128 ;
@@ -289,30 +292,39 @@ void GrGLOpsRenderPass::multiDrawArraysANGLE(const GrBuffer* drawIndirectBuffer,
289292 fInstanceCounts [i] = cmd.fInstanceCount ;
290293 fBaseInstances [i] = cmd.fBaseInstance ;
291294 }
292- GL_CALL (MultiDrawArraysInstancedBaseInstance (glPrimType, fFirsts , fCounts , fInstanceCounts ,
293- fBaseInstances , countInBatch));
295+ if (countInBatch == 1 ) {
296+ GL_CALL (DrawArraysInstancedBaseInstance (glPrimType, fFirsts [0 ], fCounts [0 ],
297+ fInstanceCounts [0 ], fBaseInstances [0 ]));
298+ } else {
299+ GL_CALL (MultiDrawArraysInstancedBaseInstance (glPrimType, fFirsts , fCounts ,
300+ fInstanceCounts , fBaseInstances ,
301+ countInBatch));
302+ }
294303 drawCount -= countInBatch;
295304 cmds += countInBatch;
296305 }
297306}
298307
299308void GrGLOpsRenderPass::onDrawIndexedIndirect (const GrBuffer* drawIndirectBuffer, size_t offset,
300309 int drawCount) {
310+ using MultiDrawType = GrGLCaps::MultiDrawType;
311+
301312 SkASSERT (fGpu ->caps ()->nativeDrawIndirectSupport ());
302313 SkASSERT (!fGpu ->caps ()->nativeDrawIndexedIndirectIsBroken ());
303314 SkASSERT (fGpu ->glCaps ().baseVertexBaseInstanceSupport ());
304315 // The vertex buffer should have already gotten bound (as opposed us stashing it away during
305316 // onBindBuffers and not expecting to bind it until this point).
306317 SkASSERT (fDidBindVertexBuffer );
307318
308- if (fGpu ->glCaps ().ANGLEMultiDrawSupport ()) {
309- this ->multiDrawElementsANGLE (drawIndirectBuffer, offset, drawCount);
319+ if (fGpu ->glCaps ().multiDrawType () == MultiDrawType::kANGLEOrWebGL ) {
320+ // ANGLE and WebGL don't support glDrawElementsIndirect. We draw everything as a multi draw.
321+ this ->multiDrawElementsANGLEOrWebGL (drawIndirectBuffer, offset, drawCount);
310322 return ;
311323 }
312324
313325 fGpu ->bindBuffer (GrGpuBufferType::kDrawIndirect , drawIndirectBuffer);
314326
315- if (fGpu ->glCaps ().multiDrawIndirectSupport () && drawCount > 1 ) {
327+ if (drawCount > 1 && fGpu ->glCaps ().multiDrawType () == MultiDrawType:: kMultiDrawIndirect ) {
316328 GrGLenum glPrimType = fGpu ->prepareToDraw (fPrimitiveType );
317329 GL_CALL (MultiDrawElementsIndirect (glPrimType, GR_GL_UNSIGNED_SHORT,
318330 buffer_offset_to_gl_address (drawIndirectBuffer, offset),
@@ -328,9 +340,9 @@ void GrGLOpsRenderPass::onDrawIndexedIndirect(const GrBuffer* drawIndirectBuffer
328340 }
329341}
330342
331- void GrGLOpsRenderPass::multiDrawElementsANGLE (const GrBuffer* drawIndirectBuffer, size_t offset ,
332- int drawCount) {
333- SkASSERT (fGpu ->glCaps ().ANGLEMultiDrawSupport () );
343+ void GrGLOpsRenderPass::multiDrawElementsANGLEOrWebGL (const GrBuffer* drawIndirectBuffer,
344+ size_t offset, int drawCount) {
345+ SkASSERT (fGpu ->glCaps ().multiDrawType () == GrGLCaps::MultiDrawType:: kANGLEOrWebGL );
334346 SkASSERT (drawIndirectBuffer->isCpuBuffer ());
335347
336348 constexpr static int kMaxDrawCountPerBatch = 128 ;
@@ -354,10 +366,18 @@ void GrGLOpsRenderPass::multiDrawElementsANGLE(const GrBuffer* drawIndirectBuffe
354366 fBaseVertices [i] = cmd.fBaseVertex ;
355367 fBaseInstances [i] = cmd.fBaseInstance ;
356368 }
357- GL_CALL (MultiDrawElementsInstancedBaseVertexBaseInstance (glPrimType, fCounts ,
358- GR_GL_UNSIGNED_SHORT, fIndices ,
359- fInstanceCounts , fBaseVertices ,
360- fBaseInstances , countInBatch));
369+ if (countInBatch == 1 ) {
370+ GL_CALL (DrawElementsInstancedBaseVertexBaseInstance (glPrimType, fCounts [0 ],
371+ GR_GL_UNSIGNED_SHORT, fIndices [0 ],
372+ fInstanceCounts [0 ],
373+ fBaseVertices [0 ],
374+ fBaseInstances [0 ]));
375+ } else {
376+ GL_CALL (MultiDrawElementsInstancedBaseVertexBaseInstance (glPrimType, fCounts ,
377+ GR_GL_UNSIGNED_SHORT, fIndices ,
378+ fInstanceCounts , fBaseVertices ,
379+ fBaseInstances , countInBatch));
380+ }
361381 drawCount -= countInBatch;
362382 cmds += countInBatch;
363383 }
0 commit comments