7#include <lib/fdio/directory.h>
8#include <lib/zx/process.h>
24 char name[ZX_MAX_NAME_LEN];
26 zx::process::self()->get_property(ZX_PROP_NAME,
name,
sizeof(
name));
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;
37 zx_status_t status = zx::process::self()->get_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.sysmem2.Allocator",
53 sysmem_allocator_.NewRequest().TakeChannel().release());
54 sysmem_allocator_->SetDebugClientInfo(
55 std::move(fuchsia::sysmem2::AllocatorSetDebugClientInfoRequest{}
60 status = fdio_service_connect(
61 "/svc/fuchsia.ui.composition.Allocator",
62 flatland_allocator_.NewRequest().TakeChannel().release());
70std::unique_ptr<SurfaceProducerSurface>
74 return CreateSurface(size);
78 const SkISize& size) {
79 TRACE_EVENT2(
"flutter",
"SoftwareSurfacePool::ProduceSurface",
"width",
80 size.width(),
"height", size.height());
83 std::unique_ptr<SurfaceProducerSurface>
surface;
85 std::find_if(available_surfaces_.begin(), available_surfaces_.end(),
87 return surface->IsValid() && surface->GetSize() == size;
89 if (exact_match_it != available_surfaces_.end()) {
91 surface = std::move(*exact_match_it);
92 available_surfaces_.erase(exact_match_it);
98 FML_LOG(ERROR) <<
"Could not acquire surface.";
102 if (!
surface->FlushSessionAcquireAndReleaseEvents()) {
103 FML_LOG(ERROR) <<
"Could not flush acquire/release events for buffer.";
111 std::vector<std::unique_ptr<SurfaceProducerSurface>> surfaces) {
112 TRACE_EVENT0(
"flutter",
"SoftwareSurfaceProducer::SubmitSurfaces");
115 for (
auto&
surface : surfaces) {
116 SubmitSurface(std::move(
surface));
120 AgeAndCollectOldBuffers();
123void SoftwareSurfaceProducer::SubmitSurface(
124 std::unique_ptr<SurfaceProducerSurface> surface) {
125 TRACE_EVENT0(
"flutter",
"SoftwareSurfacePool::SubmitSurface");
132 auto software_surface = std::unique_ptr<SoftwareSurface>(
134 if (!software_surface) {
138 uintptr_t surface_key =
reinterpret_cast<uintptr_t
>(software_surface.get());
139 auto insert_iterator = pending_surfaces_.insert(std::make_pair(
141 std::move(software_surface)
143 if (insert_iterator.second) {
144 insert_iterator.first->second->SignalWritesFinished(std::bind(
145 &SoftwareSurfaceProducer::RecyclePendingSurface,
this, surface_key));
149std::unique_ptr<SoftwareSurface> SoftwareSurfaceProducer::CreateSurface(
150 const SkISize& size) {
151 TRACE_EVENT2(
"flutter",
"SoftwareSurfacePool::CreateSurface",
"width",
152 size.width(),
"height",
size.height());
153 auto surface = std::make_unique<SoftwareSurface>(sysmem_allocator_,
154 flatland_allocator_, size);
156 FML_LOG(ERROR) <<
"Created surface is invalid.";
159 trace_surfaces_created_++;
163void SoftwareSurfaceProducer::RecycleSurface(
164 std::unique_ptr<SoftwareSurface> surface) {
168 FML_LOG(ERROR) <<
"Attempted to recycle invalid surface.";
172 TRACE_EVENT0(
"flutter",
"SoftwareSurfacePool::RecycleSurface");
176 available_surfaces_.push_back(std::move(surface));
183void SoftwareSurfaceProducer::RecyclePendingSurface(uintptr_t surface_key) {
186 auto found_in_pending = pending_surfaces_.find(surface_key);
187 if (found_in_pending == pending_surfaces_.end()) {
188 FML_LOG(ERROR) <<
"Attempted to recycle a surface that wasn't pending.";
194 auto surface_to_recycle = std::move(found_in_pending->second);
195 pending_surfaces_.erase(found_in_pending);
197 RecycleSurface(std::move(surface_to_recycle));
200void SoftwareSurfaceProducer::AgeAndCollectOldBuffers() {
201 TRACE_EVENT0(
"flutter",
"SoftwareSurfacePool::AgeAndCollectOldBuffers");
204 size_t size_before = available_surfaces_.size();
205 available_surfaces_.erase(
206 std::remove_if(available_surfaces_.begin(), available_surfaces_.end(),
208 return !surface->IsValid() ||
209 surface->AdvanceAndGetAge() >= kMaxSurfaceAge;
211 available_surfaces_.end());
212 TRACE_EVENT1(
"flutter",
"AgeAndCollect",
"aged surfaces",
213 (size_before - available_surfaces_.size()));
218void SoftwareSurfaceProducer::TraceStats() {
220 size_t cached_surfaces_bytes = 0;
221 for (
const auto& surface : available_surfaces_) {
222 cached_surfaces_bytes +=
surface->GetAllocationSize();
225 TRACE_COUNTER(
"flutter",
"SurfacePoolCounts", 0u,
"CachedCount",
226 available_surfaces_.size(),
227 "Created", trace_surfaces_created_,
228 "Reused", trace_surfaces_reused_,
229 "PendingInCompositor", pending_surfaces_.size(),
233 TRACE_COUNTER(
"flutter",
"SurfacePoolBytes", 0u,
234 "CachedBytes", cached_surfaces_bytes,
239 trace_surfaces_created_ = 0;
240 trace_surfaces_reused_ = 0;
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()
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all 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)