Reland "Move setupGeometry() from GrGLGpu to GrGLOpsRenderPass"
This is a reland of b67081f9cb4444c5430075c0822c78c3f9adeefe
Original change's description:
> Move setupGeometry() from GrGLGpu to GrGLOpsRenderPass
>
> Change-Id: I8788b96e07216be738c0ce1babb810b05bf46694
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/273696
> Reviewed-by: Brian Salomon <bsalomon@google.com>
> Commit-Queue: Chris Dalton <csmartdalton@google.com>
Change-Id: Ic30c9e1b1d9a3ae29623ff8239b9b1d7b2dad273
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/274057
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index fbc6ff5..92820b7 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -1765,6 +1765,7 @@
void GrGLGpu::flushScissorRect(const SkIRect& scissor, int rtWidth, int rtHeight,
GrSurfaceOrigin rtOrigin) {
+ SkASSERT(fHWScissorSettings.fEnabled == TriState::kYes_TriState);
auto nativeScissor = GrNativeRect::MakeRelativeTo(rtOrigin, rtHeight, scissor);
if (fHWScissorSettings.fRect != nativeScissor) {
GL_CALL(Scissor(nativeScissor.fX, nativeScissor.fY, nativeScissor.fWidth,
@@ -1813,14 +1814,11 @@
#endif
}
-bool GrGLGpu::flushGLState(GrRenderTarget* renderTarget, const GrProgramInfo& programInfo) {
+bool GrGLGpu::flushGLState(GrRenderTarget* renderTarget,
+ const GrProgramInfo& programInfo) {
this->handleDirtyContext();
- if (GrPrimitiveType::kPatches == programInfo.primitiveType()) {
- this->flushPatchVertexCount(programInfo.tessellationPatchVertexCount());
- }
-
- sk_sp<GrGLProgram> program(fProgramCache->findOrCreateProgram(renderTarget, programInfo));
+ sk_sp<GrGLProgram> program = fProgramCache->findOrCreateProgram(renderTarget, programInfo);
if (!program) {
GrCapsDebugf(this->caps(), "Failed to create program!\n");
return false;
@@ -1828,6 +1826,10 @@
this->flushProgram(std::move(program));
+ if (GrPrimitiveType::kPatches == programInfo.primitiveType()) {
+ this->flushPatchVertexCount(programInfo.tessellationPatchVertexCount());
+ }
+
// Swizzle the blend to match what the shader will output.
this->flushBlendAndColorWrite(programInfo.pipeline().getXferProcessor().getBlendInfo(),
programInfo.pipeline().outputSwizzle());
@@ -1885,54 +1887,6 @@
fHWProgramID = id;
}
-void GrGLGpu::setupGeometry(const GrBuffer* indexBuffer,
- const GrBuffer* vertexBuffer,
- int baseVertex,
- const GrBuffer* instanceBuffer,
- int baseInstance,
- GrPrimitiveRestart enablePrimitiveRestart) {
- SkASSERT((enablePrimitiveRestart == GrPrimitiveRestart::kNo) || indexBuffer);
-
- GrGLAttribArrayState* attribState;
- if (indexBuffer) {
- SkASSERT(indexBuffer->isCpuBuffer() ||
- !static_cast<const GrGpuBuffer*>(indexBuffer)->isMapped());
- attribState = fHWVertexArrayState.bindInternalVertexArray(this, indexBuffer);
- } else {
- attribState = fHWVertexArrayState.bindInternalVertexArray(this);
- }
-
- int numAttribs = fHWProgram->numVertexAttributes() + fHWProgram->numInstanceAttributes();
- attribState->enableVertexArrays(this, numAttribs, enablePrimitiveRestart);
-
- if (int vertexStride = fHWProgram->vertexStride()) {
- SkASSERT(vertexBuffer);
- SkASSERT(vertexBuffer->isCpuBuffer() ||
- !static_cast<const GrGpuBuffer*>(vertexBuffer)->isMapped());
- size_t bufferOffset = baseVertex * static_cast<size_t>(vertexStride);
- for (int i = 0; i < fHWProgram->numVertexAttributes(); ++i) {
- const auto& attrib = fHWProgram->vertexAttribute(i);
- static constexpr int kDivisor = 0;
- attribState->set(this, attrib.fLocation, vertexBuffer, attrib.fCPUType, attrib.fGPUType,
- vertexStride, bufferOffset + attrib.fOffset, kDivisor);
- }
- }
- if (int instanceStride = fHWProgram->instanceStride()) {
- SkASSERT(instanceBuffer);
- SkASSERT(instanceBuffer->isCpuBuffer() ||
- !static_cast<const GrGpuBuffer*>(instanceBuffer)->isMapped());
- size_t bufferOffset = baseInstance * static_cast<size_t>(instanceStride);
- int attribIdx = fHWProgram->numVertexAttributes();
- for (int i = 0; i < fHWProgram->numInstanceAttributes(); ++i, ++attribIdx) {
- const auto& attrib = fHWProgram->instanceAttribute(i);
- static constexpr int kDivisor = 1;
- attribState->set(this, attrib.fLocation, instanceBuffer, attrib.fCPUType,
- attrib.fGPUType, instanceStride, bufferOffset + attrib.fOffset,
- kDivisor);
- }
- }
-}
-
GrGLenum GrGLGpu::bindBuffer(GrGpuBufferType type, const GrBuffer* buffer) {
this->handleDirtyContext();
@@ -2325,6 +2279,8 @@
}
GrGLenum GrGLGpu::prepareToDraw(GrPrimitiveType primitiveType) {
+ fStats.incNumDraws();
+
if (this->glCaps().requiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines() &&
GrIsPrimTypeLines(primitiveType) && !GrIsPrimTypeLines(fLastPrimitiveType)) {
GL_CALL(Enable(GR_GL_CULL_FACE));
@@ -2352,72 +2308,40 @@
SK_ABORT("invalid GrPrimitiveType");
}
-void GrGLGpu::draw(GrPrimitiveType primitiveType, const GrBuffer* vertexBuffer, int vertexCount,
- int baseVertex) {
+void GrGLGpu::drawArrays(GrPrimitiveType primitiveType, GrGLint baseVertex, GrGLsizei vertexCount) {
+ SkASSERT(!this->glCaps().drawArraysBaseVertexIsBroken() || 0 == baseVertex);
GrGLenum glPrimType = this->prepareToDraw(primitiveType);
- if (this->glCaps().drawArraysBaseVertexIsBroken()) {
- this->setupGeometry(nullptr, vertexBuffer, baseVertex, nullptr, 0, GrPrimitiveRestart::kNo);
- GL_CALL(DrawArrays(glPrimType, 0, vertexCount));
- } else {
- this->setupGeometry(nullptr, vertexBuffer, 0, nullptr, 0, GrPrimitiveRestart::kNo);
- GL_CALL(DrawArrays(glPrimType, baseVertex, vertexCount));
- }
- fStats.incNumDraws();
+ GL_CALL(DrawArrays(glPrimType, baseVertex, vertexCount));
}
-static const GrGLvoid* element_ptr(const GrBuffer* indexBuffer, int baseIndex) {
- size_t baseOffset = baseIndex * sizeof(uint16_t);
- if (indexBuffer->isCpuBuffer()) {
- return static_cast<const GrCpuBuffer*>(indexBuffer)->data() + baseOffset;
- } else {
- return reinterpret_cast<const GrGLvoid*>(baseOffset);
- }
+void GrGLGpu::drawElements(GrPrimitiveType primitiveType, GrGLsizei indexCount, GrGLenum indexType,
+ const void* indices) {
+ GrGLenum glPrimType = this->prepareToDraw(primitiveType);
+ GL_CALL(DrawElements(glPrimType, indexCount, indexType, indices));
}
-void GrGLGpu::drawIndexed(GrPrimitiveType primitiveType, const GrBuffer* indexBuffer,
- int indexCount, int baseIndex, GrPrimitiveRestart primitiveRestart,
- uint16_t minIndexValue, uint16_t maxIndexValue,
- const GrBuffer* vertexBuffer, int baseVertex) {
+void GrGLGpu::drawRangeElements(GrPrimitiveType primitiveType, GrGLuint minIndexValue,
+ GrGLuint maxIndexValue, GrGLsizei indexCount, GrGLenum indexType,
+ const void* indices) {
+ SkASSERT(this->glCaps().drawRangeElementsSupport());
GrGLenum glPrimType = this->prepareToDraw(primitiveType);
- const GrGLvoid* elementPtr = element_ptr(indexBuffer, baseIndex);
- this->setupGeometry(indexBuffer, vertexBuffer, baseVertex, nullptr, 0, primitiveRestart);
- if (this->glCaps().drawRangeElementsSupport()) {
- GL_CALL(DrawRangeElements(glPrimType, minIndexValue, maxIndexValue, indexCount,
- GR_GL_UNSIGNED_SHORT, elementPtr));
- } else {
- GL_CALL(DrawElements(glPrimType, indexCount, GR_GL_UNSIGNED_SHORT, elementPtr));
- }
- fStats.incNumDraws();
+ GL_CALL(DrawRangeElements(glPrimType, minIndexValue, maxIndexValue, indexCount, indexType,
+ indices));
}
-void GrGLGpu::drawInstanced(GrPrimitiveType primitiveType, const GrBuffer* instanceBuffer,
- int instanceCount, int baseInstance, const GrBuffer* vertexBuffer,
- int vertexCount, int baseVertex) {
+void GrGLGpu::drawArraysInstanced(GrPrimitiveType primitiveType, GrGLint baseVertex,
+ GrGLsizei vertexCount, GrGLsizei instanceCount) {
+ SkASSERT(instanceCount <= this->glCaps().maxInstancesPerDrawWithoutCrashing(instanceCount));
GrGLenum glPrimType = this->prepareToDraw(primitiveType);
- int maxInstances = this->glCaps().maxInstancesPerDrawWithoutCrashing(instanceCount);
- for (int i = 0; i < instanceCount; i += maxInstances) {
- this->setupGeometry(nullptr, vertexBuffer, 0, instanceBuffer, baseInstance + i,
- GrPrimitiveRestart::kNo);
- GL_CALL(DrawArraysInstanced(glPrimType, baseVertex, vertexCount,
- std::min(instanceCount - i, maxInstances)));
- fStats.incNumDraws();
- }
+ GL_CALL(DrawArraysInstanced(glPrimType, baseVertex, vertexCount, instanceCount));
}
-void GrGLGpu::drawIndexedInstanced(
- GrPrimitiveType primitiveType, const GrBuffer* indexBuffer, int indexCount, int baseIndex,
- GrPrimitiveRestart primitiveRestart, const GrBuffer* instanceBuffer, int instanceCount,
- int baseInstance, const GrBuffer* vertexBuffer, int baseVertex) {
+void GrGLGpu::drawElementsInstanced(GrPrimitiveType primitiveType, GrGLsizei indexCount,
+ GrGLenum indexType, const void* indices,
+ GrGLsizei instanceCount) {
+ SkASSERT(instanceCount <= this->glCaps().maxInstancesPerDrawWithoutCrashing(instanceCount));
GrGLenum glPrimType = this->prepareToDraw(primitiveType);
- const GrGLvoid* elementPtr = element_ptr(indexBuffer, baseIndex);
- int maxInstances = this->glCaps().maxInstancesPerDrawWithoutCrashing(instanceCount);
- for (int i = 0; i < instanceCount; i += maxInstances) {
- this->setupGeometry(indexBuffer, vertexBuffer, baseVertex,
- instanceBuffer, baseInstance + i, primitiveRestart);
- GL_CALL(DrawElementsInstanced(glPrimType, indexCount, GR_GL_UNSIGNED_SHORT, elementPtr,
- std::min(instanceCount - i, maxInstances)));
- fStats.incNumDraws();
- }
+ GL_CALL(DrawElementsInstanced(glPrimType, indexCount, indexType, indices, instanceCount));
}
void GrGLGpu::onResolveRenderTarget(GrRenderTarget* target, const SkIRect& resolveRect,
@@ -3922,6 +3846,7 @@
GrGLAttribArrayState* GrGLGpu::HWVertexArrayState::bindInternalVertexArray(GrGLGpu* gpu,
const GrBuffer* ibuf) {
+ SkASSERT(!ibuf || ibuf->isCpuBuffer() || !static_cast<const GrGpuBuffer*>(ibuf)->isMapped());
GrGLAttribArrayState* attribState;
if (gpu->glCaps().isCoreProfile()) {
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index f6cc07c..fef400e 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -76,23 +76,46 @@
// Flushes state from GrProgramInfo to GL. Returns false if the state couldn't be set.
bool flushGLState(GrRenderTarget*, const GrProgramInfo&);
void flushScissorRect(const SkIRect&, int rtWidth, int rtHeight, GrSurfaceOrigin);
- void bindTextures(const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline,
- const GrSurfaceProxy* const primProcTextures[] = nullptr) {
- fHWProgram->bindTextures(primProc, pipeline, primProcTextures);
+
+ // Returns the last program bound by flushGLState(), or nullptr if a different program has since
+ // been put into use via some other method (e.g., resetContext, copySurfaceAsDraw).
+ // The returned GrGLProgram can be used for binding textures and vertex attributes.
+ GrGLProgram* currentProgram() {
+ this->handleDirtyContext();
+ return fHWProgram.get();
}
- // These methods issue draws using the current GL state. The client must call flushGLState,
- // followed by flushScissorRect and/or bindTextures if applicable, before using these method.
- void draw(GrPrimitiveType, const GrBuffer* vertexBuffer, int vertexCount, int baseVertex);
- void drawIndexed(GrPrimitiveType, const GrBuffer* indexBuffer, int indexCount, int baseIndex,
- GrPrimitiveRestart, uint16_t minIndexValue, uint16_t maxIndexValue,
- const GrBuffer* vertexBuffer, int baseVertex);
- void drawInstanced(GrPrimitiveType, const GrBuffer* instanceBuffer, int instanceCount, int
- baseInstance, const GrBuffer* vertexBuffer, int vertexCount, int baseVertex);
- void drawIndexedInstanced(GrPrimitiveType, const GrBuffer* indexBuffer, int indexCount,
- int baseIndex, GrPrimitiveRestart, const GrBuffer* instanceBuffer,
- int instanceCount, int baseInstance, const GrBuffer* vertexBuffer,
- int baseVertex);
+ // Binds the vertex array that should be used for internal draws, enables 'numAttribs' vertex
+ // arrays, and flushes the desired primitive restart settings. If an index buffer is provided,
+ // it will be bound to the vertex array. Otherwise the index buffer binding will be left
+ // unchanged.
+ //
+ // NOTE: This binds the default VAO (ID=zero) unless we are on a core profile, in which case we
+ // use a dummy array instead.
+ GrGLAttribArrayState* bindInternalVertexArray(const GrBuffer* indexBuffer, int numAttribs,
+ GrPrimitiveRestart primitiveRestart) {
+ auto* attribState = fHWVertexArrayState.bindInternalVertexArray(this, indexBuffer);
+ attribState->enableVertexArrays(this, numAttribs, primitiveRestart);
+ return attribState;
+ }
+ GrGLAttribArrayState* bindInternalVertexArray(const GrBuffer* indexBuffer, GrPrimitiveRestart);
+
+ // These methods invoke their GL namesakes, with added bookkeeping and assertions. The caller is
+ // responsible to ensure the desired GL state is configured before calling:
+ //
+ // - Call flushGLState()
+ // - If scissor test got enabled, call flushScissorRect()
+ // - If the pipeline has textures, call currentProgram()->bindTextures()
+ // - Setup index and attrib arrays via currentProgram()
+ void drawArrays(GrPrimitiveType, GrGLint baseVertex, GrGLsizei vertexCount);
+ void drawElements(GrPrimitiveType, GrGLsizei indexCount, GrGLenum indexType,
+ const void* indices);
+ void drawRangeElements(GrPrimitiveType, GrGLuint minIndexValue, GrGLuint maxIndexValue,
+ GrGLsizei indexCount, GrGLenum indexType, const void* indices);
+ void drawArraysInstanced(GrPrimitiveType, GrGLint baseVertex, GrGLsizei vertexCount,
+ GrGLsizei instanceCount);
+ void drawElementsInstanced(GrPrimitiveType, GrGLsizei indexCount, GrGLenum indexType,
+ const void* indices, GrGLsizei instanceCount);
// The GrGLOpsRenderPass does not buffer up draws before submitting them to the gpu.
// Thus this is the implementation of the clear call for the corresponding passthrough function
@@ -293,14 +316,6 @@
// Version for programs that aren't GrGLProgram.
void flushProgram(GrGLuint);
- // Sets up vertex/instance attribute pointers and strides.
- void setupGeometry(const GrBuffer* indexBuffer,
- const GrBuffer* vertexBuffer,
- int baseVertex,
- const GrBuffer* instanceBuffer,
- int baseInstance,
- GrPrimitiveRestart);
-
// Applies any necessary workarounds and returns the GL primitive type to use in draw calls.
GrGLenum prepareToDraw(GrPrimitiveType primitiveType);
@@ -568,7 +583,7 @@
* state. This binds the default VAO (ID=zero) unless we are on a core profile, in which
* case we use a dummy array instead.
*
- * If an index buffer is privided, it will be bound to the vertex array. Otherwise the
+ * If an index buffer is provided, it will be bound to the vertex array. Otherwise the
* index buffer binding will be left unchanged.
*
* The returned GrGLAttribArrayState should be used to set vertex attribute arrays.
diff --git a/src/gpu/gl/GrGLOpsRenderPass.cpp b/src/gpu/gl/GrGLOpsRenderPass.cpp
index 60af18e..27c8a11 100644
--- a/src/gpu/gl/GrGLOpsRenderPass.cpp
+++ b/src/gpu/gl/GrGLOpsRenderPass.cpp
@@ -38,36 +38,112 @@
bool GrGLOpsRenderPass::onBindTextures(const GrPrimitiveProcessor& primProc,
const GrPipeline& pipeline,
const GrSurfaceProxy* const primProcTextures[]) {
- fGpu->bindTextures(primProc, pipeline, primProcTextures);
+ GrGLProgram* program = fGpu->currentProgram();
+ if (!program) {
+ return false;
+ }
+ program->bindTextures(primProc, pipeline, primProcTextures);
return true;
}
+void GrGLOpsRenderPass::setupGeometry(const GrBuffer* indexBuffer, const GrBuffer* vertexBuffer,
+ int baseVertex, const GrBuffer* instanceBuffer,
+ int baseInstance, GrPrimitiveRestart primitiveRestart) {
+ SkASSERT((primitiveRestart == GrPrimitiveRestart::kNo) || indexBuffer);
+ GrGLProgram* program = fGpu->currentProgram();
+ if (!program) {
+ return;
+ }
+
+ int numAttribs = program->numVertexAttributes() + program->numInstanceAttributes();
+ auto* attribState = fGpu->bindInternalVertexArray(indexBuffer, numAttribs, primitiveRestart);
+
+ if (int vertexStride = program->vertexStride()) {
+ SkASSERT(vertexBuffer);
+ SkASSERT(vertexBuffer->isCpuBuffer() ||
+ !static_cast<const GrGpuBuffer*>(vertexBuffer)->isMapped());
+ size_t bufferOffset = baseVertex * static_cast<size_t>(vertexStride);
+ for (int i = 0; i < program->numVertexAttributes(); ++i) {
+ const auto& attrib = program->vertexAttribute(i);
+ static constexpr int kDivisor = 0;
+ attribState->set(fGpu, attrib.fLocation, vertexBuffer, attrib.fCPUType, attrib.fGPUType,
+ vertexStride, bufferOffset + attrib.fOffset, kDivisor);
+ }
+ }
+ if (int instanceStride = program->instanceStride()) {
+ SkASSERT(instanceBuffer);
+ SkASSERT(instanceBuffer->isCpuBuffer() ||
+ !static_cast<const GrGpuBuffer*>(instanceBuffer)->isMapped());
+ size_t bufferOffset = baseInstance * static_cast<size_t>(instanceStride);
+ int attribIdx = program->numVertexAttributes();
+ for (int i = 0; i < program->numInstanceAttributes(); ++i, ++attribIdx) {
+ const auto& attrib = program->instanceAttribute(i);
+ static constexpr int kDivisor = 1;
+ attribState->set(fGpu, attrib.fLocation, instanceBuffer, attrib.fCPUType,
+ attrib.fGPUType, instanceStride, bufferOffset + attrib.fOffset,
+ kDivisor);
+ }
+ }
+}
+
+static const GrGLvoid* get_gl_index_ptr(const GrBuffer* indexBuffer, int baseIndex) {
+ size_t baseOffset = baseIndex * sizeof(uint16_t);
+ if (indexBuffer->isCpuBuffer()) {
+ return static_cast<const GrCpuBuffer*>(indexBuffer)->data() + baseOffset;
+ } else {
+ return reinterpret_cast<const GrGLvoid*>(baseOffset);
+ }
+}
+
void GrGLOpsRenderPass::onDraw(const GrBuffer* vertexBuffer, int vertexCount, int baseVertex) {
- fGpu->draw(fPrimitiveType, vertexBuffer, vertexCount, baseVertex);
+ if (fGpu->glCaps().drawArraysBaseVertexIsBroken()) {
+ this->setupGeometry(nullptr, vertexBuffer, baseVertex, nullptr, 0, GrPrimitiveRestart::kNo);
+ fGpu->drawArrays(fPrimitiveType, 0, vertexCount);
+ return;
+ }
+
+ this->setupGeometry(nullptr, vertexBuffer, 0, nullptr, 0, GrPrimitiveRestart::kNo);
+ fGpu->drawArrays(fPrimitiveType, baseVertex, vertexCount);
}
void GrGLOpsRenderPass::onDrawIndexed(const GrBuffer* indexBuffer, int indexCount, int baseIndex,
GrPrimitiveRestart primitiveRestart, uint16_t minIndexValue,
uint16_t maxIndexValue, const GrBuffer* vertexBuffer,
int baseVertex) {
- fGpu->drawIndexed(fPrimitiveType, indexBuffer, indexCount, baseIndex, primitiveRestart,
- minIndexValue, maxIndexValue, vertexBuffer, baseVertex);
+ const GrGLvoid* indexPtr = get_gl_index_ptr(indexBuffer, baseIndex);
+ this->setupGeometry(indexBuffer, vertexBuffer, baseVertex, nullptr, 0, primitiveRestart);
+ if (fGpu->glCaps().drawRangeElementsSupport()) {
+ fGpu->drawRangeElements(fPrimitiveType, minIndexValue, maxIndexValue, indexCount,
+ GR_GL_UNSIGNED_SHORT, indexPtr);
+ } else {
+ fGpu->drawElements(fPrimitiveType, indexCount, GR_GL_UNSIGNED_SHORT, indexPtr);
+ }
}
void GrGLOpsRenderPass::onDrawInstanced(const GrBuffer* instanceBuffer, int instanceCount,
int baseInstance, const GrBuffer* vertexBuffer,
int vertexCount, int baseVertex) {
- fGpu->drawInstanced(fPrimitiveType, instanceBuffer, instanceCount, baseInstance, vertexBuffer,
- vertexCount, baseVertex);
+ int maxInstances = fGpu->glCaps().maxInstancesPerDrawWithoutCrashing(instanceCount);
+ for (int i = 0; i < instanceCount; i += maxInstances) {
+ this->setupGeometry(nullptr, vertexBuffer, 0, instanceBuffer, baseInstance + i,
+ GrPrimitiveRestart::kNo);
+ fGpu->drawArraysInstanced(fPrimitiveType, baseVertex, vertexCount,
+ std::min(instanceCount - i, maxInstances));
+ }
}
void GrGLOpsRenderPass::onDrawIndexedInstanced(
const GrBuffer* indexBuffer, int indexCount, int baseIndex,
GrPrimitiveRestart primitiveRestart, const GrBuffer* instanceBuffer, int instanceCount,
int baseInstance, const GrBuffer* vertexBuffer, int baseVertex) {
- fGpu->drawIndexedInstanced(fPrimitiveType, indexBuffer, indexCount, baseIndex, primitiveRestart,
- instanceBuffer, instanceCount, baseInstance, vertexBuffer,
- baseVertex);
+ const GrGLvoid* indexPtr = get_gl_index_ptr(indexBuffer, baseIndex);
+ int maxInstances = fGpu->glCaps().maxInstancesPerDrawWithoutCrashing(instanceCount);
+ for (int i = 0; i < instanceCount; i += maxInstances) {
+ this->setupGeometry(indexBuffer, vertexBuffer, baseVertex,
+ instanceBuffer, baseInstance + i, primitiveRestart);
+ fGpu->drawElementsInstanced(fPrimitiveType, indexCount, GR_GL_UNSIGNED_SHORT, indexPtr,
+ std::min(instanceCount - i, maxInstances));
+ }
}
void GrGLOpsRenderPass::onClear(const GrFixedClip& clip, const SkPMColor4f& color) {
diff --git a/src/gpu/gl/GrGLOpsRenderPass.h b/src/gpu/gl/GrGLOpsRenderPass.h
index e79558d..5e4faef 100644
--- a/src/gpu/gl/GrGLOpsRenderPass.h
+++ b/src/gpu/gl/GrGLOpsRenderPass.h
@@ -49,6 +49,10 @@
private:
GrGpu* gpu() override { return fGpu; }
+ void setupGeometry(const GrBuffer* indexBuffer, const GrBuffer* vertexBuffer, int baseVertex,
+ const GrBuffer* instanceBuffer, int baseInstance,
+ GrPrimitiveRestart enablePrimitiveRestart);
+
bool onBindPipeline(const GrProgramInfo& programInfo, const SkRect& drawBounds) override;
void onSetScissorRect(const SkIRect& scissor) override;
bool onBindTextures(const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline,
diff --git a/src/gpu/gl/GrGLPathRendering.cpp b/src/gpu/gl/GrGLPathRendering.cpp
index abbd9d2..2d910a8 100644
--- a/src/gpu/gl/GrGLPathRendering.cpp
+++ b/src/gpu/gl/GrGLPathRendering.cpp
@@ -122,7 +122,8 @@
this->gpu()->flushScissorRect(programInfo.fixedScissor(), renderTarget->width(),
renderTarget->height(), programInfo.origin());
}
- this->gpu()->bindTextures(programInfo.primProc(), programInfo.pipeline());
+ this->gpu()->currentProgram()->bindTextures(
+ programInfo.primProc(), programInfo.pipeline(), nullptr);
const GrGLPath* glPath = static_cast<const GrGLPath*>(path);