// 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/linux/public/flutter_linux/fl_pixel_buffer_texture.h"

#include <epoxy/gl.h>
#include <gmodule.h>

#include "flutter/shell/platform/linux/fl_pixel_buffer_texture_private.h"

typedef struct {
  GLuint texture_id;
} FlPixelBufferTexturePrivate;

// Added here to stop the compiler from optimising this function away.
G_MODULE_EXPORT GType fl_pixel_buffer_texture_get_type();

static void fl_pixel_buffer_texture_iface_init(FlTextureInterface* iface) {}

G_DEFINE_TYPE_WITH_CODE(
    FlPixelBufferTexture,
    fl_pixel_buffer_texture,
    G_TYPE_OBJECT,
    G_IMPLEMENT_INTERFACE(fl_texture_get_type(),
                          fl_pixel_buffer_texture_iface_init);
    G_ADD_PRIVATE(FlPixelBufferTexture))

static void fl_pixel_buffer_texture_dispose(GObject* object) {
  FlPixelBufferTexture* self = FL_PIXEL_BUFFER_TEXTURE(object);
  FlPixelBufferTexturePrivate* priv =
      reinterpret_cast<FlPixelBufferTexturePrivate*>(
          fl_pixel_buffer_texture_get_instance_private(self));

  if (priv->texture_id) {
    glDeleteTextures(1, &priv->texture_id);
    priv->texture_id = 0;
  }

  G_OBJECT_CLASS(fl_pixel_buffer_texture_parent_class)->dispose(object);
}

static void check_gl_error(int line) {
  GLenum err = glGetError();
  if (err) {
    g_warning("glGetError %x (%s:%d)\n", err, __FILE__, line);
  }
}

gboolean fl_pixel_buffer_texture_populate(FlPixelBufferTexture* texture,
                                          uint32_t width,
                                          uint32_t height,
                                          FlutterOpenGLTexture* opengl_texture,
                                          GError** error) {
  FlPixelBufferTexture* self = FL_PIXEL_BUFFER_TEXTURE(texture);
  FlPixelBufferTexturePrivate* priv =
      reinterpret_cast<FlPixelBufferTexturePrivate*>(
          fl_pixel_buffer_texture_get_instance_private(self));

  const uint8_t* buffer = nullptr;
  if (!FL_PIXEL_BUFFER_TEXTURE_GET_CLASS(self)->copy_pixels(
          self, &buffer, &width, &height, error)) {
    return FALSE;
  }

  if (priv->texture_id == 0) {
    glGenTextures(1, &priv->texture_id);
    check_gl_error(__LINE__);
    glBindTexture(GL_TEXTURE_2D, priv->texture_id);
    check_gl_error(__LINE__);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
    check_gl_error(__LINE__);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
    check_gl_error(__LINE__);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    check_gl_error(__LINE__);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    check_gl_error(__LINE__);
  } else {
    glBindTexture(GL_TEXTURE_2D, priv->texture_id);
    check_gl_error(__LINE__);
  }
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA,
               GL_UNSIGNED_BYTE, buffer);
  check_gl_error(__LINE__);

  opengl_texture->target = GL_TEXTURE_2D;
  opengl_texture->name = priv->texture_id;
  opengl_texture->format = GL_RGBA8;
  opengl_texture->destruction_callback = nullptr;
  opengl_texture->user_data = nullptr;
  opengl_texture->width = width;
  opengl_texture->height = height;

  return TRUE;
}

static void fl_pixel_buffer_texture_class_init(
    FlPixelBufferTextureClass* klass) {
  G_OBJECT_CLASS(klass)->dispose = fl_pixel_buffer_texture_dispose;
}

static void fl_pixel_buffer_texture_init(FlPixelBufferTexture* self) {}
