Revert "Move setupGeometry() from GrGLGpu to GrGLOpsRenderPass"

This reverts commit b67081f9cb.

Reason for revert: Crash in glDeleteProgram on ES2

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>

TBR=bsalomon@google.com,csmartdalton@google.com

Change-Id: Ibd1ae7c01ac8ac6ade94f6d542a6b711f53e7fb6
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/274021
Reviewed-by: Chris Dalton <csmartdalton@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
This commit is contained in:
Chris Dalton 2020-02-28 15:37:53 +00:00 committed by Skia Commit-Bot
parent 55f681faf3
commit 20e7a53cd2
5 changed files with 176 additions and 159 deletions

View File

@ -425,6 +425,7 @@ GrGLGpu::~GrGLGpu() {
fCopyProgramArrayBuffer.reset();
fMipmapProgramArrayBuffer.reset();
fHWProgram.reset();
if (fHWProgramID) {
// detach the current program so there is no confusion on OpenGL's part
// that we want it to be deleted
@ -500,6 +501,7 @@ void GrGLGpu::disconnect(DisconnectType type) {
}
}
fHWProgram.reset();
fProgramCache.reset();
fHWProgramID = 0;
@ -660,6 +662,7 @@ void GrGLGpu::onResetContext(uint32_t resetBits) {
if (resetBits & kProgram_GrGLBackendState) {
fHWProgramID = 0;
fHWProgram.reset();
}
++fResetTimestampForTextureParameters;
}
@ -1762,7 +1765,6 @@ void GrGLGpu::flushScissorTest(GrScissorTest scissorTest) {
void GrGLGpu::flushScissorRect(const SkIRect& scissor, int rtWidth, int rtHeight,
GrSurfaceOrigin rtOrigin) {
SkASSERT(TriState::kYes_TriState == fHWScissorSettings.fEnabled);
auto nativeScissor = GrNativeRect::MakeRelativeTo(rtOrigin, rtHeight, scissor);
if (fHWScissorSettings.fRect != nativeScissor) {
GL_CALL(Scissor(nativeScissor.fX, nativeScissor.fY, nativeScissor.fWidth,
@ -1811,27 +1813,26 @@ void GrGLGpu::disableWindowRectangles() {
#endif
}
sk_sp<GrGLProgram> GrGLGpu::flushGLState(GrRenderTarget* renderTarget,
const GrProgramInfo& programInfo) {
bool GrGLGpu::flushGLState(GrRenderTarget* renderTarget, const GrProgramInfo& programInfo) {
this->handleDirtyContext();
sk_sp<GrGLProgram> program = fProgramCache->findOrCreateProgram(renderTarget, programInfo);
if (!program) {
GrCapsDebugf(this->caps(), "Failed to create program!\n");
return nullptr;
}
this->flushProgram(program->programID());
if (GrPrimitiveType::kPatches == programInfo.primitiveType()) {
this->flushPatchVertexCount(programInfo.tessellationPatchVertexCount());
}
sk_sp<GrGLProgram> program(fProgramCache->findOrCreateProgram(renderTarget, programInfo));
if (!program) {
GrCapsDebugf(this->caps(), "Failed to create program!\n");
return false;
}
this->flushProgram(std::move(program));
// Swizzle the blend to match what the shader will output.
this->flushBlendAndColorWrite(programInfo.pipeline().getXferProcessor().getBlendInfo(),
programInfo.pipeline().outputSwizzle());
program->updateUniforms(renderTarget, programInfo);
fHWProgram->updateUniforms(renderTarget, programInfo);
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(renderTarget);
GrStencilSettings stencil;
@ -1853,18 +1854,85 @@ sk_sp<GrGLProgram> GrGLGpu::flushGLState(GrRenderTarget* renderTarget,
// to be msaa-resolved (which will modify bound FBO state).
this->flushRenderTarget(glRT);
return program;
return true;
}
void GrGLGpu::flushProgram(sk_sp<GrGLProgram> program) {
if (!program) {
fHWProgram.reset();
fHWProgramID = 0;
return;
}
SkASSERT((program == fHWProgram) == (fHWProgramID == program->programID()));
if (program == fHWProgram) {
return;
}
auto id = program->programID();
SkASSERT(id);
GL_CALL(UseProgram(id));
fHWProgram = std::move(program);
fHWProgramID = id;
}
void GrGLGpu::flushProgram(GrGLuint id) {
SkASSERT(id);
if (fHWProgramID == id) {
SkASSERT(!fHWProgram);
return;
}
fHWProgram.reset();
GL_CALL(UseProgram(id));
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();
@ -2257,8 +2325,6 @@ void GrGLGpu::flushViewport(int width, int height) {
}
GrGLenum GrGLGpu::prepareToDraw(GrPrimitiveType primitiveType) {
fStats.incNumDraws();
if (this->glCaps().requiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines() &&
GrIsPrimTypeLines(primitiveType) && !GrIsPrimTypeLines(fLastPrimitiveType)) {
GL_CALL(Enable(GR_GL_CULL_FACE));
@ -2286,40 +2352,72 @@ GrGLenum GrGLGpu::prepareToDraw(GrPrimitiveType primitiveType) {
SK_ABORT("invalid GrPrimitiveType");
}
void GrGLGpu::drawArrays(GrPrimitiveType primitiveType, GrGLint baseVertex, GrGLsizei vertexCount) {
SkASSERT(!this->glCaps().drawArraysBaseVertexIsBroken() || 0 == baseVertex);
void GrGLGpu::draw(GrPrimitiveType primitiveType, const GrBuffer* vertexBuffer, int vertexCount,
int baseVertex) {
GrGLenum glPrimType = this->prepareToDraw(primitiveType);
GL_CALL(DrawArrays(glPrimType, baseVertex, vertexCount));
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();
}
void GrGLGpu::drawElements(GrPrimitiveType primitiveType, GrGLsizei indexCount, GrGLenum indexType,
const void* indices) {
GrGLenum glPrimType = this->prepareToDraw(primitiveType);
GL_CALL(DrawElements(glPrimType, indexCount, indexType, indices));
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::drawRangeElements(GrPrimitiveType primitiveType, GrGLuint minIndexValue,
GrGLuint maxIndexValue, GrGLsizei indexCount, GrGLenum indexType,
const void* indices) {
SkASSERT(this->glCaps().drawRangeElementsSupport());
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) {
GrGLenum glPrimType = this->prepareToDraw(primitiveType);
GL_CALL(DrawRangeElements(glPrimType, minIndexValue, maxIndexValue, indexCount, indexType,
indices));
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();
}
void GrGLGpu::drawArraysInstanced(GrPrimitiveType primitiveType, GrGLint baseVertex,
GrGLsizei vertexCount, GrGLsizei instanceCount) {
SkASSERT(instanceCount <= this->glCaps().maxInstancesPerDrawWithoutCrashing(instanceCount));
void GrGLGpu::drawInstanced(GrPrimitiveType primitiveType, const GrBuffer* instanceBuffer,
int instanceCount, int baseInstance, const GrBuffer* vertexBuffer,
int vertexCount, int baseVertex) {
GrGLenum glPrimType = this->prepareToDraw(primitiveType);
GL_CALL(DrawArraysInstanced(glPrimType, baseVertex, vertexCount, instanceCount));
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();
}
}
void GrGLGpu::drawElementsInstanced(GrPrimitiveType primitiveType, GrGLsizei indexCount,
GrGLenum indexType, const void* indices,
GrGLsizei instanceCount) {
SkASSERT(instanceCount <= this->glCaps().maxInstancesPerDrawWithoutCrashing(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) {
GrGLenum glPrimType = this->prepareToDraw(primitiveType);
GL_CALL(DrawElementsInstanced(glPrimType, indexCount, indexType, indices, instanceCount));
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();
}
}
void GrGLGpu::onResolveRenderTarget(GrRenderTarget* target, const SkIRect& resolveRect,
@ -3824,7 +3922,6 @@ void GrGLGpu::testingOnly_flushGpuAndSync() {
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()) {

View File

@ -73,42 +73,26 @@ public:
// If the caller wishes to bind an index buffer to a specific VAO, it can call glBind directly.
GrGLenum bindBuffer(GrGpuBufferType type, const GrBuffer*);
// Flushes state from GrProgramInfo to GL. Returns nullptr if the state couldn't be set.
// The returned GrGLProgram can be used for binding textures and vertex attributes.
//
// The caller must keep the returned GrGLProgram alive until it is done issuing draws.
sk_sp<GrGLProgram> flushGLState(GrRenderTarget*, const GrProgramInfo&) SK_WARN_UNUSED_RESULT;
// 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);
// Binds the vertex array that should be used for internal draws, enables 'numAttribs' vertex
// arrays, and flushes the desired primitive restart settings. The returned GrGLAttribArrayState
// should be used to set vertex attribute arrays.
//
// 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;
void bindTextures(const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline,
const GrSurfaceProxy* const primProcTextures[] = nullptr) {
fHWProgram->bindTextures(primProc, pipeline, primProcTextures);
}
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 (via flushGLState(),
// flushScissor(), and bindInternalVertexArray()).
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);
// 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);
// 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
@ -304,9 +288,19 @@ private:
// binds texture unit in GL
void setTextureUnit(int unitIdx);
void flushProgram(sk_sp<GrGLProgram>);
// 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);
@ -469,6 +463,7 @@ private:
int fHWActiveTextureUnitIdx;
GrGLuint fHWProgramID;
sk_sp<GrGLProgram> fHWProgram;
enum TriState {
kNo_TriState,
@ -573,7 +568,7 @@ private:
* 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 provided, it will be bound to the vertex array. Otherwise the
* If an index buffer is privided, 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.

View File

@ -28,8 +28,7 @@ void GrGLOpsRenderPass::set(GrRenderTarget* rt, const SkIRect& contentBounds,
bool GrGLOpsRenderPass::onBindPipeline(const GrProgramInfo& programInfo,
const SkRect& drawBounds) {
fPrimitiveType = programInfo.primitiveType();
fGLProgram = fGpu->flushGLState(fRenderTarget, programInfo);
return SkToBool(fGLProgram);
return fGpu->flushGLState(fRenderTarget, programInfo);
}
void GrGLOpsRenderPass::onSetScissorRect(const SkIRect& scissor) {
@ -39,104 +38,36 @@ void GrGLOpsRenderPass::onSetScissorRect(const SkIRect& scissor) {
bool GrGLOpsRenderPass::onBindTextures(const GrPrimitiveProcessor& primProc,
const GrPipeline& pipeline,
const GrSurfaceProxy* const primProcTextures[]) {
fGLProgram->bindTextures(primProc, pipeline, primProcTextures);
fGpu->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);
int numAttribs = fGLProgram->numVertexAttributes() + fGLProgram->numInstanceAttributes();
auto* attribState = fGpu->bindInternalVertexArray(indexBuffer, numAttribs, primitiveRestart);
if (int vertexStride = fGLProgram->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 < fGLProgram->numVertexAttributes(); ++i) {
const auto& attrib = fGLProgram->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 = fGLProgram->instanceStride()) {
SkASSERT(instanceBuffer);
SkASSERT(instanceBuffer->isCpuBuffer() ||
!static_cast<const GrGpuBuffer*>(instanceBuffer)->isMapped());
size_t bufferOffset = baseInstance * static_cast<size_t>(instanceStride);
int attribIdx = fGLProgram->numVertexAttributes();
for (int i = 0; i < fGLProgram->numInstanceAttributes(); ++i, ++attribIdx) {
const auto& attrib = fGLProgram->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) {
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);
fGpu->draw(fPrimitiveType, vertexBuffer, vertexCount, baseVertex);
}
void GrGLOpsRenderPass::onDrawIndexed(const GrBuffer* indexBuffer, int indexCount, int baseIndex,
GrPrimitiveRestart primitiveRestart, uint16_t minIndexValue,
uint16_t maxIndexValue, const GrBuffer* vertexBuffer,
int 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);
}
fGpu->drawIndexed(fPrimitiveType, indexBuffer, indexCount, baseIndex, primitiveRestart,
minIndexValue, maxIndexValue, vertexBuffer, baseVertex);
}
void GrGLOpsRenderPass::onDrawInstanced(const GrBuffer* instanceBuffer, int instanceCount,
int baseInstance, const GrBuffer* vertexBuffer,
int vertexCount, int 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));
}
fGpu->drawInstanced(fPrimitiveType, instanceBuffer, instanceCount, baseInstance, vertexBuffer,
vertexCount, baseVertex);
}
void GrGLOpsRenderPass::onDrawIndexedInstanced(
const GrBuffer* indexBuffer, int indexCount, int baseIndex,
GrPrimitiveRestart primitiveRestart, const GrBuffer* instanceBuffer, int instanceCount,
int baseInstance, const GrBuffer* vertexBuffer, int 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));
}
fGpu->drawIndexedInstanced(fPrimitiveType, indexBuffer, indexCount, baseIndex, primitiveRestart,
instanceBuffer, instanceCount, baseInstance, vertexBuffer,
baseVertex);
}
void GrGLOpsRenderPass::onClear(const GrFixedClip& clip, const SkPMColor4f& color) {

View File

@ -49,10 +49,6 @@ public:
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,
@ -76,7 +72,6 @@ private:
StencilLoadAndStoreInfo fStencilLoadAndStoreInfo;
// Per-pipeline state.
sk_sp<GrGLProgram> fGLProgram;
GrPrimitiveType fPrimitiveType;
typedef GrOpsRenderPass INHERITED;

View File

@ -115,15 +115,14 @@ void GrGLPathRendering::onDrawPath(GrRenderTarget* renderTarget,
const GrPath* path) {
SkASSERT(!programInfo.hasDynamicScissors());
SkASSERT(!programInfo.hasDynamicPrimProcTextures());
sk_sp<GrGLProgram> program = this->gpu()->flushGLState(renderTarget, programInfo);
if (!program) {
if (!this->gpu()->flushGLState(renderTarget, programInfo)) {
return;
}
if (programInfo.hasFixedScissor()) {
this->gpu()->flushScissorRect(programInfo.fixedScissor(), renderTarget->width(),
renderTarget->height(), programInfo.origin());
}
program->bindTextures(programInfo.primProc(), programInfo.pipeline(), nullptr);
this->gpu()->bindTextures(programInfo.primProc(), programInfo.pipeline());
const GrGLPath* glPath = static_cast<const GrGLPath*>(path);