blob: b0009638b791b85a82be1fe4d23b7b3318d6fda9 [file] [log] [blame]
// 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