From 8e45b4f3a3d34d20ec9a13692f3e4de94997145c Mon Sep 17 00:00:00 2001 From: Chris Dalton Date: Fri, 5 May 2017 14:00:56 -0400 Subject: [PATCH] GL: track enabled vertex arrays as a count rather than a mask Bug: skia: Change-Id: I63e70ab844a7e04df20165aba025b963efcafa9e Reviewed-on: https://skia-review.googlesource.com/15630 Reviewed-by: Brian Salomon Commit-Queue: Chris Dalton --- src/gpu/gl/GrGLGpu.cpp | 35 ++++++++++----------------- src/gpu/gl/GrGLVertexArray.cpp | 44 ++++++++++++++++------------------ src/gpu/gl/GrGLVertexArray.h | 31 ++++++++++-------------- 3 files changed, 45 insertions(+), 65 deletions(-) diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index 99db511911..e842ddc4f5 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -2003,34 +2003,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); } } @@ -3922,9 +3911,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)); @@ -3975,9 +3964,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(); @@ -4215,9 +4204,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 3551da06a5..1970e30425 100644 --- a/src/gpu/gl/GrGLVertexArray.h +++ b/src/gpu/gl/GrGLVertexArray.h @@ -29,9 +29,7 @@ public: void resize(int newCount) { fAttribArrayStates.resize_back(newCount); - for (int i = 0; i < newCount; ++i) { - fAttribArrayStates[i].invalidate(); - } + this->invalidate(); } /** @@ -44,19 +42,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 +67,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; }; /**