// Copyright (c) 2017 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.

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

#include <stddef.h>

#include "base/base64.h"
#include "ui/gl/gl_bindings.h"

#if defined(USE_EGL)
#include "ui/gl/angle_platform_impl.h"
#include "ui/gl/gl_surface_egl.h"
#endif  // defined(USE_EGL)

#ifndef EGL_ANGLE_program_cache_control
#define EGL_ANGLE_program_cache_control 1
#define EGL_PROGRAM_CACHE_SIZE_ANGLE 0x3455
#define EGL_PROGRAM_CACHE_KEY_LENGTH_ANGLE 0x3456
#define EGL_PROGRAM_CACHE_RESIZE_ANGLE 0x3457
#define EGL_PROGRAM_CACHE_TRIM_ANGLE 0x3458
#define EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE 0x3459
#endif /* EGL_ANGLE_program_cache_control */

namespace gpu {
namespace gles2 {

namespace {

bool ProgramCacheControlExtensionAvailable() {
#if defined(USE_EGL)
  // The display should be initialized if the extension is available.
  return gl::g_driver_egl.ext.b_EGL_ANGLE_program_cache_control;
#else
  return false;
#endif  // defined(USE_EGL)
}

}  // 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) {
  if (!CacheEnabled()) {
    return;
  }

#if defined(USE_EGL)
  EGLDisplay display = gl::GLSurfaceEGL::GetHardwareDisplay();
  DCHECK(display != EGL_NO_DISPLAY);

  eglProgramCacheResizeANGLE(display, max_cache_size_bytes,
                             EGL_PROGRAM_CACHE_RESIZE_ANGLE);
#endif  // defined(USE_EGL)
}

PassthroughProgramCache::~PassthroughProgramCache() {
#if defined(USE_EGL)
  // Ensure the program cache callback is cleared.
  angle::ResetCacheProgramCallback();
#endif  // defined(USE_EGL)
}

void PassthroughProgramCache::ClearBackend() {
  Trim(0);
}

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,
    GLES2DecoderClient* client) {
  NOTREACHED();
  return PROGRAM_LOAD_FAILURE;
}

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,
    GLES2DecoderClient* client) {
  NOTREACHED();
}

void PassthroughProgramCache::LoadProgram(const std::string& key,
                                          const std::string& program) {
  if (!CacheEnabled()) {
    // Early exit if this display can't support cache control
    return;
  }

#if defined(USE_EGL)
  EGLDisplay display = gl::GLSurfaceEGL::GetHardwareDisplay();
  DCHECK(display != EGL_NO_DISPLAY);

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

  eglProgramCachePopulateANGLE(display, key_decoded.c_str(), key_decoded.size(),
                               program_decoded.c_str(), program_decoded.size());
#endif  // defined(USE_EGL)
}

size_t PassthroughProgramCache::Trim(size_t limit) {
  if (!CacheEnabled()) {
    // Early exit if this display can't support cache control
    return 0;
  }

#if defined(USE_EGL)
  EGLDisplay display = gl::GLSurfaceEGL::GetHardwareDisplay();
  DCHECK(display != EGL_NO_DISPLAY);

  EGLint trimmed =
      eglProgramCacheResizeANGLE(display, limit, EGL_PROGRAM_CACHE_TRIM_ANGLE);
  return static_cast<size_t>(trimmed);
#else
  return 0;
#endif  // defined(USE_EGL)
}

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

}  // namespace gles2
}  // namespace gpu
