aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2019-08-29 14:20:39 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2019-08-30 12:53:54 +0200
commita6323d1ad8ad7af585ed76a5a3a97a48e955ff91 (patch)
tree2cb4f43469df538b6b737660b95a61c47988d61a /src
parentcefab21cbd464171f0f90de9ac12c6174ecd7d59 (diff)
Add a createTextureFromId() alternative
Say hello to createTextureFromNativeObject(). This is the future replaecment for createTextureFromId(), and is capable of operating on both the direct OpenGL and the RHI code paths. In practice this allows creating a QSGTexture that wraps - but does not own - an existing VkImage, ID3D11Texture2D*, MTLTexture*, or GLuint. Change-Id: I500ee4c76da67eca1a70599a30b03d7b126b570d Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/quick/items/qquickwindow.cpp116
-rw-r--r--src/quick/items/qquickwindow.h10
-rw-r--r--src/quick/scenegraph/scenegraph.pri2
-rw-r--r--src/quick/scenegraph/util/qsgplaintexture.cpp19
-rw-r--r--src/quick/scenegraph/util/qsgplaintexture_p.h4
-rw-r--r--src/quick/scenegraph/util/qsgrhinativetextureimporter.cpp104
-rw-r--r--src/quick/scenegraph/util/qsgrhinativetextureimporter_p.h70
7 files changed, 318 insertions, 7 deletions
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 8b5e2a012a..27e2a4572e 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -4450,7 +4450,8 @@ QSGTexture *QQuickWindow::createTextureFromImage(const QImage &image, CreateText
\note This function only has an effect when using the default OpenGL scene graph
adaptation.
- \note This function has no effect when running on the RHI graphics abstraction.
+ \note This function has no effect when running on the RHI graphics
+ abstraction. Use createTextureFromNativeObject() instead.
\sa sceneGraphInitialized(), QSGTexture
*/
@@ -4458,19 +4459,120 @@ QSGTexture *QQuickWindow::createTextureFromId(uint id, const QSize &size, Create
{
#if QT_CONFIG(opengl)
Q_D(const QQuickWindow);
- if (!d->rhi && openglContext()) {
- QSGPlainTexture *texture = new QSGPlainTexture();
- texture->setTextureId(id);
+ if (!d->rhi) {
+ if (openglContext()) {
+ QSGPlainTexture *texture = new QSGPlainTexture();
+ texture->setTextureId(id);
+ texture->setHasAlphaChannel(options & TextureHasAlphaChannel);
+ texture->setOwnsTexture(options & TextureOwnsGLTexture);
+ texture->setTextureSize(size);
+ return texture;
+ }
+ } else {
+ qWarning("createTextureFromId() must not be called when running on the RHI. "
+ "Use createTextureFromNativeObject() instead.");
+ }
+#else
+ Q_UNUSED(id)
+ Q_UNUSED(size)
+ Q_UNUSED(options)
+#endif
+ return nullptr;
+}
+
+/*!
+ \enum QQuickWindow::NativeObjectType
+ \since 5.14
+
+ Specifies the type of the native object passed to functions such as
+ createTextureFromNativeObject().
+
+ \value NativeObjectTexture The native object is a 2D texture (OpenGL,
+ Direct3D 11, Metal) or image (Vulkan).
+ */
+
+/*!
+ Creates a new QSGTexture object from an existing native object.
+
+ The native object is wrapped, but not owned, by the resulting QSGTexture.
+ The caller of the function is responsible for deleting the returned
+ QSGTexture, but that will not destroy the underlying native object.
+
+ \a type specifies the type of the object. In practice the type is
+ NativeObjectTexture, indicating that the native object is a texture or
+ image of the underlying graphics API. Other types may be introduced in the
+ future.
+
+ This function is currently suitable for 2D RGBA textures only.
+
+ Unlike createTextureFromId(), this function supports both direct OpenGL
+ usage and the RHI abstracted rendering path.
+
+ \warning This function will return null if the scenegraph has not yet been
+ initialized.
+
+ Use \a options to customize the texture attributes. Only the
+ TextureHasAlphaChannel and TextureHasMipmaps are taken into account here.
+
+ \warning Unlike createTextureFromId(), this function never takes ownership
+ of the native object, and the TextureOwnsGLTexture flag is ignored.
+
+ \a size specifies the size in pixels.
+
+ \a nativeObjectPtr is a pointer to the native object handle. With OpenGL,
+ the native handle is a GLuint value, so \a nativeObjectPtr is then a
+ pointer to a GLuint. With Vulkan, the native handle is a VkImage, so \a
+ nativeObjectPtr is a pointer to a VkImage. With Direct3D 11 and Metal \a
+ nativeObjectPtr is a pointer to a ID3D11Texture2D or MTLTexture pointer.
+
+ \note Pay attention to the fact that \a nativeObjectPtr is always a pointer
+ to the native texture handle type, even if the native type itself is a
+ pointer.
+
+ \a nativeLayout is only used for APIs like Vulkan. When applicable, it must
+ specify the current image layout, such as, a VkImageLayout value.
+
+ \sa sceneGraphInitialized(), QSGTextures
+
+ \since 5.14
+ */
+QSGTexture *QQuickWindow::createTextureFromNativeObject(NativeObjectType type,
+ const void *nativeObjectPtr,
+ int nativeLayout,
+ const QSize &size,
+ CreateTextureOptions options) const
+{
+ if (type != NativeObjectTexture) {
+ qWarning("createTextureFromNativeObject: only textures are supported");
+ return nullptr;
+ }
+
+#if QT_CONFIG(opengl) /* || QT_CONFIG(vulkan) || defined(Q_OS_WIN) || defined(Q_OS_DARWIN) */
+ Q_D(const QQuickWindow);
+ if (d->rhi) {
+ QSGPlainTexture *texture = new QSGPlainTexture;
+ texture->setTextureFromNativeObject(d->rhi, type, nativeObjectPtr, nativeLayout,
+ size, options.testFlag(TextureHasMipmaps));
+ texture->setHasAlphaChannel(options & TextureHasAlphaChannel);
+ // note that the QRhiTexture does not (and cannot) own the native object
+ texture->setOwnsTexture(true); // texture meaning the QRhiTexture here, not the native object
+ texture->setTextureSize(size);
+ return texture;
+ } else if (openglContext()) {
+ QSGPlainTexture *texture = new QSGPlainTexture;
+ texture->setTextureId(*reinterpret_cast<const uint *>(nativeObjectPtr));
texture->setHasAlphaChannel(options & TextureHasAlphaChannel);
texture->setOwnsTexture(options & TextureOwnsGLTexture);
texture->setTextureSize(size);
return texture;
}
#else
- Q_UNUSED(id)
- Q_UNUSED(size)
- Q_UNUSED(options)
+ Q_UNUSED(nativeObjectPtr);
+ Q_UNUSED(nativeLayout);
+ Q_UNUSED(size);
+ Q_UNUSED(options);
#endif
+
return nullptr;
}
diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h
index ab3046611f..9dbff88f0d 100644
--- a/src/quick/items/qquickwindow.h
+++ b/src/quick/items/qquickwindow.h
@@ -109,6 +109,11 @@ public:
};
Q_ENUM(TextRenderType)
+ enum NativeObjectType {
+ NativeObjectTexture
+ };
+ Q_ENUM(NativeObjectType)
+
explicit QQuickWindow(QWindow *parent = nullptr);
explicit QQuickWindow(QQuickRenderControl *renderControl);
@@ -153,6 +158,11 @@ public:
QSGTexture *createTextureFromImage(const QImage &image) const;
QSGTexture *createTextureFromImage(const QImage &image, CreateTextureOptions options) const;
QSGTexture *createTextureFromId(uint id, const QSize &size, CreateTextureOptions options = CreateTextureOption()) const;
+ QSGTexture *createTextureFromNativeObject(NativeObjectType type,
+ const void *nativeObjectPtr,
+ int nativeLayout,
+ const QSize &size,
+ CreateTextureOptions options = CreateTextureOption()) const;
void setClearBeforeRendering(bool enabled);
bool clearBeforeRendering() const;
diff --git a/src/quick/scenegraph/scenegraph.pri b/src/quick/scenegraph/scenegraph.pri
index ee9ea0f5ed..c345f3b16d 100644
--- a/src/quick/scenegraph/scenegraph.pri
+++ b/src/quick/scenegraph/scenegraph.pri
@@ -53,6 +53,7 @@ HEADERS += \
$$PWD/util/qsgengine.h \
$$PWD/util/qsgengine_p.h \
$$PWD/util/qsgplaintexture_p.h \
+ $$PWD/util/qsgrhinativetextureimporter_p.h \
$$PWD/util/qsgsimplerectnode.h \
$$PWD/util/qsgsimpletexturenode.h \
$$PWD/util/qsgtextureprovider.h \
@@ -69,6 +70,7 @@ SOURCES += \
$$PWD/util/qsgareaallocator.cpp \
$$PWD/util/qsgengine.cpp \
$$PWD/util/qsgplaintexture.cpp \
+ $$PWD/util/qsgrhinativetextureimporter.cpp \
$$PWD/util/qsgsimplerectnode.cpp \
$$PWD/util/qsgsimpletexturenode.cpp \
$$PWD/util/qsgtextureprovider.cpp \
diff --git a/src/quick/scenegraph/util/qsgplaintexture.cpp b/src/quick/scenegraph/util/qsgplaintexture.cpp
index 72313db836..fdebe03494 100644
--- a/src/quick/scenegraph/util/qsgplaintexture.cpp
+++ b/src/quick/scenegraph/util/qsgplaintexture.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include "qsgplaintexture_p.h"
+#include "qsgrhinativetextureimporter_p.h"
#include <QtQuick/private/qsgcontext_p.h>
#include <qmath.h>
#include <private/qquickprofiler_p.h>
@@ -274,6 +275,24 @@ void QSGPlainTexture::setTexture(QRhiTexture *texture) // RHI only
m_mipmaps_generated = false;
}
+void QSGPlainTexture::setTextureFromNativeObject(QRhi *rhi, QQuickWindow::NativeObjectType type,
+ const void *nativeObjectPtr, int nativeLayout,
+ const QSize &size, bool mipmap)
+{
+ Q_UNUSED(type);
+
+ QRhiTexture::Flags flags = 0;
+ if (mipmap)
+ flags |= QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips;
+
+ QRhiTexture *t = rhi->newTexture(QRhiTexture::RGBA8, size, 1, flags);
+
+ // ownership of the native object is never taken
+ QSGRhiNativeTextureImporter::buildWrapper(rhi, t, nativeObjectPtr, nativeLayout);
+
+ setTexture(t);
+}
+
int QSGPlainTexturePrivate::comparisonKey() const
{
Q_Q(const QSGPlainTexture);
diff --git a/src/quick/scenegraph/util/qsgplaintexture_p.h b/src/quick/scenegraph/util/qsgplaintexture_p.h
index 69c0153f9a..1eb0b59d2e 100644
--- a/src/quick/scenegraph/util/qsgplaintexture_p.h
+++ b/src/quick/scenegraph/util/qsgplaintexture_p.h
@@ -53,6 +53,7 @@
#include <QtQuick/private/qtquickglobal_p.h>
#include <QtQuick/private/qsgtexture_p.h>
+#include <QtQuick/qquickwindow.h>
QT_BEGIN_NAMESPACE
@@ -85,6 +86,9 @@ public:
void bind() override;
void setTexture(QRhiTexture *texture);
+ void setTextureFromNativeObject(QRhi *rhi, QQuickWindow::NativeObjectType type,
+ const void *nativeObjectPtr, int nativeLayout,
+ const QSize &size, bool mipmap);
static QSGPlainTexture *fromImage(const QImage &image) {
QSGPlainTexture *t = new QSGPlainTexture();
diff --git a/src/quick/scenegraph/util/qsgrhinativetextureimporter.cpp b/src/quick/scenegraph/util/qsgrhinativetextureimporter.cpp
new file mode 100644
index 0000000000..7a7c19f587
--- /dev/null
+++ b/src/quick/scenegraph/util/qsgrhinativetextureimporter.cpp
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick 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 "qsgrhinativetextureimporter_p.h"
+#include <private/qsgrhisupport_p.h> // to get all the relevant qrhi headers
+
+QT_BEGIN_NAMESPACE
+
+void QSGRhiNativeTextureImporter::buildWrapper(QRhi *rhi, QRhiTexture *t,
+ const void *nativeObjectPtr, int nativeLayout)
+{
+#if !QT_CONFIG(vulkan)
+ Q_UNUSED(nativeLayout);
+#endif
+#if !QT_CONFIG(opengl) && !QT_CONFIG(vulkan) && !defined(Q_OS_WIN) && !defined(Q_OS_DARWIN)
+ Q_UNUSED(nativeObjectPtr);
+#endif
+
+ switch (rhi->backend()) {
+ case QRhi::OpenGLES2:
+ {
+#if QT_CONFIG(opengl)
+ QRhiGles2TextureNativeHandles h;
+ h.texture = *reinterpret_cast<const uint *>(nativeObjectPtr);
+ t->buildFrom(&h);
+#endif
+ }
+ break;
+ case QRhi::Vulkan:
+ {
+#if QT_CONFIG(vulkan)
+ QRhiVulkanTextureNativeHandles h;
+ h.image = *reinterpret_cast<const VkImage *>(nativeObjectPtr);
+ h.layout = VkImageLayout(nativeLayout);
+ t->buildFrom(&h);
+#endif
+ }
+ break;
+ case QRhi::D3D11:
+ {
+#ifdef Q_OS_WIN
+ QRhiD3D11TextureNativeHandles h;
+ h.texture = *reinterpret_cast<void * const *>(nativeObjectPtr);
+ t->buildFrom(&h);
+#endif
+ }
+ break;
+ case QRhi::Metal:
+ {
+#ifdef Q_OS_DARWIN
+ QRhiMetalTextureNativeHandles h;
+ h.texture = *reinterpret_cast<void * const *>(nativeObjectPtr);
+ t->buildFrom(&h);
+#endif
+ }
+ break;
+ case QRhi::Null:
+ t->build();
+ break;
+ default:
+ qWarning("QSGRhiNativeTextureImporter: encountered an unsupported QRhi backend (%d)",
+ int(rhi->backend()));
+ t->build();
+ break;
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/util/qsgrhinativetextureimporter_p.h b/src/quick/scenegraph/util/qsgrhinativetextureimporter_p.h
new file mode 100644
index 0000000000..e811109a94
--- /dev/null
+++ b/src/quick/scenegraph/util/qsgrhinativetextureimporter_p.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick 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$
+**
+****************************************************************************/
+
+#ifndef QSGRHINATIVETEXTUREIMPORTER_P_H
+#define QSGRHINATIVETEXTUREIMPORTER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtQuick/private/qtquickglobal_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QRhi;
+class QRhiTexture;
+
+class QSGRhiNativeTextureImporter
+{
+public:
+ static void buildWrapper(QRhi *rhi, QRhiTexture *t,
+ const void *nativeObjectPtr, int nativeLayout);
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGRHINATIVETEXTUREIMPORTER_P_H