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>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/at_exit.h"
1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/debug/trace_event.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using gpu::gles2::ShaderTranslator;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FinalizeShaderTranslator(void* /* dummy */) {
2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TRACE_EVENT0("gpu", "ShFinalize");
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ShFinalize();
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InitializeShaderTranslator() {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool initialized = false;
2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!initialized) {
2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    TRACE_EVENT0("gpu", "ShInitialize");
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    CHECK(ShInitialize());
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AtExitManager::RegisterCallback(&FinalizeShaderTranslator, NULL);
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    initialized = true;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return initialized;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(ANGLE_SH_VERSION) || ANGLE_SH_VERSION < 108
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef int ANGLEGetInfoType;
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef size_t ANGLEGetInfoType;
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetVariableInfo(ShHandle compiler, ShShaderInfo var_type,
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     ShaderTranslator::VariableMap* var_map) {
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ANGLEGetInfoType 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)
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ANGLEGetInfoType num_vars = 0;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ShGetInfo(compiler, var_type, &num_vars);
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (ANGLEGetInfoType i = 0; i < num_vars; ++i) {
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ANGLEGetInfoType len = 0;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int size = 0;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ShDataType type = SH_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) {
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ANGLEGetInfoType hashed_names_count = 0;
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShGetInfo(compiler, SH_HASHED_NAMES_COUNT, &hashed_names_count);
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (hashed_names_count == 0)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ANGLEGetInfoType name_max_len = 0, hashed_name_max_len = 0;
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShGetInfo(compiler, SH_NAME_MAX_LENGTH, &name_max_len);
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShGetInfo(compiler, SH_HASHED_NAME_MAX_LENGTH, &hashed_name_max_len);
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<char[]> name(new char[name_max_len]);
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<char[]> hashed_name(new char[hashed_name_max_len]);
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (ANGLEGetInfoType i = 0; i < hashed_names_count; ++i) {
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ShGetNameHashingEntry(compiler, i, name.get(), hashed_name.get());
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    (*name_map)[hashed_name.get()] = name.get();
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gpu {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gles2 {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ShaderTranslator::DestructionObserver::DestructionObserver() {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ShaderTranslator::DestructionObserver::~DestructionObserver() {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ShaderTranslator::ShaderTranslator()
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : compiler_(NULL),
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      implementation_is_glsl_es_(false),
12158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      driver_bug_workarounds_(static_cast<ShCompileOptions>(0)) {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ShaderTranslator::Init(
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ShShaderType shader_type,
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ShShaderSpec shader_spec,
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ShBuiltInResources* resources,
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ShaderTranslatorInterface::GlslImplementationType glsl_implementation_type,
12958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ShCompileOptions driver_bug_workarounds) {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure Init is called only once.
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(compiler_ == NULL);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(shader_type == SH_FRAGMENT_SHADER || shader_type == SH_VERTEX_SHADER);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(shader_spec == SH_GLES2_SPEC || shader_spec == SH_WEBGL_SPEC);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(resources != NULL);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!InitializeShaderTranslator())
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ShShaderOutput shader_output =
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (glsl_implementation_type == kGlslES ? SH_ESSL_OUTPUT : SH_GLSL_OUTPUT);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  {
14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    TRACE_EVENT0("gpu", "ShConstructCompiler");
14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    compiler_ = ShConstructCompiler(
14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        shader_type, shader_spec, shader_output, resources);
14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  compiler_options_ = *resources;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  implementation_is_glsl_es_ = (glsl_implementation_type == kGlslES);
14958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  driver_bug_workarounds_ = driver_bug_workarounds;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return compiler_ != NULL;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int ShaderTranslator::GetCompileOptions() const {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int compile_options =
1553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      SH_OBJECT_CODE | SH_VARIABLES |
15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      SH_MAP_LONG_VARIABLE_NAMES | SH_ENFORCE_PACKING_RESTRICTIONS |
15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      SH_LIMIT_EXPRESSION_COMPLEXITY | SH_LIMIT_CALL_STACK_DEPTH;
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  compile_options |= SH_CLAMP_INDIRECT_ARRAY_BOUNDS;
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  compile_options |= driver_bug_workarounds_;
16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return compile_options;
16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
16690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool ShaderTranslator::Translate(const char* shader) {
16790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Make sure this instance is initialized.
16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(compiler_ != NULL);
16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(shader != NULL);
17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ClearResults();
17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool success = false;
17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  {
17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    TRACE_EVENT0("gpu", "ShCompile");
17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    success = !!ShCompile(compiler_, &shader, 1, GetCompileOptions());
17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (success) {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Get translated shader.
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ANGLEGetInfoType obj_code_len = 0;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ShGetInfo(compiler_, SH_OBJECT_CODE_LENGTH, &obj_code_len);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (obj_code_len > 1) {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      translated_shader_.reset(new char[obj_code_len]);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ShGetObjectCode(compiler_, translated_shader_.get());
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Get info for attribs and uniforms.
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetVariableInfo(compiler_, SH_ACTIVE_ATTRIBUTES, &attrib_map_);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetVariableInfo(compiler_, SH_ACTIVE_UNIFORMS, &uniform_map_);
1883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    GetVariableInfo(compiler_, SH_VARYINGS, &varying_map_);
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Get info for name hashing.
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GetNameHashingInfo(compiler_, &name_map_);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get info log.
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ANGLEGetInfoType info_log_len = 0;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ShGetInfo(compiler_, SH_INFO_LOG_LENGTH, &info_log_len);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (info_log_len > 1) {
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info_log_.reset(new char[info_log_len]);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ShGetInfoLog(compiler_, info_log_.get());
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info_log_.reset();
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return success;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::string ShaderTranslator::GetStringForOptionsThatWouldEffectCompilation()
20790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const {
208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const size_t kNumIntFields = 16;
20990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const size_t kNumEnumFields = 1;
21090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const size_t kNumFunctionPointerFields = 1;
21190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  struct MustMatchShBuiltInResource {
21290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    typedef khronos_uint64_t (*FunctionPointer)(const char*, size_t);
21390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    enum Enum {
21490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      kFirst,
21590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    };
21690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    int int_fields[kNumIntFields];
21790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    FunctionPointer pointer_fields[kNumFunctionPointerFields];
21890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    Enum enum_fields[kNumEnumFields];
21990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  };
22090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // If this assert fails most likely that means something below needs updating.
22190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  COMPILE_ASSERT(
22290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      sizeof(ShBuiltInResources) == sizeof(MustMatchShBuiltInResource),
22390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      Fields_Have_Changed_In_ShBuiltInResource_So_Update_Below);
22490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
22590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return std::string(
22690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ":CompileOptions:" +
22790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::IntToString(GetCompileOptions()) +
22890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ":MaxVertexAttribs:" +
22990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::IntToString(compiler_options_.MaxVertexAttribs) +
23090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ":MaxVertexUniformVectors:" +
23190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::IntToString(compiler_options_.MaxVertexUniformVectors) +
23290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ":MaxVaryingVectors:" +
23390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::IntToString(compiler_options_.MaxVaryingVectors) +
23490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ":MaxVertexTextureImageUnits:" +
23590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::IntToString(compiler_options_.MaxVertexTextureImageUnits) +
23690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ":MaxCombinedTextureImageUnits:" +
23790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::IntToString(compiler_options_.MaxCombinedTextureImageUnits) +
23890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ":MaxTextureImageUnits:" +
23990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::IntToString(compiler_options_.MaxTextureImageUnits) +
24090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ":MaxFragmentUniformVectors:" +
24190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::IntToString(compiler_options_.MaxFragmentUniformVectors) +
24290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ":MaxDrawBuffers:" +
24390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::IntToString(compiler_options_.MaxDrawBuffers) +
24490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ":OES_standard_derivatives:" +
24590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::IntToString(compiler_options_.OES_standard_derivatives) +
24690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ":OES_EGL_image_external:" +
24790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::IntToString(compiler_options_.OES_EGL_image_external) +
24890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ":ARB_texture_rectangle:" +
24990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::IntToString(compiler_options_.ARB_texture_rectangle) +
25090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ":EXT_draw_buffers:" +
25190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::IntToString(compiler_options_.EXT_draw_buffers) +
25290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ":FragmentPrecisionHigh:" +
25390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::IntToString(compiler_options_.FragmentPrecisionHigh) +
25490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ":MaxExpressionComplexity:" +
25590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::IntToString(compiler_options_.MaxExpressionComplexity) +
25690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ":MaxCallStackDepth:" +
257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::IntToString(compiler_options_.MaxCallStackDepth) +
258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ":EXT_frag_depth:" +
259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::IntToString(compiler_options_.EXT_frag_depth));
26090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
26190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* ShaderTranslator::translated_shader() const {
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return translated_shader_.get();
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* ShaderTranslator::info_log() const {
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return info_log_.get();
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ShaderTranslatorInterface::VariableMap&
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ShaderTranslator::attrib_map() const {
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return attrib_map_;
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ShaderTranslatorInterface::VariableMap&
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ShaderTranslator::uniform_map() const {
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return uniform_map_;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const ShaderTranslatorInterface::VariableMap&
2813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)ShaderTranslator::varying_map() const {
2823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return varying_map_;
2833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const ShaderTranslatorInterface::NameMap&
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShaderTranslator::name_map() const {
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return name_map_;
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShaderTranslator::AddDestructionObserver(
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DestructionObserver* observer) {
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  destruction_observers_.AddObserver(observer);
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShaderTranslator::RemoveDestructionObserver(
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DestructionObserver* observer) {
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  destruction_observers_.RemoveObserver(observer);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ShaderTranslator::~ShaderTranslator() {
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(DestructionObserver,
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    destruction_observers_,
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnDestruct(this));
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (compiler_ != NULL)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ShDestruct(compiler_);
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShaderTranslator::ClearResults() {
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  translated_shader_.reset();
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info_log_.reset();
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  attrib_map_.clear();
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uniform_map_.clear();
3143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  varying_map_.clear();
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  name_map_.clear();
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gles2
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gpu
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
321