Flutter Engine
flutter_runner::VulkanSurfacePool Class Referencefinal

#include <vulkan_surface_pool.h>

Public Member Functions

 VulkanSurfacePool (vulkan::VulkanProvider &vulkan_provider, sk_sp< GrDirectContext > context, scenic::Session *scenic_session)
 
 ~VulkanSurfacePool ()
 
std::unique_ptr< VulkanSurfaceCreateSurface (const SkISize &size)
 
std::unique_ptr< VulkanSurfaceAcquireSurface (const SkISize &size)
 
void SubmitSurface (std::unique_ptr< SurfaceProducerSurface > surface)
 
void AgeAndCollectOldBuffers ()
 
void ShrinkToFit ()
 

Static Public Attributes

static constexpr int kMaxSurfaces = 12
 
static constexpr int kMaxSurfaceAge = 3
 

Detailed Description

Definition at line 17 of file vulkan_surface_pool.h.

Constructor & Destructor Documentation

◆ VulkanSurfacePool()

flutter_runner::VulkanSurfacePool::VulkanSurfacePool ( vulkan::VulkanProvider vulkan_provider,
sk_sp< GrDirectContext >  context,
scenic::Session *  scenic_session 
)

Definition at line 32 of file vulkan_surface_pool.cc.

References FML_CHECK, FML_DCHECK, flutter_runner::GetCurrentProcessId(), and flutter_runner::GetCurrentProcessName().

35  : vulkan_provider_(vulkan_provider),
36  context_(std::move(context)),
37  scenic_session_(scenic_session) {
38  FML_CHECK(context_ != nullptr);
39 
40  zx_status_t status = fdio_service_connect(
41  "/svc/fuchsia.sysmem.Allocator",
42  sysmem_allocator_.NewRequest().TakeChannel().release());
43  sysmem_allocator_->SetDebugClientInfo(GetCurrentProcessName(),
45  FML_DCHECK(status != ZX_OK);
46 
47  if (!scenic_session_) {
48  status = fdio_service_connect(
49  "/svc/fuchsia.ui.composition.Allocator",
50  flatland_allocator_.NewRequest().TakeChannel().release());
51  FML_DCHECK(status != ZX_OK);
52  }
53 }
#define FML_DCHECK(condition)
Definition: logging.h:86
static std::string GetCurrentProcessName()
fuchsia::ui::composition::AllocatorPtr flatland_allocator_
#define FML_CHECK(condition)
Definition: logging.h:68
static zx_koid_t GetCurrentProcessId()

◆ ~VulkanSurfacePool()

flutter_runner::VulkanSurfacePool::~VulkanSurfacePool ( )

Definition at line 55 of file vulkan_surface_pool.cc.

55 {}

Member Function Documentation

◆ AcquireSurface()

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

Definition at line 57 of file vulkan_surface_pool.cc.

References CreateSurface(), FML_LOG, fml::size(), TRACE_EVENT2, and TRACE_EVENT_INSTANT0.

58  {
59  auto surface = GetCachedOrCreateSurface(size);
60 
61  if (surface == nullptr) {
62  FML_LOG(ERROR) << "VulkanSurfaceProducer: Could not acquire surface";
63  return nullptr;
64  }
65 
66  if (!surface->FlushSessionAcquireAndReleaseEvents()) {
67  FML_LOG(ERROR) << "VulkanSurfaceProducer: Could not flush acquire/release "
68  "events for buffer.";
69  return nullptr;
70  }
71 
72  return surface;
73 }
constexpr std::size_t size(T(&array)[N])
Definition: size.h:13
#define FML_LOG(severity)
Definition: logging.h:65

◆ AgeAndCollectOldBuffers()

void flutter_runner::VulkanSurfacePool::AgeAndCollectOldBuffers ( )

Definition at line 171 of file vulkan_surface_pool.cc.

References CreateSurface(), FML_LOG, kMaxSurfaceAge, TRACE_EVENT0, TRACE_EVENT1, and TRACE_EVENT_INSTANT0.

171  {
172  TRACE_EVENT0("flutter", "VulkanSurfacePool::AgeAndCollectOldBuffers");
173 
174  // Remove all surfaces that are no longer valid or are too old.
175  size_t size_before = available_surfaces_.size();
176  available_surfaces_.erase(
177  std::remove_if(available_surfaces_.begin(), available_surfaces_.end(),
178  [&](auto& surface) {
179  return !surface->IsValid() ||
180  surface->AdvanceAndGetAge() >= kMaxSurfaceAge;
181  }),
182  available_surfaces_.end());
183  TRACE_EVENT1("flutter", "AgeAndCollect", "aged surfaces",
184  (size_before - available_surfaces_.size()));
185 
186  // Look for a surface that has both a larger |VkDeviceMemory| allocation
187  // than is necessary for its |VkImage|, and has a stable size history.
188  auto surface_to_remove_it = std::find_if(
189  available_surfaces_.begin(), available_surfaces_.end(),
190  [](const auto& surface) {
191  return surface->IsOversized() && surface->HasStableSizeHistory();
192  });
193  // If we found such a surface, then destroy it and cache a new one that only
194  // uses a necessary amount of memory.
195  if (surface_to_remove_it != available_surfaces_.end()) {
196  TRACE_EVENT_INSTANT0("flutter", "replacing surface with smaller one");
197  auto size = (*surface_to_remove_it)->GetSize();
198  available_surfaces_.erase(surface_to_remove_it);
199  auto new_surface = CreateSurface(size);
200  if (new_surface != nullptr) {
201  available_surfaces_.push_back(std::move(new_surface));
202  } else {
203  FML_LOG(ERROR)
204  << "VulkanSurfaceProducer: Failed to create a new shrunk surface";
205  }
206  }
207 
208  TraceStats();
209 }
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:90
#define TRACE_EVENT_INSTANT0(category_group, name)
Definition: trace_event.h:119
constexpr std::size_t size(T(&array)[N])
Definition: size.h:13
#define FML_LOG(severity)
Definition: logging.h:65
std::unique_ptr< VulkanSurface > CreateSurface(const SkISize &size)
#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val)
Definition: trace_event.h:94

◆ CreateSurface()

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

Definition at line 122 of file vulkan_surface_pool.cc.

References FML_LOG, kMaxSurfaces, fml::size(), TRACE_EVENT0, TRACE_EVENT2, and TRACE_EVENT_INSTANT0.

Referenced by AcquireSurface(), AgeAndCollectOldBuffers(), and ShrinkToFit().

123  {
124  TRACE_EVENT2("flutter", "VulkanSurfacePool::CreateSurface", "width",
125  size.width(), "height", size.height());
126  auto surface = std::make_unique<VulkanSurface>(
127  vulkan_provider_, sysmem_allocator_, flatland_allocator_, context_,
128  scenic_session_, size, buffer_id_++);
129  if (!surface->IsValid()) {
130  FML_LOG(ERROR) << "VulkanSurfaceProducer: Created surface is invalid";
131  return nullptr;
132  }
133  trace_surfaces_created_++;
134  return surface;
135 }
constexpr std::size_t size(T(&array)[N])
Definition: size.h:13
#define FML_LOG(severity)
Definition: logging.h:65
fuchsia::ui::composition::AllocatorPtr flatland_allocator_
#define TRACE_EVENT2(category_group, name, arg1_name, arg1_val, arg2_name, arg2_val)
Definition: trace_event.h:98

◆ ShrinkToFit()

void flutter_runner::VulkanSurfacePool::ShrinkToFit ( )

Definition at line 211 of file vulkan_surface_pool.cc.

References CreateSurface(), FML_LOG, and TRACE_EVENT0.

211  {
212  TRACE_EVENT0("flutter", "VulkanSurfacePool::ShrinkToFit");
213  // Reset all oversized surfaces in |available_surfaces_| so that the old
214  // surfaces and new surfaces don't exist at the same time at any point,
215  // reducing our peak memory footprint.
216  std::vector<SkISize> sizes_to_recreate;
217  for (auto& surface : available_surfaces_) {
218  if (surface->IsOversized()) {
219  sizes_to_recreate.push_back(surface->GetSize());
220  surface.reset();
221  }
222  }
223  available_surfaces_.erase(std::remove(available_surfaces_.begin(),
224  available_surfaces_.end(), nullptr),
225  available_surfaces_.end());
226  for (const auto& size : sizes_to_recreate) {
227  auto surface = CreateSurface(size);
228  if (surface != nullptr) {
229  available_surfaces_.push_back(std::move(surface));
230  } else {
231  FML_LOG(ERROR)
232  << "VulkanSurfaceProducer: Failed to create resized surface";
233  }
234  }
235 
236  TraceStats();
237 }
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:90
constexpr std::size_t size(T(&array)[N])
Definition: size.h:13
#define FML_LOG(severity)
Definition: logging.h:65
std::unique_ptr< VulkanSurface > CreateSurface(const SkISize &size)

◆ SubmitSurface()

void flutter_runner::VulkanSurfacePool::SubmitSurface ( std::unique_ptr< SurfaceProducerSurface surface)

Definition at line 97 of file vulkan_surface_pool.cc.

References TRACE_EVENT0.

98  {
99  TRACE_EVENT0("flutter", "VulkanSurfacePool::SubmitSurface");
100 
101  // This cast is safe because |VulkanSurface| is the only implementation of
102  // |SurfaceProducerSurface| for Flutter on Fuchsia. Additionally, it is
103  // required, because we need to access |VulkanSurface| specific information
104  // of the surface (such as the amount of VkDeviceMemory it contains).
105  auto vulkan_surface = std::unique_ptr<VulkanSurface>(
106  static_cast<VulkanSurface*>(p_surface.release()));
107  if (!vulkan_surface) {
108  return;
109  }
110 
111  uintptr_t surface_key = reinterpret_cast<uintptr_t>(vulkan_surface.get());
112  auto insert_iterator = pending_surfaces_.insert(std::make_pair(
113  surface_key, // key
114  std::move(vulkan_surface) // value
115  ));
116  if (insert_iterator.second) {
117  insert_iterator.first->second->SignalWritesFinished(std::bind(
118  &VulkanSurfacePool::RecyclePendingSurface, this, surface_key));
119  }
120 }
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:90

Member Data Documentation

◆ kMaxSurfaceAge

constexpr int flutter_runner::VulkanSurfacePool::kMaxSurfaceAge = 3
static

Definition at line 23 of file vulkan_surface_pool.h.

Referenced by AgeAndCollectOldBuffers().

◆ kMaxSurfaces

constexpr int flutter_runner::VulkanSurfacePool::kMaxSurfaces = 12
static

Definition at line 21 of file vulkan_surface_pool.h.

Referenced by CreateSurface().


The documentation for this class was generated from the following files: