#include "components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h"
#include <algorithm>
#include <utility>
#include <vector>
#include "base/containers/flat_set.h"
#include "base/functional/overloaded.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/task/single_thread_task_runner.h"
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "components/viz/common/features.h"
#include "components/viz/common/frame_sinks/begin_frame_source.h"
#include "components/viz/service/display/display.h"
#include "components/viz/service/display/output_surface.h"
#include "components/viz/service/display_embedder/output_surface_provider.h"
#include "components/viz/service/display_embedder/vsync_parameter_listener.h"
#include "components/viz/service/frame_sinks/external_begin_frame_source_mojo.h"
#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
#include "components/viz/service/hit_test/hit_test_aggregator.h"
#include "services/viz/public/mojom/compositing/layer_context.mojom.h"
#include "ui/base/ozone_buildflags.h"
#include "ui/gfx/geometry/skia_conversions.h"
#if BUILDFLAG(IS_ANDROID)
#include "components/viz/service/frame_sinks/external_begin_frame_source_android.h"
#endif
#if BUILDFLAG(IS_IOS)
#include "components/viz/service/frame_sinks/external_begin_frame_source_ios.h"
#endif
#if BUILDFLAG(IS_MAC)
#include "base/feature_list.h"
#include "components/viz/service/frame_sinks/external_begin_frame_source_mac.h"
#endif
#if BUILDFLAG(IS_WIN)
#include "components/viz/service/frame_sinks/external_begin_frame_source_win.h"
#endif
namespace viz {
class RootCompositorFrameSinkImpl::StandaloneBeginFrameObserver
: public BeginFrameObserverBase { … };
std::unique_ptr<RootCompositorFrameSinkImpl>
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::~RootCompositorFrameSinkImpl() { … }
bool RootCompositorFrameSinkImpl::WillEvictSurface(
const SurfaceId& surface_id) { … }
const SurfaceId& RootCompositorFrameSinkImpl::CurrentSurfaceId() const { … }
void RootCompositorFrameSinkImpl::SetDisplayVisible(bool visible) { … }
#if BUILDFLAG(IS_WIN)
void RootCompositorFrameSinkImpl::DisableSwapUntilResize(
DisableSwapUntilResizeCallback callback) {
display_->DisableSwapUntilResize(std::move(callback));
}
#endif
void RootCompositorFrameSinkImpl::Resize(const gfx::Size& size) { … }
void RootCompositorFrameSinkImpl::SetDisplayColorMatrix(
const gfx::Transform& color_matrix) { … }
void RootCompositorFrameSinkImpl::SetDisplayColorSpaces(
const gfx::DisplayColorSpaces& display_color_spaces) { … }
#if BUILDFLAG(IS_MAC)
void RootCompositorFrameSinkImpl::SetVSyncDisplayID(int64_t display_id) {
begin_frame_source()->SetVSyncDisplayID(display_id);
}
#endif
void RootCompositorFrameSinkImpl::SetOutputIsSecure(bool secure) { … }
void RootCompositorFrameSinkImpl::SetDisplayVSyncParameters(
base::TimeTicks timebase,
base::TimeDelta interval) { … }
base::flat_set<base::TimeDelta>
RootCompositorFrameSinkImpl::GetSupportedFrameIntervals() { … }
void RootCompositorFrameSinkImpl::UpdateVSyncParameters() { … }
void RootCompositorFrameSinkImpl::ForceImmediateDrawAndSwapIfPossible() { … }
#if BUILDFLAG(IS_ANDROID)
void RootCompositorFrameSinkImpl::SetVSyncPaused(bool paused) {
if (external_begin_frame_source_)
external_begin_frame_source_->OnSetBeginFrameSourcePaused(paused);
}
void RootCompositorFrameSinkImpl::UpdateRefreshRate(float refresh_rate) {
if (external_begin_frame_source_)
external_begin_frame_source_->UpdateRefreshRate(refresh_rate);
}
void RootCompositorFrameSinkImpl::PreserveChildSurfaceControls() {
display_->PreserveChildSurfaceControls();
}
void RootCompositorFrameSinkImpl::SetSwapCompletionCallbackEnabled(
bool enable) {
enable_swap_completion_callback_ = enable;
}
#endif
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS_ASH)
void RootCompositorFrameSinkImpl::SetSupportedRefreshRates(
const std::vector<float>& supported_refresh_rates) {
#if BUILDFLAG(IS_CHROMEOS_ASH)
CHECK_NE(use_preferred_interval_,
features::IsCrosContentAdjustedRefreshRateEnabled());
if (use_preferred_interval_) {
return;
}
#endif
exact_supported_refresh_rates_.clear();
for (float rate : supported_refresh_rates) {
const base::TimeDelta interval = base::Hertz(rate);
exact_supported_refresh_rates_[interval] = rate;
}
display_->SetSupportedFrameIntervals(GetSupportedFrameIntervals());
UpdateFrameIntervalDeciderSettings();
}
#endif
void RootCompositorFrameSinkImpl::AddVSyncParameterObserver(
mojo::PendingRemote<mojom::VSyncParameterObserver> observer) { … }
void RootCompositorFrameSinkImpl::SetDelegatedInkPointRenderer(
mojo::PendingReceiver<gfx::mojom::DelegatedInkPointRenderer> receiver) { … }
void RootCompositorFrameSinkImpl::SetStandaloneBeginFrameObserver(
mojo::PendingRemote<mojom::BeginFrameObserver> observer) { … }
void RootCompositorFrameSinkImpl::SetNeedsBeginFrame(bool needs_begin_frame) { … }
void RootCompositorFrameSinkImpl::SetWantsAnimateOnlyBeginFrames() { … }
void RootCompositorFrameSinkImpl::SetWantsBeginFrameAcks() { … }
void RootCompositorFrameSinkImpl::SetAutoNeedsBeginFrame() { … }
void RootCompositorFrameSinkImpl::SubmitCompositorFrame(
const LocalSurfaceId& local_surface_id,
CompositorFrame frame,
std::optional<HitTestRegionList> hit_test_region_list,
uint64_t submit_time) { … }
void RootCompositorFrameSinkImpl::SubmitCompositorFrameSync(
const LocalSurfaceId& local_surface_id,
CompositorFrame frame,
std::optional<HitTestRegionList> hit_test_region_list,
uint64_t submit_time,
SubmitCompositorFrameSyncCallback callback) { … }
void RootCompositorFrameSinkImpl::DidNotProduceFrame(
const BeginFrameAck& begin_frame_ack) { … }
void RootCompositorFrameSinkImpl::DidAllocateSharedBitmap(
base::ReadOnlySharedMemoryRegion region,
const SharedBitmapId& id) { … }
void RootCompositorFrameSinkImpl::DidDeleteSharedBitmap(
const SharedBitmapId& id) { … }
void RootCompositorFrameSinkImpl::InitializeCompositorFrameSinkType(
mojom::CompositorFrameSinkType type) { … }
void RootCompositorFrameSinkImpl::BindLayerContext(
mojom::PendingLayerContextPtr context) { … }
#if BUILDFLAG(IS_ANDROID)
void RootCompositorFrameSinkImpl::SetThreadIds(
const std::vector<int32_t>& thread_ids) {
support_->SetThreadIds(false,
base::MakeFlatSet<base::PlatformThreadId>(thread_ids));
}
#endif
RootCompositorFrameSinkImpl::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 RootCompositorFrameSinkImpl::UpdateFrameIntervalDeciderSettings() { … }
void RootCompositorFrameSinkImpl::FrameIntervalDeciderResultCallback(
FrameIntervalDecider::Result result,
FrameIntervalMatcherType matcher_type) { … }
void RootCompositorFrameSinkImpl::DisplayOutputSurfaceLost() { … }
void RootCompositorFrameSinkImpl::DisplayWillDrawAndSwap(
bool will_draw_and_swap,
AggregatedRenderPassList* render_passes) { … }
#if BUILDFLAG(IS_ANDROID)
base::ScopedClosureRunner RootCompositorFrameSinkImpl::GetCacheBackBufferCb() {
return display_->GetCacheBackBufferCb();
}
#endif
void RootCompositorFrameSinkImpl::SetHwSupportForMultipleRefreshRates(
bool support) { … }
void RootCompositorFrameSinkImpl::StartOverdrawTracking(
int interval_length_in_seconds) { … }
OverdrawTracker::OverdrawTimeSeries
RootCompositorFrameSinkImpl::StopOverdrawTracking() { … }
void RootCompositorFrameSinkImpl::DisplayDidReceiveCALayerParams(
const gfx::CALayerParams& ca_layer_params) { … }
void RootCompositorFrameSinkImpl::DisplayDidCompleteSwapWithSize(
const gfx::Size& pixel_size) { … }
void RootCompositorFrameSinkImpl::DisplayAddChildWindowToBrowser(
gpu::SurfaceHandle child_window) { … }
void RootCompositorFrameSinkImpl::SetWideColorEnabled(bool enabled) { … }
void RootCompositorFrameSinkImpl::SetPreferredFrameInterval(
base::TimeDelta interval) { … }
base::TimeDelta
RootCompositorFrameSinkImpl::GetPreferredFrameIntervalForFrameSinkId(
const FrameSinkId& id,
mojom::CompositorFrameSinkType* type) { … }
void RootCompositorFrameSinkImpl::DisplayDidDrawAndSwap() { … }
BeginFrameSource* RootCompositorFrameSinkImpl::begin_frame_source() { … }
void RootCompositorFrameSinkImpl::SetMaxVSyncAndVrr(
std::optional<base::TimeDelta> max_vsync_interval,
display::VariableRefreshRateState vrr_state) { … }
}