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 buffer()38 Buffer* buffer() const { return buffer_.get(); } 39 offset()40 GLsizei offset() const { 41 return offset_; 42 } 43 index()44 GLuint index() const { 45 return index_; 46 } 47 size()48 GLint size() const { 49 return size_; 50 } 51 type()52 GLenum type() const { 53 return type_; 54 } 55 normalized()56 GLboolean normalized() const { 57 return normalized_; 58 } 59 gl_stride()60 GLsizei gl_stride() const { 61 return gl_stride_; 62 } 63 divisor()64 GLuint divisor() const { 65 return divisor_; 66 } 67 enabled()68 bool enabled() const { 69 return enabled_; 70 } 71 72 // Find the maximum vertex accessed, accounting for instancing. MaxVertexAccessed(GLsizei primcount,GLuint max_vertex_accessed)73 GLuint MaxVertexAccessed(GLsizei primcount, 74 GLuint max_vertex_accessed) const { 75 return divisor_ ? ((primcount - 1) / divisor_) : max_vertex_accessed; 76 } 77 is_client_side_array()78 bool is_client_side_array() const { 79 return is_client_side_array_; 80 } 81 set_is_client_side_array(bool value)82 void set_is_client_side_array(bool value) { 83 is_client_side_array_ = value; 84 } 85 86 private: 87 friend class VertexAttribManager; 88 set_enabled(bool enabled)89 void set_enabled(bool enabled) { 90 enabled_ = enabled; 91 } 92 set_index(GLuint index)93 void set_index(GLuint index) { 94 index_ = index; 95 } 96 SetList(VertexAttribList * new_list)97 void SetList(VertexAttribList* new_list) { 98 DCHECK(new_list); 99 100 if (list_) { 101 list_->erase(it_); 102 } 103 104 it_ = new_list->insert(new_list->end(), this); 105 list_ = new_list; 106 } 107 108 void SetInfo( 109 Buffer* buffer, 110 GLint size, 111 GLenum type, 112 GLboolean normalized, 113 GLsizei gl_stride, 114 GLsizei real_stride, 115 GLsizei offset); 116 SetDivisor(GLsizei divisor)117 void SetDivisor(GLsizei divisor) { 118 divisor_ = divisor; 119 } 120 121 void Unbind(Buffer* buffer); 122 123 // The index of this attrib. 124 GLuint index_; 125 126 // Whether or not this attribute is enabled. 127 bool enabled_; 128 129 // number of components (1, 2, 3, 4) 130 GLint size_; 131 132 // GL_BYTE, GL_FLOAT, etc. See glVertexAttribPointer. 133 GLenum type_; 134 135 // The offset into the buffer. 136 GLsizei offset_; 137 138 GLboolean normalized_; 139 140 // The stride passed to glVertexAttribPointer. 141 GLsizei gl_stride_; 142 143 // The stride that will be used to access the buffer. This is the actual 144 // stide, NOT the GL bogus stride. In other words there is never a stride 145 // of 0. 146 GLsizei real_stride_; 147 148 GLsizei divisor_; 149 150 // Will be true if this was assigned to a client side array. 151 bool is_client_side_array_; 152 153 // The buffer bound to this attribute. 154 scoped_refptr<Buffer> buffer_; 155 156 // List this info is on. 157 VertexAttribList* list_; 158 159 // Iterator for list this info is on. Enabled/Disabled 160 VertexAttribList::iterator it_; 161 }; 162 163 // Manages vertex attributes. 164 // This class also acts as the service-side representation of a 165 // vertex array object and it's contained state. 166 class GPU_EXPORT VertexAttribManager : 167 public base::RefCounted<VertexAttribManager> { 168 public: 169 typedef std::list<VertexAttrib*> VertexAttribList; 170 171 VertexAttribManager(); 172 173 void Initialize(uint32 num_vertex_attribs, bool init_attribs); 174 175 bool Enable(GLuint index, bool enable); 176 HaveFixedAttribs()177 bool HaveFixedAttribs() const { 178 return num_fixed_attribs_ != 0; 179 } 180 GetEnabledVertexAttribs()181 const VertexAttribList& GetEnabledVertexAttribs() const { 182 return enabled_vertex_attribs_; 183 } 184 GetVertexAttrib(GLuint index)185 VertexAttrib* GetVertexAttrib(GLuint index) { 186 if (index < vertex_attribs_.size()) { 187 return &vertex_attribs_[index]; 188 } 189 return NULL; 190 } 191 SetAttribInfo(GLuint index,Buffer * buffer,GLint size,GLenum type,GLboolean normalized,GLsizei gl_stride,GLsizei real_stride,GLsizei offset)192 void SetAttribInfo( 193 GLuint index, 194 Buffer* buffer, 195 GLint size, 196 GLenum type, 197 GLboolean normalized, 198 GLsizei gl_stride, 199 GLsizei real_stride, 200 GLsizei offset) { 201 VertexAttrib* attrib = GetVertexAttrib(index); 202 if (attrib) { 203 if (attrib->type() == GL_FIXED) { 204 --num_fixed_attribs_; 205 } 206 if (type == GL_FIXED) { 207 ++num_fixed_attribs_; 208 } 209 attrib->SetInfo( 210 buffer, size, type, normalized, gl_stride, real_stride, offset); 211 } 212 } 213 SetDivisor(GLuint index,GLuint divisor)214 void SetDivisor(GLuint index, GLuint divisor) { 215 VertexAttrib* attrib = GetVertexAttrib(index); 216 if (attrib) { 217 attrib->SetDivisor(divisor); 218 } 219 } 220 221 void SetElementArrayBuffer(Buffer* buffer); 222 element_array_buffer()223 Buffer* element_array_buffer() const { return element_array_buffer_.get(); } 224 service_id()225 GLuint service_id() const { 226 return service_id_; 227 } 228 229 void Unbind(Buffer* buffer); 230 IsDeleted()231 bool IsDeleted() const { 232 return deleted_; 233 } 234 IsValid()235 bool IsValid() const { 236 return !IsDeleted(); 237 } 238 num_attribs()239 size_t num_attribs() const { 240 return vertex_attribs_.size(); 241 } 242 243 bool ValidateBindings( 244 const char* function_name, 245 GLES2Decoder* decoder, 246 FeatureInfo* feature_info, 247 Program* current_program, 248 GLuint max_vertex_accessed, 249 bool instanced, 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 MarkAsDeleted()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