// 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 "impeller/renderer/backend/metal/surface_mtl.h"

#include "flutter/fml/trace_event.h"
#include "impeller/base/validation.h"
#include "impeller/renderer/backend/metal/formats_mtl.h"
#include "impeller/renderer/backend/metal/texture_mtl.h"
#include "impeller/renderer/render_target.h"

namespace impeller {

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunguarded-availability-new"

std::unique_ptr<Surface> SurfaceMTL::WrapCurrentMetalLayerDrawable(
    std::shared_ptr<Context> context,
    CAMetalLayer* layer) {
  TRACE_EVENT0("impeller", "SurfaceMTL::WrapCurrentMetalLayerDrawable");

  if (context == nullptr || !context->IsValid() || layer == nil) {
    return nullptr;
  }

  auto current_drawable = [layer nextDrawable];

  if (!current_drawable) {
    VALIDATION_LOG << "Could not acquire current drawable.";
    return nullptr;
  }

  const auto color_format =
      FromMTLPixelFormat(current_drawable.texture.pixelFormat);

  if (color_format == PixelFormat::kUnknown) {
    VALIDATION_LOG << "Unknown drawable color format.";
    return nullptr;
  }

  TextureDescriptor color0_tex_desc;
  color0_tex_desc.type = TextureType::kTexture2DMultisample;
  color0_tex_desc.sample_count = SampleCount::kCount4;
  color0_tex_desc.format = color_format;
  color0_tex_desc.size = {
      static_cast<ISize::Type>(current_drawable.texture.width),
      static_cast<ISize::Type>(current_drawable.texture.height)};
  color0_tex_desc.usage = static_cast<uint64_t>(TextureUsage::kRenderTarget);

  auto msaa_tex = context->GetPermanentsAllocator()->CreateTexture(
      StorageMode::kDeviceTransient, color0_tex_desc);
  if (!msaa_tex) {
    VALIDATION_LOG << "Could not allocate MSAA resolve texture.";
    return nullptr;
  }

  msaa_tex->SetLabel("ImpellerOnscreenColorMSAA");

  TextureDescriptor color0_resolve_tex_desc;
  color0_resolve_tex_desc.format = color_format;
  color0_resolve_tex_desc.size = color0_tex_desc.size;
  color0_resolve_tex_desc.usage =
      static_cast<uint64_t>(TextureUsage::kRenderTarget);

  ColorAttachment color0;
  color0.texture = msaa_tex;
  color0.clear_color = Color::DarkSlateGray();
  color0.load_action = LoadAction::kClear;
  color0.store_action = StoreAction::kMultisampleResolve;
  color0.resolve_texture = std::make_shared<TextureMTL>(
      color0_resolve_tex_desc, current_drawable.texture);

  TextureDescriptor stencil0_tex;
  stencil0_tex.type = TextureType::kTexture2DMultisample;
  stencil0_tex.sample_count = SampleCount::kCount4;
  stencil0_tex.format = PixelFormat::kDefaultStencil;
  stencil0_tex.size = color0_tex_desc.size;
  stencil0_tex.usage =
      static_cast<TextureUsageMask>(TextureUsage::kRenderTarget);
  auto stencil_texture = context->GetPermanentsAllocator()->CreateTexture(
      StorageMode::kDeviceTransient, stencil0_tex);

  if (!stencil_texture) {
    VALIDATION_LOG << "Could not create stencil texture.";
    return nullptr;
  }
  stencil_texture->SetLabel("ImpellerOnscreenStencil");

  StencilAttachment stencil0;
  stencil0.texture = stencil_texture;
  stencil0.clear_stencil = 0;
  stencil0.load_action = LoadAction::kClear;
  stencil0.store_action = StoreAction::kDontCare;

  RenderTarget render_target_desc;
  render_target_desc.SetColorAttachment(color0, 0u);
  render_target_desc.SetStencilAttachment(stencil0);

  // The constructor is private. So make_unique may not be used.
  return std::unique_ptr<SurfaceMTL>(
      new SurfaceMTL(std::move(render_target_desc), current_drawable));
}

SurfaceMTL::SurfaceMTL(RenderTarget target, id<MTLDrawable> drawable)
    : Surface(std::move(target)), drawable_(drawable) {}

// |Surface|
SurfaceMTL::~SurfaceMTL() = default;

// |Surface|
bool SurfaceMTL::Present() const {
  if (drawable_ == nil) {
    return false;
  }

  [drawable_ present];
  return true;
}
#pragma GCC diagnostic pop

}  // namespace impeller
