1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265
|
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_VIZ_SERVICE_FRAME_SINKS_ROOT_COMPOSITOR_FRAME_SINK_IMPL_H_
#define COMPONENTS_VIZ_SERVICE_FRAME_SINKS_ROOT_COMPOSITOR_FRAME_SINK_IMPL_H_
#include <memory>
#include <optional>
#include <vector>
#include "base/containers/flat_set.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/read_only_shared_memory_region.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "components/viz/common/surfaces/frame_sink_id.h"
#include "components/viz/common/surfaces/local_surface_id.h"
#include "components/viz/service/display/display_client.h"
#include "components/viz/service/display/frame_interval_decider.h"
#include "components/viz/service/display/overdraw_tracker.h"
#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
#include "components/viz/service/viz_service_export.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/viz/privileged/mojom/compositing/begin_frame_observer.mojom.h"
#include "services/viz/privileged/mojom/compositing/display_private.mojom.h"
#include "services/viz/privileged/mojom/compositing/frame_sink_manager.mojom.h"
#include "services/viz/public/mojom/compositing/compositor_frame_sink.mojom.h"
#include "ui/base/ozone_buildflags.h"
#include "ui/gfx/ca_layer_params.h"
#if BUILDFLAG(IS_ANDROID)
#include "ui/gfx/android/surface_control_frame_rate.h"
#endif
namespace viz {
class Display;
class OutputSurfaceProvider;
class ExternalBeginFrameSource;
class FrameSinkManagerImpl;
class HintSessionFactory;
class SyntheticBeginFrameSource;
class VSyncParameterListener;
// The viz portion of a root CompositorFrameSink. Holds the Binding/InterfacePtr
// for the mojom::CompositorFrameSink interface and owns the Display.
class VIZ_SERVICE_EXPORT RootCompositorFrameSinkImpl
: public mojom::CompositorFrameSink,
public mojom::DisplayPrivate,
public DisplayClient {
public:
// Creates a new RootCompositorFrameSinkImpl.
static std::unique_ptr<RootCompositorFrameSinkImpl> Create(
mojom::RootCompositorFrameSinkParamsPtr params,
FrameSinkManagerImpl* frame_sink_manager,
OutputSurfaceProvider* output_surface_provider,
uint32_t restart_id,
bool run_all_compositor_stages_before_draw,
const DebugRendererSettings* debug_settings,
HintSessionFactory* hint_session_factory);
RootCompositorFrameSinkImpl(const RootCompositorFrameSinkImpl&) = delete;
RootCompositorFrameSinkImpl& operator=(const RootCompositorFrameSinkImpl&) =
delete;
~RootCompositorFrameSinkImpl() override;
void DidEvictSurface(const SurfaceId& surface_id);
const SurfaceId& CurrentSurfaceId() const;
// mojom::DisplayPrivate:
void SetDisplayVisible(bool visible) override;
#if BUILDFLAG(IS_WIN)
void DisableSwapUntilResize(DisableSwapUntilResizeCallback callback) override;
#endif
void Resize(const gfx::Size& size) override;
void SetDisplayColorMatrix(const gfx::Transform& color_matrix) override;
void SetDisplayColorSpaces(
const gfx::DisplayColorSpaces& display_color_spaces) override;
#if BUILDFLAG(IS_MAC)
void SetVSyncDisplayID(int64_t display_id) override;
#endif
void SetOutputIsSecure(bool secure) override;
void SetDisplayVSyncParameters(base::TimeTicks timebase,
base::TimeDelta interval) override;
void ForceImmediateDrawAndSwapIfPossible() override;
#if BUILDFLAG(IS_ANDROID)
void UpdateRefreshRate(float refresh_rate) override;
void SetAdaptiveRefreshRateInfo(
bool has_support,
float suggested_high,
float device_scale_factor) override;
void PreserveChildSurfaceControls() override;
void SetSwapCompletionCallbackEnabled(bool enable) override;
#endif // BUILDFLAG(IS_ANDROID)
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS)
void SetSupportedRefreshRates(
const std::vector<float>& supported_refresh_rates) override;
#endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS)
void AddVSyncParameterObserver(
mojo::PendingRemote<mojom::VSyncParameterObserver> observer) override;
void SetDelegatedInkPointRenderer(
mojo::PendingReceiver<gfx::mojom::DelegatedInkPointRenderer> receiver)
override;
void SetStandaloneBeginFrameObserver(
mojo::PendingRemote<mojom::BeginFrameObserver> observer) override;
void SetMaxVSyncAndVrr(std::optional<base::TimeDelta> max_vsync_interval,
display::VariableRefreshRateState vrr_state) override;
// mojom::CompositorFrameSink:
void SetNeedsBeginFrame(bool needs_begin_frame) override;
void SetWantsAnimateOnlyBeginFrames() override;
void SetAutoNeedsBeginFrame() override;
void SubmitCompositorFrame(
const LocalSurfaceId& local_surface_id,
CompositorFrame frame,
std::optional<HitTestRegionList> hit_test_region_list,
uint64_t submit_time) override;
void DidNotProduceFrame(const BeginFrameAck& begin_frame_ack) override;
void SubmitCompositorFrameSync(
const LocalSurfaceId& local_surface_id,
CompositorFrame frame,
std::optional<HitTestRegionList> hit_test_region_list,
uint64_t submit_time,
SubmitCompositorFrameSyncCallback callback) override;
void NotifyNewLocalSurfaceIdExpectedWhilePaused() override;
void BindLayerContext(mojom::PendingLayerContextPtr context,
bool draw_mode_is_gpu) override;
#if BUILDFLAG(IS_ANDROID)
void SetThreads(const std::vector<Thread>& threads) override;
#endif
#if BUILDFLAG(IS_ANDROID)
base::ScopedClosureRunner GetCacheBackBufferCb();
#endif
ExternalBeginFrameSource* external_begin_frame_source() {
return external_begin_frame_source_.get();
}
void SetHwSupportForMultipleRefreshRates(bool support);
void StartOverdrawTracking(int interval_length_in_seconds);
OverdrawTracker::OverdrawTimeSeries StopOverdrawTracking();
private:
class StandaloneBeginFrameObserver;
RootCompositorFrameSinkImpl(
FrameSinkManagerImpl* frame_sink_manager,
const FrameSinkId& frame_sink_id,
mojo::PendingAssociatedReceiver<mojom::CompositorFrameSink>
frame_sink_receiver,
mojo::PendingRemote<mojom::CompositorFrameSinkClient> frame_sink_client,
mojo::PendingAssociatedReceiver<mojom::DisplayPrivate> display_receiver,
mojo::Remote<mojom::DisplayClient> display_client,
std::unique_ptr<SyntheticBeginFrameSource> synthetic_begin_frame_source,
std::unique_ptr<ExternalBeginFrameSource> external_begin_frame_source,
std::unique_ptr<Display> display,
bool hw_support_for_multiple_refresh_rates);
void UpdateFrameIntervalDeciderSettings();
void FrameIntervalDeciderResultCallback(
FrameIntervalDecider::Result result,
FrameIntervalMatcherType matcher_type);
// DisplayClient:
void DisplayOutputSurfaceLost() override;
void DisplayWillDrawAndSwap(bool will_draw_and_swap,
AggregatedRenderPassList* render_passes) override;
void DisplayDidDrawAndSwap() override;
void DisplayDidReceiveCALayerParams(
const gfx::CALayerParams& ca_layer_params) override;
void DisplayDidCompleteSwapWithSize(const gfx::Size& pixel_size) override;
void DisplayAddChildWindowToBrowser(gpu::SurfaceHandle child_window) override;
void SetWideColorEnabled(bool enabled) override;
void SetPreferredFrameInterval(base::TimeDelta interval);
void UpdateVSyncParameters();
BeginFrameSource* begin_frame_source();
base::flat_set<base::TimeDelta> GetSupportedFrameIntervals();
mojo::Remote<mojom::CompositorFrameSinkClient> compositor_frame_sink_client_;
mojo::AssociatedReceiver<mojom::CompositorFrameSink>
compositor_frame_sink_receiver_;
// |display_client_| may be NullRemote on platforms that do not use it.
[[maybe_unused]] mojo::Remote<mojom::DisplayClient> display_client_;
mojo::AssociatedReceiver<mojom::DisplayPrivate> display_private_receiver_;
std::unique_ptr<VSyncParameterListener> vsync_listener_;
// Must be destroyed before |compositor_frame_sink_client_|. This must never
// change for the lifetime of RootCompositorFrameSinkImpl.
const std::unique_ptr<CompositorFrameSinkSupport> support_;
// FrameIntervalDecider related members.
// True indicates FrameIntervalDecider uses FixedIntervalSettings.
bool interval_decider_use_fixed_intervals_ = true;
// The current display frame interval that FrameIntervalDecider decided on.
base::TimeDelta decided_display_interval_;
#if BUILDFLAG(IS_ANDROID)
gfx::SurfaceControlFrameRateCompatibility decided_display_frame_rate_compat_ =
gfx::SurfaceControlFrameRateCompatibility::kFixedSource;
#endif
// RootCompositorFrameSinkImpl holds a Display and a BeginFrameSource if it
// was created with a non-null gpu::SurfaceHandle. The source can either be a
// |synthetic_begin_frame_source_| or an |external_begin_frame_source_|.
std::unique_ptr<SyntheticBeginFrameSource> synthetic_begin_frame_source_;
// If non-null, |synthetic_begin_frame_source_| will not exist.
std::unique_ptr<ExternalBeginFrameSource> external_begin_frame_source_;
// Should be destroyed before begin frame sources since it can issue callbacks
// to the BFS.
std::unique_ptr<Display> display_;
std::unique_ptr<StandaloneBeginFrameObserver>
standalone_begin_frame_observer_;
// |use_preferred_interval_| indicates if we should use the preferred interval
// from FrameRateDecider to tick.
bool use_preferred_interval_ = false;
base::TimeTicks display_frame_timebase_;
base::TimeDelta display_frame_interval_ = BeginFrameArgs::DefaultInterval();
base::TimeDelta preferred_frame_interval_;
#if BUILDFLAG(IS_LINUX) && BUILDFLAG(IS_OZONE_X11)
gfx::Size last_swap_pixel_size_;
#endif // BUILDFLAG(IS_LINUX) && BUILDFLAG(IS_OZONE_X11)
#if BUILDFLAG(IS_APPLE)
gfx::CALayerParams last_ca_layer_params_;
// Used to force a call to OnDisplayReceivedCALayerParams() even if the params
// did not change.
base::TimeTicks next_forced_ca_layer_params_update_time_;
#endif
#if BUILDFLAG(IS_ANDROID)
// Let client control whether it wants `DidCompleteSwapWithSize`.
bool enable_swap_completion_callback_ = false;
bool supports_adaptive_refresh_rate_ = false;
base::TimeDelta suggested_frame_interval_high_;
float device_scale_factor_ = 1.0f;
#endif
// Map which retains the exact supported refresh rates, keyed by their
// interval conversion value which may be subject to precision loss.
base::flat_map<base::TimeDelta, float> exact_supported_refresh_rates_;
// The maximum interval that the display supports. Used for VRR (variable
// refresh rate) or continuous range framerate selection in
// `FrameIntervalDecider`. Absent if the display does not support those
// features.
std::optional<base::TimeDelta> max_vsync_interval_ = std::nullopt;
};
} // namespace viz
#endif // COMPONENTS_VIZ_SERVICE_FRAME_SINKS_ROOT_COMPOSITOR_FRAME_SINK_IMPL_H_
|