diff --git a/obs/data/locale/en-US.ini b/obs/data/locale/en-US.ini
index 3253831bc..67793c074 100644
--- a/obs/data/locale/en-US.ini
+++ b/obs/data/locale/en-US.ini
@@ -43,6 +43,8 @@ Untitled="Untitled"
New="New"
Duplicate="Duplicate"
Enable="Enable"
+DisableOSXVSync="Disable OSX V-Sync"
+ResetOSXVSyncOnExit="Reset OSX V-Sync on Exit"
HighResourceUsage="Encoding overloaded! Consider turning down video settings or using a faster encoding preset."
# title bar strings
diff --git a/obs/forms/OBSBasicSettings.ui b/obs/forms/OBSBasicSettings.ui
index 267722e0c..ee47eee90 100644
--- a/obs/forms/OBSBasicSettings.ui
+++ b/obs/forms/OBSBasicSettings.ui
@@ -2824,6 +2824,20 @@
+ -
+
+
+ DisableOSXVSync
+
+
+
+ -
+
+
+ ResetOSXVSyncOnExit
+
+
+
diff --git a/obs/obs-app.cpp b/obs/obs-app.cpp
index d273c128d..d0ab9902b 100644
--- a/obs/obs-app.cpp
+++ b/obs/obs-app.cpp
@@ -333,6 +333,12 @@ bool OBSApp::InitGlobalConfigDefaults()
config_set_default_bool(globalConfig, "BasicWindow", "PreviewEnabled",
true);
+
+#ifdef __APPLE__
+ config_set_default_bool(globalConfig, "Video", "DisableOSXVSync", true);
+ config_set_default_bool(globalConfig, "Video", "ResetOSXVSyncOnExit",
+ true);
+#endif
return true;
}
@@ -530,6 +536,15 @@ OBSApp::OBSApp(int &argc, char **argv, profiler_name_store_t *store)
OBSApp::~OBSApp()
{
+#ifdef __APPLE__
+ bool vsyncDiabled = config_get_bool(globalConfig, "Video",
+ "DisableOSXVSync");
+ bool resetVSync = config_get_bool(globalConfig, "Video",
+ "ResetOSXVSyncOnExit");
+ if (vsyncDiabled && resetVSync)
+ EnableOSXVSync(true);
+#endif
+
os_inhibit_sleep_set_active(sleepInhibitor, false);
os_inhibit_sleep_destroy(sleepInhibitor);
}
@@ -639,6 +654,11 @@ void OBSApp::AppInit()
config_set_default_string(globalConfig, "Basic", "SceneCollectionFile",
Str("Untitled"));
+#ifdef __APPLE__
+ if (config_get_bool(globalConfig, "Video", "DisableOSXVSync"))
+ EnableOSXVSync(false);
+#endif
+
move_basic_to_profiles();
move_basic_to_scene_collections();
diff --git a/obs/platform-osx.mm b/obs/platform-osx.mm
index 8f68ea43f..ec02bbec4 100644
--- a/obs/platform-osx.mm
+++ b/obs/platform-osx.mm
@@ -16,6 +16,7 @@
******************************************************************************/
#include
+#include
#include
#include
#include "platform.hpp"
@@ -148,3 +149,33 @@ void SetAlwaysOnTop(QMainWindow *window, bool enable)
window->setWindowFlags(flags);
window->show();
}
+
+typedef void (*set_int_t)(int);
+
+void EnableOSXVSync(bool enable)
+{
+ static bool initialized = false;
+ static bool valid = false;
+ static set_int_t set_debug_options = nullptr;
+ static set_int_t deferred_updates = nullptr;
+
+ if (!initialized) {
+ void *quartzCore = dlopen("/System/Library/Frameworks/"
+ "QuartzCore.framework/QuartzCore", RTLD_LAZY);
+ if (quartzCore) {
+ set_debug_options = (set_int_t)dlsym(quartzCore,
+ "CGSSetDebugOptions");
+ deferred_updates = (set_int_t)dlsym(quartzCore,
+ "CGSDeferredUpdates");
+
+ valid = set_debug_options && deferred_updates;
+ }
+
+ initialized = true;
+ }
+
+ if (valid) {
+ set_debug_options(enable ? 0 : 0x08000000);
+ deferred_updates(enable ? 1 : 0);
+ }
+}
diff --git a/obs/platform.hpp b/obs/platform.hpp
index 5f1658910..de9d1c660 100644
--- a/obs/platform.hpp
+++ b/obs/platform.hpp
@@ -52,3 +52,7 @@ void SetAlwaysOnTop(QMainWindow *window, bool enable);
uint32_t GetWindowsVersion();
void SetAeroEnabled(bool enable);
#endif
+
+#ifdef __APPLE__
+void EnableOSXVSync(bool enable);
+#endif
diff --git a/obs/window-basic-settings.cpp b/obs/window-basic-settings.cpp
index aef988534..3f89611b1 100644
--- a/obs/window-basic-settings.cpp
+++ b/obs/window-basic-settings.cpp
@@ -346,6 +346,8 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
HookWidget(ui->colorFormat, COMBO_CHANGED, ADV_CHANGED);
HookWidget(ui->colorSpace, COMBO_CHANGED, ADV_CHANGED);
HookWidget(ui->colorRange, COMBO_CHANGED, ADV_CHANGED);
+ HookWidget(ui->disableOSXVSync, CHECK_CHANGED, ADV_CHANGED);
+ HookWidget(ui->resetOSXVSync, CHECK_CHANGED, ADV_CHANGED);
HookWidget(ui->streamDelayEnable, CHECK_CHANGED, ADV_CHANGED);
HookWidget(ui->streamDelaySec, SCROLL_CHANGED, ADV_CHANGED);
HookWidget(ui->streamDelayPreserve, CHECK_CHANGED, ADV_CHANGED);
@@ -378,6 +380,13 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
ui->adapter = nullptr;
#endif
+#ifndef __APPLE__
+ delete ui->disableOSXVSync;
+ delete ui->resetOSXVSync;
+ ui->disableOSXVSync = nullptr;
+ ui->resetOSXVSync = nullptr;
+#endif
+
connect(ui->streamDelaySec, SIGNAL(valueChanged(int)),
this, SLOT(UpdateStreamDelayEstimate()));
connect(ui->outputMode, SIGNAL(currentIndexChanged(int)),
@@ -1676,6 +1685,16 @@ void OBSBasicSettings::LoadAdvancedSettings()
ui->advancedVideoContainer->setEnabled(false);
}
+#ifdef __APPLE__
+ bool disableOSXVSync = config_get_bool(App()->GlobalConfig(),
+ "Video", "DisableOSXVSync");
+ bool resetOSXVSync = config_get_bool(App()->GlobalConfig(),
+ "Video", "ResetOSXVSyncOnExit");
+ ui->disableOSXVSync->setChecked(disableOSXVSync);
+ ui->resetOSXVSync->setChecked(resetOSXVSync);
+ ui->resetOSXVSync->setEnabled(disableOSXVSync);
+#endif
+
loading = false;
}
@@ -2074,6 +2093,20 @@ void OBSBasicSettings::SaveAdvancedSettings()
config_set_string(App()->GlobalConfig(), "Video", "Renderer",
QT_TO_UTF8(ui->renderer->currentText()));
#endif
+
+#ifdef __APPLE__
+ if (WidgetChanged(ui->disableOSXVSync)) {
+ bool disable = ui->disableOSXVSync->isChecked();
+ config_set_bool(App()->GlobalConfig(),
+ "Video", "DisableOSXVSync", disable);
+ EnableOSXVSync(!disable);
+ }
+ if (WidgetChanged(ui->resetOSXVSync))
+ config_set_bool(App()->GlobalConfig(),
+ "Video", "ResetOSXVSyncOnExit",
+ ui->resetOSXVSync->isChecked());
+#endif
+
SaveSpinBox(ui->audioBufferingTime, "Audio", "BufferingTime");
SaveCombo(ui->colorFormat, "Video", "ColorFormat");
SaveCombo(ui->colorSpace, "Video", "ColorSpace");
@@ -2992,3 +3025,13 @@ void OBSBasicSettings::SimpleRecordingQualityLosslessWarning(int idx)
lastSimpleRecQualityIdx = idx;
}
+
+void OBSBasicSettings::on_disableOSXVSync_clicked()
+{
+#ifdef __APPLE__
+ if (!loading) {
+ bool disable = ui->disableOSXVSync->isChecked();
+ ui->resetOSXVSync->setEnabled(disable);
+ }
+#endif
+}
diff --git a/obs/window-basic-settings.hpp b/obs/window-basic-settings.hpp
index 8a592897e..ded66eedd 100644
--- a/obs/window-basic-settings.hpp
+++ b/obs/window-basic-settings.hpp
@@ -256,6 +256,8 @@ private slots:
void on_outputResolution_editTextChanged(const QString &text);
void on_baseResolution_editTextChanged(const QString &text);
+ void on_disableOSXVSync_clicked();
+
void GeneralChanged();
void AudioChanged();
void AudioChangedRestart();