// Copyright 2020 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_BATCH_GPU_DOWNLOADER_H_
#define SRC_UI_LIB_ESCHER_RENDERER_BATCH_GPU_DOWNLOADER_H_

#include <lib/fit/function.h>

#include <variant>

#include "src/ui/lib/escher/escher.h"
#include "src/ui/lib/escher/renderer/buffer_cache.h"
#include "src/ui/lib/escher/renderer/frame.h"
#include "src/ui/lib/escher/third_party/granite/vk/command_buffer.h"
#include "src/ui/lib/escher/vk/buffer.h"
#include "src/ui/lib/escher/vk/command_buffer.h"

#include <vulkan/vulkan.hpp>

namespace escher {

// Provides host-accessible GPU memory for clients to download Images and
// Buffers from the GPU to host memory. Offers the ability to batch downloads
// into consolidated submissions to the GPU driver.
//
// About synchronization:
//   We use semaphore (usually generated by ChainedSemaphoreGenerator) for
// synchronization between BatchGpuDownloader/Uploader and other gfx components,
// so we only need the barrier to synchronize all transfer-related commands.
//
//   Currently users of BatchGpuDownloader should manually enforce that
// the BatchGpuDownloader waits on other BatchGpuUploader or gfx::Engine if they
// write to the images / buffers the BatchGpuDownloader reads from, by using
// AddWaitSemaphore() function. Also, Submit() function will return a semaphore
// being signaled when command buffer finishes execution, which can be used for
// synchronization.
//
// TODO(fxbug.dev/24401) Add memory barriers so the BatchGpuUploader and
// BatchGpuDownloader can handle synchronzation of reads and writes on the same
// Resource.
//
class BatchGpuDownloader {
 public:
  // Called after download is complete, with a pointer into the downloaded data.
  using Callback = fit::function<void(const void* host_ptr, size_t size)>;

 public:
  static std::unique_ptr<BatchGpuDownloader> New(
      EscherWeakPtr weak_escher,
      CommandBuffer::Type command_buffer_type = CommandBuffer::Type::kTransfer,
      uint64_t frame_trace_number = 0);

  BatchGpuDownloader(EscherWeakPtr weak_escher,
                     CommandBuffer::Type command_buffer_type = CommandBuffer::Type::kTransfer,
                     uint64_t frame_trace_number = 0);
  ~BatchGpuDownloader();

  // Returns true if the BatchGpuDownloader has work to do on the GPU.
  bool HasContentToDownload() const { return !copy_info_records_.empty(); }

  // Returns true if BatchGpuDownloader needs a command buffer, i.e. it needs to
  // downloading images/buffers, or it needs to wait on/signal semaphores.
  bool NeedsCommandBuffer() const {
    return HasContentToDownload() || !wait_semaphores_.empty() || !signal_semaphores_.empty();
  }

  // Schedule a buffer-to-buffer copy that will be submitted when Submit()
  // is called.  Retains a reference to the source until the submission's
  // CommandBuffer is retired.
  //
  // |source_offset| is the starting offset in bytes from the start of the
  //   source buffer.
  // |copy_size| is the size to be copied to the buffer.
  //
  // These arguments are used to build VkBufferCopy struct.  See the Vulkan
  // specs of VkBufferCopy for more details. If copy_size is set to 0 by
  // default, it copies all the contents from source.
  void ScheduleReadBuffer(const BufferPtr& source, Callback callback,
                          vk::DeviceSize source_offset = 0U, vk::DeviceSize copy_size = 0U);

  // Schedule a image-to-buffer copy that will be submitted when Submit()
  // is called.  Retains a reference to the source until the submission's
  // CommandBuffer is retired.
  //
  // |region| specifies the buffer region which will be copied to the target
  // image.
  //   |region.bufferOffset| should be set to zero since target buffer is
  //   managed internally by the uploader; currently |imageOffset| requires to
  //   be zero and |imageExtent| requires to be the whole image.
  // The default value of |region| is vk::BufferImageCopy(), in which case we
  // create a default copy region which reads the color data from the whole
  // image with only one mipmap layer.
  //
  // |write_function| is a callback function which will be called at
  // GenerateCommands(), where we copy our data to the host-visible buffer.
  void ScheduleReadImage(const ImagePtr& source, Callback callback,
                         vk::BufferImageCopy region = vk::BufferImageCopy());

  // Submits all pending work to the given CommandBuffer. Users need to call
  // cmds->Submit() after calling this function. Returns a lambda function
  // which calls all the callback functions we passed in to ScheduleReadBuffer
  // and ScheduleReadImage functions; this function should be called after the
  // command buffer has finished execution, typically by passing it to
  // cmds->Submit().
  //
  // After this function is called, all the contents in |copy_info_records|,
  // staged |resources_| and semaphores will be moved to the lambda function
  // and the downloader will be cleaned and ready for reuse.
  //
  // The argument |cmds| cannot be nullptr if there is any pending work,
  // including writing to buffer/images and waiting on/signaling semaphores.
  CommandBufferFinishedCallback GenerateCommands(CommandBuffer* cmds);

  // Submits all pending work to the GPU.
  // The function |callback|, and all callback functions the user passed to
  // ScheduleReadBuffer and ScheduleReadImage, will be called after all work
  // is done.
  //
  // After this function is called, all the contents in |copy_info_records|,
  // staged |resources_| and semaphores will be moved to the lambda function
  // and the downloader will be cleaned and ready for reuse.
  void Submit(CommandBufferFinishedCallback client_callback = nullptr);

  // Submit() and GenerateCommands() will wait on all semaphores added by
  // AddWaitSemaphore().
  void AddWaitSemaphore(SemaphorePtr sema, vk::PipelineStageFlags flags) {
    wait_semaphores_.push_back({std::move(sema), flags});
  }

  // Submit() and GenerateCommands() will signals all semaphores added by
  // AddSignalSemaphore().
  void AddSignalSemaphore(SemaphorePtr sema) { signal_semaphores_.push_back(std::move(sema)); }

 private:
  enum class CopyType { COPY_IMAGE = 0, COPY_BUFFER = 1 };
  struct ImageCopyInfo {
    ImagePtr source;
    vk::BufferImageCopy region;
  };
  struct BufferCopyInfo {
    BufferPtr source;
    vk::BufferCopy region;
  };
  using CopyInfoVariant = std::variant<ImageCopyInfo, BufferCopyInfo>;
  struct CopyInfo {
    CopyType type;
    vk::DeviceSize offset;
    vk::DeviceSize size;
    Callback callback;
    // copy_info can either be a ImageCopyInfo or a BufferCopyInfo.
    CopyInfoVariant copy_info;
  };

  EscherWeakPtr escher_;

  CommandBuffer::Type command_buffer_type_ = CommandBuffer::Type::kTransfer;
  // The trace number for the frame. Cached to support lazy frame creation.
  const uint64_t frame_trace_number_;
  BufferCacheWeakPtr buffer_cache_;

  vk::DeviceSize current_offset_ = 0U;

  std::vector<CopyInfo> copy_info_records_;
  std::vector<ResourcePtr> resources_;

  std::vector<std::pair<SemaphorePtr, vk::PipelineStageFlags>> wait_semaphores_;
  std::vector<SemaphorePtr> signal_semaphores_;

  FXL_DISALLOW_COPY_AND_ASSIGN(BatchGpuDownloader);
};

}  // namespace escher

#endif  // SRC_UI_LIB_ESCHER_RENDERER_BATCH_GPU_DOWNLOADER_H_
