diff options
author | Giulio Camuffo <giulio.camuffo@jollamobile.com> | 2014-02-10 14:32:34 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-03-11 15:05:34 +0100 |
commit | eeb365a8f164a1402c19ca5a7e38e01f4e69cf7b (patch) | |
tree | f50857284b63cb6497e5ac73f66ee3c32aee9b57 /src/compositor/wayland_wrapper/qwlsurface.cpp | |
parent | 666f597ccd2ced23ecc71ba497981d1a88c34d77 (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.cpp | 17 |
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) { |