// 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/entity/contents/scene_contents.h"

#include "impeller/core/formats.h"
#include "impeller/entity/contents/content_context.h"
#include "impeller/entity/contents/tiled_texture_contents.h"
#include "impeller/entity/entity.h"
#include "impeller/geometry/path_builder.h"
#include "impeller/scene/camera.h"
#include "impeller/scene/scene.h"

namespace impeller {

SceneContents::SceneContents() = default;

SceneContents::~SceneContents() = default;

void SceneContents::SetCameraTransform(Matrix matrix) {
  camera_transform_ = matrix;
}

void SceneContents::SetNode(std::shared_ptr<scene::Node> node) {
  node_ = std::move(node);
}

bool SceneContents::Render(const ContentContext& renderer,
                           const Entity& entity,
                           RenderPass& pass) const {
  if (!node_) {
    return true;
  }

  auto coverage = GetCoverage(entity);
  if (!coverage.has_value()) {
    return true;
  }

  // This happens for CoverGeometry (DrawPaint). In this situation,
  // Draw the scene to the full layer.
  if (coverage.value().IsMaximum()) {
    coverage = Rect::MakeSize(pass.GetRenderTargetSize());
  }

  RenderTarget subpass_target;
  if (renderer.GetContext()->GetCapabilities()->SupportsOffscreenMSAA()) {
    subpass_target = RenderTarget::CreateOffscreenMSAA(
        *renderer.GetContext(),             // context
        *renderer.GetRenderTargetCache(),   // allocator
        ISize(coverage.value().GetSize()),  // size
        "SceneContents",                    // label
        RenderTarget::AttachmentConfigMSAA{
            .storage_mode = StorageMode::kDeviceTransient,
            .resolve_storage_mode = StorageMode::kDevicePrivate,
            .load_action = LoadAction::kClear,
            .store_action = StoreAction::kMultisampleResolve,
        },  // color_attachment_config
        RenderTarget::AttachmentConfig{
            .storage_mode = StorageMode::kDeviceTransient,
            .load_action = LoadAction::kDontCare,
            .store_action = StoreAction::kDontCare,
        }  // stencil_attachment_config
    );
  } else {
    subpass_target = RenderTarget::CreateOffscreen(
        *renderer.GetContext(),             // context
        *renderer.GetRenderTargetCache(),   // allocator
        ISize(coverage.value().GetSize()),  // size
        "SceneContents",                    // label
        RenderTarget::AttachmentConfig{
            .storage_mode = StorageMode::kDevicePrivate,
            .load_action = LoadAction::kClear,
            .store_action = StoreAction::kStore,
        },  // color_attachment_config
        RenderTarget::AttachmentConfig{
            .storage_mode = StorageMode::kDeviceTransient,
            .load_action = LoadAction::kClear,
            .store_action = StoreAction::kDontCare,
        }  // stencil_attachment_config
    );
  }

  if (!subpass_target.IsValid()) {
    return false;
  }

  scene::Scene scene(renderer.GetSceneContext());
  scene.GetRoot().AddChild(node_);

  if (!scene.Render(subpass_target, camera_transform_)) {
    return false;
  }

  // Render the texture to the pass.
  TiledTextureContents contents;
  contents.SetGeometry(GetGeometry());
  contents.SetTexture(subpass_target.GetRenderTargetTexture());
  contents.SetEffectTransform(
      Matrix::MakeScale(1 / entity.GetTransform().GetScale()));
  return contents.Render(renderer, entity, pass);
}

}  // namespace impeller
