// 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_runner {

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<flutter::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 flutter::LayerRasterCacheKey& key) const {
    return retained_surfaces_.find(key) != retained_surfaces_.end();
  }
  // For |VulkanSurfaceProducer::GetRetainedNode|.
  const scenic::EntityNode& GetRetainedNode(
      const flutter::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.
  flutter::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(flutter::LayerRasterCacheKey key);

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

  void TraceStats();

  FML_DISALLOW_COPY_AND_ASSIGN(VulkanSurfacePool);
};

}  // namespace flutter_runner
