1 /*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "GrGLVertexArray.h"
9 #include "GrGLGpu.h"
10
11
set(const GrGLGpu * gpu,int index,GrGLVertexBuffer * buffer,GrGLint size,GrGLenum type,GrGLboolean normalized,GrGLsizei stride,GrGLvoid * offset)12 void GrGLAttribArrayState::set(const GrGLGpu* gpu,
13 int index,
14 GrGLVertexBuffer* buffer,
15 GrGLint size,
16 GrGLenum type,
17 GrGLboolean normalized,
18 GrGLsizei stride,
19 GrGLvoid* offset) {
20 SkASSERT(index >= 0 && index < fAttribArrayStates.count());
21 AttribArrayState* array = &fAttribArrayStates[index];
22 if (!array->fEnableIsValid || !array->fEnabled) {
23 GR_GL_CALL(gpu->glInterface(), EnableVertexAttribArray(index));
24 array->fEnableIsValid = true;
25 array->fEnabled = true;
26 }
27 if (!array->fAttribPointerIsValid ||
28 array->fVertexBufferID != buffer->bufferID() ||
29 array->fSize != size ||
30 array->fNormalized != normalized ||
31 array->fStride != stride ||
32 array->fOffset != offset) {
33
34 buffer->bind();
35 GR_GL_CALL(gpu->glInterface(), VertexAttribPointer(index,
36 size,
37 type,
38 normalized,
39 stride,
40 offset));
41 array->fAttribPointerIsValid = true;
42 array->fVertexBufferID = buffer->bufferID();
43 array->fSize = size;
44 array->fNormalized = normalized;
45 array->fStride = stride;
46 array->fOffset = offset;
47 }
48 }
49
disableUnusedArrays(const GrGLGpu * gpu,uint64_t usedMask)50 void GrGLAttribArrayState::disableUnusedArrays(const GrGLGpu* gpu, uint64_t usedMask) {
51 int count = fAttribArrayStates.count();
52 for (int i = 0; i < count; ++i) {
53 if (!(usedMask & 0x1)) {
54 if (!fAttribArrayStates[i].fEnableIsValid || fAttribArrayStates[i].fEnabled) {
55 GR_GL_CALL(gpu->glInterface(), DisableVertexAttribArray(i));
56 fAttribArrayStates[i].fEnableIsValid = true;
57 fAttribArrayStates[i].fEnabled = false;
58 }
59 } else {
60 SkASSERT(fAttribArrayStates[i].fEnableIsValid && fAttribArrayStates[i].fEnabled);
61 }
62 // if the count is greater than 64 then this will become 0 and we will disable arrays 64+.
63 usedMask >>= 1;
64 }
65 }
66
67 ///////////////////////////////////////////////////////////////////////////////////////////////////
68
GrGLVertexArray(GrGLint id,int attribCount)69 GrGLVertexArray::GrGLVertexArray(GrGLint id, int attribCount)
70 : fID(id)
71 , fAttribArrays(attribCount)
72 , fIndexBufferIDIsValid(false) {
73 }
74
bind(GrGLGpu * gpu)75 GrGLAttribArrayState* GrGLVertexArray::bind(GrGLGpu* gpu) {
76 if (0 == fID) {
77 return NULL;
78 }
79 gpu->bindVertexArray(fID);
80 return &fAttribArrays;
81 }
82
bindWithIndexBuffer(GrGLGpu * gpu,const GrGLIndexBuffer * buffer)83 GrGLAttribArrayState* GrGLVertexArray::bindWithIndexBuffer(GrGLGpu* gpu,
84 const GrGLIndexBuffer* buffer) {
85 GrGLAttribArrayState* state = this->bind(gpu);
86 if (state && buffer) {
87 GrGLuint bufferID = buffer->bufferID();
88 if (!fIndexBufferIDIsValid || bufferID != fIndexBufferID) {
89 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, bufferID));
90 fIndexBufferIDIsValid = true;
91 fIndexBufferID = bufferID;
92 }
93 }
94 return state;
95 }
96
notifyIndexBufferDelete(GrGLuint bufferID)97 void GrGLVertexArray::notifyIndexBufferDelete(GrGLuint bufferID) {
98 if (fIndexBufferIDIsValid && bufferID == fIndexBufferID) {
99 fIndexBufferID = 0;
100 }
101 }
102
invalidateCachedState()103 void GrGLVertexArray::invalidateCachedState() {
104 fAttribArrays.invalidate();
105 fIndexBufferIDIsValid = false;
106 }
107