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
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
gpu / command_buffer / client / program_info_manager.h [blame]
// Copyright 2012 The Chromium Authors
// 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);
enum ProgramInfoType {
kES2,
kES3UniformBlocks,
kES3TransformFeedbackVaryings,
kES3Uniformsiv,
kNone,
};
void UpdateProgramInfo(GLuint program,
base::span<const int8_t> result,
ProgramInfoType type);
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);
// 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(base::span<const int8_t> result);
// Updates the ES3 UniformBlock info after a successful link.
void UpdateES3UniformBlocks(base::span<const int8_t> result);
// Updates the ES3 Uniformsiv info after a successful link.
void UpdateES3Uniformsiv(base::span<const int8_t> result);
// Updates the ES3 TransformFeedbackVaryings info after a successful link.
void UpdateES3TransformFeedbackVaryings(base::span<const 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) EXCLUSIVE_LOCKS_REQUIRED(lock_);
typedef std::unordered_map<GLuint, Program> ProgramInfoMap;
ProgramInfoMap program_infos_ GUARDED_BY(lock_);
mutable base::Lock lock_;
};
} // namespace gles2
} // namespace gpu
#endif // GPU_COMMAND_BUFFER_CLIENT_PROGRAM_INFO_MANAGER_H_