| /* |
| * Copyright 2013 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #ifndef GrGLVertexArray_DEFINED |
| #define GrGLVertexArray_DEFINED |
| |
| #include "GrGpuResource.h" |
| #include "GrTypesPriv.h" |
| #include "gl/GrGLDefines.h" |
| #include "gl/GrGLTypes.h" |
| #include "SkTArray.h" |
| |
| class GrBuffer; |
| class GrGLGpu; |
| |
| /** |
| * This sets and tracks the vertex attribute array state. It is used internally by GrGLVertexArray |
| * (below) but is separate because it is also used to track the state of vertex array object 0. |
| */ |
| class GrGLAttribArrayState { |
| public: |
| explicit GrGLAttribArrayState(int arrayCount = 0) { |
| this->resize(arrayCount); |
| } |
| |
| void resize(int newCount) { |
| fAttribArrayStates.resize_back(newCount); |
| this->invalidate(); |
| } |
| |
| /** |
| * This function enables and sets vertex attrib state for the specified attrib index. It is |
| * assumed that the GrGLAttribArrayState is tracking the state of the currently bound vertex |
| * array object. |
| */ |
| void set(GrGLGpu*, |
| int attribIndex, |
| const GrBuffer* vertexBuffer, |
| GrVertexAttribType type, |
| GrGLsizei stride, |
| size_t offsetInBytes, |
| int divisor = 0); |
| |
| enum class EnablePrimitiveRestart : bool { |
| kYes = true, |
| kNo = false |
| }; |
| |
| /** |
| * This function enables the first 'enabledCount' vertex arrays and disables the rest. |
| */ |
| void enableVertexArrays(const GrGLGpu*, int enabledCount, |
| EnablePrimitiveRestart = EnablePrimitiveRestart::kNo); |
| |
| void invalidate() { |
| int count = fAttribArrayStates.count(); |
| for (int i = 0; i < count; ++i) { |
| fAttribArrayStates[i].invalidate(); |
| } |
| fEnableStateIsValid = false; |
| } |
| |
| /** |
| * The number of attrib arrays that this object is configured to track. |
| */ |
| int count() const { return fAttribArrayStates.count(); } |
| |
| private: |
| static constexpr int kInvalidDivisor = -1; |
| |
| /** |
| * Tracks the state of glVertexAttribArray for an attribute index. |
| */ |
| struct AttribArrayState { |
| void invalidate() { |
| fVertexBufferUniqueID.makeInvalid(); |
| fDivisor = kInvalidDivisor; |
| } |
| |
| GrGpuResource::UniqueID fVertexBufferUniqueID; |
| GrVertexAttribType fType; |
| GrGLsizei fStride; |
| size_t fOffset; |
| int fDivisor; |
| }; |
| |
| SkSTArray<16, AttribArrayState, true> fAttribArrayStates; |
| int fNumEnabledArrays; |
| EnablePrimitiveRestart fPrimitiveRestartEnabled; |
| bool fEnableStateIsValid = false; |
| }; |
| |
| /** |
| * This class represents an OpenGL vertex array object. It manages the lifetime of the vertex array |
| * and is used to track the state of the vertex array to avoid redundant GL calls. |
| */ |
| class GrGLVertexArray { |
| public: |
| GrGLVertexArray(GrGLint id, int attribCount); |
| |
| /** |
| * Binds this vertex array. If the ID has been deleted or abandoned then nullptr is returned. |
| * Otherwise, the GrGLAttribArrayState that is tracking this vertex array's attrib bindings is |
| * returned. |
| */ |
| GrGLAttribArrayState* bind(GrGLGpu*); |
| |
| /** |
| * This is a version of the above function that also binds an index buffer to the vertex |
| * array object. |
| */ |
| GrGLAttribArrayState* bindWithIndexBuffer(GrGLGpu* gpu, const GrBuffer* indexBuffer); |
| |
| GrGLuint arrayID() const { return fID; } |
| |
| void invalidateCachedState(); |
| |
| private: |
| GrGLuint fID; |
| GrGLAttribArrayState fAttribArrays; |
| GrGpuResource::UniqueID fIndexBufferUniqueID; |
| }; |
| |
| #endif |