// Copyright 2013 The Flutter 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 "flutter/shell/platform/embedder/tests/embedder_test_context_gl.h"

#include "flutter/fml/make_copyable.h"
#include "flutter/fml/paths.h"
#include "flutter/runtime/dart_vm.h"
#include "flutter/shell/platform/embedder/tests/embedder_assertions.h"
#include "flutter/shell/platform/embedder/tests/embedder_test_compositor_gl.h"
#include "flutter/testing/testing.h"
#include "tests/embedder_test.h"
#include "third_party/dart/runtime/bin/elf_loader.h"
#include "third_party/skia/include/core/SkSurface.h"

namespace flutter {
namespace testing {

EmbedderTestContextGL::EmbedderTestContextGL(std::string assets_path)
    : EmbedderTestContext(assets_path) {}

EmbedderTestContextGL::~EmbedderTestContextGL() {
  SetGLGetFBOCallback(nullptr);
}

void EmbedderTestContextGL::SetupSurface(SkISize surface_size) {
  FML_CHECK(!gl_surface_);
  gl_surface_ = std::make_unique<TestGLSurface>(surface_size);
}

bool EmbedderTestContextGL::GLMakeCurrent() {
  FML_CHECK(gl_surface_) << "GL surface must be initialized.";
  return gl_surface_->MakeCurrent();
}

bool EmbedderTestContextGL::GLClearCurrent() {
  FML_CHECK(gl_surface_) << "GL surface must be initialized.";
  return gl_surface_->ClearCurrent();
}

bool EmbedderTestContextGL::GLPresent(FlutterPresentInfo present_info) {
  FML_CHECK(gl_surface_) << "GL surface must be initialized.";
  gl_surface_present_count_++;

  GLPresentCallback callback;
  {
    std::scoped_lock lock(gl_callback_mutex_);
    callback = gl_present_callback_;
  }

  if (callback) {
    callback(present_info);
  }

  FireRootSurfacePresentCallbackIfPresent(
      [&]() { return gl_surface_->GetRasterSurfaceSnapshot(); });

  return gl_surface_->Present();
}

void EmbedderTestContextGL::SetGLGetFBOCallback(GLGetFBOCallback callback) {
  std::scoped_lock lock(gl_callback_mutex_);
  gl_get_fbo_callback_ = callback;
}

void EmbedderTestContextGL::SetGLPopulateExistingDamageCallback(
    GLPopulateExistingDamageCallback callback) {
  std::scoped_lock lock(gl_callback_mutex_);
  gl_populate_existing_damage_callback_ = callback;
}

void EmbedderTestContextGL::SetGLPresentCallback(GLPresentCallback callback) {
  std::scoped_lock lock(gl_callback_mutex_);
  gl_present_callback_ = callback;
}

uint32_t EmbedderTestContextGL::GLGetFramebuffer(FlutterFrameInfo frame_info) {
  FML_CHECK(gl_surface_) << "GL surface must be initialized.";

  GLGetFBOCallback callback;
  {
    std::scoped_lock lock(gl_callback_mutex_);
    callback = gl_get_fbo_callback_;
  }

  if (callback) {
    callback(frame_info);
  }

  const auto size = frame_info.size;
  return gl_surface_->GetFramebuffer(size.width, size.height);
}

void EmbedderTestContextGL::GLPopulateExistingDamage(
    const intptr_t id,
    FlutterDamage* existing_damage) {
  FML_CHECK(gl_surface_) << "GL surface must be initialized.";

  GLPopulateExistingDamageCallback callback;
  {
    std::scoped_lock lock(gl_callback_mutex_);
    callback = gl_populate_existing_damage_callback_;
  }

  if (callback) {
    callback(id, existing_damage);
  }
}

bool EmbedderTestContextGL::GLMakeResourceCurrent() {
  FML_CHECK(gl_surface_) << "GL surface must be initialized.";
  return gl_surface_->MakeResourceCurrent();
}

void* EmbedderTestContextGL::GLGetProcAddress(const char* name) {
  FML_CHECK(gl_surface_) << "GL surface must be initialized.";
  return gl_surface_->GetProcAddress(name);
}

size_t EmbedderTestContextGL::GetSurfacePresentCount() const {
  return gl_surface_present_count_;
}

EmbedderTestContextType EmbedderTestContextGL::GetContextType() const {
  return EmbedderTestContextType::kOpenGLContext;
}

uint32_t EmbedderTestContextGL::GetWindowFBOId() const {
  FML_CHECK(gl_surface_);
  return gl_surface_->GetWindowFBOId();
}

void EmbedderTestContextGL::SetupCompositor() {
  FML_CHECK(!compositor_) << "Already set up a compositor in this context.";
  FML_CHECK(gl_surface_)
      << "Set up the GL surface before setting up a compositor.";
  compositor_ = std::make_unique<EmbedderTestCompositorGL>(
      gl_surface_->GetSurfaceSize(), gl_surface_->GetGrContext());
  GLClearCurrent();
}

}  // namespace testing
}  // namespace flutter
