// Copyright 2017 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/passthrough_program_cache.h"

#include <stddef.h>

#include <algorithm>
#include <cmath>
#include <string_view>
#include <utility>

#include "base/base64.h"
#include "base/compiler_specific.h"
#include "base/feature_list.h"
#include "base/memory_coordinator/memory_coordinator_features.h"
#include "base/memory_coordinator/utils.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_view_util.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_display.h"
#include "ui/gl/gl_surface_egl.h"

namespace gpu {
namespace gles2 {

namespace {

bool BlobCacheExtensionAvailable(gl::GLDisplayEGL* gl_display) {
  // The display should be initialized if the extension is available.
  return gl_display->ext->b_EGL_ANDROID_blob_cache;
}

// EGL_ANDROID_blob_cache doesn't give user pointer to the callbacks so we are
// forced to have this be global.
PassthroughProgramCache* g_program_cache = nullptr;

// Blob cache function pointers can only be set once per EGLDisplay. Using a
// single bool is not technically correct, but it's acceptable since we only
// have one EGLDisplay in practice.
bool g_blob_cache_funcs_set = false;

}  // namespace

PassthroughProgramCache::PassthroughProgramCache(
    size_t max_cache_size_bytes,
    bool disable_gpu_shader_disk_cache)
    : ProgramCache(max_cache_size_bytes),
      disable_gpu_shader_disk_cache_(disable_gpu_shader_disk_cache),
      curr_size_bytes_(0),
      store_(ProgramLRUCache::NO_AUTO_EVICT),
      memory_consumer_registration_(
          "PassthroughProgramCache",
          std::nullopt,  // TODO(crbug.com/489671163): Add traits.
          this,
          base::AsyncMemoryConsumerRegistration::CheckUnregister::kDisabled,
          base::AsyncMemoryConsumerRegistration::CheckRegistryExists::
              kDisabled),
      current_max_size_bytes_(max_cache_size_bytes) {
  gl::GLDisplayEGL* gl_display = gl::GLSurfaceEGL::GetGLDisplayEGL();
  EGLDisplay egl_display = gl_display->GetDisplay();

  DCHECK(!g_program_cache);
  g_program_cache = this;

  // display is EGL_NO_DISPLAY during unittests.
  if (egl_display != EGL_NO_DISPLAY && !g_blob_cache_funcs_set &&
      BlobCacheExtensionAvailable(gl_display)) {
    // Register the blob cache callbacks.
    eglSetBlobCacheFuncsANDROID(egl_display, BlobCacheSet, BlobCacheGet);
    g_blob_cache_funcs_set = true;
  }
}

PassthroughProgramCache::~PassthroughProgramCache() {
  // Clear up the blob cache callbacks.  Note that this not allowed by the
  // EGL_ANDROID_blob_cache spec, so we just set the pointer to this object to
  // nullptr as a workaround.  The callbacks don't work with this pointer
  // missing.
  g_program_cache = nullptr;
}

void PassthroughProgramCache::ClearBackend() {
  base::AutoLock auto_lock(lock_);
  store_.Clear();
  DCHECK_EQ(0U, curr_size_bytes_);
}

ProgramCache::ProgramLoadResult PassthroughProgramCache::LoadLinkedProgram(
    GLuint program,
    Shader* shader_a,
    Shader* shader_b,
    const LocationMap* bind_attrib_location_map,
    const std::vector<std::string>& transform_feedback_varyings,
    GLenum transform_feedback_buffer_mode,
    DecoderClient* client) {
  NOTREACHED();
}

void PassthroughProgramCache::SaveLinkedProgram(
    GLuint program,
    const Shader* shader_a,
    const Shader* shader_b,
    const LocationMap* bind_attrib_location_map,
    const std::vector<std::string>& transform_feedback_varyings,
    GLenum transform_feedback_buffer_mode,
    DecoderClient* client) {
  NOTREACHED();
}

void PassthroughProgramCache::LoadProgram(const std::string& key,
                                          const std::string& program) {
  base::AutoLock auto_lock(lock_);
  if (!CacheEnabled()) {
    return;
  }

  std::string key_decoded;
  std::string program_decoded;
  base::Base64Decode(key, &key_decoded);
  base::Base64Decode(program, &program_decoded);

  Key entry_key(key_decoded.begin(), key_decoded.end());
  Value entry_value(program_decoded.begin(), program_decoded.end());

  store_.Put(entry_key, ProgramCacheValue(std::move(entry_value), this));
}

size_t PassthroughProgramCache::Trim(size_t limit) {
  base::AutoLock auto_lock(lock_);
  return TrimLocked(limit);
}

void PassthroughProgramCache::OnUpdateMemoryLimit() {
  base::AutoLock auto_lock(lock_);
  if (!base::FeatureList::IsEnabled(base::kStatefulMemoryPressure)) {
    return;
  }
  // To match previous behavior, the size must be 1/4 at 50% memory limit.
  double ratio = std::clamp(memory_limit_ratio(), 0.0, 1.0);
  size_t target_size = max_size_bytes() * std::pow(ratio, 2.0);
  current_max_size_bytes_ = std::max(curr_size_bytes_, target_size);
}

void PassthroughProgramCache::OnReleaseMemory() {
  base::AutoLock auto_lock(lock_);
  if (base::FeatureList::IsEnabled(base::kStatefulMemoryPressure)) {
    // To match previous behavior, the size must be 1/4 at 50% memory limit.
    double ratio = std::clamp(memory_limit_ratio(), 0.0, 1.0);
    size_t target_size = max_size_bytes() * std::pow(ratio, 2.0);
    current_max_size_bytes_ = target_size;
    TrimLocked(current_max_size_bytes_);
    return;
  }

  int limit = memory_limit();
  if (limit <= base::kCriticalMemoryPressureThreshold) {
    TrimLocked(0);
  } else if (limit <= base::kModerateMemoryPressureThreshold) {
    TrimLocked(max_size_bytes() / 4);
  }
}

bool PassthroughProgramCache::CacheEnabled() const {
  return !disable_gpu_shader_disk_cache_;
}

void PassthroughProgramCache::Set(Key&& key,
                                  Value&& value,
                                  CacheProgramCallback callback) {
  base::AutoLock auto_lock(lock_);
  // If the value is so big it will never fit in the cache, throw it away.
  if (value.size() > GetCurrentMaxSizeBytes()) {
    return;
  }

  // Evict any cached program with the same key in favor of the least recently
  // accessed.
  ProgramLRUCache::iterator existing = store_.Peek(key);
  if (existing != store_.end()) {
    store_.Erase(existing);
  }

  // If the cache is overflowing, remove some old entries.
  DCHECK(GetCurrentMaxSizeBytes() >= value.size());

  TrimLocked(GetCurrentMaxSizeBytes() - value.size());

  // If callback is set, notify that there was a new/updated blob entry so it
  // can be stored in disk.  Note that this is done before the Put() call as
  // that consumes `value`.
  CacheProgramCallback callback_with_fallback =
      callback ? callback : cache_program_callback_;
  if (callback_with_fallback) {
    // Convert the key and binary to base-64 string form.
    std::string key_string_64 = base::Base64Encode(key);
    std::string value_string_64 = base::Base64Encode(value);
    callback_with_fallback.Run(key_string_64, value_string_64);
  }

  store_.Put(key, ProgramCacheValue(std::move(value), this));
}

size_t PassthroughProgramCache::Get(const Key& key,
                                    void* out_value,
                                    size_t value_size) {
  // Note that the |lock_| should be held during whole time ProgramCacheValue is
  // being accessed below.
  base::AutoLock auto_lock(lock_);

  ProgramLRUCache::iterator found = store_.Get(key);

  UMA_HISTOGRAM_BOOLEAN("Gpu.PassthroughProgramCacheLoadHitInCache",
                        found != store_.end());

  if (found == store_.end()) {
    return 0;
  }

  const PassthroughProgramCache::Value& entry_value = found->second.data();

  if (value_size > 0) {
    if (static_cast<size_t>(value_size) >= entry_value.size()) {
      UNSAFE_TODO(memcpy(out_value, entry_value.data(), entry_value.size()));
    }
  }

  return entry_value.size();
}

EGLsizeiANDROID PassthroughProgramCache::BlobCacheGetImpl(
    const void* key,
    EGLsizeiANDROID key_size,
    void* value,
    EGLsizeiANDROID value_size) {
  if (key_size < 0) {
    return 0;
  }

  const uint8_t* key_begin = reinterpret_cast<const uint8_t*>(key);
  PassthroughProgramCache::Key entry_key(key_begin,
                                         UNSAFE_TODO(key_begin + key_size));

  return Get(entry_key, value, value_size);
}

void PassthroughProgramCache::BlobCacheSetImpl(const void* key,
                                               EGLsizeiANDROID key_size,
                                               const void* value,
                                               EGLsizeiANDROID value_size) {
  if (key_size < 0 || value_size < 0) {
    return;
  }

  const uint8_t* key_begin = reinterpret_cast<const uint8_t*>(key);
  PassthroughProgramCache::Key entry_key(key_begin,
                                         UNSAFE_TODO(key_begin + key_size));

  const uint8_t* value_begin = reinterpret_cast<const uint8_t*>(value);
  PassthroughProgramCache::Value entry_value(
      value_begin, UNSAFE_TODO(value_begin + value_size));

  // Pass a null callback to use the default cache_program_callback_
  Set(std::move(entry_key), std::move(entry_value), CacheProgramCallback());
}

size_t PassthroughProgramCache::TrimLocked(size_t limit) {
  size_t initial_size = curr_size_bytes_;
  while (curr_size_bytes_ > limit) {
    DCHECK(!store_.empty());
    store_.Erase(store_.rbegin());
  }
  return initial_size - curr_size_bytes_;
}

size_t PassthroughProgramCache::GetCurrentMaxSizeBytes() const {
  if (base::FeatureList::IsEnabled(base::kStatefulMemoryPressure)) {
    return current_max_size_bytes_;
  }
  return max_size_bytes();
}

void PassthroughProgramCache::BlobCacheSet(const void* key,
                                           EGLsizeiANDROID key_size,
                                           const void* value,
                                           EGLsizeiANDROID value_size) {
  if (!g_program_cache)
    return;

  g_program_cache->BlobCacheSetImpl(key, key_size, value, value_size);
}

EGLsizeiANDROID PassthroughProgramCache::BlobCacheGet(
    const void* key,
    EGLsizeiANDROID key_size,
    void* value,
    EGLsizeiANDROID value_size) {
  if (!g_program_cache)
    return 0;

  return g_program_cache->BlobCacheGetImpl(key, key_size, value, value_size);
}

PassthroughProgramCache::ProgramCacheValue::ProgramCacheValue(
    PassthroughProgramCache::Value&& program_blob,
    PassthroughProgramCache* program_cache)
    : program_blob_(std::move(program_blob)), program_cache_(program_cache) {
  program_cache_->curr_size_bytes_ += program_blob_.size();
}

PassthroughProgramCache::ProgramCacheValue::~ProgramCacheValue() {
  if (program_cache_) {
    program_cache_->curr_size_bytes_ -= program_blob_.size();
  }
}

PassthroughProgramCache::ProgramCacheValue::ProgramCacheValue(
    ProgramCacheValue&& other)
    : program_blob_(std::move(other.program_blob_)),
      program_cache_(std::exchange(other.program_cache_, nullptr)) {}

PassthroughProgramCache::ProgramCacheValue&
PassthroughProgramCache::ProgramCacheValue::operator=(
    ProgramCacheValue&& other) {
  program_blob_ = std::move(other.program_blob_);
  program_cache_ = std::exchange(other.program_cache_, nullptr);
  return *this;
}

}  // namespace gles2
}  // namespace gpu
