blob: f7fd4955dcaff195f7e548d38cf8b15ed4ade789 [file] [log] [blame]
// 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_;
}
GLboolean integer() const {
return integer_;
}
bool enabled() const {
return enabled_;
}
// Find the maximum vertex accessed, accounting for instancing.
GLuint MaxVertexAccessed(GLsizei primcount,
GLuint max_vertex_accessed) const {
return 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,
GLboolean integer);
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_;
GLboolean integer_;
// 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,
GLboolean integer) {
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, integer);
}
}
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,
bool instanced,
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_