// 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 "surface.h"
#include <algorithm>

#include "third_party/skia/include/gpu/GrBackendSurface.h"
#include "third_party/skia/include/gpu/GrDirectContext.h"
#include "third_party/skia/include/gpu/ganesh/gl/GrGLBackendSurface.h"
#include "third_party/skia/include/gpu/ganesh/gl/GrGLDirectContext.h"

using namespace Skwasm;

Surface::Surface() {
  assert(emscripten_is_main_browser_thread());

  pthread_attr_t attr;
  pthread_attr_init(&attr);
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

  pthread_create(
      &_thread, &attr,
      [](void* context) -> void* {
        static_cast<Surface*>(context)->_runWorker();
        return nullptr;
      },
      this);
  // Listen to messages from the worker
  skwasm_registerMessageListener(_thread);

  // Synchronize the time origin for the worker thread
  skwasm_syncTimeOriginForThread(_thread);
}

// Main thread only
void Surface::dispose() {
  assert(emscripten_is_main_browser_thread());
  emscripten_dispatch_to_thread(_thread, EM_FUNC_SIG_VI,
                                reinterpret_cast<void*>(fDispose), nullptr,
                                this);
}

// Main thread only
uint32_t Surface::renderPictures(SkPicture** pictures, int count) {
  assert(emscripten_is_main_browser_thread());
  uint32_t callbackId = ++_currentCallbackId;
  std::unique_ptr<sk_sp<SkPicture>[]> picturePointers =
      std::make_unique<sk_sp<SkPicture>[]>(count);
  for (int i = 0; i < count; i++) {
    picturePointers[i] = sk_ref_sp(pictures[i]);
  }

  // Releasing picturePointers here and will recreate the unique_ptr on the
  // other thread See surface_renderPicturesOnWorker
  skwasm_dispatchRenderPictures(_thread, this, picturePointers.release(), count,
                                callbackId);
  return callbackId;
}

// Main thread only
uint32_t Surface::rasterizeImage(SkImage* image, ImageByteFormat format) {
  assert(emscripten_is_main_browser_thread());
  uint32_t callbackId = ++_currentCallbackId;
  image->ref();

  emscripten_dispatch_to_thread(_thread, EM_FUNC_SIG_VIIII,
                                reinterpret_cast<void*>(fRasterizeImage),
                                nullptr, this, image, format, callbackId);
  return callbackId;
}

std::unique_ptr<TextureSourceWrapper> Surface::createTextureSourceWrapper(
    SkwasmObject textureSource) {
  return std::unique_ptr<TextureSourceWrapper>(
      new TextureSourceWrapper(_thread, textureSource));
}

// Main thread only
void Surface::setCallbackHandler(CallbackHandler* callbackHandler) {
  assert(emscripten_is_main_browser_thread());
  _callbackHandler = callbackHandler;
}

// Worker thread only
void Surface::_runWorker() {
  _init();
  emscripten_exit_with_live_runtime();
}

// Worker thread only
void Surface::_init() {
  // Listen to messages from the main thread
  skwasm_registerMessageListener(0);
  _glContext = skwasm_createOffscreenCanvas(256, 256);
  if (!_glContext) {
    printf("Failed to create context!\n");
    return;
  }

  makeCurrent(_glContext);
  emscripten_webgl_enable_extension(_glContext, "WEBGL_debug_renderer_info");

  _grContext = GrDirectContexts::MakeGL(GrGLMakeNativeInterface());

  // WebGL should already be clearing the color and stencil buffers, but do it
  // again here to ensure Skia receives them in the expected state.
  emscripten_glBindFramebuffer(GL_FRAMEBUFFER, 0);
  emscripten_glClearColor(0, 0, 0, 0);
  emscripten_glClearStencil(0);
  emscripten_glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  _grContext->resetContext(kRenderTarget_GrGLBackendState |
                           kMisc_GrGLBackendState);

  // The on-screen canvas is FBO 0. Wrap it in a Skia render target so Skia
  // can render to it.
  _fbInfo.fFBOID = 0;
  _fbInfo.fFormat = GL_RGBA8_OES;

  emscripten_glGetIntegerv(GL_SAMPLES, &_sampleCount);
  emscripten_glGetIntegerv(GL_STENCIL_BITS, &_stencil);
}

// Worker thread only
void Surface::_dispose() {
  delete this;
}

// Worker thread only
void Surface::_resizeCanvasToFit(int width, int height) {
  if (!_surface || width > _canvasWidth || height > _canvasHeight) {
    _canvasWidth = std::max(width, _canvasWidth);
    _canvasHeight = std::max(height, _canvasHeight);
    _recreateSurface();
  }
}

// Worker thread only
void Surface::_recreateSurface() {
  makeCurrent(_glContext);
  skwasm_resizeCanvas(_glContext, _canvasWidth, _canvasHeight);
  auto target = GrBackendRenderTargets::MakeGL(_canvasWidth, _canvasHeight,
                                               _sampleCount, _stencil, _fbInfo);
  _surface = SkSurfaces::WrapBackendRenderTarget(
      _grContext.get(), target, kBottomLeft_GrSurfaceOrigin,
      kRGBA_8888_SkColorType, SkColorSpace::MakeSRGB(), nullptr);
}

// Worker thread only
void Surface::renderPicturesOnWorker(sk_sp<SkPicture>* pictures,
                                     int pictureCount,
                                     uint32_t callbackId,
                                     double rasterStart) {
  // This is populated by the `captureImageBitmap` call the first time it is
  // passed in.
  SkwasmObject imagePromiseArray = __builtin_wasm_ref_null_extern();
  for (int i = 0; i < pictureCount; i++) {
    sk_sp<SkPicture> picture = pictures[i];
    SkRect pictureRect = picture->cullRect();
    SkIRect roundedOutRect;
    pictureRect.roundOut(&roundedOutRect);
    _resizeCanvasToFit(roundedOutRect.width(), roundedOutRect.height());
    SkMatrix matrix =
        SkMatrix::Translate(-roundedOutRect.fLeft, -roundedOutRect.fTop);
    makeCurrent(_glContext);
    auto canvas = _surface->getCanvas();
    canvas->drawColor(SK_ColorTRANSPARENT, SkBlendMode::kSrc);
    canvas->drawPicture(picture, &matrix, nullptr);
    _grContext->flush(_surface.get());
    imagePromiseArray =
        skwasm_captureImageBitmap(_glContext, roundedOutRect.width(),
                                  roundedOutRect.height(), imagePromiseArray);
  }
  skwasm_resolveAndPostImages(this, imagePromiseArray, rasterStart, callbackId);
}

void Surface::_rasterizeImage(SkImage* image,
                              ImageByteFormat format,
                              uint32_t callbackId) {
  // We handle PNG encoding with browser APIs so that we can omit libpng from
  // skia to save binary size.
  assert(format != ImageByteFormat::png);
  sk_sp<SkData> data;
  SkAlphaType alphaType = format == ImageByteFormat::rawStraightRgba
                              ? SkAlphaType::kUnpremul_SkAlphaType
                              : SkAlphaType::kPremul_SkAlphaType;
  SkImageInfo info = SkImageInfo::Make(image->width(), image->height(),
                                       SkColorType::kRGBA_8888_SkColorType,
                                       alphaType, SkColorSpace::MakeSRGB());
  size_t bytesPerRow = 4 * image->width();
  size_t byteSize = info.computeByteSize(bytesPerRow);
  data = SkData::MakeUninitialized(byteSize);
  uint8_t* pixels = reinterpret_cast<uint8_t*>(data->writable_data());
  bool success = image->readPixels(_grContext.get(), image->imageInfo(), pixels,
                                   bytesPerRow, 0, 0);
  if (!success) {
    printf("Failed to read pixels from image!\n");
    data = nullptr;
  }
  emscripten_async_run_in_main_runtime_thread(
      EM_FUNC_SIG_VIII, fOnRasterizeComplete, this, data.release(), callbackId);
}

void Surface::_onRasterizeComplete(SkData* data, uint32_t callbackId) {
  _callbackHandler(callbackId, data, __builtin_wasm_ref_null_extern());
}

// Main thread only
void Surface::onRenderComplete(uint32_t callbackId, SkwasmObject imageBitmap) {
  assert(emscripten_is_main_browser_thread());
  _callbackHandler(callbackId, nullptr, imageBitmap);
}

void Surface::fDispose(Surface* surface) {
  surface->_dispose();
}

void Surface::fOnRasterizeComplete(Surface* surface,
                                   SkData* imageData,
                                   uint32_t callbackId) {
  surface->_onRasterizeComplete(imageData, callbackId);
}

void Surface::fRasterizeImage(Surface* surface,
                              SkImage* image,
                              ImageByteFormat format,
                              uint32_t callbackId) {
  surface->_rasterizeImage(image, format, callbackId);
  image->unref();
}

SKWASM_EXPORT Surface* surface_create() {
  return new Surface();
}

SKWASM_EXPORT unsigned long surface_getThreadId(Surface* surface) {
  return surface->getThreadId();
}

SKWASM_EXPORT void surface_setCallbackHandler(
    Surface* surface,
    Surface::CallbackHandler* callbackHandler) {
  surface->setCallbackHandler(callbackHandler);
}

SKWASM_EXPORT void surface_destroy(Surface* surface) {
  surface->dispose();
}

SKWASM_EXPORT uint32_t surface_renderPictures(Surface* surface,
                                              SkPicture** pictures,
                                              int count) {
  return surface->renderPictures(pictures, count);
}

SKWASM_EXPORT void surface_renderPicturesOnWorker(Surface* surface,
                                                  sk_sp<SkPicture>* pictures,
                                                  int pictureCount,
                                                  uint32_t callbackId,
                                                  double rasterStart) {
  // This will release the pictures when they leave scope.
  std::unique_ptr<sk_sp<SkPicture>[]> picturesPointer =
      std::unique_ptr<sk_sp<SkPicture>[]>(pictures);
  surface->renderPicturesOnWorker(pictures, pictureCount, callbackId,
                                  rasterStart);
}

SKWASM_EXPORT uint32_t surface_rasterizeImage(Surface* surface,
                                              SkImage* image,
                                              ImageByteFormat format) {
  return surface->rasterizeImage(image, format);
}

// This is used by the skwasm JS support code to call back into C++ when the
// we finish creating the image bitmap, which is an asynchronous operation.
SKWASM_EXPORT void surface_onRenderComplete(Surface* surface,
                                            uint32_t callbackId,
                                            SkwasmObject imageBitmap) {
  return surface->onRenderComplete(callbackId, imageBitmap);
}
