summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@digia.com>2014-04-30 18:16:26 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-05-12 19:11:32 +0200
commit43db107bcc29a54044b020544e3874048687d8e7 (patch)
treee6d5e199ea34c4f6a9325a1d0e27372883d48268
parent85af7572d7326b0580970e8871b3f540b04fd484 (diff)
Check properly for EGL extensions before using them
Always check both EGL_EXTENSIONS and the validity of the returned function pointers. Otherwise bad things happen on EGL implementations that do not have the extension. Fix also linking to EGL. CONFIG+=egl has to be in core_module.pro too. Change-Id: I5e3dc54675d83123fc79e2d27a7af19fcc7f936a Reviewed-by: Jocelyn Turcotte <jocelyn.turcotte@digia.com>
-rw-r--r--src/core/core_module.pro2
-rw-r--r--src/core/delegated_frame_node.cpp27
2 files changed, 22 insertions, 7 deletions
diff --git a/src/core/core_module.pro b/src/core/core_module.pro
index ef9721a1..7aad0de9 100644
--- a/src/core/core_module.pro
+++ b/src/core/core_module.pro
@@ -19,3 +19,5 @@ load(qt_module)
# Using -Wl,-Bsymbolic-functions seems to confuse the dynamic linker
# and doesn't let Chromium get access to libc symbols through dlsym.
CONFIG -= bsymbolic_functions
+
+contains(QT_CONFIG, egl): CONFIG += egl
diff --git a/src/core/delegated_frame_node.cpp b/src/core/delegated_frame_node.cpp
index 6573c99a..173e2d4c 100644
--- a/src/core/delegated_frame_node.cpp
+++ b/src/core/delegated_frame_node.cpp
@@ -213,6 +213,15 @@ static QSGNode *buildLayerChain(QSGNode *chainParent, const cc::SharedQuadState
return layerChain;
}
+#if !defined(QT_NO_EGL)
+static bool hasEGLExtension(EGLDisplay display, const char *name)
+{
+ QList<QByteArray> extensions = QByteArray(reinterpret_cast<const char *>(
+ eglQueryString(display, EGL_EXTENSIONS))).split(' ');
+ return extensions.contains(name);
+}
+#endif
+
static void waitAndDeleteChromiumSync(FenceSync *sync)
{
// Chromium uses its own GL bindings and stores in in thread local storage.
@@ -229,16 +238,20 @@ static void waitAndDeleteChromiumSync(FenceSync *sync)
static PFNEGLDESTROYSYNCKHRPROC eglDestroySyncKHR = 0;
if (!resolved) {
- QOpenGLContext *context = QOpenGLContext::currentContext();
- eglClientWaitSyncKHR = (PFNEGLCLIENTWAITSYNCKHRPROC)context->getProcAddress("eglClientWaitSyncKHR");
- eglDestroySyncKHR = (PFNEGLDESTROYSYNCKHRPROC)context->getProcAddress("eglDestroySyncKHR");
+ if (hasEGLExtension(sync->egl.display, "EGL_KHR_reusable_sync")) {
+ QOpenGLContext *context = QOpenGLContext::currentContext();
+ eglClientWaitSyncKHR = (PFNEGLCLIENTWAITSYNCKHRPROC)context->getProcAddress("eglClientWaitSyncKHR");
+ eglDestroySyncKHR = (PFNEGLDESTROYSYNCKHRPROC)context->getProcAddress("eglDestroySyncKHR");
+ }
resolved = true;
}
- // FIXME: Use the less wasteful eglWaitSyncKHR once we have a device that supports EGL_KHR_wait_sync.
- eglClientWaitSyncKHR(sync->egl.display, sync->egl.sync, 0, EGL_FOREVER_KHR);
- eglDestroySyncKHR(sync->egl.display, sync->egl.sync);
- sync->reset();
+ if (eglClientWaitSyncKHR && eglDestroySyncKHR) {
+ // FIXME: Use the less wasteful eglWaitSyncKHR once we have a device that supports EGL_KHR_wait_sync.
+ eglClientWaitSyncKHR(sync->egl.display, sync->egl.sync, 0, EGL_FOREVER_KHR);
+ eglDestroySyncKHR(sync->egl.display, sync->egl.sync);
+ sync->reset();
+ }
}
#endif
break;