// 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/fl_renderer_gl.h"

#include "flutter/shell/platform/linux/fl_backing_store_provider.h"
#include "flutter/shell/platform/linux/fl_view_private.h"

struct _FlRendererGL {
  FlRenderer parent_instance;
};

G_DEFINE_TYPE(FlRendererGL, fl_renderer_gl, fl_renderer_get_type())

// Implements FlRenderer::create_contexts.
static gboolean fl_renderer_gl_create_contexts(FlRenderer* renderer,
                                               GtkWidget* widget,
                                               GdkGLContext** visible,
                                               GdkGLContext** resource,
                                               GError** error) {
  GdkWindow* window = gtk_widget_get_parent_window(widget);

  *visible = gdk_window_create_gl_context(window, error);

  if (*error != nullptr)
    return FALSE;

  *resource = gdk_window_create_gl_context(window, error);

  if (*error != nullptr)
    return FALSE;
  return TRUE;
}

// Implements FlRenderer::create_backing_store.
static gboolean fl_renderer_gl_create_backing_store(
    FlRenderer* renderer,
    const FlutterBackingStoreConfig* config,
    FlutterBackingStore* backing_store_out) {
  g_autoptr(GError) error = nullptr;
  gboolean result = fl_renderer_make_current(renderer, &error);
  if (!result) {
    g_warning("Failed to make renderer current when creating backing store: %s",
              error->message);
    return FALSE;
  }

  FlBackingStoreProvider* provider =
      fl_backing_store_provider_new(config->size.width, config->size.height);
  if (!provider) {
    g_warning("Failed to create backing store");
    return FALSE;
  }

  uint32_t name = fl_backing_store_provider_get_gl_framebuffer_id(provider);
  uint32_t format = fl_backing_store_provider_get_gl_format(provider);

  backing_store_out->type = kFlutterBackingStoreTypeOpenGL;
  backing_store_out->open_gl.type = kFlutterOpenGLTargetTypeFramebuffer;
  backing_store_out->open_gl.framebuffer.user_data = provider;
  backing_store_out->open_gl.framebuffer.name = name;
  backing_store_out->open_gl.framebuffer.target = format;

  return TRUE;
}

// Implements FlRenderer::collect_backing_store.
static gboolean fl_renderer_gl_collect_backing_store(
    FlRenderer* renderer,
    const FlutterBackingStore* backing_store) {
  g_autoptr(GError) error = nullptr;
  gboolean result = fl_renderer_make_current(renderer, &error);
  if (!result) {
    g_warning(
        "Failed to make renderer current when collecting backing store: %s",
        error->message);
    return FALSE;
  }

  // OpenGL context is required when destroying #FlBackingStoreProvider.
  g_object_unref(backing_store->open_gl.framebuffer.user_data);
  return TRUE;
}

// Implements FlRenderer::present_layers.
static gboolean fl_renderer_gl_present_layers(FlRenderer* renderer,
                                              const FlutterLayer** layers,
                                              size_t layers_count) {
  FlView* view = fl_renderer_get_view(renderer);
  GdkGLContext* context = fl_renderer_get_context(renderer);
  if (!view || !context)
    return FALSE;
  fl_view_begin_frame(view);

  for (size_t i = 0; i < layers_count; ++i) {
    const FlutterLayer* layer = layers[i];
    switch (layer->type) {
      case kFlutterLayerContentTypeBackingStore: {
        const FlutterBackingStore* backing_store = layer->backing_store;
        auto framebuffer = &backing_store->open_gl.framebuffer;
        g_object_ref(context);
        fl_view_add_gl_area(
            view, context,
            reinterpret_cast<FlBackingStoreProvider*>(framebuffer->user_data));
      } break;
      case kFlutterLayerContentTypePlatformView: {
        // Currently unsupported.
      } break;
    }
  }

  fl_view_end_frame(view);
  return TRUE;
}

static void fl_renderer_gl_class_init(FlRendererGLClass* klass) {
  FL_RENDERER_CLASS(klass)->create_contexts = fl_renderer_gl_create_contexts;
  FL_RENDERER_CLASS(klass)->create_backing_store =
      fl_renderer_gl_create_backing_store;
  FL_RENDERER_CLASS(klass)->collect_backing_store =
      fl_renderer_gl_collect_backing_store;
  FL_RENDERER_CLASS(klass)->present_layers = fl_renderer_gl_present_layers;
}

static void fl_renderer_gl_init(FlRendererGL* self) {}

FlRendererGL* fl_renderer_gl_new() {
  return FL_RENDERER_GL(g_object_new(fl_renderer_gl_get_type(), nullptr));
}
