// 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(uint32_t fbo_id) {
  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(fbo_id);
  }

  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::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);
}

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
