summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMikko Levonmaa <mikko.levonmaa@lge.com>2015-11-10 14:46:26 +0200
committerMikko Levonmaa <mikko.levonmaa@bitfactor.fi>2015-11-12 06:41:18 +0000
commit7963e85b771852f96a923839cd0530219676914e (patch)
tree61df438b04210a1fbd2953bc2b12ab6bd2919ab3
parent2eff05fe14c910c8b2cade8674e49404c6843e74 (diff)
Make swap buffer call non-blocking for subsurfaces
Allows clients that use subsurfaces in synchronized mode to continue processing the event loop even in cases where a frame callback is not delivered from the compositor pending a parent surface commit Change-Id: I7df38afc4080546b60184dacecde321ba8062fac Reviewed-by: Giulio Camuffo <giulio.camuffo@jollamobile.com>
-rw-r--r--src/client/qwaylandsubsurface.cpp2
-rw-r--r--src/client/qwaylandsubsurface_p.h3
-rw-r--r--src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp30
-rw-r--r--src/hardwareintegration/client/wayland-egl/qwaylandglcontext.h1
4 files changed, 35 insertions, 1 deletions
diff --git a/src/client/qwaylandsubsurface.cpp b/src/client/qwaylandsubsurface.cpp
index 72b80c18f..eac847c75 100644
--- a/src/client/qwaylandsubsurface.cpp
+++ b/src/client/qwaylandsubsurface.cpp
@@ -58,11 +58,13 @@ QWaylandSubSurface::~QWaylandSubSurface()
void QWaylandSubSurface::setSync()
{
+ QMutexLocker l(&m_syncLock);
QWaylandSubSurface::set_sync();
}
void QWaylandSubSurface::setDeSync()
{
+ QMutexLocker l(&m_syncLock);
QWaylandSubSurface::set_desync();
}
diff --git a/src/client/qwaylandsubsurface_p.h b/src/client/qwaylandsubsurface_p.h
index 5255df5c9..b8ea6aaf3 100644
--- a/src/client/qwaylandsubsurface_p.h
+++ b/src/client/qwaylandsubsurface_p.h
@@ -48,6 +48,7 @@
#include <wayland-client.h>
#include <QtCore/qglobal.h>
+#include <QtCore/qmutex.h>
#include <QtWaylandClient/private/qwaylandclientexport_p.h>
#include <QtWaylandClient/private/qwayland-wayland.h>
@@ -71,6 +72,7 @@ public:
void setSync();
void setDeSync();
bool isSync() const { return m_synchronized; }
+ QMutex *syncMutex() { return &m_syncLock; }
private:
@@ -81,6 +83,7 @@ private:
QWaylandWindow *m_window;
QWaylandWindow *m_parent;
bool m_synchronized;
+ QMutex m_syncLock;
};
diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
index 18ed1d61e..b8ba4c631 100644
--- a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
+++ b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
@@ -35,6 +35,7 @@
#include <QtWaylandClient/private/qwaylanddisplay_p.h>
#include <QtWaylandClient/private/qwaylandwindow_p.h>
+#include <QtWaylandClient/private/qwaylandsubsurface_p.h>
#include <QtWaylandClient/private/qwaylandabstractdecoration_p.h>
#include <QtWaylandClient/private/qwaylandintegration_p.h>
#include "qwaylandeglwindow.h"
@@ -50,6 +51,8 @@
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QOpenGLFunctions>
+#include <QtCore/qmutex.h>
+
// Constants from EGL_KHR_create_context
#ifndef EGL_CONTEXT_MINOR_VERSION_KHR
#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB
@@ -220,6 +223,7 @@ QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, QWaylandDisplay *dis
, m_display(display)
, m_blitter(0)
, mUseNativeDefaultFbo(false)
+ , mSupportNonBlockingSwap(true)
{
QSurfaceFormat fmt = format;
if (static_cast<QWaylandIntegration *>(QGuiApplicationPrivate::platformIntegration())->display()->supportsWindowDecoration())
@@ -290,6 +294,17 @@ QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, QWaylandDisplay *dis
return;
}
+ EGLint a = EGL_MIN_SWAP_INTERVAL;
+ EGLint b = EGL_MAX_SWAP_INTERVAL;
+ if (!eglGetConfigAttrib(m_eglDisplay, m_config, a, &a) ||
+ !eglGetConfigAttrib(m_eglDisplay, m_config, b, &b) ||
+ a > 0) {
+ mSupportNonBlockingSwap = false;
+ }
+ if (!mSupportNonBlockingSwap) {
+ qWarning() << "Non-blocking swap buffers not supported. Subsurface rendering can be affected.";
+ }
+
updateGLFormat();
}
@@ -518,7 +533,20 @@ void QWaylandGLContext::swapBuffers(QPlatformSurface *surface)
m_blitter->blit(window);
}
- eglSwapBuffers(m_eglDisplay, eglSurface);
+
+ QWaylandSubSurface *sub = window->subSurfaceWindow();
+ if (sub) {
+ QMutexLocker l(sub->syncMutex());
+
+ int si = (sub->isSync() && mSupportNonBlockingSwap) ? 0 : m_format.swapInterval();
+
+ eglSwapInterval(m_eglDisplay, si);
+ eglSwapBuffers(m_eglDisplay, eglSurface);
+ } else {
+ eglSwapInterval(m_eglDisplay, m_format.swapInterval());
+ eglSwapBuffers(m_eglDisplay, eglSurface);
+ }
+
window->setCanResize(true);
}
diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.h b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.h
index bc92c9501..42236c643 100644
--- a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.h
+++ b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.h
@@ -86,6 +86,7 @@ private:
DecorationsBlitter *m_blitter;
bool mUseNativeDefaultFbo;
uint m_api;
+ bool mSupportNonBlockingSwap;
friend class DecorationsBlitter;
};