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

#include "gpu/command_buffer/service/program_cache.h"

#include <stddef.h>

#include <memory>
#include <string>

#include "base/metrics/histogram_macros.h"
#include "gpu/command_buffer/service/shader_manager.h"
#include "third_party/angle/src/common/angle_version_info.h"

namespace gpu {
namespace gles2 {

ProgramCache::ScopedCacheUse::ScopedCacheUse(ProgramCache* cache,
                                             CacheProgramCallback callback)
    : cache_(cache) {
  base::AutoLock auto_lock(cache_->lock_);
  // The existing callback should be null, otherwise we'll overwrite it.
  DCHECK(!cache_->cache_program_callback_);
  cache_->cache_program_callback_ = std::move(callback);
}

ProgramCache::ScopedCacheUse::~ScopedCacheUse() {
  base::AutoLock auto_lock(cache_->lock_);
  // The callback should be the one installed by the constructor. The DCHECK
  // doesn't exactly check that, but checking for non-null is a cheap second.
  DCHECK(cache_->cache_program_callback_);
  cache_->cache_program_callback_.Reset();
}

ProgramCache::ProgramCache(size_t max_cache_size_bytes)
    : max_size_bytes_(max_cache_size_bytes) {}
ProgramCache::~ProgramCache() = default;

void ProgramCache::Clear() {
  ClearBackend();
  link_status_.clear();
  compiled_shaders_.clear();
}

bool ProgramCache::HasSuccessfullyCompiledShader(
    const std::string& shader_signature) const {
  char sha[kHashLength];
  ComputeShaderHash(shader_signature, sha);
  const std::string sha_string(sha, kHashLength);

  if (compiled_shaders_.find(sha_string) != compiled_shaders_.end()) {
    return true;
  }
  return false;
}

ProgramCache::LinkedProgramStatus ProgramCache::GetLinkedProgramStatus(
    const std::string& shader_signature_a,
    const std::string& shader_signature_b,
    const std::map<std::string, GLint>* bind_attrib_location_map,
    const std::vector<std::string>& transform_feedback_varyings,
    GLenum transform_feedback_buffer_mode) const {
  char a_sha[kHashLength];
  char b_sha[kHashLength];
  ComputeShaderHash(shader_signature_a, a_sha);
  ComputeShaderHash(shader_signature_b, b_sha);

  char sha[kHashLength];
  ComputeProgramHash(a_sha,
                     b_sha,
                     bind_attrib_location_map,
                     transform_feedback_varyings,
                     transform_feedback_buffer_mode,
                     sha);
  const std::string sha_string(sha, kHashLength);

  LinkStatusMap::const_iterator found = link_status_.find(sha_string);
  if (found == link_status_.end()) {
    return ProgramCache::LINK_UNKNOWN;
  } else {
    return found->second;
  }
}

void ProgramCache::LinkedProgramCacheSuccess(
    const std::string& shader_signature_a,
    const std::string& shader_signature_b,
    const LocationMap* bind_attrib_location_map,
    const std::vector<std::string>& transform_feedback_varyings,
    GLenum transform_feedback_buffer_mode) {
  char a_sha[kHashLength];
  char b_sha[kHashLength];
  ComputeShaderHash(shader_signature_a, a_sha);
  ComputeShaderHash(shader_signature_b, b_sha);
  char sha[kHashLength];
  ComputeProgramHash(a_sha,
                     b_sha,
                     bind_attrib_location_map,
                     transform_feedback_varyings,
                     transform_feedback_buffer_mode,
                     sha);
  const std::string a_sha_string(a_sha, kHashLength);
  const std::string b_sha_string(b_sha, kHashLength);
  const std::string sha_string(sha, kHashLength);

  CompiledShaderCacheSuccess(a_sha_string);
  CompiledShaderCacheSuccess(b_sha_string);
  LinkedProgramCacheSuccess(sha_string);
}

void ProgramCache::LinkedProgramCacheSuccess(const std::string& program_hash) {
  link_status_[program_hash] = LINK_SUCCEEDED;
}

void ProgramCache::CompiledShaderCacheSuccess(const std::string& shader_hash) {
  compiled_shaders_.insert(shader_hash);
}

void ProgramCache::ComputeShaderHash(
    const std::string& str,
    char* result) const {
  base::SHA1HashBytes(reinterpret_cast<const unsigned char*>(str.c_str()),
                      str.length(), reinterpret_cast<unsigned char*>(result));
}

void ProgramCache::Evict(const std::string& program_hash,
                         const std::string& shader_0_hash,
                         const std::string& shader_1_hash) {
  link_status_.erase(program_hash);
  compiled_shaders_.erase(shader_0_hash);
  compiled_shaders_.erase(shader_1_hash);
}

namespace {
size_t CalculateMapSize(const std::map<std::string, GLint>* map) {
  if (!map) {
    return 0;
  }
  size_t total = 0;
  for (auto it = map->begin(); it != map->end(); ++it) {
    total += 4 + it->first.length();
  }
  return total;
}

size_t CalculateVaryingsSize(const std::vector<std::string>& varyings) {
  size_t total = 0;
  for (auto& varying : varyings) {
    total += 1 + varying.length();
  }
  return total;
}
}  // anonymous namespace

void ProgramCache::ComputeProgramHash(
    const char* hashed_shader_0,
    const char* hashed_shader_1,
    const std::map<std::string, GLint>* bind_attrib_location_map,
    const std::vector<std::string>& transform_feedback_varyings,
    GLenum transform_feedback_buffer_mode,
    char* result) const {
  const size_t shader0_size = kHashLength;
  const size_t shader1_size = kHashLength;
  const size_t angle_commit_size = angle::GetANGLECommitHashSize();
  const size_t map_size = CalculateMapSize(bind_attrib_location_map);
  const size_t var_size = CalculateVaryingsSize(transform_feedback_varyings);
  const size_t total_size = shader0_size + shader1_size + angle_commit_size
      + map_size + var_size + sizeof(transform_feedback_buffer_mode);

  std::unique_ptr<unsigned char[]> buffer(new unsigned char[total_size]);
  memcpy(buffer.get(), hashed_shader_0, shader0_size);
  memcpy(&buffer[shader0_size], hashed_shader_1, shader1_size);
  size_t current_pos = shader0_size + shader1_size;
  memcpy(&buffer[current_pos], angle::GetANGLECommitHash(), angle_commit_size);
  current_pos += angle_commit_size;
  if (map_size != 0) {
    // copy our map
    for (auto it = bind_attrib_location_map->begin();
         it != bind_attrib_location_map->end();
         ++it) {
      const size_t name_size = it->first.length();
      memcpy(&buffer.get()[current_pos], it->first.c_str(), name_size);
      current_pos += name_size;
      const GLint value = it->second;
      buffer[current_pos++] = value >> 24;
      buffer[current_pos++] = static_cast<unsigned char>(value >> 16);
      buffer[current_pos++] = static_cast<unsigned char>(value >> 8);
      buffer[current_pos++] = static_cast<unsigned char>(value);
    }
  }

  if (var_size != 0) {
    // copy transform feedback varyings
    for (auto& varying : transform_feedback_varyings) {
      const size_t name_size = varying.length();
      memcpy(&buffer.get()[current_pos], varying.c_str(), name_size);
      current_pos += name_size;
      buffer[current_pos++] = ' ';
    }
  }
  memcpy(&buffer[current_pos], &transform_feedback_buffer_mode,
      sizeof(transform_feedback_buffer_mode));
  base::SHA1HashBytes(buffer.get(),
                      total_size, reinterpret_cast<unsigned char*>(result));
}

void ProgramCache::HandleMemoryPressure(
    base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) {
  if (memory_pressure_level ==
      base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE) {
    return;
  }

  // Set a low limit on cache size for MEMORY_PRESSURE_LEVEL_MODERATE.
  size_t limit = max_size_bytes_ / 4;
  if (memory_pressure_level ==
      base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL) {
    limit = 0;
  }

  Trim(limit);
}

}  // namespace gles2
}  // namespace gpu
