// Copyright 2016 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_ESCHER_H_
#define SRC_UI_LIB_ESCHER_ESCHER_H_

#include <memory>

#include "src/lib/fxl/macros.h"
#include "src/lib/fxl/memory/weak_ptr.h"
#include "src/ui/lib/escher/forward_declarations.h"
#include "src/ui/lib/escher/impl/image_cache.h"
#include "src/ui/lib/escher/shape/mesh_builder_factory.h"
#include "src/ui/lib/escher/status.h"
#include "src/ui/lib/escher/util/hash.h"
#include "src/ui/lib/escher/util/hash_map.h"
#include "src/ui/lib/escher/vk/chained_semaphore_generator.h"
#include "src/ui/lib/escher/vk/command_buffer.h"
#include "src/ui/lib/escher/vk/shader_program_factory.h"
#include "src/ui/lib/escher/vk/vulkan_context.h"
#include "src/ui/lib/escher/vk/vulkan_device_queues.h"

namespace escher {

// Escher is the primary class used by clients of the Escher library.
//
// Escher is currently not thread-safe; it (and all objects obtained from it)
// must be used from a single thread.
class Escher final : public MeshBuilderFactory, public ShaderProgramFactory {
 public:
  // Escher does not take ownership of the objects in the Vulkan context.  It is
  // up to the application to eventually destroy them, and also to ensure that
  // they outlive the Escher instance.
  explicit Escher(VulkanDeviceQueuesPtr device);
  // If |gpu_allocator| is nullptr, a default allocator will be created.
  Escher(VulkanDeviceQueuesPtr device, HackFilesystemPtr filesystem,
         std::shared_ptr<GpuAllocator> gpu_allocator);
  ~Escher();

  EscherWeakPtr GetWeakPtr() { return weak_factory_.GetWeakPtr(); }

  // Implement MeshBuilderFactory interface.
  MeshBuilderPtr NewMeshBuilder(BatchGpuUploader* gpu_uploader, const MeshSpec& spec,
                                size_t max_vertex_count, size_t max_index_count) override;

  // Return new Image containing the provided pixels.
  ImagePtr NewRgbaImage(BatchGpuUploader* gpu_uploader, uint32_t width, uint32_t height,
                        const uint8_t* bytes);
  // Returns RGBA image.
  ImagePtr NewCheckerboardImage(BatchGpuUploader* gpu_uploader, uint32_t width, uint32_t height);
  // Returns RGBA image.
  ImagePtr NewGradientImage(BatchGpuUploader* gpu_uploader, uint32_t width, uint32_t height);
  // Returns single-channel luminance image.
  ImagePtr NewNoiseImage(BatchGpuUploader* gpu_uploader, uint32_t width, uint32_t height);
  // Return a new Frame, which is passed to Renderers to obtain and submit
  // command buffers, to add timestamps for GPU profiling, etc.  If
  // |enable_gpu_logging| is true, GPU profiling timestamps will be logged via
  // FX_LOGS().
  FramePtr NewFrame(
      const char* trace_literal, uint64_t frame_number, bool enable_gpu_logging = false,
      escher::CommandBuffer::Type requested_type = escher::CommandBuffer::Type::kGraphics,
      bool use_protected_memory = false);

  // Construct a new Texture, which encapsulates a newly-created VkImageView and
  // VkSampler.  |aspect_mask| is used to create the VkImageView, and |filter|
  // and |use_unnormalized_coordinates| are used to create the VkSampler.
  TexturePtr NewTexture(ImagePtr image, vk::Filter filter,
                        vk::ImageAspectFlags aspect_mask = vk::ImageAspectFlagBits::eColor,
                        bool use_unnormalized_coordinates = false);

  // Construct a new Texture, which encapsulates a newly-created VkImage,
  // VkImageView and VkSampler.  |aspect_mask| is used to create the
  // VkImageView, and |filter| and |use_unnormalized_coordinates| are used to
  // create the VkSampler.
  TexturePtr NewTexture(vk::Format format, uint32_t width, uint32_t height, uint32_t sample_count,
                        vk::ImageUsageFlags usage_flags, vk::Filter filter,
                        vk::ImageAspectFlags aspect_flags,
                        bool use_unnormalized_coordinates = false,
                        vk::MemoryPropertyFlags memory_flags = vk::MemoryPropertyFlags());

  // Construct a new Buffer, which encapsulates a newly-created VkBuffer.
  // |usage_flags| defines whether it is to be used as e.g. a uniform and/or a
  // vertex buffer, and |memory_property_flags| is used to select the heap that
  // the buffer's backing VkDeviceMemory is allocated from.
  BufferPtr NewBuffer(vk::DeviceSize size, vk::BufferUsageFlags usage_flags,
                      vk::MemoryPropertyFlags memory_property_flags);

  // Same as the NewTexture() variant that creates the image, except that it
  // automatically sets up the vk::ImageAspectFlags, and adds the following to
  // |additional_usage_flags|:
  //   - either eColorAttachment or eDepthAttachment, depending on |format|
  //   - optionally eTransientAttachment, depending on |is_transient|
  //   - optionally eInputAttachment, depending on |is_input|
  TexturePtr NewAttachmentTexture(
      vk::Format format, uint32_t width, uint32_t height, uint32_t sample_count, vk::Filter filter,
      vk::ImageUsageFlags additional_usage_flags = vk::ImageUsageFlags(),
      bool use_unnormalized_coordinates = false,
      vk::MemoryPropertyFlags memory_flags = vk::MemoryPropertyFlags());

  uint64_t GetNumGpuBytesAllocated();

  // Do periodic housekeeping.  This is called by Renderer::EndFrame(), so you
  // don't need to call it if your application is constantly rendering.
  // However, if your app enters a "quiet period" then you might want to
  // arrange to call Cleanup() after the last frame has finished rendering.
  // Return true if cleanup was complete, and false if more cleanup remains
  // (in that case, the app should wait a moment before calling Cleanup()
  // again).
  bool Cleanup();

  // Allow clients to set the pipeline builder; if this isn't called then Escher will use a
  // default builder.
  void set_pipeline_builder(std::unique_ptr<PipelineBuilder> pipeline_builder);

  VulkanDeviceQueues* device() const { return device_.get(); }
  vk::Device vk_device() const { return device_->vk_device(); }
  vk::PhysicalDevice vk_physical_device() const { return device_->vk_physical_device(); }
  const VulkanContext& vulkan_context() const { return vulkan_context_; }

  ResourceRecycler* resource_recycler() { return resource_recycler_.get(); }
  GpuAllocator* gpu_allocator() { return gpu_allocator_.get(); }
  impl::CommandBufferSequencer* command_buffer_sequencer() {
    return command_buffer_sequencer_.get();
  }

#if ESCHER_USE_RUNTIME_GLSL
  shaderc::Compiler* shaderc_compiler() { return shaderc_compiler_.get(); }
#endif

  ImageFactory* image_cache() { return image_cache_.get(); }
  BufferCache* buffer_cache() { return buffer_cache_.get(); }
  SamplerCache* sampler_cache() { return sampler_cache_.get(); }
  impl::MeshManager* mesh_manager() { return mesh_manager_.get(); }
  impl::PipelineLayoutCache* pipeline_layout_cache() { return pipeline_layout_cache_.get(); }
  impl::DescriptorSetAllocatorCache* descriptor_set_allocator_cache() {
    return descriptor_set_allocator_cache_.get();
  }
  impl::RenderPassCache* render_pass_cache() const { return render_pass_cache_.get(); }
  impl::FramebufferAllocator* framebuffer_allocator() const { return framebuffer_allocator_.get(); }
  ImageViewAllocator* image_view_allocator() const { return image_view_allocator_.get(); }
  ChainedSemaphoreGenerator* semaphore_chain() const { return semaphore_chain_.get(); }

  // Pool for CommandBuffers submitted on the main queue.
  impl::CommandBufferPool* command_buffer_pool() { return command_buffer_pool_.get(); }
  // Pool for CommandBuffers submitted on the transfer queue (if one exists).
  impl::CommandBufferPool* transfer_command_buffer_pool() {
    return transfer_command_buffer_pool_.get();
  }
  // Pool for CommandBuffers submitted in a protected context.
  impl::CommandBufferPool* protected_command_buffer_pool();

  DefaultShaderProgramFactory* shader_program_factory() { return shader_program_factory_.get(); }

  PipelineBuilder* pipeline_builder() const { return pipeline_builder_.get(); }

  // Check if GPU performance profiling is supported.
  bool supports_timer_queries() const { return supports_timer_queries_; }
  float timestamp_period() const { return timestamp_period_; }
  bool supports_wireframe() const { return device_->caps().enabled_features.fillModeNonSolid; }
  bool allow_protected_memory() const { return device_->caps().allow_protected_memory; }
  bool allow_ycbcr() const { return device_->caps().allow_ycbcr; }

 private:
  // |ShaderProgramFactory|
  ShaderProgramPtr GetProgramImpl(const std::string shader_paths[EnumCount<ShaderStage>()],
                                  ShaderVariantArgs args) override;

  VulkanDeviceQueuesPtr device_;
  VulkanContext vulkan_context_;

  // These can be constructed without an EscherWeakPtr.
  std::shared_ptr<GpuAllocator> gpu_allocator_;
  std::unique_ptr<impl::CommandBufferSequencer> command_buffer_sequencer_;
  std::unique_ptr<impl::CommandBufferPool> command_buffer_pool_;
  std::unique_ptr<impl::CommandBufferPool> transfer_command_buffer_pool_;
  std::unique_ptr<impl::CommandBufferPool> protected_command_buffer_pool_;

#if ESCHER_USE_RUNTIME_GLSL
  std::unique_ptr<shaderc::Compiler> shaderc_compiler_;
#endif

  // Everything below this point requires |weak_factory_| to be initialized
  // before they can be constructed.

  std::unique_ptr<ResourceRecycler> resource_recycler_;
  std::unique_ptr<impl::ImageCache> image_cache_;
  std::unique_ptr<BufferCache> buffer_cache_;
  std::unique_ptr<SamplerCache> sampler_cache_;
  std::unique_ptr<impl::MeshManager> mesh_manager_;
  std::unique_ptr<DefaultShaderProgramFactory> shader_program_factory_;
  std::unique_ptr<PipelineBuilder> pipeline_builder_;

  std::unique_ptr<impl::DescriptorSetAllocatorCache> descriptor_set_allocator_cache_;
  std::unique_ptr<impl::PipelineLayoutCache> pipeline_layout_cache_;

  std::unique_ptr<impl::RenderPassCache> render_pass_cache_;
  std::unique_ptr<impl::FramebufferAllocator> framebuffer_allocator_;
  std::unique_ptr<ImageViewAllocator> image_view_allocator_;
  std::unique_ptr<impl::FrameManager> frame_manager_;

  std::unique_ptr<ChainedSemaphoreGenerator> semaphore_chain_;

  bool supports_timer_queries_ = false;
  float timestamp_period_ = 0.f;

  fxl::WeakPtrFactory<Escher> weak_factory_;  // must be last

  FXL_DISALLOW_COPY_AND_ASSIGN(Escher);
};

using EscherUniquePtr = std::unique_ptr<Escher, std::function<void(Escher*)>>;

}  // namespace escher

#endif  // SRC_UI_LIB_ESCHER_ESCHER_H_
