1 // Copyright 2013 The Flutter Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #pragma once 6 7 #include <unordered_map> 8 #include <vector> 9 10 #include "flutter/fml/macros.h" 11 #include "vulkan_surface.h" 12 13 namespace flutter_runner { 14 15 class VulkanSurfacePool final { 16 public: 17 // Only keep 12 surfaces at a time. This value was based on how many 18 // surfaces got cached in the old, exact-match-only caching logic. 19 static constexpr int kMaxSurfaces = 12; 20 // If a surface doesn't get used for 3 or more generations, we discard it. 21 static constexpr int kMaxSurfaceAge = 3; 22 23 VulkanSurfacePool(vulkan::VulkanProvider& vulkan_provider, 24 sk_sp<GrContext> context, 25 scenic::Session* scenic_session); 26 27 ~VulkanSurfacePool(); 28 29 std::unique_ptr<VulkanSurface> AcquireSurface(const SkISize& size); 30 31 void SubmitSurface( 32 std::unique_ptr<flutter::SceneUpdateContext::SurfaceProducerSurface> 33 surface); 34 35 void AgeAndCollectOldBuffers(); 36 37 // Shrink all oversized |VulkanSurfaces| in |available_surfaces_| to as 38 // small as they can be. 39 void ShrinkToFit(); 40 41 // For |VulkanSurfaceProducer::HasRetainedNode|. HasRetainedNode(const flutter::LayerRasterCacheKey & key)42 bool HasRetainedNode(const flutter::LayerRasterCacheKey& key) const { 43 return retained_surfaces_.find(key) != retained_surfaces_.end(); 44 } 45 // For |VulkanSurfaceProducer::GetRetainedNode|. GetRetainedNode(const flutter::LayerRasterCacheKey & key)46 const scenic::EntityNode& GetRetainedNode( 47 const flutter::LayerRasterCacheKey& key) { 48 FML_DCHECK(HasRetainedNode(key)); 49 return retained_surfaces_[key].vk_surface->GetRetainedNode(); 50 } 51 52 private: 53 // Struct for retained_surfaces_ map. 54 struct RetainedSurface { 55 // If |is_pending| is true, the |vk_surface| is still under painting 56 // (similar to those in |pending_surfaces_|) so we can't recycle the 57 // |vk_surface| yet. 58 bool is_pending; 59 std::unique_ptr<VulkanSurface> vk_surface; 60 }; 61 62 vulkan::VulkanProvider& vulkan_provider_; 63 sk_sp<GrContext> context_; 64 scenic::Session* scenic_session_; 65 std::vector<std::unique_ptr<VulkanSurface>> available_surfaces_; 66 std::unordered_map<uintptr_t, std::unique_ptr<VulkanSurface>> 67 pending_surfaces_; 68 69 // Retained surfaces keyed by the layer that created and used the surface. 70 flutter::LayerRasterCacheKey::Map<RetainedSurface> retained_surfaces_; 71 72 size_t trace_surfaces_created_ = 0; 73 size_t trace_surfaces_reused_ = 0; 74 75 std::unique_ptr<VulkanSurface> GetCachedOrCreateSurface(const SkISize& size); 76 77 std::unique_ptr<VulkanSurface> CreateSurface(const SkISize& size); 78 79 void RecycleSurface(std::unique_ptr<VulkanSurface> surface); 80 81 void RecyclePendingSurface(uintptr_t surface_key); 82 83 // Clear the |is_pending| flag of the retained surface. 84 void SignalRetainedReady(flutter::LayerRasterCacheKey key); 85 86 // Remove the corresponding surface from |retained_surfaces| and recycle it. 87 // The surface must not be pending. 88 void RecycleRetainedSurface(const flutter::LayerRasterCacheKey& key); 89 90 void TraceStats(); 91 92 FML_DISALLOW_COPY_AND_ASSIGN(VulkanSurfacePool); 93 }; 94 95 } // namespace flutter_runner 96