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 <bsalomon@google.com> Commit-Queue: Chris Dalton <csmartdalton@google.com>
This commit is contained in:
parent
39748b2771
commit
8e45b4f3a3
@ -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<GrGLsizei>(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<GrGLvoid*>(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;
|
||||
|
@ -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<const GrGLvoid*>(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;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user