diff options
-rw-r--r-- | src/client/hardwareintegration/qwaylandclientbufferintegration_p.h | 2 | ||||
-rw-r--r-- | src/client/qwaylandintegration.cpp | 10 | ||||
-rw-r--r-- | src/client/qwaylandshmbackingstore.cpp | 47 | ||||
-rw-r--r-- | src/client/qwaylandshmbackingstore_p.h | 7 | ||||
-rw-r--r-- | src/client/qwaylandshmwindow.cpp | 7 | ||||
-rw-r--r-- | src/client/qwaylandshmwindow_p.h | 13 | ||||
-rw-r--r-- | src/client/qwaylandwindow_p.h | 6 | ||||
-rw-r--r-- | src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.cpp | 20 | ||||
-rw-r--r-- | src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.h | 1 | ||||
-rw-r--r-- | src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp | 10 |
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 ®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<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()); } |