diff options
author | Paul Olav Tvete <paul.tvete@qt.io> | 2019-01-30 10:33:55 +0100 |
---|---|---|
committer | Paul Olav Tvete <paul.tvete@qt.io> | 2019-03-28 14:40:19 +0000 |
commit | 80001cbf0451f4ba2a971fb20b80dc8e25ac604d (patch) | |
tree | 69c965b678b8bb8533e7bb7355b24f5fbef424eb /src/imports | |
parent | fde6362edc6ecadbcca8872f71c111bd7c896801 (diff) |
New texture sharing protocol and infrastructure
This adds a higher level protocol on top of the server buffer extension,
providing an easy way for Qt Quick applications to use the shared
textures.
[ChangeLog] Added protocol and Qt Quick image provider for sharing
textures in graphics memory between compositor and multiple clients.
Task-number: QTBUG-73822
Change-Id: Idc41b3479d6ca37be35d9ccd7b89e9994ff17f8f
Reviewed-by: Johan Helsing <johan.helsing@qt.io>
Diffstat (limited to 'src/imports')
-rw-r--r-- | src/imports/imports.pro | 7 | ||||
-rw-r--r-- | src/imports/texture-sharing-extension/plugin.cpp | 109 | ||||
-rw-r--r-- | src/imports/texture-sharing-extension/qmldir | 3 | ||||
-rw-r--r-- | src/imports/texture-sharing-extension/texture-sharing-extension.pro | 11 | ||||
-rw-r--r-- | src/imports/texture-sharing/plugin.cpp | 97 | ||||
-rw-r--r-- | src/imports/texture-sharing/qmldir | 3 | ||||
-rw-r--r-- | src/imports/texture-sharing/sharedtextureprovider.cpp | 322 | ||||
-rw-r--r-- | src/imports/texture-sharing/sharedtextureprovider.h | 118 | ||||
-rw-r--r-- | src/imports/texture-sharing/texture-sharing.pro | 21 | ||||
-rw-r--r-- | src/imports/texture-sharing/texturesharingextension.cpp | 86 | ||||
-rw-r--r-- | src/imports/texture-sharing/texturesharingextension.h | 77 |
11 files changed, 853 insertions, 1 deletions
diff --git a/src/imports/imports.pro b/src/imports/imports.pro index c57c95d20..c8394f0c1 100644 --- a/src/imports/imports.pro +++ b/src/imports/imports.pro @@ -1,3 +1,8 @@ TEMPLATE = subdirs -qtHaveModule(quick): SUBDIRS += compositor +qtHaveModule(quick): { + SUBDIRS += \ + compositor \ + texture-sharing \ + texture-sharing-extension +} diff --git a/src/imports/texture-sharing-extension/plugin.cpp b/src/imports/texture-sharing-extension/plugin.cpp new file mode 100644 index 000000000..42dcd8e2d --- /dev/null +++ b/src/imports/texture-sharing-extension/plugin.cpp @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module 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 The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtQml/qqmlextensionplugin.h> +#include <QtQml/qqmlengine.h> + +#include "QtWaylandCompositor/private/qwltexturesharingextension_p.h" + +/*! + \qmlmodule QtWayland.Compositor.TextureSharingExtension 1 + \title Qt Wayland Shared Texture Provider + \ingroup qmlmodules + \brief Adds a mechanism to share GPU memory + + \section2 Summary + + This module lets the compositor export graphical resources that can be used by clients, + without allocating any graphics memory in the client. + + \section2 Usage + + This module is imported like this: + + \code + import QtWayland.Compositor.TextureSharingExtension 1.0 + \endcode + + To use this module in a compositor, instantiate the extension object as a child of the compositor object, like this: + + + \code + WaylandCompositor { + //... + TextureSharingExtension { + } + } + \endcode + + The sharing functionality is provided through a QQuickImageProvider. Use + the "image:" scheme for the URL source of the image, followed by the + identifier \e wlshared, followed by the image file path. For example: + + \code + Image { source: "image://wlshared/wallpapers/mybackground.jpg" } + \endcode + +*/ + +QT_BEGIN_NAMESPACE + +class QWaylandTextureSharingExtensionPlugin : public QQmlExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) +public: + QWaylandTextureSharingExtensionPlugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent) {} + + void registerTypes(const char *uri) override + { + Q_ASSERT(uri == QStringLiteral("QtWayland.Compositor.TextureSharingExtension")); + qmlRegisterType<QWaylandTextureSharingExtensionQuickExtension>("QtWayland.Compositor.TextureSharingExtension", 1, 0, "TextureSharingExtension"); + } + + void initializeEngine(QQmlEngine *engine, const char *uri) override + { + Q_UNUSED(uri); + engine->addImageProvider("wlshared", new QWaylandSharedTextureProvider); + } +}; + +QT_END_NAMESPACE + +#include "plugin.moc" diff --git a/src/imports/texture-sharing-extension/qmldir b/src/imports/texture-sharing-extension/qmldir new file mode 100644 index 000000000..182e5c0ee --- /dev/null +++ b/src/imports/texture-sharing-extension/qmldir @@ -0,0 +1,3 @@ +module QtWayland.Compositor.TextureSharingExtension +plugin qwaylandtexturesharingextension +classname QWaylandTextureSharingExtensionPlugin diff --git a/src/imports/texture-sharing-extension/texture-sharing-extension.pro b/src/imports/texture-sharing-extension/texture-sharing-extension.pro new file mode 100644 index 000000000..68a8cf757 --- /dev/null +++ b/src/imports/texture-sharing-extension/texture-sharing-extension.pro @@ -0,0 +1,11 @@ +CXX_MODULE = qml +TARGET = qwaylandtexturesharingextension +TARGETPATH = QtWayland/Compositor/TextureSharingExtension +IMPORT_VERSION = 1.$$QT_MINOR_VERSION + +SOURCES += \ + plugin.cpp + +QT += quick-private qml gui-private core-private waylandcompositor waylandcompositor-private + +load(qml_plugin) diff --git a/src/imports/texture-sharing/plugin.cpp b/src/imports/texture-sharing/plugin.cpp new file mode 100644 index 000000000..9cf6bbca1 --- /dev/null +++ b/src/imports/texture-sharing/plugin.cpp @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWaylandClient module 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 The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtQml/qqmlextensionplugin.h> +#include <QtQml/qqmlengine.h> + +#include "sharedtextureprovider.h" + +/*! + \qmlmodule QtWayland.Client.TextureSharing 1 + \title Qt Wayland Shared Texture Provider + \ingroup qmlmodules + \brief Adds an image provider which utilizes shared GPU memory + + \section2 Summary + + This module allows Qt Wayland clients to use graphical resources exported + by the compositor, without allocating any graphics memory in the client. + \section2 Usage + + To use this module, import it like this: + \code + import QtWayland.Client.TextureSharing 1.0 + \endcode + + The sharing functionality is provided through a QQuickImageProvider. Use + the "image:" scheme for the URL source of the image, followed by the + identifier \e wlshared, followed by the image file path. For example: + + \code + Image { source: "image://wlshared/wallpapers/mybackground.jpg" } + \endcode + + The shared texture module does not provide any directly usable QML types. +*/ + +QT_BEGIN_NAMESPACE + +class QWaylandTextureSharingPlugin : public QQmlExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) +public: + QWaylandTextureSharingPlugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent) {} + + void registerTypes(const char *uri) override + { + Q_ASSERT(uri == QStringLiteral("QtWayland.Client.TextureSharing")); + qmlRegisterModule(uri, 1, 0); + } + + void initializeEngine(QQmlEngine *engine, const char *uri) override + { + Q_UNUSED(uri); + engine->addImageProvider("wlshared", new SharedTextureProvider); + } +}; + +QT_END_NAMESPACE + +#include "plugin.moc" diff --git a/src/imports/texture-sharing/qmldir b/src/imports/texture-sharing/qmldir new file mode 100644 index 000000000..cf3b74c48 --- /dev/null +++ b/src/imports/texture-sharing/qmldir @@ -0,0 +1,3 @@ +module QtWayland.Client.TextureSharing +plugin qwaylandtexturesharing +classname QWaylandTextureSharingPlugin diff --git a/src/imports/texture-sharing/sharedtextureprovider.cpp b/src/imports/texture-sharing/sharedtextureprovider.cpp new file mode 100644 index 000000000..707e94ae6 --- /dev/null +++ b/src/imports/texture-sharing/sharedtextureprovider.cpp @@ -0,0 +1,322 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** 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 The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include "sharedtextureprovider.h" + +#include <QFile> +#include <QDebug> +#include <qopenglfunctions.h> +#include <QQuickWindow> + +#include <QtWaylandClient/private/qwaylandintegration_p.h> +#include <QtWaylandClient/private/qwaylandserverbufferintegration_p.h> +#include <QtGui/QGuiApplication> +#include <QtGui/private/qguiapplication_p.h> +#include <QtGui/qpa/qplatformnativeinterface.h> +#include <QtGui/QWindow> +#include <QOpenGLTexture> +#include <QImageReader> + +#include <QTimer> + +#include "texturesharingextension.h" + +QT_BEGIN_NAMESPACE + +SharedTexture::SharedTexture(QtWaylandClient::QWaylandServerBuffer *buffer) + : m_buffer(buffer), m_tex(nullptr) +{ +} + +int SharedTexture::textureId() const +{ + updateGLTexture(); + return m_tex ? m_tex->textureId() : 0; +} + +QSize SharedTexture::textureSize() const +{ + updateGLTexture(); + return m_tex ? QSize(m_tex->width(), m_tex->height()) : QSize(); +} + +bool SharedTexture::hasAlphaChannel() const +{ + return true; +} + +bool SharedTexture::hasMipmaps() const +{ + updateGLTexture(); + return m_tex ? (m_tex->mipLevels() > 1) : false; +} + +void SharedTexture::bind() +{ + updateGLTexture(); + if (m_tex) + m_tex->bind(); +} + +inline void SharedTexture::updateGLTexture() const +{ + if (!m_tex && m_buffer) + m_tex = m_buffer->toOpenGlTexture(); +} + +class SharedTextureFactory : public QQuickTextureFactory +{ +public: + SharedTextureFactory(const QtWaylandClient::QWaylandServerBuffer *buffer, const QString &id, SharedTextureRegistry *registry) + : m_buffer(buffer), m_id(id), m_registry(registry) + { + } + + ~SharedTextureFactory() override + { + //qDebug() << "====> DESTRUCTOR SharedTextureFactory" << this; + if (m_registry) + m_registry->abandonBuffer(m_id); + delete m_buffer; // TODO: make sure we are not keeping references to this elsewhere + //qDebug() << "buffer deleted"; + } + + QSize textureSize() const override + { + return m_buffer ? m_buffer->size() : QSize(); + } + + int textureByteCount() const override + { + return m_buffer ? (m_buffer->size().width() * m_buffer->size().height() * 4) : 0; + } + + QSGTexture *createTexture(QQuickWindow *) const override + { + return new SharedTexture(const_cast<QtWaylandClient::QWaylandServerBuffer *>(m_buffer)); + } + +private: + const QtWaylandClient::QWaylandServerBuffer *m_buffer = nullptr; + QString m_id; + QPointer<SharedTextureRegistry> m_registry; +}; + + +SharedTextureRegistry::SharedTextureRegistry() + : m_extension(new TextureSharingExtension) +{ + connect(m_extension, &TextureSharingExtension::bufferReceived, this, &SharedTextureRegistry::receiveBuffer); + connect(m_extension, &TextureSharingExtension::activeChanged, this, &SharedTextureRegistry::handleExtensionActive); +} + +SharedTextureRegistry::~SharedTextureRegistry() +{ + delete m_extension; +} + +const QtWaylandClient::QWaylandServerBuffer *SharedTextureRegistry::bufferForId(const QString &id) const +{ + return m_buffers.value(id); +} + +void SharedTextureRegistry::requestBuffer(const QString &id) +{ + if (!m_extension->isActive()) { + //qDebug() << "Extension not active, adding" << id << "to queue"; + m_pendingBuffers << id; + return; + } + m_extension->requestImage(id); +} + +void SharedTextureRegistry::abandonBuffer(const QString &id) +{ + m_buffers.remove(id); + m_extension->abandonImage(id); +} + + +void SharedTextureRegistry::handleExtensionActive() +{ + //qDebug() << "handleExtensionActive, queue:" << m_pendingBuffers; + if (m_extension->isActive()) + while (!m_pendingBuffers.isEmpty()) + requestBuffer(m_pendingBuffers.takeFirst()); +} + +bool SharedTextureRegistry::preinitialize() +{ + auto *serverBufferIntegration = QGuiApplicationPrivate::platformIntegration()->nativeInterface()->nativeResourceForIntegration("server_buffer_integration"); + + if (!serverBufferIntegration) { + qWarning() << "Wayland Server Buffer Integration not available."; + return false; + } + + return true; +} + +void SharedTextureRegistry::receiveBuffer(QtWaylandClient::QWaylandServerBuffer *buffer, const QString& id) +{ + //qDebug() << "ReceiveBuffer for id" << id; + if (buffer) + m_buffers.insert(id, buffer); + emit replyReceived(id); +} + +class SharedTextureImageResponse : public QQuickImageResponse +{ + Q_OBJECT +public: + SharedTextureImageResponse(SharedTextureRegistry *registry, const QString &id) + : m_id(id), m_registry(registry) + { + if (!m_registry || m_registry->bufferForId(id)) { + // Shortcut: no server roundtrip needed, just let the event loop call the slot + QMetaObject::invokeMethod(this, "doResponse", Qt::QueuedConnection, Q_ARG(QString, id)); + + } else { + // TBD: timeout? + connect(registry, &SharedTextureRegistry::replyReceived, this, &SharedTextureImageResponse::doResponse); + registry->requestBuffer(id); + } + } + + QQuickTextureFactory *textureFactory() const override + { + if (m_registry) { + const QtWaylandClient::QWaylandServerBuffer *buffer = m_registry->bufferForId(m_id); + if (buffer) { + //qDebug() << "Creating shared buffer texture for" << m_id; + return new SharedTextureFactory(buffer, m_id, m_registry); + } + //qDebug() << "Shared buffer NOT found for" << m_id; + } + + // No shared buffer, do fallback + QString fbPath = fallbackPath(); + if (fbPath.isEmpty()) { + m_errorString = QStringLiteral("Shared buffer not found, and no fallback path set."); + return nullptr; + } + + QImageReader reader(fbPath + m_id); + QImage img = reader.read(); + if (img.isNull()) { + qWarning() << "Could not load local image from id/path" << reader.fileName(); + m_errorString = QStringLiteral("Shared buffer not found, and fallback local file loading failed: ") + reader.errorString(); + return nullptr; + } + return QQuickTextureFactory::textureFactoryForImage(img); + } + + QString errorString() const override + { + return m_errorString; + } + + static QString fallbackPath() + { + static QString fbPath; + static bool isInit = false; + if (!isInit) { + isInit = true; + QByteArray envVal = qgetenv("QT_SHAREDTEXTURE_FALLBACK_DIR"); + if (!envVal.isEmpty()) { + fbPath = QString::fromLocal8Bit(envVal); + if (!fbPath.endsWith(QLatin1Char('/'))) + fbPath.append(QLatin1Char('/')); + } + } + return fbPath; + } + + +public slots: + void doResponse(const QString &key) { + if (key != m_id) + return; // not our buffer + + // No need to be called again + if (m_registry) + disconnect(m_registry, &SharedTextureRegistry::replyReceived, this, &SharedTextureImageResponse::doResponse); + + emit finished(); + } + +private: + QString m_id; + SharedTextureRegistry *m_registry = nullptr; + mutable QString m_errorString; +}; + + +SharedTextureProvider::SharedTextureProvider() +{ + m_sharingAvailable = SharedTextureRegistry::preinitialize(); + if (!m_sharingAvailable) { + if (SharedTextureImageResponse::fallbackPath().isEmpty()) + qWarning() << "Shared buffer images not available, and no fallback directory set."; + else + qWarning() << "Shared buffer images not available, will fallback to local image files from" << SharedTextureImageResponse::fallbackPath(); + } +} + +SharedTextureProvider::~SharedTextureProvider() +{ + delete m_registry; +} + +QQuickImageResponse *SharedTextureProvider::requestImageResponse(const QString &id, const QSize &requestedSize) +{ + Q_UNUSED(requestedSize); + + //qDebug() << "Provider: got request for" << id; + + if (m_sharingAvailable && !m_registry) + m_registry = new SharedTextureRegistry; + + return new SharedTextureImageResponse(m_registry, id); +} + +QT_END_NAMESPACE + +#include "sharedtextureprovider.moc" diff --git a/src/imports/texture-sharing/sharedtextureprovider.h b/src/imports/texture-sharing/sharedtextureprovider.h new file mode 100644 index 000000000..f25c7de9c --- /dev/null +++ b/src/imports/texture-sharing/sharedtextureprovider.h @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** 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 The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SHAREDTEXTUREPROVIDER_H +#define SHAREDTEXTUREPROVIDER_H + +#include <QOpenGLFunctions> +#include <QQuickImageProvider> +#include <QtQuick/QSGTexture> +#include <QScopedPointer> +#include <QHash> + +#include <QtWaylandClient/private/qwaylandserverbufferintegration_p.h> + +QT_BEGIN_NAMESPACE + +class TextureSharingExtension; + +class SharedTextureRegistry : public QObject +{ + Q_OBJECT +public: + SharedTextureRegistry(); + ~SharedTextureRegistry() override; + + const QtWaylandClient::QWaylandServerBuffer *bufferForId(const QString &id) const; + void requestBuffer(const QString &id); + void abandonBuffer(const QString &id); + + static bool preinitialize(); + +public slots: + void receiveBuffer(QtWaylandClient::QWaylandServerBuffer *buffer, const QString &id); + +signals: + void replyReceived(const QString &id); + +private slots: + void handleExtensionActive(); + +private: + TextureSharingExtension *m_extension = nullptr; + QHash<QString, QtWaylandClient::QWaylandServerBuffer *> m_buffers; + QStringList m_pendingBuffers; +}; + +class SharedTextureProvider : public QQuickAsyncImageProvider +{ +public: + SharedTextureProvider(); + ~SharedTextureProvider() override; + + QQuickImageResponse *requestImageResponse(const QString &id, const QSize &requestedSize) override; + +private: + SharedTextureRegistry *m_registry = nullptr; + bool m_sharingAvailable = false; +}; + +class SharedTexture : public QSGTexture +{ + Q_OBJECT +public: + SharedTexture(QtWaylandClient::QWaylandServerBuffer *buffer); + + int textureId() const override; + QSize textureSize() const override; + bool hasAlphaChannel() const override; + bool hasMipmaps() const override; + + void bind() override; + +private: + void updateGLTexture() const; + QtWaylandClient::QWaylandServerBuffer *m_buffer = nullptr; + mutable QOpenGLTexture *m_tex = nullptr; +}; + + +QT_END_NAMESPACE + +#endif // SHAREDTEXTUREPROVIDER_H diff --git a/src/imports/texture-sharing/texture-sharing.pro b/src/imports/texture-sharing/texture-sharing.pro new file mode 100644 index 000000000..bec769ecb --- /dev/null +++ b/src/imports/texture-sharing/texture-sharing.pro @@ -0,0 +1,21 @@ +CXX_MODULE = qml +TARGET = qwaylandtexturesharing +TARGETPATH = QtWayland/Client/TextureSharing +IMPORT_VERSION = 1.$$QT_MINOR_VERSION + +HEADERS += \ + sharedtextureprovider.h \ + texturesharingextension.h + +SOURCES += \ + plugin.cpp \ + sharedtextureprovider.cpp \ + texturesharingextension.cpp + +QT += quick-private qml gui-private core-private waylandclient waylandclient-private +CONFIG += wayland-scanner + +WAYLANDCLIENTSOURCES += ../../extensions/qt-texture-sharing-unstable-v1.xml + + +load(qml_plugin) diff --git a/src/imports/texture-sharing/texturesharingextension.cpp b/src/imports/texture-sharing/texturesharingextension.cpp new file mode 100644 index 000000000..31106d694 --- /dev/null +++ b/src/imports/texture-sharing/texturesharingextension.cpp @@ -0,0 +1,86 @@ + +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** 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 The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "texturesharingextension.h" +#include <QtWaylandClient/private/qwaylanddisplay_p.h> +#include <QtWaylandClient/private/qwaylandintegration_p.h> +#include <QtWaylandClient/private/qwaylandserverbufferintegration_p.h> +#include <QtGui/QGuiApplication> +#include <QtGui/private/qguiapplication_p.h> +#include <QtGui/QWindow> +#include <QtGui/QPlatformSurfaceEvent> +#include <QtGui/qpa/qplatformnativeinterface.h> +#include <QDebug> + +QT_BEGIN_NAMESPACE + +TextureSharingExtension::TextureSharingExtension() + : QWaylandClientExtensionTemplate(/* Supported protocol version */ 1 ) +{ + auto *wayland_integration = static_cast<QtWaylandClient::QWaylandIntegration *>(QGuiApplicationPrivate::platformIntegration()); + m_server_buffer_integration = wayland_integration->serverBufferIntegration(); + if (!m_server_buffer_integration) { + qCritical() << "This application requires a working serverBufferIntegration"; + QGuiApplication::quit(); + } +} + +void TextureSharingExtension::zqt_texture_sharing_v1_provide_buffer(struct ::qt_server_buffer *buffer, const QString &key) +{ + QtWaylandClient::QWaylandServerBuffer *serverBuffer = m_server_buffer_integration->serverBuffer(buffer); + emit bufferReceived(serverBuffer, key); +} + +void TextureSharingExtension::zqt_texture_sharing_v1_image_failed(const QString &key, const QString &message) +{ + qWarning() << "TextureSharingExtension" << key << "not found" << message; + emit bufferReceived(nullptr, key); +} +void TextureSharingExtension::requestImage(const QString &key) +{ + request_image(key); +} + +void TextureSharingExtension::abandonImage(const QString &key) +{ + abandon_image(key); +} + +QT_END_NAMESPACE diff --git a/src/imports/texture-sharing/texturesharingextension.h b/src/imports/texture-sharing/texturesharingextension.h new file mode 100644 index 000000000..7b864fbc8 --- /dev/null +++ b/src/imports/texture-sharing/texturesharingextension.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** 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 The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef TEXTURESHARINGEXTENSION_H +#define TEXTURESHARINGEXTENSION_H + +#include <qpa/qwindowsysteminterface.h> +#include <QtWaylandClient/private/qwayland-wayland.h> +#include <QtWaylandClient/qwaylandclientextension.h> +#include "qwayland-qt-texture-sharing-unstable-v1.h" + +QT_BEGIN_NAMESPACE + +namespace QtWaylandClient { + class QWaylandServerBuffer; + class QWaylandServerBufferIntegration; +}; + +class TextureSharingExtension : public QWaylandClientExtensionTemplate<TextureSharingExtension> + , public QtWayland::zqt_texture_sharing_v1 +{ + Q_OBJECT +public: + TextureSharingExtension(); + +public slots: + void requestImage(const QString &key); + void abandonImage(const QString &key); + +signals: + void bufferReceived(QtWaylandClient::QWaylandServerBuffer *buffer, const QString &key); + +private: + void zqt_texture_sharing_v1_provide_buffer(struct ::qt_server_buffer *buffer, const QString &key) override; + void zqt_texture_sharing_v1_image_failed(const QString &key, const QString &message) override; + QtWaylandClient::QWaylandServerBufferIntegration *m_server_buffer_integration = nullptr; +}; + +QT_END_NAMESPACE + +#endif // TEXTURESHARINGEXTENSION_H |