diff --git a/src/plugins/platforms/wayland/hardwareintegration/qwaylandclientbufferintegration_p.h b/src/plugins/platforms/wayland/hardwareintegration/qwaylandclientbufferintegration_p.h index 7d79f326330..be594984b56 100644 --- a/src/plugins/platforms/wayland/hardwareintegration/qwaylandclientbufferintegration_p.h +++ b/src/plugins/platforms/wayland/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/plugins/platforms/wayland/qwaylandintegration.cpp b/src/plugins/platforms/wayland/qwaylandintegration.cpp index 0c90626964c..3b6d4acf944 100644 --- a/src/plugins/platforms/wayland/qwaylandintegration.cpp +++ b/src/plugins/platforms/wayland/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(this)->initializeClientBufferIntegration(); - return mClientBufferIntegration; + return mClientBufferIntegration && mClientBufferIntegration->isValid() ? mClientBufferIntegration : 0; } QWaylandServerBufferIntegration *QWaylandIntegration::serverBufferIntegration() const diff --git a/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp b/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp index 0677ed0d398..14e1285d37b 100644 --- a/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp +++ b/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp @@ -39,14 +39,12 @@ ** ****************************************************************************/ #include "qwaylandshmbackingstore_p.h" - -#include - +#include "qwaylandwindow_p.h" #include "qwaylanddisplay_p.h" -#include "qwaylandshmwindow_p.h" #include "qwaylandscreen_p.h" #include "qwaylanddecoration_p.h" +#include #include #include @@ -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(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 ®ion, 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(window()->handle()); + return static_cast(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(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/plugins/platforms/wayland/qwaylandshmbackingstore_p.h b/src/plugins/platforms/wayland/qwaylandshmbackingstore_p.h index 6097b5282c8..33f363f6873 100644 --- a/src/plugins/platforms/wayland/qwaylandshmbackingstore_p.h +++ b/src/plugins/platforms/wayland/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/plugins/platforms/wayland/qwaylandshmwindow.cpp b/src/plugins/platforms/wayland/qwaylandshmwindow.cpp index de87682ce70..431ed2fdb97 100644 --- a/src/plugins/platforms/wayland/qwaylandshmwindow.cpp +++ b/src/plugins/platforms/wayland/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/plugins/platforms/wayland/qwaylandshmwindow_p.h b/src/plugins/platforms/wayland/qwaylandshmwindow_p.h index 83479f31303..47ee742699d 100644 --- a/src/plugins/platforms/wayland/qwaylandshmwindow_p.h +++ b/src/plugins/platforms/wayland/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/plugins/platforms/wayland/qwaylandwindow_p.h b/src/plugins/platforms/wayland/qwaylandwindow_p.h index 9c0be84c6a5..0d0833e54eb 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow_p.h +++ b/src/plugins/platforms/wayland/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);