diff options
-rw-r--r-- | examples/quick/rendercontrol/rendercontrol_d3d11/window.cpp | 6 | ||||
-rw-r--r-- | examples/quick/rendercontrol/rendercontrol_opengl/window_singlethreaded.cpp | 2 | ||||
-rw-r--r-- | src/quick/items/qquickrendertarget.cpp | 149 | ||||
-rw-r--r-- | src/quick/items/qquickrendertarget.h | 27 | ||||
-rw-r--r-- | src/quick/items/qquickrendertarget_p.h | 6 | ||||
-rw-r--r-- | src/quickwidgets/qquickwidget.cpp | 2 | ||||
-rw-r--r-- | tests/auto/quick/qquickrendercontrol/tst_qquickrendercontrol.cpp | 5 |
7 files changed, 172 insertions, 25 deletions
diff --git a/examples/quick/rendercontrol/rendercontrol_d3d11/window.cpp b/examples/quick/rendercontrol/rendercontrol_d3d11/window.cpp index c574343a98..884f7e3981 100644 --- a/examples/quick/rendercontrol/rendercontrol_d3d11/window.cpp +++ b/examples/quick/rendercontrol/rendercontrol_d3d11/window.cpp @@ -368,9 +368,9 @@ void Window::updateQuick() qWarning("Failed to initialize redirected Qt Quick rendering"); // Redirect Qt Quick's output. - m_quickWindow->setRenderTarget(QQuickRenderTarget::fromNativeTexture({ quint64(m_res.texture), 0 }, - QSize(QML_WIDTH, QML_HEIGHT), - SAMPLE_COUNT)); + m_quickWindow->setRenderTarget(QQuickRenderTarget::fromD3D11Texture(m_res.texture, + QSize(QML_WIDTH, QML_HEIGHT), + SAMPLE_COUNT)); m_quickInitialized = true; } diff --git a/examples/quick/rendercontrol/rendercontrol_opengl/window_singlethreaded.cpp b/examples/quick/rendercontrol/rendercontrol_opengl/window_singlethreaded.cpp index 0d29a155dd..8f3bfe77db 100644 --- a/examples/quick/rendercontrol/rendercontrol_opengl/window_singlethreaded.cpp +++ b/examples/quick/rendercontrol/rendercontrol_opengl/window_singlethreaded.cpp @@ -182,7 +182,7 @@ void WindowSingleThreaded::createTexture() f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); f->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_textureSize.width(), m_textureSize.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); - m_quickWindow->setRenderTarget(QQuickRenderTarget::fromNativeTexture({ quint64(m_textureId), 0 }, m_textureSize)); + m_quickWindow->setRenderTarget(QQuickRenderTarget::fromOpenGLTexture(m_textureId, m_textureSize)); } void WindowSingleThreaded::destroyTexture() diff --git a/src/quick/items/qquickrendertarget.cpp b/src/quick/items/qquickrendertarget.cpp index b4b8154f74..bdaee055a8 100644 --- a/src/quick/items/qquickrendertarget.cpp +++ b/src/quick/items/qquickrendertarget.cpp @@ -123,15 +123,138 @@ bool QQuickRenderTarget::isNull() const } /*! - \return a new QQuickRenderTarget referencing a native texture or image - object. + \return a new QQuickRenderTarget referencing an OpenGL texture object + specified by \a textureId. - \a nativeTexture references a native resource, for example, a \c VkImage, - \c ID3D11Texture2D*, c MTLTexture*, or \c GLuint. Where applicable, this - must be complemented by the current layout of the image. + \a pixelSize specifies the size of the image, in pixels. Currently only 2D + textures are supported. + + \a sampleCount specific the number of samples. 0 or 1 means no + multisampling, while a value like 4 or 8 states that the native object is a + multisample texture. + + \note the resulting QQuickRenderTarget does not own any native resources, + it merely contains references and the associated metadata of the size and + sample count. It is the caller's responsibility to ensure that the native + resource exists as long as necessary. + + \sa QQuickWindow::setRenderTarget(), QQuickRenderControl + */ +#if QT_CONFIG(opengl) || defined(Q_CLANG_QDOC) +QQuickRenderTarget QQuickRenderTarget::fromOpenGLTexture(uint textureId, const QSize &pixelSize, int sampleCount) +{ + QQuickRenderTarget rt; + QQuickRenderTargetPrivate *d = QQuickRenderTargetPrivate::get(&rt); + + if (!textureId) { + qWarning("QQuickRenderTarget: textureId is invalid"); + return rt; + } + + if (pixelSize.isEmpty()) { + qWarning("QQuickRenderTarget: Cannot create with empty size"); + return rt; + } + + d->type = QQuickRenderTargetPrivate::Type::NativeTexture; + d->pixelSize = pixelSize; + d->sampleCount = qMax(1, sampleCount); + d->u.nativeTexture = { textureId, 0 }; + + return rt; +} +#endif + +/*! + \return a new QQuickRenderTarget referencing an D3D11 texture object + specified by \a texture. + + \a pixelSize specifies the size of the image, in pixels. Currently only 2D + textures are supported. + + \a sampleCount specific the number of samples. 0 or 1 means no + multisampling, while a value like 4 or 8 states that the native object is a + multisample texture. + + \note the resulting QQuickRenderTarget does not own any native resources, + it merely contains references and the associated metadata of the size and + sample count. It is the caller's responsibility to ensure that the native + resource exists as long as necessary. + + \sa QQuickWindow::setRenderTarget(), QQuickRenderControl + */ +#if defined(Q_OS_WIN) || defined(Q_CLANG_QDOC) +QQuickRenderTarget QQuickRenderTarget::fromD3D11Texture(void *texture, const QSize &pixelSize, int sampleCount) +{ + QQuickRenderTarget rt; + QQuickRenderTargetPrivate *d = QQuickRenderTargetPrivate::get(&rt); - \note the \c object field in \a nativeTexture must always be a pointer to - the native object, even if the type is already a pointer. + if (!texture) { + qWarning("QQuickRenderTarget: texture is null"); + return rt; + } + + if (pixelSize.isEmpty()) { + qWarning("QQuickRenderTarget: Cannot create with empty size"); + return rt; + } + + d->type = QQuickRenderTargetPrivate::Type::NativeTexture; + d->pixelSize = pixelSize; + d->sampleCount = qMax(1, sampleCount); + d->u.nativeTexture = { quint64(texture), 0 }; + + return rt; +} +#endif + +/*! + \return a new QQuickRenderTarget referencing an Metal texture object + specified by \a texture. + + \a pixelSize specifies the size of the image, in pixels. Currently only 2D + textures are supported. + + \a sampleCount specific the number of samples. 0 or 1 means no + multisampling, while a value like 4 or 8 states that the native object is a + multisample texture. + + \note the resulting QQuickRenderTarget does not own any native resources, + it merely contains references and the associated metadata of the size and + sample count. It is the caller's responsibility to ensure that the native + resource exists as long as necessary. + + \sa QQuickWindow::setRenderTarget(), QQuickRenderControl + */ +#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) || defined(Q_CLANG_QDOC) +QQuickRenderTarget QQuickRenderTarget::fromMetalTexture(MTLTexture *texture, const QSize &pixelSize, int sampleCount) +{ + QQuickRenderTarget rt; + QQuickRenderTargetPrivate *d = QQuickRenderTargetPrivate::get(&rt); + + if (!texture) { + qWarning("QQuickRenderTarget: texture is null"); + return rt; + } + + if (pixelSize.isEmpty()) { + qWarning("QQuickRenderTarget: Cannot create with empty size"); + return rt; + } + + d->type = QQuickRenderTargetPrivate::Type::NativeTexture; + d->pixelSize = pixelSize; + d->sampleCount = qMax(1, sampleCount); + d->u.nativeTexture = { quint64(texture), 0 }; + + return rt; +} +#endif + +/*! + \return a new QQuickRenderTarget referencing an Vulkan image object + specified by \a image. The current \a layout of the image must be provided + as well. \a pixelSize specifies the size of the image, in pixels. Currently only 2D textures are supported. @@ -147,15 +270,14 @@ bool QQuickRenderTarget::isNull() const \sa QQuickWindow::setRenderTarget(), QQuickRenderControl */ -QQuickRenderTarget QQuickRenderTarget::fromNativeTexture(const QSGTexture::NativeTexture &nativeTexture, - const QSize &pixelSize, - int sampleCount) +#if QT_CONFIG(vulkan) || defined(Q_CLANG_QDOC) +QQuickRenderTarget QQuickRenderTarget::fromVulkanImage(VkImage image, VkImageLayout layout, const QSize &pixelSize, int sampleCount) { QQuickRenderTarget rt; QQuickRenderTargetPrivate *d = QQuickRenderTargetPrivate::get(&rt); - if (!nativeTexture.object) { - qWarning("QQuickRenderTarget: nativeTexture.object is null"); + if (image == VK_NULL_HANDLE) { + qWarning("QQuickRenderTarget: image is invalid"); return rt; } @@ -167,10 +289,11 @@ QQuickRenderTarget QQuickRenderTarget::fromNativeTexture(const QSGTexture::Nativ d->type = QQuickRenderTargetPrivate::Type::NativeTexture; d->pixelSize = pixelSize; d->sampleCount = qMax(1, sampleCount); - d->u.nativeTexture = nativeTexture; + d->u.nativeTexture = { quint64(image), layout }; return rt; } +#endif /*! \internal diff --git a/src/quick/items/qquickrendertarget.h b/src/quick/items/qquickrendertarget.h index 5139046ad4..a40df626d1 100644 --- a/src/quick/items/qquickrendertarget.h +++ b/src/quick/items/qquickrendertarget.h @@ -41,7 +41,14 @@ #define QQUICKRENDERTARGET_H #include <QtQuick/qtquickglobal.h> -#include <QtQuick/qsgtexture.h> + +#if QT_CONFIG(vulkan) +#include <QtGui/QVulkanInstance> +#endif + +#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) +Q_FORWARD_DECLARE_OBJC_CLASS(MTLTexture); +#endif QT_BEGIN_NAMESPACE @@ -58,9 +65,21 @@ public: bool isNull() const; - static QQuickRenderTarget fromNativeTexture(const QSGTexture::NativeTexture &nativeTexture, - const QSize &pixelSize, - int sampleCount = 1); +#if QT_CONFIG(opengl) || defined(Q_CLANG_QDOC) + static QQuickRenderTarget fromOpenGLTexture(uint textureId, const QSize &pixelSize, int sampleCount = 1); +#endif + +#if defined(Q_OS_WIN) || defined(Q_CLANG_QDOC) + static QQuickRenderTarget fromD3D11Texture(void *texture, const QSize &pixelSize, int sampleCount = 1); +#endif + +#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) || defined(Q_CLANG_QDOC) + static QQuickRenderTarget fromMetalTexture(MTLTexture *texture, const QSize &pixelSize, int sampleCount = 1); +#endif + +#if QT_CONFIG(vulkan) || defined(Q_CLANG_QDOC) + static QQuickRenderTarget fromVulkanImage(VkImage image, VkImageLayout layout, const QSize &pixelSize, int sampleCount = 1); +#endif static QQuickRenderTarget fromRhiRenderTarget(QRhiRenderTarget *renderTarget); diff --git a/src/quick/items/qquickrendertarget_p.h b/src/quick/items/qquickrendertarget_p.h index 628e5c277b..173cb699b6 100644 --- a/src/quick/items/qquickrendertarget_p.h +++ b/src/quick/items/qquickrendertarget_p.h @@ -79,8 +79,12 @@ public: Type type = Type::Null; QSize pixelSize; int sampleCount = 1; + struct NativeTexture { + quint64 object; + int layout; + }; union { - QSGTexture::NativeTexture nativeTexture; + NativeTexture nativeTexture; QRhiRenderTarget *rhiRt; } u; }; diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp index 04c321d0a5..ed0210629d 100644 --- a/src/quickwidgets/qquickwidget.cpp +++ b/src/quickwidgets/qquickwidget.cpp @@ -1077,7 +1077,7 @@ void QQuickWidget::createFramebufferObject() #endif GLuint textureId = d->fbo->texture(); - d->offscreenWindow->setRenderTarget( QQuickRenderTarget::fromNativeTexture({ textureId, 0 }, fboSize, samples)); + d->offscreenWindow->setRenderTarget( QQuickRenderTarget::fromOpenGLTexture(textureId, fboSize, samples)); d->renderControl->setSamples(samples); diff --git a/tests/auto/quick/qquickrendercontrol/tst_qquickrendercontrol.cpp b/tests/auto/quick/qquickrendercontrol/tst_qquickrendercontrol.cpp index a2217f5427..d81c40f5b6 100644 --- a/tests/auto/quick/qquickrendercontrol/tst_qquickrendercontrol.cpp +++ b/tests/auto/quick/qquickrendercontrol/tst_qquickrendercontrol.cpp @@ -487,8 +487,9 @@ void tst_RenderControl::renderAndReadBackWithVulkanNative() QCOMPARE(err, VK_SUCCESS); // Tell Qt Quick to target our VkImage. - quickWindow->setRenderTarget(QQuickRenderTarget::fromNativeTexture({ quint64(img), VK_IMAGE_LAYOUT_PREINITIALIZED }, - rootItem->size().toSize())); + quickWindow->setRenderTarget(QQuickRenderTarget::fromVulkanImage(img, + VK_IMAGE_LAYOUT_PREINITIALIZED, + rootItem->size().toSize())); // Create a readback buffer. VkBuffer buf = VK_NULL_HANDLE; |