7#include <lib/fdio/directory.h>
8#include <lib/zx/process.h>
16#include "flutter/fml/logging.h"
17#include "flutter/fml/trace_event.h"
24 char name[ZX_MAX_NAME_LEN];
27 if (status != ZX_OK) {
28 FML_LOG(
ERROR) <<
"Failed to get process name for sysmem; using \"\".";
32 return std::string(
name);
36 zx_info_handle_basic_t
info;
38 ZX_INFO_HANDLE_BASIC, &
info,
sizeof(
info),
nullptr,
40 if (status != ZX_OK) {
41 FML_LOG(
ERROR) <<
"Failed to get process ID for sysmem; using 0.";
42 return ZX_KOID_INVALID;
51 zx_status_t status = fdio_service_connect(
52 "/svc/fuchsia.sysmem.Allocator",
53 sysmem_allocator_.NewRequest().TakeChannel().release());
58 status = fdio_service_connect(
59 "/svc/fuchsia.ui.composition.Allocator",
60 flatland_allocator_.NewRequest().TakeChannel().release());
68std::unique_ptr<SurfaceProducerSurface>
72 return CreateSurface(
size);
77 TRACE_EVENT2(
"flutter",
"SoftwareSurfacePool::ProduceSurface",
"width",
78 size.width(),
"height",
size.height());
81 std::unique_ptr<SurfaceProducerSurface>
surface;
83 std::find_if(available_surfaces_.begin(), available_surfaces_.end(),
85 return surface->IsValid() && surface->GetSize() == size;
87 if (exact_match_it != available_surfaces_.end()) {
89 surface = std::move(*exact_match_it);
90 available_surfaces_.erase(exact_match_it);
100 if (!
surface->FlushSessionAcquireAndReleaseEvents()) {
101 FML_LOG(
ERROR) <<
"Could not flush acquire/release events for buffer.";
109 std::vector<std::unique_ptr<SurfaceProducerSurface>> surfaces) {
110 TRACE_EVENT0(
"flutter",
"SoftwareSurfaceProducer::SubmitSurfaces");
113 for (
auto&
surface : surfaces) {
114 SubmitSurface(std::move(
surface));
118 AgeAndCollectOldBuffers();
121void SoftwareSurfaceProducer::SubmitSurface(
122 std::unique_ptr<SurfaceProducerSurface>
surface) {
123 TRACE_EVENT0(
"flutter",
"SoftwareSurfacePool::SubmitSurface");
130 auto software_surface = std::unique_ptr<SoftwareSurface>(
132 if (!software_surface) {
136 uintptr_t surface_key =
reinterpret_cast<uintptr_t
>(software_surface.get());
137 auto insert_iterator = pending_surfaces_.insert(std::make_pair(
139 std::move(software_surface)
141 if (insert_iterator.second) {
142 insert_iterator.first->second->SignalWritesFinished(std::bind(
143 &SoftwareSurfaceProducer::RecyclePendingSurface,
this, surface_key));
147std::unique_ptr<SoftwareSurface> SoftwareSurfaceProducer::CreateSurface(
149 TRACE_EVENT2(
"flutter",
"SoftwareSurfacePool::CreateSurface",
"width",
150 size.width(),
"height",
size.height());
151 auto surface = std::make_unique<SoftwareSurface>(sysmem_allocator_,
152 flatland_allocator_,
size);
157 trace_surfaces_created_++;
161void SoftwareSurfaceProducer::RecycleSurface(
162 std::unique_ptr<SoftwareSurface>
surface) {
166 FML_LOG(
ERROR) <<
"Attempted to recycle invalid surface.";
170 TRACE_EVENT0(
"flutter",
"SoftwareSurfacePool::RecycleSurface");
174 available_surfaces_.push_back(std::move(
surface));
181void SoftwareSurfaceProducer::RecyclePendingSurface(uintptr_t surface_key) {
184 auto found_in_pending = pending_surfaces_.find(surface_key);
185 if (found_in_pending == pending_surfaces_.end()) {
186 FML_LOG(
ERROR) <<
"Attempted to recycle a surface that wasn't pending.";
192 auto surface_to_recycle = std::move(found_in_pending->second);
193 pending_surfaces_.erase(found_in_pending);
195 RecycleSurface(std::move(surface_to_recycle));
198void SoftwareSurfaceProducer::AgeAndCollectOldBuffers() {
199 TRACE_EVENT0(
"flutter",
"SoftwareSurfacePool::AgeAndCollectOldBuffers");
202 size_t size_before = available_surfaces_.size();
203 available_surfaces_.erase(
204 std::remove_if(available_surfaces_.begin(), available_surfaces_.end(),
206 return !surface->IsValid() ||
207 surface->AdvanceAndGetAge() >= kMaxSurfaceAge;
209 available_surfaces_.end());
210 TRACE_EVENT1(
"flutter",
"AgeAndCollect",
"aged surfaces",
211 (size_before - available_surfaces_.size()));
216void SoftwareSurfaceProducer::TraceStats() {
218 size_t cached_surfaces_bytes = 0;
219 for (
const auto&
surface : available_surfaces_) {
220 cached_surfaces_bytes +=
surface->GetAllocationSize();
223 TRACE_COUNTER(
"flutter",
"SurfacePoolCounts", 0u,
"CachedCount",
224 available_surfaces_.size(),
225 "Created", trace_surfaces_created_,
226 "Reused", trace_surfaces_reused_,
227 "PendingInCompositor", pending_surfaces_.size(),
231 TRACE_COUNTER(
"flutter",
"SurfacePoolBytes", 0u,
232 "CachedBytes", cached_surfaces_bytes,
237 trace_surfaces_created_ = 0;
238 trace_surfaces_reused_ = 0;
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
void SubmitSurfaces(std::vector< std::unique_ptr< SurfaceProducerSurface > > surfaces) override
SoftwareSurfaceProducer()
~SoftwareSurfaceProducer() override
static constexpr int kMaxSurfaces
std::unique_ptr< SurfaceProducerSurface > ProduceOffscreenSurface(const SkISize &size) override
std::unique_ptr< SurfaceProducerSurface > ProduceSurface(const SkISize &size) override
#define FML_LOG(severity)
#define FML_CHECK(condition)
#define FML_DCHECK(condition)
static zx_koid_t GetCurrentProcessId()
static std::string GetCurrentProcessName()
DEF_SWITCHES_START aot vmservice shared library name
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
#define TRACE_EVENT0(category_group, name)
#define TRACE_EVENT2(category_group, name, arg1_name, arg1_val, arg2_name, arg2_val)
#define TRACE_EVENT_INSTANT0(category_group, name)
#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val)