• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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