commit a17d30fdccc1e5f442b88787647947bcc42e97e8
parent c1fbf0df4af5e490088e9e7f95b5b974666aa047
Author: Brad Werth <werth@efn.org>
Date: Tue, 16 Dec 2025 17:43:09 +0000
Bug 1985140 Part 3: Make OSXVsyncSource give up when display reconfiguration fails. r=mstange
This adds a method gfxPlatform::ResetHardwareVsyncSource to allow a
hardware vsync source to remove itself when needed. The OSXVsyncSource
now calls this method when display reconfiguration fails, and the
time-delayed retry *also* fails. This allows a software vsync method to
be used as a fallback, ensuring that some vsync source is active.
Differential Revision: https://phabricator.services.mozilla.com/D273131
Diffstat:
3 files changed, 31 insertions(+), 6 deletions(-)
diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp
@@ -3553,6 +3553,14 @@ void gfxPlatform::ReInitFrameRate(const char* aPrefIgnored,
gPlatform->mVsyncDispatcher->SetVsyncSource(vsyncSource);
}
+/* static */
+void gfxPlatform::ResetHardwareVsyncSource() {
+ if (gPlatform->mGlobalHardwareVsyncSource) {
+ gPlatform->mGlobalHardwareVsyncSource->Shutdown();
+ gPlatform->mGlobalHardwareVsyncSource = nullptr;
+ }
+}
+
const char* gfxPlatform::GetAzureCanvasBackend() const {
BackendType backend{};
diff --git a/gfx/thebes/gfxPlatform.h b/gfx/thebes/gfxPlatform.h
@@ -689,6 +689,12 @@ class gfxPlatform : public mozilla::layers::MemoryPressureListener {
static void ReInitFrameRate(const char* aPrefIgnored, void* aDataIgnored);
/**
+ * Reset the global hardware vsync source. The next call to ReInitFrameRate
+ * will attempt to reestablish it, and fall back to software if needed.
+ */
+ static void ResetHardwareVsyncSource();
+
+ /**
* Update force subpixel AA quality setting (called after pref
* changes).
*/
diff --git a/gfx/thebes/gfxPlatformMac.cpp b/gfx/thebes/gfxPlatformMac.cpp
@@ -760,10 +760,7 @@ class OSXVsyncSource final : public VsyncSource {
virtual ~OSXVsyncSource() {
MOZ_ASSERT(NS_IsMainThread());
- CGDisplayRemoveReconfigurationCallback(DisplayReconfigurationCallback,
- this);
- DisableVsync();
- DestroyDisplayLink();
+ Shutdown();
}
static void RetryCreateDisplayLinkAndEnableVsync(nsITimer* aTimer,
@@ -772,8 +769,18 @@ class OSXVsyncSource final : public VsyncSource {
OSXVsyncSource* osxVsyncSource =
static_cast<OSXVsyncSource*>(aOsxVsyncSource);
MOZ_ASSERT(osxVsyncSource);
+
+ osxVsyncSource->DisableVsync();
+ osxVsyncSource->DestroyDisplayLink();
osxVsyncSource->CreateDisplayLink();
osxVsyncSource->EnableVsync();
+
+ if (!osxVsyncSource->IsVsyncEnabled()) {
+ gfxWarning() << "Display reconfiguration vsync has failed; giving up.";
+ osxVsyncSource->Shutdown();
+ gfxPlatform::ResetHardwareVsyncSource();
+ gfxPlatform::ReInitFrameRate(nullptr, nullptr);
+ }
}
void CreateDisplayLink() {
@@ -891,8 +898,12 @@ class OSXVsyncSource final : public VsyncSource {
void Shutdown() override {
MOZ_ASSERT(NS_IsMainThread());
- mTimer->Cancel();
- mTimer = nullptr;
+ if (mTimer) {
+ mTimer->Cancel();
+ mTimer = nullptr;
+ }
+ CGDisplayRemoveReconfigurationCallback(DisplayReconfigurationCallback,
+ this);
DisableVsync();
DestroyDisplayLink();
}