Chromium Code Reviews| Index: src/gpu/gl/GrGLGpu.cpp |
| diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp |
| index c8c12a388d3fcf1aa730188e8210e4e0d55027f3..027d05cbfe2992a266e41e7b8faca1875bd5b15c 100644 |
| --- a/src/gpu/gl/GrGLGpu.cpp |
| +++ b/src/gpu/gl/GrGLGpu.cpp |
| @@ -188,12 +188,45 @@ static bool gPrintStartupSpew; |
| GrGLGpu::GrGLGpu(GrGLContext* ctx, GrContext* context) |
| : GrGpu(context) |
| - , fGLContext(ctx) { |
| + , fGLContext(ctx) |
| + , fProgramCache(new ProgramCache(this)) |
| + , fHWProgramID(0) |
| + , fTempSrcFBOID(0) |
| + , fTempDstFBOID(0) |
| + , fStencilClearFBOID(0) |
| + , fHWPLSEnabled(false) |
| + , fPLSHasBeenUsed(false) |
| + , fHWMinSampleShading(0.0) { |
| + for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) { |
| + fCopyPrograms[i].fProgram = 0; |
| + } |
| + fWireRectProgram.fProgram = 0; |
| + fPLSSetupProgram.fProgram = 0; |
| + |
| SkASSERT(ctx); |
| fCaps.reset(SkRef(ctx->caps())); |
| fHWBoundTextureUniqueIDs.reset(this->glCaps().glslCaps()->maxCombinedSamplers()); |
| + fHWBufferState[kVertex_GrBufferType].fGLTarget = GR_GL_ARRAY_BUFFER; |
| + fHWBufferState[kIndex_GrBufferType].fGLTarget = GR_GL_ELEMENT_ARRAY_BUFFER; |
| + fHWBufferState[kTexel_GrBufferType].fGLTarget = GR_GL_TEXTURE_BUFFER; |
| + fHWBufferState[kDrawIndirect_GrBufferType].fGLTarget = GR_GL_DRAW_INDIRECT_BUFFER; |
| + if (GrGLCaps::kChromium_TransferBufferType == this->glCaps().transferBufferType()) { |
| + fHWBufferState[kXferCpuToGpu_GrBufferType].fGLTarget = |
| + GR_GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM; |
| + fHWBufferState[kXferGpuToCpu_GrBufferType].fGLTarget = |
| + GR_GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM; |
| + } else { |
| + fHWBufferState[kXferCpuToGpu_GrBufferType].fGLTarget = GR_GL_PIXEL_UNPACK_BUFFER; |
| + fHWBufferState[kXferGpuToCpu_GrBufferType].fGLTarget = GR_GL_PIXEL_PACK_BUFFER; |
| + } |
| + GR_STATIC_ASSERT(6 == SK_ARRAY_COUNT(fHWBufferState)); |
| + |
| + if (this->glCaps().shaderCaps()->pathRenderingSupport()) { |
| + fPathRendering.reset(new GrGLPathRendering(this)); |
| + } |
| + |
| GrGLClearErr(this->glInterface()); |
| if (gPrintStartupSpew) { |
| const GrGLubyte* vendor; |
| @@ -212,35 +245,15 @@ GrGLGpu::GrGLGpu(GrGLContext* ctx, GrContext* context) |
| SkDebugf("\n"); |
| SkDebugf("%s", this->glCaps().dump().c_str()); |
| } |
| - |
| - fProgramCache = new ProgramCache(this); |
| - |
| - fHWProgramID = 0; |
| - fTempSrcFBOID = 0; |
| - fTempDstFBOID = 0; |
| - fStencilClearFBOID = 0; |
| - |
| - if (this->glCaps().shaderCaps()->pathRenderingSupport()) { |
| - fPathRendering.reset(new GrGLPathRendering(this)); |
| - } |
| - this->createCopyPrograms(); |
| - fWireRectProgram.fProgram = 0; |
| - fWireRectArrayBuffer = 0; |
| - if (this->glCaps().shaderCaps()->plsPathRenderingSupport()) { |
| - this->createPLSSetupProgram(); |
| - } |
| - else { |
| - memset(&fPLSSetupProgram, 0, sizeof(fPLSSetupProgram)); |
| - } |
| - fHWPLSEnabled = false; |
| - fPLSHasBeenUsed = false; |
| - fHWMinSampleShading = 0.0; |
| } |
| GrGLGpu::~GrGLGpu() { |
| - // Delete the path rendering explicitly, since it will need working gpu object to release the |
| - // resources the object itself holds. |
| + // Ensure any GrGpuResource objects get deleted first, since they will require a working GrGpu |
| + // to release the resources held by the objects themselves. |
| fPathRendering.reset(); |
| + fCopyProgramArrayBuffer.reset(); |
|
bsalomon
2016/04/05 15:17:28
Should we go ahead and declare GrGLGpu final? I do
Chris Dalton
2016/04/05 17:59:15
Done.
|
| + fWireRectArrayBuffer.reset(); |
| + fPLSSetupProgram.fArrayBuffer.reset(); |
| if (0 != fHWProgramID) { |
| // detach the current program so there is no confusion on OpenGL's part |
| @@ -264,22 +277,10 @@ GrGLGpu::~GrGLGpu() { |
| } |
| } |
| - if (0 != fCopyProgramArrayBuffer) { |
| - GL_CALL(DeleteBuffers(1, &fCopyProgramArrayBuffer)); |
| - } |
| - |
| if (0 != fWireRectProgram.fProgram) { |
| GL_CALL(DeleteProgram(fWireRectProgram.fProgram)); |
| } |
| - if (0 != fWireRectArrayBuffer) { |
| - GL_CALL(DeleteBuffers(1, &fWireRectArrayBuffer)); |
| - } |
| - |
| - if (0 != fPLSSetupProgram.fArrayBuffer) { |
| - GL_CALL(DeleteBuffers(1, &fPLSSetupProgram.fArrayBuffer)); |
| - } |
| - |
| if (0 != fPLSSetupProgram.fProgram) { |
| GL_CALL(DeleteProgram(fPLSSetupProgram.fProgram)); |
| } |
| @@ -287,6 +288,14 @@ GrGLGpu::~GrGLGpu() { |
| delete fProgramCache; |
| } |
| +void GrGLGpu::initGpuResources() { |
|
bsalomon
2016/04/05 15:17:28
Could we eliminate the need for this deferred init
Chris Dalton
2016/04/05 17:59:15
Done.
|
| + this->createCopyPrograms(); |
| + |
| + if (this->glCaps().shaderCaps()->plsPathRenderingSupport()) { |
| + this->createPLSSetupProgram(); |
| + } |
| +} |
| + |
| void GrGLGpu::createPLSSetupProgram() { |
| const GrGLSLCaps* glslCaps = this->glCaps().glslCaps(); |
| const char* version = glslCaps->versionDeclString(); |
| @@ -371,19 +380,15 @@ void GrGLGpu::createPLSSetupProgram() { |
| GL_CALL(DeleteShader(vshader)); |
| GL_CALL(DeleteShader(fshader)); |
| - GL_CALL(GenBuffers(1, &fPLSSetupProgram.fArrayBuffer)); |
| - fHWGeometryState.setVertexBufferID(this, fPLSSetupProgram.fArrayBuffer); |
| - static const GrGLfloat vdata[] = { |
| - 0, 0, |
| - 0, 1, |
| - 1, 0, |
| - 1, 1 |
| - }; |
| - GL_ALLOC_CALL(this->glInterface(), |
| - BufferData(GR_GL_ARRAY_BUFFER, |
| - (GrGLsizeiptr) sizeof(vdata), |
| - vdata, // data ptr |
| - GR_GL_STATIC_DRAW)); |
| + fPLSSetupProgram.fArrayBuffer.reset( |
| + GrGLBuffer::Create(this, 4 * 2 * sizeof(GrGLfloat), kVertex_GrBufferType, |
| + kStatic_GrAccessPattern, (const GrGLfloat[4 * 2]) { |
| + 0, 0, |
| + 0, 1, |
| + 1, 0, |
| + 1, 1 |
| + }) |
| + ); |
| } |
| void GrGLGpu::disconnect(DisconnectType type) { |
| @@ -401,9 +406,6 @@ void GrGLGpu::disconnect(DisconnectType type) { |
| if (fStencilClearFBOID) { |
| GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID)); |
| } |
| - if (fCopyProgramArrayBuffer) { |
| - GL_CALL(DeleteBuffers(1, &fCopyProgramArrayBuffer)); |
| - } |
| for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) { |
| if (fCopyPrograms[i].fProgram) { |
| GL_CALL(DeleteProgram(fCopyPrograms[i].fProgram)); |
| @@ -412,20 +414,22 @@ void GrGLGpu::disconnect(DisconnectType type) { |
| if (fWireRectProgram.fProgram) { |
| GL_CALL(DeleteProgram(fWireRectProgram.fProgram)); |
| } |
| - if (fWireRectArrayBuffer) { |
| - GL_CALL(DeleteBuffers(1, &fWireRectArrayBuffer)); |
| - } |
| - |
| if (fPLSSetupProgram.fProgram) { |
| GL_CALL(DeleteProgram(fPLSSetupProgram.fProgram)); |
| } |
| - if (fPLSSetupProgram.fArrayBuffer) { |
| - GL_CALL(DeleteBuffers(1, &fPLSSetupProgram.fArrayBuffer)); |
| - } |
| } else { |
| if (fProgramCache) { |
| fProgramCache->abandon(); |
| } |
| + if (fCopyProgramArrayBuffer) { |
|
bsalomon
2016/04/05 15:17:28
We shouldn't ever call abandon outside of the cach
Chris Dalton
2016/04/05 17:59:15
Done.
|
| + fCopyProgramArrayBuffer->abandon(); |
| + } |
| + if (fWireRectArrayBuffer) { |
| + fWireRectArrayBuffer->abandon(); |
| + } |
| + if (fPLSSetupProgram.fArrayBuffer) { |
| + fPLSSetupProgram.fArrayBuffer->abandon(); |
| + } |
| } |
| delete fProgramCache; |
| @@ -435,14 +439,14 @@ void GrGLGpu::disconnect(DisconnectType type) { |
| fTempSrcFBOID = 0; |
| fTempDstFBOID = 0; |
| fStencilClearFBOID = 0; |
| - fCopyProgramArrayBuffer = 0; |
| + fCopyProgramArrayBuffer.reset(); |
| for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) { |
| fCopyPrograms[i].fProgram = 0; |
| } |
| fWireRectProgram.fProgram = 0; |
| - fWireRectArrayBuffer = 0; |
| + fWireRectArrayBuffer.reset(); |
| fPLSSetupProgram.fProgram = 0; |
| - fPLSSetupProgram.fArrayBuffer = 0; |
| + fPLSSetupProgram.fArrayBuffer.reset(); |
| if (this->glCaps().shaderCaps()->pathRenderingSupport()) { |
| this->glPathRendering()->disconnect(type); |
| } |
| @@ -456,8 +460,10 @@ void GrGLGpu::onResetContext(uint32_t resetBits) { |
| GL_CALL(Disable(GR_GL_DEPTH_TEST)); |
| GL_CALL(DepthMask(GR_GL_FALSE)); |
| - fHWBoundTextureBufferIDIsValid = false; |
| - fHWBoundDrawIndirectBufferIDIsValid = false; |
| + fHWBufferState[kTexel_GrBufferType].invalidate(); |
| + fHWBufferState[kDrawIndirect_GrBufferType].invalidate(); |
| + fHWBufferState[kXferCpuToGpu_GrBufferType].invalidate(); |
| + fHWBufferState[kXferGpuToCpu_GrBufferType].invalidate(); |
| fHWDrawFace = GrPipelineBuilder::kInvalid_DrawFace; |
| @@ -538,7 +544,9 @@ void GrGLGpu::onResetContext(uint32_t resetBits) { |
| // Vertex |
| if (resetBits & kVertex_GrGLBackendState) { |
| - fHWGeometryState.invalidate(); |
| + fHWVertexArrayState.invalidate(); |
| + fHWBufferState[kVertex_GrBufferType].invalidate(); |
| + fHWBufferState[kIndex_GrBufferType].invalidate(); |
| } |
| if (resetBits & kRenderTarget_GrGLBackendState) { |
| @@ -900,11 +908,10 @@ bool GrGLGpu::onTransferPixels(GrSurface* surface, |
| this->setScratchTextureUnit(); |
| GL_CALL(BindTexture(glTex->target(), glTex->textureID())); |
| - SkASSERT(kXferCpuToGpu_GrBufferType == transferBuffer->type()); |
| SkASSERT(!transferBuffer->isMapped()); |
| SkASSERT(!transferBuffer->isCPUBacked()); |
| const GrGLBuffer* glBuffer = static_cast<const GrGLBuffer*>(transferBuffer); |
| - this->bindBuffer(glBuffer->bufferID(), glBuffer->target()); |
| + this->bindBuffer(kXferCpuToGpu_GrBufferType, glBuffer); |
| bool success = false; |
| GrMipLevel mipLevel; |
| @@ -1974,8 +1981,9 @@ GrStencilAttachment* GrGLGpu::createStencilAttachmentForRenderTarget(const GrRen |
| // objects are implemented as client-side-arrays on tile-deferred architectures. |
| #define DYNAMIC_USAGE_PARAM GR_GL_STREAM_DRAW |
| -GrBuffer* GrGLGpu::onCreateBuffer(GrBufferType type, size_t size, GrAccessPattern accessPattern) { |
| - return GrGLBuffer::Create(this, type, size, accessPattern); |
| +GrBuffer* GrGLGpu::onCreateBuffer(size_t size, GrBufferType intendedType, |
| + GrAccessPattern accessPattern) { |
| + return GrGLBuffer::Create(this, size, intendedType, accessPattern); |
| } |
| void GrGLGpu::flushScissor(const GrScissorState& scissorState, |
| @@ -2079,22 +2087,21 @@ void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc, |
| SkASSERT(vbuf); |
| SkASSERT(!vbuf->isMapped()); |
| - SkASSERT(kVertex_GrBufferType == vbuf->type()); |
| - const GrGLBuffer* ibuf = nullptr; |
| + GrGLAttribArrayState* attribState; |
| if (mesh.isIndexed()) { |
| SkASSERT(indexOffsetInBytes); |
| *indexOffsetInBytes = 0; |
| - ibuf = static_cast<const GrGLBuffer*>(mesh.indexBuffer()); |
| + const GrGLBuffer* ibuf = static_cast<const GrGLBuffer*>(mesh.indexBuffer()); |
| SkASSERT(ibuf); |
| SkASSERT(!ibuf->isMapped()); |
| - SkASSERT(kIndex_GrBufferType == ibuf->type()); |
| *indexOffsetInBytes += ibuf->baseOffset(); |
| + attribState = fHWVertexArrayState.bindInternalVertexArray(this, ibuf); |
| + } else { |
| + attribState = fHWVertexArrayState.bindInternalVertexArray(this); |
| } |
| - GrGLAttribArrayState* attribState = |
| - fHWGeometryState.bindArrayAndBuffersToDraw(this, vbuf, ibuf); |
| int vaCount = primProc.numAttribs(); |
| if (vaCount > 0) { |
| @@ -2114,7 +2121,7 @@ void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc, |
| GrVertexAttribType attribType = attrib.fType; |
| attribState->set(this, |
| attribIndex, |
| - vbuf->bufferID(), |
| + vbuf, |
| attribType, |
| stride, |
| reinterpret_cast<GrGLvoid*>(vertexOffsetInBytes + offset)); |
| @@ -2124,57 +2131,26 @@ void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc, |
| } |
| } |
| -void GrGLGpu::bindBuffer(GrGLuint id, GrGLenum type) { |
| +GrGLenum GrGLGpu::bindBuffer(GrBufferType type, const GrGLBuffer* buffer) { |
| this->handleDirtyContext(); |
| - switch (type) { |
| - case GR_GL_ARRAY_BUFFER: |
| - this->bindVertexBuffer(id); |
| - break; |
| - case GR_GL_ELEMENT_ARRAY_BUFFER: |
| - this->bindIndexBufferAndDefaultVertexArray(id); |
| - break; |
| - case GR_GL_TEXTURE_BUFFER: |
| - if (!fHWBoundTextureBufferIDIsValid || id != fHWBoundTextureBufferID) { |
| - GR_GL_CALL(this->glInterface(), BindBuffer(type, id)); |
| - fHWBoundTextureBufferID = id; |
| - fHWBoundTextureBufferIDIsValid = true; |
| - } |
| - break; |
| - case GR_GL_DRAW_INDIRECT_BUFFER: |
| - if (!fHWBoundDrawIndirectBufferIDIsValid || id != fHWBoundDrawIndirectBufferID) { |
| - GR_GL_CALL(this->glInterface(), BindBuffer(type, id)); |
| - fHWBoundDrawIndirectBufferID = id; |
| - fHWBoundDrawIndirectBufferIDIsValid = true; |
| - } |
| - break; |
| - default: |
| - SkDebugf("WARNING: buffer target 0x%x is not tracked by GrGLGpu.\n", type); |
| - GR_GL_CALL(this->glInterface(), BindBuffer(type, id)); |
| - break; |
| + |
| + // Index buffer state is tied to the vertex array. |
| + if (kIndex_GrBufferType == type) { |
| + this->bindVertexArray(0); |
| } |
| -} |
| -void GrGLGpu::releaseBuffer(GrGLuint id, GrGLenum type) { |
| - this->handleDirtyContext(); |
| - GL_CALL(DeleteBuffers(1, &id)); |
| - switch (type) { |
| - case GR_GL_ARRAY_BUFFER: |
| - this->notifyVertexBufferDelete(id); |
| - break; |
| - case GR_GL_ELEMENT_ARRAY_BUFFER: |
| - this->notifyIndexBufferDelete(id); |
| - break; |
| - case GR_GL_TEXTURE_BUFFER: |
| - if (fHWBoundTextureBufferIDIsValid && id == fHWBoundTextureBufferID) { |
| - fHWBoundTextureBufferID = 0; |
| - } |
| - break; |
| - case GR_GL_DRAW_INDIRECT_BUFFER: |
| - if (fHWBoundDrawIndirectBufferIDIsValid && id == fHWBoundDrawIndirectBufferID) { |
| - fHWBoundDrawIndirectBufferID = 0; |
| - } |
| - break; |
| + SkASSERT(type >= 0 && type <= kLast_GrBufferType); |
| + auto& bufferState = fHWBufferState[type]; |
| + |
| + if (buffer->getUniqueID() != bufferState.fBoundBufferUniqueID) { |
| + if (!buffer->isCPUBacked() || !bufferState.fBufferZeroKnownBound) { |
| + GL_CALL(BindBuffer(bufferState.fGLTarget, buffer->bufferID())); |
| + bufferState.fBufferZeroKnownBound = buffer->isCPUBacked(); |
| + } |
| + bufferState.fBoundBufferUniqueID = buffer->getUniqueID(); |
| } |
| + |
| + return bufferState.fGLTarget; |
| } |
| void GrGLGpu::disableScissor() { |
| @@ -2844,12 +2820,11 @@ void GrGLGpu::onDraw(const GrPipeline& pipeline, |
| } |
| void GrGLGpu::stampRectUsingProgram(GrGLuint program, const SkRect& bounds, GrGLint posXformUniform, |
| - GrGLuint arrayBuffer) { |
| + const GrGLBuffer* arrayBuffer) { |
| GL_CALL(UseProgram(program)); |
| - this->fHWGeometryState.setVertexArrayID(this, 0); |
| + this->fHWVertexArrayState.setVertexArrayID(this, 0); |
| - GrGLAttribArrayState* attribs = |
| - this->fHWGeometryState.bindArrayAndBufferToDraw(this, arrayBuffer); |
| + GrGLAttribArrayState* attribs = this->fHWVertexArrayState.bindInternalVertexArray(this); |
| attribs->set(this, 0, arrayBuffer, kVec2f_GrVertexAttribType, 2 * sizeof(GrGLfloat), 0); |
| attribs->disableUnusedArrays(this, 0x1); |
| @@ -3705,20 +3680,15 @@ void GrGLGpu::createCopyPrograms() { |
| GL_CALL(DeleteShader(vshader)); |
| GL_CALL(DeleteShader(fshader)); |
| } |
| - fCopyProgramArrayBuffer = 0; |
| - GL_CALL(GenBuffers(1, &fCopyProgramArrayBuffer)); |
| - fHWGeometryState.setVertexBufferID(this, fCopyProgramArrayBuffer); |
| - static const GrGLfloat vdata[] = { |
| - 0, 0, |
| - 0, 1, |
| - 1, 0, |
| - 1, 1 |
| - }; |
| - GL_ALLOC_CALL(this->glInterface(), |
| - BufferData(GR_GL_ARRAY_BUFFER, |
| - (GrGLsizeiptr) sizeof(vdata), |
| - vdata, // data ptr |
| - GR_GL_STATIC_DRAW)); |
| + fCopyProgramArrayBuffer.reset( |
| + GrGLBuffer::Create(this, 4 * 2 * sizeof(GrGLfloat), kVertex_GrBufferType, |
| + kStatic_GrAccessPattern, (const GrGLfloat[4 * 2]) { |
| + 0, 0, |
| + 0, 1, |
| + 1, 0, |
| + 1, 1 |
| + }) |
| + ); |
| } |
| void GrGLGpu::createWireRectProgram() { |
| @@ -3796,19 +3766,15 @@ void GrGLGpu::createWireRectProgram() { |
| GL_CALL(DeleteShader(vshader)); |
| GL_CALL(DeleteShader(fshader)); |
| - GL_CALL(GenBuffers(1, &fWireRectArrayBuffer)); |
| - fHWGeometryState.setVertexBufferID(this, fWireRectArrayBuffer); |
| - static const GrGLfloat vdata[] = { |
| - 0, 0, |
| - 0, 1, |
| - 1, 1, |
| - 1, 0, |
| - }; |
| - GL_ALLOC_CALL(this->glInterface(), |
| - BufferData(GR_GL_ARRAY_BUFFER, |
| - (GrGLsizeiptr) sizeof(vdata), |
| - vdata, // data ptr |
| - GR_GL_STATIC_DRAW)); |
| + fWireRectArrayBuffer.reset( |
| + GrGLBuffer::Create(this, 4 * 2 * sizeof(GrGLfloat), kVertex_GrBufferType, |
| + kStatic_GrAccessPattern, (const GrGLfloat[4 * 2]) { |
| + 0, 0, |
| + 0, 1, |
| + 1, 1, |
| + 1, 0 |
| + }) |
| + ); |
| } |
| void GrGLGpu::drawDebugWireRect(GrRenderTarget* rt, const SkIRect& rect, GrColor color) { |
| @@ -3853,10 +3819,9 @@ void GrGLGpu::drawDebugWireRect(GrRenderTarget* rt, const SkIRect& rect, GrColor |
| GL_CALL(UseProgram(fWireRectProgram.fProgram)); |
| fHWProgramID = fWireRectProgram.fProgram; |
| - fHWGeometryState.setVertexArrayID(this, 0); |
| + fHWVertexArrayState.setVertexArrayID(this, 0); |
| - GrGLAttribArrayState* attribs = |
| - fHWGeometryState.bindArrayAndBufferToDraw(this, fWireRectArrayBuffer); |
| + GrGLAttribArrayState* attribs = fHWVertexArrayState.bindInternalVertexArray(this); |
| attribs->set(this, 0, fWireRectArrayBuffer, kVec2f_GrVertexAttribType, 2 * sizeof(GrGLfloat), |
| 0); |
| attribs->disableUnusedArrays(this, 0x1); |
| @@ -3902,10 +3867,9 @@ void GrGLGpu::copySurfaceAsDraw(GrSurface* dst, |
| GL_CALL(UseProgram(fCopyPrograms[progIdx].fProgram)); |
| fHWProgramID = fCopyPrograms[progIdx].fProgram; |
| - fHWGeometryState.setVertexArrayID(this, 0); |
| + fHWVertexArrayState.setVertexArrayID(this, 0); |
| - GrGLAttribArrayState* attribs = |
| - fHWGeometryState.bindArrayAndBufferToDraw(this, fCopyProgramArrayBuffer); |
| + GrGLAttribArrayState* attribs = fHWVertexArrayState.bindInternalVertexArray(this); |
| attribs->set(this, 0, fCopyProgramArrayBuffer, kVec2f_GrVertexAttribType, 2 * sizeof(GrGLfloat), |
| 0); |
| attribs->disableUnusedArrays(this, 0x1); |
| @@ -4198,52 +4162,27 @@ void GrGLGpu::resetShaderCacheForTesting() const { |
| } |
| /////////////////////////////////////////////////////////////////////////////// |
| -GrGLAttribArrayState* GrGLGpu::HWGeometryState::bindArrayAndBuffersToDraw( |
| - GrGLGpu* gpu, |
| - const GrGLBuffer* vbuffer, |
| - const GrGLBuffer* ibuffer) { |
| - SkASSERT(vbuffer); |
| - GrGLuint vbufferID = vbuffer->bufferID(); |
| - GrGLuint* ibufferIDPtr = nullptr; |
| - GrGLuint ibufferID; |
| - if (ibuffer) { |
| - ibufferID = ibuffer->bufferID(); |
| - ibufferIDPtr = &ibufferID; |
| - } |
| - return this->internalBind(gpu, vbufferID, ibufferIDPtr); |
| -} |
| - |
| -GrGLAttribArrayState* GrGLGpu::HWGeometryState::bindArrayAndBufferToDraw(GrGLGpu* gpu, |
| - GrGLuint vbufferID) { |
| - return this->internalBind(gpu, vbufferID, nullptr); |
| -} |
| - |
| -GrGLAttribArrayState* GrGLGpu::HWGeometryState::bindArrayAndBuffersToDraw(GrGLGpu* gpu, |
| - GrGLuint vbufferID, |
| - GrGLuint ibufferID) { |
| - return this->internalBind(gpu, vbufferID, &ibufferID); |
| -} |
| -GrGLAttribArrayState* GrGLGpu::HWGeometryState::internalBind(GrGLGpu* gpu, |
| - GrGLuint vbufferID, |
| - GrGLuint* ibufferID) { |
| +GrGLAttribArrayState* GrGLGpu::HWVertexArrayState::bindInternalVertexArray(GrGLGpu* gpu, |
| + const GrGLBuffer* ibuf) { |
| GrGLAttribArrayState* attribState; |
| - if (gpu->glCaps().isCoreProfile() && 0 != vbufferID) { |
| - if (!fVBOVertexArray) { |
| + if (gpu->glCaps().isCoreProfile()) { |
| + if (!fCoreProfileVertexArray) { |
| GrGLuint arrayID; |
| GR_GL_CALL(gpu->glInterface(), GenVertexArrays(1, &arrayID)); |
| int attrCount = gpu->glCaps().maxVertexAttributes(); |
| - fVBOVertexArray = new GrGLVertexArray(arrayID, attrCount); |
| + fCoreProfileVertexArray = new GrGLVertexArray(arrayID, attrCount); |
| } |
| - if (ibufferID) { |
| - attribState = fVBOVertexArray->bindWithIndexBuffer(gpu, *ibufferID); |
| + if (ibuf) { |
| + attribState = fCoreProfileVertexArray->bindWithIndexBuffer(gpu, ibuf); |
| } else { |
| - attribState = fVBOVertexArray->bind(gpu); |
| + attribState = fCoreProfileVertexArray->bind(gpu); |
| } |
| } else { |
| - if (ibufferID) { |
| - this->setIndexBufferIDOnDefaultVertexArray(gpu, *ibufferID); |
| + if (ibuf) { |
| + // bindBuffer implicitly binds VAO 0 when binding an index buffer. |
| + gpu->bindBuffer(kIndex_GrBufferType, ibuf); |
| } else { |
| this->setVertexArrayID(gpu, 0); |
| } |