123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574 |
- // Copyright (c) 2012 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef UI_COMPOSITOR_COMPOSITOR_H_
- #define UI_COMPOSITOR_COMPOSITOR_H_
- #include <stdint.h>
- #include <memory>
- #include <unordered_set>
- #include "base/callback_forward.h"
- #include "base/containers/flat_map.h"
- #include "base/containers/flat_set.h"
- #include "base/memory/raw_ptr.h"
- #include "base/memory/ref_counted.h"
- #include "base/observer_list.h"
- #include "base/power_monitor/power_observer.h"
- #include "base/task/single_thread_task_runner.h"
- #include "base/time/time.h"
- #include "build/build_config.h"
- #include "build/chromeos_buildflags.h"
- #include "cc/metrics/events_metrics_manager.h"
- #include "cc/metrics/frame_sequence_tracker.h"
- #include "cc/paint/element_id.h"
- #include "cc/trees/layer_tree_host.h"
- #include "cc/trees/layer_tree_host_client.h"
- #include "cc/trees/layer_tree_host_single_thread_client.h"
- #include "cc/trees/paint_holding_reason.h"
- #include "components/viz/common/frame_sinks/begin_frame_args.h"
- #include "components/viz/common/surfaces/frame_sink_id.h"
- #include "components/viz/common/surfaces/subtree_capture_id.h"
- #include "components/viz/host/host_frame_sink_client.h"
- #include "mojo/public/cpp/bindings/pending_remote.h"
- #include "services/viz/privileged/mojom/compositing/vsync_parameter_observer.mojom-forward.h"
- #include "third_party/skia/include/core/SkColor.h"
- #include "third_party/skia/include/core/SkM44.h"
- #include "ui/compositor/compositor_animation_observer.h"
- #include "ui/compositor/compositor_export.h"
- #include "ui/compositor/compositor_lock.h"
- #include "ui/compositor/compositor_observer.h"
- #include "ui/compositor/layer_animator_collection.h"
- #include "ui/compositor/throughput_tracker.h"
- #include "ui/compositor/throughput_tracker_host.h"
- #include "ui/gfx/display_color_spaces.h"
- #include "ui/gfx/geometry/size.h"
- #include "ui/gfx/geometry/vector2d.h"
- #include "ui/gfx/gpu_memory_buffer.h"
- #include "ui/gfx/native_widget_types.h"
- #include "ui/gfx/overlay_transform.h"
- namespace base {
- class SingleThreadTaskRunner;
- }
- namespace cc {
- class AnimationHost;
- class AnimationTimeline;
- class Layer;
- class LayerTreeDebugState;
- class LayerTreeFrameSink;
- class LayerTreeSettings;
- class TaskGraphRunner;
- }
- namespace gfx {
- namespace mojom {
- class DelegatedInkPointRenderer;
- } // namespace mojom
- struct PresentationFeedback;
- class Rect;
- class Size;
- }
- namespace gpu {
- class GpuMemoryBufferManager;
- }
- namespace viz {
- namespace mojom {
- class DisplayPrivate;
- class ExternalBeginFrameController;
- } // namespace mojom
- class ContextProvider;
- class HostFrameSinkManager;
- class LocalSurfaceId;
- class RasterContextProvider;
- } // namespace viz
- namespace ui {
- class Compositor;
- class Layer;
- class ScopedAnimationDurationScaleMode;
- class ScrollInputHandler;
- class ThroughputTracker;
- struct PendingBeginFrameArgs;
- constexpr int kCompositorLockTimeoutMs = 67;
- // This class abstracts the creation of the 3D context for the compositor. It is
- // a global object.
- class COMPOSITOR_EXPORT ContextFactory {
- public:
- virtual ~ContextFactory() {}
- // Creates an output surface for the given compositor. The factory may keep
- // per-compositor data (e.g. a shared context), that needs to be cleaned up
- // by calling RemoveCompositor when the compositor gets destroyed.
- virtual void CreateLayerTreeFrameSink(
- base::WeakPtr<Compositor> compositor) = 0;
- // Return a reference to a shared offscreen context provider usable from the
- // main thread.
- virtual scoped_refptr<viz::ContextProvider>
- SharedMainThreadContextProvider() = 0;
- // Return a reference to a shared offscreen context provider usable from the
- // main thread.
- virtual scoped_refptr<viz::RasterContextProvider>
- SharedMainThreadRasterContextProvider() = 0;
- // Destroys per-compositor data.
- virtual void RemoveCompositor(Compositor* compositor) = 0;
- // Gets the GPU memory buffer manager.
- virtual gpu::GpuMemoryBufferManager* GetGpuMemoryBufferManager() = 0;
- // Gets the task graph runner.
- virtual cc::TaskGraphRunner* GetTaskGraphRunner() = 0;
- // Allocate a new client ID for the display compositor.
- virtual viz::FrameSinkId AllocateFrameSinkId() = 0;
- // Allocates a new capture ID for a layer subtree within a frame sink.
- virtual viz::SubtreeCaptureId AllocateSubtreeCaptureId() = 0;
- // Gets the frame sink manager host instance.
- virtual viz::HostFrameSinkManager* GetHostFrameSinkManager() = 0;
- };
- // Compositor object to take care of GPU painting.
- // A Browser compositor object is responsible for generating the final
- // displayable form of pixels comprising a single widget's contents. It draws an
- // appropriately transformed texture for each transformed view in the widget's
- // view hierarchy.
- class COMPOSITOR_EXPORT Compositor : public base::PowerSuspendObserver,
- public cc::LayerTreeHostClient,
- public cc::LayerTreeHostSingleThreadClient,
- public viz::HostFrameSinkClient,
- public ThroughputTrackerHost {
- public:
- Compositor(const viz::FrameSinkId& frame_sink_id,
- ui::ContextFactory* context_factory,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner,
- bool enable_pixel_canvas,
- bool use_external_begin_frame_control = false,
- bool force_software_compositor = false,
- bool enable_compositing_based_throttling = false,
- size_t memory_limit_when_visible_mb = 0);
- Compositor(const Compositor&) = delete;
- Compositor& operator=(const Compositor&) = delete;
- ~Compositor() override;
- ui::ContextFactory* context_factory() { return context_factory_; }
- void AddChildFrameSink(const viz::FrameSinkId& frame_sink_id);
- void RemoveChildFrameSink(const viz::FrameSinkId& frame_sink_id);
- void SetLayerTreeFrameSink(std::unique_ptr<cc::LayerTreeFrameSink> surface,
- viz::mojom::DisplayPrivate* display_private);
- void SetExternalBeginFrameController(viz::mojom::ExternalBeginFrameController*
- external_begin_frame_controller);
- // Called when a child surface is about to resize.
- void OnChildResizing();
- // Schedules a redraw of the layer tree associated with this compositor.
- void ScheduleDraw();
- // Sets the root of the layer tree drawn by this Compositor. The root layer
- // must have no parent. The compositor's root layer is reset if the root layer
- // is destroyed. NULL can be passed to reset the root layer, in which case the
- // compositor will stop drawing anything.
- // The Compositor does not own the root layer.
- const Layer* root_layer() const { return root_layer_; }
- Layer* root_layer() { return root_layer_; }
- void SetRootLayer(Layer* root_layer);
- // HideHelper temporarily hides the root layer and replaces it with a
- // temporary layer, without calling SetRootLayer (but doing much of the work
- // that SetRootLayer does). During that time we must disable ticking
- // of animations, since animations that animate layers that are not in
- // cc's layer tree must not tick. These methods make those changes
- // and record/reflect that state.
- void DisableAnimations();
- void EnableAnimations();
- bool animations_are_enabled() const { return animations_are_enabled_; }
- cc::AnimationTimeline* GetAnimationTimeline() const;
- // The scale factor of the device that this compositor is
- // compositing layers on.
- float device_scale_factor() const { return device_scale_factor_; }
- // Gets and sets the color matrix used to transform the output colors of what
- // this compositor renders.
- const SkM44& display_color_matrix() const { return display_color_matrix_; }
- void SetDisplayColorMatrix(const SkM44& matrix);
- // Where possible, draws are scissored to a damage region calculated from
- // changes to layer properties. This bypasses that and indicates that
- // the whole frame needs to be drawn.
- void ScheduleFullRedraw();
- // Schedule redraw and append damage_rect to the damage region calculated
- // from changes to layer properties.
- void ScheduleRedrawRect(const gfx::Rect& damage_rect);
- #if BUILDFLAG(IS_WIN)
- // Until this is called with |should| true then both DisableSwapUntilResize()
- // and ReenableSwap() do nothing.
- void SetShouldDisableSwapUntilResize(bool should);
- // Attempts to immediately swap a frame with the current size if possible,
- // then disables swapping on this surface until it is resized.
- void DisableSwapUntilResize();
- void ReenableSwap();
- #endif
- // Sets the compositor's device scale factor and size.
- void SetScaleAndSize(float scale,
- const gfx::Size& size_in_pixel,
- const viz::LocalSurfaceId& local_surface_id);
- // Set the output color profile into which this compositor should render. Also
- // sets the SDR white level (in nits) used to scale HDR color space primaries.
- void SetDisplayColorSpaces(
- const gfx::DisplayColorSpaces& display_color_spaces);
- const gfx::DisplayColorSpaces& display_color_spaces() const {
- return display_color_spaces_;
- }
- // Set the transform/rotation info for the display output surface.
- void SetDisplayTransformHint(gfx::OverlayTransform hint);
- gfx::OverlayTransform display_transform_hint() const {
- return host_->display_transform_hint();
- }
- // Returns the size of the widget that is being drawn to in pixel coordinates.
- const gfx::Size& size() const { return size_; }
- // Sets the background color used for areas that aren't covered by
- // the |root_layer|.
- void SetBackgroundColor(SkColor color);
- // Inform the display corresponding to this compositor if it is visible. When
- // false it does not need to produce any frames. Visibility is reset for each
- // call to CreateLayerTreeFrameSink.
- void SetVisible(bool visible);
- // Gets the visibility of the underlying compositor.
- bool IsVisible();
- // Gets or sets the scroll offset for the given layer in step with the
- // cc::InputHandler. Returns true if the layer is active on the impl side.
- bool GetScrollOffsetForLayer(cc::ElementId element_id,
- gfx::PointF* offset) const;
- bool ScrollLayerTo(cc::ElementId element_id, const gfx::PointF& offset);
- // Mac path for transporting vsync parameters to the display. Other platforms
- // update it via the BrowserCompositorLayerTreeFrameSink directly.
- void SetDisplayVSyncParameters(base::TimeTicks timebase,
- base::TimeDelta interval);
- void AddVSyncParameterObserver(
- mojo::PendingRemote<viz::mojom::VSyncParameterObserver> observer);
- // Sets the widget for the compositor to render into.
- void SetAcceleratedWidget(gfx::AcceleratedWidget widget);
- // Releases the widget previously set through SetAcceleratedWidget().
- // After returning it will not be used for rendering anymore.
- // The compositor must be set to invisible when taking away a widget.
- gfx::AcceleratedWidget ReleaseAcceleratedWidget();
- gfx::AcceleratedWidget widget() const;
- // This flag is used to force a compositor into software compositing even tho
- // in general chrome is using gpu compositing. This allows the compositor to
- // be created without a gpu context, and does not go through the gpu path at
- // all. This flag can not be used with a compositor that embeds any external
- // content via a SurfaceLayer, as they would not agree on what compositing
- // mode to use for resources, but may be used eg for tooltip windows.
- bool force_software_compositor() { return force_software_compositor_; }
- // Returns the main thread task runner this compositor uses. Users of the
- // compositor generally shouldn't use this.
- scoped_refptr<base::SingleThreadTaskRunner> task_runner() const {
- return task_runner_;
- }
- // Compositor does not own observers. It is the responsibility of the
- // observer to remove itself when it is done observing.
- void AddObserver(CompositorObserver* observer);
- void RemoveObserver(CompositorObserver* observer);
- bool HasObserver(const CompositorObserver* observer) const;
- void AddAnimationObserver(CompositorAnimationObserver* observer);
- void RemoveAnimationObserver(CompositorAnimationObserver* observer);
- bool HasAnimationObserver(const CompositorAnimationObserver* observer) const;
- // Creates a compositor lock. Returns NULL if it is not possible to lock at
- // this time (i.e. we're waiting to complete a previous unlock). If the
- // timeout is null, then no timeout is used.
- std::unique_ptr<CompositorLock> GetCompositorLock(
- CompositorLockClient* client,
- base::TimeDelta timeout = base::Milliseconds(kCompositorLockTimeoutMs)) {
- return lock_manager_.GetCompositorLock(client, timeout,
- host_->DeferMainFrameUpdate());
- }
- // 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).
- // See ui/gfx/presentation_feedback.h for details on the args (TimeTicks is
- // always non-zero).
- using PresentationTimeCallback =
- base::OnceCallback<void(const gfx::PresentationFeedback&)>;
- void RequestPresentationTimeForNextFrame(PresentationTimeCallback callback);
- void IssueExternalBeginFrame(
- const viz::BeginFrameArgs& args,
- bool force,
- base::OnceCallback<void(const viz::BeginFrameAck&)> callback);
- // Creates a ThroughputTracker for tracking this Compositor.
- ThroughputTracker RequestNewThroughputTracker();
- // Returns a percentage of dropped frames of the last second.
- double GetPercentDroppedFrames() const;
- // Activates a scoped monitor for the current event to track its metrics.
- // `done_callback` is called when the monitor goes out of scope.
- std::unique_ptr<cc::EventsMetricsManager::ScopedMonitor>
- GetScopedEventMetricsMonitor(
- cc::EventsMetricsManager::ScopedMonitor::DoneCallback done_callback);
- // LayerTreeHostClient implementation.
- void WillBeginMainFrame() override {}
- void DidBeginMainFrame() override {}
- void OnDeferMainFrameUpdatesChanged(bool) override {}
- void OnDeferCommitsChanged(
- bool,
- cc::PaintHoldingReason,
- absl::optional<cc::PaintHoldingCommitTrigger>) override {}
- void WillUpdateLayers() override {}
- void DidUpdateLayers() override;
- void BeginMainFrame(const viz::BeginFrameArgs& args) override;
- void BeginMainFrameNotExpectedSoon() override;
- void BeginMainFrameNotExpectedUntil(base::TimeTicks time) override;
- void UpdateLayerTreeHost() override;
- void ApplyViewportChanges(const cc::ApplyViewportChangesArgs& args) override {
- }
- void UpdateCompositorScrollState(
- const cc::CompositorCommitData& commit_data) override {}
- void RequestNewLayerTreeFrameSink() override;
- void DidInitializeLayerTreeFrameSink() override {}
- void DidFailToInitializeLayerTreeFrameSink() override;
- void WillCommit(const cc::CommitState&) override {}
- void DidCommit(base::TimeTicks, base::TimeTicks) override;
- void DidCommitAndDrawFrame() override {}
- void DidReceiveCompositorFrameAck() override;
- void DidCompletePageScaleAnimation() override {}
- void DidPresentCompositorFrame(
- uint32_t frame_token,
- const gfx::PresentationFeedback& feedback) override;
- void RecordStartOfFrameMetrics() override {}
- void RecordEndOfFrameMetrics(
- base::TimeTicks frame_begin_time,
- cc::ActiveFrameSequenceTrackers trackers) override {}
- std::unique_ptr<cc::BeginMainFrameMetrics> GetBeginMainFrameMetrics()
- override;
- std::unique_ptr<cc::WebVitalMetrics> GetWebVitalMetrics() override;
- void NotifyThroughputTrackerResults(
- cc::CustomTrackerResults results) override;
- void DidObserveFirstScrollDelay(
- base::TimeDelta first_scroll_delay,
- base::TimeTicks first_scroll_timestamp) override {}
- void ReportEventLatency(
- std::vector<cc::EventLatencyTracker::LatencyData> latencies) override;
- // cc::LayerTreeHostSingleThreadClient implementation.
- void DidSubmitCompositorFrame() override;
- void DidLoseLayerTreeFrameSink() override {}
- void FrameIntervalUpdated(base::TimeDelta interval) override;
- void FrameSinksToThrottleUpdated(
- const base::flat_set<viz::FrameSinkId>& ids) override;
- // viz::HostFrameSinkClient implementation.
- void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override;
- void OnFrameTokenChanged(uint32_t frame_token,
- base::TimeTicks activation_time) override;
- // ThroughputTrackerHost implementation.
- void StartThroughputTracker(
- TrackerId tracker_id,
- ThroughputTrackerHost::ReportCallback callback) override;
- bool StopThroughtputTracker(TrackerId tracker_id) override;
- void CancelThroughtputTracker(TrackerId tracker_id) override;
- // base::PowerSuspendObserver:
- void OnResume() override;
- // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
- // of lacros-chrome is complete.
- #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
- void OnCompleteSwapWithNewSize(const gfx::Size& size);
- #endif
- bool IsLocked() { return lock_manager_.IsLocked(); }
- void SetOutputIsSecure(bool output_is_secure);
- const cc::LayerTreeDebugState& GetLayerTreeDebugState() const;
- void SetLayerTreeDebugState(const cc::LayerTreeDebugState& debug_state);
- LayerAnimatorCollection* layer_animator_collection() {
- return &layer_animator_collection_;
- }
- const viz::FrameSinkId& frame_sink_id() const { return frame_sink_id_; }
- int activated_frame_count() const { return activated_frame_count_; }
- float refresh_rate() const { return refresh_rate_; }
- bool use_external_begin_frame_control() const {
- return use_external_begin_frame_control_;
- }
- void SetAllowLocksToExtendTimeout(bool allowed) {
- lock_manager_.set_allow_locks_to_extend_timeout(allowed);
- }
- // If true, all paint commands are recorded at pixel size instead of DIP.
- bool is_pixel_canvas() const { return is_pixel_canvas_; }
- ScrollInputHandler* scroll_input_handler() const {
- return scroll_input_handler_.get();
- }
- virtual void SetDelegatedInkPointRenderer(
- mojo::PendingReceiver<gfx::mojom::DelegatedInkPointRenderer> receiver);
- const cc::LayerTreeSettings& GetLayerTreeSettings() const;
- private:
- friend class base::RefCounted<Compositor>;
- friend class TotalAnimationThroughputReporter;
- // Called when collected metrics for the tracker of |tracker_id| is ready.
- void ReportMetricsForTracker(
- int tracker_id,
- const cc::FrameSequenceMetrics::CustomReportData& data);
- gfx::Size size_;
- raw_ptr<ui::ContextFactory> context_factory_;
- // |display_private_| can be null for:
- // 1. Tests that don't set |display_private_|.
- // 2. Intermittently on creation or if there is some kind of error (GPU crash,
- // GL context loss, etc.) that triggers reinitializing message pipes to the
- // GPU process RootCompositorFrameSinkImpl.
- // Therefore, it should always be null checked for safety before use.
- //
- // These pointers are owned by |context_factory_|, and must be reset before
- // calling RemoveCompositor();
- raw_ptr<viz::mojom::DisplayPrivate, DanglingUntriaged> display_private_ =
- nullptr;
- raw_ptr<viz::mojom::ExternalBeginFrameController>
- external_begin_frame_controller_ = nullptr;
- std::unique_ptr<PendingBeginFrameArgs> pending_begin_frame_args_;
- // The root of the Layer tree drawn by this compositor.
- raw_ptr<Layer> root_layer_ = nullptr;
- base::ObserverList<CompositorObserver, true>::Unchecked observer_list_;
- base::ObserverList<CompositorAnimationObserver>::Unchecked
- animation_observer_list_;
- gfx::AcceleratedWidget widget_ = gfx::kNullAcceleratedWidget;
- // A sequence number of a current compositor frame for use with metrics.
- int activated_frame_count_ = 0;
- // Current vsync refresh rate per second. Initialized to 60hz as a reasonable
- // value until first begin frame arrives with the real refresh rate.
- float refresh_rate_ = 60.f;
- // A map from child id to parent id.
- std::unordered_set<viz::FrameSinkId, viz::FrameSinkIdHash> child_frame_sinks_;
- bool widget_valid_ = false;
- bool layer_tree_frame_sink_requested_ = false;
- const viz::FrameSinkId frame_sink_id_;
- scoped_refptr<cc::Layer> root_web_layer_;
- std::unique_ptr<cc::AnimationHost> animation_host_;
- std::unique_ptr<cc::LayerTreeHost> host_;
- base::WeakPtr<cc::InputHandler> input_handler_weak_;
- scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
- // Snapshot of last set vsync parameters, to avoid redundant IPCs.
- base::TimeTicks vsync_timebase_;
- base::TimeDelta vsync_interval_ = viz::BeginFrameArgs::DefaultInterval();
- bool has_vsync_params_ = false;
- const bool use_external_begin_frame_control_;
- const bool force_software_compositor_;
- // The device scale factor of the monitor that this compositor is compositing
- // layers on.
- float device_scale_factor_ = 0.f;
- LayerAnimatorCollection layer_animator_collection_;
- scoped_refptr<cc::AnimationTimeline> animation_timeline_;
- std::unique_ptr<ScopedAnimationDurationScaleMode> slow_animations_;
- SkM44 display_color_matrix_;
- gfx::DisplayColorSpaces display_color_spaces_;
- bool output_is_secure_ = false;
- // If true, all paint commands are recorded at pixel size instead of DIP.
- const bool is_pixel_canvas_;
- CompositorLockManager lock_manager_;
- std::unique_ptr<ScrollInputHandler> scroll_input_handler_;
- #if BUILDFLAG(IS_WIN)
- bool should_disable_swap_until_resize_ = false;
- #endif
- // Set in DisableSwapUntilResize and reset when a resize happens.
- bool disabled_swap_until_resize_ = false;
- bool animations_are_enabled_ = true;
- TrackerId next_throughput_tracker_id_ = 1u;
- struct TrackerState {
- TrackerState();
- TrackerState(TrackerState&&);
- TrackerState& operator=(TrackerState&&);
- ~TrackerState();
- // Whether a tracker is waiting for report and `report_callback` should be
- // invoked. This is set to true when a tracker is stopped.
- bool should_report = false;
- // Whether the report for a tracker has happened. This is set when an
- // involuntary report happens before the tracker is stopped and set
- // `should_report` field above.
- bool report_attempted = false;
- // Invoked to send report to the owner of a tracker.
- ThroughputTrackerHost::ReportCallback report_callback;
- };
- using ThroughputTrackerMap = base::flat_map<TrackerId, TrackerState>;
- ThroughputTrackerMap throughput_tracker_map_;
- base::WeakPtrFactory<Compositor> context_creation_weak_ptr_factory_{this};
- base::WeakPtrFactory<Compositor> weak_ptr_factory_{this};
- };
- } // namespace ui
- #endif // UI_COMPOSITOR_COMPOSITOR_H_
|