diff options
Diffstat (limited to 'src/compositor/compositor_api')
-rw-r--r-- | src/compositor/compositor_api/compositor_api.pri | 15 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandbufferref.cpp | 131 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandbufferref.h | 87 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandcompositor.cpp | 37 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandcompositor.h | 5 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandquickcompositor.cpp | 102 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandquickcompositor.h | 64 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandquicksurface.cpp | 241 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandquicksurface.h | 91 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandsurface.cpp | 220 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandsurface.h | 57 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandsurface_p.h | 68 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandsurfaceitem.cpp | 173 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandsurfaceitem.h | 41 |
14 files changed, 995 insertions, 337 deletions
diff --git a/src/compositor/compositor_api/compositor_api.pri b/src/compositor/compositor_api/compositor_api.pri index 87d28003c..8e7fd3ace 100644 --- a/src/compositor/compositor_api/compositor_api.pri +++ b/src/compositor/compositor_api/compositor_api.pri @@ -2,29 +2,34 @@ INCLUDEPATH += compositor_api HEADERS += \ compositor_api/qwaylandcompositor.h \ + compositor_api/qwaylandcompositor_p.h \ compositor_api/qwaylandsurface.h \ + compositor_api/qwaylandsurface_p.h \ compositor_api/qwaylandinput.h \ compositor_api/qwaylandinputpanel.h \ - compositor_api/qwaylanddrag.h + compositor_api/qwaylanddrag.h \ + compositor_api/qwaylandbufferref.h SOURCES += \ compositor_api/qwaylandcompositor.cpp \ compositor_api/qwaylandsurface.cpp \ compositor_api/qwaylandinput.cpp \ compositor_api/qwaylandinputpanel.cpp \ - compositor_api/qwaylanddrag.cpp + compositor_api/qwaylanddrag.cpp \ + compositor_api/qwaylandbufferref.cpp QT += core-private qtHaveModule(quick) { SOURCES += \ + compositor_api/qwaylandquickcompositor.cpp \ + compositor_api/qwaylandquicksurface.cpp \ compositor_api/qwaylandsurfaceitem.cpp HEADERS += \ + compositor_api/qwaylandquickcompositor.h \ + compositor_api/qwaylandquicksurface.h \ compositor_api/qwaylandsurfaceitem.h - DEFINES += QT_COMPOSITOR_QUICK - QT += qml quick - QT += quick-private gui-private } diff --git a/src/compositor/compositor_api/qwaylandbufferref.cpp b/src/compositor/compositor_api/qwaylandbufferref.cpp new file mode 100644 index 000000000..67554c7cb --- /dev/null +++ b/src/compositor/compositor_api/qwaylandbufferref.cpp @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Jolla Ltd, author: <giulio.camuffo@jollamobile.com> +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QDebug> +#include <QAtomicInt> + +#include "qwaylandbufferref.h" +#include "wayland_wrapper/qwlsurfacebuffer_p.h" + +QT_BEGIN_NAMESPACE + +class QWaylandBufferRefPrivate +{ +public: + QtWayland::SurfaceBuffer *buffer; +}; + +QWaylandBufferRef::QWaylandBufferRef() + : d(new QWaylandBufferRefPrivate) +{ + d->buffer = 0; +} + +QWaylandBufferRef::QWaylandBufferRef(QtWayland::SurfaceBuffer *buffer) + : d(new QWaylandBufferRefPrivate) +{ + d->buffer = buffer; + if (buffer) + buffer->m_refCount.ref(); +} + +QWaylandBufferRef::QWaylandBufferRef(const QWaylandBufferRef &ref) + : d(new QWaylandBufferRefPrivate) +{ + d->buffer = 0; + *this = ref; +} + +QWaylandBufferRef::~QWaylandBufferRef() +{ + if (d->buffer && !d->buffer->m_refCount.deref()) + d->buffer->disown(); + delete d; +} + +QWaylandBufferRef &QWaylandBufferRef::operator=(const QWaylandBufferRef &ref) +{ + if (d->buffer && !d->buffer->m_refCount.deref()) + d->buffer->disown(); + + d->buffer = ref.d->buffer; + if (d->buffer) + d->buffer->m_refCount.ref(); + + return *this; +} + +QWaylandBufferRef::operator bool() const +{ + return d->buffer && d->buffer->waylandBufferHandle(); +} + +bool QWaylandBufferRef::isShm() const +{ + return d->buffer->isShmBuffer(); +} + +QImage QWaylandBufferRef::image() const +{ + if (d->buffer->isShmBuffer()) + return d->buffer->image(); + return QImage(); +} + +#ifdef QT_COMPOSITOR_WAYLAND_GL + +GLuint QWaylandBufferRef::createTexture() +{ + if (!d->buffer->isShmBuffer() && !d->buffer->textureCreated()) { + d->buffer->createTexture(); + } + return d->buffer->texture(); +} + +void QWaylandBufferRef::destroyTexture() +{ + if (!d->buffer->isShmBuffer() && d->buffer->textureCreated()) { + d->buffer->destroyTexture(); + } +} +#endif + +QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandbufferref.h b/src/compositor/compositor_api/qwaylandbufferref.h new file mode 100644 index 000000000..0d1573bbb --- /dev/null +++ b/src/compositor/compositor_api/qwaylandbufferref.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Jolla Ltd, author: <giulio.camuffo@jollamobile.com> +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDBUFFERREF_H +#define QWAYLANDBUFFERREF_H + +#ifdef QT_COMPOSITOR_WAYLAND_GL +#include <QtGui/qopengl.h> +#endif + +#include <QtCompositor/qwaylandexport.h> + +QT_BEGIN_NAMESPACE + +namespace QtWayland +{ + class SurfaceBuffer; +} + +class Q_COMPOSITOR_EXPORT QWaylandBufferRef +{ +public: + QWaylandBufferRef(); + explicit QWaylandBufferRef(QtWayland::SurfaceBuffer *buffer); + QWaylandBufferRef(const QWaylandBufferRef &ref); + ~QWaylandBufferRef(); + + QWaylandBufferRef &operator=(const QWaylandBufferRef &ref); + operator bool() const; + bool isShm() const; + + QImage image() const; +#ifdef QT_COMPOSITOR_WAYLAND_GL + /** + * There must be a GL context bound when calling this function. + * It is responsibility of the caller to call destroyTexture() later. + */ + GLuint createTexture(); + void destroyTexture(); +#endif + +private: + class QWaylandBufferRefPrivate *const d; + friend class QWaylandBufferRefPrivate; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/compositor/compositor_api/qwaylandcompositor.cpp b/src/compositor/compositor_api/qwaylandcompositor.cpp index 342dce510..2135a0e94 100644 --- a/src/compositor/compositor_api/qwaylandcompositor.cpp +++ b/src/compositor/compositor_api/qwaylandcompositor.cpp @@ -55,33 +55,26 @@ #include <QDebug> -#ifdef QT_COMPOSITOR_QUICK -#include "qwaylandsurfaceitem.h" -#endif - QT_BEGIN_NAMESPACE QWaylandCompositor::QWaylandCompositor(QWindow *window, const char *socketName, ExtensionFlags extensions) - : m_compositor(0) + : m_compositor(new QtWayland::Compositor(this, extensions)) , m_toplevel_window(window) - , m_socket_name(socketName) { - QStringList arguments = QCoreApplication::instance()->arguments(); + m_compositor->m_socket_name = socketName; + m_compositor->init(); - int socketArg = arguments.indexOf(QLatin1String("--wayland-socket-name")); - if (socketArg != -1 && socketArg + 1 < arguments.size()) - m_socket_name = arguments.at(socketArg + 1).toLocal8Bit(); - - m_compositor = new QtWayland::Compositor(this, extensions); -#ifdef QT_COMPOSITOR_QUICK - qmlRegisterType<QWaylandSurfaceItem>("WaylandCompositor", 1, 0, "WaylandSurfaceItem"); - qmlRegisterType<QWaylandSurface>("WaylandCompositor", 1, 0, "WaylandSurface"); -#else - qRegisterMetaType<QWaylandSurface*>("WaylandSurface*"); +#if !defined(QT_NO_DEBUG) && !defined(QT_WAYLAND_NO_CLEANUP_WARNING) + qWarning("QWaylandCompositor::cleanupGraphicsResources() must be called manually"); #endif - m_compositor->initializeHardwareIntegration(); - m_compositor->initializeExtensions(); - m_compositor->initializeDefaultInputDevice(); +} + +QWaylandCompositor::QWaylandCompositor(QWindow *window, const char *socketName, QtWayland::Compositor *dptr) + : m_compositor(dptr) + , m_toplevel_window(window) +{ + m_compositor->m_socket_name = socketName; + m_compositor->init(); } QWaylandCompositor::~QWaylandCompositor() @@ -213,9 +206,9 @@ void QWaylandCompositor::setClientFullScreenHint(bool value) const char *QWaylandCompositor::socketName() const { - if (m_socket_name.isEmpty()) + if (m_compositor->m_socket_name.isEmpty()) return 0; - return m_socket_name.constData(); + return m_compositor->m_socket_name.constData(); } /*! diff --git a/src/compositor/compositor_api/qwaylandcompositor.h b/src/compositor/compositor_api/qwaylandcompositor.h index 9009f4caa..85f10b281 100644 --- a/src/compositor/compositor_api/qwaylandcompositor.h +++ b/src/compositor/compositor_api/qwaylandcompositor.h @@ -141,13 +141,14 @@ public: void configureTouchExtension(TouchExtensionFlags flags); protected: + QWaylandCompositor(QWindow *window, const char *socketName, QtWayland::Compositor *dptr); virtual void retainedSelectionReceived(QMimeData *mimeData); -private: friend class QtWayland::Compositor; QtWayland::Compositor *m_compositor; + +private: QWindow *m_toplevel_window; - QByteArray m_socket_name; }; Q_DECLARE_OPERATORS_FOR_FLAGS(QWaylandCompositor::ExtensionFlags) diff --git a/src/compositor/compositor_api/qwaylandquickcompositor.cpp b/src/compositor/compositor_api/qwaylandquickcompositor.cpp new file mode 100644 index 000000000..bc475f1c5 --- /dev/null +++ b/src/compositor/compositor_api/qwaylandquickcompositor.cpp @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Jolla Ltd, author: <giulio.camuffo@jollamobile.com> +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QQuickWindow> + +#include <QtCompositor/private/qwlcompositor_p.h> + +#include "qwaylandquickcompositor.h" +#include "qwaylandquicksurface.h" +#include "qwaylandsurfaceitem.h" + +QT_BEGIN_NAMESPACE + +class QWaylandQuickCompositorPrivate : public QtWayland::Compositor +{ +public: + QWaylandQuickCompositorPrivate(QWaylandQuickCompositor *compositor, QWaylandCompositor::ExtensionFlags extensions) + : QtWayland::Compositor(compositor, extensions) + , updateScheduled(false) + { + } + + void compositor_create_surface(Resource *resource, uint32_t id) Q_DECL_OVERRIDE + { + QWaylandQuickSurface *surface = new QWaylandQuickSurface(resource->client(), id, static_cast<QWaylandQuickCompositor *>(m_qt_compositor)); + m_surfaces << surface->handle(); + //BUG: This may not be an on-screen window surface though + m_qt_compositor->surfaceCreated(surface); + } + + void updateStarted() + { + updateScheduled = false; + m_qt_compositor->frameStarted(); + m_qt_compositor->cleanupGraphicsResources(); + } + + bool updateScheduled; +}; + + +QWaylandQuickCompositor::QWaylandQuickCompositor(QQuickWindow *window, const char *socketName, ExtensionFlags extensions) + : QWaylandCompositor(window, socketName, new QWaylandQuickCompositorPrivate(this, extensions)) +{ + window->connect(window, &QQuickWindow::beforeSynchronizing, d_ptr(), &QWaylandQuickCompositorPrivate::updateStarted, Qt::DirectConnection); + + qmlRegisterType<QWaylandSurfaceItem>("QtCompositor", 1, 0, "WaylandSurfaceItem"); + qmlRegisterUncreatableType<QWaylandQuickSurface>("QtCompositor", 1, 0, "WaylandQuickSurface", QObject::tr("Cannot create instance of WaylandQuickSurface")); +} + +QWaylandQuickCompositorPrivate *QWaylandQuickCompositor::d_ptr() +{ + return static_cast<QWaylandQuickCompositorPrivate *>(m_compositor); +} + +void QWaylandQuickCompositor::update() +{ + if (!d_ptr()->updateScheduled) { + static_cast<QQuickWindow *>(window())->update(); + d_ptr()->updateScheduled = true; + } +} + +QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandquickcompositor.h b/src/compositor/compositor_api/qwaylandquickcompositor.h new file mode 100644 index 000000000..c87585221 --- /dev/null +++ b/src/compositor/compositor_api/qwaylandquickcompositor.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Jolla Ltd, author: <giulio.camuffo@jollamobile.com> +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDQUICKCOMPOSITOR_H +#define QWAYLANDQUICKCOMPOSITOR_H + +#include <QtCompositor/qwaylandcompositor.h> + +QT_BEGIN_NAMESPACE + +class QQuickWindow; +class QWaylandQuickCompositorPrivate; + +class Q_COMPOSITOR_EXPORT QWaylandQuickCompositor : public QWaylandCompositor +{ +public: + QWaylandQuickCompositor(QQuickWindow *window = 0, const char *socketName = 0, QWaylandCompositor::ExtensionFlags extensions = DefaultExtensions); + + void update(); + +private: + friend class QWaylandQuickCompositorPrivate; + QWaylandQuickCompositorPrivate *d_ptr(); +}; + +#endif diff --git a/src/compositor/compositor_api/qwaylandquicksurface.cpp b/src/compositor/compositor_api/qwaylandquicksurface.cpp new file mode 100644 index 000000000..e4a5f7732 --- /dev/null +++ b/src/compositor/compositor_api/qwaylandquicksurface.cpp @@ -0,0 +1,241 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Jolla Ltd, author: <giulio.camuffo@jollamobile.com> +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QSGTexture> +#include <QOpenGLTexture> +#include <QQuickWindow> +#include <QDebug> +#include <QQmlPropertyMap> + +#include "qwaylandquicksurface.h" +#include "qwaylandquickcompositor.h" +#include "qwaylandsurfaceitem.h" +#include <QtCompositor/qwaylandbufferref.h> +#include <QtCompositor/private/qwaylandsurface_p.h> + +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() + { + if (bufferRef) + bufferRef.destroyTexture(); + bufferRef = nextBuffer; + + QQuickWindow *window = static_cast<QQuickWindow *>(surface->compositor()->window()); + // If the next buffer is NULL do not delete the current texture. If the client called + // attach(0) the surface is going to be unmapped anyway, if instead the client attached + // a valid buffer but died before we got here we want to keep the old buffer around + // in case some destroy animation is run. + if (bufferRef) { + delete texture; + + 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 invalidateTexture() + { + delete texture; + texture = 0; + } + + QWaylandQuickSurface *surface; + QWaylandBufferRef bufferRef; + QWaylandBufferRef nextBuffer; + QSGTexture *texture; + bool update; +}; + + +class QWaylandQuickSurfacePrivate : public QWaylandSurfacePrivate +{ +public: + QWaylandQuickSurfacePrivate(wl_client *client, quint32 id, QWaylandQuickCompositor *c, QWaylandQuickSurface *surf) + : QWaylandSurfacePrivate(client, id, 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 + { + if (m_pending.newlyAttached) { + buffer->update = true; + } + QWaylandSurfacePrivate::surface_commit(resource); + + compositor->update(); + } + + BufferAttacher *buffer; + QWaylandQuickCompositor *compositor; + bool useTextureAlpha; + QQmlPropertyMap *windowPropertyMap; + bool clientRenderingEnabled; +}; + +QWaylandQuickSurface::QWaylandQuickSurface(wl_client *client, quint32 id, QWaylandQuickCompositor *compositor) + : QWaylandSurface(new QWaylandQuickSurfacePrivate(client, id, compositor, this)) +{ + Q_D(QWaylandQuickSurface); + d->buffer->surface = this; + setBufferAttacher(d->buffer); + + QQuickWindow *window = static_cast<QQuickWindow *>(compositor->window()); + connect(window, &QQuickWindow::beforeSynchronizing, this, &QWaylandQuickSurface::updateTexture, Qt::DirectConnection); + connect(window, &QQuickWindow::sceneGraphInvalidated, this, &QWaylandQuickSurface::invalidateTexture, Qt::DirectConnection); + connect(this, &QWaylandSurface::windowPropertyChanged, d->windowPropertyMap, &QQmlPropertyMap::insert); + connect(d->windowPropertyMap, &QQmlPropertyMap::valueChanged, this, &QWaylandSurface::setWindowProperty); + +} + +QWaylandQuickSurface::~QWaylandQuickSurface() +{ + +} + +QSGTexture *QWaylandQuickSurface::texture() const +{ + Q_D(const QWaylandQuickSurface); + return d->buffer->texture; +} + +bool QWaylandQuickSurface::useTextureAlpha() const +{ + Q_D(const QWaylandQuickSurface); + return d->useTextureAlpha; +} + +void QWaylandQuickSurface::setUseTextureAlpha(bool useTextureAlpha) +{ + Q_D(QWaylandQuickSurface); + if (d->useTextureAlpha != useTextureAlpha) { + d->useTextureAlpha = useTextureAlpha; + emit useTextureAlphaChanged(); + emit configure(); + } +} + +QObject *QWaylandQuickSurface::windowPropertyMap() const +{ + Q_D(const QWaylandQuickSurface); + return d->windowPropertyMap; +} + + +void QWaylandQuickSurface::updateTexture() +{ + Q_D(QWaylandQuickSurface); + if (d->buffer->update) + d->buffer->createTexture(); +} + +void QWaylandQuickSurface::invalidateTexture() +{ + Q_D(QWaylandQuickSurface); + d->buffer->invalidateTexture(); +} + +bool QWaylandQuickSurface::clientRenderingEnabled() const +{ + Q_D(const QWaylandQuickSurface); + return d->clientRenderingEnabled; +} + +void QWaylandQuickSurface::setClientRenderingEnabled(bool enabled) +{ + Q_D(QWaylandQuickSurface); + if (d->clientRenderingEnabled != enabled) { + d->clientRenderingEnabled = enabled; + + sendOnScreenVisibilityChange(enabled); + + emit clientRenderingEnabledChanged(); + } +} + +QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandquicksurface.h b/src/compositor/compositor_api/qwaylandquicksurface.h new file mode 100644 index 000000000..6c464ecd7 --- /dev/null +++ b/src/compositor/compositor_api/qwaylandquicksurface.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Jolla Ltd, author: <giulio.camuffo@jollamobile.com> +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKWAYLANDSURFACE_H +#define QQUICKWAYLANDSURFACE_H + +#include <QSGTexture> +#include <QSGTextureProvider> + +#include "qwaylandsurface.h" + +struct wl_client; + +QT_BEGIN_NAMESPACE + +class QWaylandSurfaceItem; +class QWaylandQuickSurfacePrivate; +class QWaylandQuickCompositor; + +class Q_COMPOSITOR_EXPORT QWaylandQuickSurface : public QWaylandSurface +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QWaylandQuickSurface) + Q_PROPERTY(bool useTextureAlpha READ useTextureAlpha WRITE setUseTextureAlpha NOTIFY useTextureAlphaChanged) + Q_PROPERTY(bool clientRenderingEnabled READ clientRenderingEnabled WRITE setClientRenderingEnabled NOTIFY clientRenderingEnabledChanged) + Q_PROPERTY(QObject *windowProperties READ windowPropertyMap CONSTANT) +public: + QWaylandQuickSurface(wl_client *client, quint32 id, QWaylandQuickCompositor *compositor); + ~QWaylandQuickSurface(); + + QSGTexture *texture() const; + + bool useTextureAlpha() const; + void setUseTextureAlpha(bool useTextureAlpha); + + bool clientRenderingEnabled() const; + void setClientRenderingEnabled(bool enabled); + + QObject *windowPropertyMap() const; + +signals: + void useTextureAlphaChanged(); + void clientRenderingEnabledChanged(); + +private: + void updateTexture(); + void invalidateTexture(); + +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/compositor/compositor_api/qwaylandsurface.cpp b/src/compositor/compositor_api/qwaylandsurface.cpp index 2b7d713c8..5fd7fabe9 100644 --- a/src/compositor/compositor_api/qwaylandsurface.cpp +++ b/src/compositor/compositor_api/qwaylandsurface.cpp @@ -53,74 +53,51 @@ #include "qwaylandcompositor.h" #include "waylandwindowmanagerintegration.h" +#include "qwaylandsurface_p.h" +#include "qwaylandbufferref.h" #include <QtGui/QGuiApplication> #include <QtGui/QScreen> -#ifdef QT_COMPOSITOR_QUICK -#include "qwaylandsurfaceitem.h" -#include <QtQml/QQmlPropertyMap> -#endif - QT_BEGIN_NAMESPACE -class QWaylandSurfacePrivate : public QObjectPrivate -{ -public: - QWaylandSurfacePrivate(QtWayland::Surface *srfc) - : surface(srfc) -#ifdef QT_COMPOSITOR_QUICK - , surface_item(0) - , windowPropertyMap(new QQmlPropertyMap) -#endif - {} - - ~QWaylandSurfacePrivate() - { -#ifdef QT_COMPOSITOR_QUICK - if (surface_item) - surface_item->setSurface(0); - if (windowPropertyMap) - windowPropertyMap->deleteLater(); -#endif - } +QWaylandSurfacePrivate::QWaylandSurfacePrivate(wl_client *client, quint32 id, QWaylandCompositor *compositor, QWaylandSurface *surface) + : QtWayland::Surface(client, id, compositor, surface) + , closing(false) + , refCount(1) +{} - QtWayland::Surface *surface; -#ifdef QT_COMPOSITOR_QUICK - QWaylandSurfaceItem *surface_item; - QQmlPropertyMap *windowPropertyMap; -#endif -}; -QWaylandSurface::QWaylandSurface(QtWayland::Surface *surface) - : QObject(*new QWaylandSurfacePrivate(surface)) + +QWaylandSurface::QWaylandSurface(wl_client *client, quint32 id, QWaylandCompositor *compositor) + : QObject(*new QWaylandSurfacePrivate(client, id, compositor, this)) { -#ifdef QT_COMPOSITOR_QUICK - Q_D(QWaylandSurface); - connect(this, &QWaylandSurface::windowPropertyChanged, - d->windowPropertyMap, &QQmlPropertyMap::insert); - connect(d->windowPropertyMap, &QQmlPropertyMap::valueChanged, - this, &QWaylandSurface::setWindowProperty); -#endif + } -void QWaylandSurface::swapBuffers() +QWaylandSurface::QWaylandSurface(QWaylandSurfacePrivate *dptr) + : QObject(*dptr) { - Q_D(const QWaylandSurface); - d->surface->swapBuffers(); + +} + +QWaylandSurface::~QWaylandSurface() +{ + Q_D(QWaylandSurface); + delete d->m_attacher; } WaylandClient *QWaylandSurface::client() const { Q_D(const QWaylandSurface); - return d->surface->resource()->client(); + return d->resource()->client(); } QWaylandSurface *QWaylandSurface::parentSurface() const { Q_D(const QWaylandSurface); - if (d->surface->subSurface() && d->surface->subSurface()->parent()) { - return d->surface->subSurface()->parent()->waylandSurface(); + if (d->subSurface() && d->subSurface()->parent()) { + return d->subSurface()->parent()->waylandSurface(); } return 0; } @@ -128,8 +105,8 @@ QWaylandSurface *QWaylandSurface::parentSurface() const QLinkedList<QWaylandSurface *> QWaylandSurface::subSurfaces() const { Q_D(const QWaylandSurface); - if (d->surface->subSurface()) { - return d->surface->subSurface()->subSurfaces(); + if (d->subSurface()) { + return d->subSurface()->subSurfaces(); } return QLinkedList<QWaylandSurface *>(); } @@ -137,13 +114,13 @@ QLinkedList<QWaylandSurface *> QWaylandSurface::subSurfaces() const QWaylandSurface::Type QWaylandSurface::type() const { Q_D(const QWaylandSurface); - return d->surface->type(); + return d->type(); } bool QWaylandSurface::isYInverted() const { Q_D(const QWaylandSurface); - return d->surface->isYInverted(); + return d->isYInverted(); } bool QWaylandSurface::visible() const @@ -154,110 +131,70 @@ bool QWaylandSurface::visible() const bool QWaylandSurface::isMapped() const { Q_D(const QWaylandSurface); - return d->surface->mapped(); + return d->mapped(); } QPointF QWaylandSurface::pos() const { Q_D(const QWaylandSurface); - return d->surface->pos(); + return d->pos(); } void QWaylandSurface::setPos(const QPointF &pos) { Q_D(QWaylandSurface); - d->surface->setPos(pos); + d->setPos(pos); } QSize QWaylandSurface::size() const { Q_D(const QWaylandSurface); - return d->surface->size(); + return d->size(); } void QWaylandSurface::requestSize(const QSize &size) { Q_D(QWaylandSurface); - if (d->surface->shellSurface()) - d->surface->shellSurface()->sendConfigure(WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT, size.width(), size.height()); + if (d->shellSurface()) + d->shellSurface()->sendConfigure(WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT, size.width(), size.height()); } Qt::ScreenOrientations QWaylandSurface::orientationUpdateMask() const { Q_D(const QWaylandSurface); - return d->surface->compositor()->orientationUpdateMaskForClient(static_cast<wl_client *>(client())); + return d->compositor()->orientationUpdateMaskForClient(static_cast<wl_client *>(client())); } Qt::ScreenOrientation QWaylandSurface::contentOrientation() const { Q_D(const QWaylandSurface); - if (!d->surface->extendedSurface()) + if (!d->extendedSurface()) return Qt::PrimaryOrientation; - return d->surface->extendedSurface()->contentOrientation(); + return d->extendedSurface()->contentOrientation(); } QWaylandSurface::WindowFlags QWaylandSurface::windowFlags() const { Q_D(const QWaylandSurface); - if (!d->surface->extendedSurface()) + if (!d->extendedSurface()) return QWaylandSurface::WindowFlags(0); - return d->surface->extendedSurface()->windowFlags(); + return d->extendedSurface()->windowFlags(); } QWaylandSurface::WindowType QWaylandSurface::windowType() const { Q_D(const QWaylandSurface); - if (d->surface->shellSurface()) - return d->surface->shellSurface()->windowType(); + if (d->shellSurface()) + return d->shellSurface()->windowType(); return QWaylandSurface::None; } -QImage QWaylandSurface::image() const -{ - Q_D(const QWaylandSurface); - return d->surface->image(); -} - -#ifdef QT_COMPOSITOR_WAYLAND_GL -GLuint QWaylandSurface::texture() const -{ - Q_D(const QWaylandSurface); - return d->surface->textureId(); -} -#else //QT_COMPOSITOR_WAYLAND_GL -uint QWaylandSurface::texture() const -{ - return 0; -} -#endif - -QtWayland::Surface * QWaylandSurface::handle() const -{ - Q_D(const QWaylandSurface); - return d->surface; -} - -#ifdef QT_COMPOSITOR_QUICK -QWaylandSurfaceItem *QWaylandSurface::surfaceItem() const -{ - Q_D(const QWaylandSurface); - return d->surface_item; -} - -void QWaylandSurface::setSurfaceItem(QWaylandSurfaceItem *surfaceItem) +QtWayland::Surface * QWaylandSurface::handle() { Q_D(QWaylandSurface); - d->surface_item = surfaceItem; + return d; } -QObject *QWaylandSurface::windowPropertyMap() const -{ - Q_D(const QWaylandSurface); - return d->windowPropertyMap; -} - -#endif //QT_COMPOSITOR_QUICK - qint64 QWaylandSurface::processId() const { struct wl_client *client = static_cast<struct wl_client *>(this->client()); @@ -269,19 +206,19 @@ qint64 QWaylandSurface::processId() const QVariantMap QWaylandSurface::windowProperties() const { Q_D(const QWaylandSurface); - if (!d->surface->extendedSurface()) + if (!d->extendedSurface()) return QVariantMap(); - return d->surface->extendedSurface()->windowProperties(); + return d->extendedSurface()->windowProperties(); } void QWaylandSurface::setWindowProperty(const QString &name, const QVariant &value) { Q_D(QWaylandSurface); - if (!d->surface->extendedSurface()) + if (!d->extendedSurface()) return; - d->surface->extendedSurface()->setWindowProperty(name, value); + d->extendedSurface()->setWindowProperty(name, value); } QPointF QWaylandSurface::mapToParent(const QPointF &pos) const @@ -307,22 +244,22 @@ QPointF QWaylandSurface::mapTo(QWaylandSurface *parent, const QPointF &pos) cons QWaylandCompositor *QWaylandSurface::compositor() const { Q_D(const QWaylandSurface); - return d->surface->compositor()->waylandCompositor(); + return d->compositor()->waylandCompositor(); } QWaylandSurface *QWaylandSurface::transientParent() const { Q_D(const QWaylandSurface); - if (d->surface->shellSurface() && d->surface->shellSurface()->transientParent()) - return d->surface->shellSurface()->transientParent()->surface()->waylandSurface(); + if (d->shellSurface() && d->shellSurface()->transientParent()) + return d->shellSurface()->transientParent()->surface()->waylandSurface(); return 0; } QWindow::Visibility QWaylandSurface::visibility() const { Q_D(const QWaylandSurface); - if (d->surface->extendedSurface()) - return d->surface->extendedSurface()->visibility(); + if (d->extendedSurface()) + return d->extendedSurface()->visibility(); return QWindow::AutomaticVisibility; } @@ -330,8 +267,8 @@ QWindow::Visibility QWaylandSurface::visibility() const void QWaylandSurface::setVisibility(QWindow::Visibility visibility) { Q_D(QWaylandSurface); - if (d->surface->extendedSurface()) - d->surface->extendedSurface()->setVisibility(visibility); + if (d->extendedSurface()) + d->extendedSurface()->setVisibility(visibility); } void QWaylandSurface::sendOnScreenVisibilityChange(bool visible) @@ -342,19 +279,19 @@ void QWaylandSurface::sendOnScreenVisibilityChange(bool visible) QString QWaylandSurface::className() const { Q_D(const QWaylandSurface); - return d->surface->className(); + return d->className(); } QString QWaylandSurface::title() const { Q_D(const QWaylandSurface); - return d->surface->title(); + return d->title(); } bool QWaylandSurface::hasShellSurface() const { Q_D(const QWaylandSurface); - if (d->surface->shellSurface()) + if (d->shellSurface()) return true; return false; @@ -364,7 +301,7 @@ bool QWaylandSurface::hasInputPanelSurface() const { Q_D(const QWaylandSurface); - return d->surface->inputPanelSurface() != 0; + return d->inputPanelSurface() != 0; } /*! @@ -373,14 +310,21 @@ bool QWaylandSurface::hasInputPanelSurface() const bool QWaylandSurface::transientInactive() const { Q_D(const QWaylandSurface); - return d->surface->transientInactive(); + return d->transientInactive(); +} + +void QWaylandSurface::destroy() +{ + Q_D(QWaylandSurface); + if (--d->refCount == 0) + compositor()->handle()->destroySurface(d); } void QWaylandSurface::destroySurface() { Q_D(QWaylandSurface); - if (d->surface->extendedSurface()) { - d->surface->extendedSurface()->send_close(); + if (d->extendedSurface()) { + d->extendedSurface()->send_close(); } else { destroySurfaceByForce(); } @@ -389,15 +333,15 @@ void QWaylandSurface::destroySurface() void QWaylandSurface::destroySurfaceByForce() { Q_D(QWaylandSurface); - wl_resource *surface_resource = d->surface->resource()->handle; + wl_resource *surface_resource = d->resource()->handle; wl_resource_destroy(surface_resource); } void QWaylandSurface::ping() { Q_D(QWaylandSurface); - if (d->surface->shellSurface()) - d->surface->shellSurface()->ping(); + if (d->shellSurface()) + d->shellSurface()->ping(); } /*! @@ -408,14 +352,32 @@ void QWaylandSurface::ping() void QWaylandSurface::updateSelection() { Q_D(QWaylandSurface); - const QtWayland::InputDevice *inputDevice = d->surface->compositor()->defaultInputDevice(); + const QtWayland::InputDevice *inputDevice = d->compositor()->defaultInputDevice(); if (inputDevice) { const QtWayland::DataDevice *dataDevice = inputDevice->dataDevice(); if (dataDevice) { - d->surface->compositor()->dataDeviceManager()->offerRetainedSelection( - dataDevice->resourceMap().value(d->surface->resource()->client())->handle); + d->compositor()->dataDeviceManager()->offerRetainedSelection( + dataDevice->resourceMap().value(d->resource()->client())->handle); } } } +void QWaylandSurface::ref() +{ + Q_D(QWaylandSurface); + ++d->refCount; +} + +void QWaylandSurface::setBufferAttacher(QWaylandBufferAttacher *attacher) +{ + Q_D(QWaylandSurface); + d->m_attacher = attacher; +} + +QWaylandBufferAttacher *QWaylandSurface::bufferAttacher() const +{ + Q_D(const QWaylandSurface); + return d->m_attacher; +} + QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandsurface.h b/src/compositor/compositor_api/qwaylandsurface.h index 2f7b70ce8..22deee5ae 100644 --- a/src/compositor/compositor_api/qwaylandsurface.h +++ b/src/compositor/compositor_api/qwaylandsurface.h @@ -48,19 +48,14 @@ #include <QtGui/QWindow> #include <QtCore/QVariantMap> -#ifdef QT_COMPOSITOR_WAYLAND_GL -#include <QtGui/qopengl.h> -#endif +struct wl_client; QT_BEGIN_NAMESPACE class QTouchEvent; class QWaylandSurfacePrivate; class QWaylandCompositor; - -#ifdef QT_COMPOSITOR_QUICK -class QWaylandSurfaceItem; -#endif +class QWaylandBufferRef; namespace QtWayland { class Surface; @@ -68,6 +63,17 @@ class SurfacePrivate; class ExtendedSurface; } +class Q_COMPOSITOR_EXPORT QWaylandBufferAttacher +{ +public: + virtual ~QWaylandBufferAttacher() {} + +protected: + virtual void attach(const QWaylandBufferRef &ref) = 0; + + friend class QtWayland::Surface; +}; + class Q_COMPOSITOR_EXPORT QWaylandSurface : public QObject { Q_OBJECT @@ -81,9 +87,7 @@ class Q_COMPOSITOR_EXPORT QWaylandSurface : public QObject Q_PROPERTY(QString title READ title NOTIFY titleChanged) Q_PROPERTY(Qt::ScreenOrientations orientationUpdateMask READ orientationUpdateMask NOTIFY orientationUpdateMaskChanged) Q_PROPERTY(QWindow::Visibility visibility READ visibility WRITE setVisibility NOTIFY visibilityChanged) -#ifdef QT_COMPOSITOR_QUICK - Q_PROPERTY(QObject * windowProperties READ windowPropertyMap CONSTANT) -#endif + Q_PROPERTY(QSize size READ size NOTIFY sizeChanged) Q_ENUMS(WindowFlag WindowType) Q_FLAGS(WindowFlag WindowFlags) @@ -109,7 +113,8 @@ public: Texture }; - QWaylandSurface(QtWayland::Surface *surface = 0); + QWaylandSurface(wl_client *client, quint32 id, QWaylandCompositor *compositor); + virtual ~QWaylandSurface(); WaylandClient *client() const; @@ -134,27 +139,13 @@ public: WindowType windowType() const; - QImage image() const; -#ifdef QT_COMPOSITOR_WAYLAND_GL - GLuint texture() const; -#else - uint texture() const; -#endif - QWindow::Visibility visibility() const; void setVisibility(QWindow::Visibility visibility); Q_INVOKABLE void sendOnScreenVisibilityChange(bool visible); // Compat QWaylandSurface *transientParent() const; - QtWayland::Surface *handle() const; - -#ifdef QT_COMPOSITOR_QUICK - QWaylandSurfaceItem *surfaceItem() const; - void setSurfaceItem(QWaylandSurfaceItem *surfaceItem); - - QObject *windowPropertyMap() const; -#endif + QtWayland::Surface *handle(); qint64 processId() const; QByteArray authenticationToken() const; @@ -175,20 +166,26 @@ public: bool transientInactive() const; + Q_INVOKABLE void destroy(); Q_INVOKABLE void destroySurface(); Q_INVOKABLE void destroySurfaceByForce(); Q_INVOKABLE void ping(); - void swapBuffers(); + void ref(); + + void setBufferAttacher(QWaylandBufferAttacher *attacher); + QWaylandBufferAttacher *bufferAttacher() const; public slots: void updateSelection(); +protected: + QWaylandSurface(QWaylandSurfacePrivate *dptr); + signals: void mapped(); void unmapped(); void damaged(const QRegion &rect); - void committed(); void parentChanged(QWaylandSurface *newParent, QWaylandSurface *oldParent); void sizeChanged(); void posChanged(); @@ -204,6 +201,10 @@ signals: void lowerRequested(); void visibilityChanged(); void pong(); + void surfaceDestroyed(); + + void configure(); + void redraw(); }; QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandsurface_p.h b/src/compositor/compositor_api/qwaylandsurface_p.h new file mode 100644 index 000000000..aff0a8758 --- /dev/null +++ b/src/compositor/compositor_api/qwaylandsurface_p.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Jolla Ltd, author: <giulio.camuffo@jollamobile.com> +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDSURFACE_P_H +#define QWAYLANDSURFACE_P_H + +#include <QtCompositor/qwaylandexport.h> +#include <private/qobject_p.h> + +#include <QtCompositor/private/qwlsurface_p.h> + +QT_BEGIN_NAMESPACE + +class QWaylandCompositor; +class QWaylandSurface; + +class Q_COMPOSITOR_EXPORT QWaylandSurfacePrivate : public QObjectPrivate, public QtWayland::Surface +{ +public: + QWaylandSurfacePrivate(wl_client *client, quint32 id, QWaylandCompositor *compositor, QWaylandSurface *surface); + + bool closing; + int refCount; + + friend class QWaylandSurface; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/compositor/compositor_api/qwaylandsurfaceitem.cpp b/src/compositor/compositor_api/qwaylandsurfaceitem.cpp index 57e5c2906..1a1dc7cdb 100644 --- a/src/compositor/compositor_api/qwaylandsurfaceitem.cpp +++ b/src/compositor/compositor_api/qwaylandsurfaceitem.cpp @@ -39,12 +39,9 @@ ****************************************************************************/ #include "qwaylandsurfaceitem.h" -#include "qwaylandsurface.h" -#include "qwaylandcompositor.h" -#include "qwaylandinput.h" - -#include "qwlsurface_p.h" -#include "qwlextendedsurface_p.h" +#include "qwaylandquicksurface.h" +#include <QtCompositor/qwaylandcompositor.h> +#include <QtCompositor/qwaylandinput.h> #include <QtGui/QKeyEvent> #include <QtGui/QGuiApplication> @@ -58,15 +55,15 @@ QT_BEGIN_NAMESPACE +QMutex *QWaylandSurfaceItem::mutex = 0; + class QWaylandSurfaceTextureProvider : public QSGTextureProvider { - Q_OBJECT - public: QWaylandSurfaceTextureProvider() : t(0) { } - ~QWaylandSurfaceTextureProvider() { delete t; } - QSGTexture *texture() const { + QSGTexture *texture() const Q_DECL_OVERRIDE + { if (t) t->setFiltering(smooth ? QSGTexture::Linear : QSGTexture::Nearest); return t; @@ -74,55 +71,45 @@ public: bool smooth; QSGTexture *t; - -public slots: - void invalidate() - { - delete t; - t = 0; - } }; -QMutex *QWaylandSurfaceItem::mutex = 0; - QWaylandSurfaceItem::QWaylandSurfaceItem(QQuickItem *parent) : QQuickItem(parent) , m_surface(0) , m_provider(0) , m_paintEnabled(true) - , m_useTextureAlpha(false) - , m_clientRenderingEnabled(true) , m_touchEventsEnabled(false) , m_resizeSurfaceToItem(false) + , m_newTexture(false) { if (!mutex) mutex = new QMutex; + + setFlag(ItemHasContents); } -QWaylandSurfaceItem::QWaylandSurfaceItem(QWaylandSurface *surface, QQuickItem *parent) +QWaylandSurfaceItem::QWaylandSurfaceItem(QWaylandQuickSurface *surface, QQuickItem *parent) : QQuickItem(parent) , m_surface(0) , m_provider(0) , m_paintEnabled(true) - , m_useTextureAlpha(false) - , m_clientRenderingEnabled(true) , m_touchEventsEnabled(false) , m_resizeSurfaceToItem(false) { init(surface); } -void QWaylandSurfaceItem::init(QWaylandSurface *surface) +void QWaylandSurfaceItem::init(QWaylandQuickSurface *surface) { + if (m_surface) + m_surface->destroy(); + if (!surface) return; - if (m_surface) { - m_surface->setSurfaceItem(0); - } - m_surface = surface; - m_surface->setSurfaceItem(this); + surface->ref(); + update(); if (m_resizeSurfaceToItem) { updateSurfaceSize(); @@ -134,7 +121,7 @@ void QWaylandSurfaceItem::init(QWaylandSurface *surface) updatePosition(); setSmooth(true); - setFlag(ItemHasContents); + setAcceptedMouseButtons(Qt::LeftButton | Qt::MiddleButton | Qt::RightButton | Qt::ExtraButton1 | Qt::ExtraButton2 | Qt::ExtraButton3 | Qt::ExtraButton4 | Qt::ExtraButton5 | Qt::ExtraButton6 | Qt::ExtraButton7 | Qt::ExtraButton8 | @@ -143,29 +130,29 @@ void QWaylandSurfaceItem::init(QWaylandSurface *surface) setAcceptHoverEvents(true); connect(surface, &QWaylandSurface::mapped, this, &QWaylandSurfaceItem::surfaceMapped); connect(surface, &QWaylandSurface::unmapped, this, &QWaylandSurfaceItem::surfaceUnmapped); - connect(surface, &QWaylandSurface::destroyed, this, &QWaylandSurfaceItem::surfaceDestroyed); - connect(surface, &QWaylandSurface::damaged, this, &QWaylandSurfaceItem::surfaceDamaged); - connect(surface, &QWaylandSurface::committed, this, &QQuickItem::update); + connect(surface, &QWaylandSurface::surfaceDestroyed, this, &QWaylandSurfaceItem::surfaceDestroyed); connect(surface, &QWaylandSurface::parentChanged, this, &QWaylandSurfaceItem::parentChanged); connect(surface, &QWaylandSurface::sizeChanged, this, &QWaylandSurfaceItem::updateSize); connect(surface, &QWaylandSurface::posChanged, this, &QWaylandSurfaceItem::updatePosition); + connect(surface, &QWaylandSurface::configure, this, &QWaylandSurfaceItem::updateBuffer); + connect(surface, &QWaylandSurface::redraw, this, &QQuickItem::update); connect(this, &QWaylandSurfaceItem::widthChanged, this, &QWaylandSurfaceItem::updateSurfaceSize); connect(this, &QWaylandSurfaceItem::heightChanged, this, &QWaylandSurfaceItem::updateSurfaceSize); - m_damaged = false; m_yInverted = surface ? surface->isYInverted() : true; + emit yInvertedChanged(); } QWaylandSurfaceItem::~QWaylandSurfaceItem() { QMutexLocker locker(mutex); if (m_surface) - m_surface->setSurfaceItem(0); + m_surface->destroy(); if (m_provider) m_provider->deleteLater(); } -void QWaylandSurfaceItem::setSurface(QWaylandSurface *surface) +void QWaylandSurfaceItem::setSurface(QWaylandQuickSurface *surface) { if (surface == m_surface) return; @@ -181,16 +168,9 @@ bool QWaylandSurfaceItem::isYInverted() const QSGTextureProvider *QWaylandSurfaceItem::textureProvider() const { - const_cast<QWaylandSurfaceItem *>(this)->ensureProvider(); - return m_provider; -} - -void QWaylandSurfaceItem::ensureProvider() -{ - if (!m_provider) { + if (!m_provider) m_provider = new QWaylandSurfaceTextureProvider(); - connect(window(), &QQuickWindow::sceneGraphInvalidated, m_provider, &QWaylandSurfaceTextureProvider::invalidate, Qt::DirectConnection); - } + return m_provider; } void QWaylandSurfaceItem::mousePressEvent(QMouseEvent *event) @@ -281,40 +261,10 @@ void QWaylandSurfaceItem::surfaceUnmapped() update(); } -void QWaylandSurfaceItem::surfaceDestroyed(QObject *) -{ - if (m_surface) - m_surface->setSurfaceItem(0); - - m_surface = 0; -} - -void QWaylandSurfaceItem::setDamagedFlag(bool on) -{ - m_damaged = on; -} - - -void QWaylandSurfaceItem::surfaceDamaged(const QRegion &) -{ - m_damaged = true; - if (m_surface) { - bool inverted = m_surface->isYInverted(); - if (inverted != m_yInverted) { - m_yInverted = inverted; - emit yInvertedChanged(); - } - } - emit textureChanged(); -} - void QWaylandSurfaceItem::parentChanged(QWaylandSurface *newParent, QWaylandSurface *oldParent) { Q_UNUSED(oldParent); - QWaylandSurfaceItem *item = newParent? newParent->surfaceItem():0; - setParentItem(item); - if (newParent) { setPaintEnabled(true); setVisible(true); @@ -340,6 +290,14 @@ void QWaylandSurfaceItem::updatePosition() setPosition(m_surface->pos()); } +/*! + \qmlproperty bool QtWayland::QWaylandSurfaceItem::paintEnabled + + If this property is true, the \l item is hidden, though the texture + will still be updated. As opposed to hiding the \l item by + setting \l{Item::visible}{visible} to false, setting this property to true + will not prevent mouse or keyboard input from reaching \l item. +*/ bool QWaylandSurfaceItem::paintEnabled() const { return m_paintEnabled; @@ -351,29 +309,14 @@ void QWaylandSurfaceItem::setPaintEnabled(bool enabled) update(); } -void QWaylandSurfaceItem::updateTexture() +void QWaylandSurfaceItem::updateBuffer() { - ensureProvider(); - QSGTexture *texture = m_provider->t; - if (m_damaged) { - m_damaged = false; - QSGTexture *oldTexture = texture; - if (m_surface->type() == QWaylandSurface::Texture) { - QQuickWindow::CreateTextureOptions opt = 0; - if (useTextureAlpha()) { - opt |= QQuickWindow::TextureHasAlphaChannel; - } - texture = window()->createTextureFromId(m_surface->texture(), m_surface->size(), opt); - } else { - texture = window()->createTextureFromImage(m_surface->image()); - } - texture->bind(); - delete oldTexture; - } + bool inv = m_yInverted; + m_yInverted = surface()->isYInverted(); + if (inv != m_yInverted) + emit yInvertedChanged(); - m_provider->t = texture; - emit m_provider->textureChanged(); - m_provider->smooth = smooth(); + m_newTexture = true; } QSGNode *QWaylandSurfaceItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) @@ -383,14 +326,20 @@ QSGNode *QWaylandSurfaceItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeD return 0; } + if (!m_provider) + m_provider = new QWaylandSurfaceTextureProvider(); + // Order here is important, as the state of visible is that of the pending // buffer but will be replaced after we advance the buffer queue. bool mapped = m_surface->isMapped(); - surface()->swapBuffers(); if (mapped) - updateTexture(); + m_provider->t = surface()->texture(); + m_provider->smooth = smooth(); + if (m_newTexture) + emit m_provider->textureChanged(); + m_newTexture = false; - if (!mapped|| !m_provider || !m_provider->t || !m_paintEnabled) { + if (!mapped || !m_provider->t || !m_paintEnabled) { delete oldNode; return 0; } @@ -409,28 +358,6 @@ QSGNode *QWaylandSurfaceItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeD return node; } -void QWaylandSurfaceItem::setUseTextureAlpha(bool useTextureAlpha) -{ - m_useTextureAlpha = useTextureAlpha; - - if ((flags() & ItemHasContents) != 0) { - update(); - } -} - -void QWaylandSurfaceItem::setClientRenderingEnabled(bool enabled) -{ - if (m_clientRenderingEnabled != enabled) { - m_clientRenderingEnabled = enabled; - - if (m_surface) { - m_surface->sendOnScreenVisibilityChange(enabled); - } - - emit clientRenderingEnabledChanged(); - } -} - void QWaylandSurfaceItem::setTouchEventsEnabled(bool enabled) { if (m_touchEventsEnabled != enabled) { @@ -448,5 +375,3 @@ void QWaylandSurfaceItem::setResizeSurfaceToItem(bool enabled) } QT_END_NAMESPACE - -#include "qwaylandsurfaceitem.moc" diff --git a/src/compositor/compositor_api/qwaylandsurfaceitem.h b/src/compositor/compositor_api/qwaylandsurfaceitem.h index 8abd4bf2d..f1da27995 100644 --- a/src/compositor/compositor_api/qwaylandsurfaceitem.h +++ b/src/compositor/compositor_api/qwaylandsurfaceitem.h @@ -42,38 +42,37 @@ #define QWAYLANDSURFACEITEM_H #include <QtCompositor/qwaylandexport.h> -#include <QtCompositor/qwaylandsurface.h> #include <QtQuick/QQuickItem> #include <QtQuick/qsgtexture.h> #include <QtQuick/qsgtextureprovider.h> +#include "qwaylandquicksurface.h" + QT_BEGIN_NAMESPACE class QWaylandSurfaceTextureProvider; class QMutex; -Q_DECLARE_METATYPE(QWaylandSurface*) +Q_DECLARE_METATYPE(QWaylandQuickSurface*) -class Q_COMPOSITOR_EXPORT QWaylandSurfaceItem : public QQuickItem +class QWaylandSurfaceItem : public QQuickItem { Q_OBJECT - Q_PROPERTY(QWaylandSurface* surface READ surface WRITE setSurface NOTIFY surfaceChanged) + Q_PROPERTY(QWaylandQuickSurface* surface READ surface WRITE setSurface NOTIFY surfaceChanged) Q_PROPERTY(bool paintEnabled READ paintEnabled WRITE setPaintEnabled) - Q_PROPERTY(bool useTextureAlpha READ useTextureAlpha WRITE setUseTextureAlpha NOTIFY useTextureAlphaChanged) - Q_PROPERTY(bool clientRenderingEnabled READ clientRenderingEnabled WRITE setClientRenderingEnabled NOTIFY clientRenderingEnabledChanged) Q_PROPERTY(bool touchEventsEnabled READ touchEventsEnabled WRITE setTouchEventsEnabled NOTIFY touchEventsEnabledChanged) Q_PROPERTY(bool isYInverted READ isYInverted NOTIFY yInvertedChanged) Q_PROPERTY(bool resizeSurfaceToItem READ resizeSurfaceToItem WRITE setResizeSurfaceToItem NOTIFY resizeSurfaceToItemChanged) public: QWaylandSurfaceItem(QQuickItem *parent = 0); - QWaylandSurfaceItem(QWaylandSurface *surface, QQuickItem *parent = 0); + QWaylandSurfaceItem(QWaylandQuickSurface *surface, QQuickItem *parent = 0); ~QWaylandSurfaceItem(); - void setSurface(QWaylandSurface *surface); - QWaylandSurface *surface() const {return m_surface; } + void setSurface(QWaylandQuickSurface *surface); + QWaylandQuickSurface *surface() const {return m_surface; } Q_INVOKABLE bool isYInverted() const; @@ -81,18 +80,12 @@ public: QSGTextureProvider *textureProvider() const; bool paintEnabled() const; - bool useTextureAlpha() const { return m_useTextureAlpha; } - bool clientRenderingEnabled() const { return m_clientRenderingEnabled; } bool touchEventsEnabled() const { return m_touchEventsEnabled; } bool resizeSurfaceToItem() const { return m_resizeSurfaceToItem; } - void setUseTextureAlpha(bool useTextureAlpha); - void setClientRenderingEnabled(bool enabled); void setTouchEventsEnabled(bool enabled); void setResizeSurfaceToItem(bool enabled); - void setDamagedFlag(bool on); - protected: void mousePressEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); @@ -111,21 +104,18 @@ public slots: private slots: void surfaceMapped(); void surfaceUnmapped(); - void surfaceDestroyed(QObject *object); - void surfaceDamaged(const QRegion &); void parentChanged(QWaylandSurface *newParent, QWaylandSurface *oldParent); void updateSize(); void updateSurfaceSize(); void updatePosition(); + void updateBuffer(); signals: - void textureChanged(); - void useTextureAlphaChanged(); - void clientRenderingEnabledChanged(); void touchEventsEnabledChanged(); void yInvertedChanged(); void surfaceChanged(); void resizeSurfaceToItemChanged(); + void surfaceDestroyed(); protected: QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *); @@ -133,20 +123,17 @@ protected: private: friend class QWaylandSurfaceNode; void updateTexture(); - void init(QWaylandSurface *); - void ensureProvider(); + void init(QWaylandQuickSurface *); static QMutex *mutex; - QWaylandSurface *m_surface; - QWaylandSurfaceTextureProvider *m_provider; + QWaylandQuickSurface *m_surface; + mutable QWaylandSurfaceTextureProvider *m_provider; bool m_paintEnabled; - bool m_useTextureAlpha; - bool m_clientRenderingEnabled; bool m_touchEventsEnabled; - bool m_damaged; bool m_yInverted; bool m_resizeSurfaceToItem; + bool m_newTexture; }; QT_END_NAMESPACE |