1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
|
// 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 <vector>
#include "base/containers/hash_tables.h"
#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);
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();
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();
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 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_;
base::hash_map<std::string, GLint> frag_data_locations_;
base::hash_map<std::string, GLint> frag_data_indices_;
};
Program* GetProgramInfo(
GLES2Implementation* gl, GLuint program, ProgramInfoType type);
typedef base::hash_map<GLuint, Program> ProgramInfoMap;
ProgramInfoMap program_infos_;
mutable base::Lock lock_;
};
} // namespace gles2
} // namespace gpu
#endif // GPU_COMMAND_BUFFER_CLIENT_PROGRAM_INFO_MANAGER_H_
|