// 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.

#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterGLCompositor.h"

#import <OpenGL/gl.h>

#include "flutter/fml/logging.h"
#include "flutter/fml/platform/darwin/cf_utils.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterBackingStore.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterBackingStoreData.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterFrameBufferProvider.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterIOSurfaceHolder.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/gpu/gl/GrGLAssembleInterface.h"
#include "third_party/skia/include/utils/mac/SkCGUtils.h"

namespace flutter {

FlutterGLCompositor::FlutterGLCompositor(FlutterViewController* view_controller,
                                         NSOpenGLContext* opengl_context)
    : FlutterCompositor(view_controller), open_gl_context_(opengl_context) {}

bool FlutterGLCompositor::CreateBackingStore(const FlutterBackingStoreConfig* config,
                                             FlutterBackingStore* backing_store_out) {
  if (!view_controller_) {
    return false;
  }

  CGSize size = CGSizeMake(config->size.width, config->size.height);

  if (!frame_started_) {
    StartFrame();
    // If the backing store is for the first layer, return the fbo for the
    // FlutterView.
    FlutterOpenGLRenderBackingStore* backingStore =
        reinterpret_cast<FlutterOpenGLRenderBackingStore*>(
            [view_controller_.flutterView backingStoreForSize:size]);
    backing_store_out->open_gl.framebuffer.name = backingStore.frameBufferID;
  } else {
    FlutterFrameBufferProvider* fb_provider =
        [[FlutterFrameBufferProvider alloc] initWithOpenGLContext:open_gl_context_];
    FlutterIOSurfaceHolder* io_surface_holder = [FlutterIOSurfaceHolder alloc];

    GLuint fbo = [fb_provider glFrameBufferId];
    GLuint texture = [fb_provider glTextureId];

    size_t layer_id = CreateCALayer();

    [io_surface_holder bindSurfaceToTexture:texture fbo:fbo size:size];
    FlutterBackingStoreData* data =
        [[FlutterBackingStoreData alloc] initWithLayerId:layer_id
                                              fbProvider:fb_provider
                                         ioSurfaceHolder:io_surface_holder];

    backing_store_out->open_gl.framebuffer.name = fbo;
    backing_store_out->open_gl.framebuffer.user_data = (__bridge_retained void*)data;
  }

  backing_store_out->type = kFlutterBackingStoreTypeOpenGL;
  backing_store_out->open_gl.type = kFlutterOpenGLTargetTypeFramebuffer;
  backing_store_out->open_gl.framebuffer.target = GL_RGBA8;
  backing_store_out->open_gl.framebuffer.destruction_callback = [](void* user_data) {
    if (user_data != nullptr) {
      CFRelease(user_data);
    }
  };

  return true;
}

bool FlutterGLCompositor::CollectBackingStore(const FlutterBackingStore* backing_store) {
  return true;
}

bool FlutterGLCompositor::Present(const FlutterLayer** layers, size_t layers_count) {
  for (size_t i = 0; i < layers_count; ++i) {
    const auto* layer = layers[i];
    FlutterBackingStore* backing_store = const_cast<FlutterBackingStore*>(layer->backing_store);
    switch (layer->type) {
      case kFlutterLayerContentTypeBackingStore: {
        if (backing_store->open_gl.framebuffer.user_data) {
          FlutterBackingStoreData* backing_store_data =
              (__bridge FlutterBackingStoreData*)backing_store->open_gl.framebuffer.user_data;

          FlutterIOSurfaceHolder* io_surface_holder = [backing_store_data ioSurfaceHolder];
          size_t layer_id = [backing_store_data layerId];

          CALayer* content_layer = ca_layer_map_[layer_id];

          FML_CHECK(content_layer) << "Unable to find a content layer with layer id " << layer_id;

          content_layer.frame = content_layer.superlayer.bounds;

          // The surface is an OpenGL texture, which means it has origin in bottom left corner
          // and needs to be flipped vertically
          content_layer.transform = CATransform3DMakeScale(1, -1, 1);
          IOSurfaceRef io_surface_contents = [io_surface_holder ioSurface];
          [content_layer setContents:(__bridge id)io_surface_contents];
        }
        break;
      }
      case kFlutterLayerContentTypePlatformView:
        // Add functionality in follow up PR.
        FML_LOG(WARNING) << "Presenting PlatformViews not yet supported";
        break;
    };
  }
  // The frame has been presented, prepare FlutterGLCompositor to
  // render a new frame.
  frame_started_ = false;
  return present_callback_();
}

void FlutterGLCompositor::StartFrame() {
  // First reset all the state.
  ca_layer_count_ = 0;

  // First remove all CALayers from the superlayer.
  for (auto const& ca_layer_kvp : ca_layer_map_) {
    [ca_layer_kvp.second removeFromSuperlayer];
  }

  // Reset layer map.
  ca_layer_map_.clear();

  frame_started_ = true;
}

size_t FlutterGLCompositor::CreateCALayer() {
  if (!view_controller_) {
    return 0;
  }

  // FlutterGLCompositor manages the lifecycle of content layers.
  // The id for a CALayer starts at 0 and increments by 1 for
  // any given frame.
  CALayer* content_layer = [[CALayer alloc] init];
  [view_controller_.flutterView.layer addSublayer:content_layer];
  ca_layer_map_[ca_layer_count_] = content_layer;
  return ca_layer_count_++;
}

}  // namespace flutter
