15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/shader_translator.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h>
8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include <GLES2/gl2.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/at_exit.h"
1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/debug/trace_event.h"
13c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "base/lazy_instance.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using gpu::gles2::ShaderTranslator;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochclass ShaderTranslatorInitializer {
22c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch public:
23c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ShaderTranslatorInitializer() {
2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    TRACE_EVENT0("gpu", "ShInitialize");
2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    CHECK(ShInitialize());
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
27c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
28c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ~ShaderTranslatorInitializer() {
29c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    TRACE_EVENT0("gpu", "ShFinalize");
30c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    ShFinalize();
31c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
32c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch};
33c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
34c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochbase::LazyInstance<ShaderTranslatorInitializer> g_translator_initializer =
35c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    LAZY_INSTANCE_INITIALIZER;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetVariableInfo(ShHandle compiler, ShShaderInfo var_type,
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     ShaderTranslator::VariableMap* var_map) {
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!var_map)
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  var_map->clear();
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  size_t name_len = 0, mapped_name_len = 0;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (var_type) {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SH_ACTIVE_ATTRIBUTES:
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ShGetInfo(compiler, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, &name_len);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SH_ACTIVE_UNIFORMS:
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ShGetInfo(compiler, SH_ACTIVE_UNIFORM_MAX_LENGTH, &name_len);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case SH_VARYINGS:
523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      ShGetInfo(compiler, SH_VARYING_MAX_LENGTH, &name_len);
533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      break;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default: NOTREACHED();
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ShGetInfo(compiler, SH_MAPPED_NAME_MAX_LENGTH, &mapped_name_len);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (name_len <= 1 || mapped_name_len <= 1) return;
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<char[]> name(new char[name_len]);
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<char[]> mapped_name(new char[mapped_name_len]);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  size_t num_vars = 0;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ShGetInfo(compiler, var_type, &num_vars);
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = 0; i < num_vars; ++i) {
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    size_t len = 0;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int size = 0;
66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    sh::GLenum type = GL_NONE;
67424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    ShPrecisionType precision = SH_PRECISION_UNDEFINED;
68424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    int static_use = 0;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ShGetVariableInfo(compiler, var_type, i,
71424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                      &len, &size, &type, &precision, &static_use,
723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                      name.get(), mapped_name.get());
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // In theory we should CHECK(len <= name_len - 1) here, but ANGLE needs
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // to handle long struct field name mapping before we can do this.
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Also, we should modify the ANGLE interface to also return a length
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // for mapped_name.
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string name_string(name.get(), std::min(len, name_len - 1));
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mapped_name.get()[mapped_name_len - 1] = '\0';
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    ShaderTranslator::VariableInfo info(
82424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        type, size, precision, static_use, name_string);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*var_map)[mapped_name.get()] = info;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GetNameHashingInfo(
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ShHandle compiler, ShaderTranslator::NameMap* name_map) {
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!name_map)
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  name_map->clear();
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  size_t hashed_names_count = 0;
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShGetInfo(compiler, SH_HASHED_NAMES_COUNT, &hashed_names_count);
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (hashed_names_count == 0)
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  size_t name_max_len = 0, hashed_name_max_len = 0;
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShGetInfo(compiler, SH_NAME_MAX_LENGTH, &name_max_len);
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShGetInfo(compiler, SH_HASHED_NAME_MAX_LENGTH, &hashed_name_max_len);
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<char[]> name(new char[name_max_len]);
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<char[]> hashed_name(new char[hashed_name_max_len]);
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = 0; i < hashed_names_count; ++i) {
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ShGetNameHashingEntry(compiler, i, name.get(), hashed_name.get());
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    (*name_map)[hashed_name.get()] = name.get();
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gpu {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gles2 {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ShaderTranslator::DestructionObserver::DestructionObserver() {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ShaderTranslator::DestructionObserver::~DestructionObserver() {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ShaderTranslator::ShaderTranslator()
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : compiler_(NULL),
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      implementation_is_glsl_es_(false),
12558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      driver_bug_workarounds_(static_cast<ShCompileOptions>(0)) {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ShaderTranslator::Init(
129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    GLenum shader_type,
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ShShaderSpec shader_spec,
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ShBuiltInResources* resources,
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ShaderTranslatorInterface::GlslImplementationType glsl_implementation_type,
13358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ShCompileOptions driver_bug_workarounds) {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure Init is called only once.
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(compiler_ == NULL);
136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(shader_type == GL_FRAGMENT_SHADER || shader_type == GL_VERTEX_SHADER);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(shader_spec == SH_GLES2_SPEC || shader_spec == SH_WEBGL_SPEC);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(resources != NULL);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
140c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  g_translator_initializer.Get();
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ShShaderOutput shader_output =
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (glsl_implementation_type == kGlslES ? SH_ESSL_OUTPUT : SH_GLSL_OUTPUT);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  {
14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    TRACE_EVENT0("gpu", "ShConstructCompiler");
14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    compiler_ = ShConstructCompiler(
14890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        shader_type, shader_spec, shader_output, resources);
14990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  compiler_options_ = *resources;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  implementation_is_glsl_es_ = (glsl_implementation_type == kGlslES);
15258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  driver_bug_workarounds_ = driver_bug_workarounds;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return compiler_ != NULL;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int ShaderTranslator::GetCompileOptions() const {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int compile_options =
158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      SH_OBJECT_CODE | SH_VARIABLES | SH_ENFORCE_PACKING_RESTRICTIONS |
159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      SH_LIMIT_EXPRESSION_COMPLEXITY | SH_LIMIT_CALL_STACK_DEPTH |
160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      SH_CLAMP_INDIRECT_ARRAY_BOUNDS;
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  compile_options |= driver_bug_workarounds_;
16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return compile_options;
16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
16690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool ShaderTranslator::Translate(const std::string& shader_source,
1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 std::string* info_log,
1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 std::string* translated_source,
1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 VariableMap* attrib_map,
1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 VariableMap* uniform_map,
1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 VariableMap* varying_map,
1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 NameMap* name_map) const {
17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Make sure this instance is initialized.
17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(compiler_ != NULL);
17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool success = false;
17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  {
17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    TRACE_EVENT0("gpu", "ShCompile");
1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const char* const shader_strings[] = { shader_source.c_str() };
1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    success = !!ShCompile(
1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        compiler_, shader_strings, 1, GetCompileOptions());
18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (success) {
1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (translated_source) {
1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      translated_source->clear();
1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // Get translated shader.
1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      size_t obj_code_len = 0;
1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ShGetInfo(compiler_, SH_OBJECT_CODE_LENGTH, &obj_code_len);
1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (obj_code_len > 1) {
1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        scoped_ptr<char[]> buffer(new char[obj_code_len]);
1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        ShGetObjectCode(compiler_, buffer.get());
1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        *translated_source = std::string(buffer.get(), obj_code_len - 1);
1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      }
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Get info for attribs, uniforms, and varyings.
1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    GetVariableInfo(compiler_, SH_ACTIVE_ATTRIBUTES, attrib_map);
1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    GetVariableInfo(compiler_, SH_ACTIVE_UNIFORMS, uniform_map);
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    GetVariableInfo(compiler_, SH_VARYINGS, varying_map);
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Get info for name hashing.
2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    GetNameHashingInfo(compiler_, name_map);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get info log.
2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (info_log) {
2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    info_log->clear();
2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    size_t info_log_len = 0;
2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ShGetInfo(compiler_, SH_INFO_LOG_LENGTH, &info_log_len);
2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (info_log_len > 1) {
2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      scoped_ptr<char[]> buffer(new char[info_log_len]);
2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ShGetInfoLog(compiler_, buffer.get());
2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      *info_log = std::string(buffer.get(), info_log_len - 1);
2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return success;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)std::string ShaderTranslator::GetStringForOptionsThatWouldAffectCompilation()
22090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const {
221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(compiler_ != NULL);
222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  size_t resource_len = 0;
224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ShGetInfo(compiler_, SH_RESOURCES_STRING_LENGTH, &resource_len);
225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(resource_len > 1);
226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<char[]> resource_str(new char[resource_len]);
227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ShGetBuiltInResourcesString(compiler_, resource_len, resource_str.get());
229e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return std::string(":CompileOptions:" +
231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)         base::IntToString(GetCompileOptions())) +
232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)         std::string(resource_str.get());
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShaderTranslator::AddDestructionObserver(
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DestructionObserver* observer) {
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  destruction_observers_.AddObserver(observer);
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShaderTranslator::RemoveDestructionObserver(
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DestructionObserver* observer) {
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  destruction_observers_.RemoveObserver(observer);
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ShaderTranslator::~ShaderTranslator() {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(DestructionObserver,
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    destruction_observers_,
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnDestruct(this));
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (compiler_ != NULL)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ShDestruct(compiler_);
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gles2
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gpu
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
257