summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/client/hardwareintegration/qwaylandclientbufferintegration_p.h2
-rw-r--r--src/client/qwaylandintegration.cpp10
-rw-r--r--src/client/qwaylandshmbackingstore.cpp47
-rw-r--r--src/client/qwaylandshmbackingstore_p.h7
-rw-r--r--src/client/qwaylandshmwindow.cpp7
-rw-r--r--src/client/qwaylandshmwindow_p.h13
-rw-r--r--src/client/qwaylandwindow_p.h6
-rw-r--r--src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.cpp20
-rw-r--r--src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.h1
-rw-r--r--src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp10
10 files changed, 72 insertions, 51 deletions
diff --git a/src/client/hardwareintegration/qwaylandclientbufferintegration_p.h b/src/client/hardwareintegration/qwaylandclientbufferintegration_p.h
index 7d79f3263..be594984b 100644
--- a/src/client/hardwareintegration/qwaylandclientbufferintegration_p.h
+++ b/src/client/hardwareintegration/qwaylandclientbufferintegration_p.h
@@ -62,6 +62,8 @@ public:
virtual void initialize(QWaylandDisplay *display) = 0;
+ virtual bool isValid() const { return true; }
+
virtual bool supportsThreadedOpenGL() const { return false; }
virtual QWaylandWindow *createEglWindow(QWindow *window) = 0;
diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp
index 0c9062696..3b6d4acf9 100644
--- a/src/client/qwaylandintegration.cpp
+++ b/src/client/qwaylandintegration.cpp
@@ -42,9 +42,9 @@
#include "qwaylandintegration_p.h"
#include "qwaylanddisplay_p.h"
+#include "qwaylandshmwindow_p.h"
#include "qwaylandinputcontext_p.h"
#include "qwaylandshmbackingstore_p.h"
-#include "qwaylandshmwindow_p.h"
#include "qwaylandnativeinterface_p.h"
#include "qwaylandclipboard_p.h"
#include "qwaylanddnd_p.h"
@@ -162,14 +162,18 @@ bool QWaylandIntegration::hasCapability(QPlatformIntegration::Capability cap) co
case MultipleWindows:
case NonFullScreenWindows:
return true;
+ case RasterGLSurface:
+ return true;
default: return QPlatformIntegration::hasCapability(cap);
}
}
QPlatformWindow *QWaylandIntegration::createPlatformWindow(QWindow *window) const
{
- if (window->surfaceType() == QWindow::OpenGLSurface && mDisplay->clientBufferIntegration())
+ if ((window->surfaceType() == QWindow::OpenGLSurface || window->surfaceType() == QWindow::RasterGLSurface)
+ && mDisplay->clientBufferIntegration())
return mDisplay->clientBufferIntegration()->createEglWindow(window);
+
return new QWaylandShmWindow(window);
}
@@ -255,7 +259,7 @@ QWaylandClientBufferIntegration *QWaylandIntegration::clientBufferIntegration()
if (!mClientBufferIntegrationInitialized)
const_cast<QWaylandIntegration *>(this)->initializeClientBufferIntegration();
- return mClientBufferIntegration;
+ return mClientBufferIntegration && mClientBufferIntegration->isValid() ? mClientBufferIntegration : 0;
}
QWaylandServerBufferIntegration *QWaylandIntegration::serverBufferIntegration() const
diff --git a/src/client/qwaylandshmbackingstore.cpp b/src/client/qwaylandshmbackingstore.cpp
index 0677ed0d3..14e1285d3 100644
--- a/src/client/qwaylandshmbackingstore.cpp
+++ b/src/client/qwaylandshmbackingstore.cpp
@@ -39,14 +39,12 @@
**
****************************************************************************/
#include "qwaylandshmbackingstore_p.h"
-
-#include <QtCore/qdebug.h>
-
+#include "qwaylandwindow_p.h"
#include "qwaylanddisplay_p.h"
-#include "qwaylandshmwindow_p.h"
#include "qwaylandscreen_p.h"
#include "qwaylanddecoration_p.h"
+#include <QtCore/qdebug.h>
#include <QtGui/QPainter>
#include <wayland-client.h>
@@ -156,9 +154,7 @@ QWaylandShmBackingStore::~QWaylandShmBackingStore()
QPaintDevice *QWaylandShmBackingStore::paintDevice()
{
- if (!windowDecoration())
- return mBackBuffer->image();
- return mBackBuffer->imageInsideMargins(windowDecorationMargins());
+ return contentSurface();
}
void QWaylandShmBackingStore::beginPaint(const QRegion &)
@@ -166,13 +162,11 @@ void QWaylandShmBackingStore::beginPaint(const QRegion &)
mPainting = true;
ensureSize();
- if (waylandWindow()->attached() && mBackBuffer == waylandWindow()->attached() && mFrameCallback) {
- QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window()->handle());
- Q_ASSERT(waylandWindow->windowType() == QWaylandWindow::Shm);
- waylandWindow->waitForFrameSync();
- }
+ QWaylandWindow *window = waylandWindow();
+ if (window->attached() && mBackBuffer == window->attached() && mFrameCallback)
+ window->waitForFrameSync();
- waylandWindow()->setCanResize(false);
+ window->setCanResize(false);
}
void QWaylandShmBackingStore::endPaint()
@@ -190,9 +184,15 @@ void QWaylandShmBackingStore::ensureSize()
void QWaylandShmBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
{
+ // Invoked when the window is of type RasterSurface or when the window is
+ // RasterGLSurface and there are no child widgets requiring OpenGL composition.
+
+ // For the case of RasterGLSurface + having to compose, the composeAndFlush() is
+ // called instead. The default implementation from QPlatformBackingStore is sufficient
+ // however so no need to reimplement that.
+
Q_UNUSED(window);
Q_UNUSED(offset);
- Q_ASSERT(waylandWindow()->windowType() == QWaylandWindow::Shm);
if (windowDecoration() && windowDecoration()->isDirty())
updateDecorations();
@@ -260,6 +260,11 @@ QImage *QWaylandShmBackingStore::entireSurface() const
return mBackBuffer->image();
}
+QImage *QWaylandShmBackingStore::contentSurface() const
+{
+ return windowDecoration() ? mBackBuffer->imageInsideMargins(windowDecorationMargins()) : mBackBuffer->image();
+}
+
void QWaylandShmBackingStore::updateDecorations()
{
QPainter decorationPainter(entireSurface());
@@ -302,11 +307,19 @@ QMargins QWaylandShmBackingStore::windowDecorationMargins() const
return QMargins();
}
-QWaylandShmWindow *QWaylandShmBackingStore::waylandWindow() const
+QWaylandWindow *QWaylandShmBackingStore::waylandWindow() const
{
- return static_cast<QWaylandShmWindow *>(window()->handle());
+ return static_cast<QWaylandWindow *>(window()->handle());
}
+QImage QWaylandShmBackingStore::toImage() const
+{
+ // Invoked from QPlatformBackingStore::composeAndFlush() that is called
+ // instead of flush() for widgets that have renderToTexture children
+ // (QOpenGLWidget, QQuickWidget).
+
+ return *contentSurface();
+}
void QWaylandShmBackingStore::done(void *data, wl_callback *callback, uint32_t time)
{
@@ -315,7 +328,7 @@ void QWaylandShmBackingStore::done(void *data, wl_callback *callback, uint32_t t
static_cast<QWaylandShmBackingStore *>(data);
if (callback != self->mFrameCallback) // others, like QWaylandWindow, may trigger callbacks too
return;
- QWaylandShmWindow *window = self->waylandWindow();
+ QWaylandWindow *window = self->waylandWindow();
wl_callback_destroy(self->mFrameCallback);
self->mFrameCallback = 0;
diff --git a/src/client/qwaylandshmbackingstore_p.h b/src/client/qwaylandshmbackingstore_p.h
index 6097b5282..33f363f68 100644
--- a/src/client/qwaylandshmbackingstore_p.h
+++ b/src/client/qwaylandshmbackingstore_p.h
@@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE
class QWaylandDisplay;
class QWaylandDecoration;
-class QWaylandShmWindow;
+class QWaylandWindow;
class Q_WAYLAND_CLIENT_EXPORT QWaylandShmBuffer : public QWaylandBuffer {
public:
@@ -87,11 +87,14 @@ public:
QMargins windowDecorationMargins() const;
QImage *entireSurface() const;
+ QImage *contentSurface() const;
void ensureSize();
- QWaylandShmWindow *waylandWindow() const;
+ QWaylandWindow *waylandWindow() const;
void iterateBuffer();
+ QImage toImage() const Q_DECL_OVERRIDE;
+
private:
void updateDecorations();
diff --git a/src/client/qwaylandshmwindow.cpp b/src/client/qwaylandshmwindow.cpp
index de87682ce..431ed2fdb 100644
--- a/src/client/qwaylandshmwindow.cpp
+++ b/src/client/qwaylandshmwindow.cpp
@@ -51,13 +51,11 @@ QT_BEGIN_NAMESPACE
QWaylandShmWindow::QWaylandShmWindow(QWindow *window)
: QWaylandWindow(window)
- , mBackingStore(0)
{
}
QWaylandShmWindow::~QWaylandShmWindow()
{
-
}
QWaylandWindow::WindowType QWaylandShmWindow::windowType() const
@@ -65,9 +63,4 @@ QWaylandWindow::WindowType QWaylandShmWindow::windowType() const
return QWaylandWindow::Shm;
}
-void QWaylandShmWindow::setBackingStore(QWaylandShmBackingStore *backingStore)
-{
- mBackingStore = backingStore;
-}
-
QT_END_NAMESPACE
diff --git a/src/client/qwaylandshmwindow_p.h b/src/client/qwaylandshmwindow_p.h
index 83479f313..47ee74269 100644
--- a/src/client/qwaylandshmwindow_p.h
+++ b/src/client/qwaylandshmwindow_p.h
@@ -47,8 +47,6 @@
QT_BEGIN_NAMESPACE
-class QWaylandShmBackingStore;
-
class Q_WAYLAND_CLIENT_EXPORT QWaylandShmWindow : public QWaylandWindow
{
public:
@@ -57,19 +55,8 @@ public:
WindowType windowType() const;
QSurfaceFormat format() const { return QSurfaceFormat(); }
-
- void setBackingStore(QWaylandShmBackingStore *backingStore);
- QWaylandShmBackingStore *backingStore() const;
-
-private:
- QWaylandShmBackingStore *mBackingStore;
};
-inline QWaylandShmBackingStore *QWaylandShmWindow::backingStore() const
-{
- return mBackingStore;
-}
-
QT_END_NAMESPACE
#endif // QWAYLANDSHMWINDOW_H
diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
index 9c0be84c6..0d0833e54 100644
--- a/src/client/qwaylandwindow_p.h
+++ b/src/client/qwaylandwindow_p.h
@@ -63,6 +63,7 @@ class QWaylandSubSurface;
class QWaylandDecoration;
class QWaylandInputDevice;
class QWaylandScreen;
+class QWaylandShmBackingStore;
class Q_WAYLAND_CLIENT_EXPORT QWaylandWindowConfigure
{
@@ -179,6 +180,9 @@ public:
QVariant property(const QString &name);
QVariant property(const QString &name, const QVariant &defaultValue);
+ void setBackingStore(QWaylandShmBackingStore *backingStore) { mBackingStore = backingStore; }
+ QWaylandShmBackingStore *backingStore() const { return mBackingStore; }
+
public slots:
void requestResize();
@@ -216,6 +220,8 @@ protected:
Qt::WindowState mState;
+ QWaylandShmBackingStore *mBackingStore;
+
private:
bool setWindowStateInternal(Qt::WindowState flags);
void setGeometry_helper(const QRect &rect);
diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.cpp
index 68d38c498..b0edc175c 100644
--- a/src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.cpp
+++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.cpp
@@ -57,6 +57,7 @@ static const char *qwaylandegl_threadedgl_blacklist_vendor[] = {
QWaylandEglClientBufferIntegration::QWaylandEglClientBufferIntegration()
: m_waylandDisplay(0)
+ , m_eglDisplay(EGL_NO_DISPLAY)
, m_supportsThreading(false)
{
qDebug() << "Using Wayland-EGL";
@@ -79,13 +80,15 @@ void QWaylandEglClientBufferIntegration::initialize(QWaylandDisplay *display)
EGLint major,minor;
m_eglDisplay = eglGetDisplay((EGLNativeDisplayType) m_waylandDisplay);
- if (m_eglDisplay == NULL) {
+ if (m_eglDisplay == EGL_NO_DISPLAY) {
qWarning("EGL not available");
- } else {
- if (!eglInitialize(m_eglDisplay, &major, &minor)) {
- qWarning("failed to initialize EGL display");
- return;
- }
+ return;
+ }
+
+ if (!eglInitialize(m_eglDisplay, &major, &minor)) {
+ qWarning("failed to initialize EGL display");
+ m_eglDisplay = EGL_NO_DISPLAY;
+ return;
}
m_supportsThreading = true;
@@ -101,6 +104,11 @@ void QWaylandEglClientBufferIntegration::initialize(QWaylandDisplay *display)
}
}
+bool QWaylandEglClientBufferIntegration::isValid() const
+{
+ return m_eglDisplay != EGL_NO_DISPLAY;
+}
+
bool QWaylandEglClientBufferIntegration::supportsThreadedOpenGL() const
{
return m_supportsThreading;
diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.h b/src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.h
index 0c7d76cb9..7f2e28b88 100644
--- a/src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.h
+++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.h
@@ -58,6 +58,7 @@ public:
~QWaylandEglClientBufferIntegration();
void initialize(QWaylandDisplay *display) Q_DECL_OVERRIDE;
+ bool isValid() const Q_DECL_OVERRIDE;
bool supportsThreadedOpenGL() const Q_DECL_OVERRIDE;
QWaylandWindow *createEglWindow(QWindow *window) Q_DECL_OVERRIDE;
diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
index 527ac868b..a9247d4a1 100644
--- a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
+++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
@@ -64,7 +64,10 @@ QWaylandEglWindow::QWaylandEglWindow(QWindow *window)
, m_resize(false)
, m_format(q_glFormatFromConfig(m_clientBufferIntegration->eglDisplay(), m_eglConfig))
{
- updateSurface(true);
+ // Do not create anything from here. This platform window may belong to a
+ // RasterGLSurface window which may have pure raster content. In this case, where the
+ // window is never actually made current, creating a wl_egl_window and EGL surface
+ // should be avoided.
}
QWaylandEglWindow::~QWaylandEglWindow()
@@ -74,7 +77,8 @@ QWaylandEglWindow::~QWaylandEglWindow()
m_eglSurface = 0;
}
- wl_egl_window_destroy(m_waylandEglWindow);
+ if (m_waylandEglWindow)
+ wl_egl_window_destroy(m_waylandEglWindow);
delete m_contentFBO;
}
@@ -125,7 +129,7 @@ void QWaylandEglWindow::updateSurface(bool create)
m_resize = true;
}
- } else {
+ } else if (create) {
m_waylandEglWindow = wl_egl_window_create(object(), sizeWithMargins.width(), sizeWithMargins.height());
}