1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef GPU_COMMAND_BUFFER_SERVICE_PROGRAM_MANAGER_H_
6 #define GPU_COMMAND_BUFFER_SERVICE_PROGRAM_MANAGER_H_
11 #include "base/basictypes.h"
12 #include "base/logging.h"
13 #include "base/memory/ref_counted.h"
14 #include "gpu/command_buffer/service/common_decoder.h"
15 #include "gpu/command_buffer/service/gl_utils.h"
16 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
17 #include "gpu/command_buffer/service/shader_manager.h"
18 #include "gpu/gpu_export.h"
28 class ShaderTranslator;
30 // This is used to track which attributes a particular program needs
31 // so we can verify at glDrawXXX time that every attribute is either disabled
32 // or if enabled that it points to a valid source.
33 class GPU_EXPORT Program : public base::RefCounted<Program> {
35 static const int kMaxAttachedShaders = 2;
40 GLsizei _size, GLenum _type, GLint _fake_location_base,
41 const std::string& _name);
44 bool IsValid() const {
48 bool IsSampler() const {
49 return type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
50 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES;
55 GLint fake_location_base;
58 std::vector<GLint> element_locations;
59 std::vector<GLuint> texture_units;
62 VertexAttrib(GLsizei _size, GLenum _type, const std::string& _name,
75 typedef std::vector<UniformInfo> UniformInfoVector;
76 typedef std::vector<VertexAttrib> AttribInfoVector;
77 typedef std::vector<int> SamplerIndices;
78 typedef std::map<std::string, GLint> LocationMap;
80 Program(ProgramManager* manager, GLuint service_id);
82 GLuint service_id() const {
86 const SamplerIndices& sampler_indices() {
87 return sampler_indices_;
90 const AttribInfoVector& GetAttribInfos() const {
94 const VertexAttrib* GetAttribInfo(GLint index) const {
95 return (static_cast<size_t>(index) < attrib_infos_.size()) ?
96 &attrib_infos_[index] : NULL;
99 GLint GetAttribLocation(const std::string& name) const;
101 const VertexAttrib* GetAttribInfoByLocation(GLuint location) const {
102 if (location < attrib_location_to_index_map_.size()) {
103 GLint index = attrib_location_to_index_map_[location];
105 return &attrib_infos_[index];
111 const UniformInfo* GetUniformInfo(GLint index) const;
113 // If the original name is not found, return NULL.
114 const std::string* GetAttribMappedName(
115 const std::string& original_name) const;
117 // If the hashed name is not found, return NULL.
118 const std::string* GetOriginalNameFromHashedName(
119 const std::string& hashed_name) const;
121 // Gets the fake location of a uniform by name.
122 GLint GetUniformFakeLocation(const std::string& name) const;
124 // Gets the UniformInfo of a uniform by location.
125 const UniformInfo* GetUniformInfoByFakeLocation(
126 GLint fake_location, GLint* real_location, GLint* array_index) const;
128 // Gets all the program info.
130 ProgramManager* manager, CommonDecoder::Bucket* bucket) const;
132 // Sets the sampler values for a uniform.
133 // This is safe to call for any location. If the location is not
134 // a sampler uniform nothing will happen.
135 // Returns false if fake_location is a sampler and any value
136 // is >= num_texture_units. Returns true otherwise.
138 GLint num_texture_units, GLint fake_location,
139 GLsizei count, const GLint* value);
141 bool IsDeleted() const {
145 void GetProgramiv(GLenum pname, GLint* params);
147 bool IsValid() const {
151 bool AttachShader(ShaderManager* manager, Shader* shader);
152 bool DetachShader(ShaderManager* manager, Shader* shader);
154 bool CanLink() const;
156 // Performs glLinkProgram and related activities.
157 bool Link(ShaderManager* manager,
158 ShaderTranslator* vertex_translator,
159 ShaderTranslator* fragment_shader,
160 FeatureInfo* feature_info,
161 const ShaderCacheCallback& shader_callback);
163 // Performs glValidateProgram and related activities.
166 const std::string* log_info() const {
167 return log_info_.get();
171 DCHECK_GE(use_count_, 0);
172 return use_count_ != 0;
175 // Sets attribute-location binding from a glBindAttribLocation() call.
176 void SetAttribLocationBinding(const std::string& attrib, GLint location) {
177 bind_attrib_location_map_[attrib] = location;
180 // Sets uniform-location binding from a glBindUniformLocationCHROMIUM call.
181 // returns false if error.
182 bool SetUniformLocationBinding(const std::string& name, GLint location);
184 // Detects if there are attribute location conflicts from
185 // glBindAttribLocation() calls.
186 // We only consider the declared attributes in the program.
187 bool DetectAttribLocationBindingConflicts() const;
189 // Detects if there are uniforms of the same name but different type
190 // or precision in vertex/fragment shaders.
191 // Return true if such cases are detected.
192 bool DetectUniformsMismatch() const;
194 // Return true if a varying is statically used in fragment shader, but it
195 // is not declared in vertex shader.
196 bool DetectVaryingsMismatch() const;
198 // Return true if an uniform and an attribute share the same name.
199 bool DetectGlobalNameConflicts() const;
201 // Return false if varyings can't be packed into the max available
202 // varying registers.
203 bool CheckVaryingsPacking() const;
205 // Visible for testing
206 const LocationMap& bind_attrib_location_map() const {
207 return bind_attrib_location_map_;
211 friend class base::RefCounted<Program>;
212 friend class ProgramManager;
216 void set_log_info(const char* str) {
217 log_info_.reset(str ? new std::string(str) : NULL);
220 void ClearLinkStatus() {
221 link_status_ = false;
230 DCHECK_GE(use_count_, 0);
233 void MarkAsDeleted() {
238 // Resets the program.
241 // Updates the program info after a successful link.
244 // Process the program log, replacing the hashed names with original names.
245 std::string ProcessLogInfo(const std::string& log);
247 // Updates the program log info from GL
248 void UpdateLogInfo();
250 // Clears all the uniforms.
251 void ClearUniforms(std::vector<uint8>* zero_buffer);
253 // If long attribate names are mapped during shader translation, call
254 // glBindAttribLocation() again with the mapped names.
255 // This is called right before the glLink() call, but after shaders are
257 void ExecuteBindAttribLocationCalls();
260 GLsizei size, GLenum type, GLint location, GLint fake_base_location,
261 const std::string& name, const std::string& original_name,
262 size_t* next_available_index);
264 void GetCorrectedVariableInfo(
265 bool use_uniforms, const std::string& name, std::string* corrected_name,
266 std::string* original_name, GLsizei* size, GLenum* type) const;
268 void DetachShaders(ShaderManager* manager);
270 static inline GLint GetUniformInfoIndexFromFakeLocation(
271 GLint fake_location) {
272 return fake_location & 0xFFFF;
275 static inline GLint GetArrayElementIndexFromFakeLocation(
276 GLint fake_location) {
277 return (fake_location >> 16) & 0xFFFF;
280 ProgramManager* manager_;
284 GLsizei max_attrib_name_length_;
287 AttribInfoVector attrib_infos_;
289 // Attrib by location to index.
290 std::vector<GLint> attrib_location_to_index_map_;
292 GLsizei max_uniform_name_length_;
294 // Uniform info by index.
295 UniformInfoVector uniform_infos_;
297 // The indices of the uniforms that are samplers.
298 SamplerIndices sampler_indices_;
300 // The program this Program is tracking.
303 // Shaders by type of shader.
304 scoped_refptr<Shader>
305 attached_shaders_[kMaxAttachedShaders];
307 // True if this program is marked as deleted.
310 // This is true if glLinkProgram was successful at least once.
313 // This is true if glLinkProgram was successful last time it was called.
316 // True if the uniforms have been cleared.
317 bool uniforms_cleared_;
319 // This is different than uniform_infos_.size() because
320 // that is a sparce array.
324 scoped_ptr<std::string> log_info_;
326 // attribute-location binding map from glBindAttribLocation() calls.
327 LocationMap bind_attrib_location_map_;
329 // uniform-location binding map from glBindUniformLocationCHROMIUM() calls.
330 LocationMap bind_uniform_location_map_;
333 // Tracks the Programs.
335 // NOTE: To support shared resources an instance of this class will
336 // need to be shared by multiple GLES2Decoders.
337 class GPU_EXPORT ProgramManager {
339 explicit ProgramManager(ProgramCache* program_cache,
340 uint32 max_varying_vectors);
343 // Must call before destruction.
344 void Destroy(bool have_context);
346 // Creates a new program.
347 Program* CreateProgram(GLuint client_id, GLuint service_id);
350 Program* GetProgram(GLuint client_id);
352 // Gets a client id for a given service id.
353 bool GetClientId(GLuint service_id, GLuint* client_id) const;
355 // Gets the shader cache
356 ProgramCache* program_cache() const;
358 // Marks a program as deleted. If it is not used the program will be deleted.
359 void MarkAsDeleted(ShaderManager* shader_manager, Program* program);
361 // Marks a program as used.
362 void UseProgram(Program* program);
364 // Makes a program as unused. If deleted the program will be removed.
365 void UnuseProgram(ShaderManager* shader_manager, Program* program);
367 // Clears the uniforms for this program.
368 void ClearUniforms(Program* program);
370 // Returns true if prefix is invalid for gl.
371 static bool IsInvalidPrefix(const char* name, size_t length);
373 // Check if a Program is owned by this ProgramManager.
374 bool IsOwned(Program* program);
376 static int32 MakeFakeLocation(int32 index, int32 element);
378 void DoCompileShader(Shader* shader,
379 ShaderTranslator* translator,
380 FeatureInfo* feature_info);
382 uint32 max_varying_vectors() const {
383 return max_varying_vectors_;
387 friend class Program;
389 void StartTracking(Program* program);
390 void StopTracking(Program* program);
392 void RemoveProgramInfoIfUnused(
393 ShaderManager* shader_manager, Program* program);
395 // Info for each "successfully linked" program by service side program Id.
396 // TODO(gman): Choose a faster container.
397 typedef std::map<GLuint, scoped_refptr<Program> > ProgramMap;
398 ProgramMap programs_;
400 // Counts the number of Program allocated with 'this' as its manager.
401 // Allows to check no Program will outlive this.
402 unsigned int program_count_;
406 bool disable_workarounds_;
408 // Used to clear uniforms.
409 std::vector<uint8> zero_;
411 ProgramCache* program_cache_;
413 uint32 max_varying_vectors_;
415 DISALLOW_COPY_AND_ASSIGN(ProgramManager);
421 #endif // GPU_COMMAND_BUFFER_SERVICE_PROGRAM_MANAGER_H_