Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / gpu / command_buffer / service / shader_translator.cc
blob04e12276afb372a6707355e912ab5ae04a24ae3a
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 #include "gpu/command_buffer/service/shader_translator.h"
7 #include <string.h>
8 #include <GLES2/gl2.h>
9 #include <algorithm>
11 #include "base/at_exit.h"
12 #include "base/command_line.h"
13 #include "base/lazy_instance.h"
14 #include "base/logging.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "base/trace_event/trace_event.h"
17 #include "gpu/command_buffer/service/gpu_switches.h"
18 #include "ui/gl/gl_implementation.h"
20 namespace gpu {
21 namespace gles2 {
23 namespace {
25 class ShaderTranslatorInitializer {
26 public:
27 ShaderTranslatorInitializer() {
28 TRACE_EVENT0("gpu", "ShInitialize");
29 CHECK(ShInitialize());
32 ~ShaderTranslatorInitializer() {
33 TRACE_EVENT0("gpu", "ShFinalize");
34 ShFinalize();
38 base::LazyInstance<ShaderTranslatorInitializer> g_translator_initializer =
39 LAZY_INSTANCE_INITIALIZER;
41 void GetAttributes(ShHandle compiler, AttributeMap* var_map) {
42 if (!var_map)
43 return;
44 var_map->clear();
45 const std::vector<sh::Attribute>* attribs = ShGetAttributes(compiler);
46 if (attribs) {
47 for (size_t ii = 0; ii < attribs->size(); ++ii)
48 (*var_map)[(*attribs)[ii].mappedName] = (*attribs)[ii];
52 void GetUniforms(ShHandle compiler, UniformMap* var_map) {
53 if (!var_map)
54 return;
55 var_map->clear();
56 const std::vector<sh::Uniform>* uniforms = ShGetUniforms(compiler);
57 if (uniforms) {
58 for (size_t ii = 0; ii < uniforms->size(); ++ii)
59 (*var_map)[(*uniforms)[ii].mappedName] = (*uniforms)[ii];
63 void GetVaryings(ShHandle compiler, VaryingMap* var_map) {
64 if (!var_map)
65 return;
66 var_map->clear();
67 const std::vector<sh::Varying>* varyings = ShGetVaryings(compiler);
68 if (varyings) {
69 for (size_t ii = 0; ii < varyings->size(); ++ii)
70 (*var_map)[(*varyings)[ii].mappedName] = (*varyings)[ii];
74 void GetNameHashingInfo(ShHandle compiler, NameMap* name_map) {
75 if (!name_map)
76 return;
77 name_map->clear();
79 typedef std::map<std::string, std::string> NameMapANGLE;
80 const NameMapANGLE* angle_map = ShGetNameHashingMap(compiler);
81 DCHECK(angle_map);
83 for (NameMapANGLE::const_iterator iter = angle_map->begin();
84 iter != angle_map->end(); ++iter) {
85 // Note that in ANGLE, the map is (original_name, hash);
86 // here, we want (hash, original_name).
87 (*name_map)[iter->second] = iter->first;
91 } // namespace
93 ShaderTranslator::DestructionObserver::DestructionObserver() {
96 ShaderTranslator::DestructionObserver::~DestructionObserver() {
99 ShaderTranslator::ShaderTranslator()
100 : compiler_(NULL),
101 implementation_is_glsl_es_(false),
102 driver_bug_workarounds_(static_cast<ShCompileOptions>(0)) {
105 bool ShaderTranslator::Init(
106 GLenum shader_type,
107 ShShaderSpec shader_spec,
108 const ShBuiltInResources* resources,
109 ShaderTranslatorInterface::GlslImplementationType glsl_implementation_type,
110 ShCompileOptions driver_bug_workarounds) {
111 // Make sure Init is called only once.
112 DCHECK(compiler_ == NULL);
113 DCHECK(shader_type == GL_FRAGMENT_SHADER || shader_type == GL_VERTEX_SHADER);
114 DCHECK(shader_spec == SH_GLES2_SPEC || shader_spec == SH_WEBGL_SPEC ||
115 shader_spec == SH_GLES3_SPEC || shader_spec == SH_WEBGL2_SPEC);
116 DCHECK(resources != NULL);
118 g_translator_initializer.Get();
120 ShShaderOutput shader_output;
121 if (glsl_implementation_type == kGlslES) {
122 shader_output = SH_ESSL_OUTPUT;
123 } else {
124 // TODO(kbr): clean up the tests of shader_spec and
125 // gfx::GetGLImplementation(). crbug.com/471960
126 if (shader_spec == SH_WEBGL2_SPEC ||
127 gfx::GetGLImplementation() ==
128 gfx::kGLImplementationDesktopGLCoreProfile) {
129 shader_output = SH_GLSL_410_CORE_OUTPUT;
130 } else {
131 shader_output = SH_GLSL_COMPATIBILITY_OUTPUT;
136 TRACE_EVENT0("gpu", "ShConstructCompiler");
137 compiler_ = ShConstructCompiler(
138 shader_type, shader_spec, shader_output, resources);
140 implementation_is_glsl_es_ = (glsl_implementation_type == kGlslES);
141 driver_bug_workarounds_ = driver_bug_workarounds;
142 return compiler_ != NULL;
145 int ShaderTranslator::GetCompileOptions() const {
146 int compile_options =
147 SH_OBJECT_CODE | SH_VARIABLES | SH_ENFORCE_PACKING_RESTRICTIONS |
148 SH_LIMIT_EXPRESSION_COMPLEXITY | SH_LIMIT_CALL_STACK_DEPTH |
149 SH_CLAMP_INDIRECT_ARRAY_BOUNDS;
151 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
152 switches::kGLShaderIntermOutput))
153 compile_options |= SH_INTERMEDIATE_TREE;
155 compile_options |= driver_bug_workarounds_;
157 return compile_options;
160 bool ShaderTranslator::Translate(const std::string& shader_source,
161 std::string* info_log,
162 std::string* translated_source,
163 int* shader_version,
164 AttributeMap* attrib_map,
165 UniformMap* uniform_map,
166 VaryingMap* varying_map,
167 NameMap* name_map) const {
168 // Make sure this instance is initialized.
169 DCHECK(compiler_ != NULL);
171 bool success = false;
173 TRACE_EVENT0("gpu", "ShCompile");
174 const char* const shader_strings[] = { shader_source.c_str() };
175 success = ShCompile(
176 compiler_, shader_strings, 1, GetCompileOptions());
178 if (success) {
179 // Get translated shader.
180 if (translated_source) {
181 *translated_source = ShGetObjectCode(compiler_);
183 // Get shader version.
184 *shader_version = ShGetShaderVersion(compiler_);
185 // Get info for attribs, uniforms, and varyings.
186 GetAttributes(compiler_, attrib_map);
187 GetUniforms(compiler_, uniform_map);
188 GetVaryings(compiler_, varying_map);
189 // Get info for name hashing.
190 GetNameHashingInfo(compiler_, name_map);
193 // Get info log.
194 if (info_log) {
195 *info_log = ShGetInfoLog(compiler_);
198 // We don't need results in the compiler anymore.
199 ShClearResults(compiler_);
201 return success;
204 std::string ShaderTranslator::GetStringForOptionsThatWouldAffectCompilation()
205 const {
206 DCHECK(compiler_ != NULL);
207 return std::string(":CompileOptions:" +
208 base::IntToString(GetCompileOptions())) +
209 ShGetBuiltInResourcesString(compiler_);
212 void ShaderTranslator::AddDestructionObserver(
213 DestructionObserver* observer) {
214 destruction_observers_.AddObserver(observer);
217 void ShaderTranslator::RemoveDestructionObserver(
218 DestructionObserver* observer) {
219 destruction_observers_.RemoveObserver(observer);
222 ShaderTranslator::~ShaderTranslator() {
223 FOR_EACH_OBSERVER(DestructionObserver,
224 destruction_observers_,
225 OnDestruct(this));
227 if (compiler_ != NULL)
228 ShDestruct(compiler_);
231 } // namespace gles2
232 } // namespace gpu