Qt: Manually toggle swap interval as needed

This commit is contained in:
Vicki Pfau 2023-04-18 17:47:33 -07:00
parent d79a83321c
commit 70bbe06bfb
7 changed files with 69 additions and 1 deletions

View File

@ -419,6 +419,13 @@ if(BUILD_GL)
elseif(UNIX AND NOT APPLE AND TARGET OpenGL::GL)
set(OPENGL_LIBRARY OpenGL::GL)
endif()
if(OpenGL_GLX_FOUND)
list(APPEND FEATURES GLX)
endif()
if(OpenGL_EGL_FOUND)
list(APPEND FEATURES EGL)
list(APPEND OPENGL_LIBRARY ${OPENGL_egl_LIBRARY})
endif()
endif()
if(BUILD_GL)
list(APPEND FEATURE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/opengl/gl.c)

View File

@ -111,6 +111,7 @@ void QGBA::Display::configure(ConfigController* config) {
filter(opts->resampleVideo);
config->updateOption("showOSD");
config->updateOption("showFrameCounter");
config->updateOption("videoSync");
#if defined(BUILD_GL) || defined(BUILD_GLES2) || defined(BUILD_GLES3)
if (opts->shader && supportsShaders()) {
struct VDir* shader = VDirOpen(opts->shader);

View File

@ -72,6 +72,7 @@ public slots:
virtual void showOSDMessages(bool enable);
virtual void showFrameCounter(bool enable);
virtual void filter(bool filter);
virtual void swapInterval(int interval) = 0;
virtual void framePosted() = 0;
virtual void setShaders(struct VDir*) = 0;
virtual void clearShaders() = 0;

View File

@ -38,6 +38,21 @@ using QOpenGLFunctions_Baseline = QOpenGLFunctions_3_2_Core;
#endif
#endif
#ifdef _WIN32
#include <windows.h>
#elif defined(Q_OS_MAC)
#include <OpenGL/OpenGL.h>
#endif
#ifdef USE_GLX
#define GLX_GLXEXT_PROTOTYPES
typedef struct _XDisplay Display;
#include <GL/glx.h>
#include <GL/glxext.h>
#endif
#ifdef USE_EGL
#include <EGL/egl.h>
#endif
#ifdef _WIN32
#define OVERHEAD_NSEC 1000000
#else
@ -412,6 +427,10 @@ void DisplayGL::filter(bool filter) {
QMetaObject::invokeMethod(m_painter.get(), "filter", Q_ARG(bool, filter));
}
void DisplayGL::swapInterval(int interval) {
QMetaObject::invokeMethod(m_painter.get(), "swapInterval", Q_ARG(int, interval));
}
void DisplayGL::framePosted() {
m_painter->enqueue(m_context->drawContext());
QMetaObject::invokeMethod(m_painter.get(), "draw");
@ -717,6 +736,32 @@ void PainterGL::filter(bool filter) {
}
}
void PainterGL::swapInterval(int interval) {
if (!m_started) {
return;
}
m_swapInterval = interval;
#ifdef Q_OS_WIN
wglSwapIntervalEXT(interval);
#elif defined(Q_OS_MAC)
CGLSetParameter(CGLGetCurrentContext(), kCGLCPSwapInterval, &interval);
#else
#ifdef USE_GLX
if (QGuiApplication::platformName() == "xcb") {
::Display* display = glXGetCurrentDisplay();
GLXDrawable drawable = glXGetCurrentDrawable();
glXSwapIntervalEXT(display, drawable, interval);
}
#endif
#ifdef USE_EGL
if (QGuiApplication::platformName().contains("egl")) {
EGLDisplay display = eglGetCurrentDisplay();
eglSwapInterval(display, interval);
}
#endif
#endif
}
#ifndef GL_DEBUG_OUTPUT_SYNCHRONOUS
#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242
#endif
@ -773,6 +818,9 @@ void PainterGL::draw() {
}
return;
}
if (m_swapInterval != !!sync->videoFrameWait) {
swapInterval(!!sync->videoFrameWait);
}
dequeue();
bool forceRedraw = true;
if (!m_delayTimer.isValid()) {

View File

@ -108,6 +108,7 @@ public slots:
void showOSDMessages(bool enable) override;
void showFrameCounter(bool enable) override;
void filter(bool filter) override;
void swapInterval(int interval) override;
void framePosted() override;
void setShaders(struct VDir*) override;
void clearShaders() override;
@ -182,6 +183,7 @@ public slots:
void showOSD(bool enable);
void showFrameCounter(bool enable);
void filter(bool filter);
void swapInterval(int interval);
void resizeContext();
void updateFramebufferHandle();
@ -240,6 +242,7 @@ private:
MessagePainter* m_messagePainter = nullptr;
QElapsedTimer m_delayTimer;
std::shared_ptr<VideoProxy> m_videoProxy;
int m_swapInterval = -1;
};
}

View File

@ -31,6 +31,7 @@ public slots:
void lockAspectRatio(bool lock) override;
void lockIntegerScaling(bool lock) override;
void interframeBlending(bool enable) override;
void swapInterval(int) override {};
void filter(bool filter) override;
void framePosted() override;
void setShaders(struct VDir*) override {}

View File

@ -1788,7 +1788,14 @@ void Window::setupMenu(QMenuBar* menubar) {
void Window::setupOptions() {
ConfigOption* videoSync = m_config->addOption("videoSync");
videoSync->connect([this](const QVariant&) {
videoSync->connect([this](const QVariant& variant) {
if (m_display) {
bool ok;
int interval = variant.toInt(&ok);
if (ok) {
m_display->swapInterval(interval);
}
}
reloadConfig();
}, this);