// 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.

#ifndef FLUTTER_IMPELLER_RENDERER_RENDER_TARGET_H_
#define FLUTTER_IMPELLER_RENDERER_RENDER_TARGET_H_

#include <functional>
#include <map>
#include <optional>

#include "flutter/fml/macros.h"
#include "impeller/core/allocator.h"
#include "impeller/core/formats.h"
#include "impeller/geometry/size.h"

namespace impeller {

class Context;

/// @brief a wrapper around the impeller [Allocator] instance that can be used
///        to provide caching of allocated render target textures.
class RenderTargetAllocator {
 public:
  explicit RenderTargetAllocator(std::shared_ptr<Allocator> allocator);

  virtual ~RenderTargetAllocator() = default;

  /// @brief Create a new render target texture, or recycle a previously
  /// allocated render
  ///        target texture.
  virtual std::shared_ptr<Texture> CreateTexture(const TextureDescriptor& desc);

  /// @brief Mark the beginning of a frame workload.
  ///
  ///       This may be used to reset any tracking state on whether or not a
  ///       particular texture instance is still in use.
  virtual void Start();

  /// @brief Mark the end of a frame workload.
  ///
  ///        This may be used to deallocate any unused textures.
  virtual void End();

 private:
  std::shared_ptr<Allocator> allocator_;
};

class RenderTarget final {
 public:
  struct AttachmentConfig {
    StorageMode storage_mode;
    LoadAction load_action;
    StoreAction store_action;
    Color clear_color;
  };

  struct AttachmentConfigMSAA {
    StorageMode storage_mode;
    StorageMode resolve_storage_mode;
    LoadAction load_action;
    StoreAction store_action;
    Color clear_color;
  };

  static constexpr AttachmentConfig kDefaultColorAttachmentConfig = {
      .storage_mode = StorageMode::kDevicePrivate,
      .load_action = LoadAction::kClear,
      .store_action = StoreAction::kStore,
      .clear_color = Color::BlackTransparent()};

  static constexpr AttachmentConfigMSAA kDefaultColorAttachmentConfigMSAA = {
      .storage_mode = StorageMode::kDeviceTransient,
      .resolve_storage_mode = StorageMode::kDevicePrivate,
      .load_action = LoadAction::kClear,
      .store_action = StoreAction::kMultisampleResolve,
      .clear_color = Color::BlackTransparent()};

  static constexpr AttachmentConfig kDefaultStencilAttachmentConfig = {
      .storage_mode = StorageMode::kDeviceTransient,
      .load_action = LoadAction::kClear,
      .store_action = StoreAction::kDontCare,
      .clear_color = Color::BlackTransparent()};

  static RenderTarget CreateOffscreen(
      const Context& context,
      RenderTargetAllocator& allocator,
      ISize size,
      const std::string& label = "Offscreen",
      AttachmentConfig color_attachment_config = kDefaultColorAttachmentConfig,
      std::optional<AttachmentConfig> stencil_attachment_config =
          kDefaultStencilAttachmentConfig);

  static RenderTarget CreateOffscreenMSAA(
      const Context& context,
      RenderTargetAllocator& allocator,
      ISize size,
      const std::string& label = "Offscreen MSAA",
      AttachmentConfigMSAA color_attachment_config =
          kDefaultColorAttachmentConfigMSAA,
      std::optional<AttachmentConfig> stencil_attachment_config =
          kDefaultStencilAttachmentConfig);

  RenderTarget();

  ~RenderTarget();

  bool IsValid() const;

  void SetupStencilAttachment(const Context& context,
                              RenderTargetAllocator& allocator,
                              ISize size,
                              bool msaa,
                              const std::string& label = "Offscreen",
                              AttachmentConfig stencil_attachment_config =
                                  kDefaultStencilAttachmentConfig);

  SampleCount GetSampleCount() const;

  bool HasColorAttachment(size_t index) const;

  ISize GetRenderTargetSize() const;

  std::shared_ptr<Texture> GetRenderTargetTexture() const;

  PixelFormat GetRenderTargetPixelFormat() const;

  std::optional<ISize> GetColorAttachmentSize(size_t index) const;

  RenderTarget& SetColorAttachment(const ColorAttachment& attachment,
                                   size_t index);

  RenderTarget& SetDepthAttachment(std::optional<DepthAttachment> attachment);

  RenderTarget& SetStencilAttachment(
      std::optional<StencilAttachment> attachment);

  size_t GetMaxColorAttacmentBindIndex() const;

  const std::map<size_t, ColorAttachment>& GetColorAttachments() const;

  const std::optional<DepthAttachment>& GetDepthAttachment() const;

  const std::optional<StencilAttachment>& GetStencilAttachment() const;

  size_t GetTotalAttachmentCount() const;

  void IterateAllAttachments(
      const std::function<bool(const Attachment& attachment)>& iterator) const;

  std::string ToString() const;

 private:
  std::map<size_t, ColorAttachment> colors_;
  std::optional<DepthAttachment> depth_;
  std::optional<StencilAttachment> stencil_;
};

}  // namespace impeller

#endif  // FLUTTER_IMPELLER_RENDERER_RENDER_TARGET_H_
