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)#ifndef GPU_COMMAND_BUFFER_SERVICE_SHADER_TRANSLATOR_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GPU_COMMAND_BUFFER_SERVICE_SHADER_TRANSLATOR_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/containers/hash_tables.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/observer_list.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/gpu_export.h"
167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/angle_dx11/include/GLSLANG/ShaderLang.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gpu {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gles2 {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Translates a GLSL ES 2.0 shader to desktop GLSL shader, or just
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// validates GLSL ES 2.0 shaders on a true GLSL ES implementation.
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ShaderTranslatorInterface {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum GlslImplementationType {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kGlsl,
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kGlslES
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum GlslBuiltInFunctionBehavior {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kGlslBuiltInFunctionOriginal,
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kGlslBuiltInFunctionEmulated
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct VariableInfo {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VariableInfo()
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        : type(0),
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          size(0) {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VariableInfo(int _type, int _size, std::string _name)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        : type(_type),
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          size(_size),
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          name(_name) {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool operator==(
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const ShaderTranslatorInterface::VariableInfo& other) const {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return type == other.type &&
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          size == other.size &&
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          strcmp(name.c_str(), other.name.c_str()) == 0;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int type;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int size;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string name;  // name in the original shader source.
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Mapping between variable name and info.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef base::hash_map<std::string, VariableInfo> VariableMap;
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Mapping between hashed name and original name.
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef base::hash_map<std::string, std::string> NameMap;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initializes the translator.
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Must be called once before using the translator object.
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool Init(
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ShShaderType shader_type,
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ShShaderSpec shader_spec,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const ShBuiltInResources* resources,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GlslImplementationType glsl_implementation_type,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GlslBuiltInFunctionBehavior glsl_built_in_function_behavior) = 0;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Translates the given shader source.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if translation is successful, false otherwise.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool Translate(const char* shader) = 0;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The following functions return results from the last translation.
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The results are NULL/empty if the translation was unsuccessful.
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A valid info-log is always returned irrespective of whether translation
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // was successful or not.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual const char* translated_shader() const = 0;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual const char* info_log() const = 0;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual const VariableMap& attrib_map() const = 0;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual const VariableMap& uniform_map() const = 0;
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual const NameMap& name_map() const = 0;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Return a string that is unique for a specfic set of options that would
8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // possibly effect compilation.
8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual std::string GetStringForOptionsThatWouldEffectCompilation() const = 0;
9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ShaderTranslatorInterface() {}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Implementation of ShaderTranslatorInterface
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GPU_EXPORT ShaderTranslator
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public base::RefCounted<ShaderTranslator>,
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NON_EXPORTED_BASE(public ShaderTranslatorInterface) {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class DestructionObserver {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DestructionObserver();
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual ~DestructionObserver();
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnDestruct(ShaderTranslator* translator) = 0;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   private:
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DISALLOW_COPY_AND_ASSIGN(DestructionObserver);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ShaderTranslator();
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from ShaderTranslatorInterface.
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool Init(
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ShShaderType shader_type,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ShShaderSpec shader_spec,
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const ShBuiltInResources* resources,
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GlslImplementationType glsl_implementation_type,
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GlslBuiltInFunctionBehavior glsl_built_in_function_behavior) OVERRIDE;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from ShaderTranslatorInterface.
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool Translate(const char* shader) OVERRIDE;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from ShaderTranslatorInterface.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual const char* translated_shader() const OVERRIDE;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual const char* info_log() const OVERRIDE;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from ShaderTranslatorInterface.
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual const VariableMap& attrib_map() const OVERRIDE;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual const VariableMap& uniform_map() const OVERRIDE;
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual const NameMap& name_map() const OVERRIDE;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual std::string GetStringForOptionsThatWouldEffectCompilation() const
13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      OVERRIDE;
13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddDestructionObserver(DestructionObserver* observer);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RemoveDestructionObserver(DestructionObserver* observer);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class base::RefCounted<ShaderTranslator>;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ShaderTranslator();
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ClearResults();
14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int GetCompileOptions() const;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ShHandle compiler_;
14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ShBuiltInResources compiler_options_;
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<char[]> translated_shader_;
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<char[]> info_log_;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VariableMap attrib_map_;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VariableMap uniform_map_;
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NameMap name_map_;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool implementation_is_glsl_es_;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool needs_built_in_function_emulation_;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ObserverList<DestructionObserver> destruction_observers_;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ShaderTranslator);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gles2
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gpu
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // GPU_COMMAND_BUFFER_SERVICE_SHADER_TRANSLATOR_H_
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165