// Copyright 2017 The Fuchsia 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 SRC_UI_LIB_ESCHER_RENDERER_FRAME_H_
#define SRC_UI_LIB_ESCHER_RENDERER_FRAME_H_

#include <lib/fit/function.h>

#include <cstdint>
#include <functional>

#include "src/ui/lib/escher/base/reffable.h"
#include "src/ui/lib/escher/forward_declarations.h"
#include "src/ui/lib/escher/impl/command_buffer.h"
#include "src/ui/lib/escher/profiling/timestamp_profiler.h"
#include "src/ui/lib/escher/renderer/uniform_block_allocator.h"
#include "src/ui/lib/escher/util/block_allocator.h"
#include "src/ui/lib/escher/vk/command_buffer.h"

#include <vulkan/vulkan.hpp>

namespace escher {

typedef fit::function<void()> FrameRetiredCallback;

class Frame;
using FramePtr = fxl::RefPtr<Frame>;

// Represents a single render pass on a command queue. There may be multiple
// frames issuing commands per render draw call. Frame is passed into a
// Renderer, which uses it to obtain command buffers, submit partial frames, do
// profiling, etc.
class Frame : public Resource {
 public:
  static const ResourceTypeInfo kTypeInfo;
  const ResourceTypeInfo& type_info() const override { return kTypeInfo; }

  ~Frame();

  // Submit the current CommandBuffer, and obtain a new CommandBuffer for subsequent commands.  If
  // |partial_frame_done| is not null, it will be signaled when the submitted CommandBuffer is
  // finished.
  void SubmitPartialFrame(const SemaphorePtr& partial_frame_done);

  // Submit the frame's final CommandBuffer.  When it is finished, |frame_done| will be signaled and
  // |frame_retired_callback| will be invoked; the latter occurs when the command-buffer is cleaned
  // up in Escher::Cleanup(), perhaps more than a millisecond later.
  void EndFrame(const SemaphorePtr& frame_done, FrameRetiredCallback frame_retired_callback);

  // Submit the frame's final CommandBuffer.  When it is finished, all of the semaphores in the
  // vector |semaphores| will signaled and |frame_retired_callback| will be invoked; the latter
  // occurs when the the command-buffer is cleaned up in Escher::Cleanup(), perhaps more than a
  // millisecond later.
  void EndFrame(const std::vector<SemaphorePtr>& semaphores,
                FrameRetiredCallback frame_retired_callback);

  // If profiling is enabled, inserts a Vulkan timestamp query into the frame's
  // current CommandBuffer; the result will be inserted into the trace log.
  // |stages| denotes the set of pipeline stages that must be completed by all
  // previously-issued commands; see TimestampProfiler docs for more details.
  void AddTimestamp(const char* name,
                    vk::PipelineStageFlagBits stages = vk::PipelineStageFlagBits::eBottomOfPipe);

  // See |CommandBuffer::DisableLazyPipelineCreation()|.  Disables lazy pipeline creation on the
  // frame's current and subsequent CommandBuffers.
  void DisableLazyPipelineCreation();

  uint64_t frame_number() const { return frame_number_; }

  CommandBuffer* cmds() const { return command_buffer_.get(); }
  vk::CommandBuffer vk_command_buffer() const;
  uint64_t command_buffer_sequence_number() const { return command_buffer_sequence_number_; }
  GpuAllocator* gpu_allocator();
  BlockAllocator* host_allocator() { return &block_allocator_; }

  // Allocate temporary CPU memory that is valid until EndFrame() is called.
  template <typename T>
  T* Allocate() {
    return block_allocator_.Allocate<T>();
  }

  // Allocate temporary CPU memory that is valid until EndFrame() is called.
  template <typename T>
  T* AllocateMany(size_t count) {
    return block_allocator_.AllocateMany<T>(count);
  }

  // Allocate temporary GPU uniform buffer memory that is valid until the frame is finished
  // rendering (after EndFrame() is called).
  UniformAllocation AllocateUniform(size_t size, size_t alignment) {
    return uniform_block_allocator_.Allocate(size, alignment);
  }

  bool use_protected_memory() const { return use_protected_memory_; }

 private:
  // These resources will be retained until the current frame is finished
  // running on the GPU.
  void KeepAlive(ResourcePtr resource);

  // Constructor called by Escher::NewFrame().
  // NOTE: moving the BlockAllocator into the Frame (instead of e.g. passing a
  // unique_ptr) avoids an extra pointer indirection on each allocation.
  friend class impl::FrameManager;
  Frame(impl::FrameManager* manager, CommandBuffer::Type requested_type, BlockAllocator allocator,
        impl::UniformBufferPoolWeakPtr uniform_buffer_pool, uint64_t frame_number,
        const char* trace_literal, const char* gpu_vthread_literal, uint64_t gpu_vthread_id,
        bool enable_gpu_logging, bool use_protected_memory);
  void BeginFrame();

  // Issues a new CommandBuffer for a frame, and marks the frame as InProgress.
  void IssueCommandBuffer();

  // Called by impl::FrameManager when the Frame is returned to the pool, so
  // that it can be reused in newly constructed frames.
  BlockAllocator TakeBlockAllocator() { return std::move(block_allocator_); }

  // Called by BatchGpuUploader and BatchGpuDownloader to write to the
  // new_command_buffer_ and gather work to post to the GPU.
  // TODO(fxbug.dev/24063) Remove these functions once BatchGpuUploader::Writers are
  // backed by secondary buffers, and the frame's primary command buffer is not
  // moved into the Writer.
  friend class BatchGpuUploader;
  friend class BatchGpuDownloader;
  CommandBufferPtr TakeCommandBuffer();
  void PutCommandBuffer(CommandBufferPtr command_buffer);

  enum class State {
    kReadyToBegin,
    kInProgress,
    kFinishing,
  };

  State state_ = State::kReadyToBegin;

  // The frame number associated with this frame. Used to correlate work across
  // threads for tracing events.
  const uint64_t frame_number_;
  // A unique number to identify this escher frame. It can diverge from
  // frame_number_, as frame_number_ is used by the client for its own tracking.
  const uint64_t escher_frame_number_;
  // A string constant that is the name of the trace event this frame will
  // generate.
  const char* trace_literal_;
  // A string constant that is the name of the virtual thread this frame
  // generates events for.
  const char* gpu_vthread_literal_;
  // A unique identifier for the virtual thread this frame generates events for.
  const uint64_t gpu_vthread_id_;
  bool enable_gpu_logging_;
  bool use_protected_memory_;
  vk::Queue queue_;

  CommandBuffer::Type command_buffer_type_;
  // The sequence number of the command_buffer managed by this frame. Cached
  // here to track which command_buffer was managed by this frame if the command
  // buffer was taken (via TakeCommandBuffer()) for GPU uploads.
  uint64_t command_buffer_sequence_number_;
  CommandBufferPtr command_buffer_;

  BlockAllocator block_allocator_;

  // TODO(fxbug.dev/42570): investigate whether this memory is host-coherent, and whether it should be
  // (it seems like it isn't and should be).  Document the usage guarantees/requirements in
  // AllocateUniform(), above.
  UniformBlockAllocator uniform_block_allocator_;

  TimestampProfilerPtr profiler_;
  uint32_t submission_count_ = 0;

  // TODO(fxbug.dev/7194): ideally we can move away from explicitly retaining used
  // resources in the Frame.  For now, this approach is easy and relatively
  // fool-proof.
  std::vector<ResourcePtr> keep_alive_;

  bool disable_lazy_pipeline_creation_ = false;
};

}  // namespace escher

#endif  // SRC_UI_LIB_ESCHER_RENDERER_FRAME_H_
