Make GL bindings conditional
[chromium-blink-merge.git] / gpu / command_buffer / service / shader_translator.cc
blob878490c3cb9d7e15da3f0f81b2960dbe78a13492
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"
19 namespace gpu {
20 namespace gles2 {
22 namespace {
24 class ShaderTranslatorInitializer {
25 public:
26 ShaderTranslatorInitializer() {
27 TRACE_EVENT0("gpu", "ShInitialize");
28 CHECK(ShInitialize());
31 ~ShaderTranslatorInitializer() {
32 TRACE_EVENT0("gpu", "ShFinalize");
33 ShFinalize();
37 base::LazyInstance<ShaderTranslatorInitializer> g_translator_initializer =
38 LAZY_INSTANCE_INITIALIZER;
40 void GetAttributes(ShHandle compiler, AttributeMap* var_map) {
41 if (!var_map)
42 return;
43 var_map->clear();
44 const std::vector<sh::Attribute>* attribs = ShGetAttributes(compiler);
45 if (attribs) {
46 for (size_t ii = 0; ii < attribs->size(); ++ii)
47 (*var_map)[(*attribs)[ii].mappedName] = (*attribs)[ii];
51 void GetUniforms(ShHandle compiler, UniformMap* var_map) {
52 if (!var_map)
53 return;
54 var_map->clear();
55 const std::vector<sh::Uniform>* uniforms = ShGetUniforms(compiler);
56 if (uniforms) {
57 for (size_t ii = 0; ii < uniforms->size(); ++ii)
58 (*var_map)[(*uniforms)[ii].mappedName] = (*uniforms)[ii];
62 void GetVaryings(ShHandle compiler, VaryingMap* var_map) {
63 if (!var_map)
64 return;
65 var_map->clear();
66 const std::vector<sh::Varying>* varyings = ShGetVaryings(compiler);
67 if (varyings) {
68 for (size_t ii = 0; ii < varyings->size(); ++ii)
69 (*var_map)[(*varyings)[ii].mappedName] = (*varyings)[ii];
73 void GetNameHashingInfo(ShHandle compiler, NameMap* name_map) {
74 if (!name_map)
75 return;
76 name_map->clear();
78 typedef std::map<std::string, std::string> NameMapANGLE;
79 const NameMapANGLE* angle_map = ShGetNameHashingMap(compiler);
80 DCHECK(angle_map);
82 for (NameMapANGLE::const_iterator iter = angle_map->begin();
83 iter != angle_map->end(); ++iter) {
84 // Note that in ANGLE, the map is (original_name, hash);
85 // here, we want (hash, original_name).
86 (*name_map)[iter->second] = iter->first;
90 } // namespace
92 ShaderTranslator::DestructionObserver::DestructionObserver() {
95 ShaderTranslator::DestructionObserver::~DestructionObserver() {
98 ShaderTranslator::ShaderTranslator()
99 : compiler_(NULL),
100 implementation_is_glsl_es_(false),
101 driver_bug_workarounds_(static_cast<ShCompileOptions>(0)) {
104 bool ShaderTranslator::Init(
105 GLenum shader_type,
106 ShShaderSpec shader_spec,
107 const ShBuiltInResources* resources,
108 ShaderTranslatorInterface::GlslImplementationType glsl_implementation_type,
109 ShCompileOptions driver_bug_workarounds) {
110 // Make sure Init is called only once.
111 DCHECK(compiler_ == NULL);
112 DCHECK(shader_type == GL_FRAGMENT_SHADER || shader_type == GL_VERTEX_SHADER);
113 DCHECK(shader_spec == SH_GLES2_SPEC || shader_spec == SH_WEBGL_SPEC);
114 DCHECK(resources != NULL);
116 g_translator_initializer.Get();
118 ShShaderOutput shader_output =
119 (glsl_implementation_type == kGlslES ? SH_ESSL_OUTPUT : SH_GLSL_OUTPUT);
122 TRACE_EVENT0("gpu", "ShConstructCompiler");
123 compiler_ = ShConstructCompiler(
124 shader_type, shader_spec, shader_output, resources);
126 compiler_options_ = *resources;
127 implementation_is_glsl_es_ = (glsl_implementation_type == kGlslES);
128 driver_bug_workarounds_ = driver_bug_workarounds;
129 return compiler_ != NULL;
132 int ShaderTranslator::GetCompileOptions() const {
133 int compile_options =
134 SH_OBJECT_CODE | SH_VARIABLES | SH_ENFORCE_PACKING_RESTRICTIONS |
135 SH_LIMIT_EXPRESSION_COMPLEXITY | SH_LIMIT_CALL_STACK_DEPTH |
136 SH_CLAMP_INDIRECT_ARRAY_BOUNDS;
138 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
139 switches::kGLShaderIntermOutput))
140 compile_options |= SH_INTERMEDIATE_TREE;
142 compile_options |= driver_bug_workarounds_;
144 return compile_options;
147 bool ShaderTranslator::Translate(const std::string& shader_source,
148 std::string* info_log,
149 std::string* translated_source,
150 AttributeMap* attrib_map,
151 UniformMap* uniform_map,
152 VaryingMap* varying_map,
153 NameMap* name_map) const {
154 // Make sure this instance is initialized.
155 DCHECK(compiler_ != NULL);
157 bool success = false;
159 TRACE_EVENT0("gpu", "ShCompile");
160 const char* const shader_strings[] = { shader_source.c_str() };
161 success = ShCompile(
162 compiler_, shader_strings, 1, GetCompileOptions());
164 if (success) {
165 // Get translated shader.
166 if (translated_source) {
167 *translated_source = ShGetObjectCode(compiler_);
169 // Get info for attribs, uniforms, and varyings.
170 GetAttributes(compiler_, attrib_map);
171 GetUniforms(compiler_, uniform_map);
172 GetVaryings(compiler_, varying_map);
173 // Get info for name hashing.
174 GetNameHashingInfo(compiler_, name_map);
177 // Get info log.
178 if (info_log) {
179 *info_log = ShGetInfoLog(compiler_);
182 return success;
185 std::string ShaderTranslator::GetStringForOptionsThatWouldAffectCompilation()
186 const {
187 DCHECK(compiler_ != NULL);
188 return std::string(":CompileOptions:" +
189 base::IntToString(GetCompileOptions())) +
190 ShGetBuiltInResourcesString(compiler_);
193 void ShaderTranslator::AddDestructionObserver(
194 DestructionObserver* observer) {
195 destruction_observers_.AddObserver(observer);
198 void ShaderTranslator::RemoveDestructionObserver(
199 DestructionObserver* observer) {
200 destruction_observers_.RemoveObserver(observer);
203 ShaderTranslator::~ShaderTranslator() {
204 FOR_EACH_OBSERVER(DestructionObserver,
205 destruction_observers_,
206 OnDestruct(this));
208 if (compiler_ != NULL)
209 ShDestruct(compiler_);
212 } // namespace gles2
213 } // namespace gpu