diff options
author | Giulio Camuffo <giulio.camuffo@jollamobile.com> | 2014-02-10 13:29:49 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-03-11 14:25:00 +0100 |
commit | 666f597ccd2ced23ecc71ba497981d1a88c34d77 (patch) | |
tree | ed8e1e89840688d78c3017de90a899d773b99144 | |
parent | 8643053f8f5255fb8e21911c9e7287e675f4b4ed (diff) | |
download | qtwayland-666f597ccd2ced23ecc71ba497981d1a88c34d77.tar.gz qtwayland-666f597ccd2ced23ecc71ba497981d1a88c34d77.tar.bz2 qtwayland-666f597ccd2ced23ecc71ba497981d1a88c34d77.zip |
Remove the buffer queue.
A client calling attach(A);commit();attach(B);commit() should result
in its back buffer be set to B, and A be discarded.
If the client wants to have a queue it should keep it client side or
a protocol extension tailored for that purpose should be developed.
Change-Id: Ia0048f311504d85821df9f5b9225887801efec71
Reviewed-by: Jørgen Lind <jorgen.lind@digia.com>
-rw-r--r-- | examples/qwidget-compositor/main.cpp | 10 | ||||
-rw-r--r-- | examples/qwindow-compositor/qwindowcompositor.cpp | 10 | ||||
-rw-r--r-- | examples/qwindow-compositor/qwindowcompositor.h | 4 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandsurface.cpp | 4 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandsurface.h | 4 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandsurfaceitem.cpp | 4 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandsurfaceitem.h | 2 | ||||
-rw-r--r-- | src/compositor/wayland_wrapper/qwlsurface.cpp | 101 | ||||
-rw-r--r-- | src/compositor/wayland_wrapper/qwlsurface_p.h | 15 | ||||
-rw-r--r-- | src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp | 13 | ||||
-rw-r--r-- | src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h | 4 |
11 files changed, 59 insertions, 112 deletions
diff --git a/examples/qwidget-compositor/main.cpp b/examples/qwidget-compositor/main.cpp index c0e688cf..cf7fdda7 100644 --- a/examples/qwidget-compositor/main.cpp +++ b/examples/qwidget-compositor/main.cpp @@ -110,13 +110,13 @@ private slots: update(); } - void surfaceDamaged(const QRect &rect) { + void surfaceDamaged(const QRegion &rect) { QWaylandSurface *surface = qobject_cast<QWaylandSurface *>(sender()); surfaceDamaged(surface, rect); } protected: - void surfaceDamaged(QWaylandSurface *surface, const QRect &rect) + void surfaceDamaged(QWaylandSurface *surface, const QRegion &rect) { #ifdef QT_COMPOSITOR_WAYLAND_GL Q_UNUSED(surface); @@ -130,7 +130,7 @@ protected: void surfaceCreated(QWaylandSurface *surface) { connect(surface, SIGNAL(destroyed(QObject *)), this, SLOT(surfaceDestroyed(QObject *))); connect(surface, SIGNAL(mapped()), this, SLOT(surfaceMapped())); - connect(surface, SIGNAL(damaged(const QRect &)), this, SLOT(surfaceDamaged(const QRect &))); + connect(surface, SIGNAL(damaged(const QRegion &)), this, SLOT(surfaceDamaged(const QRegion &))); update(); } @@ -140,7 +140,7 @@ protected: QOpenGLFunctions *functions = QOpenGLContext::currentContext()->functions(); QSize windowSize = surface->size(); - surface->advanceBufferQueue(); + surface->swapBuffers(); if (!m_surfaceCompositorFbo) functions->glGenFramebuffers(1,&m_surfaceCompositorFbo); @@ -173,7 +173,7 @@ protected: QWaylandSurface *subSurface = i.next(); QPointF p = subSurface->mapTo(window,QPoint(0,0)); QSize size = subSurface->size(); - subSurface->advanceBufferQueue(); + subSurface->swapBuffers(); if (size.isValid()) { GLuint texture = 0; if (subSurface->type() == QWaylandSurface::Texture) { diff --git a/examples/qwindow-compositor/qwindowcompositor.cpp b/examples/qwindow-compositor/qwindowcompositor.cpp index 1d9c3d5e..9eef717e 100644 --- a/examples/qwindow-compositor/qwindowcompositor.cpp +++ b/examples/qwindow-compositor/qwindowcompositor.cpp @@ -159,7 +159,7 @@ void QWindowCompositor::surfaceUnmapped() ensureKeyboardFocusSurface(surface); } -void QWindowCompositor::surfaceDamaged(const QRect &rect) +void QWindowCompositor::surfaceDamaged(const QRegion &rect) { QWaylandSurface *surface = qobject_cast<QWaylandSurface *>(sender()); surfaceDamaged(surface, rect); @@ -170,7 +170,7 @@ void QWindowCompositor::surfacePosChanged() m_renderScheduler.start(0); } -void QWindowCompositor::surfaceDamaged(QWaylandSurface *surface, const QRect &rect) +void QWindowCompositor::surfaceDamaged(QWaylandSurface *surface, const QRegion &rect) { Q_UNUSED(surface) Q_UNUSED(rect) @@ -182,7 +182,7 @@ void QWindowCompositor::surfaceCreated(QWaylandSurface *surface) connect(surface, SIGNAL(destroyed(QObject *)), this, SLOT(surfaceDestroyed(QObject *))); connect(surface, SIGNAL(mapped()), this, SLOT(surfaceMapped())); connect(surface, SIGNAL(unmapped()), this, SLOT(surfaceUnmapped())); - connect(surface, SIGNAL(damaged(const QRect &)), this, SLOT(surfaceDamaged(const QRect &))); + connect(surface, SIGNAL(damaged(const QRegion &)), this, SLOT(surfaceDamaged(const QRegion &))); connect(surface, SIGNAL(extendedSurfaceReady()), this, SLOT(sendExpose())); connect(surface, SIGNAL(posChanged()), this, SLOT(surfacePosChanged())); m_renderScheduler.start(0); @@ -253,7 +253,7 @@ GLuint QWindowCompositor::composeSurface(QWaylandSurface *surface, bool *texture GLuint texture = 0; QSize windowSize = surface->size(); - surface->advanceBufferQueue(); + surface->swapBuffers(); QOpenGLFunctions *functions = QOpenGLContext::currentContext()->functions(); functions->glBindFramebuffer(GL_FRAMEBUFFER, m_surface_fbo); @@ -288,7 +288,7 @@ void QWindowCompositor::paintChildren(QWaylandSurface *surface, QWaylandSurface QWaylandSurface *subSurface = i.next(); QPointF p = subSurface->mapTo(window,QPointF(0,0)); QSize subSize = subSurface->size(); - subSurface->advanceBufferQueue(); + subSurface->swapBuffers(); if (subSize.isValid()) { GLuint texture = 0; if (subSurface->type() == QWaylandSurface::Texture) { diff --git a/examples/qwindow-compositor/qwindowcompositor.h b/examples/qwindow-compositor/qwindowcompositor.h index c58c0d57..f8d354c3 100644 --- a/examples/qwindow-compositor/qwindowcompositor.h +++ b/examples/qwindow-compositor/qwindowcompositor.h @@ -61,12 +61,12 @@ private slots: void surfaceDestroyed(QObject *object); void surfaceMapped(); void surfaceUnmapped(); - void surfaceDamaged(const QRect &rect); + void surfaceDamaged(const QRegion &rect); void surfacePosChanged(); void render(); protected: - void surfaceDamaged(QWaylandSurface *surface, const QRect &rect); + void surfaceDamaged(QWaylandSurface *surface, const QRegion &rect); void surfaceCreated(QWaylandSurface *surface); QWaylandSurface* surfaceAt(const QPointF &point, QPointF *local = 0); diff --git a/src/compositor/compositor_api/qwaylandsurface.cpp b/src/compositor/compositor_api/qwaylandsurface.cpp index a865f32d..f9eda135 100644 --- a/src/compositor/compositor_api/qwaylandsurface.cpp +++ b/src/compositor/compositor_api/qwaylandsurface.cpp @@ -104,10 +104,10 @@ QWaylandSurface::QWaylandSurface(QtWayland::Surface *surface) #endif } -void QWaylandSurface::advanceBufferQueue() +void QWaylandSurface::swapBuffers() { Q_D(const QWaylandSurface); - d->surface->advanceBufferQueue(); + d->surface->swapBuffers(); } WaylandClient *QWaylandSurface::client() const diff --git a/src/compositor/compositor_api/qwaylandsurface.h b/src/compositor/compositor_api/qwaylandsurface.h index 7dc219d9..774464a8 100644 --- a/src/compositor/compositor_api/qwaylandsurface.h +++ b/src/compositor/compositor_api/qwaylandsurface.h @@ -178,7 +178,7 @@ public: Q_INVOKABLE void destroySurfaceByForce(); Q_INVOKABLE void ping(); - void advanceBufferQueue(); + void swapBuffers(); public slots: void updateSelection(); @@ -186,7 +186,7 @@ public slots: signals: void mapped(); void unmapped(); - void damaged(const QRect &rect); + void damaged(const QRegion &rect); void parentChanged(QWaylandSurface *newParent, QWaylandSurface *oldParent); void sizeChanged(); void posChanged(); diff --git a/src/compositor/compositor_api/qwaylandsurfaceitem.cpp b/src/compositor/compositor_api/qwaylandsurfaceitem.cpp index 04649fa7..b87bbb61 100644 --- a/src/compositor/compositor_api/qwaylandsurfaceitem.cpp +++ b/src/compositor/compositor_api/qwaylandsurfaceitem.cpp @@ -298,7 +298,7 @@ void QWaylandSurfaceItem::setDamagedFlag(bool on) } -void QWaylandSurfaceItem::surfaceDamaged(const QRect &) +void QWaylandSurfaceItem::surfaceDamaged(const QRegion &) { m_damaged = true; if (m_surface) { @@ -390,7 +390,7 @@ QSGNode *QWaylandSurfaceItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeD // Order here is important, as the state of visible is that of the pending // buffer but will be replaced after we advance the buffer queue. bool visible = m_surface->visible(); - surface()->advanceBufferQueue(); + surface()->swapBuffers(); if (visible) updateTexture(); diff --git a/src/compositor/compositor_api/qwaylandsurfaceitem.h b/src/compositor/compositor_api/qwaylandsurfaceitem.h index 26288a7d..b17b892f 100644 --- a/src/compositor/compositor_api/qwaylandsurfaceitem.h +++ b/src/compositor/compositor_api/qwaylandsurfaceitem.h @@ -112,7 +112,7 @@ private slots: void surfaceMapped(); void surfaceUnmapped(); void surfaceDestroyed(QObject *object); - void surfaceDamaged(const QRect &); + void surfaceDamaged(const QRegion &); void parentChanged(QWaylandSurface *newParent, QWaylandSurface *oldParent); void updateSize(); void updateSurfaceSize(); diff --git a/src/compositor/wayland_wrapper/qwlsurface.cpp b/src/compositor/wayland_wrapper/qwlsurface.cpp index 79b83ab7..a0e61bc2 100644 --- a/src/compositor/wayland_wrapper/qwlsurface.cpp +++ b/src/compositor/wayland_wrapper/qwlsurface.cpp @@ -129,6 +129,8 @@ Surface::Surface(struct wl_client *client, uint32_t id, Compositor *compositor) , m_transientInactive(false) , m_isCursorSurface(false) { + m_pending.buffer = 0; + m_pending.newlyAttached = false; } Surface::~Surface() @@ -335,7 +337,7 @@ Compositor *Surface::compositor() const return m_compositor; } -void Surface::advanceBufferQueue() +void Surface::swapBuffers() { SurfaceBuffer *front = m_frontBuffer; @@ -349,16 +351,6 @@ void Surface::advanceBufferQueue() m_backBuffer = 0; } - // Set a new back buffer if there is something in the queue. - if (m_bufferQueue.size() && m_bufferQueue.first()->isComitted()) { - SurfaceBuffer *next = m_bufferQueue.takeFirst(); - while (next && next->isDestroyed()) { - next->disown(); - next = m_bufferQueue.size() ? m_bufferQueue.takeFirst() : 0; - } - setBackBuffer(next); - } - // Release the old front buffer if we changed it. if (front && front != m_frontBuffer) front->disown(); @@ -366,7 +358,7 @@ void Surface::advanceBufferQueue() /*! * Sets the backbuffer for this surface. The back buffer is not yet on - * screen and will become live during the next advanceBufferQueue(). + * screen and will become live during the next swapBuffers(). * * The backbuffer represents the current state of the surface for the * purpose of GUI-thread accessible properties such as size and visibility. @@ -387,7 +379,8 @@ void Surface::setBackBuffer(SurfaceBuffer *buffer) emit m_waylandSurface->unmapped(); } - emit m_waylandSurface->damaged(m_backBuffer->damageRect()); + m_damage = m_damage.intersected(QRect(QPoint(), m_size)); + emit m_waylandSurface->damaged(m_damage); } else { InputDevice *inputDevice = m_compositor->defaultInputDevice(); if (inputDevice->keyboardFocus() == this) @@ -395,6 +388,7 @@ void Surface::setBackBuffer(SurfaceBuffer *buffer) if (inputDevice->mouseFocus() == this) inputDevice->setMouseFocus(0, QPointF(), QPointF()); } + m_damage = QRegion(); } SurfaceBuffer *Surface::createSurfaceBuffer(struct ::wl_resource *buffer) @@ -419,41 +413,6 @@ SurfaceBuffer *Surface::createSurfaceBuffer(struct ::wl_resource *buffer) return newBuffer; } -void Surface::attach(struct ::wl_resource *buffer) -{ - SurfaceBuffer *last = m_bufferQueue.size()?m_bufferQueue.last():0; - if (last) { - if (last->waylandBufferHandle() == buffer) { - if (QT_WAYLAND_PRINT_BUFFERING_WARNINGS) - qWarning() << "attaching already attached buffer"; - return; - } - if (!last->damageRect().isValid() || !last->isComitted() || isCursorSurface() ){ - last->disown(); - m_bufferQueue.takeLast(); - } - } - - SurfaceBuffer *surfBuf = createSurfaceBuffer(buffer); - m_bufferQueue << surfBuf; -} - -void Surface::damage(const QRect &rect) -{ - if (m_bufferQueue.empty()) { - if (QT_WAYLAND_PRINT_BUFFERING_WARNINGS) - qWarning() << "Surface::damage() null buffer"; - return; - } - SurfaceBuffer *surfaceBuffer = m_bufferQueue.last(); - if (surfaceBuffer->isComitted()) { - if (QT_WAYLAND_PRINT_BUFFERING_WARNINGS) - qWarning("Surface::damage() on a committed surface"); - } else{ - surfaceBuffer->setDamage(rect); - } -} - void Surface::surface_destroy_resource(Resource *) { compositor()->destroySurface(this); @@ -466,15 +425,16 @@ void Surface::surface_destroy(Resource *resource) void Surface::surface_attach(Resource *, struct wl_resource *buffer, int x, int y) { - Q_UNUSED(x); - Q_UNUSED(y); - - attach(buffer); + if (m_pending.buffer) + m_pending.buffer->disown(); + m_pending.buffer = createSurfaceBuffer(buffer); + m_pending.offset = QPoint(x, y); + m_pending.newlyAttached = true; } void Surface::surface_damage(Resource *, int32_t x, int32_t y, int32_t width, int32_t height) { - damage(QRect(x, y, width, height)); + m_pending.damage = m_pending.damage.united(QRect(x, y, width, height)); } void Surface::surface_frame(Resource *resource, uint32_t callback) @@ -495,28 +455,27 @@ void Surface::surface_set_input_region(Resource *, struct wl_resource *region) void Surface::surface_commit(Resource *) { - if (m_bufferQueue.empty()) { - if (QT_WAYLAND_PRINT_BUFFERING_WARNINGS) - qWarning("Commit on invalid surface"); - return; - } + m_damage = m_pending.damage; - SurfaceBuffer *surfaceBuffer = m_bufferQueue.last(); - if (surfaceBuffer->isComitted()) { - if (QT_WAYLAND_PRINT_BUFFERING_WARNINGS) - qWarning("Committing buffer that has already been committed"); - } else { - surfaceBuffer->setCommitted(); - } + if (m_pending.buffer || m_pending.newlyAttached) { + if (m_backBuffer && m_backBuffer != m_pending.buffer) + m_backBuffer->disown(); - // A new buffer was added to the queue, so we set it as the current - // back buffer. Second and third buffers, if the come, will be handled - // in advanceBufferQueue(). - if (!m_backBuffer && m_bufferQueue.size() == 1) { - setBackBuffer(surfaceBuffer); - m_bufferQueue.takeFirst(); + setBackBuffer(m_pending.buffer); + if (!m_backBuffer && m_surfaceMapped) { + m_surfaceMapped = false; + emit m_waylandSurface->unmapped(); + } } + m_pending.buffer = 0; + m_pending.offset = QPoint(); + m_pending.newlyAttached = false; + m_pending.damage = QRegion(); + + if (m_backBuffer) + m_backBuffer->setCommitted(); + m_frameCallbacks << m_pendingFrameCallbacks; m_pendingFrameCallbacks.clear(); } diff --git a/src/compositor/wayland_wrapper/qwlsurface_p.h b/src/compositor/wayland_wrapper/qwlsurface_p.h index bad65e93..af7d1e0c 100644 --- a/src/compositor/wayland_wrapper/qwlsurface_p.h +++ b/src/compositor/wayland_wrapper/qwlsurface_p.h @@ -48,6 +48,7 @@ #include <QtCore/QVector> #include <QtCore/QRect> +#include <QtGui/QRegion> #include <QtGui/QImage> #include <QtCore/QTextStream> @@ -139,7 +140,7 @@ public: bool isCursorSurface() const { return m_isCursorSurface; } void setCursorSurface(bool isCursor) { m_isCursorSurface = isCursor; } - void advanceBufferQueue(); + void swapBuffers(); void releaseSurfaces(); private: @@ -149,10 +150,17 @@ private: QWaylandSurface *m_waylandSurface; SurfaceBuffer *m_backBuffer; + QRegion m_damage; SurfaceBuffer *m_frontBuffer; - QList<SurfaceBuffer *> m_bufferQueue; bool m_surfaceMapped; + struct { + SurfaceBuffer *buffer; + QRegion damage; + QPoint offset; + bool newlyAttached; + } m_pending; + QPoint m_lastLocalMousePos; QPoint m_lastGlobalMousePos; @@ -177,12 +185,9 @@ private: bool m_isCursorSurface; inline SurfaceBuffer *currentSurfaceBuffer() const; - void damage(const QRect &rect); void setBackBuffer(SurfaceBuffer *buffer); SurfaceBuffer *createSurfaceBuffer(struct ::wl_resource *buffer); - void attach(struct ::wl_resource *buffer); - void surface_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; void surface_destroy(Resource *resource) Q_DECL_OVERRIDE; diff --git a/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp b/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp index 1d919cdf..b0e67e1f 100644 --- a/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp +++ b/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp @@ -96,7 +96,6 @@ void SurfaceBuffer::initialize(struct ::wl_resource *buffer) m_destroy_listener.listener.notify = destroy_listener_callback; if (buffer) wl_signal_add(&buffer->destroy_signal, &m_destroy_listener.listener); - m_damageRect = QRect(); } void SurfaceBuffer::destructBufferState() @@ -171,18 +170,6 @@ void SurfaceBuffer::disown() void SurfaceBuffer::setDisplayed() { m_is_displayed = true; - m_damageRect = QRect(); -} - -void SurfaceBuffer::setDamage(const QRect &rect) -{ - if (m_damageRect.isValid()) { - m_damageRect = m_damageRect.united(rect); - } else { - m_damageRect = rect; - } - m_image = QImage(); - } void SurfaceBuffer::destroyTexture() diff --git a/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h b/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h index 257c8246..c2c39253 100644 --- a/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h +++ b/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h @@ -87,9 +87,6 @@ public: inline void setCommitted() { m_committed = true; } inline bool isDisplayed() const { return m_is_displayed; } - inline QRect damageRect() const { return m_damageRect; } - void setDamage(const QRect &rect); - inline bool textureCreated() const { return m_texture; } bool isDestroyed() { return m_destroyed; } @@ -112,7 +109,6 @@ private: Compositor *m_compositor; struct ::wl_resource *m_buffer; struct surface_buffer_destroy_listener m_destroy_listener; - QRect m_damageRect; bool m_committed; bool m_is_registered_for_buffer; bool m_surface_has_buffer; |