#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "cc/trees/layer_tree_host.h"
#include <stddef.h>
#include <stdint.h>
#include <algorithm>
#include <memory>
#include <string>
#include "base/atomic_sequence_num.h"
#include "base/auto_reset.h"
#include "base/command_line.h"
#include "base/containers/adapters.h"
#include "base/containers/contains.h"
#include "base/functional/bind.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/not_fatal_until.h"
#include "base/numerics/safe_math.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/timer/elapsed_timer.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/traced_value.h"
#include "base/types/optional_ref.h"
#include "build/build_config.h"
#include "cc/base/devtools_instrumentation.h"
#include "cc/base/features.h"
#include "cc/base/histograms.h"
#include "cc/base/math_util.h"
#include "cc/debug/rendering_stats_instrumentation.h"
#include "cc/input/browser_controls_offset_tags_info.h"
#include "cc/input/layer_selection_bound.h"
#include "cc/input/overscroll_behavior.h"
#include "cc/input/page_scale_animation.h"
#include "cc/layers/heads_up_display_layer.h"
#include "cc/layers/heads_up_display_layer_impl.h"
#include "cc/layers/layer.h"
#include "cc/layers/painted_scrollbar_layer.h"
#include "cc/metrics/ukm_manager.h"
#include "cc/metrics/ukm_smoothness_data.h"
#include "cc/paint/paint_worklet_layer_painter.h"
#include "cc/resources/ui_resource_manager.h"
#include "cc/tiles/raster_dark_mode_filter.h"
#include "cc/trees/clip_node.h"
#include "cc/trees/commit_state.h"
#include "cc/trees/compositor_commit_data.h"
#include "cc/trees/draw_property_utils.h"
#include "cc/trees/effect_node.h"
#include "cc/trees/layer_tree_host_client.h"
#include "cc/trees/layer_tree_host_impl.h"
#include "cc/trees/layer_tree_impl.h"
#include "cc/trees/mobile_optimized_viewport_util.h"
#include "cc/trees/mutator_host.h"
#include "cc/trees/paint_holding_reason.h"
#include "cc/trees/property_tree_builder.h"
#include "cc/trees/proxy_main.h"
#include "cc/trees/render_frame_metadata_observer.h"
#include "cc/trees/scroll_node.h"
#include "cc/trees/single_thread_proxy.h"
#include "cc/trees/swap_promise_manager.h"
#include "cc/trees/transform_node.h"
#include "cc/trees/tree_synchronizer.h"
#include "cc/view_transition/view_transition_request.h"
#include "components/viz/common/features.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
#include "services/tracing/public/cpp/perfetto/flow_event_utils.h"
#include "services/tracing/public/cpp/perfetto/macros.h"
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/gfx/geometry/vector2d_conversions.h"
#include "ui/gfx/presentation_feedback.h"
namespace {
static base::AtomicSequenceNumber s_layer_tree_host_sequence_number;
static base::AtomicSequenceNumber s_image_decode_sequence_number;
}
namespace cc {
namespace {
bool AreEmbedTokensEqual(const viz::LocalSurfaceId& lsi1,
const viz::LocalSurfaceId& lsi2) { … }
bool AreParentSequencesEqual(const viz::LocalSurfaceId& lsi1,
const viz::LocalSurfaceId& lsi2) { … }
}
LayerTreeHost::InitParams::InitParams() = default;
LayerTreeHost::InitParams::~InitParams() = default;
LayerTreeHost::InitParams::InitParams(InitParams&&) = default;
LayerTreeHost::InitParams& LayerTreeHost::InitParams::operator=(InitParams&&) =
default;
LayerTreeHost::ScrollAnimationState::ScrollAnimationState() = default;
LayerTreeHost::ScrollAnimationState::~ScrollAnimationState() = default;
std::unique_ptr<LayerTreeHost> LayerTreeHost::CreateThreaded(
scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner,
InitParams params) { … }
std::unique_ptr<LayerTreeHost> LayerTreeHost::CreateSingleThreaded(
LayerTreeHostSingleThreadClient* single_thread_client,
InitParams params) { … }
LayerTreeHost::LayerTreeHost(InitParams params, CompositorMode mode)
: … { … }
bool LayerTreeHost::IsMobileOptimized() const { … }
void LayerTreeHost::InitializeThreaded(
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) { … }
void LayerTreeHost::InitializeSingleThreaded(
LayerTreeHostSingleThreadClient* single_thread_client,
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner) { … }
void LayerTreeHost::InitializeForTesting(
std::unique_ptr<TaskRunnerProvider> task_runner_provider,
std::unique_ptr<Proxy> proxy_for_testing) { … }
void LayerTreeHost::SetTaskRunnerProviderForTesting(
std::unique_ptr<TaskRunnerProvider> task_runner_provider) { … }
void LayerTreeHost::SetUIResourceManagerForTesting(
std::unique_ptr<UIResourceManager> ui_resource_manager) { … }
void LayerTreeHost::InitializeProxy(std::unique_ptr<Proxy> proxy) { … }
LayerTreeHost::~LayerTreeHost() { … }
int LayerTreeHost::GetId() const { … }
int LayerTreeHost::SourceFrameNumber() const { … }
UIResourceManager* LayerTreeHost::GetUIResourceManager() { … }
TaskRunnerProvider* LayerTreeHost::GetTaskRunnerProvider() { … }
bool LayerTreeHost::IsMainThread() const { … }
bool LayerTreeHost::IsImplThread() const { … }
bool LayerTreeHost::IsOwnerThread() const { … }
bool LayerTreeHost::InProtectedSequence() const { … }
SwapPromiseManager* LayerTreeHost::GetSwapPromiseManager() { … }
std::unique_ptr<EventsMetricsManager::ScopedMonitor>
LayerTreeHost::GetScopedEventMetricsMonitor(
EventsMetricsManager::ScopedMonitor::DoneCallback done_callback) { … }
void LayerTreeHost::ClearEventsMetrics() { … }
const LayerTreeSettings& LayerTreeHost::GetSettings() const { … }
void LayerTreeHost::QueueSwapPromise(
std::unique_ptr<SwapPromise> swap_promise) { … }
void LayerTreeHost::WillBeginMainFrame() { … }
void LayerTreeHost::DidBeginMainFrame() { … }
void LayerTreeHost::BeginMainFrameNotExpectedSoon() { … }
void LayerTreeHost::BeginMainFrameNotExpectedUntil(base::TimeTicks time) { … }
void LayerTreeHost::BeginMainFrame(const viz::BeginFrameArgs& args) { … }
const LayerTreeDebugState& LayerTreeHost::GetDebugState() const { … }
void LayerTreeHost::RequestMainFrameUpdate(bool report_metrics) { … }
void LayerTreeHost::ImageDecodesFinished(
const std::vector<std::pair<int, bool>>& results) { … }
void LayerTreeHost::SetNextCommitWaitsForActivation() { … }
std::unique_ptr<CommitState> LayerTreeHost::WillCommit(
std::unique_ptr<CompletionEvent> completion,
bool has_updates) { … }
std::unique_ptr<CommitState> LayerTreeHost::ActivateCommitState() { … }
void LayerTreeHost::WaitForProtectedSequenceCompletion() const { … }
void LayerTreeHost::WaitForCommitCompletion(bool for_protected_sequence) const { … }
void LayerTreeHost::UpdateDeferMainFrameUpdateInternal() { … }
bool LayerTreeHost::MainFrameUpdatesAreDeferred() const { … }
bool LayerTreeHost::IsUsingLayerLists() const { … }
void LayerTreeHost::CommitComplete(int source_frame_number,
const CommitTimestamps& commit_timestamps) { … }
void LayerTreeHost::NotifyImageDecodeFinished(int request_id,
bool decode_succeeded) { … }
void LayerTreeHost::NotifyTransitionRequestsFinished(
const std::vector<uint32_t>& sequence_ids) { … }
void LayerTreeHost::SetLayerTreeFrameSink(
std::unique_ptr<LayerTreeFrameSink> surface) { … }
std::unique_ptr<LayerTreeFrameSink> LayerTreeHost::ReleaseLayerTreeFrameSink() { … }
void LayerTreeHost::RequestNewLayerTreeFrameSink() { … }
void LayerTreeHost::DidInitializeLayerTreeFrameSink() { … }
void LayerTreeHost::DidFailToInitializeLayerTreeFrameSink() { … }
std::unique_ptr<LayerTreeHostImpl> LayerTreeHost::CreateLayerTreeHostImpl(
LayerTreeHostImplClient* client) { … }
std::unique_ptr<LayerTreeHostImpl>
LayerTreeHost::CreateLayerTreeHostImplInternal(
LayerTreeHostImplClient* client,
MutatorHost* mutator_host,
const LayerTreeSettings& settings,
TaskRunnerProvider* task_runner_provider,
raw_ptr<RasterDarkModeFilter>& dark_mode_filter,
int id,
raw_ptr<TaskGraphRunner>& task_graph_runner,
scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner,
LayerTreeHostSchedulingClient* scheduling_client,
RenderingStatsInstrumentation* rendering_stats_instrumentation,
std::unique_ptr<UkmRecorderFactory>& ukm_recorder_factory,
base::WeakPtr<CompositorDelegateForInput>& compositor_delegate_weak_ptr) { … }
void LayerTreeHost::DidLoseLayerTreeFrameSink() { … }
ScopedDeferMainFrameUpdate::ScopedDeferMainFrameUpdate(LayerTreeHost* host)
: … { … }
ScopedDeferMainFrameUpdate::~ScopedDeferMainFrameUpdate() { … }
std::unique_ptr<ScopedDeferMainFrameUpdate>
LayerTreeHost::DeferMainFrameUpdate() { … }
ScopedPauseRendering::ScopedPauseRendering(LayerTreeHost* host)
: … { … }
ScopedPauseRendering::~ScopedPauseRendering() { … }
std::unique_ptr<ScopedPauseRendering> LayerTreeHost::PauseRendering() { … }
void LayerTreeHost::OnDeferMainFrameUpdatesChanged(bool defer_status) { … }
bool LayerTreeHost::StartDeferringCommits(base::TimeDelta timeout,
PaintHoldingReason reason) { … }
void LayerTreeHost::StopDeferringCommits(PaintHoldingCommitTrigger trigger) { … }
bool LayerTreeHost::IsDeferringCommits() const { … }
bool LayerTreeHost::IsRenderingPaused() const { … }
void LayerTreeHost::OnDeferCommitsChanged(
bool defer_status,
PaintHoldingReason reason,
std::optional<PaintHoldingCommitTrigger> trigger) { … }
DISABLE_CFI_PERF
void LayerTreeHost::SetNeedsAnimate() { … }
void LayerTreeHost::SetNeedsAnimateIfNotInsideMainFrame() { … }
DISABLE_CFI_PERF
void LayerTreeHost::SetNeedsUpdateLayers() { … }
void LayerTreeHost::SetNeedsCommit() { … }
void LayerTreeHost::OnCommitRequested() { … }
void LayerTreeHost::SetTargetLocalSurfaceId(
const viz::LocalSurfaceId& target_local_surface_id) { … }
bool LayerTreeHost::RequestedMainFramePending() const { … }
void LayerTreeHost::SetNeedsRecalculateRasterScales() { … }
void LayerTreeHost::SetNeedsRedrawRect(const gfx::Rect& damage_rect) { … }
bool LayerTreeHost::CommitRequested() const { … }
void LayerTreeHost::SetNeedsCommitWithForcedRedraw() { … }
void LayerTreeHost::SetDebugState(const LayerTreeDebugState& new_debug_state) { … }
void LayerTreeHost::ApplyPageScaleDeltaFromImplSide(float page_scale_delta) { … }
void LayerTreeHost::SetVisible(bool visible) { … }
bool LayerTreeHost::IsVisible() const { … }
void LayerTreeHost::SetShouldWarmUp() { … }
bool LayerTreeHost::ShouldWarmUp() const { … }
void LayerTreeHost::LayoutAndUpdateLayers() { … }
void LayerTreeHost::CompositeForTest(base::TimeTicks frame_begin_time,
bool raster,
base::OnceClosure callback) { … }
bool LayerTreeHost::UpdateLayers() { … }
void LayerTreeHost::DidPresentCompositorFrame(
uint32_t frame_token,
std::vector<PresentationTimeCallbackBuffer::Callback>
presentation_callbacks,
std::vector<PresentationTimeCallbackBuffer::SuccessfulCallbackWithDetails>
successful_presentation_callbacks,
const viz::FrameTimingDetails& frame_timing_details) { … }
void LayerTreeHost::DidCompletePageScaleAnimation() { … }
std::string LayerTreeHost::LayersAsString() const { … }
bool LayerTreeHost::CaptureContent(std::vector<NodeInfo>* content) const { … }
void LayerTreeHost::DidObserveFirstScrollDelay(
int source_frame_number,
base::TimeDelta first_scroll_delay,
base::TimeTicks first_scroll_timestamp) { … }
void LayerTreeHost::AddViewTransitionRequest(
std::unique_ptr<ViewTransitionRequest> request) { … }
bool LayerTreeHost::DoUpdateLayers() { … }
void LayerTreeHost::ApplyViewportChanges(
const CompositorCommitData& commit_data) { … }
void LayerTreeHost::UpdateScrollOffsetFromImpl(
const ElementId& id,
const gfx::Vector2dF& delta,
const std::optional<TargetSnapAreaElementIds>& snap_target_ids) { … }
void LayerTreeHost::ApplyCompositorChanges(CompositorCommitData* commit_data) { … }
void LayerTreeHost::ApplyMutatorEvents(std::unique_ptr<MutatorEvents> events) { … }
void LayerTreeHost::RecordStartOfFrameMetrics() { … }
void LayerTreeHost::RecordEndOfFrameMetrics(
base::TimeTicks frame_begin_time,
ActiveFrameSequenceTrackers trackers) { … }
void LayerTreeHost::NotifyThroughputTrackerResults(
CustomTrackerResults results) { … }
const base::WeakPtr<CompositorDelegateForInput>&
LayerTreeHost::GetDelegateForInput() const { … }
void LayerTreeHost::DetachInputDelegateAndRenderFrameObserver() { … }
void LayerTreeHost::UpdateBrowserControlsState(
BrowserControlsState constraints,
BrowserControlsState current,
bool animate,
base::optional_ref<const BrowserControlsOffsetTagsInfo> offset_tags_info) { … }
void LayerTreeHost::AnimateLayers(base::TimeTicks monotonic_time) { … }
int LayerTreeHost::ScheduleMicroBenchmark(
const std::string& benchmark_name,
base::Value::Dict settings,
MicroBenchmark::DoneCallback callback) { … }
bool LayerTreeHost::SendMessageToMicroBenchmark(int id,
base::Value::Dict message) { … }
void LayerTreeHost::SetLayerTreeMutator(
std::unique_ptr<LayerTreeMutator> mutator) { … }
void LayerTreeHost::SetPaintWorkletLayerPainter(
std::unique_ptr<PaintWorkletLayerPainter> painter) { … }
bool LayerTreeHost::IsSingleThreaded() const { … }
bool LayerTreeHost::IsThreaded() const { … }
void LayerTreeHost::RequestPresentationTimeForNextFrame(
PresentationTimeCallbackBuffer::Callback callback) { … }
void LayerTreeHost::RequestSuccessfulPresentationTimeForNextFrame(
PresentationTimeCallbackBuffer::SuccessfulCallbackWithDetails callback) { … }
void LayerTreeHost::RequestScrollAnimationEndNotification(
base::OnceClosure callback) { … }
void LayerTreeHost::SetRootLayer(scoped_refptr<Layer> new_root_layer) { … }
void LayerTreeHost::RegisterViewportPropertyIds(
const ViewportPropertyIds& ids) { … }
Layer* LayerTreeHost::InnerViewportScrollLayerForTesting() { … }
Layer* LayerTreeHost::OuterViewportScrollLayerForTesting() { … }
ElementId LayerTreeHost::OuterViewportScrollElementId() const { … }
void LayerTreeHost::RegisterSelection(const LayerSelection& selection) { … }
void LayerTreeHost::SetHaveScrollEventHandlers(bool have_event_handlers) { … }
void LayerTreeHost::SetEventListenerProperties(
EventListenerClass event_class,
EventListenerProperties properties) { … }
void LayerTreeHost::SetViewportRectAndScale(
const gfx::Rect& device_viewport_rect,
float device_scale_factor,
const viz::LocalSurfaceId& local_surface_id_from_parent) { … }
void LayerTreeHost::SetVisualDeviceViewportIntersectionRect(
const gfx::Rect& intersection_rect) { … }
void LayerTreeHost::SetVisualDeviceViewportSize(
const gfx::Size& visual_device_viewport_size) { … }
void LayerTreeHost::SetBrowserControlsParams(
const BrowserControlsParams& params) { … }
void LayerTreeHost::SetBrowserControlsShownRatio(float top_ratio,
float bottom_ratio) { … }
void LayerTreeHost::SetOverscrollBehavior(const OverscrollBehavior& behavior) { … }
void LayerTreeHost::SetPageScaleFactorAndLimits(float page_scale_factor,
float min_page_scale_factor,
float max_page_scale_factor) { … }
void LayerTreeHost::StartPageScaleAnimation(const gfx::Point& target_offset,
bool use_anchor,
float scale,
base::TimeDelta duration) { … }
bool LayerTreeHost::HasPendingPageScaleAnimation() const { … }
void LayerTreeHost::SetRecordingScaleFactor(float recording_scale_factor) { … }
void LayerTreeHost::SetDisplayColorSpaces(
const gfx::DisplayColorSpaces& display_color_spaces) { … }
void LayerTreeHost::UpdateViewportIsMobileOptimized(
bool is_viewport_mobile_optimized) { … }
void LayerTreeHost::SetPrefersReducedMotion(bool prefers_reduced_motion) { … }
void LayerTreeHost::SetMayThrottleIfUndrawnFrames(
bool may_throttle_if_undrawn_frames) { … }
bool LayerTreeHost::GetMayThrottleIfUndrawnFramesForTesting() const { … }
void LayerTreeHost::SetExternalPageScaleFactor(
float page_scale_factor,
bool is_external_pinch_gesture_active) { … }
void LayerTreeHost::SetLocalSurfaceIdFromParent(
const viz::LocalSurfaceId& local_surface_id_from_parent) { … }
void LayerTreeHost::RequestViewportScreenshot(
const base::UnguessableToken& token) { … }
void LayerTreeHost::SetPrimaryMainFrameItemSequenceNumber(
int64_t primary_main_frame_item_sequence_number) { … }
void LayerTreeHost::RequestNewLocalSurfaceId() { … }
void LayerTreeHost::RegisterLayer(Layer* layer) { … }
void LayerTreeHost::UnregisterLayer(Layer* layer) { … }
Layer* LayerTreeHost::LayerById(int id) { … }
bool LayerTreeHost::PaintContent(const LayerList& update_layer_list) { … }
void LayerTreeHost::AddSurfaceRange(const viz::SurfaceRange& surface_range) { … }
void LayerTreeHost::RemoveSurfaceRange(const viz::SurfaceRange& surface_range) { … }
void LayerTreeHost::AddLayerShouldPushProperties(Layer* layer) { … }
void LayerTreeHost::SetPageScaleFromImplSide(float page_scale) { … }
void LayerTreeHost::SetElasticOverscrollFromImplSide(
gfx::Vector2dF elastic_overscroll) { … }
void LayerTreeHost::UpdateHudLayer(bool show_hud_info) { … }
bool LayerTreeHost::is_hud_layer(const Layer* layer) const { … }
void LayerTreeHost::SetNeedsFullTreeSync() { … }
void LayerTreeHost::ResetNeedsFullTreeSyncForTesting() { … }
void LayerTreeHost::SetPropertyTreesNeedRebuild() { … }
Layer* LayerTreeHost::LayerByElementId(ElementId element_id) { … }
const Layer* LayerTreeHost::LayerByElementId(ElementId element_id) const { … }
void LayerTreeHost::RegisterElement(ElementId element_id,
Layer* layer) { … }
void LayerTreeHost::UnregisterElement(ElementId element_id) { … }
void LayerTreeHost::SetElementIdsForTesting() { … }
void LayerTreeHost::BuildPropertyTreesForTesting() { … }
bool LayerTreeHost::IsElementInPropertyTrees(ElementId element_id,
ElementListType list_type) const { … }
void LayerTreeHost::SetMutatorsNeedCommit() { … }
void LayerTreeHost::SetMutatorsNeedRebuildPropertyTrees() { … }
void LayerTreeHost::SetElementFilterMutated(ElementId element_id,
ElementListType list_type,
const FilterOperations& filters) { … }
void LayerTreeHost::SetElementBackdropFilterMutated(
ElementId element_id,
ElementListType list_type,
const FilterOperations& backdrop_filters) { … }
void LayerTreeHost::SetElementOpacityMutated(ElementId element_id,
ElementListType list_type,
float opacity) { … }
void LayerTreeHost::SetElementTransformMutated(
ElementId element_id,
ElementListType list_type,
const gfx::Transform& transform) { … }
void LayerTreeHost::SetElementScrollOffsetMutated(
ElementId element_id,
ElementListType list_type,
const gfx::PointF& scroll_offset) { … }
void LayerTreeHost::ElementIsAnimatingChanged(
const PropertyToElementIdMap& element_id_map,
ElementListType list_type,
const PropertyAnimationState& mask,
const PropertyAnimationState& state) { … }
void LayerTreeHost::MaximumScaleChanged(ElementId element_id,
ElementListType list_type,
float maximum_scale) { … }
bool LayerTreeHost::RunsOnCurrentThread() const { … }
void LayerTreeHost::QueueImageDecode(const PaintImage& image,
base::OnceCallback<void(bool)> callback) { … }
LayerListIterator LayerTreeHost::begin() { … }
LayerListConstIterator LayerTreeHost::begin() const { … }
LayerListIterator LayerTreeHost::end() { … }
LayerListConstIterator LayerTreeHost::end() const { … }
LayerListReverseIterator LayerTreeHost::rbegin() { … }
LayerListReverseConstIterator LayerTreeHost::rbegin() const { … }
LayerListReverseIterator LayerTreeHost::rend() { … }
LayerListReverseConstIterator LayerTreeHost::rend() const { … }
void LayerTreeHost::SetPropertyTreesForTesting(
const PropertyTrees* property_trees) { … }
void LayerTreeHost::SetNeedsDisplayOnAllLayers() { … }
void LayerTreeHost::SetHasCopyRequest(bool has_copy_request) { … }
void LayerTreeHost::RequestBeginMainFrameNotExpected(bool new_state) { … }
void LayerTreeHost::SetSourceURL(ukm::SourceId source_id, const GURL& url) { … }
base::ReadOnlySharedMemoryRegion
LayerTreeHost::CreateSharedMemoryForSmoothnessUkm() { … }
void LayerTreeHost::SetRenderFrameObserver(
std::unique_ptr<RenderFrameMetadataObserver> observer) { … }
void LayerTreeHost::SetDelegatedInkMetadata(
std::unique_ptr<gfx::DelegatedInkMetadata> metadata) { … }
std::vector<base::OnceClosure>
LayerTreeHost::TakeViewTransitionCallbacksForTesting() { … }
double LayerTreeHost::GetPercentDroppedFrames() const { … }
void LayerTreeHost::DropActiveScrollDeltaNextCommit(ElementId scroll_element) { … }
}