diff options
author | Laszlo Agocs <laszlo.agocs@digia.com> | 2014-04-30 18:16:26 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-05-12 19:11:32 +0200 |
commit | 43db107bcc29a54044b020544e3874048687d8e7 (patch) | |
tree | e6d5e199ea34c4f6a9325a1d0e27372883d48268 /src/core/delegated_frame_node.cpp | |
parent | 85af7572d7326b0580970e8871b3f540b04fd484 (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>
Diffstat (limited to 'src/core/delegated_frame_node.cpp')
-rw-r--r-- | src/core/delegated_frame_node.cpp | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/src/core/delegated_frame_node.cpp b/src/core/delegated_frame_node.cpp index 6573c99a5..173e2d4c8 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; |