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

#pragma once

#include <memory>
#include "flutter/flow/scene_update_context.h"
#include "flutter/vulkan/vulkan_handle.h"
#include "flutter/vulkan/vulkan_proc_table.h"
#include "lib/fsl/tasks/message_loop.h"
#include "lib/fsl/tasks/message_loop_handler.h"
#include "lib/fxl/macros.h"
#include "lib/ui/scenic/client/resources.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/gpu/vk/GrVkBackendContext.h"
#include "zx/event.h"
#include "zx/vmo.h"

namespace flutter_runner {

class VulkanSurface : public flow::SceneUpdateContext::SurfaceProducerSurface,
                      public fsl::MessageLoopHandler {
 public:
  VulkanSurface(vulkan::VulkanProcTable& p_vk,
                sk_sp<GrContext> context,
                sk_sp<GrVkBackendContext> backend_context,
                scenic_lib::Session* session,
                const SkISize& size);

  ~VulkanSurface() override;

  size_t AdvanceAndGetAge() override;

  bool FlushSessionAcquireAndReleaseEvents() override;

  bool IsValid() const override;

  SkISize GetSize() const override;

  // Note: It is safe for the caller to collect the surface in the
  // |on_writes_committed| callback.
  void SignalWritesFinished(
      std::function<void(void)> on_writes_committed) override;

  // |flow::SceneUpdateContext::SurfaceProducerSurface|
  scenic_lib::Image* GetImage() override;

  // |flow::SceneUpdateContext::SurfaceProducerSurface|
  sk_sp<SkSurface> GetSkiaSurface() const override;

  // This transfers ownership of the GrBackendSemaphore but not the underlying
  // VkSemaphore (i.e. it is ok to let the returned GrBackendSemaphore go out of
  // scope but it is not ok to call VkDestroySemaphore on the underlying
  // VkSemaphore)
  GrBackendSemaphore GetAcquireSemaphore() const;

 private:
  vulkan::VulkanProcTable& vk_;
  sk_sp<GrVkBackendContext> backend_context_;
  scenic_lib::Session* session_;
  vulkan::VulkanHandle<VkImage> vk_image_;
  vulkan::VulkanHandle<VkDeviceMemory> vk_memory_;
  sk_sp<SkSurface> sk_surface_;
  std::unique_ptr<scenic_lib::Image> session_image_;
  zx::event acquire_event_;
  vulkan::VulkanHandle<VkSemaphore> acquire_semaphore_;
  zx::event release_event_;
  fsl::MessageLoop::HandlerKey event_handler_key_ = 0;
  std::function<void(void)> pending_on_writes_committed_;
  size_t age_ = 0;
  bool valid_ = false;

  // |fsl::MessageLoopHandler|
  void OnHandleReady(zx_handle_t handle,
                     zx_signals_t pending,
                     uint64_t count) override;

  bool AllocateDeviceMemory(sk_sp<GrContext> context,
                            const SkISize& size,
                            zx::vmo& exported_vmo);

  bool SetupSkiaSurface(sk_sp<GrContext> context,
                        const SkISize& size,
                        const VkImageCreateInfo& image_create_info,
                        const VkMemoryRequirements& memory_reqs);

  bool CreateFences();

  bool PushSessionImageSetupOps(scenic_lib::Session* session,
                                zx::vmo exported_vmo);

  void Reset();

  vulkan::VulkanHandle<VkSemaphore> SemaphoreFromEvent(
      const zx::event& event) const;

  FXL_DISALLOW_COPY_AND_ASSIGN(VulkanSurface);
};

}  // namespace flutter_runner
