1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef GPU_COMMAND_BUFFER_SERVICE_VERTEX_ATTRIB_MANAGER_H_ 6 #define GPU_COMMAND_BUFFER_SERVICE_VERTEX_ATTRIB_MANAGER_H_ 7 8 #include <list> 9 #include <vector> 10 #include "base/logging.h" 11 #include "base/memory/ref_counted.h" 12 #include "build/build_config.h" 13 #include "gpu/command_buffer/service/buffer_manager.h" 14 #include "gpu/command_buffer/service/gl_utils.h" 15 #include "gpu/gpu_export.h" 16 17 namespace gpu { 18 namespace gles2 { 19 20 class FeatureInfo; 21 class GLES2Decoder; 22 class Program; 23 class VertexArrayManager; 24 25 // Info about a Vertex Attribute. This is used to track what the user currently 26 // has bound on each Vertex Attribute so that checking can be done at 27 // glDrawXXX time. 28 class GPU_EXPORT VertexAttrib { 29 public: 30 typedef std::list<VertexAttrib*> VertexAttribList; 31 32 VertexAttrib(); 33 ~VertexAttrib(); 34 35 // Returns true if this VertexAttrib can access index. 36 bool CanAccess(GLuint index) const; 37 38 Buffer* buffer() const { return buffer_.get(); } 39 40 GLsizei offset() const { 41 return offset_; 42 } 43 44 GLuint index() const { 45 return index_; 46 } 47 48 GLint size() const { 49 return size_; 50 } 51 52 GLenum type() const { 53 return type_; 54 } 55 56 GLboolean normalized() const { 57 return normalized_; 58 } 59 60 GLsizei gl_stride() const { 61 return gl_stride_; 62 } 63 64 GLuint divisor() const { 65 return divisor_; 66 } 67 68 bool enabled() const { 69 return enabled_; 70 } 71 72 // Find the maximum vertex accessed, accounting for instancing. 73 GLuint MaxVertexAccessed(GLsizei primcount, 74 GLuint max_vertex_accessed) const { 75 return (primcount && divisor_) ? ((primcount - 1) / divisor_) : 76 max_vertex_accessed; 77 } 78 79 bool is_client_side_array() const { 80 return is_client_side_array_; 81 } 82 83 void set_is_client_side_array(bool value) { 84 is_client_side_array_ = value; 85 } 86 87 private: 88 friend class VertexAttribManager; 89 90 void set_enabled(bool enabled) { 91 enabled_ = enabled; 92 } 93 94 void set_index(GLuint index) { 95 index_ = index; 96 } 97 98 void SetList(VertexAttribList* new_list) { 99 DCHECK(new_list); 100 101 if (list_) { 102 list_->erase(it_); 103 } 104 105 it_ = new_list->insert(new_list->end(), this); 106 list_ = new_list; 107 } 108 109 void SetInfo( 110 Buffer* buffer, 111 GLint size, 112 GLenum type, 113 GLboolean normalized, 114 GLsizei gl_stride, 115 GLsizei real_stride, 116 GLsizei offset); 117 118 void SetDivisor(GLsizei divisor) { 119 divisor_ = divisor; 120 } 121 122 void Unbind(Buffer* buffer); 123 124 // The index of this attrib. 125 GLuint index_; 126 127 // Whether or not this attribute is enabled. 128 bool enabled_; 129 130 // number of components (1, 2, 3, 4) 131 GLint size_; 132 133 // GL_BYTE, GL_FLOAT, etc. See glVertexAttribPointer. 134 GLenum type_; 135 136 // The offset into the buffer. 137 GLsizei offset_; 138 139 GLboolean normalized_; 140 141 // The stride passed to glVertexAttribPointer. 142 GLsizei gl_stride_; 143 144 // The stride that will be used to access the buffer. This is the actual 145 // stide, NOT the GL bogus stride. In other words there is never a stride 146 // of 0. 147 GLsizei real_stride_; 148 149 GLsizei divisor_; 150 151 // Will be true if this was assigned to a client side array. 152 bool is_client_side_array_; 153 154 // The buffer bound to this attribute. 155 scoped_refptr<Buffer> buffer_; 156 157 // List this info is on. 158 VertexAttribList* list_; 159 160 // Iterator for list this info is on. Enabled/Disabled 161 VertexAttribList::iterator it_; 162 }; 163 164 // Manages vertex attributes. 165 // This class also acts as the service-side representation of a 166 // vertex array object and it's contained state. 167 class GPU_EXPORT VertexAttribManager : 168 public base::RefCounted<VertexAttribManager> { 169 public: 170 typedef std::list<VertexAttrib*> VertexAttribList; 171 172 VertexAttribManager(); 173 174 void Initialize(uint32 num_vertex_attribs, bool init_attribs = true); 175 176 bool Enable(GLuint index, bool enable); 177 178 bool HaveFixedAttribs() const { 179 return num_fixed_attribs_ != 0; 180 } 181 182 const VertexAttribList& GetEnabledVertexAttribs() const { 183 return enabled_vertex_attribs_; 184 } 185 186 VertexAttrib* GetVertexAttrib(GLuint index) { 187 if (index < vertex_attribs_.size()) { 188 return &vertex_attribs_[index]; 189 } 190 return NULL; 191 } 192 193 void SetAttribInfo( 194 GLuint index, 195 Buffer* buffer, 196 GLint size, 197 GLenum type, 198 GLboolean normalized, 199 GLsizei gl_stride, 200 GLsizei real_stride, 201 GLsizei offset) { 202 VertexAttrib* attrib = GetVertexAttrib(index); 203 if (attrib) { 204 if (attrib->type() == GL_FIXED) { 205 --num_fixed_attribs_; 206 } 207 if (type == GL_FIXED) { 208 ++num_fixed_attribs_; 209 } 210 attrib->SetInfo( 211 buffer, size, type, normalized, gl_stride, real_stride, offset); 212 } 213 } 214 215 void SetDivisor(GLuint index, GLuint divisor) { 216 VertexAttrib* attrib = GetVertexAttrib(index); 217 if (attrib) { 218 attrib->SetDivisor(divisor); 219 } 220 } 221 222 void SetElementArrayBuffer(Buffer* buffer); 223 224 Buffer* element_array_buffer() const { return element_array_buffer_.get(); } 225 226 GLuint service_id() const { 227 return service_id_; 228 } 229 230 void Unbind(Buffer* buffer); 231 232 bool IsDeleted() const { 233 return deleted_; 234 } 235 236 bool IsValid() const { 237 return !IsDeleted(); 238 } 239 240 size_t num_attribs() const { 241 return vertex_attribs_.size(); 242 } 243 244 bool ValidateBindings( 245 const char* function_name, 246 GLES2Decoder* decoder, 247 FeatureInfo* feature_info, 248 Program* current_program, 249 GLuint max_vertex_accessed, 250 GLsizei primcount); 251 252 private: 253 friend class VertexArrayManager; 254 friend class VertexArrayManagerTest; 255 friend class base::RefCounted<VertexAttribManager>; 256 257 // Used when creating from a VertexArrayManager 258 VertexAttribManager(VertexArrayManager* manager, GLuint service_id, 259 uint32 num_vertex_attribs); 260 261 ~VertexAttribManager(); 262 263 void MarkAsDeleted() { 264 deleted_ = true; 265 } 266 267 // number of attribs using type GL_FIXED. 268 int num_fixed_attribs_; 269 270 // Info for each vertex attribute saved so we can check at glDrawXXX time 271 // if it is safe to draw. 272 std::vector<VertexAttrib> vertex_attribs_; 273 274 // The currently bound element array buffer. If this is 0 it is illegal 275 // to call glDrawElements. 276 scoped_refptr<Buffer> element_array_buffer_; 277 278 // Lists for which vertex attribs are enabled, disabled. 279 VertexAttribList enabled_vertex_attribs_; 280 VertexAttribList disabled_vertex_attribs_; 281 282 // The VertexArrayManager that owns this VertexAttribManager 283 VertexArrayManager* manager_; 284 285 // True if deleted. 286 bool deleted_; 287 288 // Service side vertex array object id. 289 GLuint service_id_; 290 }; 291 292 } // namespace gles2 293 } // namespace gpu 294 295 #endif // GPU_COMMAND_BUFFER_SERVICE_VERTEX_ATTRIB_MANAGER_H_ 296 297