// 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 <memory>
#include <utility>

#include "flutter/shell/platform/embedder/embedder_surface_metal_impeller.h"

#include "flutter/fml/logging.h"
#include "flutter/fml/synchronization/sync_switch.h"
#include "flutter/shell/gpu/gpu_surface_metal_delegate.h"
#include "flutter/shell/gpu/gpu_surface_metal_impeller.h"
#import "flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.h"
#include "impeller/entity/mtl/entity_shaders.h"
#include "impeller/entity/mtl/framebuffer_blend_shaders.h"
#include "impeller/entity/mtl/modern_shaders.h"
#include "impeller/renderer/backend/metal/context_mtl.h"

#if IMPELLER_ENABLE_3D
#include "impeller/scene/shaders/mtl/scene_shaders.h"  // nogncheck
#endif                                                 // IMPELLER_ENABLE_3D

FLUTTER_ASSERT_NOT_ARC

namespace flutter {

EmbedderSurfaceMetalImpeller::EmbedderSurfaceMetalImpeller(
    GPUMTLDeviceHandle device,
    GPUMTLCommandQueueHandle command_queue,
    MetalDispatchTable metal_dispatch_table,
    std::shared_ptr<EmbedderExternalViewEmbedder> external_view_embedder)
    : GPUSurfaceMetalDelegate(MTLRenderTargetType::kMTLTexture),
      metal_dispatch_table_(std::move(metal_dispatch_table)),
      external_view_embedder_(std::move(external_view_embedder)) {
  std::vector<std::shared_ptr<fml::Mapping>> shader_mappings = {
    std::make_shared<fml::NonOwnedMapping>(impeller_entity_shaders_data,
                                           impeller_entity_shaders_length),
#if IMPELLER_ENABLE_3D
    std::make_shared<fml::NonOwnedMapping>(impeller_scene_shaders_data,
                                           impeller_scene_shaders_length),
#endif  // IMPELLER_ENABLE_3D
    std::make_shared<fml::NonOwnedMapping>(impeller_modern_shaders_data,
                                           impeller_modern_shaders_length),
    std::make_shared<fml::NonOwnedMapping>(impeller_framebuffer_blend_shaders_data,
                                           impeller_framebuffer_blend_shaders_length),
  };
  context_ = impeller::ContextMTL::Create(
      (id<MTLDevice>)device,                     // device
      (id<MTLCommandQueue>)command_queue,        // command_queue
      shader_mappings,                           // shader_libraries_data
      std::make_shared<fml::SyncSwitch>(false),  // is_gpu_disabled_sync_switch
      "Impeller Library"                         // library_label
  );
  FML_LOG(ERROR) << "Using the Impeller rendering backend (Metal).";

  valid_ = !!context_;
}

EmbedderSurfaceMetalImpeller::~EmbedderSurfaceMetalImpeller() = default;

bool EmbedderSurfaceMetalImpeller::IsValid() const {
  return valid_;
}

std::unique_ptr<Surface> EmbedderSurfaceMetalImpeller::CreateGPUSurface()
    IMPELLER_CA_METAL_LAYER_AVAILABLE {
  if (!IsValid()) {
    return nullptr;
  }

  const bool render_to_surface = !external_view_embedder_;
  auto surface = std::make_unique<GPUSurfaceMetalImpeller>(this, context_, render_to_surface);

  if (!surface->IsValid()) {
    return nullptr;
  }

  return surface;
}

std::shared_ptr<impeller::Context> EmbedderSurfaceMetalImpeller::CreateImpellerContext() const {
  return context_;
}

GPUCAMetalLayerHandle EmbedderSurfaceMetalImpeller::GetCAMetalLayer(
    const SkISize& frame_info) const {
  FML_CHECK(false) << "Only rendering to MTLTexture is supported.";
  return nullptr;
}

bool EmbedderSurfaceMetalImpeller::PresentDrawable(GrMTLHandle drawable) const {
  FML_CHECK(false) << "Only rendering to MTLTexture is supported.";
  return false;
}

GPUMTLTextureInfo EmbedderSurfaceMetalImpeller::GetMTLTexture(const SkISize& frame_info) const {
  return metal_dispatch_table_.get_texture(frame_info);
}

bool EmbedderSurfaceMetalImpeller::PresentTexture(GPUMTLTextureInfo texture) const {
  return metal_dispatch_table_.present(texture);
}

}  // namespace flutter
