- add sources.
[platform/framework/web/crosswalk.git] / src / gpu / command_buffer / service / program_manager.h
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.
4
5 #ifndef GPU_COMMAND_BUFFER_SERVICE_PROGRAM_MANAGER_H_
6 #define GPU_COMMAND_BUFFER_SERVICE_PROGRAM_MANAGER_H_
7
8 #include <map>
9 #include <string>
10 #include <vector>
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"
19
20 namespace gpu {
21 namespace gles2 {
22
23 class FeatureInfo;
24 class ProgramCache;
25 class ProgramManager;
26 class Shader;
27 class ShaderManager;
28 class ShaderTranslator;
29
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> {
34  public:
35   static const int kMaxAttachedShaders = 2;
36
37   struct UniformInfo {
38     UniformInfo();
39     UniformInfo(
40         GLsizei _size, GLenum _type, GLint _fake_location_base,
41         const std::string& _name);
42     ~UniformInfo();
43
44     bool IsValid() const {
45       return size != 0;
46     }
47
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;
51     }
52
53     GLsizei size;
54     GLenum type;
55     GLint fake_location_base;
56     bool is_array;
57     std::string name;
58     std::vector<GLint> element_locations;
59     std::vector<GLuint> texture_units;
60   };
61   struct VertexAttrib {
62     VertexAttrib(GLsizei _size, GLenum _type, const std::string& _name,
63                      GLint _location)
64         : size(_size),
65           type(_type),
66           location(_location),
67           name(_name) {
68     }
69     GLsizei size;
70     GLenum type;
71     GLint location;
72     std::string name;
73   };
74
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;
79
80   Program(ProgramManager* manager, GLuint service_id);
81
82   GLuint service_id() const {
83     return service_id_;
84   }
85
86   const SamplerIndices& sampler_indices() {
87     return sampler_indices_;
88   }
89
90   const AttribInfoVector& GetAttribInfos() const {
91     return attrib_infos_;
92   }
93
94   const VertexAttrib* GetAttribInfo(GLint index) const {
95     return (static_cast<size_t>(index) < attrib_infos_.size()) ?
96        &attrib_infos_[index] : NULL;
97   }
98
99   GLint GetAttribLocation(const std::string& name) const;
100
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];
104       if (index >= 0) {
105         return &attrib_infos_[index];
106       }
107     }
108     return NULL;
109   }
110
111   const UniformInfo* GetUniformInfo(GLint index) const;
112
113   // If the original name is not found, return NULL.
114   const std::string* GetAttribMappedName(
115       const std::string& original_name) const;
116
117   // If the hashed name is not found, return NULL.
118   const std::string* GetOriginalNameFromHashedName(
119       const std::string& hashed_name) const;
120
121   // Gets the fake location of a uniform by name.
122   GLint GetUniformFakeLocation(const std::string& name) const;
123
124   // Gets the UniformInfo of a uniform by location.
125   const UniformInfo* GetUniformInfoByFakeLocation(
126       GLint fake_location, GLint* real_location, GLint* array_index) const;
127
128   // Gets all the program info.
129   void GetProgramInfo(
130       ProgramManager* manager, CommonDecoder::Bucket* bucket) const;
131
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.
137   bool SetSamplers(
138       GLint num_texture_units, GLint fake_location,
139       GLsizei count, const GLint* value);
140
141   bool IsDeleted() const {
142     return deleted_;
143   }
144
145   void GetProgramiv(GLenum pname, GLint* params);
146
147   bool IsValid() const {
148     return valid_;
149   }
150
151   bool AttachShader(ShaderManager* manager, Shader* shader);
152   bool DetachShader(ShaderManager* manager, Shader* shader);
153
154   bool CanLink() const;
155
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);
162
163   // Performs glValidateProgram and related activities.
164   void Validate();
165
166   const std::string* log_info() const {
167     return log_info_.get();
168   }
169
170   bool InUse() const {
171     DCHECK_GE(use_count_, 0);
172     return use_count_ != 0;
173   }
174
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;
178   }
179
180   // Sets uniform-location binding from a glBindUniformLocationCHROMIUM call.
181   // returns false if error.
182   bool SetUniformLocationBinding(const std::string& name, GLint location);
183
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;
188
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;
193
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;
197
198   // Return true if an uniform and an attribute share the same name.
199   bool DetectGlobalNameConflicts() const;
200
201   // Return false if varyings can't be packed into the max available
202   // varying registers.
203   bool CheckVaryingsPacking() const;
204
205   // Visible for testing
206   const LocationMap& bind_attrib_location_map() const {
207     return bind_attrib_location_map_;
208   }
209
210  private:
211   friend class base::RefCounted<Program>;
212   friend class ProgramManager;
213
214   ~Program();
215
216   void set_log_info(const char* str) {
217     log_info_.reset(str ? new std::string(str) : NULL);
218   }
219
220   void ClearLinkStatus() {
221     link_status_ = false;
222   }
223
224   void IncUseCount() {
225     ++use_count_;
226   }
227
228   void DecUseCount() {
229     --use_count_;
230     DCHECK_GE(use_count_, 0);
231   }
232
233   void MarkAsDeleted() {
234     DCHECK(!deleted_);
235     deleted_ =  true;
236   }
237
238   // Resets the program.
239   void Reset();
240
241   // Updates the program info after a successful link.
242   void Update();
243
244   // Process the program log, replacing the hashed names with original names.
245   std::string ProcessLogInfo(const std::string& log);
246
247   // Updates the program log info from GL
248   void UpdateLogInfo();
249
250   // Clears all the uniforms.
251   void ClearUniforms(std::vector<uint8>* zero_buffer);
252
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
256   // translated.
257   void ExecuteBindAttribLocationCalls();
258
259   bool AddUniformInfo(
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);
263
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;
267
268   void DetachShaders(ShaderManager* manager);
269
270   static inline GLint GetUniformInfoIndexFromFakeLocation(
271       GLint fake_location) {
272     return fake_location & 0xFFFF;
273   }
274
275   static inline GLint GetArrayElementIndexFromFakeLocation(
276       GLint fake_location) {
277     return (fake_location >> 16) & 0xFFFF;
278   }
279
280   ProgramManager* manager_;
281
282   int use_count_;
283
284   GLsizei max_attrib_name_length_;
285
286   // Attrib by index.
287   AttribInfoVector attrib_infos_;
288
289   // Attrib by location to index.
290   std::vector<GLint> attrib_location_to_index_map_;
291
292   GLsizei max_uniform_name_length_;
293
294   // Uniform info by index.
295   UniformInfoVector uniform_infos_;
296
297   // The indices of the uniforms that are samplers.
298   SamplerIndices sampler_indices_;
299
300   // The program this Program is tracking.
301   GLuint service_id_;
302
303   // Shaders by type of shader.
304   scoped_refptr<Shader>
305       attached_shaders_[kMaxAttachedShaders];
306
307   // True if this program is marked as deleted.
308   bool deleted_;
309
310   // This is true if glLinkProgram was successful at least once.
311   bool valid_;
312
313   // This is true if glLinkProgram was successful last time it was called.
314   bool link_status_;
315
316   // True if the uniforms have been cleared.
317   bool uniforms_cleared_;
318
319   // This is different than uniform_infos_.size() because
320   // that is a sparce array.
321   GLint num_uniforms_;
322
323   // Log info
324   scoped_ptr<std::string> log_info_;
325
326   // attribute-location binding map from glBindAttribLocation() calls.
327   LocationMap bind_attrib_location_map_;
328
329   // uniform-location binding map from glBindUniformLocationCHROMIUM() calls.
330   LocationMap bind_uniform_location_map_;
331 };
332
333 // Tracks the Programs.
334 //
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 {
338  public:
339   explicit ProgramManager(ProgramCache* program_cache,
340                           uint32 max_varying_vectors);
341   ~ProgramManager();
342
343   // Must call before destruction.
344   void Destroy(bool have_context);
345
346   // Creates a new program.
347   Program* CreateProgram(GLuint client_id, GLuint service_id);
348
349   // Gets a program.
350   Program* GetProgram(GLuint client_id);
351
352   // Gets a client id for a given service id.
353   bool GetClientId(GLuint service_id, GLuint* client_id) const;
354
355   // Gets the shader cache
356   ProgramCache* program_cache() const;
357
358   // Marks a program as deleted. If it is not used the program will be deleted.
359   void MarkAsDeleted(ShaderManager* shader_manager, Program* program);
360
361   // Marks a program as used.
362   void UseProgram(Program* program);
363
364   // Makes a program as unused. If deleted the program will be removed.
365   void UnuseProgram(ShaderManager* shader_manager, Program* program);
366
367   // Clears the uniforms for this program.
368   void ClearUniforms(Program* program);
369
370   // Returns true if prefix is invalid for gl.
371   static bool IsInvalidPrefix(const char* name, size_t length);
372
373   // Check if a Program is owned by this ProgramManager.
374   bool IsOwned(Program* program);
375
376   static int32 MakeFakeLocation(int32 index, int32 element);
377
378   void DoCompileShader(Shader* shader,
379                        ShaderTranslator* translator,
380                        FeatureInfo* feature_info);
381
382   uint32 max_varying_vectors() const {
383     return max_varying_vectors_;
384   }
385
386  private:
387   friend class Program;
388
389   void StartTracking(Program* program);
390   void StopTracking(Program* program);
391
392   void RemoveProgramInfoIfUnused(
393       ShaderManager* shader_manager, Program* program);
394
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_;
399
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_;
403
404   bool have_context_;
405
406   bool disable_workarounds_;
407
408   // Used to clear uniforms.
409   std::vector<uint8> zero_;
410
411   ProgramCache* program_cache_;
412
413   uint32 max_varying_vectors_;
414
415   DISALLOW_COPY_AND_ASSIGN(ProgramManager);
416 };
417
418 }  // namespace gles2
419 }  // namespace gpu
420
421 #endif  // GPU_COMMAND_BUFFER_SERVICE_PROGRAM_MANAGER_H_