• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "GrGpuGL.h"
10 
11 #define GPUGL static_cast<GrGpuGL*>(this->getGpu())
12 #define GL_CALL(X) GR_GL_CALL(GPUGL->glInterface(), X);
13 
set(const GrGpuGL * gpu,int index,GrGLVertexBuffer * buffer,GrGLint size,GrGLenum type,GrGLboolean normalized,GrGLsizei stride,GrGLvoid * offset)14 void GrGLAttribArrayState::set(const GrGpuGL* gpu,
15                                int index,
16                                GrGLVertexBuffer* buffer,
17                                GrGLint size,
18                                GrGLenum type,
19                                GrGLboolean normalized,
20                                GrGLsizei stride,
21                                GrGLvoid* offset) {
22     SkASSERT(index >= 0 && index < fAttribArrayStates.count());
23     AttribArrayState* array = &fAttribArrayStates[index];
24     if (!array->fEnableIsValid || !array->fEnabled) {
25         GR_GL_CALL(gpu->glInterface(), EnableVertexAttribArray(index));
26         array->fEnableIsValid = true;
27         array->fEnabled = true;
28     }
29     if (!array->fAttribPointerIsValid ||
30         array->fVertexBufferID != buffer->bufferID() ||
31         array->fSize != size ||
32         array->fNormalized != normalized ||
33         array->fStride != stride ||
34         array->fOffset != offset) {
35 
36         buffer->bind();
37         GR_GL_CALL(gpu->glInterface(), VertexAttribPointer(index,
38                                                            size,
39                                                            type,
40                                                            normalized,
41                                                            stride,
42                                                            offset));
43         array->fAttribPointerIsValid = true;
44         array->fVertexBufferID = buffer->bufferID();
45         array->fSize = size;
46         array->fNormalized = normalized;
47         array->fStride = stride;
48         array->fOffset = offset;
49     }
50 }
51 
setFixedFunctionVertexArray(const GrGpuGL * gpu,GrGLVertexBuffer * buffer,GrGLint size,GrGLenum type,GrGLsizei stride,GrGLvoid * offset)52 void GrGLAttribArrayState::setFixedFunctionVertexArray(const GrGpuGL* gpu,
53                                                        GrGLVertexBuffer* buffer,
54                                                        GrGLint size,
55                                                        GrGLenum type,
56                                                        GrGLsizei stride,
57                                                        GrGLvoid* offset) {
58     SkASSERT(gpu->glCaps().fixedFunctionSupport());
59     AttribArrayState* array = &fFixedFunctionVertexArray;
60     if (!array->fEnableIsValid || !array->fEnabled) {
61         GR_GL_CALL(gpu->glInterface(), EnableClientState(GR_GL_VERTEX_ARRAY));
62         array->fEnableIsValid = true;
63         array->fEnabled = true;
64     }
65     if (!array->fAttribPointerIsValid ||
66         array->fVertexBufferID != buffer->bufferID() ||
67         array->fSize != size ||
68         array->fStride != stride ||
69         array->fOffset != offset) {
70 
71         buffer->bind();
72         GR_GL_CALL(gpu->glInterface(), VertexPointer(size,
73                                                      type,
74                                                      stride,
75                                                      offset));
76         array->fAttribPointerIsValid = true;
77         array->fVertexBufferID = buffer->bufferID();
78         array->fSize = size;
79         array->fStride = stride;
80         array->fOffset = offset;
81     }
82 }
83 
disableUnusedArrays(const GrGpuGL * gpu,uint64_t usedMask,bool usingFFVertexArray)84 void GrGLAttribArrayState::disableUnusedArrays(const GrGpuGL* gpu, uint64_t usedMask, bool usingFFVertexArray) {
85     int count = fAttribArrayStates.count();
86     for (int i = 0; i < count; ++i) {
87         if (!(usedMask & 0x1)) {
88             if (!fAttribArrayStates[i].fEnableIsValid || fAttribArrayStates[i].fEnabled) {
89                 GR_GL_CALL(gpu->glInterface(), DisableVertexAttribArray(i));
90                 fAttribArrayStates[i].fEnableIsValid = true;
91                 fAttribArrayStates[i].fEnabled = false;
92             }
93         } else {
94             SkASSERT(fAttribArrayStates[i].fEnableIsValid && fAttribArrayStates[i].fEnabled);
95         }
96         // if the count is greater than 64 then this will become 0 and we will disable arrays 64+.
97         usedMask >>= 1;
98     }
99 
100     // Deal with fixed-function vertex arrays.
101     if (gpu->glCaps().fixedFunctionSupport()) {
102         if (!usingFFVertexArray) {
103             if (!fFixedFunctionVertexArray.fEnableIsValid || fFixedFunctionVertexArray.fEnabled) {
104                 GR_GL_CALL(gpu->glInterface(), DisableClientState(GR_GL_VERTEX_ARRAY));
105                 fFixedFunctionVertexArray.fEnableIsValid = true;
106                 fFixedFunctionVertexArray.fEnabled = false;
107             }
108         } else {
109             SkASSERT(fFixedFunctionVertexArray.fEnableIsValid && fFixedFunctionVertexArray.fEnabled);
110         }
111         // When we use fixed function vertex processing we always use the vertex array and none of
112         // the other arrays.
113         if (!fUnusedFixedFunctionArraysDisabled) {
114             GR_GL_CALL(gpu->glInterface(), DisableClientState(GR_GL_NORMAL_ARRAY));
115             GR_GL_CALL(gpu->glInterface(), DisableClientState(GR_GL_COLOR_ARRAY));
116             GR_GL_CALL(gpu->glInterface(), DisableClientState(GR_GL_SECONDARY_COLOR_ARRAY));
117             GR_GL_CALL(gpu->glInterface(), DisableClientState(GR_GL_INDEX_ARRAY));
118             GR_GL_CALL(gpu->glInterface(), DisableClientState(GR_GL_EDGE_FLAG_ARRAY));
119             for (int i = 0; i < gpu->glCaps().maxFixedFunctionTextureCoords(); ++i) {
120                 GR_GL_CALL(gpu->glInterface(), ClientActiveTexture(GR_GL_TEXTURE0 + i));
121                 GR_GL_CALL(gpu->glInterface(), DisableClientState(GR_GL_TEXTURE_COORD_ARRAY));
122             }
123             fUnusedFixedFunctionArraysDisabled = true;
124         }
125     } else {
126         SkASSERT(!usingFFVertexArray);
127     }
128 }
129 
130 ///////////////////////////////////////////////////////////////////////////////////////////////////
131 
GrGLVertexArray(GrGpuGL * gpu,GrGLint id,int attribCount)132 GrGLVertexArray::GrGLVertexArray(GrGpuGL* gpu, GrGLint id, int attribCount)
133     : GrResource(gpu, false)
134     , fID(id)
135     , fAttribArrays(attribCount)
136     , fIndexBufferIDIsValid(false) {
137 }
138 
onAbandon()139 void GrGLVertexArray::onAbandon() {
140     fID = 0;
141     INHERITED::onAbandon();
142 }
143 
onRelease()144 void GrGLVertexArray::onRelease() {
145     if (0 != fID) {
146         GL_CALL(DeleteVertexArrays(1, &fID));
147         GPUGL->notifyVertexArrayDelete(fID);
148         fID = 0;
149     }
150     INHERITED::onRelease();
151 }
152 
bind()153 GrGLAttribArrayState* GrGLVertexArray::bind() {
154     if (0 == fID) {
155         return NULL;
156     }
157     GPUGL->bindVertexArray(fID);
158     return &fAttribArrays;
159 }
160 
bindWithIndexBuffer(const GrGLIndexBuffer * buffer)161 GrGLAttribArrayState* GrGLVertexArray::bindWithIndexBuffer(const GrGLIndexBuffer* buffer) {
162     GrGLAttribArrayState* state = this->bind();
163     if (NULL != state && NULL != buffer) {
164         GrGLuint bufferID = buffer->bufferID();
165         if (!fIndexBufferIDIsValid || bufferID != fIndexBufferID) {
166             GL_CALL(BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, bufferID));
167             fIndexBufferIDIsValid = true;
168             fIndexBufferID = bufferID;
169         }
170     }
171     return state;
172 }
173 
notifyIndexBufferDelete(GrGLuint bufferID)174 void GrGLVertexArray::notifyIndexBufferDelete(GrGLuint bufferID) {
175     if (fIndexBufferIDIsValid && bufferID == fIndexBufferID) {
176         fIndexBufferID = 0;
177     }
178  }
179 
invalidateCachedState()180 void GrGLVertexArray::invalidateCachedState() {
181     fAttribArrays.invalidate();
182     fIndexBufferIDIsValid = false;
183 }
184