// Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "flutter/lib/ui/volatile_path_tracker.h" namespace flutter { VolatilePathTracker::VolatilePathTracker( fml::RefPtr ui_task_runner, bool enabled) : ui_task_runner_(ui_task_runner), enabled_(enabled) {} void VolatilePathTracker::Insert(std::shared_ptr path) { FML_DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); FML_DCHECK(path); FML_DCHECK(path->path.isVolatile()); if (!enabled_) { path->path.setIsVolatile(false); return; } paths_.insert(path); } void VolatilePathTracker::Erase(std::shared_ptr path) { if (!enabled_) { return; } FML_DCHECK(path); if (ui_task_runner_->RunsTasksOnCurrentThread()) { paths_.erase(path); return; } std::scoped_lock lock(paths_to_remove_mutex_); needs_drain_ = true; paths_to_remove_.push_back(path); } void VolatilePathTracker::OnFrame() { FML_DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); if (!enabled_) { return; } std::string total_count = std::to_string(paths_.size()); TRACE_EVENT1("flutter", "VolatilePathTracker::OnFrame", "total_count", total_count.c_str()); Drain(); std::set> surviving_paths_; for (const std::shared_ptr& path : paths_) { path->frame_count++; if (path->frame_count >= kFramesOfVolatility) { path->path.setIsVolatile(false); path->tracking_volatility = false; } else { surviving_paths_.insert(path); } } paths_.swap(surviving_paths_); std::string post_removal_count = std::to_string(paths_.size()); TRACE_EVENT_INSTANT1("flutter", "VolatilePathTracker::OnFrame", "remaining_count", post_removal_count.c_str()); } void VolatilePathTracker::Drain() { if (needs_drain_) { TRACE_EVENT0("flutter", "VolatilePathTracker::Drain"); std::deque> paths_to_remove; { std::scoped_lock lock(paths_to_remove_mutex_); paths_to_remove.swap(paths_to_remove_); needs_drain_ = false; } std::string count = std::to_string(paths_to_remove.size()); TRACE_EVENT_INSTANT1("flutter", "VolatilePathTracker::Drain", "count", count.c_str()); for (auto& path : paths_to_remove) { paths_.erase(path); } } } } // namespace flutter