Home | History | Annotate | Download | only in service
      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 divisor_ ? ((primcount - 1) / divisor_) : max_vertex_accessed;
     76   }
     77 
     78   bool is_client_side_array() const {
     79     return is_client_side_array_;
     80   }
     81 
     82   void set_is_client_side_array(bool value) {
     83     is_client_side_array_ = value;
     84   }
     85 
     86  private:
     87   friend class VertexAttribManager;
     88 
     89   void set_enabled(bool enabled) {
     90     enabled_ = enabled;
     91   }
     92 
     93   void set_index(GLuint index) {
     94     index_ = index;
     95   }
     96 
     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 
    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 
    177   bool HaveFixedAttribs() const {
    178     return num_fixed_attribs_ != 0;
    179   }
    180 
    181   const VertexAttribList& GetEnabledVertexAttribs() const {
    182     return enabled_vertex_attribs_;
    183   }
    184 
    185   VertexAttrib* GetVertexAttrib(GLuint index) {
    186     if (index < vertex_attribs_.size()) {
    187       return &vertex_attribs_[index];
    188     }
    189     return NULL;
    190   }
    191 
    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 
    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 
    223   Buffer* element_array_buffer() const { return element_array_buffer_.get(); }
    224 
    225   GLuint service_id() const {
    226     return service_id_;
    227   }
    228 
    229   void Unbind(Buffer* buffer);
    230 
    231   bool IsDeleted() const {
    232     return deleted_;
    233   }
    234 
    235   bool IsValid() const {
    236     return !IsDeleted();
    237   }
    238 
    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 
    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