summaryrefslogtreecommitdiff
path: root/src/render
diff options
context:
space:
mode:
authorVaxry <43317083+vaxerski@users.noreply.github.com>2025-07-19 12:38:41 +0200
committerGitHub <noreply@github.com>2025-07-19 12:38:41 +0200
commitd84699d8e5e984422da37595ee41fc0d8d93fef5 (patch)
treeb3ed5c1f47d25e961c53c823ead9d0000141a138 /src/render
parentae3cc48f223386b057137400354ed0ca1f7a8b1a (diff)
opengl: detect android fence support and disable explicit if it's missing (#11077)
Checks for explicit sync support via the android fences, and falls back to implicit sync if it isn't
Diffstat (limited to 'src/render')
-rw-r--r--src/render/OpenGL.cpp17
-rw-r--r--src/render/OpenGL.hpp3
-rw-r--r--src/render/Renderer.cpp22
3 files changed, 36 insertions, 6 deletions
diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp
index 65d0cf38..b1dfc073 100644
--- a/src/render/OpenGL.cpp
+++ b/src/render/OpenGL.cpp
@@ -257,7 +257,7 @@ EGLDeviceEXT CHyprOpenGLImpl::eglDeviceFromDRMFD(int drmFD) {
CHyprOpenGLImpl::CHyprOpenGLImpl() : m_drmFD(g_pCompositor->m_drmFD) {
const std::string EGLEXTENSIONS = (const char*)eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
- Debug::log(LOG, "Supported EGL extensions: ({}) {}", std::ranges::count(EGLEXTENSIONS, ' '), EGLEXTENSIONS);
+ Debug::log(LOG, "Supported EGL global extensions: ({}) {}", std::ranges::count(EGLEXTENSIONS, ' '), EGLEXTENSIONS);
m_exts.KHR_display_reference = EGLEXTENSIONS.contains("KHR_display_reference");
@@ -344,6 +344,15 @@ CHyprOpenGLImpl::CHyprOpenGLImpl() : m_drmFD(g_pCompositor->m_drmFD) {
if (!m_exts.EXT_image_dma_buf_import || !m_exts.EXT_image_dma_buf_import_modifiers)
Debug::log(WARN, "Your GPU does not support DMABUFs, this will possibly cause issues and will take a hit on the performance.");
+ const std::string EGLEXTENSIONS_DISPLAY = (const char*)eglQueryString(m_eglDisplay, EGL_EXTENSIONS);
+
+ Debug::log(LOG, "Supported EGL display extensions: ({}) {}", std::ranges::count(EGLEXTENSIONS_DISPLAY, ' '), EGLEXTENSIONS_DISPLAY);
+
+ m_exts.EGL_ANDROID_native_fence_sync_ext = EGLEXTENSIONS_DISPLAY.contains("EGL_ANDROID_native_fence_sync");
+
+ if (!m_exts.EGL_ANDROID_native_fence_sync_ext)
+ Debug::log(WARN, "Your GPU does not support explicit sync via the EGL_ANDROID_native_fence_sync extension.");
+
#ifdef USE_TRACY_GPU
loadGLProc(&glQueryCounter, "glQueryCounterEXT");
@@ -3054,6 +3063,10 @@ uint32_t CHyprOpenGLImpl::getPreferredReadFormat(PHLMONITOR pMonitor) {
return pMonitor->m_output->state->state().drmFormat;
}
+bool CHyprOpenGLImpl::explicitSyncSupported() {
+ return m_exts.EGL_ANDROID_native_fence_sync_ext;
+}
+
std::vector<SDRMFormat> CHyprOpenGLImpl::getDRMFormats() {
return m_drmFormats;
}
@@ -3120,6 +3133,8 @@ float SRenderModifData::combinedScale() {
}
UP<CEGLSync> CEGLSync::create() {
+ RASSERT(g_pHyprOpenGL->m_exts.EGL_ANDROID_native_fence_sync_ext, "Tried to create an EGL sync when syncs are not supported on the gpu");
+
EGLSyncKHR sync = g_pHyprOpenGL->m_proc.eglCreateSyncKHR(g_pHyprOpenGL->m_eglDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
if (sync == EGL_NO_SYNC_KHR) {
diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp
index 4c6f55f9..c5040e0e 100644
--- a/src/render/OpenGL.hpp
+++ b/src/render/OpenGL.hpp
@@ -253,6 +253,8 @@ class CHyprOpenGLImpl {
void ensureLockTexturesRendered(bool load);
+ bool explicitSyncSupported();
+
bool m_shadersInitialized = false;
SP<SPreparedShaders> m_shaders;
@@ -297,6 +299,7 @@ class CHyprOpenGLImpl {
bool KHR_display_reference = false;
bool IMG_context_priority = false;
bool EXT_create_context_robustness = false;
+ bool EGL_ANDROID_native_fence_sync_ext = false;
} m_exts;
SP<CTexture> m_screencopyDeniedTexture;
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp
index e9797fbe..13f8ff4d 100644
--- a/src/render/Renderer.cpp
+++ b/src/render/Renderer.cpp
@@ -2326,6 +2326,22 @@ void CHyprRenderer::endRender(const std::function<void()>& renderingDoneCallback
if (m_renderMode == RENDER_MODE_NORMAL)
PMONITOR->m_output->state->setBuffer(m_currentBuffer);
+ if (!g_pHyprOpenGL->explicitSyncSupported()) {
+ Debug::log(TRACE, "renderer: Explicit sync unsupported, falling back to implicit in endRender");
+
+ // nvidia doesn't have implicit sync, so we have to explicitly wait here
+ if (isNvidia() && *PNVIDIAANTIFLICKER)
+ glFinish();
+ else
+ glFlush(); // mark an implicit sync point
+
+ m_usedAsyncBuffers.clear(); // release all buffer refs and hope implicit sync works
+ if (renderingDoneCallback)
+ renderingDoneCallback();
+
+ return;
+ }
+
UP<CEGLSync> eglSync = CEGLSync::create();
if (eglSync && eglSync->isValid()) {
for (auto const& buf : m_usedAsyncBuffers) {
@@ -2350,11 +2366,7 @@ void CHyprRenderer::endRender(const std::function<void()>& renderingDoneCallback
PMONITOR->m_output->state->setExplicitInFence(PMONITOR->m_inFence.get());
}
} else {
- Debug::log(ERR, "renderer: couldn't use EGLSync for explicit gpu synchronization");
-
- // nvidia doesn't have implicit sync, so we have to explicitly wait here
- if (isNvidia() && *PNVIDIAANTIFLICKER)
- glFinish();
+ Debug::log(ERR, "renderer: Explicit sync failed, releasing resources");
m_usedAsyncBuffers.clear(); // release all buffer refs and hope implicit sync works
if (renderingDoneCallback)