summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJørgen Lind <jorgen.lind@theqtcompany.com>2015-07-29 14:58:54 +0200
committerJørgen Lind <jorgen.lind@theqtcompany.com>2015-08-28 13:09:41 +0200
commita327ca8d8a1f6e0a44a3aa6bd4dac716911c434e (patch)
treeae4c432c495a7baee8f97737160836cbb2e38476 /src
parent6c9c54587c6cd1059d5de652d06e248456832ab6 (diff)
Move the texture ownership from the QWaylandSurface
to the respective QWaylandSurfaceView. For all GL applications this will have no significant impact, but will cause a memory regression for shm surfaces with multiple views. This is done to simplify the creation and destruction of textures, especially in multi-threaded environments. Also the same patch removes the y_inverted property and replaces it with a origin property. Its done in the same patch as a lot of the code was overlapping. Change-Id: I4bce50c614c9ac3ba0580e0560339476eac03433
Diffstat (limited to 'src')
-rw-r--r--src/compositor/compositor_api/qwaylandbufferref.cpp78
-rw-r--r--src/compositor/compositor_api/qwaylandbufferref.h27
-rw-r--r--src/compositor/compositor_api/qwaylandquickcompositor.cpp12
-rw-r--r--src/compositor/compositor_api/qwaylandquicksurface.cpp109
-rw-r--r--src/compositor/compositor_api/qwaylandquicksurface.h10
-rw-r--r--src/compositor/compositor_api/qwaylandsurface.cpp33
-rw-r--r--src/compositor/compositor_api/qwaylandsurface.h30
-rw-r--r--src/compositor/compositor_api/qwaylandsurfaceitem.cpp173
-rw-r--r--src/compositor/compositor_api/qwaylandsurfaceitem.h24
-rw-r--r--src/compositor/compositor_api/qwaylandsurfaceview.cpp29
-rw-r--r--src/compositor/compositor_api/qwaylandsurfaceview.h4
-rw-r--r--src/compositor/hardware_integration/qwlclientbufferintegration_p.h3
-rw-r--r--src/compositor/wayland_wrapper/qwlsurface.cpp56
-rw-r--r--src/compositor/wayland_wrapper/qwlsurface_p.h12
-rw-r--r--src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp219
-rw-r--r--src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h64
-rw-r--r--src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp8
-rw-r--r--src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h2
-rw-r--r--src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.cpp6
-rw-r--r--src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.h2
-rw-r--r--src/hardwareintegration/compositor/xcomposite_share/xcompositebuffer.cpp2
-rw-r--r--src/hardwareintegration/compositor/xcomposite_share/xcompositebuffer.h7
22 files changed, 376 insertions, 534 deletions
diff --git a/src/compositor/compositor_api/qwaylandbufferref.cpp b/src/compositor/compositor_api/qwaylandbufferref.cpp
index 8a0b9242c..7b5b3cd2b 100644
--- a/src/compositor/compositor_api/qwaylandbufferref.cpp
+++ b/src/compositor/compositor_api/qwaylandbufferref.cpp
@@ -46,6 +46,10 @@ class QWaylandBufferRefPrivate
{
public:
QtWayland::SurfaceBuffer *buffer;
+
+ bool nullOrDestroyed() {
+ return !buffer || buffer->isDestroyed();
+ }
};
QWaylandBufferRef::QWaylandBufferRef()
@@ -65,8 +69,9 @@ QWaylandBufferRef::QWaylandBufferRef(QtWayland::SurfaceBuffer *buffer)
QWaylandBufferRef::QWaylandBufferRef(const QWaylandBufferRef &ref)
: d(new QWaylandBufferRefPrivate)
{
- d->buffer = 0;
- *this = ref;
+ d->buffer = ref.d->buffer;
+ if (d->buffer)
+ d->buffer->ref();
}
QWaylandBufferRef::~QWaylandBufferRef()
@@ -88,44 +93,75 @@ QWaylandBufferRef &QWaylandBufferRef::operator=(const QWaylandBufferRef &ref)
return *this;
}
-QWaylandBufferRef::operator bool() const
+bool QWaylandBufferRef::operator==(const QWaylandBufferRef &ref)
{
- return d->buffer && d->buffer->waylandBufferHandle();
+ return d->buffer == ref.d->buffer;
}
-bool QWaylandBufferRef::isShm() const
+bool QWaylandBufferRef::operator!=(const QWaylandBufferRef &ref)
{
- return d->buffer->isShmBuffer();
+ return d->buffer != ref.d->buffer;
}
-QImage QWaylandBufferRef::image() const
+bool QWaylandBufferRef::isNull() const
{
- if (d->buffer->isShmBuffer())
- return d->buffer->image();
- return QImage();
+ return !d->buffer;
}
-#ifdef QT_COMPOSITOR_WAYLAND_GL
+bool QWaylandBufferRef::hasBuffer() const
+{
+ return d->buffer && !d->buffer->isDestroyed();
+}
-GLuint QWaylandBufferRef::createTexture()
+struct ::wl_resource *QWaylandBufferRef::wl_buffer() const
{
- if (!d->buffer->isShmBuffer() && !d->buffer->textureCreated()) {
- d->buffer->createTexture();
- }
- return d->buffer->texture();
+ return d->buffer ? d->buffer->waylandBufferHandle() : Q_NULLPTR;
}
-void QWaylandBufferRef::destroyTexture()
+QSize QWaylandBufferRef::size() const
{
- if (!d->buffer->isShmBuffer() && d->buffer->textureCreated()) {
- d->buffer->destroyTexture();
- }
+ if (d->nullOrDestroyed())
+ return QSize();
+
+ return d->buffer->size();
+}
+
+QWaylandSurface::Origin QWaylandBufferRef::origin() const
+{
+ if (d->nullOrDestroyed())
+ return QWaylandSurface::OriginBottomLeft;
+
+ return d->buffer->origin();
+}
+
+bool QWaylandBufferRef::isShm() const
+{
+ if (d->nullOrDestroyed())
+ return false;
+
+ return d->buffer->isShm();
+}
+
+QImage QWaylandBufferRef::image() const
+{
+ if (d->nullOrDestroyed())
+ return QImage();
+
+ return d->buffer->image();
+}
+
+void QWaylandBufferRef::bindToTexture() const
+{
+ if (d->nullOrDestroyed())
+ return;
+
+ return d->buffer->bindToTexture();
+
}
void *QWaylandBufferRef::nativeBuffer() const
{
return d->buffer->handle();
}
-#endif
QT_END_NAMESPACE
diff --git a/src/compositor/compositor_api/qwaylandbufferref.h b/src/compositor/compositor_api/qwaylandbufferref.h
index b397116a2..fa978fe80 100644
--- a/src/compositor/compositor_api/qwaylandbufferref.h
+++ b/src/compositor/compositor_api/qwaylandbufferref.h
@@ -43,8 +43,11 @@
#include <QtGui/qopengl.h>
#endif
+#include <QtCompositor/QWaylandSurface>
#include <QtCompositor/qwaylandexport.h>
+struct wl_resource;
+
QT_BEGIN_NAMESPACE
namespace QtWayland
@@ -61,20 +64,22 @@ public:
~QWaylandBufferRef();
QWaylandBufferRef &operator=(const QWaylandBufferRef &ref);
- operator bool() const;
- bool isShm() const;
+ bool isNull() const;
+ bool hasBuffer() const;
+ bool operator==(const QWaylandBufferRef &ref);
+ bool operator!=(const QWaylandBufferRef &ref);
+
+ wl_resource *wl_buffer() const;
+ QSize size() const;
+ QWaylandSurface::Origin origin() const;
+
+ bool isShm() const;
QImage image() const;
-#ifdef QT_COMPOSITOR_WAYLAND_GL
- /**
- * There must be a GL context bound when calling this function.
- * The texture will be automatically destroyed when the last QWaylandBufferRef
- * referring to the same underlying buffer will be destroyed or reset.
- */
- GLuint createTexture();
- void destroyTexture();
+
+ void bindToTexture() const;
+
void *nativeBuffer() const;
-#endif
private:
class QWaylandBufferRefPrivate *const d;
diff --git a/src/compositor/compositor_api/qwaylandquickcompositor.cpp b/src/compositor/compositor_api/qwaylandquickcompositor.cpp
index 15923659d..7c37e6c59 100644
--- a/src/compositor/compositor_api/qwaylandquickcompositor.cpp
+++ b/src/compositor/compositor_api/qwaylandquickcompositor.cpp
@@ -38,6 +38,8 @@
#include <QtCompositor/private/qwlcompositor_p.h>
#include <QtCompositor/private/qwlsurface_p.h>
+#include <QtQml/QQmlEngine>
+
#include "qwaylandclient.h"
#include "qwaylandquickcompositor.h"
#include "qwaylandquicksurface.h"
@@ -101,16 +103,22 @@ QWaylandOutput *QWaylandQuickCompositor::createOutput(QWindow *window,
const QString &manufacturer,
const QString &model)
{
+ QQmlEngine::setObjectOwnership(window, QQmlEngine::CppOwnership);
+
QQuickWindow *quickWindow = qobject_cast<QQuickWindow *>(window);
if (!quickWindow)
qFatal("%s: couldn't cast QWindow to QQuickWindow. All output windows must "
"be QQuickWindow derivates when using QWaylandQuickCompositor", Q_FUNC_INFO);
- return new QWaylandQuickOutput(this, quickWindow, manufacturer, model);
+ QWaylandQuickOutput *output = new QWaylandQuickOutput(this, quickWindow, manufacturer, model);
+ QQmlEngine::setObjectOwnership(output, QQmlEngine::CppOwnership);
+ return output;
}
QWaylandSurfaceView *QWaylandQuickCompositor::createView()
{
- return new QWaylandSurfaceItem();
+ QWaylandSurfaceItem *view = new QWaylandSurfaceItem();
+ QQmlEngine::setObjectOwnership(view, QQmlEngine::JavaScriptOwnership);
+ return view;
}
QWaylandSurface *QWaylandQuickCompositor::createSurface(QWaylandClient *client, quint32 id, int version)
diff --git a/src/compositor/compositor_api/qwaylandquicksurface.cpp b/src/compositor/compositor_api/qwaylandquicksurface.cpp
index a55569da9..ebefb3bc3 100644
--- a/src/compositor/compositor_api/qwaylandquicksurface.cpp
+++ b/src/compositor/compositor_api/qwaylandquicksurface.cpp
@@ -49,96 +49,21 @@
QT_BEGIN_NAMESPACE
-class BufferAttacher : public QWaylandBufferAttacher
-{
-public:
- BufferAttacher()
- : surface(0)
- , texture(0)
- , update(false)
- {
-
- }
-
- ~BufferAttacher()
- {
- if (texture)
- texture->deleteLater();
- bufferRef = QWaylandBufferRef();
- nextBuffer = QWaylandBufferRef();
- }
-
- void attach(const QWaylandBufferRef &ref) Q_DECL_OVERRIDE
- {
- nextBuffer = ref;
- update = true;
- }
-
- void createTexture()
- {
- bufferRef = nextBuffer;
- delete texture;
- texture = 0;
-
- QQuickWindow *window = static_cast<QQuickWindow *>(surface->mainOutput()->window());
- if (nextBuffer) {
- if (bufferRef.isShm()) {
- texture = window->createTextureFromImage(bufferRef.image());
- } else {
- QQuickWindow::CreateTextureOptions opt = 0;
- if (surface->useTextureAlpha()) {
- opt |= QQuickWindow::TextureHasAlphaChannel;
- }
- texture = window->createTextureFromId(bufferRef.createTexture(), surface->size(), opt);
- }
- texture->bind();
- }
-
- update = false;
- }
-
- void unmap() Q_DECL_OVERRIDE
- {
- nextBuffer = QWaylandBufferRef();
- update = true;
- }
-
- void invalidateTexture()
- {
- if (bufferRef)
- bufferRef.destroyTexture();
- delete texture;
- texture = 0;
- update = true;
- bufferRef = QWaylandBufferRef();
- }
-
- QWaylandQuickSurface *surface;
- QWaylandBufferRef bufferRef;
- QWaylandBufferRef nextBuffer;
- QSGTexture *texture;
- bool update;
-};
-
-
class QWaylandQuickSurfacePrivate : public QWaylandSurfacePrivate
{
public:
QWaylandQuickSurfacePrivate(wl_client *client, quint32 id, int version, QWaylandQuickCompositor *c, QWaylandQuickSurface *surf)
: QWaylandSurfacePrivate(client, id, version, c, surf)
- , buffer(new BufferAttacher)
, compositor(c)
, useTextureAlpha(true)
, windowPropertyMap(new QQmlPropertyMap)
, clientRenderingEnabled(true)
{
-
}
~QWaylandQuickSurfacePrivate()
{
windowPropertyMap->deleteLater();
- // buffer is deleted automatically by ~Surface(), since it is the assigned attacher
}
void surface_commit(Resource *resource) Q_DECL_OVERRIDE
@@ -149,7 +74,6 @@ public:
output->waylandOutput()->update();
}
- BufferAttacher *buffer;
QWaylandQuickCompositor *compositor;
bool useTextureAlpha;
QQmlPropertyMap *windowPropertyMap;
@@ -160,8 +84,10 @@ QWaylandQuickSurface::QWaylandQuickSurface(wl_client *client, quint32 id, int ve
: QWaylandSurface(new QWaylandQuickSurfacePrivate(client, id, version, compositor, this))
{
Q_D(QWaylandQuickSurface);
- d->buffer->surface = this;
- setBufferAttacher(d->buffer);
+ connect(this, &QWaylandSurface::shellViewCreated, this, &QWaylandQuickSurface::shellViewCreated);
+ connect(this, &QWaylandSurface::outputChanged, this, &QWaylandQuickSurface::outputWindowChanged);
+ connect(this, &QWaylandSurface::windowPropertyChanged, d->windowPropertyMap, &QQmlPropertyMap::insert);
+ connect(d->windowPropertyMap, &QQmlPropertyMap::valueChanged, this, &QWaylandSurface::setWindowProperty);
connect(this, &QWaylandSurface::windowPropertyChanged, d->windowPropertyMap, &QQmlPropertyMap::insert);
connect(d->windowPropertyMap, &QQmlPropertyMap::valueChanged, this, &QWaylandSurface::setWindowProperty);
@@ -173,12 +99,6 @@ QWaylandQuickSurface::~QWaylandQuickSurface()
}
-QSGTexture *QWaylandQuickSurface::texture() const
-{
- Q_D(const QWaylandQuickSurface);
- return d->buffer->texture;
-}
-
bool QWaylandQuickSurface::useTextureAlpha() const
{
Q_D(const QWaylandQuickSurface);
@@ -191,7 +111,7 @@ void QWaylandQuickSurface::setUseTextureAlpha(bool useTextureAlpha)
if (d->useTextureAlpha != useTextureAlpha) {
d->useTextureAlpha = useTextureAlpha;
emit useTextureAlphaChanged();
- emit configure(d->buffer->bufferRef);
+ emit configure(handle()->currentBufferRef().hasBuffer());
}
}
@@ -251,25 +171,6 @@ bool QWaylandQuickSurface::event(QEvent *e)
return QObject::event(e);
}
-void QWaylandQuickSurface::updateTexture()
-{
- Q_D(QWaylandQuickSurface);
- const bool update = d->buffer->update;
- if (d->buffer->update)
- d->buffer->createTexture();
- foreach (QWaylandSurfaceView *view, views())
- static_cast<QWaylandSurfaceItem *>(view)->updateTexture(update);
-}
-
-void QWaylandQuickSurface::invalidateTexture()
-{
- Q_D(QWaylandQuickSurface);
- d->buffer->invalidateTexture();
- foreach (QWaylandSurfaceView *view, views())
- static_cast<QWaylandSurfaceItem *>(view)->updateTexture(true);
- emit redraw();
-}
-
bool QWaylandQuickSurface::clientRenderingEnabled() const
{
Q_D(const QWaylandQuickSurface);
diff --git a/src/compositor/compositor_api/qwaylandquicksurface.h b/src/compositor/compositor_api/qwaylandquicksurface.h
index 0ab019d6c..3f262a402 100644
--- a/src/compositor/compositor_api/qwaylandquicksurface.h
+++ b/src/compositor/compositor_api/qwaylandquicksurface.h
@@ -43,8 +43,6 @@ struct wl_client;
QT_BEGIN_NAMESPACE
-class QSGTexture;
-
class QWaylandSurfaceItem;
class QWaylandQuickSurfacePrivate;
class QWaylandQuickCompositor;
@@ -62,8 +60,6 @@ public:
QWaylandQuickSurface(wl_client *client, quint32 id, int version, QWaylandQuickCompositor *compositor);
~QWaylandQuickSurface();
- QSGTexture *texture() const;
-
bool useTextureAlpha() const;
void setUseTextureAlpha(bool useTextureAlpha);
@@ -83,12 +79,6 @@ Q_SIGNALS:
void clientRenderingEnabledChanged();
void shellViewCreated();
void outputWindowChanged();
-
-private:
- void updateTexture();
- void invalidateTexture();
-
- void onOutputChanged(QWaylandOutput *newOutput, QWaylandOutput *oldOutput);
};
QT_END_NAMESPACE
diff --git a/src/compositor/compositor_api/qwaylandsurface.cpp b/src/compositor/compositor_api/qwaylandsurface.cpp
index bec39a184..5ffe58e0a 100644
--- a/src/compositor/compositor_api/qwaylandsurface.cpp
+++ b/src/compositor/compositor_api/qwaylandsurface.cpp
@@ -132,20 +132,17 @@ QWaylandOutput *QWaylandSurfaceLeaveEvent::output() const
QWaylandSurface::QWaylandSurface(wl_client *client, quint32 id, int version, QWaylandCompositor *compositor)
: QObject(*new QWaylandSurfacePrivate(client, id, version, compositor, this))
{
-
}
QWaylandSurface::QWaylandSurface(QWaylandSurfacePrivate *dptr)
: QObject(*dptr)
{
-
}
QWaylandSurface::~QWaylandSurface()
{
Q_D(QWaylandSurface);
qDeleteAll(d->interfaces);
- delete d->m_attacher;
}
QWaylandClient *QWaylandSurface::client() const
@@ -186,18 +183,6 @@ void QWaylandSurface::removeInterface(QWaylandSurfaceInterface *iface)
d->interfaces.removeOne(iface);
}
-QWaylandSurface::Type QWaylandSurface::type() const
-{
- Q_D(const QWaylandSurface);
- return d->type();
-}
-
-bool QWaylandSurface::isYInverted() const
-{
- Q_D(const QWaylandSurface);
- return d->isYInverted();
-}
-
bool QWaylandSurface::visible() const
{
return isMapped();
@@ -253,6 +238,12 @@ QWaylandSurface::WindowType QWaylandSurface::windowType() const
return d->windowType;
}
+QWaylandSurface::Origin QWaylandSurface::origin() const
+{
+ Q_D(const QWaylandSurface);
+ return d->origin();
+}
+
QWaylandSurface *QWaylandSurface::transientParent() const
{
Q_D(const QWaylandSurface);
@@ -459,18 +450,6 @@ void QWaylandSurface::setMapped(bool mapped)
d->setMapped(mapped);
}
-void QWaylandSurface::setBufferAttacher(QWaylandBufferAttacher *attacher)
-{
- Q_D(QWaylandSurface);
- d->m_attacher = attacher;
-}
-
-QWaylandBufferAttacher *QWaylandSurface::bufferAttacher() const
-{
- Q_D(const QWaylandSurface);
- return d->m_attacher;
-}
-
QList<QWaylandSurfaceView *> QWaylandSurface::views() const
{
Q_D(const QWaylandSurface);
diff --git a/src/compositor/compositor_api/qwaylandsurface.h b/src/compositor/compositor_api/qwaylandsurface.h
index a8ce58495..9dce15a6b 100644
--- a/src/compositor/compositor_api/qwaylandsurface.h
+++ b/src/compositor/compositor_api/qwaylandsurface.h
@@ -66,18 +66,6 @@ class SurfacePrivate;
class ExtendedSurface;
}
-class Q_COMPOSITOR_EXPORT QWaylandBufferAttacher
-{
-public:
- virtual ~QWaylandBufferAttacher() {}
-
-protected:
- virtual void attach(const QWaylandBufferRef &ref) = 0;
- virtual void unmap() = 0;
-
- friend class QtWayland::Surface;
-};
-
class QWaylandSurfaceEnterEventPrivate;
class Q_COMPOSITOR_EXPORT QWaylandSurfaceEnterEvent : public QEvent
@@ -126,7 +114,7 @@ class Q_COMPOSITOR_EXPORT QWaylandSurface : public QObject
Q_PROPERTY(QWaylandSurface *transientParent READ transientParent)
Q_PROPERTY(QPointF transientOffset READ transientOffset)
Q_PROPERTY(QWaylandOutput *output READ output NOTIFY outputChanged)
- Q_PROPERTY(bool isYInverted READ isYInverted NOTIFY yInvertedChanged)
+ Q_PROPERTY(QWaylandSurface::Origin origin READ origin NOTIFY originChanged);
Q_ENUMS(WindowFlag WindowType)
Q_FLAGS(WindowFlag WindowFlags)
@@ -146,10 +134,9 @@ public:
Popup
};
- enum Type {
- Invalid,
- Shm,
- Texture
+ enum Origin {
+ OriginTopLeft,
+ OriginBottomLeft
};
QWaylandSurface(wl_client *client, quint32 id, int version, QWaylandCompositor *compositor);
@@ -162,9 +149,6 @@ public:
void addInterface(QWaylandSurfaceInterface *interface);
void removeInterface(QWaylandSurfaceInterface *interface);
- Type type() const;
- bool isYInverted() const;
-
bool visible() const;
bool isMapped() const;
@@ -177,6 +161,7 @@ public:
WindowFlags windowFlags() const;
WindowType windowType() const;
+ Origin origin() const;
QWindow::Visibility visibility() const;
void setVisibility(QWindow::Visibility visibility);
@@ -217,9 +202,6 @@ public:
void deref();
void setMapped(bool mapped);
- void setBufferAttacher(QWaylandBufferAttacher *attacher);
- QWaylandBufferAttacher *bufferAttacher() const;
-
QList<QWaylandSurfaceView *> views() const;
QList<QWaylandSurfaceInterface *> interfaces() const;
@@ -257,7 +239,7 @@ Q_SIGNALS:
void surfaceDestroyed();
void shellViewCreated();
void outputChanged(QWaylandOutput *newOutput, QWaylandOutput *oldOutput);
- void yInvertedChanged();
+ void originChanged();
void configure(bool hasBuffer);
void redraw();
diff --git a/src/compositor/compositor_api/qwaylandsurfaceitem.cpp b/src/compositor/compositor_api/qwaylandsurfaceitem.cpp
index de5172ff5..4c3615c9f 100644
--- a/src/compositor/compositor_api/qwaylandsurfaceitem.cpp
+++ b/src/compositor/compositor_api/qwaylandsurfaceitem.cpp
@@ -38,6 +38,9 @@
#include "qwaylandquicksurface.h"
#include <QtCompositor/qwaylandcompositor.h>
#include <QtCompositor/qwaylandinput.h>
+#include <QtCompositor/qwaylandbufferref.h>
+#include <QtCompositor/private/qwlcompositor_p.h>
+#include <QtCompositor/private/qwlclientbufferintegration_p.h>
#include <QtGui/QKeyEvent>
#include <QtGui/QGuiApplication>
@@ -49,6 +52,8 @@
#include <QtCore/QMutexLocker>
#include <QtCore/QMutex>
+#include <wayland-server.h>
+#include <QThread>
QT_BEGIN_NAMESPACE
QMutex *QWaylandSurfaceItem::mutex = 0;
@@ -56,30 +61,76 @@ QMutex *QWaylandSurfaceItem::mutex = 0;
class QWaylandSurfaceTextureProvider : public QSGTextureProvider
{
public:
- QWaylandSurfaceTextureProvider() : t(0) { }
+ QWaylandSurfaceTextureProvider()
+ : m_smooth(false)
+ , m_sgTex(0)
+ {
+ }
+
+ ~QWaylandSurfaceTextureProvider()
+ {
+ if (m_sgTex)
+ m_sgTex->deleteLater();
+ }
+
+ void setBufferRef(QWaylandSurfaceItem *surfaceItem, const QWaylandBufferRef &buffer)
+ {
+ Q_ASSERT(QThread::currentThread() == thread());
+ m_ref = buffer;
+ delete m_sgTex;
+ m_sgTex = 0;
+ if (m_ref.hasBuffer()) {
+ if (buffer.isShm()) {
+ m_sgTex = surfaceItem->window()->createTextureFromImage(buffer.image());
+ m_invertY = false;
+ if (m_sgTex) {
+ m_sgTex->bind();
+ }
+ } else {
+ QQuickWindow::CreateTextureOptions opt = QQuickWindow::TextureOwnsGLTexture;
+ if (surfaceItem->surface()->useTextureAlpha()) {
+ opt |= QQuickWindow::TextureHasAlphaChannel;
+ }
+
+ GLuint texture;
+ glGenTextures(1, &texture);
+ glBindTexture(GL_TEXTURE_2D, texture);
+ buffer.bindToTexture();
+ m_sgTex = surfaceItem->window()->createTextureFromId(texture , QSize(surfaceItem->width(), surfaceItem->height()), opt);
+ m_invertY = buffer.origin() == QWaylandSurface::OriginBottomLeft;
+ }
+ }
+ emit textureChanged();
+ }
QSGTexture *texture() const Q_DECL_OVERRIDE
{
- if (t)
- t->setFiltering(smooth ? QSGTexture::Linear : QSGTexture::Nearest);
- return t;
+ if (m_sgTex)
+ m_sgTex->setFiltering(m_smooth ? QSGTexture::Linear : QSGTexture::Nearest);
+ return m_sgTex;
}
- bool smooth;
- QSGTexture *t;
+ void setSmooth(bool smooth) { m_smooth = smooth; }
+ bool invertY() const { return m_invertY; }
+private:
+ bool m_smooth;
+ bool m_invertY;
+ QSGTexture *m_sgTex;
+ QWaylandBufferRef m_ref;
};
QWaylandSurfaceItem::QWaylandSurfaceItem(QQuickItem *parent)
: QQuickItem(parent)
, QWaylandSurfaceView()
- , m_provider(0)
+ , m_provider(Q_NULLPTR)
, m_paintEnabled(true)
, m_touchEventsEnabled(false)
- , m_yInverted(false)
, m_resizeSurfaceToItem(false)
- , m_newTexture(false)
, m_followRequestedPos(true)
, m_inputEventsEnabled(true)
+ , m_newTexture(false)
+ , m_connectedWindow(Q_NULLPTR)
+ , m_origin(QWaylandSurface::OriginTopLeft)
{
setAcceptHoverEvents(true);
if (!mutex)
@@ -98,11 +149,7 @@ QWaylandSurfaceItem::QWaylandSurfaceItem(QQuickItem *parent)
Qt::ExtraButton12 | Qt::ExtraButton13);
setAcceptHoverEvents(true);
- connect(this, &QWaylandSurfaceItem::widthChanged, this, &QWaylandSurfaceItem::updateSurfaceSize);
- connect(this, &QWaylandSurfaceItem::heightChanged, this, &QWaylandSurfaceItem::updateSurfaceSize);
-
-
- emit yInvertedChanged();
+ connect(this, &QQuickItem::windowChanged, this, &QWaylandSurfaceItem::updateWindow);
}
QWaylandSurfaceItem::~QWaylandSurfaceItem()
@@ -122,15 +169,13 @@ void QWaylandSurfaceItem::setSurface(QWaylandQuickSurface *surface)
QWaylandSurfaceView::setSurface(surface);
}
-bool QWaylandSurfaceItem::isYInverted() const
+QWaylandSurface::Origin QWaylandSurfaceItem::origin() const
{
- return m_yInverted;
+ return m_origin;
}
QSGTextureProvider *QWaylandSurfaceItem::textureProvider() const
{
- if (!m_provider)
- m_provider = new QWaylandSurfaceTextureProvider();
return m_provider;
}
@@ -291,7 +336,7 @@ void QWaylandSurfaceItem::waylandSurfaceChanged(QWaylandSurface *newSurface, QWa
if (oldSurface) {
disconnect(oldSurface, &QWaylandSurface::mapped, this, &QWaylandSurfaceItem::surfaceMapped);
disconnect(oldSurface, &QWaylandSurface::unmapped, this, &QWaylandSurfaceItem::surfaceUnmapped);
- disconnect(oldSurface, &QWaylandSurface::surfaceDestroyed, this, &QWaylandSurfaceItem::surfaceDestroyed);
+ disconnect(oldSurface, &QWaylandSurface::surfaceDestroyed, this, &QWaylandSurfaceItem::handleSurfaceDestroyed);
disconnect(oldSurface, &QWaylandSurface::parentChanged, this, &QWaylandSurfaceItem::parentChanged);
disconnect(oldSurface, &QWaylandSurface::sizeChanged, this, &QWaylandSurfaceItem::updateSize);
disconnect(oldSurface, &QWaylandSurface::configure, this, &QWaylandSurfaceItem::updateBuffer);
@@ -300,16 +345,16 @@ void QWaylandSurfaceItem::waylandSurfaceChanged(QWaylandSurface *newSurface, QWa
if (newSurface) {
connect(newSurface, &QWaylandSurface::mapped, this, &QWaylandSurfaceItem::surfaceMapped);
connect(newSurface, &QWaylandSurface::unmapped, this, &QWaylandSurfaceItem::surfaceUnmapped);
- connect(newSurface, &QWaylandSurface::surfaceDestroyed, this, &QWaylandSurfaceItem::surfaceDestroyed);
+ connect(newSurface, &QWaylandSurface::surfaceDestroyed, this, &QWaylandSurfaceItem::handleSurfaceDestroyed);
connect(newSurface, &QWaylandSurface::parentChanged, this, &QWaylandSurfaceItem::parentChanged);
connect(newSurface, &QWaylandSurface::sizeChanged, this, &QWaylandSurfaceItem::updateSize);
connect(newSurface, &QWaylandSurface::configure, this, &QWaylandSurfaceItem::updateBuffer);
connect(newSurface, &QWaylandSurface::redraw, this, &QQuickItem::update);
setWidth(surface()->size().width());
setHeight(surface()->size().height());
- if (newSurface->isYInverted() != m_yInverted) {
- m_yInverted = newSurface->isYInverted();
- emit yInvertedChanged();
+ if (newSurface->origin() != m_origin) {
+ m_origin = newSurface->origin();
+ emit originChanged();
}
}
@@ -359,10 +404,13 @@ void QWaylandSurfaceItem::updateSize()
}
}
-void QWaylandSurfaceItem::updateSurfaceSize()
+void QWaylandSurfaceItem::geometryChanged(const QRectF &newGeometry,
+ const QRectF &oldGeometry)
{
+ QQuickItem::geometryChanged(newGeometry, oldGeometry);
+
if (surface() && m_resizeSurfaceToItem) {
- surface()->requestSize(QSize(width(), height()));
+ surface()->requestSize(newGeometry.size().toSize());
}
}
@@ -422,6 +470,11 @@ void QWaylandSurfaceItem::setRequestedYPosition(qreal yPos)
setRequestedPosition(reqPos);
}
+void QWaylandSurfaceItem::syncGraphicsState()
+{
+
+}
+
/*!
\qmlproperty bool QtWayland::QWaylandSurfaceItem::paintEnabled
@@ -443,38 +496,39 @@ void QWaylandSurfaceItem::setPaintEnabled(bool enabled)
void QWaylandSurfaceItem::updateBuffer(bool hasBuffer)
{
- Q_UNUSED(hasBuffer)
-
- bool inv = m_yInverted;
- m_yInverted = surface()->isYInverted();
- if (inv != m_yInverted)
- emit yInvertedChanged();
-
- m_newTexture = true;
+ Q_UNUSED(hasBuffer);
+ if (m_origin != surface()->origin()) {
+ m_origin = surface()->origin();
+ emit originChanged();
+ }
}
-void QWaylandSurfaceItem::updateTexture()
+void QWaylandSurfaceItem::updateWindow()
{
- updateTexture(false);
+ if (m_connectedWindow) {
+ disconnect(m_connectedWindow, &QQuickWindow::beforeSynchronizing, this, &QWaylandSurfaceItem::beforeSync);
+ }
+
+ m_connectedWindow = window();
+
+ if (m_connectedWindow) {
+ connect(m_connectedWindow, &QQuickWindow::beforeSynchronizing, this, &QWaylandSurfaceItem::beforeSync, Qt::DirectConnection);
+ }
}
-void QWaylandSurfaceItem::updateTexture(bool changed)
+void QWaylandSurfaceItem::beforeSync()
{
- if (!m_provider)
- m_provider = new QWaylandSurfaceTextureProvider();
-
- m_provider->t = static_cast<QWaylandQuickSurface *>(surface())->texture();
- m_provider->smooth = smooth();
- if (m_newTexture || changed)
- emit m_provider->textureChanged();
- m_newTexture = false;
+ if (advance()) {
+ m_newTexture = true;
+ update();
+ }
}
QSGNode *QWaylandSurfaceItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
{
- bool mapped = surface() && surface()->isMapped();
+ bool mapped = surface() && surface()->isMapped() && currentBuffer().hasBuffer();
- if (!mapped || !m_provider || !m_provider->t || !m_paintEnabled) {
+ if (!mapped || !m_paintEnabled) {
delete oldNode;
return 0;
}
@@ -483,14 +537,21 @@ QSGNode *QWaylandSurfaceItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeD
if (!node)
node = new QSGSimpleTextureNode();
- node->setTexture(m_provider->t);
- // Surface textures come by default with the OpenGL coordinate system, which is inverted relative
- // to the QtQuick one. So we're dealing with a double invertion here, and if isYInverted() returns
- // true it means it is NOT inverted relative to QtQuick, while if it returns false it means it IS.
- if (surface()->isYInverted()) {
- node->setRect(0, 0, width(), height());
+
+ if (!m_provider)
+ m_provider = new QWaylandSurfaceTextureProvider();
+
+ if (m_newTexture) {
+ m_provider->setBufferRef(this, currentBuffer());
+ node->setTexture(m_provider->texture());
+ }
+
+ m_provider->setSmooth(smooth());
+
+ if (m_provider->invertY()) {
+ node->setRect(0, height(), width(), -height());
} else {
- node->setRect(0, height(), width(), -height());
+ node->setRect(0, 0, width(), height());
}
return node;
@@ -521,4 +582,10 @@ void QWaylandSurfaceItem::setInputEventsEnabled(bool enabled)
}
}
+void QWaylandSurfaceItem::handleSurfaceDestroyed()
+{
+ emit surfaceDestroyed();
+ setSurface(Q_NULLPTR);
+}
+
QT_END_NAMESPACE
diff --git a/src/compositor/compositor_api/qwaylandsurfaceitem.h b/src/compositor/compositor_api/qwaylandsurfaceitem.h
index 6711d8ef2..4c5db4ad5 100644
--- a/src/compositor/compositor_api/qwaylandsurfaceitem.h
+++ b/src/compositor/compositor_api/qwaylandsurfaceitem.h
@@ -61,7 +61,7 @@ class Q_COMPOSITOR_EXPORT QWaylandSurfaceItem : public QQuickItem, public QWayla
Q_PROPERTY(QWaylandQuickSurface* surface READ surface WRITE setSurface NOTIFY surfaceChanged)
Q_PROPERTY(bool paintEnabled READ paintEnabled WRITE setPaintEnabled)
Q_PROPERTY(bool touchEventsEnabled READ touchEventsEnabled WRITE setTouchEventsEnabled NOTIFY touchEventsEnabledChanged)
- Q_PROPERTY(bool isYInverted READ isYInverted NOTIFY yInvertedChanged)
+ Q_PROPERTY(QWaylandSurface::Origin origin READ origin NOTIFY originChanged);
Q_PROPERTY(bool resizeSurfaceToItem READ resizeSurfaceToItem WRITE setResizeSurfaceToItem NOTIFY resizeSurfaceToItemChanged)
Q_PROPERTY(bool followRequestedPosition READ followRequestedPosition WRITE setFollowRequestedPosition NOTIFY followRequestedPositionChanged)
Q_PROPERTY(qreal requestedXPosition READ requestedXPosition WRITE setRequestedXPosition NOTIFY requestedXPositionChanged)
@@ -75,7 +75,7 @@ public:
QWaylandQuickSurface *surface() const;
void setSurface(QWaylandQuickSurface *surface);
- bool isYInverted() const;
+ QWaylandSurface::Origin origin() const;
bool isTextureProvider() const { return true; }
QSGTextureProvider *textureProvider() const;
@@ -83,7 +83,6 @@ public:
bool paintEnabled() const;
bool touchEventsEnabled() const { return m_touchEventsEnabled; }
bool resizeSurfaceToItem() const { return m_resizeSurfaceToItem; }
- void updateTexture();
void setTouchEventsEnabled(bool enabled);
void setResizeSurfaceToItem(bool enabled);
@@ -101,6 +100,9 @@ public:
qreal requestedYPosition() const;
void setRequestedYPosition(qreal yPos);
+ Q_INVOKABLE void syncGraphicsState();
+
+ void markForNewBuffer();
protected:
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
@@ -117,6 +119,8 @@ protected:
void waylandSurfaceChanged(QWaylandSurface *newSurface, QWaylandSurface *oldSurface) Q_DECL_OVERRIDE;
+ void geometryChanged(const QRectF &newGeometry,
+ const QRectF &oldGeometry) Q_DECL_OVERRIDE;
public Q_SLOTS:
virtual void takeFocus(QWaylandInputDevice *device = 0);
void setPaintEnabled(bool paintEnabled);
@@ -126,13 +130,14 @@ private Q_SLOTS:
void surfaceUnmapped();
void parentChanged(QWaylandSurface *newParent, QWaylandSurface *oldParent);
void updateSize();
- void updateSurfaceSize();
void updateBuffer(bool hasBuffer);
+ void updateWindow();
+ void beforeSync();
Q_SIGNALS:
void surfaceChanged();
void touchEventsEnabledChanged();
- void yInvertedChanged();
+ void originChanged();
void resizeSurfaceToItemChanged();
void surfaceDestroyed();
void followRequestedPositionChanged();
@@ -146,20 +151,21 @@ protected:
private:
friend class QWaylandSurfaceNode;
friend class QWaylandQuickSurface;
- void init(QWaylandQuickSurface *);
- void updateTexture(bool changed);
bool shouldSendInputEvents() const { return surface() && m_inputEventsEnabled; }
+ void handleSurfaceDestroyed();
static QMutex *mutex;
mutable QWaylandSurfaceTextureProvider *m_provider;
bool m_paintEnabled;
bool m_touchEventsEnabled;
- bool m_yInverted;
bool m_resizeSurfaceToItem;
- bool m_newTexture;
bool m_followRequestedPos;
bool m_inputEventsEnabled;
+ bool m_newTexture;
+
+ QQuickWindow *m_connectedWindow;
+ QWaylandSurface::Origin m_origin;
};
QT_END_NAMESPACE
diff --git a/src/compositor/compositor_api/qwaylandsurfaceview.cpp b/src/compositor/compositor_api/qwaylandsurfaceview.cpp
index 88bd61fea..b8f7c0d1a 100644
--- a/src/compositor/compositor_api/qwaylandsurfaceview.cpp
+++ b/src/compositor/compositor_api/qwaylandsurfaceview.cpp
@@ -40,6 +40,8 @@
#include "qwaylandcompositor.h"
#include "qwaylandinput.h"
+#include <QtCore/QMutex>
+
QT_BEGIN_NAMESPACE
class QWaylandSurfaceViewPrivate
@@ -50,6 +52,9 @@ public:
{ }
QWaylandSurface *surface;
QPointF requestedPos;
+ QMutex bufferMutex;
+ QWaylandBufferRef currentBuffer;
+ QWaylandBufferRef nextBuffer;
};
QWaylandSurfaceView::QWaylandSurfaceView()
@@ -89,6 +94,8 @@ void QWaylandSurfaceView::setSurface(QWaylandSurface *newSurface)
QWaylandSurfacePrivate::get(newSurface)->refView(this);
waylandSurfaceChanged(newSurface, oldSurface);
+ d->currentBuffer = QWaylandBufferRef();
+ d->nextBuffer = QWaylandBufferRef();
}
QWaylandCompositor *QWaylandSurfaceView::compositor() const
@@ -111,6 +118,28 @@ QPointF QWaylandSurfaceView::pos() const
return d->requestedPos;
}
+void QWaylandSurfaceView::attach(const QWaylandBufferRef &ref)
+{
+ QMutexLocker locker(&d->bufferMutex);
+ d->nextBuffer = ref;
+}
+
+bool QWaylandSurfaceView::advance()
+{
+ QMutexLocker locker(&d->bufferMutex);
+ if (d->currentBuffer == d->nextBuffer)
+ return false;
+
+ d->currentBuffer = d->nextBuffer;
+ return true;
+}
+
+QWaylandBufferRef QWaylandSurfaceView::currentBuffer()
+{
+ QMutexLocker locker(&d->bufferMutex);
+ return d->currentBuffer;
+}
+
void QWaylandSurfaceView::waylandSurfaceChanged(QWaylandSurface *newSurface, QWaylandSurface *oldSurface)
{
Q_UNUSED(newSurface);
diff --git a/src/compositor/compositor_api/qwaylandsurfaceview.h b/src/compositor/compositor_api/qwaylandsurfaceview.h
index 1685abfbb..c6bd288aa 100644
--- a/src/compositor/compositor_api/qwaylandsurfaceview.h
+++ b/src/compositor/compositor_api/qwaylandsurfaceview.h
@@ -39,6 +39,7 @@
#include <QPointF>
+#include <QtCompositor/QWaylandBufferRef>
#include <QtCompositor/qwaylandexport.h>
QT_BEGIN_NAMESPACE
@@ -61,6 +62,9 @@ public:
virtual QPointF requestedPosition() const;
virtual QPointF pos() const;
+ virtual void attach(const QWaylandBufferRef &ref);
+ virtual bool advance();
+ virtual QWaylandBufferRef currentBuffer();
protected:
virtual void waylandSurfaceChanged(QWaylandSurface *newSurface, QWaylandSurface *oldSurface);
diff --git a/src/compositor/hardware_integration/qwlclientbufferintegration_p.h b/src/compositor/hardware_integration/qwlclientbufferintegration_p.h
index f03d5ad2c..9d684553a 100644
--- a/src/compositor/hardware_integration/qwlclientbufferintegration_p.h
+++ b/src/compositor/hardware_integration/qwlclientbufferintegration_p.h
@@ -38,6 +38,7 @@
#define QWAYLANDCLIENTBUFFERINTEGRATION_H
#include <QtCompositor/qwaylandexport.h>
+#include <QtCompositor/qwaylandsurface.h>
#include <QtCore/QSize>
#include <QtGui/qopengl.h>
#include <QtGui/QOpenGLContext>
@@ -68,7 +69,7 @@ public:
// Called with the texture bound.
virtual void bindTextureToBuffer(struct ::wl_resource *buffer) = 0;
- virtual bool isYInverted(struct ::wl_resource *) const { return true; }
+ virtual QWaylandSurface::Origin origin(struct ::wl_resource *) const { return QWaylandSurface::OriginBottomLeft; }
virtual void *lockNativeBuffer(struct ::wl_resource *) const { return 0; }
virtual void unlockNativeBuffer(void *) const { return; }
diff --git a/src/compositor/wayland_wrapper/qwlsurface.cpp b/src/compositor/wayland_wrapper/qwlsurface.cpp
index 8f94f97cc..9ac0293ab 100644
--- a/src/compositor/wayland_wrapper/qwlsurface.cpp
+++ b/src/compositor/wayland_wrapper/qwlsurface.cpp
@@ -47,6 +47,8 @@
#include "qwaylandsurfaceview.h"
#include "qwaylandoutput.h"
+#include "qwaylandsurface_p.h"
+
#include <QtCore/QDebug>
#include <QTouchEvent>
#include <QGuiApplication>
@@ -114,7 +116,6 @@ Surface::Surface(struct wl_client *client, uint32_t id, int version, QWaylandCom
, m_mainOutput(0)
, m_buffer(0)
, m_surfaceMapped(false)
- , m_attacher(0)
, m_shellSurface(0)
, m_extendedSurface(0)
, m_subSurface(0)
@@ -173,25 +174,6 @@ Surface *Surface::fromResource(struct ::wl_resource *resource)
return static_cast<Surface *>(Resource::fromResource(resource)->surface_object);
}
-QWaylandSurface::Type Surface::type() const
-{
- if (m_buffer && m_buffer->waylandBufferHandle()) {
- if (m_buffer->isShmBuffer()) {
- return QWaylandSurface::Shm;
- } else {
- return QWaylandSurface::Texture;
- }
- }
- return QWaylandSurface::Invalid;
-}
-
-bool Surface::isYInverted() const
-{
- if (m_buffer)
- return m_buffer->isYInverted();
- return false;
-}
-
bool Surface::mapped() const
{
return !m_unmapLocks.isEmpty() || (m_buffer && bool(m_buffer->waylandBufferHandle()));
@@ -379,9 +361,10 @@ void Surface::removeFromOutput()
* The backbuffer represents the current state of the surface for the
* purpose of GUI-thread accessible properties such as size and visibility.
*/
-void Surface::setBackBuffer(SurfaceBuffer *buffer)
+void Surface::setBackBuffer(SurfaceBuffer *buffer, const QRegion &damage)
{
m_buffer = buffer;
+ m_bufferRef = QWaylandBufferRef(m_buffer);
if (m_buffer) {
bool valid = m_buffer->waylandBufferHandle() != 0;
@@ -393,7 +376,16 @@ void Surface::setBackBuffer(SurfaceBuffer *buffer)
} else {
m_compositor->resetInputDevice(this);
}
- m_damage = QRegion();
+ m_damage = damage;
+
+ QWaylandSurfacePrivate *priv = QWaylandSurfacePrivate::get(waylandSurface());
+ for (int i = 0; i < priv->views.size(); i++) {
+ priv->views.at(i)->attach(m_bufferRef);
+ }
+
+ emit m_waylandSurface->configure(m_bufferRef.hasBuffer());
+ if (!m_pending.offset.isNull())
+ emit m_waylandSurface->offsetForNextFrame(m_pending.offset);
}
void Surface::setMapped(bool mapped)
@@ -502,26 +494,8 @@ void Surface::surface_set_input_region(Resource *, struct wl_resource *region)
void Surface::surface_commit(Resource *)
{
- m_damage = m_pending.damage;
-
if (m_pending.buffer || m_pending.newlyAttached) {
- setBackBuffer(m_pending.buffer);
- m_bufferRef = QWaylandBufferRef(m_buffer);
-
- if (m_attacher) {
- if (m_bufferRef) {
- m_attacher->attach(m_bufferRef);
- } else if (!mapped()) {
- setSize(QSize());
- m_attacher->unmap();
- }
- }
- emit m_waylandSurface->configure(m_bufferRef);
- if (m_roleHandler)
- m_roleHandler->configure(m_pending.offset.x(), m_pending.offset.y());
-
- if (!m_pending.offset.isNull())
- emit m_waylandSurface->offsetForNextFrame(m_pending.offset);
+ setBackBuffer(m_pending.buffer, m_pending.damage);
}
m_pending.buffer = 0;
diff --git a/src/compositor/wayland_wrapper/qwlsurface_p.h b/src/compositor/wayland_wrapper/qwlsurface_p.h
index 127ff3576..2ba1b1428 100644
--- a/src/compositor/wayland_wrapper/qwlsurface_p.h
+++ b/src/compositor/wayland_wrapper/qwlsurface_p.h
@@ -89,9 +89,6 @@ public:
static Surface *fromResource(struct ::wl_resource *resource);
- QWaylandSurface::Type type() const;
- bool isYInverted() const;
-
bool mapped() const;
using QtWaylandServer::wl_surface::resource;
@@ -161,6 +158,9 @@ public:
Qt::ScreenOrientation contentOrientation() const;
+ QWaylandSurface::Origin origin() const { return m_buffer ? m_buffer->origin() : QWaylandSurface::OriginTopLeft; }
+
+ QWaylandBufferRef currentBufferRef() const { return m_bufferRef; }
protected:
void surface_destroy_resource(Resource *resource) Q_DECL_OVERRIDE;
@@ -189,7 +189,6 @@ protected:
SurfaceBuffer *m_buffer;
QWaylandBufferRef m_bufferRef;
bool m_surfaceMapped;
- QWaylandBufferAttacher *m_attacher;
QVector<QWaylandUnmapLock *> m_unmapLocks;
struct {
@@ -230,10 +229,9 @@ protected:
const SurfaceRole *m_role;
RoleBase *m_roleHandler;
- void setBackBuffer(SurfaceBuffer *buffer);
- SurfaceBuffer *createSurfaceBuffer(struct ::wl_resource *buffer);
+ void setBackBuffer(SurfaceBuffer *buffer, const QRegion &damage);
- QList<QWaylandSurfaceView *> views;
+ SurfaceBuffer *createSurfaceBuffer(struct ::wl_resource *buffer);
friend class QWaylandSurface;
friend class RoleBase;
diff --git a/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp b/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp
index cbb2fb0f3..225b49f4f 100644
--- a/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp
+++ b/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp
@@ -62,14 +62,8 @@ SurfaceBuffer::SurfaceBuffer(Surface *surface)
, m_surface_has_buffer(false)
, m_destroyed(false)
, m_is_displayed(false)
- , m_texture(0)
- , m_is_shm_resolved(false)
- , m_shmBuffer(0)
- , m_isSizeResolved(false)
- , m_size()
, m_used(false)
, m_destroyIfUnused(false)
- , m_image(0)
{
}
@@ -82,17 +76,11 @@ SurfaceBuffer::~SurfaceBuffer()
void SurfaceBuffer::initialize(struct ::wl_resource *buffer)
{
m_buffer = buffer;
- m_texture = 0;
m_committed = false;
m_is_registered_for_buffer = true;
m_surface_has_buffer = true;
m_is_displayed = false;
m_destroyed = false;
- m_handle = 0;
- m_is_shm_resolved = false;
- m_shmBuffer = 0;
- m_isSizeResolved = false;
- m_size = QSize();
m_destroy_listener.surfaceBuffer = this;
m_destroy_listener.listener.notify = destroy_listener_callback;
if (buffer)
@@ -101,58 +89,14 @@ void SurfaceBuffer::initialize(struct ::wl_resource *buffer)
void SurfaceBuffer::destructBufferState()
{
- destroyTexture();
if (m_buffer) {
sendRelease();
-
- if (m_handle) {
- if (m_shmBuffer) {
- delete static_cast<QImage *>(m_handle);
-#ifdef QT_COMPOSITOR_WAYLAND_GL
- } else {
- ClientBufferIntegration *hwIntegration = m_compositor->clientBufferIntegration();
- hwIntegration->unlockNativeBuffer(m_handle);
-#endif
- }
- }
wl_list_remove(&m_destroy_listener.listener.link);
}
m_buffer = 0;
- m_handle = 0;
m_committed = false;
m_is_registered_for_buffer = false;
m_is_displayed = false;
- m_image = QImage();
-}
-
-QSize SurfaceBuffer::size() const
-{
- if (!m_isSizeResolved) {
- if (isShmBuffer()) {
- m_size = QSize(wl_shm_buffer_get_width(m_shmBuffer), wl_shm_buffer_get_height(m_shmBuffer));
-#ifdef QT_COMPOSITOR_WAYLAND_GL
- } else {
- ClientBufferIntegration *hwIntegration = m_compositor->clientBufferIntegration();
- m_size = hwIntegration->bufferSize(m_buffer);
-#endif
- }
- }
-
- return m_size;
-}
-
-bool SurfaceBuffer::isShmBuffer() const
-{
- if (!m_is_shm_resolved) {
-#if (WAYLAND_VERSION_MAJOR >= 1) && (WAYLAND_VERSION_MINOR >= 2)
- m_shmBuffer = wl_shm_buffer_get(m_buffer);
-#else
- if (wl_buffer_is_shm(static_cast<struct ::wl_buffer*>(m_buffer->data)))
- m_shmBuffer = static_cast<struct ::wl_buffer*>(m_buffer->data);
-#endif
- m_is_shm_resolved = true;
- }
- return m_shmBuffer != 0;
}
void SurfaceBuffer::sendRelease()
@@ -173,74 +117,6 @@ void SurfaceBuffer::setDisplayed()
m_is_displayed = true;
}
-void SurfaceBuffer::destroyTexture()
-{
-#ifdef QT_COMPOSITOR_WAYLAND_GL
- if (m_texture) {
- Q_ASSERT(QOpenGLContext::currentContext());
- ClientBufferIntegration *hwIntegration = m_compositor->clientBufferIntegration();
- if (hwIntegration->textureForBuffer(m_buffer) == 0)
- glDeleteTextures(1, &m_texture);
- else
- hwIntegration->destroyTextureForBuffer(m_buffer);
- m_texture = 0;
- }
-#endif
-}
-
-void SurfaceBuffer::handleAboutToBeDisplayed()
-{
- qDebug() << Q_FUNC_INFO;
-}
-
-void SurfaceBuffer::handleDisplayed()
-{
- qDebug() << Q_FUNC_INFO;
-}
-
-void *SurfaceBuffer::handle() const
-{
- if (!m_buffer)
- return 0;
-
- if (!m_handle) {
- SurfaceBuffer *that = const_cast<SurfaceBuffer *>(this);
- if (isShmBuffer()) {
- const uchar *data = static_cast<const uchar *>(wl_shm_buffer_get_data(m_shmBuffer));
- int stride = wl_shm_buffer_get_stride(m_shmBuffer);
- int width = wl_shm_buffer_get_width(m_shmBuffer);
- int height = wl_shm_buffer_get_height(m_shmBuffer);
- QImage *image = new QImage(data,width,height,stride, QImage::Format_ARGB32_Premultiplied);
- that->m_handle = image;
-#ifdef QT_COMPOSITOR_WAYLAND_GL
- } else {
- ClientBufferIntegration *clientBufferIntegration = m_compositor->clientBufferIntegration();
- that->m_handle = clientBufferIntegration->lockNativeBuffer(m_buffer);
-#endif
- }
- }
- return m_handle;
-}
-
-QImage SurfaceBuffer::image()
-{
- /* This api may be available on non-shm buffer. But be sure about it's format. */
- if (!m_buffer || !isShmBuffer())
- return QImage();
-
- if (m_image.isNull())
- {
- const uchar *data = static_cast<const uchar *>(wl_shm_buffer_get_data(m_shmBuffer));
- int stride = wl_shm_buffer_get_stride(m_shmBuffer);
- int width = wl_shm_buffer_get_width(m_shmBuffer);
- int height = wl_shm_buffer_get_height(m_shmBuffer);
- QImage::Format format = QWaylandShmFormatHelper::fromWaylandShmFormat(wl_shm_format(wl_shm_buffer_get_format(m_shmBuffer)));
- m_image = QImage(data, width, height, stride, format);
- }
-
- return m_image;
-}
-
void SurfaceBuffer::destroy_listener_callback(wl_listener *listener, void *data)
{
Q_UNUSED(data);
@@ -254,39 +130,6 @@ void SurfaceBuffer::destroy_listener_callback(wl_listener *listener, void *data)
d->m_buffer = 0;
}
-void SurfaceBuffer::createTexture()
-{
- destroyTexture();
-
- ClientBufferIntegration *hwIntegration = m_compositor->clientBufferIntegration();
-#ifdef QT_COMPOSITOR_WAYLAND_GL
- if (!m_texture)
- m_texture = hwIntegration->textureForBuffer(m_buffer);
- if (!m_texture)
- glGenTextures(1, &m_texture);
- glBindTexture(GL_TEXTURE_2D, m_texture);
- hwIntegration->bindTextureToBuffer(m_buffer);
-#else
- Q_UNUSED(hwIntegration);
-#endif
-}
-
-bool SurfaceBuffer::isYInverted() const
-{
- bool ret = false;
- static bool negateReturn = qgetenv("QT_COMPOSITOR_NEGATE_INVERTED_Y").toInt();
- ClientBufferIntegration *clientBufferIntegration = m_compositor->clientBufferIntegration();
-
-#ifdef QT_COMPOSITOR_WAYLAND_GL
- if (clientBufferIntegration && waylandBufferHandle() && !isShmBuffer()) {
- ret = clientBufferIntegration->isYInverted(waylandBufferHandle());
- } else
-#endif
- ret = true;
-
- return ret != negateReturn;
-}
-
void SurfaceBuffer::ref()
{
m_used = m_refCount.ref();
@@ -311,6 +154,68 @@ void SurfaceBuffer::destroyIfUnused()
delete this;
}
+QSize SurfaceBuffer::size() const
+{
+ if (wl_shm_buffer *shmBuffer = wl_shm_buffer_get(m_buffer)) {
+ int width = wl_shm_buffer_get_width(shmBuffer);
+ int height = wl_shm_buffer_get_height(shmBuffer);
+ return QSize(width, height);
+ }
+ if (ClientBufferIntegration *integration = m_compositor->clientBufferIntegration()) {
+ return integration->bufferSize(m_buffer);
+ }
+
+ return QSize();
+}
+
+QWaylandSurface::Origin SurfaceBuffer::origin() const
+{
+ if (isShm()) {
+ return QWaylandSurface::OriginTopLeft;
+ }
+
+ if (ClientBufferIntegration *integration = m_compositor->clientBufferIntegration()) {
+ return integration->origin(m_buffer);
+ }
+ return QWaylandSurface::OriginTopLeft;
+}
+
+QImage SurfaceBuffer::image() const
+{
+ if (wl_shm_buffer *shmBuffer = wl_shm_buffer_get(m_buffer)) {
+ int width = wl_shm_buffer_get_width(shmBuffer);
+ int height = wl_shm_buffer_get_height(shmBuffer);
+ int bytesPerLine = wl_shm_buffer_get_stride(shmBuffer);
+ uchar *data = static_cast<uchar *>(wl_shm_buffer_get_data(shmBuffer));
+ return QImage(data, width, height, bytesPerLine, QImage::Format_ARGB32_Premultiplied);
+ }
+
+ return QImage();
+}
+
+void SurfaceBuffer::bindToTexture() const
+{
+ Q_ASSERT(m_compositor);
+ if (isShm()) {
+ QImage image = this->image();
+ if (image.hasAlphaChannel()) {
+ if (image.format() != QImage::Format_RGBA8888) {
+ image = image.convertToFormat(QImage::Format_RGBA8888);
+ }
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, image.constBits());
+ } else {
+ if (image.format() != QImage::Format_RGBX8888) {
+ image = image.convertToFormat(QImage::Format_RGBX8888);
+ }
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.width(), image.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, image.constBits());
+ }
+ } else {
+ if (QtWayland::ClientBufferIntegration *clientInt = m_compositor->clientBufferIntegration()) {
+ clientInt->bindTextureToBuffer(m_buffer);
+ }
+ }
+}
+
}
QT_END_NAMESPACE
diff --git a/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h b/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h
index 7003e9360..8eecfa73f 100644
--- a/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h
+++ b/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h
@@ -42,6 +42,8 @@
#include <QImage>
#include <QAtomicInt>
+#include <QtCompositor/QWaylandSurface>
+
#include <wayland-server.h>
QT_BEGIN_NAMESPACE
@@ -70,11 +72,6 @@ public:
void initialize(struct ::wl_resource *bufferResource);
void destructBufferState();
- QSize size() const;
-
- bool isShmBuffer() const;
- bool isYInverted() const;
-
inline bool isRegisteredWithBuffer() const { return m_is_registered_for_buffer; }
void sendRelease();
@@ -86,29 +83,19 @@ public:
inline void setCommitted() { m_committed = true; }
inline bool isDisplayed() const { return m_is_displayed; }
- inline bool textureCreated() const { return m_texture; }
-
bool isDestroyed() { return m_destroyed; }
- void createTexture();
-#ifdef QT_COMPOSITOR_WAYLAND_GL
- inline GLuint texture() const;
-#else
- inline uint texture() const;
-#endif
-
- void destroyTexture();
-
inline struct ::wl_resource *waylandBufferHandle() const { return m_buffer; }
- void handleAboutToBeDisplayed();
- void handleDisplayed();
-
- void bufferWasDestroyed();
void setDestroyIfUnused(bool destroy);
- void *handle() const;
- QImage image();
+ QSize size() const;
+ QWaylandSurface::Origin origin() const;
+ bool isShm() const { return wl_shm_buffer_get(m_buffer); }
+
+ QImage image() const;
+ void bindToTexture() const;
+
private:
void ref();
void deref();
@@ -124,47 +111,16 @@ private:
bool m_destroyed;
bool m_is_displayed;
-#ifdef QT_COMPOSITOR_WAYLAND_GL
- GLuint m_texture;
-#else
- uint m_texture;
-#endif
- void *m_handle;
- mutable bool m_is_shm_resolved;
-
-#if (WAYLAND_VERSION_MAJOR >= 1) && (WAYLAND_VERSION_MINOR >= 2)
- mutable struct ::wl_shm_buffer *m_shmBuffer;
-#else
- mutable struct ::wl_buffer *m_shmBuffer;
-#endif
-
- mutable bool m_isSizeResolved;
- mutable QSize m_size;
+
QAtomicInt m_refCount;
bool m_used;
bool m_destroyIfUnused;
- QImage m_image;
-
static void destroy_listener_callback(wl_listener *listener, void *data);
friend class ::QWaylandBufferRef;
};
-#ifdef QT_COMPOSITOR_WAYLAND_GL
-GLuint SurfaceBuffer::texture() const
-{
- if (m_buffer)
- return m_texture;
- return 0;
-}
-#else
-uint SurfaceBuffer::texture() const
-{
- return 0;
-}
-#endif
-
}
QT_END_NAMESPACE
diff --git a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp
index 0453a31b7..d22b2db04 100644
--- a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp
+++ b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp
@@ -190,7 +190,7 @@ void WaylandEglClientBufferIntegration::bindTextureToBuffer(struct ::wl_resource
d->egl_destroy_image(d->egl_display, image);
}
-bool WaylandEglClientBufferIntegration::isYInverted(struct ::wl_resource *buffer) const
+QWaylandSurface::Origin WaylandEglClientBufferIntegration::origin(struct ::wl_resource *buffer) const
{
#if defined(EGL_WAYLAND_Y_INVERTED_WL)
Q_D(const WaylandEglClientBufferIntegration);
@@ -203,11 +203,11 @@ bool WaylandEglClientBufferIntegration::isYInverted(struct ::wl_resource *buffer
// value (not supported) should be treated the same as EGL_TRUE return value
// and EGL_TRUE in value.
if (ret == EGL_FALSE || isYInverted == EGL_TRUE)
- return true;
- return false;
+ return QWaylandSurface::OriginTopLeft;
+ return QWaylandSurface::OriginBottomLeft;
#endif
- return QtWayland::ClientBufferIntegration::isYInverted(buffer);
+ return QtWayland::ClientBufferIntegration::origin(buffer);
}
diff --git a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h
index 66b827caa..874d960f5 100644
--- a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h
+++ b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h
@@ -53,7 +53,7 @@ public:
void initializeHardware(QtWayland::Display *waylandDisplay) Q_DECL_OVERRIDE;
void bindTextureToBuffer(struct ::wl_resource *buffer) Q_DECL_OVERRIDE;
- bool isYInverted(struct ::wl_resource *) const Q_DECL_OVERRIDE;
+ QWaylandSurface::Origin origin(struct ::wl_resource *) const Q_DECL_OVERRIDE;
void *lockNativeBuffer(struct ::wl_resource *buffer) const Q_DECL_OVERRIDE;
void unlockNativeBuffer(void *native_buffer) const Q_DECL_OVERRIDE;
diff --git a/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.cpp b/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.cpp
index 0c46172b7..0d909dcf6 100644
--- a/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.cpp
+++ b/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.cpp
@@ -115,7 +115,7 @@ void XCompositeEglClientBufferIntegration::bindTextureToBuffer(struct ::wl_resou
qDebug() << "Failed to create eglsurface" << pixmap << compositorBuffer->window();
}
- compositorBuffer->setInvertedY(true);
+ compositorBuffer->setOrigin(QWaylandSurface::OriginTopLeft);
if (!eglBindTexImage(mEglDisplay,surface,EGL_BACK_BUFFER)) {
qDebug() << "Failed to bind";
@@ -124,10 +124,10 @@ void XCompositeEglClientBufferIntegration::bindTextureToBuffer(struct ::wl_resou
// eglDestroySurface(mEglDisplay,surface);
}
-bool XCompositeEglClientBufferIntegration::isYInverted(struct ::wl_resource *buffer) const
+QWaylandSurface::Origin XCompositeEglClientBufferIntegration::origin(struct ::wl_resource *buffer) const
{
XCompositeBuffer *compositorBuffer = XCompositeBuffer::fromResource(buffer);
- return compositorBuffer->isYInverted();
+ return compositorBuffer->origin();
}
QSize XCompositeEglClientBufferIntegration::bufferSize(struct ::wl_resource *buffer) const
diff --git a/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.h b/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.h
index a976963d2..27d99eb28 100644
--- a/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.h
+++ b/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.h
@@ -53,7 +53,7 @@ public:
void initializeHardware(QtWayland::Display *waylandDisplay) Q_DECL_OVERRIDE;
void bindTextureToBuffer(struct ::wl_resource *buffer) Q_DECL_OVERRIDE;
- bool isYInverted(struct ::wl_resource *) const Q_DECL_OVERRIDE;
+ QWaylandSurface::Origin origin(struct ::wl_resource *) const Q_DECL_OVERRIDE;
QSize bufferSize(struct ::wl_resource *buffer) const Q_DECL_OVERRIDE;
diff --git a/src/hardwareintegration/compositor/xcomposite_share/xcompositebuffer.cpp b/src/hardwareintegration/compositor/xcomposite_share/xcompositebuffer.cpp
index 58f333f6a..a14b8f136 100644
--- a/src/hardwareintegration/compositor/xcomposite_share/xcompositebuffer.cpp
+++ b/src/hardwareintegration/compositor/xcomposite_share/xcompositebuffer.cpp
@@ -42,7 +42,7 @@ XCompositeBuffer::XCompositeBuffer(Window window, const QSize &size,
struct ::wl_client *client, uint32_t id)
: QtWaylandServer::wl_buffer(client, id, 1)
, mWindow(window)
- , mInvertedY(false)
+ , mOrigin(QWaylandSurface::OriginBottomLeft)
, mSize(size)
{
}
diff --git a/src/hardwareintegration/compositor/xcomposite_share/xcompositebuffer.h b/src/hardwareintegration/compositor/xcomposite_share/xcompositebuffer.h
index b753c4ccf..e6753e185 100644
--- a/src/hardwareintegration/compositor/xcomposite_share/xcompositebuffer.h
+++ b/src/hardwareintegration/compositor/xcomposite_share/xcompositebuffer.h
@@ -39,6 +39,7 @@
#include <private/qwlcompositor_p.h>
#include <qwayland-server-wayland.h>
+#include <QtCompositor/QWaylandSurface>
#include <QtCore/QSize>
@@ -59,8 +60,8 @@ public:
Window window();
- bool isYInverted() const { return mInvertedY; }
- void setInvertedY(bool inverted) { mInvertedY = inverted; }
+ QWaylandSurface::Origin origin() const { return mOrigin; }
+ void setOrigin(QWaylandSurface::Origin origin) { mOrigin = origin; }
QSize size() const { return mSize; }
@@ -72,7 +73,7 @@ protected:
private:
Window mWindow;
- bool mInvertedY;
+ QWaylandSurface::Origin mOrigin;
QSize mSize;
};