// 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_LIB_VULKAN_SWAPCHAIN_IMAGE_PIPE_SURFACE_ASYNC_H_
#define SRC_LIB_VULKAN_SWAPCHAIN_IMAGE_PIPE_SURFACE_ASYNC_H_

#include <fuchsia/sysmem/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/async/cpp/task.h>

#include <mutex>
#include <thread>
#include <unordered_map>

#include "image_pipe_surface.h"

namespace image_pipe_swapchain {

// An implementation of ImagePipeSurface based on an async fidl ImagePipe.
class ImagePipeSurfaceAsync : public ImagePipeSurface {
 public:
  explicit ImagePipeSurfaceAsync(zx_handle_t image_pipe_handle)
      : loop_(&kAsyncLoopConfigNoAttachToCurrentThread) {
    loop_.StartThread();
    async::PostTask(loop_.dispatcher(), [this, image_pipe_handle] {
      // image_pipe_ is thread hostile so it must be bound on the thread
      // that will use it.
      image_pipe_.Bind(zx::channel(image_pipe_handle), loop_.dispatcher());
      image_pipe_.set_error_handler([this](zx_status_t status) {
        std::lock_guard<std::mutex> lock(mutex_);
        channel_closed_ = true;
        queue_.clear();
      });
    });
    std::vector<VkSurfaceFormatKHR> formats(
        {{VK_FORMAT_R8G8B8A8_UNORM, VK_COLORSPACE_SRGB_NONLINEAR_KHR},
         {VK_FORMAT_R8G8B8A8_SRGB, VK_COLORSPACE_SRGB_NONLINEAR_KHR},
         {VK_FORMAT_B8G8R8A8_UNORM, VK_COLORSPACE_SRGB_NONLINEAR_KHR},
         {VK_FORMAT_B8G8R8A8_SRGB, VK_COLORSPACE_SRGB_NONLINEAR_KHR}});
    supported_image_properties_ = {formats};
  }

  ~ImagePipeSurfaceAsync() override {
    async::PostTask(loop_.dispatcher(), [this] {
      // image_pipe_ is thread hostile so it must be turn down on the thread
      // that will use it.
      image_pipe_ = nullptr;
      loop_.Quit();
    });
    loop_.JoinThreads();
  }

  bool Init() override;

  bool IsLost() override;
  bool CreateImage(VkDevice device, VkLayerDispatchTable* pDisp, VkFormat format,
                   VkImageUsageFlags usage, VkSwapchainCreateFlagsKHR swapchain_flags,
                   VkExtent2D extent, uint32_t image_count, const VkAllocationCallbacks* pAllocator,
                   std::vector<ImageInfo>* image_info_out) override;

  void RemoveImage(uint32_t image_id) override;

  void PresentImage(uint32_t image_id, std::vector<std::unique_ptr<PlatformEvent>> acquire_fences,
                    std::vector<std::unique_ptr<PlatformEvent>> release_fences,
                    VkQueue queue) override;

  SupportedImageProperties& GetSupportedImageProperties() override;

 private:
  class FenceSignaler {
   public:
    explicit FenceSignaler(zx::event event) : event_(std::move(event)) {}
    ~FenceSignaler() {
      if (event_)
        event_.signal(0, ZX_EVENT_SIGNALED);
    }
    const zx::event& event() { return event_; }
    void reset() { event_.reset(); }

   private:
    zx::event event_;
  };

  // Called on the async loop.
  void PresentNextImageLocked() __attribute__((requires_capability(mutex_)));

  async::Loop loop_;
  std::mutex mutex_;

  // Can only be accessed from the async loop's thread.
  fuchsia::images::ImagePipe2Ptr image_pipe_;

  uint32_t current_buffer_id_ = 0;
  std::unordered_map</*image_id=*/uint32_t, /*buffer_id=*/uint32_t> image_id_to_buffer_id_;
  std::unordered_map</*buffer_id=*/uint32_t, /*image count=*/uint32_t> buffer_counts_;

  struct PendingPresent {
    uint32_t image_id;
    std::vector<zx::event> acquire_fences;
    // These fences will automatically be signaled when they go out of scope, which could happen if
    // the ImagePipe channel is closed. As these events are passed to the application as acquire
    // semaphores, this prevents semaphore waits on them from hanging until the GPU driver decides
    // to time them out.
    // The only case where we don't automatically signal them is if the PresentImage callback is
    // run, in which case scenic is responsible for signaling them.
    std::vector<std::unique_ptr<FenceSignaler>> release_fences;
  };
  std::vector<PendingPresent> queue_ __attribute__((guarded_by(mutex_)));
  bool present_pending_ __attribute__((guarded_by(mutex_))) = false;
  fuchsia::sysmem::AllocatorSyncPtr sysmem_allocator_;
  SupportedImageProperties supported_image_properties_;
  bool channel_closed_ __attribute__((guarded_by(mutex_))) = false;
};

}  // namespace image_pipe_swapchain

#endif  // SRC_LIB_VULKAN_SWAPCHAIN_IMAGE_PIPE_SURFACE_ASYNC_H_
