// 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 <unordered_map>
#include <vector>

#include "flutter/fml/macros.h"
#include "vulkan_surface.h"

namespace flutter {

class VulkanSurfacePool final {
 public:
  // Only keep 12 surfaces at a time.  This value was based on how many
  // surfaces got cached in the old, exact-match-only caching logic.
  static constexpr int kMaxSurfaces = 12;
  // If a surface doesn't get used for 3 or more generations, we discard it.
  static constexpr int kMaxSurfaceAge = 3;

  VulkanSurfacePool(vulkan::VulkanProvider& vulkan_provider,
                    sk_sp<GrContext> context, scenic::Session* scenic_session);

  ~VulkanSurfacePool();

  std::unique_ptr<VulkanSurface> AcquireSurface(const SkISize& size);

  void SubmitSurface(
      std::unique_ptr<flow::SceneUpdateContext::SurfaceProducerSurface>
          surface);

  void AgeAndCollectOldBuffers();

  // Shrink all oversized |VulkanSurfaces| in |available_surfaces_| to as
  // small as they can be.
  void ShrinkToFit();

  // For |VulkanSurfaceProducer::HasRetainedNode|.
  bool HasRetainedNode(const flow::LayerRasterCacheKey& key) const {
    return retained_surfaces_.find(key) != retained_surfaces_.end();
  }
  // For |VulkanSurfaceProducer::GetRetainedNode|.
  const scenic::EntityNode& GetRetainedNode(
      const flow::LayerRasterCacheKey& key)  {
    FML_DCHECK(HasRetainedNode(key));
    return retained_surfaces_[key].vk_surface->GetRetainedNode();
  }


 private:
  // Struct for retained_surfaces_ map.
  struct RetainedSurface {
    // If |is_pending| is true, the |vk_surface| is still under painting
    // (similar to those in |pending_surfaces_|) so we can't recycle the
    // |vk_surface| yet.
    bool is_pending;
    std::unique_ptr<VulkanSurface> vk_surface;
  };

  vulkan::VulkanProvider& vulkan_provider_;
  sk_sp<GrContext> context_;
  scenic::Session* scenic_session_;
  std::vector<std::unique_ptr<VulkanSurface>> available_surfaces_;
  std::unordered_map<uintptr_t, std::unique_ptr<VulkanSurface>>
      pending_surfaces_;

  // Retained surfaces keyed by the layer that created and used the surface.
  flow::LayerRasterCacheKey::Map<RetainedSurface>
      retained_surfaces_;

  size_t trace_surfaces_created_ = 0;
  size_t trace_surfaces_reused_ = 0;

  std::unique_ptr<VulkanSurface> GetCachedOrCreateSurface(const SkISize& size);

  std::unique_ptr<VulkanSurface> CreateSurface(const SkISize& size);

  void RecycleSurface(std::unique_ptr<VulkanSurface> surface);

  void RecyclePendingSurface(uintptr_t surface_key);

  // Clear the |is_pending| flag of the retained surface.
  void SignalRetainedReady(flow::LayerRasterCacheKey key);

  // Remove the corresponding surface from |retained_surfaces| and recycle it.
  // The surface must not be pending.
  void RecycleRetainedSurface(const flow::LayerRasterCacheKey& key);

  void TraceStats();

  FML_DISALLOW_COPY_AND_ASSIGN(VulkanSurfacePool);
};

}  // namespace flutter
