summaryrefslogtreecommitdiffstats
path: root/src/compositor/wayland_wrapper/qwlsurface.cpp
diff options
context:
space:
mode:
authorGiulio Camuffo <giulio.camuffo@jollamobile.com>2014-02-10 14:32:34 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-03-11 15:05:34 +0100
commiteeb365a8f164a1402c19ca5a7e38e01f4e69cf7b (patch)
treef50857284b63cb6497e5ac73f66ee3c32aee9b57 /src/compositor/wayland_wrapper/qwlsurface.cpp
parent666f597ccd2ced23ecc71ba497981d1a88c34d77 (diff)
Make sure the frame callbacks are sent at the right time
When there is a rendering thread, like with QtQuick compositors, there is a race condition where the frame callbacks are sent before the last buffer the client sent is released. Assume the following scenario: attach(B1)/frame(F1)/commit()...frame started...attach(B2)/frame(F2)/ commit()...frame finished. On frame finished the callback just installed is emitted before the buffer B2 is being used and B1 released. That forces the client to allocate a third buffer to draw the next frame. Now, do not send out the frame callbacks until a new frame started. The successive draw will release B1, use the new B2 and than send out F2. Change-Id: I5743c7baf9fdd3cde28c5f594ff646c06abb74b7 Reviewed-by: Gunnar Sletta <gunnar.sletta@jollamobile.com> Reviewed-by: Jørgen Lind <jorgen.lind@digia.com>
Diffstat (limited to 'src/compositor/wayland_wrapper/qwlsurface.cpp')
-rw-r--r--src/compositor/wayland_wrapper/qwlsurface.cpp17
1 files changed, 14 insertions, 3 deletions
diff --git a/src/compositor/wayland_wrapper/qwlsurface.cpp b/src/compositor/wayland_wrapper/qwlsurface.cpp
index a0e61bc22..cd5320677 100644
--- a/src/compositor/wayland_wrapper/qwlsurface.cpp
+++ b/src/compositor/wayland_wrapper/qwlsurface.cpp
@@ -78,6 +78,7 @@ public:
FrameCallback(Surface *surf, wl_resource *res)
: surface(surf)
, resource(res)
+ , canSend(false)
{
#if WAYLAND_VERSION_MAJOR < 1 || (WAYLAND_VERSION_MAJOR == 1 && WAYLAND_VERSION_MINOR <= 2)
res->data = this;
@@ -113,6 +114,7 @@ public:
}
Surface *surface;
wl_resource *resource;
+ bool canSend;
};
Surface::Surface(struct wl_client *client, uint32_t id, Compositor *compositor)
@@ -269,9 +271,12 @@ GLuint Surface::textureId() const
void Surface::sendFrameCallback()
{
uint time = m_compositor->currentTimeMsecs();
- foreach (FrameCallback *callback, m_frameCallbacks)
- callback->send(time);
- m_frameCallbacks.clear();
+ foreach (FrameCallback *callback, m_frameCallbacks) {
+ if (callback->canSend) {
+ callback->send(time);
+ m_frameCallbacks.removeOne(callback);
+ }
+ }
}
void Surface::removeFrameCallback(FrameCallback *callback)
@@ -480,6 +485,12 @@ void Surface::surface_commit(Resource *)
m_pendingFrameCallbacks.clear();
}
+void Surface::frameStarted()
+{
+ foreach (FrameCallback *c, m_frameCallbacks)
+ c->canSend = true;
+}
+
void Surface::setClassName(const QString &className)
{
if (m_className != className) {