// Copyright 2018 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "starboard/testing/fake_graphics_context_provider.h"

#include "starboard/common/condition_variable.h"
#include "starboard/common/log.h"
#include "starboard/common/mutex.h"

#if defined(ADDRESS_SANITIZER)
// By default, Leak Sanitizer and Address Sanitizer is expected to exist
// together. However, this is not true for all platforms.
// HAS_LEAK_SANTIZIER=0 explicitly removes the Leak Sanitizer from code.
#ifndef HAS_LEAK_SANITIZER
#define HAS_LEAK_SANITIZER 1
#endif  // HAS_LEAK_SANITIZER
#endif  // defined(ADDRESS_SANITIZER)

#if HAS_LEAK_SANITIZER
#include <sanitizer/lsan_interface.h>
#endif  // HAS_LEAK_SANITIZER

#include "starboard/configuration.h"
#include "starboard/memory.h"

#define EGL_CALL_PREFIX SbGetEglInterface()->

#define EGLConfig SbEglConfig
#define EGLint SbEglInt32
#define EGLNativeWindowType SbEglNativeWindowType

#define EGL_ALPHA_SIZE SB_EGL_ALPHA_SIZE
#define EGL_BLUE_SIZE SB_EGL_BLUE_SIZE
#define EGL_CONTEXT_CLIENT_VERSION SB_EGL_CONTEXT_CLIENT_VERSION
#define EGL_DEFAULT_DISPLAY SB_EGL_DEFAULT_DISPLAY
#define EGL_GREEN_SIZE SB_EGL_GREEN_SIZE
#define EGL_NONE SB_EGL_NONE
#define EGL_NO_CONTEXT SB_EGL_NO_CONTEXT
#define EGL_NO_DISPLAY SB_EGL_NO_DISPLAY
#define EGL_NO_SURFACE SB_EGL_NO_SURFACE
#define EGL_OPENGL_ES2_BIT SB_EGL_OPENGL_ES2_BIT
#define EGL_PBUFFER_BIT SB_EGL_PBUFFER_BIT
#define EGL_RED_SIZE SB_EGL_RED_SIZE
#define EGL_RENDERABLE_TYPE SB_EGL_RENDERABLE_TYPE
#define EGL_SUCCESS SB_EGL_SUCCESS
#define EGL_SURFACE_TYPE SB_EGL_SURFACE_TYPE
#define EGL_WINDOW_BIT SB_EGL_WINDOW_BIT

#define EGL_CALL(x)                                          \
  do {                                                       \
    EGL_CALL_PREFIX x;                                       \
    SB_DCHECK(EGL_CALL_PREFIX eglGetError() == EGL_SUCCESS); \
  } while (false)

#define EGL_CALL_SIMPLE(x) (EGL_CALL_PREFIX x)

#define GL_CALL(x)                                                     \
  do {                                                                 \
    SbGetGlesInterface()->x;                                           \
    SB_DCHECK((SbGetGlesInterface()->glGetError()) == SB_GL_NO_ERROR); \
  } while (false)

namespace starboard {
namespace testing {

namespace {

EGLint const kAttributeList[] = {EGL_RED_SIZE,
                                 8,
                                 EGL_GREEN_SIZE,
                                 8,
                                 EGL_BLUE_SIZE,
                                 8,
                                 EGL_ALPHA_SIZE,
                                 8,
                                 EGL_SURFACE_TYPE,
                                 EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
                                 EGL_RENDERABLE_TYPE,
                                 EGL_OPENGL_ES2_BIT,
                                 EGL_NONE};

}  // namespace

FakeGraphicsContextProvider::FakeGraphicsContextProvider()
    : display_(EGL_NO_DISPLAY),
      surface_(EGL_NO_SURFACE),
      context_(EGL_NO_CONTEXT),
      window_(kSbWindowInvalid) {
  InitializeWindow();
  InitializeEGL();
}

FakeGraphicsContextProvider::~FakeGraphicsContextProvider() {
  functor_queue_.Put(
      std::bind(&FakeGraphicsContextProvider::DestroyContext, this));
  functor_queue_.Wake();
  SbThreadJoin(decode_target_context_thread_, NULL);
  EGL_CALL(eglDestroySurface(display_, surface_));
  EGL_CALL(eglTerminate(display_));
  SbWindowDestroy(window_);
}

void FakeGraphicsContextProvider::RunOnGlesContextThread(
    const std::function<void()>& functor) {
  if (SbThreadIsCurrent(decode_target_context_thread_)) {
    functor();
    return;
  }
  Mutex mutex;
  ConditionVariable condition_variable(mutex);
  ScopedLock scoped_lock(mutex);

  functor_queue_.Put(functor);
  functor_queue_.Put([&]() {
    ScopedLock scoped_lock(mutex);
    condition_variable.Signal();
  });
  condition_variable.Wait();
}

void FakeGraphicsContextProvider::ReleaseDecodeTarget(
    SbDecodeTarget decode_target) {
  if (SbThreadIsCurrent(decode_target_context_thread_)) {
    SbDecodeTargetRelease(decode_target);
    return;
  }

  Mutex mutex;
  ConditionVariable condition_variable(mutex);
  ScopedLock scoped_lock(mutex);

  functor_queue_.Put(std::bind(SbDecodeTargetRelease, decode_target));
  functor_queue_.Put([&]() {
    ScopedLock scoped_lock(mutex);
    condition_variable.Signal();
  });
  condition_variable.Wait();
}

// static
void* FakeGraphicsContextProvider::ThreadEntryPoint(void* context) {
  auto provider = static_cast<FakeGraphicsContextProvider*>(context);
  provider->RunLoop();

  return NULL;
}

void FakeGraphicsContextProvider::RunLoop() {
  while (std::function<void()> functor = functor_queue_.Get()) {
    if (!functor) {
      break;
    }
    functor();
  }
}

void FakeGraphicsContextProvider::InitializeWindow() {
  SbWindowOptions window_options;
  SbWindowSetDefaultOptions(&window_options);

  window_ = SbWindowCreate(&window_options);
  SB_CHECK(SbWindowIsValid(window_));
}

void FakeGraphicsContextProvider::InitializeEGL() {
  display_ = EGL_CALL_SIMPLE(eglGetDisplay(EGL_DEFAULT_DISPLAY));
  SB_DCHECK(EGL_SUCCESS == EGL_CALL_SIMPLE(eglGetError()));
  SB_CHECK(EGL_NO_DISPLAY != display_);

#if HAS_LEAK_SANITIZER
  __lsan_disable();
#endif  // HAS_LEAK_SANITIZER
  EGL_CALL_SIMPLE(eglInitialize(display_, NULL, NULL));
#if HAS_LEAK_SANITIZER
  __lsan_enable();
#endif  // HAS_LEAK_SANITIZER
  SB_DCHECK(EGL_SUCCESS == EGL_CALL_SIMPLE(eglGetError()));

  // Some EGL drivers can return a first config that doesn't allow
  // eglCreateWindowSurface(), with no differences in EGLConfig attribute values
  // from configs that do allow that. To handle that, we have to attempt
  // eglCreateWindowSurface() until we find a config that succeeds.

  // First, query how many configs match the given attribute list.
  EGLint num_configs = 0;
  EGL_CALL(eglChooseConfig(display_, kAttributeList, NULL, 0, &num_configs));
  SB_CHECK(0 != num_configs);

  // Allocate space to receive the matching configs and retrieve them.
  EGLConfig* configs =
      reinterpret_cast<EGLConfig*>(malloc(num_configs * sizeof(EGLConfig)));
  EGL_CALL(eglChooseConfig(display_, kAttributeList, configs, num_configs,
                           &num_configs));

  EGLNativeWindowType native_window =
      (EGLNativeWindowType)SbWindowGetPlatformHandle(window_);
  EGLConfig config = EGLConfig();

  // Find the first config that successfully allow a window surface to be
  // created.
  for (int config_number = 0; config_number < num_configs; ++config_number) {
    config = configs[config_number];
    surface_ = EGL_CALL_SIMPLE(
        eglCreateWindowSurface(display_, config, native_window, NULL));
    if (EGL_SUCCESS == EGL_CALL_SIMPLE(eglGetError()))
      break;
  }
  SB_DCHECK(surface_ != EGL_NO_SURFACE);

  free(configs);
  // Create the GLES2 or GLEX3 Context.
  EGLint context_attrib_list[] = {
      EGL_CONTEXT_CLIENT_VERSION,
      3,
      EGL_NONE,
  };
  if (context_ == EGL_NO_CONTEXT) {
    // Create an OpenGL ES 2.0 context.
    context_attrib_list[1] = 2;
    context_ = EGL_CALL_SIMPLE(eglCreateContext(
        display_, config, EGL_NO_CONTEXT, context_attrib_list));
  }
  SB_CHECK(EGL_SUCCESS == EGL_CALL_SIMPLE(eglGetError()));
  SB_CHECK(context_ != EGL_NO_CONTEXT);

  MakeContextCurrent();

  decoder_target_provider_.egl_display = display_;
  decoder_target_provider_.egl_context = context_;
  decoder_target_provider_.gles_context_runner = DecodeTargetGlesContextRunner;
  decoder_target_provider_.gles_context_runner_context = this;

  decode_target_context_thread_ = SbThreadCreate(
      0, kSbThreadPriorityNormal, kSbThreadNoAffinity, true, "dt_context",
      &FakeGraphicsContextProvider::ThreadEntryPoint, this);
  MakeNoContextCurrent();

  functor_queue_.Put(
      std::bind(&FakeGraphicsContextProvider::MakeContextCurrent, this));
}

void FakeGraphicsContextProvider::OnDecodeTargetGlesContextRunner(
    SbDecodeTargetGlesContextRunnerTarget target_function,
    void* target_function_context) {
  if (SbThreadIsCurrent(decode_target_context_thread_)) {
    target_function(target_function_context);
    return;
  }

  Mutex mutex;
  ConditionVariable condition_variable(mutex);
  ScopedLock scoped_lock(mutex);

  functor_queue_.Put(std::bind(target_function, target_function_context));
  functor_queue_.Put([&]() {
    ScopedLock scoped_lock(mutex);
    condition_variable.Signal();
  });
  condition_variable.Wait();
}

void FakeGraphicsContextProvider::MakeContextCurrent() {
  SB_CHECK(EGL_NO_DISPLAY != display_);
  EGL_CALL_SIMPLE(eglMakeCurrent(display_, surface_, surface_, context_));
  EGLint error = EGL_CALL_SIMPLE(eglGetError());
  SB_CHECK(EGL_SUCCESS == error) << " eglGetError " << error;
}

void FakeGraphicsContextProvider::MakeNoContextCurrent() {
  EGL_CALL(
      eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
}

void FakeGraphicsContextProvider::Render() {
  GL_CALL(glClear(SB_GL_COLOR_BUFFER_BIT));
  EGL_CALL(eglSwapBuffers(display_, surface_));
}

void FakeGraphicsContextProvider::DestroyContext() {
  MakeNoContextCurrent();
  EGL_CALL_SIMPLE(eglDestroyContext(display_, context_));
  EGLint error = EGL_CALL_SIMPLE(eglGetError());
  SB_CHECK(EGL_SUCCESS == error) << " eglGetError " << error;
}

// static
void FakeGraphicsContextProvider::DecodeTargetGlesContextRunner(
    SbDecodeTargetGraphicsContextProvider* graphics_context_provider,
    SbDecodeTargetGlesContextRunnerTarget target_function,
    void* target_function_context) {
  FakeGraphicsContextProvider* provider =
      static_cast<FakeGraphicsContextProvider*>(
          graphics_context_provider->gles_context_runner_context);
  provider->OnDecodeTargetGlesContextRunner(target_function,
                                            target_function_context);
}

}  // namespace testing
}  // namespace starboard
