blob: 5e26aab02bfe5779b8f5766223a3a3b6d0505a26 [file] [log] [blame]
// Copyright 2011 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CC_TREES_LAYER_TREE_HOST_H_
#define CC_TREES_LAYER_TREE_HOST_H_
#include <stddef.h>
#include <stdint.h>
#include <limits>
#include <memory>
#include <set>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
#include "base/callback_forward.h"
#include "base/cancelable_callback.h"
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/read_only_shared_memory_region.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/task/single_thread_task_runner.h"
#include "base/time/time.h"
#include "cc/base/completion_event.h"
#include "cc/benchmarks/micro_benchmark.h"
#include "cc/benchmarks/micro_benchmark_controller.h"
#include "cc/cc_export.h"
#include "cc/input/browser_controls_state.h"
#include "cc/input/compositor_input_interfaces.h"
#include "cc/input/event_listener_properties.h"
#include "cc/input/input_handler.h"
#include "cc/input/layer_selection_bound.h"
#include "cc/input/scrollbar.h"
#include "cc/layers/layer.h"
#include "cc/layers/layer_collections.h"
#include "cc/layers/layer_list_iterator.h"
#include "cc/metrics/begin_main_frame_metrics.h"
#include "cc/metrics/events_metrics_manager.h"
#include "cc/metrics/frame_sequence_tracker.h"
#include "cc/metrics/web_vital_metrics.h"
#include "cc/paint/node_id.h"
#include "cc/resources/ui_resource_request.h"
#include "cc/trees/browser_controls_params.h"
#include "cc/trees/commit_state.h"
#include "cc/trees/compositor_mode.h"
#include "cc/trees/layer_tree_frame_sink.h"
#include "cc/trees/layer_tree_host_client.h"
#include "cc/trees/layer_tree_settings.h"
#include "cc/trees/mutator_host.h"
#include "cc/trees/paint_holding_reason.h"
#include "cc/trees/presentation_time_callback_buffer.h"
#include "cc/trees/proxy.h"
#include "cc/trees/swap_promise.h"
#include "cc/trees/swap_promise_manager.h"
#include "cc/trees/target_property.h"
#include "cc/trees/viewport_layers.h"
#include "cc/trees/viewport_property_ids.h"
#include "components/viz/common/resources/resource_format.h"
#include "components/viz/common/surfaces/local_surface_id.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/delegated_ink_metadata.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/overlay_transform.h"
namespace gfx {
struct PresentationFeedback;
}
namespace cc {
class ViewTransitionRequest;
class HeadsUpDisplayLayer;
class LayerTreeHostImpl;
class LayerTreeHostImplClient;
class LayerTreeHostSingleThreadClient;
class LayerTreeMutator;
class MutatorEvents;
class MutatorHost;
class PaintWorkletLayerPainter;
class RasterDarkModeFilter;
class RenderFrameMetadataObserver;
class RenderingStatsInstrumentation;
class TaskGraphRunner;
class UIResourceManager;
class UkmRecorderFactory;
struct CommitState;
struct CompositorCommitData;
struct OverscrollBehavior;
struct RenderingStats;
// Returned from LayerTreeHost::DeferMainFrameUpdate. Automatically un-defers on
// destruction.
class CC_EXPORT ScopedDeferMainFrameUpdate {
public:
explicit ScopedDeferMainFrameUpdate(LayerTreeHost* host);
~ScopedDeferMainFrameUpdate();
private:
base::WeakPtr<LayerTreeHost> host_;
};
// Returned from LayerTreeHost::PauseRendering. Automatically un-pauses on
// destruction.
class CC_EXPORT ScopedPauseRendering {
public:
explicit ScopedPauseRendering(LayerTreeHost* host);
~ScopedPauseRendering();
private:
base::WeakPtr<LayerTreeHost> host_;
};
class CC_EXPORT LayerTreeHost : public MutatorHostClient {
public:
struct CC_EXPORT InitParams {
InitParams();
~InitParams();
InitParams(InitParams&&);
InitParams& operator=(InitParams&&);
raw_ptr<LayerTreeHostClient> client = nullptr;
raw_ptr<LayerTreeHostSchedulingClient> scheduling_client = nullptr;
raw_ptr<TaskGraphRunner> task_graph_runner = nullptr;
raw_ptr<const LayerTreeSettings> settings = nullptr;
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner;
raw_ptr<MutatorHost> mutator_host = nullptr;
raw_ptr<RasterDarkModeFilter> dark_mode_filter = nullptr;
// The image worker task runner is used to schedule image decodes. The
// compositor thread may make sync calls to this thread, analogous to the
// raster worker threads.
scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner;
std::unique_ptr<UkmRecorderFactory> ukm_recorder_factory;
};
// Constructs a LayerTreeHost with a compositor thread where scrolling and
// animation take place. This is used for the web compositor in the renderer
// process to move work off the main thread which javascript can dominate.
static std::unique_ptr<LayerTreeHost> CreateThreaded(
scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner,
InitParams params);
// Constructs a LayerTreeHost without a separate compositor thread, but which
// behaves and looks the same as a threaded compositor externally, with the
// exception of the additional client interface. This is used in other cases
// where the main thread creating this instance can be expected to not become
// blocked, so moving work to another thread and the overhead it adds are not
// required.
static std::unique_ptr<LayerTreeHost> CreateSingleThreaded(
LayerTreeHostSingleThreadClient* single_thread_client,
InitParams params);
LayerTreeHost(const LayerTreeHost&) = delete;
~LayerTreeHost() override;
LayerTreeHost& operator=(const LayerTreeHost&) = delete;
// Returns the process global unique identifier for this LayerTreeHost.
int GetId() const;
// The commit state for the frame being assembled by the compositor host.
const CommitState* pending_commit_state() const {
DCHECK(IsMainThread());
return pending_commit_state_.get();
}
// Additional state required for commit. Unlike pending_commit_state(), this
// state is *not* snapshotted. Both the compositor and the host access a
// single live version, so care must be taken to avoid collisions.
const ThreadUnsafeCommitState& thread_unsafe_commit_state() const {
DCHECK(IsMainThread());
return thread_unsafe_commit_state_;
}
// This should only be used to get a reference to ThreadUnsafeCommitState for
// the purpose of passing to the commit code. All other locations should use
// thread_unsafe_commit_state() instead.
ThreadUnsafeCommitState& GetUnsafeStateForCommit() {
return thread_unsafe_commit_state();
}
// The current source frame number. This is incremented for each main frame
// update(commit) pushed to the compositor thread. The initial frame number
// is 0, and it is incremented once commit is completed (which is before the
// compositor-thread-side submits its frame for the commit).
int SourceFrameNumber() const;
// Returns the UIResourceManager used to create UIResources for
// UIResourceLayers pushed to the LayerTree.
UIResourceManager* GetUIResourceManager();
// These methods are safe to call from either thread.
TaskRunnerProvider* GetTaskRunnerProvider();
bool IsMainThread() const;
bool IsImplThread() const;
// Returns the settings used by this host. These settings are constants given
// at startup.
const LayerTreeSettings& GetSettings() const;
// Sets the LayerTreeMutator interface used to directly mutate the compositor
// state on the compositor thread. (Compositor-Worker)
void SetLayerTreeMutator(std::unique_ptr<LayerTreeMutator> mutator);
// Sets the LayerTreePainter interface used to dispatch the JS paint callback
// to a worklet thread.
void SetPaintWorkletLayerPainter(
std::unique_ptr<PaintWorkletLayerPainter> painter);
// Attachs a SwapPromise to the Layer tree, that passes through the
// LayerTreeHost and LayerTreeHostImpl with the next commit and frame
// submission, which can be used to observe that progress. This also
// causes a main frame to be requested.
// See swap_promise.h for how to use SwapPromise.
void QueueSwapPromise(std::unique_ptr<SwapPromise> swap_promise);
// Returns the SwapPromiseManager, used to insert SwapPromises dynamically
// when a main frame is requested.
SwapPromiseManager* GetSwapPromiseManager();
std::unique_ptr<EventsMetricsManager::ScopedMonitor>
GetScopedEventMetricsMonitor(
EventsMetricsManager::ScopedMonitor::DoneCallback done_callback);
void ClearEventsMetrics();
size_t saved_events_metrics_count_for_testing() const {
DCHECK(IsMainThread());
return events_metrics_manager_.saved_events_metrics_count_for_testing();
}
std::unique_ptr<BeginMainFrameMetrics> TakeBeginMainFrameMetrics() {
return std::move(pending_commit_state()->begin_main_frame_metrics);
}
// Visibility and LayerTreeFrameSink -------------------------------
// Sets or gets if the LayerTreeHost is visible. When not visible it will:
// - Not request a new LayerTreeFrameSink from the client.
// - Stop submitting frames to the display compositor.
// - Stop producing main frames and committing them.
// The LayerTreeHost is not visible when first created, so this must be called
// to make it visible before it will attempt to start producing output.
void SetVisible(bool visible);
bool IsVisible() const;
// Called in response to a LayerTreeFrameSink request made to the client
// using LayerTreeHostClient::RequestNewLayerTreeFrameSink. The client will
// be informed of the LayerTreeFrameSink initialization status using
// DidInitializaLayerTreeFrameSink or DidFailToInitializeLayerTreeFrameSink.
// The request is completed when the host successfully initializes an
// LayerTreeFrameSink.
void SetLayerTreeFrameSink(
std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink);
// Forces the host to immediately release all references to the
// LayerTreeFrameSink, if any. Can be safely called any time, but the
// compositor should not be visible.
std::unique_ptr<LayerTreeFrameSink> ReleaseLayerTreeFrameSink();
// Frame Scheduling (main and compositor frames) requests -------
// Requests a main frame update even if no content has changed. This is used,
// for instance in the case of RequestAnimationFrame from blink to ensure the
// main frame update is run on the next tick without pre-emptively forcing a
// full commit synchronization or layer updates.
void SetNeedsAnimate();
// Calls SetNeedsAnimate() if there is no main frame already in progress.
void SetNeedsAnimateIfNotInsideMainFrame();
// Requests a main frame update and also ensure that the host pulls layer
// updates from the client, even if no content might have changed, without
// forcing a full commit synchronization.
virtual void SetNeedsUpdateLayers();
// Requests that the next main frame update performs a full commit
// synchronization.
virtual void SetNeedsCommit();
// Notifies that a new viz::LocalSurfaceId has been set, ahead of it becoming
// activated. Requests that the compositor thread does not produce new frames
// until it has activated.
virtual void SetTargetLocalSurfaceId(
const viz::LocalSurfaceId& target_local_surface_id);
// Returns true after SetNeedsAnimate(), SetNeedsUpdateLayers() or
// SetNeedsCommit(), until it is satisfied.
bool RequestedMainFramePending() const;
// Requests that the next frame re-chooses crisp raster scales for all layers.
void SetNeedsRecalculateRasterScales();
// Returns true if a main frame with commit synchronization has been
// requested.
bool CommitRequested() const;
// Prevents the compositor from requesting main frame updates from the client
// until the ScopedDeferMainFrameUpdate object is destroyed, or
// StopDeferringCommits is called.
std::unique_ptr<ScopedDeferMainFrameUpdate> DeferMainFrameUpdate();
// Prevents the compositor from rendering updates. As opposed to
// DeferMainFrameUpdate() which only pauses main frames, this pauses both main
// and impl frames to ensure no visual updates are presented.
//
// Note that this ensures any previously committed or in progress (if called
// during the main frame) updates are presented before rendering is paused.
[[nodiscard]] std::unique_ptr<ScopedPauseRendering> PauseRendering();
// Notification that the proxy paused or resumed rendering.
void OnPauseRenderingChanged(bool);
// Returns whether main frame updates are deferred. See conditions above.
bool MainFrameUpdatesAreDeferred() const;
// Notification that the proxy started or stopped deferring main frame updates
void OnDeferMainFrameUpdatesChanged(bool);
// Prevents the proxy from committing the layer tree to the compositor,
// while still allowing main frame lifecycle updates. |timeout|
// is the interval after which commits will restart if nothing stops
// deferring sooner. If multiple calls are made to StartDeferringCommits
// while deferal is active, the first timeout continues to apply.
bool StartDeferringCommits(base::TimeDelta timeout,
PaintHoldingReason reason);
// Stop deferring commits immediately.
void StopDeferringCommits(PaintHoldingCommitTrigger);
// Returns true if commits are currently deferred.
bool IsDeferringCommits() const;
// Returns true if rendering is currently paused.
bool IsRenderingPaused() const;
// Notification that the proxy started or stopped deferring commits.
void OnDeferCommitsChanged(bool defer_status,
PaintHoldingReason reason,
absl::optional<PaintHoldingCommitTrigger> trigger);
// Returns whether there are any outstanding ScopedDeferMainFrameUpdate,
// though commits may be deferred also when the local_surface_id_from_parent()
// is not valid.
bool defer_main_frame_update() const {
DCHECK(IsMainThread());
return defer_main_frame_update_count_;
}
// Synchronously performs a main frame update and layer updates. Used only in
// single threaded mode when the compositor's internal scheduling is disabled.
void LayoutAndUpdateLayers();
// Synchronously performs a complete main frame update, commit and compositor
// frame. Used only in single threaded mode when the compositor's internal
// scheduling is disabled.
void CompositeForTest(base::TimeTicks frame_begin_time, bool raster);
// Requests a redraw (compositor frame) for the given rect.
void SetNeedsRedrawRect(const gfx::Rect& damage_rect);
// Requests a main frame (including layer updates) and ensures that this main
// frame results in a redraw for the complete viewport when producing the
// CompositorFrame.
void SetNeedsCommitWithForcedRedraw();
// Input Handling ---------------------------------------------
// Sets the state of the browser controls. (Used for URL bar animations).
void UpdateBrowserControlsState(BrowserControlsState constraints,
BrowserControlsState current,
bool animate);
// Returns the delegate that the input handler uses to communicate with the
// LayerTreeHostImpl on the compositor thread. Must be dereferenced only on
// the input handling thread.
const base::WeakPtr<CompositorDelegateForInput>& GetDelegateForInput() const;
// Debugging and benchmarks ---------------------------------
void SetDebugState(const LayerTreeDebugState& debug_state);
const LayerTreeDebugState& GetDebugState() const;
// Returns the id of the benchmark on success, 0 otherwise.
int ScheduleMicroBenchmark(const std::string& benchmark_name,
base::Value settings,
MicroBenchmark::DoneCallback callback);
// Returns true if the message was successfully delivered and handled.
bool SendMessageToMicroBenchmark(int id, base::Value message);
// When the main thread informs the compositor thread that it is ready to
// commit, generally it would remain blocked until the main thread state is
// copied to the pending tree. Calling this would ensure that the main thread
// remains blocked until the pending tree is activated.
void SetNextCommitWaitsForActivation();
// Registers a callback that is run when the presentation feedback for the
// next submitted frame is received (it's entirely possible some frames may be
// dropped between the time this is called and the callback is run).
// Note that since this might be called on failed presentations, it is
// deprecated in favor of `RequestSuccessfulPresentationTimeForNextFrame()`
// which will be called only after a successful presentation.
void RequestPresentationTimeForNextFrame(
PresentationTimeCallbackBuffer::Callback callback);
// Registers a callback that is run when the next frame successfully makes it
// to the screen (it's entirely possible some frames may be dropped between
// the time this is called and the callback is run).
void RequestSuccessfulPresentationTimeForNextFrame(
PresentationTimeCallbackBuffer::SuccessfulCallback callback);
// Registers a callback that is run when any ongoing scroll-animation ends. If
// there are no ongoing animations, then the callback is run immediately.
void RequestScrollAnimationEndNotification(base::OnceClosure callback);
// Layer tree accessors and modifiers ------------------------
// Sets or gets the root of the Layer tree. Children of the root Layer are
// attached to it and will be added/removed along with the root Layer. The
// LayerTreeHost retains ownership of a reference to the root Layer.
void SetRootLayer(scoped_refptr<Layer> root_layer);
Layer* root_layer() { return thread_unsafe_commit_state().root_layer.get(); }
const Layer* root_layer() const {
return thread_unsafe_commit_state().root_layer.get();
}
bool has_root_layer() const { return root_layer(); }
// Sets the collection of viewport property ids, defined to allow viewport
// pinch-zoom etc. on the compositor thread. This is set only on the
// main-frame's compositor, i.e., will be unset in OOPIF and UI compositors.
void RegisterViewportPropertyIds(const ViewportPropertyIds&);
ViewportPropertyIds ViewportPropertyIdsForTesting() const {
return pending_commit_state()->viewport_property_ids;
}
Layer* InnerViewportScrollLayerForTesting();
Layer* OuterViewportScrollLayerForTesting();
ElementId OuterViewportScrollElementId() const;
// Sets or gets the position of touch handles for a text selection. These are
// submitted to the display compositor along with the Layer tree's contents
// allowing it to present the selection handles. This is done because the
// handles are a UI widget above, and not clipped to, the viewport of this
// LayerTreeHost.
void RegisterSelection(const LayerSelection& selection);
const LayerSelection& selection() const {
return pending_commit_state()->selection;
}
// Sets or gets if the client has any scroll event handlers registered. This
// allows the threaded compositor to prioritize main frames even when
// servicing a touch scroll on the compositor thread, in order to give the
// event handler a chance to be part of each frame.
void SetHaveScrollEventHandlers(bool have_event_handlers);
bool have_scroll_event_handlers() const {
return pending_commit_state()->have_scroll_event_handlers;
}
// Set or get what event handlers exist on the layer tree in order to inform
// the compositor thread if it is able to handle an input event, or it needs
// to pass it to the main thread to be handled. The class is the type of input
// event, and for each class there is a properties defining if the compositor
// thread can handle the event.
void SetEventListenerProperties(EventListenerClass event_class,
EventListenerProperties event_properties);
EventListenerProperties event_listener_properties(
EventListenerClass event_class) const {
DCHECK(IsMainThread());
return pending_commit_state()
->event_listener_properties[static_cast<size_t>(event_class)];
}
void SetViewportRectAndScale(
const gfx::Rect& device_viewport_rect,
float device_scale_factor,
const viz::LocalSurfaceId& local_surface_id_from_parent);
// VisualDeviceViewportIntersectionRect is the intersection of this
// compositor's viewport with the "visible size", aka this compositor's
// viewport intersection with the global viewport (i.e.
// VisualDeviceViewportSize). It is also specified in the device viewport
// coordinate space.
void SetVisualDeviceViewportIntersectionRect(
const gfx::Rect& intersection_rect);
// VisualDeviceViewportSize is the size of the global viewport across all
// compositors that are part of the scene that this compositor contributes to
// (i.e. the visual viewport), allowing for that scene to be broken up into
// multiple compositors that each contribute to the whole (e.g. cross-origin
// iframes are isolated from each other). This is a size instead of a rect
// because each compositor doesn't know its position relative to other
// compositors. This is specified in device viewport coordinate space.
void SetVisualDeviceViewportSize(const gfx::Size&);
gfx::Rect device_viewport_rect() const {
return pending_commit_state()->device_viewport_rect;
}
void UpdateViewportIsMobileOptimized(bool is_viewport_mobile_optimized);
// Returns if the viewport is considered to be mobile optimized.
bool IsMobileOptimized() const;
void SetPrefersReducedMotion(bool prefers_reduced_motion);
void SetMayThrottleIfUndrawnFrames(bool may_throttle_if_undrawn_frames);
bool GetMayThrottleIfUndrawnFramesForTesting() const;
void SetBrowserControlsParams(const BrowserControlsParams& params);
void SetBrowserControlsShownRatio(float top_ratio, float bottom_ratio);
void SetOverscrollBehavior(const OverscrollBehavior& overscroll_behavior);
const OverscrollBehavior& overscroll_behavior() const {
return pending_commit_state()->overscroll_behavior;
}
void SetPageScaleFactorAndLimits(float page_scale_factor,
float min_page_scale_factor,
float max_page_scale_factor);
float page_scale_factor() const {
return pending_commit_state()->page_scale_factor;
}
float min_page_scale_factor() const {
return pending_commit_state()->min_page_scale_factor;
}
float max_page_scale_factor() const {
return pending_commit_state()->max_page_scale_factor;
}
void set_background_color(SkColor4f color) {
pending_commit_state()->background_color = color;
}
SkColor4f background_color() const {
return pending_commit_state()->background_color;
}
void set_display_transform_hint(gfx::OverlayTransform hint) {
pending_commit_state()->display_transform_hint = hint;
}
gfx::OverlayTransform display_transform_hint() const {
return pending_commit_state()->display_transform_hint;
}
void StartPageScaleAnimation(const gfx::Point& target_offset,
bool use_anchor,
float scale,
base::TimeDelta duration);
bool HasPendingPageScaleAnimation() const;
float device_scale_factor() const {
return pending_commit_state()->device_scale_factor;
}
float painted_device_scale_factor() const {
return pending_commit_state()->painted_device_scale_factor;
}
void SetRecordingScaleFactor(float recording_scale_factor);
// If this LayerTreeHost needs a valid viz::LocalSurfaceId then commits will
// be deferred until a valid viz::LocalSurfaceId is provided.
void SetLocalSurfaceIdFromParent(
const viz::LocalSurfaceId& local_surface_id_from_parent);
const viz::LocalSurfaceId& local_surface_id_from_parent() const {
return pending_commit_state()->local_surface_id_from_parent;
}
// Requests the allocation of a new LocalSurfaceId on the compositor thread.
void RequestNewLocalSurfaceId();
// Returns the current state of the new LocalSurfaceId request and resets
// the state.
bool new_local_surface_id_request_for_testing() const {
return pending_commit_state()->new_local_surface_id_request;
}
void SetDisplayColorSpaces(
const gfx::DisplayColorSpaces& display_color_spaces);
const gfx::DisplayColorSpaces& display_color_spaces() const {
return pending_commit_state()->display_color_spaces;
}
bool HasCompositorDrivenScrollAnimationForTesting() const {
DCHECK(IsMainThread());
return scroll_animation_.in_progress;
}
// This layer tree may be embedded in a hierarchy that has page scale
// factor controlled at the top level. We represent that scale here as
// 'external_page_scale_factor', a value that affects raster scale in the
// same way that page_scale_factor does, but doesn't affect any geometry
// calculations.
void SetExternalPageScaleFactor(float page_scale_factor,
bool is_external_pinch_gesture_active);
bool is_external_pinch_gesture_active_for_testing() {
return pending_commit_state()->is_external_pinch_gesture_active;
}
// Requests that we force send RenderFrameMetadata with the next frame.
void RequestForceSendMetadata() {
pending_commit_state()->force_send_metadata_request = true;
}
// Returns the state of |force_send_metadata_request_| and resets the
// variable to false.
bool TakeForceSendMetadataRequest();
// Used externally by blink for setting the PropertyTrees when
// UseLayerLists() is true.
PropertyTrees* property_trees() {
return &thread_unsafe_commit_state().property_trees;
}
const PropertyTrees* property_trees() const {
return &thread_unsafe_commit_state().property_trees;
}
MutatorHost* mutator_host() {
return thread_unsafe_commit_state().mutator_host;
}
const MutatorHost* mutator_host() const {
return thread_unsafe_commit_state().mutator_host;
}
void SetPropertyTreesForTesting(const PropertyTrees* property_trees);
void SetNeedsDisplayOnAllLayers();
void RegisterLayer(Layer* layer);
void UnregisterLayer(Layer* layer);
Layer* LayerById(int id);
bool PaintContent(const LayerList& update_layer_list);
bool in_paint_layer_contents() const {
DCHECK(IsMainThread());
return in_paint_layer_contents_;
}
bool in_commit() const {
return commit_completion_event_ && !commit_completion_event_->IsSignaled();
}
void SetHasCopyRequest(bool has_copy_request);
bool has_copy_request() const {
DCHECK(IsMainThread());
return has_copy_request_;
}
void AddSurfaceRange(const viz::SurfaceRange& surface_range);
void RemoveSurfaceRange(const viz::SurfaceRange& surface_range);
// Marks or unmarks a layer are needing PushPropertiesTo in the next commit.
// These are internal methods, called from the Layer itself when changing a
// property or completing a PushPropertiesTo.
void AddLayerShouldPushProperties(Layer* layer);
void SetPageScaleFromImplSide(float page_scale);
void SetElasticOverscrollFromImplSide(gfx::Vector2dF elastic_overscroll);
gfx::Vector2dF elastic_overscroll() const {
return pending_commit_state()->elastic_overscroll;
}
// Ensures a HUD layer exists if it is needed, and updates the HUD bounds and
// position. If a HUD layer exists but is no longer needed, it is destroyed.
void UpdateHudLayer(bool show_hud_info);
HeadsUpDisplayLayer* hud_layer() {
DCHECK(IsMainThread());
return hud_layer_.get();
}
const HeadsUpDisplayLayer* hud_layer() const {
DCHECK(IsMainThread());
return hud_layer_.get();
}
bool is_hud_layer(const Layer*) const;
virtual void SetNeedsFullTreeSync();
void ResetNeedsFullTreeSyncForTesting();
bool needs_full_tree_sync() const {
return pending_commit_state()->needs_full_tree_sync;
}
void SetPropertyTreesNeedRebuild();
// Returns the layer with the given |element_id|. In layer-list mode, only
// scrollable layers are registered in this map.
Layer* LayerByElementId(ElementId element_id);
const Layer* LayerByElementId(ElementId element_id) const;
void RegisterElement(ElementId element_id,
Layer* layer);
void UnregisterElement(ElementId element_id);
void SetElementIdsForTesting();
void BuildPropertyTreesForTesting();
// Layer iterators.
LayerListIterator begin();
LayerListConstIterator begin() const;
LayerListIterator end();
LayerListConstIterator end() const;
LayerListReverseIterator rbegin();
LayerListReverseConstIterator rbegin() const;
LayerListReverseIterator rend();
LayerListReverseConstIterator rend() const;
// LayerTreeHost interface to Proxy.
void WillBeginMainFrame();
void DidBeginMainFrame();
void BeginMainFrame(const viz::BeginFrameArgs& args);
void BeginMainFrameNotExpectedSoon();
void BeginMainFrameNotExpectedUntil(base::TimeTicks time);
void AnimateLayers(base::TimeTicks monotonic_frame_begin_time);
void RequestMainFrameUpdate(bool report_metrics);
// If has_updates is true, returns the CommitState that will drive the commit.
// Otherwise, returns nullptr.
std::unique_ptr<CommitState> WillCommit(
std::unique_ptr<CompletionEvent> completion,
bool has_updates);
std::unique_ptr<CommitState> ActivateCommitState();
void CommitComplete(const CommitTimestamps&);
void RequestNewLayerTreeFrameSink();
void DidInitializeLayerTreeFrameSink();
void DidFailToInitializeLayerTreeFrameSink();
std::unique_ptr<LayerTreeHostImpl> CreateLayerTreeHostImpl(
LayerTreeHostImplClient* client);
void DidLoseLayerTreeFrameSink();
void DidCommitAndDrawFrame() {
DCHECK(IsMainThread());
client_->DidCommitAndDrawFrame();
}
void DidReceiveCompositorFrameAck() {
DCHECK(IsMainThread());
client_->DidReceiveCompositorFrameAck();
}
bool UpdateLayers();
void DidPresentCompositorFrame(
uint32_t frame_token,
std::vector<PresentationTimeCallbackBuffer::Callback>
presentation_callbacks,
std::vector<PresentationTimeCallbackBuffer::SuccessfulCallback>
successful_presentation_callbacks,
const gfx::PresentationFeedback& feedback);
// Called when the compositor completed page scale animation.
void DidCompletePageScaleAnimation();
// Virtual for testing
virtual void ApplyCompositorChanges(CompositorCommitData* commit_data);
void ApplyMutatorEvents(std::unique_ptr<MutatorEvents> events);
void RecordStartOfFrameMetrics();
void RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time,
ActiveFrameSequenceTrackers trackers);
void NotifyThroughputTrackerResults(CustomTrackerResults results);
void NotifyTransitionRequestsFinished(
const std::vector<uint32_t>& sequence_ids);
LayerTreeHostClient* client() {
DCHECK(IsMainThread());
return client_;
}
LayerTreeHostSchedulingClient* scheduling_client() {
DCHECK(IsMainThread());
return scheduling_client_;
}
void CollectRenderingStats(RenderingStats* stats) const;
RenderingStatsInstrumentation* rendering_stats_instrumentation() const {
DCHECK(IsMainThread());
return rendering_stats_instrumentation_.get();
}
Proxy* proxy() {
DCHECK(IsMainThread());
return proxy_.get();
}
bool IsSingleThreaded() const;
bool IsThreaded() const;
// Indicates whether this host is configured to use layer lists
// rather than layer trees. This also implies that property trees
// are always already built and so cc doesn't have to build them.
bool IsUsingLayerLists() const;
// ProtectedSequenceSynchronizer implementation.
bool IsOwnerThread() const override;
bool InProtectedSequence() const override;
// If commit is currently running on the impl thread, this will block until
// commit is finished.
void WaitForProtectedSequenceCompletion() const override;
// MutatorHostClient implementation.
bool IsElementInPropertyTrees(ElementId element_id,
ElementListType list_type) const override;
void SetMutatorsNeedCommit() override;
void SetMutatorsNeedRebuildPropertyTrees() override;
void SetElementFilterMutated(ElementId element_id,
ElementListType list_type,
const FilterOperations& filters) override;
void SetElementBackdropFilterMutated(
ElementId element_id,
ElementListType list_type,
const FilterOperations& backdrop_filters) override;
void SetElementOpacityMutated(ElementId element_id,
ElementListType list_type,
float opacity) override;
void SetElementTransformMutated(ElementId element_id,
ElementListType list_type,
const gfx::Transform& transform) override;
void SetElementScrollOffsetMutated(ElementId element_id,
ElementListType list_type,
const gfx::PointF& scroll_offset) override;
void ElementIsAnimatingChanged(const PropertyToElementIdMap& element_id_map,
ElementListType list_type,
const PropertyAnimationState& mask,
const PropertyAnimationState& state) override;
void MaximumScaleChanged(ElementId element_id,
ElementListType list_type,
float maximum_scale) override;
void OnCustomPropertyMutated(
PaintWorkletInput::PropertyKey property_key,
PaintWorkletInput::PropertyValue property_value) override {}
bool RunsOnCurrentThread() const override;
void ScrollOffsetAnimationFinished() override {}
void NotifyAnimationWorkletStateChange(AnimationWorkletMutationState state,
ElementListType tree_type) override {}
void QueueImageDecode(const PaintImage& image,
base::OnceCallback<void(bool)> callback);
void ImageDecodesFinished(const std::vector<std::pair<int, bool>>& results);
void RequestBeginMainFrameNotExpected(bool new_state);
float recording_scale_factor() const {
DCHECK(IsMainThread());
return recording_scale_factor_;
}
const ViewportPropertyIds& viewport_property_ids() const {
return pending_commit_state()->viewport_property_ids;
}
void SetSourceURL(ukm::SourceId source_id, const GURL& url);
base::ReadOnlySharedMemoryRegion CreateSharedMemoryForSmoothnessUkm();
void SetRenderFrameObserver(
std::unique_ptr<RenderFrameMetadataObserver> observer);
std::string LayersAsString() const;
// Captures the on-screen text content, if success, fills the associated
// NodeInfo in |content| and return true, otherwise return false.
bool CaptureContent(std::vector<NodeInfo>* content) const;
void SetDelegatedInkMetadata(
std::unique_ptr<gfx::DelegatedInkMetadata> metadata);
gfx::DelegatedInkMetadata* DelegatedInkMetadataForTesting() {
return pending_commit_state()->delegated_ink_metadata.get();
}
void DidObserveFirstScrollDelay(base::TimeDelta first_scroll_delay,
base::TimeTicks first_scroll_timestamp);
void AddViewTransitionRequest(std::unique_ptr<ViewTransitionRequest> request);
std::vector<base::OnceClosure> TakeViewTransitionCallbacksForTesting();
// Returns a percentage of dropped frames of the last second.
double GetPercentDroppedFrames() const;
// TODO(szager): Remove these once threaded compositing is enabled for all
// web_tests.
bool in_composite_for_test() const { return in_composite_for_test_; }
[[nodiscard]] base::AutoReset<bool> ForceSyncCompositeForTest() {
return base::AutoReset<bool>(&in_composite_for_test_, true);
}
// Blink compositor unit tests sometimes want to simulate pushing deltas
// without going through the whole lifecycle to test the effects of the
// deltas. This flag turns off DCHECKs that deltas being set to main are
// during a commit phase so these tests can do this.
[[nodiscard]] base::AutoReset<bool> SimulateSyncingDeltasForTesting() {
return base::AutoReset<bool>(&syncing_deltas_for_test_, true);
}
void IncrementVisualUpdateDuration(base::TimeDelta visual_update_duration);
protected:
LayerTreeHost(InitParams params, CompositorMode mode);
void InitializeThreaded(
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner);
void InitializeSingleThreaded(
LayerTreeHostSingleThreadClient* single_thread_client,
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner);
void InitializeForTesting(
std::unique_ptr<TaskRunnerProvider> task_runner_provider,
std::unique_ptr<Proxy> proxy_for_testing);
void SetTaskRunnerProviderForTesting(
std::unique_ptr<TaskRunnerProvider> task_runner_provider);
void SetUIResourceManagerForTesting(
std::unique_ptr<UIResourceManager> ui_resource_manager);
// task_graph_runner() returns a valid value only until the LayerTreeHostImpl
// is created in CreateLayerTreeHostImpl().
TaskGraphRunner* task_graph_runner() const {
DCHECK(IsMainThread());
return task_graph_runner_;
}
CommitState* pending_commit_state() {
DCHECK(task_runner_provider_->IsMainThread());
return pending_commit_state_.get();
}
ThreadUnsafeCommitState& thread_unsafe_commit_state() {
DCHECK(IsMainThread());
WaitForProtectedSequenceCompletion();
return thread_unsafe_commit_state_;
}
void OnCommitForSwapPromises();
MicroBenchmarkController micro_benchmark_controller_;
// The pointer that input uses to communicate with the layer tree host impl.
// Must be dereferenced only from the input-handling thread. This is the same
// as the valid-compositor thread, which may be a separate thread for the
// compositor, or the main thread.
base::WeakPtr<CompositorDelegateForInput> compositor_delegate_weak_ptr_;
scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner_;
std::unique_ptr<UkmRecorderFactory> ukm_recorder_factory_;
private:
friend class LayerTreeHostSerializationTest;
friend class LayerTreeTest;
friend class ScopedDeferMainFrameUpdate;
friend class ScopedPauseRendering;
// This is the number of consecutive frames in which we want the content to be
// free of slow-paths before toggling the flag.
enum { kNumFramesToConsiderBeforeRemovingSlowPathFlag = 60 };
virtual std::unique_ptr<LayerTreeHostImpl> 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 ApplyViewportChanges(const CompositorCommitData& commit_data);
void ApplyPageScaleDeltaFromImplSide(float page_scale_delta);
void InitializeProxy(std::unique_ptr<Proxy> proxy);
bool DoUpdateLayers();
void WaitForCommitCompletion(bool for_protected_sequence) const;
void UpdateDeferMainFrameUpdateInternal();
void UpdatePauseRenderingInternal();
// Preemptively applies the scroll offset and delta before sending it to the
// client. This lets the client skip a commit if the value does not change.
void UpdateScrollOffsetFromImpl(
const ElementId&,
const gfx::Vector2dF& delta,
const absl::optional<TargetSnapAreaElementIds>&);
const CompositorMode compositor_mode_;
std::unique_ptr<UIResourceManager> ui_resource_manager_;
raw_ptr<LayerTreeHostClient> client_;
raw_ptr<LayerTreeHostSchedulingClient> scheduling_client_;
std::unique_ptr<Proxy> proxy_;
std::unique_ptr<TaskRunnerProvider> task_runner_provider_;
std::unique_ptr<RenderingStatsInstrumentation>
rendering_stats_instrumentation_;
std::unique_ptr<CommitState> pending_commit_state_;
ThreadUnsafeCommitState thread_unsafe_commit_state_;
SwapPromiseManager swap_promise_manager_;
// |current_layer_tree_frame_sink_| can't be updated until we've successfully
// initialized a new LayerTreeFrameSink. |new_layer_tree_frame_sink_|
// contains the new LayerTreeFrameSink that is currently being initialized.
// If initialization is successful then |new_layer_tree_frame_sink_| replaces
// |current_layer_tree_frame_sink_|.
std::unique_ptr<LayerTreeFrameSink> new_layer_tree_frame_sink_;
std::unique_ptr<LayerTreeFrameSink> current_layer_tree_frame_sink_;
const LayerTreeSettings settings_;
bool visible_ = false;
// If set, then page scale animation has completed, but the client hasn't been
// notified about it yet.
bool did_complete_scale_animation_ = false;
const int id_;
// Track when we're inside a main frame to see if compositor is being
// destroyed midway which causes a crash. crbug.com/654672
bool inside_main_frame_ = false;
// State cached until impl side is initialized.
raw_ptr<TaskGraphRunner> task_graph_runner_;
float recording_scale_factor_ = 1.f;
// Used to track the out-bound state for ApplyViewportChanges.
bool is_pinch_gesture_active_from_impl_ = false;
uint32_t defer_main_frame_update_count_ = 0;
uint32_t pause_rendering_count_ = 0;
gfx::Rect visual_device_viewport_intersection_rect_;
scoped_refptr<HeadsUpDisplayLayer> hud_layer_;
// Layer id to Layer map.
std::unordered_map<int, Layer*> layer_id_map_;
// This is for layer tree mode only.
std::unordered_map<ElementId, Layer*, ElementIdHash> element_layers_map_;
bool in_paint_layer_contents_ = false;
bool in_apply_compositor_changes_ = false;
// This is true if atleast one layer in the layer tree has a copy request. We
// use this bool to decide whether we need to compute subtree has copy request
// for every layer during property tree building.
bool has_copy_request_ = false;
raw_ptr<MutatorHost> mutator_host_;
raw_ptr<RasterDarkModeFilter> dark_mode_filter_;
std::unordered_map<int, base::OnceCallback<void(bool)>>
pending_image_decodes_;
struct ScrollAnimationState {
ScrollAnimationState();
~ScrollAnimationState();
// Tracks whether there is an ongoing compositor-driven scroll animation.
bool in_progress = false;
// Callback to run when the scroll-animation ends.
base::OnceClosure end_notification;
} scroll_animation_;
mutable std::unique_ptr<CompletionEvent> commit_completion_event_;
EventsMetricsManager events_metrics_manager_;
// A list of callbacks that need to be invoked when they are processed.
base::flat_map<uint32_t, base::OnceClosure> view_transition_callbacks_;
// Set if WaitForCommitCompletion() was called before commit completes. Used
// for histograms.
mutable bool waited_for_protected_sequence_ = false;
bool in_composite_for_test_ = false;
bool syncing_deltas_for_test_ = false;
base::WeakPtrFactory<LayerTreeHost> weak_ptr_factory_{this};
};
} // namespace cc
#endif // CC_TREES_LAYER_TREE_HOST_H_