summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiulio Camuffo <giulio.camuffo@jollamobile.com>2014-02-10 13:29:49 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-03-11 14:25:00 +0100
commit666f597ccd2ced23ecc71ba497981d1a88c34d77 (patch)
treeed8e1e89840688d78c3017de90a899d773b99144
parent8643053f8f5255fb8e21911c9e7287e675f4b4ed (diff)
downloadqtwayland-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.cpp10
-rw-r--r--examples/qwindow-compositor/qwindowcompositor.cpp10
-rw-r--r--examples/qwindow-compositor/qwindowcompositor.h4
-rw-r--r--src/compositor/compositor_api/qwaylandsurface.cpp4
-rw-r--r--src/compositor/compositor_api/qwaylandsurface.h4
-rw-r--r--src/compositor/compositor_api/qwaylandsurfaceitem.cpp4
-rw-r--r--src/compositor/compositor_api/qwaylandsurfaceitem.h2
-rw-r--r--src/compositor/wayland_wrapper/qwlsurface.cpp101
-rw-r--r--src/compositor/wayland_wrapper/qwlsurface_p.h15
-rw-r--r--src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp13
-rw-r--r--src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h4
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;