// 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_COMMAND_BUFFER_H_
#define FLUTTER_IMPELLER_RENDERER_COMMAND_BUFFER_H_

#include <functional>
#include <memory>

#include "flutter/fml/macros.h"
#include "impeller/renderer/blit_pass.h"
#include "impeller/renderer/compute_pass.h"

namespace impeller {

class ComputePass;
class Context;
class RenderPass;
class RenderTarget;

namespace testing {
class CommandBufferMock;
}

//------------------------------------------------------------------------------
/// @brief      A collection of encoded commands to be submitted to the GPU for
///             execution. A command buffer is obtained from a graphics
///             `Context`.
///
///             To submit commands to the GPU, acquire a `RenderPass` from the
///             command buffer and record `Command`s into that pass. A
///             `RenderPass` describes the configuration of the various
///             attachments when the command is submitted.
///
///             A command buffer is only meant to be used on a single thread. If
///             a frame workload needs to be encoded from multiple threads,
///             set up and record into multiple command buffers. The order of
///             submission of commands encoded in multiple command buffers can
///             be controlled via either the order in which the command buffers
///             were created, or, using the `ReserveSpotInQueue` command which
///             allows for encoding commands for submission in an order that is
///             different from the encoding order.
///
class CommandBuffer {
  friend class testing::CommandBufferMock;

 public:
  enum class Status {
    kPending,
    kError,
    kCompleted,
  };

  using CompletionCallback = std::function<void(Status)>;

  virtual ~CommandBuffer();

  virtual bool IsValid() const = 0;

  virtual void SetLabel(const std::string& label) const = 0;

  //----------------------------------------------------------------------------
  /// @brief      Schedule the command encoded by render passes within this
  ///             command buffer on the GPU. The encoding of these commnands is
  ///             performed immediately on the calling thread.
  ///
  ///             A command buffer may only be committed once.
  ///
  /// @param[in]  callback  The completion callback.
  ///
  [[nodiscard]] bool SubmitCommands(const CompletionCallback& callback);

  [[nodiscard]] bool SubmitCommands();

  //----------------------------------------------------------------------------
  /// @brief      Schedule the command encoded by render passes within this
  ///             command buffer on the GPU. The enqueing of this buffer is
  ///             performed immediately but encoding is pushed to a worker
  ///             thread if possible.
  ///
  ///             A command buffer may only be committed once.
  ///
  [[nodiscard]] virtual bool EncodeAndSubmit(
      const std::shared_ptr<RenderPass>& render_pass);

  //----------------------------------------------------------------------------
  /// @brief      Schedule the command encoded by blit passes within this
  ///             command buffer on the GPU. The enqueing of this buffer is
  ///             performed immediately but encoding is pushed to a worker
  ///             thread if possible.
  ///
  ///             A command buffer may only be committed once.
  ///
  [[nodiscard]] virtual bool EncodeAndSubmit(
      const std::shared_ptr<BlitPass>& blit_pass,
      const std::shared_ptr<Allocator>& allocator);

  //----------------------------------------------------------------------------
  /// @brief      Force execution of pending GPU commands.
  ///
  void WaitUntilScheduled();

  //----------------------------------------------------------------------------
  /// @brief      Create a render pass to record render commands into.
  ///
  /// @param[in]  render_target  The description of the render target this pass
  ///                            will target.
  ///
  /// @return     A valid render pass or null.
  ///
  std::shared_ptr<RenderPass> CreateRenderPass(
      const RenderTarget& render_target);

  //----------------------------------------------------------------------------
  /// @brief      Create a blit pass to record blit commands into.
  ///
  /// @return     A valid blit pass or null.
  ///
  std::shared_ptr<BlitPass> CreateBlitPass();

  //----------------------------------------------------------------------------
  /// @brief      Create a compute pass to record compute commands into.
  ///
  /// @return     A valid compute pass or null.
  ///
  std::shared_ptr<ComputePass> CreateComputePass();

 protected:
  std::weak_ptr<const Context> context_;

  explicit CommandBuffer(std::weak_ptr<const Context> context);

  virtual std::shared_ptr<RenderPass> OnCreateRenderPass(
      RenderTarget render_target) = 0;

  virtual std::shared_ptr<BlitPass> OnCreateBlitPass() = 0;

  [[nodiscard]] virtual bool OnSubmitCommands(CompletionCallback callback) = 0;

  virtual void OnWaitUntilScheduled() = 0;

  virtual std::shared_ptr<ComputePass> OnCreateComputePass() = 0;

 private:
  CommandBuffer(const CommandBuffer&) = delete;

  CommandBuffer& operator=(const CommandBuffer&) = delete;
};

}  // namespace impeller

#endif  // FLUTTER_IMPELLER_RENDERER_COMMAND_BUFFER_H_
