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
|
// 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_;
}
void 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() { }
// 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_
|