blob: a25b1133958fc1ba9c8c6123a41a8599af6bcf16 [file]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/display/mac/display_link_mac.h"
#include "base/feature_list.h"
#include "base/metrics/histogram_macros.h"
#include "base/task/bind_post_task.h"
#include "ui/display/display_features.h"
#include "ui/display/mac/ca_display_link_mac.h"
#include "ui/display/mac/cv_display_link_mac.h"
#include "ui/display/mac/external_display_link_mac.h"
#include "ui/display/types/display_constants.h"
namespace ui {
// For testing only. Create CADisplayLink in the GPU process.
BASE_FEATURE(kCADisplayLinkinGpu, base::FEATURE_DISABLED_BY_DEFAULT);
////////////////////////////////////////////////////////////////////////////////
// DisplayLinkMac
// Static
bool DisplayLinkMac::SupportsDisplayLinkMacInBrowser() {
if (!@available(macos 14.0, *)) {
return false;
}
return base::FeatureList::IsEnabled(
display::features::kCADisplayLinkInBrowser);
}
// Static
bool DisplayLinkMac::IsDisplayLinkAllowed(int64_t display_id) {
if (DisplayLinkMac::SupportsDisplayLinkMacInBrowser()) {
return ExternalDisplayLinkMac::IsDisplayLinkSupported(display_id);
}
return true;
}
// static
scoped_refptr<DisplayLinkMac> DisplayLinkMac::GetForDisplay(
int64_t vsync_display_id) {
if (vsync_display_id == display::kInvalidDisplayId) {
return nullptr;
}
CGDirectDisplayID display_id =
base::checked_cast<CGDirectDisplayID>(vsync_display_id);
// CADisplayLink is available only for MacOS 14.0+.
if (@available(macos 14.0, *)) {
if (base::FeatureList::IsEnabled(kCADisplayLinkinGpu)) {
return CADisplayLinkMac::GetForDisplay(display_id);
}
}
if (SupportsDisplayLinkMacInBrowser()) {
return ExternalDisplayLinkMac::GetForDisplay(display_id);
}
return CVDisplayLinkMac::GetForDisplay(display_id);
}
void DisplayLinkMac::RecordDisplayLinkCreation(bool success) {
UMA_HISTOGRAM_BOOLEAN("Viz.ExternalBeginFrameSourceMac.DisplayLink.Create2",
success);
}
std::unique_ptr<PresentationCallbackMac>
DisplayLinkMac::RegisterPresentationCallback(
PresentationCallbackMac::Callback callback) {
NOTREACHED();
}
////////////////////////////////////////////////////////////////////////////////
// VSyncCallbackMac
VSyncCallbackMac::VSyncCallbackMac(UnregisterCallback unregister_callback,
Callback callback,
bool post_callback_to_ctor_thread)
: unregister_callback_(std::move(unregister_callback)) {
if (post_callback_to_ctor_thread) {
auto lambda = [](base::WeakPtr<VSyncCallbackMac> weak_this,
Callback callback, VSyncParamsMac params) {
if (weak_this) {
callback.Run(params);
}
};
auto callback_for_current_thread =
base::BindRepeating(lambda, weak_factory_.GetWeakPtr(), callback);
callback_for_displaylink_thread_ =
base::BindPostTaskToCurrentDefault(callback_for_current_thread);
} else {
callback_for_displaylink_thread_ = std::move(callback);
}
}
VSyncCallbackMac::~VSyncCallbackMac() {
std::move(unregister_callback_).Run(this);
}
base::WeakPtr<VSyncCallbackMac> VSyncCallbackMac::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
////////////////////////////////////////////////////////////////////////////////
// PresentationCallbackMac
PresentationCallbackMac::PresentationCallbackMac(
UnregisterCallback unregister_callback,
Callback callback,
bool post_callback_to_ctor_thread)
: unregister_callback_(std::move(unregister_callback)) {
if (post_callback_to_ctor_thread) {
auto lambda = [](base::WeakPtr<PresentationCallbackMac> weak_this,
Callback callback, int64_t drawable_id,
base::TimeTicks time) {
if (weak_this) {
callback.Run(drawable_id, time);
}
};
auto callback_for_current_thread =
base::BindRepeating(lambda, weak_factory_.GetWeakPtr(), callback);
callback_for_displaylink_thread_ =
base::BindPostTaskToCurrentDefault(callback_for_current_thread);
} else {
callback_for_displaylink_thread_ = std::move(callback);
}
}
PresentationCallbackMac::~PresentationCallbackMac() {
std::move(unregister_callback_).Run(this);
}
base::WeakPtr<PresentationCallbackMac> PresentationCallbackMac::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
} // namespace ui