blob: 66ff795d1549848bb220410d1e2d487f48fe3f81 [file] [log] [blame]
// Copyright (c) 2010 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_PROGRAM_MANAGER_H_
#define GPU_COMMAND_BUFFER_SERVICE_PROGRAM_MANAGER_H_
#include <map>
#include <string>
#include <vector>
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/ref_counted.h"
#include "gpu/command_buffer/service/gl_utils.h"
#include "gpu/command_buffer/service/shader_manager.h"
namespace gpu {
namespace gles2 {
// Tracks the Programs.
//
// NOTE: To support shared resources an instance of this class will
// need to be shared by multiple GLES2Decoders.
class ProgramManager {
public:
// This is used to track which attributes a particular program needs
// so we can verify at glDrawXXX time that every attribute is either disabled
// or if enabled that it points to a valid source.
class ProgramInfo : public base::RefCounted<ProgramInfo> {
public:
typedef scoped_refptr<ProgramInfo> Ref;
static const int kMaxAttachedShaders = 2;
struct UniformInfo {
UniformInfo(GLsizei _size, GLenum _type, const std::string& _name)
: size(_size),
type(_type),
name(_name) {
}
bool IsSampler() const {
return type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE;
}
GLsizei size;
GLenum type;
bool is_array;
std::string name;
std::vector<GLint> element_locations;
std::vector<GLuint> texture_units;
};
struct VertexAttribInfo {
VertexAttribInfo(GLsizei _size, GLenum _type, const std::string& _name,
GLint _location)
: size(_size),
type(_type),
location(_location),
name(_name) {
}
GLsizei size;
GLenum type;
GLint location;
std::string name;
};
typedef std::vector<UniformInfo> UniformInfoVector;
typedef std::vector<VertexAttribInfo> AttribInfoVector;
typedef std::vector<int> SamplerIndices;
explicit ProgramInfo(GLuint service_id)
: max_attrib_name_length_(0),
max_uniform_name_length_(0),
service_id_(service_id),
valid_(false) {
}
GLuint service_id() const {
return service_id_;
}
const SamplerIndices& sampler_indices() {
return sampler_indices_;
}
// Resets the program after an unsuccessful link.
void Reset();
// Updates the program info after a successful link.
void Update();
// Updates the program log info.
void UpdateLogInfo();
const AttribInfoVector& GetAttribInfos() const {
return attrib_infos_;
}
const VertexAttribInfo* GetAttribInfo(GLint index) const {
return (static_cast<size_t>(index) < attrib_infos_.size()) ?
&attrib_infos_[index] : NULL;
}
GLint GetAttribLocation(const std::string& name) const;
const VertexAttribInfo* GetAttribInfoByLocation(GLuint location) const {
if (location < attrib_location_to_index_map_.size()) {
GLint index = attrib_location_to_index_map_[location];
if (index >= 0) {
return &attrib_infos_[index];
}
}
return NULL;
}
const UniformInfo* GetUniformInfo(GLint index) const {
return (static_cast<size_t>(index) < uniform_infos_.size()) ?
&uniform_infos_[index] : NULL;
}
// Gets the location of a uniform by name.
GLint GetUniformLocation(const std::string& name) const;
// Gets the type of a uniform by location.
bool GetUniformTypeByLocation(GLint location, GLenum* type) const;
// Sets the sampler values for a uniform.
// This is safe to call for any location. If the location is not
// a sampler uniform nothing will happen.
bool SetSamplers(GLint location, GLsizei count, const GLint* value);
bool IsDeleted() const {
return service_id_ == 0;
}
void GetProgramiv(GLenum pname, GLint* params);
bool IsValid() const {
return valid_;
}
bool AttachShader(ShaderManager::ShaderInfo* info);
void DetachShader(ShaderManager::ShaderInfo* info);
bool CanLink() const;
const std::string& log_info() const {
return log_info_;
}
void set_log_info(const std::string& str) {
log_info_ = str;
}
private:
friend class base::RefCounted<ProgramInfo>;
friend class ProgramManager;
~ProgramInfo() { }
void MarkAsDeleted() {
service_id_ = 0;
}
const UniformInfo* AddUniformInfo(
GLsizei size, GLenum type, GLint location, const std::string& name);
GLsizei max_attrib_name_length_;
// Attrib by index.
AttribInfoVector attrib_infos_;
// Attrib by location to index.
std::vector<GLint> attrib_location_to_index_map_;
GLsizei max_uniform_name_length_;
// Uniform info by index.
UniformInfoVector uniform_infos_;
// Uniform location to index.
std::vector<GLint> uniform_location_to_index_map_;
// The indices of the uniforms that are samplers.
SamplerIndices sampler_indices_;
// The program this ProgramInfo is tracking.
GLuint service_id_;
// Shaders by type of shader.
ShaderManager::ShaderInfo::Ref attached_shaders_[kMaxAttachedShaders];
// This is true if glLinkProgram was successful.
bool valid_;
// Log info
std::string log_info_;
};
ProgramManager() { }
~ProgramManager();
// Must call before destruction.
void Destroy(bool have_context);
// Creates a new program info.
void CreateProgramInfo(GLuint client_id, GLuint service_id);
// Gets a program info
ProgramInfo* GetProgramInfo(GLuint client_id);
// Deletes the program info for the given program.
void RemoveProgramInfo(GLuint client_id);
// Gets a client id for a given service id.
bool GetClientId(GLuint service_id, GLuint* client_id) const;
// Returns true if prefix is invalid for gl.
static bool IsInvalidPrefix(const char* name, size_t length);
private:
// Info for each "successfully linked" program by service side program Id.
// TODO(gman): Choose a faster container.
typedef std::map<GLuint, ProgramInfo::Ref> ProgramInfoMap;
ProgramInfoMap program_infos_;
DISALLOW_COPY_AND_ASSIGN(ProgramManager);
};
} // namespace gles2
} // namespace gpu
#endif // GPU_COMMAND_BUFFER_SERVICE_PROGRAM_MANAGER_H_