// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef GPU_COMMAND_BUFFER_SERVICE_SHADER_MANAGER_H_
#define GPU_COMMAND_BUFFER_SERVICE_SHADER_MANAGER_H_

#include <string>
#include "base/basictypes.h"
#include "base/containers/hash_tables.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "gpu/command_buffer/service/gl_utils.h"
#include "gpu/command_buffer/service/shader_translator.h"
#include "gpu/gpu_export.h"

namespace gpu {
namespace gles2 {

// This is used to keep the source code for a shader. This is because in order
// to emluate GLES2 the shaders will have to be re-written before passed to
// the underlying OpenGL. But, when the user calls glGetShaderSource they
// should get the source they passed in, not the re-written source.
class GPU_EXPORT Shader : public base::RefCounted<Shader> {
 public:
  enum TranslatedShaderSourceType {
    kANGLE,
    kGL,  // GL or GLES
  };

  typedef ShaderTranslator::VariableInfo VariableInfo;

  void DoCompile(ShaderTranslatorInterface* translator,
                 TranslatedShaderSourceType type);

  GLuint service_id() const {
    return service_id_;
  }

  GLenum shader_type() const {
    return shader_type_;
  }

  const std::string& source() const {
    return source_;
  }

  void set_source(const std::string& source) {
    source_ = source;
  }

  const std::string& translated_source() const {
    return translated_source_;
  }

  const std::string& signature_source() const {
    return signature_source_;
  }

  const VariableInfo* GetAttribInfo(const std::string& name) const;
  const VariableInfo* GetUniformInfo(const std::string& name) const;
  const VariableInfo* GetVaryingInfo(const std::string& name) const;

  // If the original_name is not found, return NULL.
  const std::string* GetAttribMappedName(
      const std::string& original_name) const;

  // If the hashed_name is not found, return NULL.
  const std::string* GetOriginalNameFromHashedName(
      const std::string& hashed_name) const;

  const std::string& log_info() const {
    return log_info_;
  }

  bool valid() const {
    return valid_;
  }

  bool IsDeleted() const {
    return service_id_ == 0;
  }

  bool InUse() const {
    DCHECK_GE(use_count_, 0);
    return use_count_ != 0;
  }

  // Used by program cache.
  const ShaderTranslator::VariableMap& attrib_map() const {
    return attrib_map_;
  }

  // Used by program cache.
  const ShaderTranslator::VariableMap& uniform_map() const {
    return uniform_map_;
  }

  // Used by program cache.
  const ShaderTranslator::VariableMap& varying_map() const {
    return varying_map_;
  }

  // Used by program cache.
  void set_attrib_map(const ShaderTranslator::VariableMap& attrib_map) {
    // copied because cache might be cleared
    attrib_map_ = ShaderTranslator::VariableMap(attrib_map);
  }

  // Used by program cache.
  void set_uniform_map(const ShaderTranslator::VariableMap& uniform_map) {
    // copied because cache might be cleared
    uniform_map_ = ShaderTranslator::VariableMap(uniform_map);
  }

  // Used by program cache.
  void set_varying_map(const ShaderTranslator::VariableMap& varying_map) {
    // copied because cache might be cleared
    varying_map_ = ShaderTranslator::VariableMap(varying_map);
  }

 private:
  typedef ShaderTranslator::VariableMap VariableMap;
  typedef ShaderTranslator::NameMap NameMap;

  friend class base::RefCounted<Shader>;
  friend class ShaderManager;

  Shader(GLuint service_id, GLenum shader_type);
  ~Shader();

  void IncUseCount();
  void DecUseCount();
  void MarkAsDeleted();

  int use_count_;

  // The shader this Shader is tracking.
  GLuint service_id_;
  // Type of shader - GL_VERTEX_SHADER or GL_FRAGMENT_SHADER.
  GLenum shader_type_;

  // True if compilation succeeded.
  bool valid_;

  // The shader source as passed to glShaderSource.
  std::string source_;

  // The source the last compile used.
  std::string signature_source_;

  // The translated shader source.
  std::string translated_source_;

  // The shader translation log.
  std::string log_info_;

  // The type info when the shader was last compiled.
  VariableMap attrib_map_;
  VariableMap uniform_map_;
  VariableMap varying_map_;

  // The name hashing info when the shader was last compiled.
  NameMap name_map_;
};

// Tracks the Shaders.
//
// NOTE: To support shared resources an instance of this class will
// need to be shared by multiple GLES2Decoders.
class GPU_EXPORT ShaderManager {
 public:
  ShaderManager();
  ~ShaderManager();

  // Must call before destruction.
  void Destroy(bool have_context);

  // Creates a shader for the given shader ID.
  Shader* CreateShader(
      GLuint client_id,
      GLuint service_id,
      GLenum shader_type);

  // Gets an existing shader info for the given shader ID. Returns NULL if none
  // exists.
  Shader* GetShader(GLuint client_id);

  // Gets a client id for a given service id.
  bool GetClientId(GLuint service_id, GLuint* client_id) const;

  void MarkAsDeleted(Shader* shader);

  // Mark a shader as used
  void UseShader(Shader* shader);

  // Unmark a shader as used. If it has been deleted and is not used
  // then we free the shader.
  void UnuseShader(Shader* shader);

  // Check if a Shader is owned by this ShaderManager.
  bool IsOwned(Shader* shader);

 private:
  friend class Shader;

  // Info for each shader by service side shader Id.
  typedef base::hash_map<GLuint, scoped_refptr<Shader> > ShaderMap;
  ShaderMap shaders_;

  void RemoveShader(Shader* shader);

  DISALLOW_COPY_AND_ASSIGN(ShaderManager);
};

}  // namespace gles2
}  // namespace gpu

#endif  // GPU_COMMAND_BUFFER_SERVICE_SHADER_MANAGER_H_

