root/gpu/command_buffer/service/vertex_attrib_manager.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef GPU_COMMAND_BUFFER_SERVICE_VERTEX_ATTRIB_MANAGER_H_
#define GPU_COMMAND_BUFFER_SERVICE_VERTEX_ATTRIB_MANAGER_H_

#include <list>
#include <vector>
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "build/build_config.h"
#include "gpu/command_buffer/service/buffer_manager.h"
#include "gpu/command_buffer/service/gl_utils.h"
#include "gpu/gpu_export.h"

namespace gpu {
namespace gles2 {

class FeatureInfo;
class GLES2Decoder;
class Program;
class VertexArrayManager;

// Info about a Vertex Attribute. This is used to track what the user currently
// has bound on each Vertex Attribute so that checking can be done at
// glDrawXXX time.
class GPU_EXPORT VertexAttrib {
 public:
  typedef std::list<VertexAttrib*> VertexAttribList;

  VertexAttrib();
  ~VertexAttrib();

  // Returns true if this VertexAttrib can access index.
  bool CanAccess(GLuint index) const;

  Buffer* buffer() const { return buffer_.get(); }

  GLsizei offset() const {
    return offset_;
  }

  GLuint index() const {
    return index_;
  }

  GLint size() const {
    return size_;
  }

  GLenum type() const {
    return type_;
  }

  GLboolean normalized() const {
    return normalized_;
  }

  GLsizei gl_stride() const {
    return gl_stride_;
  }

  GLuint divisor() const {
    return divisor_;
  }

  bool enabled() const {
    return enabled_;
  }

  // Find the maximum vertex accessed, accounting for instancing.
  GLuint MaxVertexAccessed(GLsizei primcount,
                           GLuint max_vertex_accessed) const {
    return (primcount && divisor_) ? ((primcount - 1) / divisor_) :
                                     max_vertex_accessed;
  }

  bool is_client_side_array() const {
    return is_client_side_array_;
  }

  void set_is_client_side_array(bool value) {
    is_client_side_array_ = value;
  }

 private:
  friend class VertexAttribManager;

  void set_enabled(bool enabled) {
    enabled_ = enabled;
  }

  void set_index(GLuint index) {
    index_ = index;
  }

  void SetList(VertexAttribList* new_list) {
    DCHECK(new_list);

    if (list_) {
      list_->erase(it_);
    }

    it_ = new_list->insert(new_list->end(), this);
    list_ = new_list;
  }

  void SetInfo(
      Buffer* buffer,
      GLint size,
      GLenum type,
      GLboolean normalized,
      GLsizei gl_stride,
      GLsizei real_stride,
      GLsizei offset);

  void SetDivisor(GLsizei divisor) {
    divisor_ = divisor;
  }

  void Unbind(Buffer* buffer);

  // The index of this attrib.
  GLuint index_;

  // Whether or not this attribute is enabled.
  bool enabled_;

  // number of components (1, 2, 3, 4)
  GLint size_;

  // GL_BYTE, GL_FLOAT, etc. See glVertexAttribPointer.
  GLenum type_;

  // The offset into the buffer.
  GLsizei offset_;

  GLboolean normalized_;

  // The stride passed to glVertexAttribPointer.
  GLsizei gl_stride_;

  // The stride that will be used to access the buffer. This is the actual
  // stide, NOT the GL bogus stride. In other words there is never a stride
  // of 0.
  GLsizei real_stride_;

  GLsizei divisor_;

  // Will be true if this was assigned to a client side array.
  bool is_client_side_array_;

  // The buffer bound to this attribute.
  scoped_refptr<Buffer> buffer_;

  // List this info is on.
  VertexAttribList* list_;

  // Iterator for list this info is on. Enabled/Disabled
  VertexAttribList::iterator it_;
};

// Manages vertex attributes.
// This class also acts as the service-side representation of a
// vertex array object and it's contained state.
class GPU_EXPORT VertexAttribManager :
    public base::RefCounted<VertexAttribManager> {
 public:
  typedef std::list<VertexAttrib*> VertexAttribList;

  VertexAttribManager();

  void Initialize(uint32 num_vertex_attribs, bool init_attribs);

  bool Enable(GLuint index, bool enable);

  bool HaveFixedAttribs() const {
    return num_fixed_attribs_ != 0;
  }

  const VertexAttribList& GetEnabledVertexAttribs() const {
    return enabled_vertex_attribs_;
  }

  VertexAttrib* GetVertexAttrib(GLuint index) {
    if (index < vertex_attribs_.size()) {
      return &vertex_attribs_[index];
    }
    return NULL;
  }

  void SetAttribInfo(
      GLuint index,
      Buffer* buffer,
      GLint size,
      GLenum type,
      GLboolean normalized,
      GLsizei gl_stride,
      GLsizei real_stride,
      GLsizei offset) {
    VertexAttrib* attrib = GetVertexAttrib(index);
    if (attrib) {
      if (attrib->type() == GL_FIXED) {
        --num_fixed_attribs_;
      }
      if (type == GL_FIXED) {
        ++num_fixed_attribs_;
      }
      attrib->SetInfo(
          buffer, size, type, normalized, gl_stride, real_stride, offset);
    }
  }

  void SetDivisor(GLuint index, GLuint divisor) {
    VertexAttrib* attrib = GetVertexAttrib(index);
    if (attrib) {
      attrib->SetDivisor(divisor);
    }
  }

  void SetElementArrayBuffer(Buffer* buffer);

  Buffer* element_array_buffer() const { return element_array_buffer_.get(); }

  GLuint service_id() const {
    return service_id_;
  }

  void Unbind(Buffer* buffer);

  bool IsDeleted() const {
    return deleted_;
  }

  bool IsValid() const {
    return !IsDeleted();
  }

  size_t num_attribs() const {
    return vertex_attribs_.size();
  }

  bool ValidateBindings(
      const char* function_name,
      GLES2Decoder* decoder,
      FeatureInfo* feature_info,
      Program* current_program,
      GLuint max_vertex_accessed,
      GLsizei primcount);

 private:
  friend class VertexArrayManager;
  friend class VertexArrayManagerTest;
  friend class base::RefCounted<VertexAttribManager>;

  // Used when creating from a VertexArrayManager
  VertexAttribManager(VertexArrayManager* manager, GLuint service_id,
      uint32 num_vertex_attribs);

  ~VertexAttribManager();

  void MarkAsDeleted() {
    deleted_ = true;
  }

  // number of attribs using type GL_FIXED.
  int num_fixed_attribs_;

  // Info for each vertex attribute saved so we can check at glDrawXXX time
  // if it is safe to draw.
  std::vector<VertexAttrib> vertex_attribs_;

  // The currently bound element array buffer. If this is 0 it is illegal
  // to call glDrawElements.
  scoped_refptr<Buffer> element_array_buffer_;

  // Lists for which vertex attribs are enabled, disabled.
  VertexAttribList enabled_vertex_attribs_;
  VertexAttribList disabled_vertex_attribs_;

  // The VertexArrayManager that owns this VertexAttribManager
  VertexArrayManager* manager_;

  // True if deleted.
  bool deleted_;

  // Service side vertex array object id.
  GLuint service_id_;
};

}  // namespace gles2
}  // namespace gpu

#endif  // GPU_COMMAND_BUFFER_SERVICE_VERTEX_ATTRIB_MANAGER_H_


/* [<][>][^][v][top][bottom][index][help] */