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

#include "flutter/fml/logging.h"
#include "impeller/renderer/command.h"
#include "impeller/renderer/render_target.h"
#include "impeller/scene/scene_context.h"
#include "impeller/scene/scene_encoder.h"

namespace impeller {
namespace scene {

SceneEncoder::SceneEncoder() = default;

void SceneEncoder::Add(const SceneCommand& command) {
  // TODO(bdero): Manage multi-pass translucency ordering.
  commands_.push_back(command);
}

static void EncodeCommand(const SceneContext& scene_context,
                          const Matrix& view_transform,
                          RenderPass& render_pass,
                          const SceneCommand& scene_command) {
  auto& host_buffer = render_pass.GetTransientsBuffer();

  Command cmd;
  cmd.label = scene_command.label;
  cmd.stencil_reference =
      0;  // TODO(bdero): Configurable stencil ref per-command.

  cmd.pipeline = scene_context.GetPipeline(
      PipelineKey{scene_command.geometry->GetGeometryType(),
                  scene_command.material->GetMaterialType()},
      scene_command.material->GetContextOptions(render_pass));

  scene_command.geometry->BindToCommand(
      scene_context, host_buffer, view_transform * scene_command.transform,
      cmd);
  scene_command.material->BindToCommand(scene_context, host_buffer, cmd);

  render_pass.AddCommand(std::move(cmd));
}

std::shared_ptr<CommandBuffer> SceneEncoder::BuildSceneCommandBuffer(
    const SceneContext& scene_context,
    const Matrix& camera_transform,
    RenderTarget render_target) const {
  {
    TextureDescriptor ds_texture;
    ds_texture.type = TextureType::kTexture2DMultisample;
    ds_texture.format = PixelFormat::kD32FloatS8UInt;
    ds_texture.size = render_target.GetRenderTargetSize();
    ds_texture.usage =
        static_cast<TextureUsageMask>(TextureUsage::kRenderTarget);
    ds_texture.sample_count = SampleCount::kCount4;
    ds_texture.storage_mode = StorageMode::kDeviceTransient;
    auto texture =
        scene_context.GetContext()->GetResourceAllocator()->CreateTexture(
            ds_texture);

    DepthAttachment depth;
    depth.load_action = LoadAction::kClear;
    depth.store_action = StoreAction::kDontCare;
    depth.clear_depth = 1.0;
    depth.texture = texture;
    render_target.SetDepthAttachment(depth);

    // The stencil and depth buffers must be the same texture for MacOS ARM
    // and Vulkan.
    StencilAttachment stencil;
    stencil.load_action = LoadAction::kClear;
    stencil.store_action = StoreAction::kDontCare;
    stencil.clear_stencil = 0u;
    stencil.texture = texture;
    render_target.SetStencilAttachment(stencil);
  }

  auto command_buffer = scene_context.GetContext()->CreateCommandBuffer();
  if (!command_buffer) {
    FML_LOG(ERROR) << "Failed to create command buffer.";
    return nullptr;
  }

  auto render_pass = command_buffer->CreateRenderPass(render_target);
  if (!render_pass) {
    FML_LOG(ERROR) << "Failed to create render pass.";
    return nullptr;
  }

  for (auto& command : commands_) {
    EncodeCommand(scene_context, camera_transform, *render_pass, command);
  }

  if (!render_pass->EncodeCommands()) {
    FML_LOG(ERROR) << "Failed to encode render pass commands.";
    return nullptr;
  }

  return command_buffer;
}

}  // namespace scene
}  // namespace impeller
