blob: ee39eecb8e184f6a5fce5883ca45547c8cd4d83f [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_CLIENT_PROGRAM_INFO_MANAGER_H_
#define GPU_COMMAND_BUFFER_CLIENT_PROGRAM_INFO_MANAGER_H_
#include <GLES3/gl3.h>
#include <stdint.h>
#include <string>
#include <unordered_map>
#include <vector>
#include "base/gtest_prod_util.h"
#include "base/synchronization/lock.h"
#include "gles2_impl_export.h"
#include "gpu/command_buffer/client/gles2_implementation.h"
namespace gpu {
namespace gles2 {
// Manages info about OpenGL ES Programs.
class GLES2_IMPL_EXPORT ProgramInfoManager {
public:
ProgramInfoManager();
~ProgramInfoManager();
void CreateInfo(GLuint program);
void DeleteInfo(GLuint program);
bool GetProgramiv(
GLES2Implementation* gl, GLuint program, GLenum pname, GLint* params);
GLint GetAttribLocation(
GLES2Implementation* gl, GLuint program, const char* name);
GLint GetUniformLocation(
GLES2Implementation* gl, GLuint program, const char* name);
GLint GetFragDataIndex(GLES2Implementation* gl,
GLuint program,
const char* name);
GLint GetFragDataLocation(
GLES2Implementation* gl, GLuint program, const char* name);
bool GetActiveAttrib(
GLES2Implementation* gl, GLuint program, GLuint index, GLsizei bufsize,
GLsizei* length, GLint* size, GLenum* type, char* name);
bool GetActiveUniform(
GLES2Implementation* gl, GLuint program, GLuint index, GLsizei bufsize,
GLsizei* length, GLint* size, GLenum* type, char* name);
GLuint GetUniformBlockIndex(
GLES2Implementation* gl, GLuint program, const char* name);
bool GetActiveUniformBlockName(
GLES2Implementation* gl, GLuint program, GLuint index,
GLsizei buf_size, GLsizei* length, char* name);
bool GetActiveUniformBlockiv(
GLES2Implementation* gl, GLuint program, GLuint index,
GLenum pname, GLint* params);
// Attempt to update the |index| uniform block binding.
// It's no op if the program does not exist, or the |index| uniform block
// is not in the cache, or binding >= GL_MAX_UNIFORM_BUFFER_BINDINGS.
void UniformBlockBinding(
GLES2Implementation* gl, GLuint program, GLuint index, GLuint binding);
bool GetTransformFeedbackVarying(
GLES2Implementation* gl, GLuint program, GLuint index, GLsizei bufsize,
GLsizei* length, GLsizei* size, GLenum* type, char* name);
bool GetUniformIndices(
GLES2Implementation* gl, GLuint program, GLsizei count,
const char* const* names, GLuint* indices);
bool GetActiveUniformsiv(
GLES2Implementation* gl, GLuint program, GLsizei count,
const GLuint* indices, GLenum pname, GLint* params);
bool GetProgramInterfaceiv(
GLES2Implementation* gl, GLuint program, GLenum program_interface,
GLenum pname, GLint* params);
GLuint GetProgramResourceIndex(
GLES2Implementation* gl, GLuint program, GLenum program_interface,
const char* name);
bool GetProgramResourceName(
GLES2Implementation* gl, GLuint program, GLenum program_interface,
GLuint index, GLsizei bufsize, GLsizei* length, char* name);
bool GetProgramResourceiv(
GLES2Implementation* gl, GLuint program, GLenum program_interface,
GLuint index, GLsizei prop_count, const GLenum* props, GLsizei bufsize,
GLsizei* length, GLint* params);
GLint GetProgramResourceLocation(
GLES2Implementation* gl, GLuint program, GLenum program_interface,
const char* name);
private:
friend class ProgramInfoManagerTest;
FRIEND_TEST_ALL_PREFIXES(ProgramInfoManagerTest, UpdateES2);
FRIEND_TEST_ALL_PREFIXES(ProgramInfoManagerTest, UpdateES3UniformBlocks);
FRIEND_TEST_ALL_PREFIXES(ProgramInfoManagerTest,
UpdateES3TransformFeedbackVaryings);
FRIEND_TEST_ALL_PREFIXES(ProgramInfoManagerTest,
GetActiveUniformsivCached);
enum ProgramInfoType {
kES2,
kES3UniformBlocks,
kES3TransformFeedbackVaryings,
kES3Uniformsiv,
kNone,
};
// Need GLES2_IMPL_EXPORT for tests.
class GLES2_IMPL_EXPORT Program {
public:
struct UniformInfo {
UniformInfo(GLsizei _size, GLenum _type, const std::string& _name);
UniformInfo(const UniformInfo& other);
~UniformInfo();
GLsizei size;
GLenum type;
bool is_array;
std::string name;
std::vector<GLint> element_locations;
};
struct UniformES3 {
UniformES3();
~UniformES3();
GLint block_index;
GLint offset;
GLint array_stride;
GLint matrix_stride;
GLint is_row_major;
};
struct VertexAttrib {
VertexAttrib(GLsizei _size, GLenum _type, const std::string& _name,
GLint _location);
~VertexAttrib();
GLsizei size;
GLenum type;
GLint location;
std::string name;
};
struct UniformBlock {
UniformBlock();
UniformBlock(const UniformBlock& other);
~UniformBlock();
GLuint binding;
GLuint data_size;
std::vector<GLuint> active_uniform_indices;
GLboolean referenced_by_vertex_shader;
GLboolean referenced_by_fragment_shader;
std::string name;
};
struct TransformFeedbackVarying {
TransformFeedbackVarying();
~TransformFeedbackVarying();
GLsizei size;
GLenum type;
std::string name;
};
Program();
Program(const Program& other);
~Program();
const VertexAttrib* GetAttribInfo(GLint index) const;
GLint GetAttribLocation(const std::string& name) const;
const UniformInfo* GetUniformInfo(GLint index) const;
// Gets the location of a uniform by name.
GLint GetUniformLocation(const std::string& name) const;
// Gets the index of a uniform by name. Return INVALID_INDEX in failure.
GLuint GetUniformIndex(const std::string& name) const;
bool GetUniformsiv(
GLsizei count, const GLuint* indices, GLenum pname, GLint* params);
GLint GetFragDataIndex(const std::string& name) const;
void CacheFragDataIndex(const std::string& name, GLint index);
GLint GetFragDataLocation(const std::string& name) const;
void CacheFragDataLocation(const std::string& name, GLint loc);
bool GetProgramiv(GLenum pname, GLint* params);
// Gets the index of a uniform block by name.
GLuint GetUniformBlockIndex(const std::string& name) const;
const UniformBlock* GetUniformBlock(GLuint index) const;
// Update the binding if the |index| uniform block is in the cache.
void UniformBlockBinding(GLuint index, GLuint binding);
const TransformFeedbackVarying* GetTransformFeedbackVarying(
GLuint index) const;
// Updates the ES2 only program info after a successful link.
void UpdateES2(const std::vector<int8_t>& result);
// Updates the ES3 UniformBlock info after a successful link.
void UpdateES3UniformBlocks(const std::vector<int8_t>& result);
// Updates the ES3 Uniformsiv info after a successful link.
void UpdateES3Uniformsiv(const std::vector<int8_t>& result);
// Updates the ES3 TransformFeedbackVaryings info after a successful link.
void UpdateES3TransformFeedbackVaryings(const std::vector<int8_t>& result);
bool IsCached(ProgramInfoType type) const;
private:
bool cached_es2_;
GLsizei max_attrib_name_length_;
// Attrib by index.
std::vector<VertexAttrib> attrib_infos_;
GLsizei max_uniform_name_length_;
// Uniform info by index.
std::vector<UniformInfo> uniform_infos_;
// This is true if glLinkProgram was successful last time it was called.
bool link_status_;
// BELOW ARE ES3 ONLY INFORMATION.
bool cached_es3_uniform_blocks_;
uint32_t active_uniform_block_max_name_length_;
// Uniform blocks by index.
std::vector<UniformBlock> uniform_blocks_;
bool cached_es3_transform_feedback_varyings_;
uint32_t transform_feedback_varying_max_length_;
GLenum transform_feedback_buffer_mode_;
// TransformFeedback varyings by index.
std::vector<TransformFeedbackVarying> transform_feedback_varyings_;
bool cached_es3_uniformsiv_;
std::vector<UniformES3> uniforms_es3_;
std::unordered_map<std::string, GLint> frag_data_locations_;
std::unordered_map<std::string, GLint> frag_data_indices_;
};
Program* GetProgramInfo(
GLES2Implementation* gl, GLuint program, ProgramInfoType type);
typedef std::unordered_map<GLuint, Program> ProgramInfoMap;
ProgramInfoMap program_infos_;
mutable base::Lock lock_;
};
} // namespace gles2
} // namespace gpu
#endif // GPU_COMMAND_BUFFER_CLIENT_PROGRAM_INFO_MANAGER_H_