OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "gpu/command_buffer/service/shader_translator.h" | 5 #include "gpu/command_buffer/service/shader_translator.h" |
6 | 6 |
7 #include <string.h> | 7 #include <string.h> |
8 #include <GLES2/gl2.h> | 8 #include <GLES2/gl2.h> |
9 #include <algorithm> | 9 #include <algorithm> |
10 | 10 |
11 #include "base/at_exit.h" | 11 #include "base/at_exit.h" |
12 #include "base/debug/trace_event.h" | 12 #include "base/debug/trace_event.h" |
13 #include "base/lazy_instance.h" | 13 #include "base/lazy_instance.h" |
14 #include "base/logging.h" | 14 #include "base/logging.h" |
15 #include "base/strings/string_number_conversions.h" | 15 #include "base/strings/string_number_conversions.h" |
16 | 16 |
| 17 namespace gpu { |
| 18 namespace gles2 { |
| 19 |
17 namespace { | 20 namespace { |
18 | 21 |
19 using gpu::gles2::ShaderTranslator; | |
20 | |
21 class ShaderTranslatorInitializer { | 22 class ShaderTranslatorInitializer { |
22 public: | 23 public: |
23 ShaderTranslatorInitializer() { | 24 ShaderTranslatorInitializer() { |
24 TRACE_EVENT0("gpu", "ShInitialize"); | 25 TRACE_EVENT0("gpu", "ShInitialize"); |
25 CHECK(ShInitialize()); | 26 CHECK(ShInitialize()); |
26 } | 27 } |
27 | 28 |
28 ~ShaderTranslatorInitializer() { | 29 ~ShaderTranslatorInitializer() { |
29 TRACE_EVENT0("gpu", "ShFinalize"); | 30 TRACE_EVENT0("gpu", "ShFinalize"); |
30 ShFinalize(); | 31 ShFinalize(); |
31 } | 32 } |
32 }; | 33 }; |
33 | 34 |
34 base::LazyInstance<ShaderTranslatorInitializer> g_translator_initializer = | 35 base::LazyInstance<ShaderTranslatorInitializer> g_translator_initializer = |
35 LAZY_INSTANCE_INITIALIZER; | 36 LAZY_INSTANCE_INITIALIZER; |
36 | 37 |
37 void GetVariableInfo(ShHandle compiler, ShShaderInfo var_type, | 38 void GetAttributes(ShHandle compiler, AttributeMap* var_map) { |
38 ShaderTranslator::VariableMap* var_map) { | |
39 if (!var_map) | 39 if (!var_map) |
40 return; | 40 return; |
41 var_map->clear(); | 41 var_map->clear(); |
42 | 42 const std::vector<sh::Attribute>* attribs = ShGetAttributes(compiler); |
43 size_t name_len = 0, mapped_name_len = 0; | 43 if (attribs) { |
44 switch (var_type) { | 44 for (size_t ii = 0; ii < attribs->size(); ++ii) |
45 case SH_ACTIVE_ATTRIBUTES: | 45 (*var_map)[(*attribs)[ii].mappedName] = (*attribs)[ii]; |
46 ShGetInfo(compiler, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, &name_len); | |
47 break; | |
48 case SH_ACTIVE_UNIFORMS: | |
49 ShGetInfo(compiler, SH_ACTIVE_UNIFORM_MAX_LENGTH, &name_len); | |
50 break; | |
51 case SH_VARYINGS: | |
52 ShGetInfo(compiler, SH_VARYING_MAX_LENGTH, &name_len); | |
53 break; | |
54 default: NOTREACHED(); | |
55 } | |
56 ShGetInfo(compiler, SH_MAPPED_NAME_MAX_LENGTH, &mapped_name_len); | |
57 if (name_len <= 1 || mapped_name_len <= 1) return; | |
58 scoped_ptr<char[]> name(new char[name_len]); | |
59 scoped_ptr<char[]> mapped_name(new char[mapped_name_len]); | |
60 | |
61 size_t num_vars = 0; | |
62 ShGetInfo(compiler, var_type, &num_vars); | |
63 for (size_t i = 0; i < num_vars; ++i) { | |
64 size_t len = 0; | |
65 int size = 0; | |
66 sh::GLenum type = GL_NONE; | |
67 ShPrecisionType precision = SH_PRECISION_UNDEFINED; | |
68 int static_use = 0; | |
69 | |
70 ShGetVariableInfo(compiler, var_type, i, | |
71 &len, &size, &type, &precision, &static_use, | |
72 name.get(), mapped_name.get()); | |
73 | |
74 // In theory we should CHECK(len <= name_len - 1) here, but ANGLE needs | |
75 // to handle long struct field name mapping before we can do this. | |
76 // Also, we should modify the ANGLE interface to also return a length | |
77 // for mapped_name. | |
78 std::string name_string(name.get(), std::min(len, name_len - 1)); | |
79 mapped_name.get()[mapped_name_len - 1] = '\0'; | |
80 | |
81 ShaderTranslator::VariableInfo info( | |
82 type, size, precision, static_use, name_string); | |
83 (*var_map)[mapped_name.get()] = info; | |
84 } | 46 } |
85 } | 47 } |
86 | 48 |
87 void GetNameHashingInfo( | 49 void GetUniforms(ShHandle compiler, UniformMap* var_map) { |
88 ShHandle compiler, ShaderTranslator::NameMap* name_map) { | 50 if (!var_map) |
| 51 return; |
| 52 var_map->clear(); |
| 53 const std::vector<sh::Uniform>* uniforms = ShGetUniforms(compiler); |
| 54 if (uniforms) { |
| 55 for (size_t ii = 0; ii < uniforms->size(); ++ii) |
| 56 (*var_map)[(*uniforms)[ii].mappedName] = (*uniforms)[ii]; |
| 57 } |
| 58 } |
| 59 |
| 60 void GetVaryings(ShHandle compiler, VaryingMap* var_map) { |
| 61 if (!var_map) |
| 62 return; |
| 63 var_map->clear(); |
| 64 const std::vector<sh::Varying>* varyings = ShGetVaryings(compiler); |
| 65 if (varyings) { |
| 66 for (size_t ii = 0; ii < varyings->size(); ++ii) |
| 67 (*var_map)[(*varyings)[ii].mappedName] = (*varyings)[ii]; |
| 68 } |
| 69 } |
| 70 |
| 71 void GetNameHashingInfo(ShHandle compiler, NameMap* name_map) { |
89 if (!name_map) | 72 if (!name_map) |
90 return; | 73 return; |
91 name_map->clear(); | 74 name_map->clear(); |
92 | 75 |
93 size_t hashed_names_count = 0; | 76 size_t hashed_names_count = 0; |
94 ShGetInfo(compiler, SH_HASHED_NAMES_COUNT, &hashed_names_count); | 77 ShGetInfo(compiler, SH_HASHED_NAMES_COUNT, &hashed_names_count); |
95 if (hashed_names_count == 0) | 78 if (hashed_names_count == 0) |
96 return; | 79 return; |
97 | 80 |
98 size_t name_max_len = 0, hashed_name_max_len = 0; | 81 size_t name_max_len = 0, hashed_name_max_len = 0; |
99 ShGetInfo(compiler, SH_NAME_MAX_LENGTH, &name_max_len); | 82 ShGetInfo(compiler, SH_NAME_MAX_LENGTH, &name_max_len); |
100 ShGetInfo(compiler, SH_HASHED_NAME_MAX_LENGTH, &hashed_name_max_len); | 83 ShGetInfo(compiler, SH_HASHED_NAME_MAX_LENGTH, &hashed_name_max_len); |
101 | 84 |
102 scoped_ptr<char[]> name(new char[name_max_len]); | 85 scoped_ptr<char[]> name(new char[name_max_len]); |
103 scoped_ptr<char[]> hashed_name(new char[hashed_name_max_len]); | 86 scoped_ptr<char[]> hashed_name(new char[hashed_name_max_len]); |
104 | 87 |
105 for (size_t i = 0; i < hashed_names_count; ++i) { | 88 for (size_t i = 0; i < hashed_names_count; ++i) { |
106 ShGetNameHashingEntry(compiler, i, name.get(), hashed_name.get()); | 89 ShGetNameHashingEntry(compiler, i, name.get(), hashed_name.get()); |
107 (*name_map)[hashed_name.get()] = name.get(); | 90 (*name_map)[hashed_name.get()] = name.get(); |
108 } | 91 } |
109 } | 92 } |
110 | 93 |
111 } // namespace | 94 } // namespace |
112 | 95 |
113 namespace gpu { | |
114 namespace gles2 { | |
115 | |
116 ShaderTranslator::DestructionObserver::DestructionObserver() { | 96 ShaderTranslator::DestructionObserver::DestructionObserver() { |
117 } | 97 } |
118 | 98 |
119 ShaderTranslator::DestructionObserver::~DestructionObserver() { | 99 ShaderTranslator::DestructionObserver::~DestructionObserver() { |
120 } | 100 } |
121 | 101 |
122 ShaderTranslator::ShaderTranslator() | 102 ShaderTranslator::ShaderTranslator() |
123 : compiler_(NULL), | 103 : compiler_(NULL), |
124 implementation_is_glsl_es_(false), | 104 implementation_is_glsl_es_(false), |
125 driver_bug_workarounds_(static_cast<ShCompileOptions>(0)) { | 105 driver_bug_workarounds_(static_cast<ShCompileOptions>(0)) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 SH_CLAMP_INDIRECT_ARRAY_BOUNDS; | 140 SH_CLAMP_INDIRECT_ARRAY_BOUNDS; |
161 | 141 |
162 compile_options |= driver_bug_workarounds_; | 142 compile_options |= driver_bug_workarounds_; |
163 | 143 |
164 return compile_options; | 144 return compile_options; |
165 } | 145 } |
166 | 146 |
167 bool ShaderTranslator::Translate(const std::string& shader_source, | 147 bool ShaderTranslator::Translate(const std::string& shader_source, |
168 std::string* info_log, | 148 std::string* info_log, |
169 std::string* translated_source, | 149 std::string* translated_source, |
170 VariableMap* attrib_map, | 150 AttributeMap* attrib_map, |
171 VariableMap* uniform_map, | 151 UniformMap* uniform_map, |
172 VariableMap* varying_map, | 152 VaryingMap* varying_map, |
173 NameMap* name_map) const { | 153 NameMap* name_map) const { |
174 // Make sure this instance is initialized. | 154 // Make sure this instance is initialized. |
175 DCHECK(compiler_ != NULL); | 155 DCHECK(compiler_ != NULL); |
176 | 156 |
177 bool success = false; | 157 bool success = false; |
178 { | 158 { |
179 TRACE_EVENT0("gpu", "ShCompile"); | 159 TRACE_EVENT0("gpu", "ShCompile"); |
180 const char* const shader_strings[] = { shader_source.c_str() }; | 160 const char* const shader_strings[] = { shader_source.c_str() }; |
181 success = !!ShCompile( | 161 success = !!ShCompile( |
182 compiler_, shader_strings, 1, GetCompileOptions()); | 162 compiler_, shader_strings, 1, GetCompileOptions()); |
183 } | 163 } |
184 if (success) { | 164 if (success) { |
185 if (translated_source) { | 165 if (translated_source) { |
186 translated_source->clear(); | 166 translated_source->clear(); |
187 // Get translated shader. | 167 // Get translated shader. |
188 size_t obj_code_len = 0; | 168 size_t obj_code_len = 0; |
189 ShGetInfo(compiler_, SH_OBJECT_CODE_LENGTH, &obj_code_len); | 169 ShGetInfo(compiler_, SH_OBJECT_CODE_LENGTH, &obj_code_len); |
190 if (obj_code_len > 1) { | 170 if (obj_code_len > 1) { |
191 scoped_ptr<char[]> buffer(new char[obj_code_len]); | 171 scoped_ptr<char[]> buffer(new char[obj_code_len]); |
192 ShGetObjectCode(compiler_, buffer.get()); | 172 ShGetObjectCode(compiler_, buffer.get()); |
193 *translated_source = std::string(buffer.get(), obj_code_len - 1); | 173 *translated_source = std::string(buffer.get(), obj_code_len - 1); |
194 } | 174 } |
195 } | 175 } |
196 // Get info for attribs, uniforms, and varyings. | 176 // Get info for attribs, uniforms, and varyings. |
197 GetVariableInfo(compiler_, SH_ACTIVE_ATTRIBUTES, attrib_map); | 177 GetAttributes(compiler_, attrib_map); |
198 GetVariableInfo(compiler_, SH_ACTIVE_UNIFORMS, uniform_map); | 178 GetUniforms(compiler_, uniform_map); |
199 GetVariableInfo(compiler_, SH_VARYINGS, varying_map); | 179 GetVaryings(compiler_, varying_map); |
200 // Get info for name hashing. | 180 // Get info for name hashing. |
201 GetNameHashingInfo(compiler_, name_map); | 181 GetNameHashingInfo(compiler_, name_map); |
202 } | 182 } |
203 | 183 |
204 // Get info log. | 184 // Get info log. |
205 if (info_log) { | 185 if (info_log) { |
206 info_log->clear(); | 186 info_log->clear(); |
207 size_t info_log_len = 0; | 187 size_t info_log_len = 0; |
208 ShGetInfo(compiler_, SH_INFO_LOG_LENGTH, &info_log_len); | 188 ShGetInfo(compiler_, SH_INFO_LOG_LENGTH, &info_log_len); |
209 if (info_log_len > 1) { | 189 if (info_log_len > 1) { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 destruction_observers_, | 227 destruction_observers_, |
248 OnDestruct(this)); | 228 OnDestruct(this)); |
249 | 229 |
250 if (compiler_ != NULL) | 230 if (compiler_ != NULL) |
251 ShDestruct(compiler_); | 231 ShDestruct(compiler_); |
252 } | 232 } |
253 | 233 |
254 } // namespace gles2 | 234 } // namespace gles2 |
255 } // namespace gpu | 235 } // namespace gpu |
256 | 236 |
OLD | NEW |