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

#include "src/ui/lib/escher/renderer/batch_gpu_downloader.h"

#include <lib/fit/function.h>
#include <lib/syslog/cpp/macros.h>

#include <variant>

#include "src/ui/lib/escher/forward_declarations.h"
#include "src/ui/lib/escher/impl/vulkan_utils.h"
#include "src/ui/lib/escher/renderer/batch_gpu_uploader.h"
#include "src/ui/lib/escher/util/align.h"
#include "src/ui/lib/escher/util/trace_macros.h"

namespace escher {

namespace {

// Vulkan specs requires that bufferOffset in VkBufferImageCopy be multiple of
// 4, so we enforce that all buffer offsets (including buffers and images) align
// to multiples of 4 by aligning up the addresses.
constexpr vk::DeviceSize kByteAlignment = 4;

}  // namespace

std::unique_ptr<BatchGpuDownloader> BatchGpuDownloader::New(EscherWeakPtr weak_escher,
                                                            CommandBuffer::Type command_buffer_type,
                                                            uint64_t frame_trace_number) {
  if (!weak_escher) {
    // This class is not functional without a valid escher.
    FX_LOGS(WARNING) << "Error, creating a BatchGpuDownloader without an escher.";
    return nullptr;
  }
  return std::make_unique<BatchGpuDownloader>(std::move(weak_escher), command_buffer_type,
                                              frame_trace_number);
}

BatchGpuDownloader::BatchGpuDownloader(EscherWeakPtr weak_escher,
                                       CommandBuffer::Type command_buffer_type,
                                       uint64_t frame_trace_number)
    : escher_(std::move(weak_escher)),
      command_buffer_type_(command_buffer_type),
      frame_trace_number_(frame_trace_number),
      buffer_cache_(escher_->buffer_cache()->GetWeakPtr()) {
  FX_DCHECK(escher_);
  FX_DCHECK(buffer_cache_);
}

BatchGpuDownloader::~BatchGpuDownloader() {
  FX_CHECK(resources_.empty() && copy_info_records_.empty() && wait_semaphores_.empty() &&
           signal_semaphores_.empty() && current_offset_ == 0U);
}

void BatchGpuDownloader::ScheduleReadBuffer(const BufferPtr& source,
                                            BatchGpuDownloader::Callback callback,
                                            vk::DeviceSize source_offset,
                                            vk::DeviceSize copy_size) {
  TRACE_DURATION("gfx", "escher::BatchGpuDownloader::ScheduleReadBuffer");
  vk::DeviceSize dst_offset = AlignedToNext(current_offset_, kByteAlignment);
  copy_size = copy_size == 0U ? source->size() : copy_size;
  auto region = vk::BufferCopy(source_offset, dst_offset, copy_size);

  copy_info_records_.push_back(
      CopyInfo{.type = CopyType::COPY_BUFFER,
               .offset = dst_offset,
               .size = region.size,
               .callback = std::move(callback),
               .copy_info = BufferCopyInfo{.source = source, .region = region}});
  current_offset_ = dst_offset + copy_info_records_.back().size;
  resources_.push_back(source);
}

void BatchGpuDownloader::ScheduleReadImage(const ImagePtr& source,
                                           BatchGpuDownloader::Callback callback,
                                           vk::BufferImageCopy region) {
  if (region == vk::BufferImageCopy()) {
    region = impl::GetDefaultBufferImageCopy(source->width(), source->height());
  }
  FX_DCHECK(region.bufferOffset == 0U);

  // For now we expect that we only accept full image to be downloadable.
  FX_DCHECK(region.imageOffset == vk::Offset3D(0, 0, 0) &&
            region.imageExtent == vk::Extent3D(source->width(), source->height(), 1U));

  TRACE_DURATION("gfx", "escher::BatchGpuDownloader::ScheduleReadImage");
  vk::DeviceSize dst_offset = AlignedToNext(current_offset_, kByteAlignment);
  auto final_region = region;
  final_region.setBufferOffset(dst_offset);

  copy_info_records_.push_back(
      CopyInfo{.type = CopyType::COPY_IMAGE,
               .offset = dst_offset,
               // TODO(add a bug) Use the size calculated from region.
               .size = source->size(),
               .callback = std::move(callback),
               .copy_info = ImageCopyInfo{.source = source, .region = final_region}});
  current_offset_ = dst_offset + copy_info_records_.back().size;
  resources_.push_back(source);
}

CommandBufferFinishedCallback BatchGpuDownloader::GenerateCommands(CommandBuffer* cmds) {
  if (!NeedsCommandBuffer()) {
    return []() {};
  }

  TRACE_DURATION("gfx", "BatchGpuDownloader::GenerateCommands");
  // Check existence of command buffer and buffer cache.
  FX_DCHECK(cmds);

  // We only create the target_buffer if we need to download something.
  // If we only need to create an empty command buffer (to signal / wait on
  // semaphores), we won't need the buffer.
  BufferPtr target_buffer = BufferPtr();
  if (HasContentToDownload()) {
    // Create a large buffer to store all images / buffers to be downloaded.
    vk::DeviceSize buffer_size = copy_info_records_.back().offset + copy_info_records_.back().size;
    target_buffer = buffer_cache_->NewHostBuffer(buffer_size);
    FX_DCHECK(target_buffer) << "Error allocating buffer";
    cmds->KeepAlive(target_buffer);
  }

  // Set up pipeline flags and access flags for synchronization. See class
  // comments for details.
  constexpr auto kPipelineFlag = vk::PipelineStageFlagBits::eTransfer;
  const auto kAccessFlagOutside =
      vk::AccessFlagBits::eTransferRead | vk::AccessFlagBits::eTransferWrite;
  const auto kAccessFlagInside = vk::AccessFlagBits::eTransferRead;

  for (const auto& copy_info_record : copy_info_records_) {
    switch (copy_info_record.type) {
      case CopyType::COPY_IMAGE: {
        const auto* image_copy_info = std::get_if<ImageCopyInfo>(&copy_info_record.copy_info);
        FX_DCHECK(image_copy_info);

        ImagePtr source = image_copy_info->source;
        auto target_layout = source->is_layout_initialized()
                                 ? source->layout()
                                 : vk::ImageLayout::eShaderReadOnlyOptimal;

        cmds->ImageBarrier(source, source->layout(), vk::ImageLayout::eTransferSrcOptimal,
                           kPipelineFlag, kAccessFlagOutside, kPipelineFlag, kAccessFlagInside);
        cmds->vk().copyImageToBuffer(source->vk(), vk::ImageLayout::eTransferSrcOptimal,
                                     target_buffer->vk(), 1, &image_copy_info->region);
        cmds->ImageBarrier(source, vk::ImageLayout::eTransferSrcOptimal, target_layout,
                           kPipelineFlag, kAccessFlagInside, kPipelineFlag, kAccessFlagOutside);
        cmds->KeepAlive(source);
        break;
      }
      case CopyType::COPY_BUFFER: {
        const auto* buffer_copy_info = std::get_if<BufferCopyInfo>(&copy_info_record.copy_info);
        FX_DCHECK(buffer_copy_info);

        cmds->BufferBarrier(buffer_copy_info->source, kPipelineFlag, kAccessFlagOutside,
                            kPipelineFlag, kAccessFlagInside);
        cmds->vk().copyBuffer(buffer_copy_info->source->vk(), target_buffer->vk(), 1,
                              &buffer_copy_info->region);
        cmds->BufferBarrier(buffer_copy_info->source, kPipelineFlag, kAccessFlagInside,
                            kPipelineFlag, kAccessFlagOutside);
        cmds->KeepAlive(buffer_copy_info->source);
        break;
      }
    }
  }

  // Add semaphores for the submitted command buffer to wait on / signal.
  for (auto& pair : wait_semaphores_) {
    cmds->AddWaitSemaphore(std::move(pair.first), pair.second);
  }
  wait_semaphores_.clear();

  for (auto& sem : signal_semaphores_) {
    cmds->AddSignalSemaphore(std::move(sem));
  }
  signal_semaphores_.clear();

  // Since we keep the target alive using CommandBuffer, we can remove these
  // RefPtrs from |resources_| right now.
  resources_.clear();
  current_offset_ = 0U;

  // The target buffer will be moved to the callback function so it will be
  // still alive until this function gets called.
  // |copy_info_records_| is guaranteed to be cleared after being moved to
  // |readers_info|.
  return
      [target_buffer = std::move(target_buffer), readers_info = std::move(copy_info_records_)]() {
        for (const auto& reader_info : readers_info) {
          reader_info.callback(target_buffer->host_ptr() + reader_info.offset, reader_info.size);
        }
      };
}

void BatchGpuDownloader::Submit(CommandBufferFinishedCallback client_callback) {
  if (!NeedsCommandBuffer()) {
    // This downloader was never used, nothing to submit.
    if (client_callback) {
      client_callback();
    }
    return;
  }

  TRACE_DURATION("gfx", "BatchGpuDownloader::Submit");

  // Create new command buffer.
  FramePtr frame = escher_->NewFrame("Gpu Downloader", frame_trace_number_,
                                     /*enable_gpu_logging=*/false, command_buffer_type_,
                                     /*use_protected_memory=*/false);

  // Add commands to |frame|'s command buffer.
  CommandBufferFinishedCallback reader_callback = GenerateCommands(frame->cmds());

  // Submit the command buffer.
  frame->EndFrame(SemaphorePtr(), [client_callback = std::move(client_callback),
                                   reader_callback = std::move(reader_callback)]() {
    if (reader_callback) {
      reader_callback();
    }
    if (client_callback) {
      client_callback();
    }
  });

  // Verify that everything is reset so that the downloader can be reused as
  // though new.
  FX_CHECK(resources_.empty() && copy_info_records_.empty() && wait_semaphores_.empty() &&
           signal_semaphores_.empty() && current_offset_ == 0U);
}

}  // namespace escher
