chore: cherry-pick e6e23ba00379 from chromium (#38323)
* chore: cherry-pick e6e23ba00379 from chromium * make it work
This commit is contained in:
parent
c7ca29e80f
commit
2a16c73834
3 changed files with 664 additions and 0 deletions
|
@ -125,3 +125,5 @@ chore_patch_out_profile_methods_in_profile_selections_cc.patch
|
|||
add_gin_converter_support_for_arraybufferview.patch
|
||||
chore_defer_usb_service_getdevices_request_until_usb_service_is.patch
|
||||
fix_remove_profiles_from_spellcheck_service.patch
|
||||
cherry-pick-48a136e77e6d.patch
|
||||
cherry-pick-e6e23ba00379.patch
|
||||
|
|
232
patches/chromium/cherry-pick-48a136e77e6d.patch
Normal file
232
patches/chromium/cherry-pick-48a136e77e6d.patch
Normal file
|
@ -0,0 +1,232 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Christopher Cameron <ccameron@chromium.org>
|
||||
Date: Mon, 15 May 2023 23:09:29 +0000
|
||||
Subject: ui::Compositor: Propagate display ID
|
||||
|
||||
The display ID originates in BrowserCompositorMac (for things like
|
||||
ContentShell) or in NativeWidgetMacNSWindowHost (for views).
|
||||
|
||||
Add it as a parameter to RecyclableCompositorMac::UpdateSurface and
|
||||
use this to propagate it to ui::Compositor.
|
||||
|
||||
Ensure that its initial value is propagated correctly in
|
||||
ui::Compositor::SetLayerTreeFrameSink.
|
||||
|
||||
Remove use of base::LazyInstance from BrowserCompositorMac (it is
|
||||
long deprecated, and touching the file triggered presubmit failures).
|
||||
|
||||
Bug: 1404797
|
||||
Change-Id: Ib39addd1ac2a3b2f42e1958d7ab7c6c4750224f8
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4517539
|
||||
Commit-Queue: ccameron chromium <ccameron@chromium.org>
|
||||
Reviewed-by: Maggie Chen <magchen@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1144438}
|
||||
|
||||
diff --git a/content/browser/renderer_host/browser_compositor_view_mac.mm b/content/browser/renderer_host/browser_compositor_view_mac.mm
|
||||
index 323548d3ed7be2e2572c0048dbf5f0fa464016dc..b7311c83633746855b1e7086b6824879c1870b28 100644
|
||||
--- a/content/browser/renderer_host/browser_compositor_view_mac.mm
|
||||
+++ b/content/browser/renderer_host/browser_compositor_view_mac.mm
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "base/containers/circular_deque.h"
|
||||
-#include "base/lazy_instance.h"
|
||||
+#include "base/no_destructor.h"
|
||||
#include "base/trace_event/trace_event.h"
|
||||
#include "components/viz/common/features.h"
|
||||
#include "components/viz/common/surfaces/local_surface_id.h"
|
||||
@@ -38,8 +38,10 @@
|
||||
// signals to shut down will come in very late, long after things that the
|
||||
// ui::Compositor depend on have been destroyed).
|
||||
// https://crbug.com/805726
|
||||
-base::LazyInstance<std::set<BrowserCompositorMac*>>::Leaky
|
||||
- g_browser_compositors;
|
||||
+std::set<BrowserCompositorMac*>& GetBrowserCompositors() {
|
||||
+ static base::NoDestructor<std::set<BrowserCompositorMac*>> instance;
|
||||
+ return *instance.get();
|
||||
+}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -54,7 +56,7 @@
|
||||
: client_(client),
|
||||
accelerated_widget_mac_ns_view_(accelerated_widget_mac_ns_view),
|
||||
weak_factory_(this) {
|
||||
- g_browser_compositors.Get().insert(this);
|
||||
+ GetBrowserCompositors().insert(this);
|
||||
|
||||
root_layer_ = std::make_unique<ui::Layer>(ui::LAYER_SOLID_COLOR);
|
||||
// Ensure that this layer draws nothing when it does not not have delegated
|
||||
@@ -75,7 +77,7 @@
|
||||
delegated_frame_host_.reset();
|
||||
root_layer_.reset();
|
||||
|
||||
- size_t num_erased = g_browser_compositors.Get().erase(this);
|
||||
+ size_t num_erased = GetBrowserCompositors().erase(this);
|
||||
DCHECK_EQ(1u, num_erased);
|
||||
}
|
||||
|
||||
@@ -138,9 +140,9 @@
|
||||
}
|
||||
|
||||
if (recyclable_compositor_) {
|
||||
- recyclable_compositor_->UpdateSurface(dfh_size_pixels_,
|
||||
- current.device_scale_factor,
|
||||
- current.display_color_spaces);
|
||||
+ recyclable_compositor_->UpdateSurface(
|
||||
+ dfh_size_pixels_, current.device_scale_factor,
|
||||
+ current.display_color_spaces, current.display_id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,9 +162,9 @@
|
||||
dfh_device_scale_factor_ = new_device_scale_factor;
|
||||
root_layer_->SetBounds(gfx::Rect(dfh_size_dip_));
|
||||
if (recyclable_compositor_) {
|
||||
- recyclable_compositor_->UpdateSurface(dfh_size_pixels_,
|
||||
- current.device_scale_factor,
|
||||
- current.display_color_spaces);
|
||||
+ recyclable_compositor_->UpdateSurface(
|
||||
+ dfh_size_pixels_, current.device_scale_factor,
|
||||
+ current.display_color_spaces, current.display_id);
|
||||
}
|
||||
}
|
||||
delegated_frame_host_->EmbedSurface(
|
||||
@@ -252,9 +254,9 @@
|
||||
recyclable_compositor_ = std::make_unique<ui::RecyclableCompositorMac>(
|
||||
content::GetContextFactory());
|
||||
display::ScreenInfo current = client_->GetCurrentScreenInfo();
|
||||
- recyclable_compositor_->UpdateSurface(dfh_size_pixels_,
|
||||
- current.device_scale_factor,
|
||||
- current.display_color_spaces);
|
||||
+ recyclable_compositor_->UpdateSurface(
|
||||
+ dfh_size_pixels_, current.device_scale_factor,
|
||||
+ current.display_color_spaces, current.display_id);
|
||||
recyclable_compositor_->compositor()->SetRootLayer(root_layer_.get());
|
||||
recyclable_compositor_->compositor()->SetBackgroundColor(background_color_);
|
||||
recyclable_compositor_->widget()->SetNSView(
|
||||
@@ -273,9 +275,8 @@
|
||||
// Ensure that the client has destroyed its BrowserCompositorViewMac before
|
||||
// it dependencies are destroyed.
|
||||
// https://crbug.com/805726
|
||||
- while (!g_browser_compositors.Get().empty()) {
|
||||
- BrowserCompositorMac* browser_compositor =
|
||||
- *g_browser_compositors.Get().begin();
|
||||
+ while (!GetBrowserCompositors().empty()) {
|
||||
+ BrowserCompositorMac* browser_compositor = *GetBrowserCompositors().begin();
|
||||
browser_compositor->client_->DestroyCompositorForShutdown();
|
||||
}
|
||||
}
|
||||
diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc
|
||||
index c652c0dfd2e6c464c91e3522902ee96dd19b0287..e52e5b74146d0709925e87c6f4d5dc551ec8eec8 100644
|
||||
--- a/ui/compositor/compositor.cc
|
||||
+++ b/ui/compositor/compositor.cc
|
||||
@@ -347,6 +347,9 @@ void Compositor::SetLayerTreeFrameSink(
|
||||
display_private_->SetDisplayColorMatrix(
|
||||
gfx::SkM44ToTransform(display_color_matrix_));
|
||||
display_private_->SetOutputIsSecure(output_is_secure_);
|
||||
+#if BUILDFLAG(IS_MAC)
|
||||
+ display_private_->SetVSyncDisplayID(display_id_);
|
||||
+#endif
|
||||
if (has_vsync_params_) {
|
||||
display_private_->SetDisplayVSyncParameters(vsync_timebase_,
|
||||
vsync_interval_);
|
||||
diff --git a/ui/compositor/recyclable_compositor_mac.cc b/ui/compositor/recyclable_compositor_mac.cc
|
||||
index 0e30e781760d38778ec0e741ddae250e96c6d671..0c57b17778872702f887e5fe9d95dc8ad98d654f 100644
|
||||
--- a/ui/compositor/recyclable_compositor_mac.cc
|
||||
+++ b/ui/compositor/recyclable_compositor_mac.cc
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "ui/compositor/compositor.h"
|
||||
#include "ui/compositor/compositor_observer.h"
|
||||
#include "ui/compositor/compositor_switches.h"
|
||||
+#include "ui/display/types/display_constants.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
@@ -65,7 +66,8 @@ void RecyclableCompositorMac::Unsuspend() {
|
||||
void RecyclableCompositorMac::UpdateSurface(
|
||||
const gfx::Size& size_pixels,
|
||||
float scale_factor,
|
||||
- const gfx::DisplayColorSpaces& display_color_spaces) {
|
||||
+ const gfx::DisplayColorSpaces& display_color_spaces,
|
||||
+ int64_t display_id) {
|
||||
if (size_pixels != size_pixels_ || scale_factor != scale_factor_) {
|
||||
size_pixels_ = size_pixels;
|
||||
scale_factor_ = scale_factor;
|
||||
@@ -75,21 +77,19 @@ void RecyclableCompositorMac::UpdateSurface(
|
||||
compositor()->SetScaleAndSize(scale_factor_, size_pixels_,
|
||||
local_surface_id);
|
||||
}
|
||||
- if (display_color_spaces != display_color_spaces_) {
|
||||
- display_color_spaces_ = display_color_spaces;
|
||||
- compositor()->SetDisplayColorSpaces(display_color_spaces_);
|
||||
- }
|
||||
+ compositor()->SetDisplayColorSpaces(display_color_spaces);
|
||||
+ compositor()->SetVSyncDisplayID(display_id);
|
||||
}
|
||||
|
||||
void RecyclableCompositorMac::InvalidateSurface() {
|
||||
size_pixels_ = gfx::Size();
|
||||
scale_factor_ = 1.f;
|
||||
local_surface_id_allocator_.Invalidate();
|
||||
- display_color_spaces_ = gfx::DisplayColorSpaces();
|
||||
compositor()->SetScaleAndSize(
|
||||
scale_factor_, size_pixels_,
|
||||
local_surface_id_allocator_.GetCurrentLocalSurfaceId());
|
||||
compositor()->SetDisplayColorSpaces(gfx::DisplayColorSpaces());
|
||||
+ compositor()->SetVSyncDisplayID(display::kInvalidDisplayId);
|
||||
}
|
||||
|
||||
void RecyclableCompositorMac::OnCompositingDidCommit(
|
||||
diff --git a/ui/compositor/recyclable_compositor_mac.h b/ui/compositor/recyclable_compositor_mac.h
|
||||
index 891204a715de65bce5103b85490bb66de401ba0e..778842bee9395101c6f8b2c182e4b6de7a8a039e 100644
|
||||
--- a/ui/compositor/recyclable_compositor_mac.h
|
||||
+++ b/ui/compositor/recyclable_compositor_mac.h
|
||||
@@ -49,7 +49,8 @@ class COMPOSITOR_EXPORT RecyclableCompositorMac
|
||||
// Update the compositor's surface information, if needed.
|
||||
void UpdateSurface(const gfx::Size& size_pixels,
|
||||
float scale_factor,
|
||||
- const gfx::DisplayColorSpaces& display_color_spaces);
|
||||
+ const gfx::DisplayColorSpaces& display_color_spaces,
|
||||
+ int64_t display_id);
|
||||
|
||||
private:
|
||||
// Invalidate the compositor's surface information.
|
||||
@@ -63,7 +64,6 @@ class COMPOSITOR_EXPORT RecyclableCompositorMac
|
||||
viz::ParentLocalSurfaceIdAllocator local_surface_id_allocator_;
|
||||
gfx::Size size_pixels_;
|
||||
float scale_factor_ = 1.f;
|
||||
- gfx::DisplayColorSpaces display_color_spaces_;
|
||||
|
||||
std::unique_ptr<ui::AcceleratedWidgetMac> accelerated_widget_mac_;
|
||||
ui::Compositor compositor_;
|
||||
diff --git a/ui/views/cocoa/native_widget_mac_ns_window_host.mm b/ui/views/cocoa/native_widget_mac_ns_window_host.mm
|
||||
index c6a33c2a85206295426292406291af670ce65ab0..f1f25bf0e19a918c3fcc7b7610ecf2924a880ff4 100644
|
||||
--- a/ui/views/cocoa/native_widget_mac_ns_window_host.mm
|
||||
+++ b/ui/views/cocoa/native_widget_mac_ns_window_host.mm
|
||||
@@ -617,7 +617,7 @@ void HandleAccelerator(const ui::Accelerator& accelerator,
|
||||
content_bounds_in_screen_.size(), display_.device_scale_factor()));
|
||||
compositor_->UpdateSurface(content_bounds_in_pixels,
|
||||
display_.device_scale_factor(),
|
||||
- display_.color_spaces());
|
||||
+ display_.color_spaces(), display_.id());
|
||||
}
|
||||
|
||||
void NativeWidgetMacNSWindowHost::DestroyCompositor() {
|
||||
@@ -1173,7 +1173,7 @@ void HandleAccelerator(const ui::Accelerator& accelerator,
|
||||
content_bounds_in_screen_.size(), display_.device_scale_factor()));
|
||||
compositor_->UpdateSurface(content_bounds_in_pixels,
|
||||
display_.device_scale_factor(),
|
||||
- display_.color_spaces());
|
||||
+ display_.color_spaces(), display_.id());
|
||||
}
|
||||
|
||||
if (display_id_changed) {
|
||||
@@ -1187,7 +1187,6 @@ void HandleAccelerator(const ui::Accelerator& accelerator,
|
||||
|
||||
if (compositor_) {
|
||||
RequestVSyncParametersUpdate();
|
||||
- compositor_->compositor()->SetVSyncDisplayID(display_.id());
|
||||
}
|
||||
}
|
||||
}
|
430
patches/chromium/cherry-pick-e6e23ba00379.patch
Normal file
430
patches/chromium/cherry-pick-e6e23ba00379.patch
Normal file
|
@ -0,0 +1,430 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Christopher Cameron <ccameron@chromium.org>
|
||||
Date: Mon, 15 May 2023 15:30:36 +0200
|
||||
Subject: Use ExternalBeginFrameSourceMac on macOS
|
||||
|
||||
Change ExternalBeginFrameSourceMac from being a
|
||||
SyntheticBeginFrameSource to being an ExternalBeginFrameSource.
|
||||
|
||||
Move all of the code that is responsible for updating the VSync
|
||||
parameters every 10 seconds from NativeWidgetMacNSWindowHost to
|
||||
ExternalBeginFrameSourceMac.
|
||||
|
||||
Wire up ExternalBeginFrameSourceMac::SetVSyncDisplayID to create
|
||||
the DisplayLinkMac (that was previously created in
|
||||
NativeWidgetMacNSWindowHost). Set the VSyncCallbackMac callback in
|
||||
ExternalBeginFrameSourceMac to update the timer based VSync
|
||||
parameters the same way that was done in SyntheticBeginFrameSource.
|
||||
|
||||
Make RootCompositorFrameSinkImpl create a ExternalBeginFrameSourceMac
|
||||
instead of creating a DelayBasedBeginFrameSource.
|
||||
|
||||
Bug: 1404797
|
||||
Change-Id: I288497d94cc66356586e8da34852d53d05cf42f3
|
||||
|
||||
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn
|
||||
index 5b0a12d8b69c0b79fefcb9194e0f3fb88c4c7051..8ebcf88eadb7fbc3ce781b9094ec88f6d23134c1 100644
|
||||
--- a/components/viz/service/BUILD.gn
|
||||
+++ b/components/viz/service/BUILD.gn
|
||||
@@ -323,6 +323,12 @@ viz_component("service") {
|
||||
frameworks += [ "CoreGraphics.framework" ]
|
||||
}
|
||||
configs = ["//electron/build/config:mas_build"]
|
||||
+ if (is_mac) {
|
||||
+ sources += [
|
||||
+ "frame_sinks/external_begin_frame_source_mac.cc",
|
||||
+ "frame_sinks/external_begin_frame_source_mac.h",
|
||||
+ ]
|
||||
+ }
|
||||
}
|
||||
|
||||
if (is_android || use_ozone) {
|
||||
diff --git a/components/viz/service/frame_sinks/DEPS b/components/viz/service/frame_sinks/DEPS
|
||||
index 163224a3cdb78d1eee055491c2daa7ca09fe4baa..c0e240ec70f7b7d4da92b497ac607e73d1168923 100644
|
||||
--- a/components/viz/service/frame_sinks/DEPS
|
||||
+++ b/components/viz/service/frame_sinks/DEPS
|
||||
@@ -26,4 +26,8 @@ specific_include_rules = {
|
||||
"external_begin_frame_source_android.cc": [
|
||||
"+components/viz/service/service_jni_headers/ExternalBeginFrameSourceAndroid_jni.h",
|
||||
],
|
||||
+ "external_begin_frame_source_mac.h": [
|
||||
+ "+ui/display/mac/display_link_mac.h",
|
||||
+ "+ui/display/types/display_constants.h",
|
||||
+ ],
|
||||
}
|
||||
diff --git a/components/viz/service/frame_sinks/external_begin_frame_source_mac.cc b/components/viz/service/frame_sinks/external_begin_frame_source_mac.cc
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..f5bd62e7c486b8e6bb58d59984f363867015486c
|
||||
--- /dev/null
|
||||
+++ b/components/viz/service/frame_sinks/external_begin_frame_source_mac.cc
|
||||
@@ -0,0 +1,97 @@
|
||||
+// Copyright 2023 The Chromium Authors
|
||||
+// Use of this source code is governed by a BSD-style license that can be
|
||||
+// found in the LICENSE file.
|
||||
+
|
||||
+#include "components/viz/service/frame_sinks/external_begin_frame_source_mac.h"
|
||||
+
|
||||
+#include <algorithm>
|
||||
+#include <memory>
|
||||
+#include <utility>
|
||||
+
|
||||
+#include "base/containers/contains.h"
|
||||
+#include "base/trace_event/trace_event.h"
|
||||
+
|
||||
+namespace viz {
|
||||
+
|
||||
+ExternalBeginFrameSourceMac::ExternalBeginFrameSourceMac(
|
||||
+ std::unique_ptr<DelayBasedTimeSource> time_source,
|
||||
+ uint32_t restart_id)
|
||||
+ : ExternalBeginFrameSource(this, restart_id),
|
||||
+ time_source_(std::move(time_source)) {
|
||||
+ time_source_->SetClient(this);
|
||||
+}
|
||||
+
|
||||
+ExternalBeginFrameSourceMac::~ExternalBeginFrameSourceMac() = default;
|
||||
+
|
||||
+void ExternalBeginFrameSourceMac::SetDynamicBeginFrameDeadlineOffsetSource(
|
||||
+ DynamicBeginFrameDeadlineOffsetSource*
|
||||
+ dynamic_begin_frame_deadline_offset_source) {
|
||||
+ begin_frame_args_generator_.set_dynamic_begin_frame_deadline_offset_source(
|
||||
+ dynamic_begin_frame_deadline_offset_source);
|
||||
+}
|
||||
+
|
||||
+void ExternalBeginFrameSourceMac::SetVSyncDisplayID(int64_t display_id) {
|
||||
+ if (display_id_ == display_id) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ display_id_ = display_id;
|
||||
+ display_link_ = ui::DisplayLinkMac::GetForDisplay(
|
||||
+ base::checked_cast<CGDirectDisplayID>(display_id_));
|
||||
+ time_source_next_update_time_ = base::TimeTicks();
|
||||
+ RequestTimeSourceParamsUpdate();
|
||||
+}
|
||||
+
|
||||
+void ExternalBeginFrameSourceMac::OnNeedsBeginFrames(bool needs_begin_frames) {
|
||||
+ if (needs_begin_frames_ == needs_begin_frames) {
|
||||
+ return;
|
||||
+ }
|
||||
+ needs_begin_frames_ = needs_begin_frames;
|
||||
+
|
||||
+ DCHECK_NE(time_source_->Active(), needs_begin_frames_);
|
||||
+ time_source_->SetActive(needs_begin_frames_);
|
||||
+}
|
||||
+
|
||||
+void ExternalBeginFrameSourceMac::OnTimerTick() {
|
||||
+ // The VSync parameters skew over time (astonishingly quickly -- 0.1 msec per
|
||||
+ // second). If too much time has elapsed since the last time the vsync
|
||||
+ // parameters were calculated, re-calculate them.
|
||||
+ if (base::TimeTicks::Now() >= time_source_next_update_time_) {
|
||||
+ RequestTimeSourceParamsUpdate();
|
||||
+ }
|
||||
+
|
||||
+ // See comments in DelayBasedBeginFrameSource::OnTimerTick regarding the
|
||||
+ // computation of `frame_time`.
|
||||
+ base::TimeTicks frame_time =
|
||||
+ std::max(time_source_->LastTickTime(),
|
||||
+ time_source_->NextTickTime() - time_source_->Interval());
|
||||
+ OnBeginFrame(begin_frame_args_generator_.GenerateBeginFrameArgs(
|
||||
+ source_id(), frame_time, time_source_->NextTickTime(),
|
||||
+ time_source_->Interval()));
|
||||
+}
|
||||
+
|
||||
+void ExternalBeginFrameSourceMac::RequestTimeSourceParamsUpdate() {
|
||||
+ if (!display_link_ || time_source_updater_) {
|
||||
+ return;
|
||||
+ }
|
||||
+ time_source_updater_ = display_link_->RegisterCallback(base::BindRepeating(
|
||||
+ &ExternalBeginFrameSourceMac::OnTimeSourceParamsUpdate,
|
||||
+ weak_factory_.GetWeakPtr()));
|
||||
+}
|
||||
+
|
||||
+void ExternalBeginFrameSourceMac::OnTimeSourceParamsUpdate(
|
||||
+ ui::VSyncParamsMac params) {
|
||||
+ time_source_next_update_time_ = base::TimeTicks::Now() + base::Seconds(10);
|
||||
+ time_source_updater_ = nullptr;
|
||||
+
|
||||
+ if (params.display_times_valid) {
|
||||
+ time_source_->SetTimebaseAndInterval(params.display_timebase,
|
||||
+ params.display_interval);
|
||||
+ last_timebase_ = params.display_timebase;
|
||||
+ } else {
|
||||
+ time_source_->SetTimebaseAndInterval(last_timebase_,
|
||||
+ BeginFrameArgs::DefaultInterval());
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+} // namespace viz
|
||||
diff --git a/components/viz/service/frame_sinks/external_begin_frame_source_mac.h b/components/viz/service/frame_sinks/external_begin_frame_source_mac.h
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..4753f86371d97ec0470e355258bae17e10e77dcf
|
||||
--- /dev/null
|
||||
+++ b/components/viz/service/frame_sinks/external_begin_frame_source_mac.h
|
||||
@@ -0,0 +1,74 @@
|
||||
+// Copyright 2023 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_EXTERNAL_BEGIN_FRAME_SOURCE_MAC_H_
|
||||
+#define COMPONENTS_VIZ_SERVICE_FRAME_SINKS_EXTERNAL_BEGIN_FRAME_SOURCE_MAC_H_
|
||||
+
|
||||
+#include <memory>
|
||||
+
|
||||
+#include "components/viz/common/frame_sinks/begin_frame_source.h"
|
||||
+#include "components/viz/service/viz_service_export.h"
|
||||
+#include "ui/display/mac/display_link_mac.h"
|
||||
+#include "ui/display/types/display_constants.h"
|
||||
+
|
||||
+namespace viz {
|
||||
+
|
||||
+// A begin frame source for use on macOS. This behaves like a
|
||||
+// DelayBasedBeginFrameSource, but, instead of being informed externally of its
|
||||
+// timebase and interval, it is informed externally of its display::DisplayId
|
||||
+// and uses that to query its timebase and interval from a DisplayLinkMac.
|
||||
+class VIZ_COMMON_EXPORT ExternalBeginFrameSourceMac
|
||||
+ : public ExternalBeginFrameSource,
|
||||
+ public ExternalBeginFrameSourceClient,
|
||||
+ public DelayBasedTimeSourceClient {
|
||||
+ public:
|
||||
+ ExternalBeginFrameSourceMac(std::unique_ptr<DelayBasedTimeSource> time_source,
|
||||
+ uint32_t restart_id);
|
||||
+
|
||||
+ ExternalBeginFrameSourceMac(const ExternalBeginFrameSourceMac&) = delete;
|
||||
+ ExternalBeginFrameSourceMac& operator=(const ExternalBeginFrameSourceMac&) =
|
||||
+ delete;
|
||||
+ ~ExternalBeginFrameSourceMac() override;
|
||||
+
|
||||
+ // BeginFrameSource implementation.
|
||||
+ void SetDynamicBeginFrameDeadlineOffsetSource(
|
||||
+ DynamicBeginFrameDeadlineOffsetSource*
|
||||
+ dynamic_begin_frame_deadline_offset_source) override;
|
||||
+ void SetVSyncDisplayID(int64_t display_id) override;
|
||||
+
|
||||
+ // ExternalBeginFrameSourceClient implementation.
|
||||
+ void OnNeedsBeginFrames(bool needs_begin_frames) override;
|
||||
+
|
||||
+ // DelayBasedTimeSourceClient implementation.
|
||||
+ void OnTimerTick() override;
|
||||
+
|
||||
+ private:
|
||||
+ // Request a callback from DisplayLinkMac, and the callback function.
|
||||
+ void RequestTimeSourceParamsUpdate();
|
||||
+ void OnTimeSourceParamsUpdate(ui::VSyncParamsMac params);
|
||||
+
|
||||
+ BeginFrameArgsGenerator begin_frame_args_generator_;
|
||||
+
|
||||
+ bool needs_begin_frames_ = false;
|
||||
+
|
||||
+ // CVDisplayLink and related structures to set timer parameters.
|
||||
+ int64_t display_id_ = display::kInvalidDisplayId;
|
||||
+ scoped_refptr<ui::DisplayLinkMac> display_link_;
|
||||
+
|
||||
+ // Timer used to drive callbacks.
|
||||
+ // TODO(https://crbug.com/1404797): Only use this when it is not possible or
|
||||
+ // efficient to use `display_link_`.
|
||||
+ std::unique_ptr<DelayBasedTimeSource> time_source_;
|
||||
+ base::TimeTicks last_timebase_;
|
||||
+
|
||||
+ // The callback that is used to update `time_source_`.
|
||||
+ base::TimeTicks time_source_next_update_time_;
|
||||
+ std::unique_ptr<ui::VSyncCallbackMac> time_source_updater_;
|
||||
+
|
||||
+ base::WeakPtrFactory<ExternalBeginFrameSourceMac> weak_factory_{this};
|
||||
+};
|
||||
+
|
||||
+} // namespace viz
|
||||
+
|
||||
+#endif // COMPONENTS_VIZ_SERVICE_FRAME_SINKS_EXTERNAL_BEGIN_FRAME_SOURCE_MAC_H_
|
||||
diff --git a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
|
||||
index 13962687d262434de77f76c1c5a0f39f0fd9fb43..4d07b897a158bf39d9b29e3ac90920aee3050ce0 100644
|
||||
--- a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
|
||||
+++ b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
|
||||
@@ -36,6 +36,10 @@
|
||||
#include "components/viz/service/frame_sinks/external_begin_frame_source_ios.h"
|
||||
#endif
|
||||
|
||||
+#if BUILDFLAG(IS_MAC)
|
||||
+#include "components/viz/service/frame_sinks/external_begin_frame_source_mac.h"
|
||||
+#endif
|
||||
+
|
||||
namespace viz {
|
||||
|
||||
class RootCompositorFrameSinkImpl::StandaloneBeginFrameObserver
|
||||
@@ -140,6 +144,11 @@ RootCompositorFrameSinkImpl::Create(
|
||||
hw_support_for_multiple_refresh_rates = true;
|
||||
external_begin_frame_source =
|
||||
std::make_unique<ExternalBeginFrameSourceIOS>(restart_id);
|
||||
+#elif BUILDFLAG(IS_MAC)
|
||||
+ external_begin_frame_source = std::make_unique<ExternalBeginFrameSourceMac>(
|
||||
+ std::make_unique<DelayBasedTimeSource>(
|
||||
+ base::SingleThreadTaskRunner::GetCurrentDefault().get()),
|
||||
+ restart_id);
|
||||
#else
|
||||
if (params->disable_frame_rate_limit) {
|
||||
synthetic_begin_frame_source =
|
||||
diff --git a/ui/display/mac/screen_mac.mm b/ui/display/mac/screen_mac.mm
|
||||
index 0d5ef8c48f08b1eb5ed878ab8934f2ecd04083fa..30f72b9655e790d864fc7e28983b6a37074448a5 100644
|
||||
--- a/ui/display/mac/screen_mac.mm
|
||||
+++ b/ui/display/mac/screen_mac.mm
|
||||
@@ -9,6 +9,7 @@
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#include <IOKit/IOKitLib.h>
|
||||
#include <IOKit/graphics/IOGraphicsLib.h>
|
||||
+#include <QuartzCore/CVDisplayLink.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <map>
|
||||
@@ -27,7 +28,6 @@
|
||||
#include "base/trace_event/trace_event.h"
|
||||
#include "ui/display/display.h"
|
||||
#include "ui/display/display_change_notifier.h"
|
||||
-#include "ui/display/mac/display_link_mac.h"
|
||||
#include "ui/display/util/display_util.h"
|
||||
#include "ui/gfx/geometry/point.h"
|
||||
#include "ui/gfx/icc_profile.h"
|
||||
@@ -280,8 +280,22 @@ DisplayMac BuildDisplayForScreen(NSScreen* screen) {
|
||||
display.set_is_monochrome(CGDisplayUsesForceToGray());
|
||||
#endif
|
||||
|
||||
- if (auto display_link = ui::DisplayLinkMac::GetForDisplay(display_id))
|
||||
- display.set_display_frequency(display_link->GetRefreshRate());
|
||||
+ // Query the display's referesh rate.
|
||||
+ {
|
||||
+ CVDisplayLinkRef display_link = nullptr;
|
||||
+ if (CVDisplayLinkCreateWithCGDisplay(display_id, &display_link) ==
|
||||
+ kCVReturnSuccess) {
|
||||
+ DCHECK(display_link);
|
||||
+ CVTime cv_time =
|
||||
+ CVDisplayLinkGetNominalOutputVideoRefreshPeriod(display_link);
|
||||
+ if (!(cv_time.flags & kCVTimeIsIndefinite)) {
|
||||
+ double refresh_rate = (static_cast<double>(cv_time.timeScale) /
|
||||
+ static_cast<double>(cv_time.timeValue));
|
||||
+ display.set_display_frequency(refresh_rate);
|
||||
+ }
|
||||
+ CVDisplayLinkRelease(display_link);
|
||||
+ }
|
||||
+ }
|
||||
|
||||
// CGDisplayRotation returns a double. Display::SetRotationAsDegree will
|
||||
// handle the unexpected situations were the angle is not a multiple of 90.
|
||||
diff --git a/ui/views/cocoa/native_widget_mac_ns_window_host.h b/ui/views/cocoa/native_widget_mac_ns_window_host.h
|
||||
index e63b249a9bdc23545121a513156bfa32e92fec0b..e21c2df5d19bf01271bee91f792a3dbae29c55b7 100644
|
||||
--- a/ui/views/cocoa/native_widget_mac_ns_window_host.h
|
||||
+++ b/ui/views/cocoa/native_widget_mac_ns_window_host.h
|
||||
@@ -24,7 +24,6 @@
|
||||
#include "ui/accelerated_widget_mac/accelerated_widget_mac.h"
|
||||
#include "ui/base/cocoa/accessibility_focus_overrider.h"
|
||||
#include "ui/compositor/layer_owner.h"
|
||||
-#include "ui/display/mac/display_link_mac.h"
|
||||
#include "ui/views/cocoa/drag_drop_client_mac.h"
|
||||
#include "ui/views/cocoa/native_widget_mac_event_monitor.h"
|
||||
#include "ui/views/views_export.h"
|
||||
@@ -421,12 +420,6 @@ class VIEWS_EXPORT NativeWidgetMacNSWindowHost
|
||||
// ui::AcceleratedWidgetMacNSView:
|
||||
void AcceleratedWidgetCALayerParamsUpdated() override;
|
||||
|
||||
- // If `display_link_` is valid and `display_link_updater_` does not exist,
|
||||
- // create it. It will call back to OnVSyncParametersUpdated with new VSync
|
||||
- // parameters.
|
||||
- void RequestVSyncParametersUpdate();
|
||||
- void OnVSyncParametersUpdated(ui::VSyncParamsMac params);
|
||||
-
|
||||
// The id that this bridge may be looked up from.
|
||||
const uint64_t widget_id_;
|
||||
const raw_ptr<views::NativeWidgetMac>
|
||||
@@ -494,15 +487,6 @@ class VIEWS_EXPORT NativeWidgetMacNSWindowHost
|
||||
// The display that the window is currently on.
|
||||
display::Display display_;
|
||||
|
||||
- // Display link for getting vsync info for `display_`, and VSyncCallbackMac to
|
||||
- // use for callbacks.
|
||||
- scoped_refptr<ui::DisplayLinkMac> display_link_;
|
||||
- std::unique_ptr<ui::VSyncCallbackMac> display_link_updater_;
|
||||
-
|
||||
- // Updating VSync parameters can be expensive, so set this to the next time
|
||||
- // when we should update VSync parameters.
|
||||
- base::TimeTicks display_link_next_update_time_;
|
||||
-
|
||||
// The geometry of the window and its contents view, in screen coordinates.
|
||||
gfx::Rect window_bounds_in_screen_;
|
||||
gfx::Rect content_bounds_in_screen_;
|
||||
diff --git a/ui/views/cocoa/native_widget_mac_ns_window_host.mm b/ui/views/cocoa/native_widget_mac_ns_window_host.mm
|
||||
index f1f25bf0e19a918c3fcc7b7610ecf2924a880ff4..a0c9f71c5eb97091941ba7d9955854af74bd67d5 100644
|
||||
--- a/ui/views/cocoa/native_widget_mac_ns_window_host.mm
|
||||
+++ b/ui/views/cocoa/native_widget_mac_ns_window_host.mm
|
||||
@@ -1163,32 +1163,19 @@ void HandleAccelerator(const ui::Accelerator& accelerator,
|
||||
|
||||
void NativeWidgetMacNSWindowHost::OnWindowDisplayChanged(
|
||||
const display::Display& new_display) {
|
||||
- bool display_id_changed = display_.id() != new_display.id();
|
||||
display_ = new_display;
|
||||
- if (compositor_) {
|
||||
- // Mac device scale factor is always an integer so the result here is an
|
||||
- // integer pixel size.
|
||||
- gfx::Size content_bounds_in_pixels =
|
||||
- gfx::ToRoundedSize(gfx::ConvertSizeToPixels(
|
||||
- content_bounds_in_screen_.size(), display_.device_scale_factor()));
|
||||
- compositor_->UpdateSurface(content_bounds_in_pixels,
|
||||
- display_.device_scale_factor(),
|
||||
- display_.color_spaces(), display_.id());
|
||||
+ if (!compositor_) {
|
||||
+ return;
|
||||
}
|
||||
|
||||
- if (display_id_changed) {
|
||||
- display_link_ = ui::DisplayLinkMac::GetForDisplay(
|
||||
- base::checked_cast<CGDirectDisplayID>(display_.id()));
|
||||
- if (!display_link_) {
|
||||
- // Note that on some headless systems, the display link will fail to be
|
||||
- // created, so this should not be a fatal error.
|
||||
- LOG(ERROR) << "Failed to create display link.";
|
||||
- }
|
||||
-
|
||||
- if (compositor_) {
|
||||
- RequestVSyncParametersUpdate();
|
||||
- }
|
||||
- }
|
||||
+ // Mac device scale factor is always an integer so the result here is an
|
||||
+ // integer pixel size.
|
||||
+ gfx::Size content_bounds_in_pixels =
|
||||
+ gfx::ToRoundedSize(gfx::ConvertSizeToPixels(
|
||||
+ content_bounds_in_screen_.size(), display_.device_scale_factor()));
|
||||
+ compositor_->UpdateSurface(content_bounds_in_pixels,
|
||||
+ display_.device_scale_factor(),
|
||||
+ display_.color_spaces(), display_.id());
|
||||
}
|
||||
|
||||
void NativeWidgetMacNSWindowHost::OnWindowWillClose() {
|
||||
@@ -1619,32 +1606,6 @@ void HandleAccelerator(const ui::Accelerator& accelerator,
|
||||
void NativeWidgetMacNSWindowHost::AcceleratedWidgetCALayerParamsUpdated() {
|
||||
if (const auto* ca_layer_params = compositor_->widget()->GetCALayerParams())
|
||||
GetNSWindowMojo()->SetCALayerParams(*ca_layer_params);
|
||||
-
|
||||
- // The VSync parameters skew over time (astonishingly quickly -- 0.1 msec per
|
||||
- // second). If too much time has elapsed since the last time the vsync
|
||||
- // parameters were calculated, re-calculate them.
|
||||
- if (base::TimeTicks::Now() >= display_link_next_update_time_) {
|
||||
- RequestVSyncParametersUpdate();
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-void NativeWidgetMacNSWindowHost::RequestVSyncParametersUpdate() {
|
||||
- if (!display_link_ || display_link_updater_) {
|
||||
- return;
|
||||
- }
|
||||
- display_link_updater_ = display_link_->RegisterCallback(base::BindRepeating(
|
||||
- &NativeWidgetMacNSWindowHost::OnVSyncParametersUpdated,
|
||||
- weak_factory_for_vsync_update_.GetWeakPtr()));
|
||||
-}
|
||||
-
|
||||
-void NativeWidgetMacNSWindowHost::OnVSyncParametersUpdated(
|
||||
- ui::VSyncParamsMac params) {
|
||||
- if (compositor_ && params.display_times_valid) {
|
||||
- compositor_->compositor()->SetDisplayVSyncParameters(
|
||||
- params.display_timebase, params.display_interval);
|
||||
- display_link_next_update_time_ = base::TimeTicks::Now() + base::Seconds(10);
|
||||
- }
|
||||
- display_link_updater_ = nullptr;
|
||||
}
|
||||
|
||||
} // namespace views
|
Loading…
Reference in a new issue