• 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 "GrGLGpu.h"
10 
11 struct AttribLayout {
12     GrGLint     fCount;
13     GrGLenum    fType;
14     GrGLboolean fNormalized;  // Only used by floating point types.
15 };
16 
17 static const AttribLayout gLayouts[kGrVertexAttribTypeCount] = {
18     {1, GR_GL_FLOAT, false},         // kFloat_GrVertexAttribType
19     {2, GR_GL_FLOAT, false},         // kVec2f_GrVertexAttribType
20     {3, GR_GL_FLOAT, false},         // kVec3f_GrVertexAttribType
21     {4, GR_GL_FLOAT, false},         // kVec4f_GrVertexAttribType
22     {1, GR_GL_UNSIGNED_BYTE, true},  // kUByte_GrVertexAttribType
23     {4, GR_GL_UNSIGNED_BYTE, true},  // kVec4ub_GrVertexAttribType
24     {2, GR_GL_UNSIGNED_SHORT, true}, // kVec2s_GrVertexAttribType
25     {1, GR_GL_INT, false},           // kInt_GrVertexAttribType
26     {1, GR_GL_UNSIGNED_INT, false},  // kUint_GrVertexAttribType
27 };
28 
29 GR_STATIC_ASSERT(0 == kFloat_GrVertexAttribType);
30 GR_STATIC_ASSERT(1 == kVec2f_GrVertexAttribType);
31 GR_STATIC_ASSERT(2 == kVec3f_GrVertexAttribType);
32 GR_STATIC_ASSERT(3 == kVec4f_GrVertexAttribType);
33 GR_STATIC_ASSERT(4 == kUByte_GrVertexAttribType);
34 GR_STATIC_ASSERT(5 == kVec4ub_GrVertexAttribType);
35 GR_STATIC_ASSERT(6 == kVec2us_GrVertexAttribType);
36 GR_STATIC_ASSERT(7 == kInt_GrVertexAttribType);
37 GR_STATIC_ASSERT(8 == kUint_GrVertexAttribType);
38 
set(GrGLGpu * gpu,int index,GrGLuint vertexBufferID,GrVertexAttribType type,GrGLsizei stride,GrGLvoid * offset)39 void GrGLAttribArrayState::set(GrGLGpu* gpu,
40                                int index,
41                                GrGLuint vertexBufferID,
42                                GrVertexAttribType type,
43                                GrGLsizei stride,
44                                GrGLvoid* offset) {
45     SkASSERT(index >= 0 && index < fAttribArrayStates.count());
46     AttribArrayState* array = &fAttribArrayStates[index];
47     if (!array->fEnableIsValid || !array->fEnabled) {
48         GR_GL_CALL(gpu->glInterface(), EnableVertexAttribArray(index));
49         array->fEnableIsValid = true;
50         array->fEnabled = true;
51     }
52     if (!array->fAttribPointerIsValid ||
53         array->fVertexBufferID != vertexBufferID ||
54         array->fType != type ||
55         array->fStride != stride ||
56         array->fOffset != offset) {
57 
58         gpu->bindVertexBuffer(vertexBufferID);
59         const AttribLayout& layout = gLayouts[type];
60         if (!GrVertexAttribTypeIsIntType(type)) {
61             GR_GL_CALL(gpu->glInterface(), VertexAttribPointer(index,
62                                                                layout.fCount,
63                                                                layout.fType,
64                                                                layout.fNormalized,
65                                                                stride,
66                                                                offset));
67         } else {
68             SkASSERT(gpu->caps()->shaderCaps()->integerSupport());
69             SkASSERT(!layout.fNormalized);
70             GR_GL_CALL(gpu->glInterface(), VertexAttribIPointer(index,
71                                                                 layout.fCount,
72                                                                 layout.fType,
73                                                                 stride,
74                                                                 offset));
75         }
76         array->fAttribPointerIsValid = true;
77         array->fVertexBufferID = vertexBufferID;
78         array->fType = type;
79         array->fStride = stride;
80         array->fOffset = offset;
81     }
82 }
83 
disableUnusedArrays(const GrGLGpu * gpu,uint64_t usedMask)84 void GrGLAttribArrayState::disableUnusedArrays(const GrGLGpu* gpu, uint64_t usedMask) {
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 
101 ///////////////////////////////////////////////////////////////////////////////////////////////////
102 
GrGLVertexArray(GrGLint id,int attribCount)103 GrGLVertexArray::GrGLVertexArray(GrGLint id, int attribCount)
104     : fID(id)
105     , fAttribArrays(attribCount)
106     , fIndexBufferIDIsValid(false) {
107 }
108 
bind(GrGLGpu * gpu)109 GrGLAttribArrayState* GrGLVertexArray::bind(GrGLGpu* gpu) {
110     if (0 == fID) {
111         return nullptr;
112     }
113     gpu->bindVertexArray(fID);
114     return &fAttribArrays;
115 }
116 
bindWithIndexBuffer(GrGLGpu * gpu,GrGLuint ibufferID)117 GrGLAttribArrayState* GrGLVertexArray::bindWithIndexBuffer(GrGLGpu* gpu, GrGLuint ibufferID) {
118     GrGLAttribArrayState* state = this->bind(gpu);
119     if (state) {
120         if (!fIndexBufferIDIsValid || ibufferID != fIndexBufferID) {
121             GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, ibufferID));
122             fIndexBufferIDIsValid = true;
123             fIndexBufferID = ibufferID;
124         }
125     }
126     return state;
127 }
128 
notifyIndexBufferDelete(GrGLuint bufferID)129 void GrGLVertexArray::notifyIndexBufferDelete(GrGLuint bufferID) {
130     if (fIndexBufferIDIsValid && bufferID == fIndexBufferID) {
131         fIndexBufferID = 0;
132     }
133  }
134 
invalidateCachedState()135 void GrGLVertexArray::invalidateCachedState() {
136     fAttribArrays.invalidate();
137     fIndexBufferIDIsValid = false;
138 }
139