diff --git a/src/util/opengl_context.h b/src/util/opengl_context.h index 1a2219617..e9d92e159 100644 --- a/src/util/opengl_context.h +++ b/src/util/opengl_context.h @@ -50,9 +50,10 @@ public: virtual bool ChangeSurface(const WindowInfo& new_wi) = 0; virtual void ResizeSurface(u32 new_surface_width = 0, u32 new_surface_height = 0) = 0; virtual bool SwapBuffers() = 0; - virtual bool IsCurrent() = 0; + virtual bool IsCurrent() const = 0; virtual bool MakeCurrent() = 0; virtual bool DoneCurrent() = 0; + virtual bool SupportsNegativeSwapInterval() const = 0; virtual bool SetSwapInterval(s32 interval) = 0; virtual std::unique_ptr CreateSharedContext(const WindowInfo& wi, Error* error) = 0; diff --git a/src/util/opengl_context_agl.h b/src/util/opengl_context_agl.h index 94639fadd..953cae6c5 100644 --- a/src/util/opengl_context_agl.h +++ b/src/util/opengl_context_agl.h @@ -28,9 +28,10 @@ public: bool ChangeSurface(const WindowInfo& new_wi) override; void ResizeSurface(u32 new_surface_width = 0, u32 new_surface_height = 0) override; bool SwapBuffers() override; - bool IsCurrent() override; + bool IsCurrent() const override; bool MakeCurrent() override; bool DoneCurrent() override; + bool SupportsNegativeSwapInterval() const override; bool SetSwapInterval(s32 interval) override; std::unique_ptr CreateSharedContext(const WindowInfo& wi, Error* error) override; diff --git a/src/util/opengl_context_agl.mm b/src/util/opengl_context_agl.mm index 35408d3de..4174c8553 100644 --- a/src/util/opengl_context_agl.mm +++ b/src/util/opengl_context_agl.mm @@ -123,7 +123,7 @@ bool OpenGLContextAGL::SwapBuffers() return true; } -bool OpenGLContextAGL::IsCurrent() +bool OpenGLContextAGL::IsCurrent() const { return (m_context != nil && [NSOpenGLContext currentContext] == m_context); } @@ -140,6 +140,11 @@ bool OpenGLContextAGL::DoneCurrent() return true; } +bool OpenGLContextAGL::SupportsNegativeSwapInterval() const +{ + return false; +} + bool OpenGLContextAGL::SetSwapInterval(s32 interval) { GLint gl_interval = static_cast(interval); diff --git a/src/util/opengl_context_egl.cpp b/src/util/opengl_context_egl.cpp index 7bdcb6593..53e97774e 100644 --- a/src/util/opengl_context_egl.cpp +++ b/src/util/opengl_context_egl.cpp @@ -291,7 +291,7 @@ bool OpenGLContextEGL::SwapBuffers() return eglSwapBuffers(m_display, m_surface); } -bool OpenGLContextEGL::IsCurrent() +bool OpenGLContextEGL::IsCurrent() const { return m_context && eglGetCurrentContext() == m_context; } @@ -312,6 +312,11 @@ bool OpenGLContextEGL::DoneCurrent() return eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); } +bool OpenGLContextEGL::SupportsNegativeSwapInterval() const +{ + return m_supports_negative_swap_interval; +} + bool OpenGLContextEGL::SetSwapInterval(s32 interval) { return eglSwapInterval(m_display, interval); @@ -473,10 +478,10 @@ void OpenGLContextEGL::DestroySurface() bool OpenGLContextEGL::CreateContext(const Version& version, EGLContext share_context) { - Log_DevPrintf("Trying version %u.%u (%s)", version.major_version, version.minor_version, - version.profile == OpenGLContext::Profile::ES ? - "ES" : - (version.profile == OpenGLContext::Profile::Core ? "Core" : "None")); + Log_DevFmt("Trying version {}.{} ({})", version.major_version, version.minor_version, + version.profile == OpenGLContext::Profile::ES ? + "ES" : + (version.profile == OpenGLContext::Profile::Core ? "Core" : "None")); int surface_attribs[16] = { EGL_RENDERABLE_TYPE, (version.profile == Profile::ES) ? @@ -531,14 +536,14 @@ bool OpenGLContextEGL::CreateContext(const Version& version, EGLContext share_co EGLint num_configs; if (!eglChooseConfig(m_display, surface_attribs, nullptr, 0, &num_configs) || num_configs == 0) { - Log_ErrorPrintf("eglChooseConfig() failed: %d", eglGetError()); + Log_ErrorFmt("eglChooseConfig() failed: 0x{:x}", static_cast(eglGetError())); return false; } std::vector configs(static_cast(num_configs)); if (!eglChooseConfig(m_display, surface_attribs, configs.data(), num_configs, &num_configs)) { - Log_ErrorPrintf("eglChooseConfig() failed: %d", eglGetError()); + Log_ErrorFmt("eglChooseConfig() failed: 0x{:x}", static_cast(eglGetError())); return false; } configs.resize(static_cast(num_configs)); @@ -555,7 +560,7 @@ bool OpenGLContextEGL::CreateContext(const Version& version, EGLContext share_co if (!config.has_value()) { - Log_WarningPrintf("No EGL configs matched exactly, using first."); + Log_WarningPrint("No EGL configs matched exactly, using first."); config = configs.front(); } @@ -573,21 +578,33 @@ bool OpenGLContextEGL::CreateContext(const Version& version, EGLContext share_co if (!eglBindAPI((version.profile == Profile::ES) ? EGL_OPENGL_ES_API : EGL_OPENGL_API)) { - Log_ErrorPrintf("eglBindAPI(%s) failed", (version.profile == Profile::ES) ? "EGL_OPENGL_ES_API" : "EGL_OPENGL_API"); + Log_ErrorFmt("eglBindAPI({}) failed", (version.profile == Profile::ES) ? "EGL_OPENGL_ES_API" : "EGL_OPENGL_API"); return false; } m_context = eglCreateContext(m_display, config.value(), share_context, attribs); if (!m_context) { - Log_ErrorPrintf("eglCreateContext() failed: %d", eglGetError()); + Log_ErrorFmt("eglCreateContext() failed: 0x{:x}", static_cast(eglGetError())); return false; } - Log_InfoPrintf("Got version %u.%u (%s)", version.major_version, version.minor_version, - version.profile == OpenGLContext::Profile::ES ? - "ES" : - (version.profile == OpenGLContext::Profile::Core ? "Core" : "None")); + Log_InfoFmt("Got version {}.{} ({})", version.major_version, version.minor_version, + version.profile == OpenGLContext::Profile::ES ? + "ES" : + (version.profile == OpenGLContext::Profile::Core ? "Core" : "None")); + + EGLint min_swap_interval, max_swap_interval; + m_supports_negative_swap_interval = false; + if (eglGetConfigAttrib(m_display, config.value(), EGL_MIN_SWAP_INTERVAL, &min_swap_interval) && + eglGetConfigAttrib(m_display, config.value(), EGL_MAX_SWAP_INTERVAL, &max_swap_interval)) + { + Log_VerboseFmt("EGL_MIN_SWAP_INTERVAL = {}", min_swap_interval); + Log_VerboseFmt("EGL_MAX_SWAP_INTERVAL = {}", max_swap_interval); + m_supports_negative_swap_interval = (min_swap_interval <= -1); + } + + Log_InfoFmt("Negative swap interval/tear-control is {}supported", m_supports_negative_swap_interval ? "" : "NOT "); m_config = config.value(); m_version = version; diff --git a/src/util/opengl_context_egl.h b/src/util/opengl_context_egl.h index 3ba78a722..43abd7e4f 100644 --- a/src/util/opengl_context_egl.h +++ b/src/util/opengl_context_egl.h @@ -20,9 +20,10 @@ public: virtual bool ChangeSurface(const WindowInfo& new_wi) override; virtual void ResizeSurface(u32 new_surface_width = 0, u32 new_surface_height = 0) override; bool SwapBuffers() override; - bool IsCurrent() override; + bool IsCurrent() const override; bool MakeCurrent() override; bool DoneCurrent() override; + bool SupportsNegativeSwapInterval() const override; bool SetSwapInterval(s32 interval) override; virtual std::unique_ptr CreateSharedContext(const WindowInfo& wi, Error* error) override; @@ -52,4 +53,5 @@ protected: EGLConfig m_config = {}; bool m_use_ext_platform_base = false; + bool m_supports_negative_swap_interval = false; }; diff --git a/src/util/opengl_context_wgl.cpp b/src/util/opengl_context_wgl.cpp index 2949ae184..acaa18081 100644 --- a/src/util/opengl_context_wgl.cpp +++ b/src/util/opengl_context_wgl.cpp @@ -160,6 +160,11 @@ bool OpenGLContextWGL::DoneCurrent() return wglMakeCurrent(m_dc, nullptr); } +bool OpenGLContextWGL::SupportsNegativeSwapInterval() const +{ + return GLAD_WGL_EXT_swap_control && GLAD_WGL_EXT_swap_control_tear; +} + bool OpenGLContextWGL::SetSwapInterval(s32 interval) { if (!GLAD_WGL_EXT_swap_control) diff --git a/src/util/opengl_context_wgl.h b/src/util/opengl_context_wgl.h index 644efddb0..836bd0f58 100644 --- a/src/util/opengl_context_wgl.h +++ b/src/util/opengl_context_wgl.h @@ -25,9 +25,10 @@ public: bool ChangeSurface(const WindowInfo& new_wi) override; void ResizeSurface(u32 new_surface_width = 0, u32 new_surface_height = 0) override; bool SwapBuffers() override; - bool IsCurrent() override; + bool IsCurrent() const override; bool MakeCurrent() override; bool DoneCurrent() override; + bool SupportsNegativeSwapInterval() const override; bool SetSwapInterval(s32 interval) override; std::unique_ptr CreateSharedContext(const WindowInfo& wi, Error* error) override;