From 288d041c64322fafc77cfaf23907180ebad933a1 Mon Sep 17 00:00:00 2001 From: Chris Dalton Date: Fri, 5 May 2017 09:46:29 -0400 Subject: GL: track enabled vertex arrays as a count rather than a mask Bug: skia: Change-Id: I46ba29cb32960a415ee1993a7b957ec49c0c56d3 Reviewed-on: https://skia-review.googlesource.com/15520 Commit-Queue: Chris Dalton Reviewed-by: Brian Salomon --- src/gpu/gl/GrGLGpu.cpp | 35 ++++++++++++--------------------- src/gpu/gl/GrGLVertexArray.cpp | 44 +++++++++++++++++++----------------------- src/gpu/gl/GrGLVertexArray.h | 27 ++++++++++++-------------- 3 files changed, 44 insertions(+), 62 deletions(-) diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index 8d76faee88..54ce1e98a6 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -1996,34 +1996,23 @@ void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc, attribState = fHWVertexArrayState.bindInternalVertexArray(this); } - SkASSERT(vertexBuffer); - SkASSERT(!vertexBuffer->isMapped()); - int vaCount = primProc.numAttribs(); + attribState->enableVertexArrays(this, vaCount); + if (vaCount > 0) { + SkASSERT(vertexBuffer); + SkASSERT(!vertexBuffer->isMapped()); GrGLsizei stride = static_cast(primProc.getVertexStride()); - - size_t vertexOffsetInBytes = stride * baseVertex; - - vertexOffsetInBytes += vertexBuffer->baseOffset(); - - uint32_t usedAttribArraysMask = 0; - size_t offset = 0; + size_t vertexBufferOffsetInBytes = stride * baseVertex + vertexBuffer->baseOffset(); + size_t attribOffset = 0; for (int attribIndex = 0; attribIndex < vaCount; attribIndex++) { const GrGeometryProcessor::Attribute& attrib = primProc.getAttrib(attribIndex); - usedAttribArraysMask |= (1 << attribIndex); - GrVertexAttribType attribType = attrib.fType; - attribState->set(this, - attribIndex, - vertexBuffer, - attribType, - stride, - reinterpret_cast(vertexOffsetInBytes + offset)); - offset += attrib.fOffset; + attribState->set(this, attribIndex, vertexBuffer, attrib.fType, stride, + vertexBufferOffsetInBytes + attribOffset); + attribOffset += attrib.fOffset; } - attribState->disableUnusedArrays(this, usedAttribArraysMask); } } @@ -3937,9 +3926,9 @@ void GrGLGpu::drawDebugWireRect(GrRenderTarget* rt, const SkIRect& rect, GrColor fHWVertexArrayState.setVertexArrayID(this, 0); GrGLAttribArrayState* attribs = fHWVertexArrayState.bindInternalVertexArray(this); + attribs->enableVertexArrays(this, 1); attribs->set(this, 0, fWireRectArrayBuffer.get(), kVec2f_GrVertexAttribType, 2 * sizeof(GrGLfloat), 0); - attribs->disableUnusedArrays(this, 0x1); GL_CALL(Uniform4fv(fWireRectProgram.fRectUniform, 1, edges)); GL_CALL(Uniform4fv(fWireRectProgram.fColorUniform, 1, channels)); @@ -3991,9 +3980,9 @@ bool GrGLGpu::copySurfaceAsDraw(GrSurface* dst, fHWVertexArrayState.setVertexArrayID(this, 0); GrGLAttribArrayState* attribs = fHWVertexArrayState.bindInternalVertexArray(this); + attribs->enableVertexArrays(this, 1); attribs->set(this, 0, fCopyProgramArrayBuffer.get(), kVec2f_GrVertexAttribType, 2 * sizeof(GrGLfloat), 0); - attribs->disableUnusedArrays(this, 0x1); // dst rect edges in NDC (-1 to 1) int dw = dst->width(); @@ -4232,9 +4221,9 @@ bool GrGLGpu::generateMipmap(GrGLTexture* texture, bool gammaCorrect) { fHWVertexArrayState.setVertexArrayID(this, 0); GrGLAttribArrayState* attribs = fHWVertexArrayState.bindInternalVertexArray(this); + attribs->enableVertexArrays(this, 1); attribs->set(this, 0, fMipmapProgramArrayBuffer.get(), kVec2f_GrVertexAttribType, 2 * sizeof(GrGLfloat), 0); - attribs->disableUnusedArrays(this, 0x1); // Set "simple" state once: GrXferProcessor::BlendInfo blendInfo; diff --git a/src/gpu/gl/GrGLVertexArray.cpp b/src/gpu/gl/GrGLVertexArray.cpp index 807b9d091b..74e609e9b8 100644 --- a/src/gpu/gl/GrGLVertexArray.cpp +++ b/src/gpu/gl/GrGLVertexArray.cpp @@ -53,27 +53,23 @@ void GrGLAttribArrayState::set(GrGLGpu* gpu, const GrBuffer* vertexBuffer, GrVertexAttribType type, GrGLsizei stride, - GrGLvoid* offset) { + size_t offsetInBytes) { SkASSERT(index >= 0 && index < fAttribArrayStates.count()); AttribArrayState* array = &fAttribArrayStates[index]; - if (!array->fEnableIsValid || !array->fEnabled) { - GR_GL_CALL(gpu->glInterface(), EnableVertexAttribArray(index)); - array->fEnableIsValid = true; - array->fEnabled = true; - } if (array->fVertexBufferUniqueID != vertexBuffer->uniqueID() || array->fType != type || array->fStride != stride || - array->fOffset != offset) { + array->fOffset != offsetInBytes) { gpu->bindBuffer(kVertex_GrBufferType, vertexBuffer); const AttribLayout& layout = attrib_layout(type); + const GrGLvoid* offsetAsPtr = reinterpret_cast(offsetInBytes); if (!GrVertexAttribTypeIsIntType(type)) { GR_GL_CALL(gpu->glInterface(), VertexAttribPointer(index, layout.fCount, layout.fType, layout.fNormalized, stride, - offset)); + offsetAsPtr)); } else { SkASSERT(gpu->caps()->shaderCaps()->integerSupport()); SkASSERT(!layout.fNormalized); @@ -81,30 +77,30 @@ void GrGLAttribArrayState::set(GrGLGpu* gpu, layout.fCount, layout.fType, stride, - offset)); + offsetAsPtr)); } array->fVertexBufferUniqueID = vertexBuffer->uniqueID(); array->fType = type; array->fStride = stride; - array->fOffset = offset; + array->fOffset = offsetInBytes; } } -void GrGLAttribArrayState::disableUnusedArrays(const GrGLGpu* gpu, uint64_t usedMask) { - int count = fAttribArrayStates.count(); - for (int i = 0; i < count; ++i) { - if (!(usedMask & 0x1)) { - if (!fAttribArrayStates[i].fEnableIsValid || fAttribArrayStates[i].fEnabled) { - GR_GL_CALL(gpu->glInterface(), DisableVertexAttribArray(i)); - fAttribArrayStates[i].fEnableIsValid = true; - fAttribArrayStates[i].fEnabled = false; - } - } else { - SkASSERT(fAttribArrayStates[i].fEnableIsValid && fAttribArrayStates[i].fEnabled); - } - // if the count is greater than 64 then this will become 0 and we will disable arrays 64+. - usedMask >>= 1; +void GrGLAttribArrayState::enableVertexArrays(const GrGLGpu* gpu, int enabledCount) { + SkASSERT(enabledCount <= fAttribArrayStates.count()); + + int firstIdxToEnable = fEnabledCountIsValid ? fNumEnabledArrays : 0; + for (int i = firstIdxToEnable; i < enabledCount; ++i) { + GR_GL_CALL(gpu->glInterface(), EnableVertexAttribArray(i)); } + + int endIdxToDisable = fEnabledCountIsValid ? fNumEnabledArrays : fAttribArrayStates.count(); + for (int i = enabledCount; i < endIdxToDisable; ++i) { + GR_GL_CALL(gpu->glInterface(), DisableVertexAttribArray(i)); + } + + fNumEnabledArrays = enabledCount; + fEnabledCountIsValid = true; } /////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/gpu/gl/GrGLVertexArray.h b/src/gpu/gl/GrGLVertexArray.h index 4c77d2b582..2e951a645d 100644 --- a/src/gpu/gl/GrGLVertexArray.h +++ b/src/gpu/gl/GrGLVertexArray.h @@ -44,19 +44,19 @@ public: const GrBuffer* vertexBuffer, GrVertexAttribType type, GrGLsizei stride, - GrGLvoid* offset); + size_t offsetInBytes); /** - * This function disables vertex attribs not present in the mask. It is assumed that the - * GrGLAttribArrayState is tracking the state of the currently bound vertex array object. + * This function enables the first 'enabledCount' vertex arrays and disables the rest. */ - void disableUnusedArrays(const GrGLGpu*, uint64_t usedAttribArrayMask); + void enableVertexArrays(const GrGLGpu*, int enabledCount); void invalidate() { int count = fAttribArrayStates.count(); for (int i = 0; i < count; ++i) { fAttribArrayStates[i].invalidate(); } + fEnabledCountIsValid = false; } /** @@ -69,20 +69,17 @@ private: * Tracks the state of glVertexAttribArray for an attribute index. */ struct AttribArrayState { - void invalidate() { - fEnableIsValid = false; - fVertexBufferUniqueID.makeInvalid(); - } + void invalidate() { fVertexBufferUniqueID.makeInvalid(); } - bool fEnableIsValid; - bool fEnabled; - GrGpuResource::UniqueID fVertexBufferUniqueID; - GrVertexAttribType fType; - GrGLsizei fStride; - GrGLvoid* fOffset; + GrGpuResource::UniqueID fVertexBufferUniqueID; + GrVertexAttribType fType; + GrGLsizei fStride; + size_t fOffset; }; - SkSTArray<16, AttribArrayState, true> fAttribArrayStates; + SkSTArray<16, AttribArrayState, true> fAttribArrayStates; + int fNumEnabledArrays; + bool fEnabledCountIsValid; }; /** -- cgit v1.2.3