// 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 <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) {
    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();
    });
    loop_.StartThread();
    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 { loop_.Shutdown(); }

  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<zx::event> acquire_fences,
                    std::vector<zx::event> release_fences) 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_
