// 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;
  DEBUG_COMMAND_INFO(cmd, 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
