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