diff options
21 files changed, 643 insertions, 164 deletions
diff --git a/examples/quick/scenegraph/metaltextureimport/metaltextureimport.mm b/examples/quick/scenegraph/metaltextureimport/metaltextureimport.mm index e676ff2e5e..fa55a95ffd 100644 --- a/examples/quick/scenegraph/metaltextureimport/metaltextureimport.mm +++ b/examples/quick/scenegraph/metaltextureimport/metaltextureimport.mm @@ -263,10 +263,7 @@ void CustomTextureNode::sync() m_texture = [m_device newTextureWithDescriptor: desc]; [desc release]; - QSGTexture *wrapper = m_window->createTextureFromNativeObject(QQuickWindow::NativeObjectTexture, - quint64(m_texture), - 0, - m_size); + QSGTexture *wrapper = QPlatformInterface::QSGMetalTexture::fromNative((MTLTexture *) m_texture, m_window, m_size); qDebug() << "Got QSGTexture wrapper" << wrapper << "for an MTLTexture of size" << m_size; diff --git a/examples/quick/scenegraph/vulkantextureimport/vulkantextureimport.cpp b/examples/quick/scenegraph/vulkantextureimport/vulkantextureimport.cpp index 72833df7f5..cb56f3aabf 100644 --- a/examples/quick/scenegraph/vulkantextureimport/vulkantextureimport.cpp +++ b/examples/quick/scenegraph/vulkantextureimport/vulkantextureimport.cpp @@ -716,11 +716,12 @@ void CustomTextureNode::sync() delete texture(); freeTexture(); buildTexture(m_size); - QSGTexture *wrapper = m_window->createTextureFromNativeObject(QQuickWindow::NativeObjectTexture, - quint64(m_texture), - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - m_size); + QSGTexture *wrapper = QPlatformInterface::QSGVulkanTexture::fromNative(m_texture, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + m_window, + m_size); setTexture(wrapper); + Q_ASSERT(wrapper->platformInterface<QPlatformInterface::QSGVulkanTexture>()->nativeImage() == m_texture); } m_t = float(static_cast<CustomTextureItem *>(m_item)->t()); diff --git a/src/quick/.prev_CMakeLists.txt b/src/quick/.prev_CMakeLists.txt index 2774d1cb15..0faa2397ff 100644 --- a/src/quick/.prev_CMakeLists.txt +++ b/src/quick/.prev_CMakeLists.txt @@ -123,6 +123,7 @@ qt_add_module(Quick scenegraph/coreapi/qsgrendernode.cpp scenegraph/coreapi/qsgrendernode.h scenegraph/coreapi/qsgrendernode_p.h scenegraph/coreapi/qsgrhivisualizer.cpp scenegraph/coreapi/qsgrhivisualizer_p.h scenegraph/coreapi/qsgtexture.cpp scenegraph/coreapi/qsgtexture.h scenegraph/coreapi/qsgtexture_p.h + scenegraph/coreapi/qsgtexture_platform.h scenegraph/qsgadaptationlayer.cpp scenegraph/qsgadaptationlayer_p.h scenegraph/qsgbasicglyphnode.cpp scenegraph/qsgbasicglyphnode_p.h scenegraph/qsgbasicinternalimagenode.cpp scenegraph/qsgbasicinternalimagenode_p.h @@ -398,6 +399,11 @@ qt_extend_target(Quick CONDITION QT_FEATURE_opengl OR QT_FEATURE_opengles2 OR QT util/qquickopenglutils.cpp util/qquickopenglutils.h ) +qt_extend_target(Quick CONDITION IOS OR MACOS + SOURCES + scenegraph/coreapi/qsgtexture_mac.mm +) + qt_extend_target(Quick CONDITION QT_FEATURE_thread SOURCES scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop_p.h diff --git a/src/quick/CMakeLists.txt b/src/quick/CMakeLists.txt index 74c1600a40..412f13e808 100644 --- a/src/quick/CMakeLists.txt +++ b/src/quick/CMakeLists.txt @@ -123,6 +123,7 @@ qt_add_module(Quick scenegraph/coreapi/qsgrendernode.cpp scenegraph/coreapi/qsgrendernode.h scenegraph/coreapi/qsgrendernode_p.h scenegraph/coreapi/qsgrhivisualizer.cpp scenegraph/coreapi/qsgrhivisualizer_p.h scenegraph/coreapi/qsgtexture.cpp scenegraph/coreapi/qsgtexture.h scenegraph/coreapi/qsgtexture_p.h + scenegraph/coreapi/qsgtexture_platform.h scenegraph/qsgadaptationlayer.cpp scenegraph/qsgadaptationlayer_p.h scenegraph/qsgbasicglyphnode.cpp scenegraph/qsgbasicglyphnode_p.h scenegraph/qsgbasicinternalimagenode.cpp scenegraph/qsgbasicinternalimagenode_p.h @@ -398,6 +399,11 @@ qt_extend_target(Quick CONDITION QT_FEATURE_opengl OR QT_FEATURE_opengles2 OR QT util/qquickopenglutils.cpp util/qquickopenglutils.h ) +qt_extend_target(Quick CONDITION IOS OR MACOS + SOURCES + scenegraph/coreapi/qsgtexture_mac.mm +) + qt_extend_target(Quick CONDITION QT_FEATURE_thread SOURCES scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop_p.h diff --git a/src/quick/items/qquickframebufferobject.cpp b/src/quick/items/qquickframebufferobject.cpp index 03de94756d..b2bd8dfc6b 100644 --- a/src/quick/items/qquickframebufferobject.cpp +++ b/src/quick/items/qquickframebufferobject.cpp @@ -346,10 +346,10 @@ QSGNode *QQuickFramebufferObject::updatePaintNode(QSGNode *node, UpdatePaintNode displayTexture = n->msDisplayFbo->texture(); } - QSGTexture *wrapper = window()->createTextureFromNativeObject(QQuickWindow::NativeObjectTexture, - displayTexture, 0, - n->fbo->size(), - QQuickWindow::TextureHasAlphaChannel); + QSGTexture *wrapper = QPlatformInterface::QSGOpenGLTexture::fromNative(displayTexture, + window(), + n->fbo->size(), + QQuickWindow::TextureHasAlphaChannel); n->setTexture(wrapper); } diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 344add9b78..0735037985 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -1495,9 +1495,10 @@ void QQuickWindowPrivate::cleanup(QSGNode *n) QQuickWindow by calling rendererInterface(). The enablers for this integration are the beforeRendering(), beforeRenderPassRecording(), afterRenderPassRecording(), and related signals. These allow rendering - underlays or overlays. Alternatively, createTextureFromNativeObject() allows - wrapping an existing native texture or image object in a QSGTexture that can - then be used with the scene graph. + underlays or overlays. Alternatively, QPlatformInterface::QSGOpenGLTexture, + QPlatformInterface::QSGVulkanTexture, and other similar classes allow + wrapping an existing native texture or image object in a QSGTexture that + can then be used with the scene graph. \section2 Rendering without Acceleration @@ -4805,80 +4806,22 @@ QSGTexture *QQuickWindow::createTextureFromImage(const QImage &image, CreateText return d->context->createTexture(image, flags); } -/*! - \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. - - \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 the now-removed createTextureFromId() in Qt 5, this function - never takes ownership of the native object, and the TextureOwnsGLTexture - flag is ignored. - - \a size specifies the size in pixels. - - \a nativeObjectHandle is a 64-bit container for the native object handle. With - OpenGL, the native handle is a GLuint value, so \a nativeObjectHandle then - contains a GLuint. With Vulkan, \a nativeObjectHandle contains a VkImage, and - with Direct3D 11 and Metal it contains a ID3D11Texture2D or MTLTexture 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(), QSGTexture, QSGTexture::nativeTexture(), - {Scene Graph - Metal Texture Import}, {Scene Graph - Vulkan Texture Import} - - \since 5.14 - */ -QSGTexture *QQuickWindow::createTextureFromNativeObject(NativeObjectType type, - quint64 nativeObjectHandle, - int nativeLayout, - const QSize &size, - CreateTextureOptions options) const -{ - if (type != NativeObjectTexture) { - qWarning("createTextureFromNativeObject: only textures are supported"); +QSGTexture *QQuickWindowPrivate::createTextureFromNativeTexture(quint64 nativeObjectHandle, + int nativeLayout, + const QSize &size, + QQuickWindow::CreateTextureOptions options) const +{ + if (!rhi) return nullptr; - } - Q_D(const QQuickWindow); - if (d->rhi) { - QSGPlainTexture *texture = new QSGPlainTexture; - texture->setTextureFromNativeObject(d->rhi, type, nativeObjectHandle, 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; - } - - return nullptr; + QSGPlainTexture *texture = new QSGPlainTexture; + texture->setTextureFromNativeTexture(rhi, nativeObjectHandle, nativeLayout, + size, options.testFlag(QQuickWindow::TextureHasMipmaps)); + texture->setHasAlphaChannel(options & QQuickWindow::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; } /*! diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h index 2850bf7c2e..6af11dba39 100644 --- a/src/quick/items/qquickwindow.h +++ b/src/quick/items/qquickwindow.h @@ -113,11 +113,6 @@ public: }; Q_ENUM(TextRenderType) - enum NativeObjectType { - NativeObjectTexture - }; - Q_ENUM(NativeObjectType) - explicit QQuickWindow(QWindow *parent = nullptr); explicit QQuickWindow(QQuickRenderControl *renderControl); @@ -156,12 +151,6 @@ public: QSGTexture *createTextureFromImage(const QImage &image) const; QSGTexture *createTextureFromImage(const QImage &image, CreateTextureOptions options) const; - QSGTexture *createTextureFromNativeObject(NativeObjectType type, - quint64 nativeObjectHandle, - int nativeLayout, - const QSize &size, - CreateTextureOptions options = CreateTextureOption()) const; - void setColor(const QColor &color); QColor color() const; diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h index 09851c5fa5..2046fb0462 100644 --- a/src/quick/items/qquickwindow_p.h +++ b/src/quick/items/qquickwindow_p.h @@ -242,6 +242,11 @@ public: bool emitError(QQuickWindow::SceneGraphError error, const QString &msg); + QSGTexture *createTextureFromNativeTexture(quint64 nativeObjectHandle, + int nativeLayout, + const QSize &size, + QQuickWindow::CreateTextureOptions options) const; + QQuickItem::UpdatePaintNodeData updatePaintNodeData; QQuickItem *dirtyItemList; diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp index 35d84a2d7e..171485d678 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp @@ -45,7 +45,7 @@ QT_BEGIN_NAMESPACE QSGSoftwareLayer::QSGSoftwareLayer(QSGRenderContext *renderContext) - : QSGLayer(*(new QSGTexturePrivate)) + : QSGLayer(*(new QSGTexturePrivate(this))) , m_item(nullptr) , m_context(renderContext) , m_renderer(nullptr) diff --git a/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp index fe605d4f5a..5562ea3185 100644 --- a/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp +++ b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp @@ -49,7 +49,7 @@ QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(QSG_LOG_TEXTUREIO, "qt.scenegraph.textureio"); QSGCompressedTexture::QSGCompressedTexture(const QTextureFileData &texData) - : QSGTexture(*(new QSGTexturePrivate)), + : QSGTexture(*(new QSGTexturePrivate(this))), m_textureData(texData) { m_size = m_textureData.size(); diff --git a/src/quick/scenegraph/coreapi/qsgtexture.cpp b/src/quick/scenegraph/coreapi/qsgtexture.cpp index ee50140424..2400095125 100644 --- a/src/quick/scenegraph/coreapi/qsgtexture.cpp +++ b/src/quick/scenegraph/coreapi/qsgtexture.cpp @@ -38,8 +38,11 @@ ****************************************************************************/ #include "qsgtexture_p.h" +#include "qsgtexture_platform.h" #include <private/qqmlglobal_p.h> #include <private/qsgmaterialshader_p.h> +#include <private/qquickitem_p.h> // qquickwindow_p.h cannot be included on its own due to template nonsense +#include <private/qquickwindow_p.h> #include <QtGui/private/qrhi_p.h> #if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) && defined(__GLIBC__) @@ -101,7 +104,7 @@ QSGSamplerDescription QSGSamplerDescription::fromTexture(QSGTexture *t) return s; } -QSGTexturePrivate::QSGTexturePrivate() +QSGTexturePrivate::QSGTexturePrivate(QSGTexture *t) : wrapChanged(false) , filteringChanged(false) , anisotropyChanged(false) @@ -110,6 +113,18 @@ QSGTexturePrivate::QSGTexturePrivate() , mipmapMode(QSGTexture::None) , filterMode(QSGTexture::Nearest) , anisotropyLevel(QSGTexture::AnisotropyNone) +#if QT_CONFIG(opengl) + , m_openglTextureAccessor(t) +#endif +#ifdef Q_OS_WIN + , m_d3d11TextureAccessor(t) +#endif +#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) + , m_metalTextureAccessor(t) +#endif +#if QT_CONFIG(vulkan) + , m_vulkanTextureAccessor(t) +#endif { } @@ -315,33 +330,10 @@ static void qt_debug_remove_texture(QSGTexture* texture) */ /*! - \class QSGTexture::NativeTexture - \brief Contains information about the underlying native resources of a texture. - \since 5.15 - */ - -/*! - \variable QSGTexture::NativeTexture::object - \brief a 64-bit container of the native object handle. - - With OpenGL, the native handle is a GLuint value, so \c object then - contains a GLuint. With Vulkan, \c object contains a VkImage, and - with Direct3D 11 and Metal it contains a ID3D11Texture2D or MTLTexture - pointer. - */ - -/*! - \variable QSGTexture::NativeTexture::layout - \brief Specifies the current image layout for APIs like Vulkan. - - For Vulkan, \c layout contains a \c VkImageLayout value. - */ - -/*! Constructs the QSGTexture base class. */ QSGTexture::QSGTexture() - : QObject(*(new QSGTexturePrivate)) + : QObject(*(new QSGTexturePrivate(this))) { #ifndef QT_NO_DEBUG if (qsg_leak_check) @@ -651,24 +643,6 @@ void QSGTexture::commitTextureOperations(QRhi *rhi, QRhiResourceUpdateBatch *res Q_UNUSED(resourceUpdates); } -/*! - \return the platform-specific texture data for this texture. - - Returns an empty result (\c object is null) if there is no available - underlying native texture. - - \since 5.15 - \sa QQuickWindow::createTextureFromNativeObject() - */ -QSGTexture::NativeTexture QSGTexture::nativeTexture() const -{ - if (auto *tex = rhiTexture()) { - auto nativeTexture = tex->nativeTexture(); - return {nativeTexture.object, nativeTexture.layout}; - } - return {}; -} - bool QSGTexturePrivate::hasDirtySamplerOptions() const { return wrapChanged || filteringChanged || anisotropyChanged; @@ -714,6 +688,324 @@ QSGDynamicTexture::QSGDynamicTexture(QSGTexturePrivate &dd) { } +/*! + \fn template<typename T> T *QSGTexture::platformInterface<T>() + + Returns a platform interface of type T for the texture. + + This function provides access to platform specific functionality of + QSGTexture, as defined in the QPlatformInterface namespace. This allows + accessing the underlying native texture object, such as, the \c GLuint + texture ID with OpenGL, or the \c VkImage handle with Vulkan. + + If the requested interface is not available a \nullptr is returned. + */ + +/*! + \namespace QPlatformInterface + \inmodule QtQuick + \since 6.0 + + \brief The QPlatformInterface namespace contains graphics API specific + interfaces that allow accessing the underlying graphics resources and allow + creating QSGTexture instances that wrap an existing native resource. + + The classes in this namespace can be passed to + QSGTexture::platformInterface() to gain access to the appropriate graphics + API specific interface, as long as the scene graph has been initialized with + the graphics API in question. + + \sa QSGTexture::platformInterface() +*/ + +#if QT_CONFIG(opengl) || defined(Q_CLANG_QDOC) +namespace QPlatformInterface { +/*! + \class QPlatformInterface::QSGOpenGLTexture + \inmodule QtQuick + \brief Provides access to and enables adopting OpenGL texture objects. + \since 6.0 +*/ + +/*! + \fn VkImage QPlatformInterface::QSGOpenGLTexture::nativeTexture() const + \return the OpenGL texture ID. + */ + +/*! + \internal + */ +QSGOpenGLTexture::~QSGOpenGLTexture() +{ +} + +/*! + Creates a new QSGTexture wrapping an existing OpenGL texture object. + + The native object specified in \a textureId 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. + + This function is currently suitable for 2D RGBA textures only. + + \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. + + \a size specifies the size in pixels. + + \note This function must be called on the scenegraph rendering thread. + + \sa QQuickWindow::sceneGraphInitialized(), QSGTexture, + {Scene Graph - Metal Texture Import}, {Scene Graph - Vulkan Texture Import} + + \since 6.0 + */ +QSGTexture *QSGOpenGLTexture::fromNative(GLuint textureId, + QQuickWindow *window, + const QSize &size, + QQuickWindow::CreateTextureOptions options) +{ + return QQuickWindowPrivate::get(window)->createTextureFromNativeTexture(quint64(textureId), 0, size, options); +} +} // QPlatformInterface + +GLuint QSGTexturePlatformOpenGL::nativeTexture() const +{ + if (auto *tex = m_texture->rhiTexture()) + return GLuint(tex->nativeTexture().object); + return 0; +} + +template<> Q_QUICK_EXPORT +QPlatformInterface::QSGOpenGLTexture *QSGTexture::platformInterface<QPlatformInterface::QSGOpenGLTexture>() +{ + Q_D(QSGTexture); + return &d->m_openglTextureAccessor; +} +#endif // opengl + +#if defined(Q_OS_WIN) || defined(Q_CLANG_QDOC) +namespace QPlatformInterface { +/*! + \class QPlatformInterface::QSGD3D11Texture + \inmodule QtQuick + \brief Provides access to and enables adopting Direct3D 11 texture objects. + \since 6.0 +*/ + +/*! + \fn void *QPlatformInterface::QSGD3D11Texture::nativeTexture() const + \return the ID3D11Texture2D object. + */ + +/*! + \internal + */ +QSGD3D11Texture::~QSGD3D11Texture() +{ +} + +/*! + Creates a new QSGTexture wrapping an existing Direct 3D 11 \a texture 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. + + This function is currently suitable for 2D RGBA textures only. + + \warning This function will return null if the scene graph has not yet been + initialized. + + Use \a options to customize the texture attributes. Only the + TextureHasAlphaChannel and TextureHasMipmaps are taken into account here. + + \a size specifies the size in pixels. + + \note This function must be called on the scene graph rendering thread. + + \sa QQuickWindow::sceneGraphInitialized(), QSGTexture, + {Scene Graph - Metal Texture Import}, {Scene Graph - Vulkan Texture Import} + + \since 6.0 + */ +QSGTexture *QSGD3D11Texture::fromNative(void *texture, + QQuickWindow *window, + const QSize &size, + QQuickWindow::CreateTextureOptions options) +{ + return QQuickWindowPrivate::get(window)->createTextureFromNativeTexture(quint64(texture), 0, size, options); +} +} // QPlatformInterface + +void *QSGTexturePlatformD3D11::nativeTexture() const +{ + if (auto *tex = m_texture->rhiTexture()) + return reinterpret_cast<void *>(quintptr(tex->nativeTexture().object)); + return 0; +} + +template<> Q_QUICK_EXPORT +QPlatformInterface::QSGD3D11Texture *QSGTexture::platformInterface<QPlatformInterface::QSGD3D11Texture>() +{ + Q_D(QSGTexture); + return &d->m_d3d11TextureAccessor; +} +#endif // win + +#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) || defined(Q_CLANG_QDOC) +namespace QPlatformInterface { +/*! + \class QPlatformInterface::QSGMetalTexture + \inmodule QtQuick + \brief Provides access to and enables adopting Metal texture objects. + \since 6.0 +*/ + +/*! + \fn MTLTexture *QPlatformInterface::QSGMetalTexture::nativeTexture() const + \return the Metal texture object. + */ + +/*! + \internal + */ +QSGMetalTexture::~QSGMetalTexture() +{ +} + +/*! + \fn QSGTexture *QPlatformInterface::QSGMetalTexture::fromNative(MTLTexture *texture, QQuickWindow *window, const QSize &size, QQuickWindow::CreateTextureOptions options) + + Creates a new QSGTexture wrapping an existing Metal \a texture 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. + + This function is currently suitable for 2D RGBA textures only. + + \warning This function will return null if the scene graph has not yet been + initialized. + + Use \a options to customize the texture attributes. Only the + TextureHasAlphaChannel and TextureHasMipmaps are taken into account here. + + \a size specifies the size in pixels. + + \note This function must be called on the scene graph rendering thread. + + \sa QQuickWindow::sceneGraphInitialized(), QSGTexture, + {Scene Graph - Metal Texture Import}, {Scene Graph - Vulkan Texture Import} + + \since 6.0 + */ + +} // QPlatformInterface + +MTLTexture *QSGTexturePlatformMetal::nativeTexture() const +{ + if (auto *tex = m_texture->rhiTexture()) + return (MTLTexture *) quintptr(tex->nativeTexture().object); + return 0; +} + +template<> Q_QUICK_EXPORT +QPlatformInterface::QSGMetalTexture *QSGTexture::platformInterface<QPlatformInterface::QSGMetalTexture>() +{ + Q_D(QSGTexture); + return &d->m_metalTextureAccessor; +} +#endif // win + +#if QT_CONFIG(vulkan) || defined(Q_CLANG_QDOC) +namespace QPlatformInterface { +/*! + \class QPlatformInterface::QSGVulkanTexture + \inmodule QtQuick + \brief Provides access to and enables adopting Vulkan image objects. + \since 6.0 +*/ + +/*! + \fn VkImage QPlatformInterface::QSGVulkanTexture::nativeImage() const + \return the VkImage handle. + */ + +/*! + \fn VkImageLayout QPlatformInterface::QSGVulkanTexture::nativeImageLayout() const + \return the image layout. + */ + +/*! + \internal + */ +QSGVulkanTexture::~QSGVulkanTexture() +{ +} + +/*! + Creates a new QSGTexture wrapping an existing Vulkan \a image 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. + + This function is currently suitable for 2D RGBA textures only. + + \warning This function will return null if the scene graph has not yet been + initialized. + + \a layout must specify the current layout of the image. + + Use \a options to customize the texture attributes. Only the + TextureHasAlphaChannel and TextureHasMipmaps are taken into account here. + + \a size specifies the size in pixels. + + \note This function must be called on the scene graph rendering thread. + + \sa QQuickWindow::sceneGraphInitialized(), QSGTexture, + {Scene Graph - Metal Texture Import}, {Scene Graph - Vulkan Texture Import} + + \since 6.0 + */ +QSGTexture *QSGVulkanTexture::fromNative(VkImage image, + VkImageLayout layout, + QQuickWindow *window, + const QSize &size, + QQuickWindow::CreateTextureOptions options) +{ + return QQuickWindowPrivate::get(window)->createTextureFromNativeTexture(quint64(image), layout, size, options); +} +} // QPlatformInterface + +VkImage QSGTexturePlatformVulkan::nativeImage() const +{ + if (auto *tex = m_texture->rhiTexture()) + return VkImage(tex->nativeTexture().object); + return VK_NULL_HANDLE; +} + +VkImageLayout QSGTexturePlatformVulkan::nativeImageLayout() const +{ + if (auto *tex = m_texture->rhiTexture()) + return VkImageLayout(tex->nativeTexture().layout); + return VK_IMAGE_LAYOUT_UNDEFINED; +} + +template<> Q_QUICK_EXPORT +QPlatformInterface::QSGVulkanTexture *QSGTexture::platformInterface<QPlatformInterface::QSGVulkanTexture>() +{ + Q_D(QSGTexture); + return &d->m_vulkanTextureAccessor; +} +#endif // vulkan + QT_END_NAMESPACE #include "moc_qsgtexture.cpp" diff --git a/src/quick/scenegraph/coreapi/qsgtexture.h b/src/quick/scenegraph/coreapi/qsgtexture.h index 2d9d6b4403..978bdef057 100644 --- a/src/quick/scenegraph/coreapi/qsgtexture.h +++ b/src/quick/scenegraph/coreapi/qsgtexture.h @@ -41,8 +41,9 @@ #define QSGTEXTURE_H #include <QtQuick/qtquickglobal.h> -#include <QtCore/QObject> -#include <QtGui/QImage> +#include <QtCore/qobject.h> +#include <QtGui/qimage.h> +#include <QtQuick/qsgtexture_platform.h> QT_BEGIN_NAMESPACE @@ -80,14 +81,8 @@ public: Anisotropy16x }; - struct NativeTexture { - quint64 object; - int layout; - }; - virtual qint64 comparisonKey() const = 0; virtual QRhiTexture *rhiTexture() const; - NativeTexture nativeTexture() const; virtual QSize textureSize() const = 0; virtual bool hasAlphaChannel() const = 0; virtual bool hasMipmaps() const = 0; @@ -117,6 +112,8 @@ public: inline QRectF convertToNormalizedSourceRect(const QRectF &rect) const; + template<typename T> T *platformInterface(); + protected: QSGTexture(QSGTexturePrivate &dd); }; diff --git a/src/quick/scenegraph/coreapi/qsgtexture_mac.mm b/src/quick/scenegraph/coreapi/qsgtexture_mac.mm new file mode 100644 index 0000000000..3614e5f2f3 --- /dev/null +++ b/src/quick/scenegraph/coreapi/qsgtexture_mac.mm @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2020 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 "qsgtexture_p.h" +#include "qsgtexture_platform.h" +#include <private/qquickitem_p.h> +#include <private/qquickwindow_p.h> + +QT_BEGIN_NAMESPACE + +namespace QPlatformInterface { + +QSGTexture *QSGMetalTexture::fromNative(MTLTexture *texture, + QQuickWindow *window, + const QSize &size, + QQuickWindow::CreateTextureOptions options) +{ + return QQuickWindowPrivate::get(window)->createTextureFromNativeTexture(quint64(texture), 0, size, options); +} + +} // QPlatformInterface + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/coreapi/qsgtexture_p.h b/src/quick/scenegraph/coreapi/qsgtexture_p.h index 4a7af7ae4e..a003049099 100644 --- a/src/quick/scenegraph/coreapi/qsgtexture_p.h +++ b/src/quick/scenegraph/coreapi/qsgtexture_p.h @@ -74,11 +74,56 @@ bool operator==(const QSGSamplerDescription &a, const QSGSamplerDescription &b) bool operator!=(const QSGSamplerDescription &a, const QSGSamplerDescription &b) Q_DECL_NOTHROW; size_t qHash(const QSGSamplerDescription &s, uint seed = 0) Q_DECL_NOTHROW; +#if QT_CONFIG(opengl) +class Q_QUICK_PRIVATE_EXPORT QSGTexturePlatformOpenGL : public QPlatformInterface::QSGOpenGLTexture +{ +public: + QSGTexturePlatformOpenGL(QSGTexture *t) : m_texture(t) { } + QSGTexture *m_texture; + + GLuint nativeTexture() const override; +}; +#endif + +#ifdef Q_OS_WIN +class Q_QUICK_PRIVATE_EXPORT QSGTexturePlatformD3D11 : public QPlatformInterface::QSGD3D11Texture +{ +public: + QSGTexturePlatformD3D11(QSGTexture *t) : m_texture(t) { } + QSGTexture *m_texture; + + void *nativeTexture() const override; +}; +#endif + +#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) +class Q_QUICK_PRIVATE_EXPORT QSGTexturePlatformMetal : public QPlatformInterface::QSGMetalTexture +{ +public: + QSGTexturePlatformMetal(QSGTexture *t) : m_texture(t) { } + QSGTexture *m_texture; + + MTLTexture *nativeTexture() const override; +}; +#endif + +#if QT_CONFIG(vulkan) +class Q_QUICK_PRIVATE_EXPORT QSGTexturePlatformVulkan : public QPlatformInterface::QSGVulkanTexture +{ +public: + QSGTexturePlatformVulkan(QSGTexture *t) : m_texture(t) { } + QSGTexture *m_texture; + + VkImage nativeImage() const override; + VkImageLayout nativeImageLayout() const override; +}; +#endif + class Q_QUICK_PRIVATE_EXPORT QSGTexturePrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QSGTexture) public: - QSGTexturePrivate(); + QSGTexturePrivate(QSGTexture *t); static QSGTexturePrivate *get(QSGTexture *t) { return t->d_func(); } void resetDirtySamplerOptions(); bool hasDirtySamplerOptions() const; @@ -92,6 +137,22 @@ public: uint mipmapMode : 2; uint filterMode : 2; uint anisotropyLevel: 3; + + // While we could make QSGTexturePrivate implement all the interfaces, we + // rather choose to use separate objects to avoid clashes in the function + // names and signatures. +#if QT_CONFIG(opengl) + QSGTexturePlatformOpenGL m_openglTextureAccessor; +#endif +#ifdef Q_OS_WIN + QSGTexturePlatformD3D11 m_d3d11TextureAccessor; +#endif +#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) + QSGTexturePlatformMetal m_metalTextureAccessor; +#endif +#if QT_CONFIG(vulkan) + QSGTexturePlatformVulkan m_vulkanTextureAccessor; +#endif }; Q_QUICK_PRIVATE_EXPORT bool qsg_safeguard_texture(QSGTexture *); diff --git a/src/quick/scenegraph/coreapi/qsgtexture_platform.h b/src/quick/scenegraph/coreapi/qsgtexture_platform.h new file mode 100644 index 0000000000..f7e1591765 --- /dev/null +++ b/src/quick/scenegraph/coreapi/qsgtexture_platform.h @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** Copyright (C) 2020 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 QSGTEXTURE_PLATFORM_H +#define QSGTEXTURE_PLATFORM_H + +#include <QtQuick/qquickwindow.h> + +#if QT_CONFIG(opengl) +#include <QtGui/qopengl.h> +#endif + +#if QT_CONFIG(vulkan) +#include <QtGui/qvulkaninstance.h> +#endif + +#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) || defined(Q_CLANG_QDOC) +Q_FORWARD_DECLARE_OBJC_CLASS(MTLTexture); +#endif + +QT_BEGIN_NAMESPACE + +namespace QPlatformInterface { + +#if QT_CONFIG(opengl) || defined(Q_CLANG_QDOC) +class Q_QUICK_EXPORT QSGOpenGLTexture +{ +public: + virtual ~QSGOpenGLTexture(); + virtual GLuint nativeTexture() const = 0; + static QSGTexture *fromNative(GLuint textureId, + QQuickWindow *window, + const QSize &size, + QQuickWindow::CreateTextureOptions options = {}); +}; +#endif + +#if defined(Q_OS_WIN) || defined(Q_CLANG_QDOC) +class Q_QUICK_EXPORT QSGD3D11Texture +{ +public: + virtual ~QSGD3D11Texture(); + virtual void *nativeTexture() const = 0; + static QSGTexture *fromNative(void *texture, + QQuickWindow *window, + const QSize &size, + QQuickWindow::CreateTextureOptions options = {}); +}; +#endif + +#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) || defined(Q_CLANG_QDOC) +class Q_QUICK_EXPORT QSGMetalTexture +{ +public: + virtual ~QSGMetalTexture(); + virtual MTLTexture *nativeTexture() const = 0; + static QSGTexture *fromNative(MTLTexture *texture, + QQuickWindow *window, + const QSize &size, + QQuickWindow::CreateTextureOptions options = {}); +}; +#endif + +#if QT_CONFIG(vulkan) || defined(Q_CLANG_QDOC) +class Q_QUICK_EXPORT QSGVulkanTexture +{ +public: + virtual ~QSGVulkanTexture(); + virtual VkImage nativeImage() const = 0; + virtual VkImageLayout nativeImageLayout() const = 0; + static QSGTexture *fromNative(VkImage image, + VkImageLayout layout, + QQuickWindow *window, + const QSize &size, + QQuickWindow::CreateTextureOptions options = {}); +}; +#endif + +} // QPlatformInterface + +QT_END_NAMESPACE + +#endif // QSGTEXTURE_PLATFORM_H diff --git a/src/quick/scenegraph/qsgrhilayer.cpp b/src/quick/scenegraph/qsgrhilayer.cpp index 7ac1dcfee5..4c9e82bafd 100644 --- a/src/quick/scenegraph/qsgrhilayer.cpp +++ b/src/quick/scenegraph/qsgrhilayer.cpp @@ -44,7 +44,7 @@ #include <private/qsgdefaultrendercontext_p.h> QSGRhiLayer::QSGRhiLayer(QSGRenderContext *context) - : QSGLayer(*(new QSGTexturePrivate)) + : QSGLayer(*(new QSGTexturePrivate(this))) , m_mipmap(false) , m_live(true) , m_recursive(false) diff --git a/src/quick/scenegraph/scenegraph.pri b/src/quick/scenegraph/scenegraph.pri index 0f10e4d061..c1c489abe8 100644 --- a/src/quick/scenegraph/scenegraph.pri +++ b/src/quick/scenegraph/scenegraph.pri @@ -19,6 +19,7 @@ HEADERS += \ $$PWD/coreapi/qsggeometry_p.h \ $$PWD/coreapi/qsgtexture.h \ $$PWD/coreapi/qsgtexture_p.h \ + $$PWD/coreapi/qsgtexture_platform.h \ $$PWD/coreapi/qsgbatchrenderer_p.h \ $$PWD/coreapi/qsgrhivisualizer_p.h @@ -36,6 +37,10 @@ SOURCES += \ $$PWD/coreapi/qsgbatchrenderer.cpp \ $$PWD/coreapi/qsgrhivisualizer.cpp +macos|ios { + SOURCES += \ + $$PWD/coreapi/qsgtexture_mac.mm +} # Util API HEADERS += \ diff --git a/src/quick/scenegraph/util/qsgdefaultpainternode.cpp b/src/quick/scenegraph/util/qsgdefaultpainternode.cpp index 83bdc42687..844247521e 100644 --- a/src/quick/scenegraph/util/qsgdefaultpainternode.cpp +++ b/src/quick/scenegraph/util/qsgdefaultpainternode.cpp @@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE #define QT_MINIMUM_DYNAMIC_FBO_SIZE 64U QSGPainterTexture::QSGPainterTexture() - : QSGPlainTexture(*(new QSGPlainTexturePrivate)) + : QSGPlainTexture(*(new QSGPlainTexturePrivate(this))) { m_retain_image = true; } diff --git a/src/quick/scenegraph/util/qsgplaintexture.cpp b/src/quick/scenegraph/util/qsgplaintexture.cpp index 9069804b35..030a496e33 100644 --- a/src/quick/scenegraph/util/qsgplaintexture.cpp +++ b/src/quick/scenegraph/util/qsgplaintexture.cpp @@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE QSGPlainTexture::QSGPlainTexture() - : QSGTexture(*(new QSGPlainTexturePrivate)) + : QSGTexture(*(new QSGPlainTexturePrivate(this))) , m_texture(nullptr) , m_has_alpha(false) , m_dirty_texture(false) @@ -100,12 +100,10 @@ void QSGPlainTexture::setTexture(QRhiTexture *texture) // RHI only m_mipmaps_generated = false; } -void QSGPlainTexture::setTextureFromNativeObject(QRhi *rhi, QQuickWindow::NativeObjectType type, - quint64 nativeObjectHandle, int nativeLayout, - const QSize &size, bool mipmap) +void QSGPlainTexture::setTextureFromNativeTexture(QRhi *rhi, + quint64 nativeObjectHandle, int nativeLayout, + const QSize &size, bool mipmap) { - Q_UNUSED(type); - QRhiTexture::Flags flags; if (mipmap) flags |= QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips; diff --git a/src/quick/scenegraph/util/qsgplaintexture_p.h b/src/quick/scenegraph/util/qsgplaintexture_p.h index 58a22cbfcf..33f47f7fa0 100644 --- a/src/quick/scenegraph/util/qsgplaintexture_p.h +++ b/src/quick/scenegraph/util/qsgplaintexture_p.h @@ -87,9 +87,9 @@ public: void commitTextureOperations(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates) override; void setTexture(QRhiTexture *texture); - void setTextureFromNativeObject(QRhi *rhi, QQuickWindow::NativeObjectType type, - quint64 nativeObjectHandle, int nativeLayout, - const QSize &size, bool mipmap); + void setTextureFromNativeTexture(QRhi *rhi, + quint64 nativeObjectHandle, int nativeLayout, + const QSize &size, bool mipmap); static QSGPlainTexture *fromImage(const QImage &image) { QSGPlainTexture *t = new QSGPlainTexture(); @@ -119,6 +119,7 @@ class QSGPlainTexturePrivate : public QSGTexturePrivate { Q_DECLARE_PUBLIC(QSGPlainTexture) public: + QSGPlainTexturePrivate(QSGTexture *t) : QSGTexturePrivate(t) { } QSGTexture::Filtering m_last_mipmap_filter = QSGTexture::None; }; diff --git a/src/quick/scenegraph/util/qsgrhiatlastexture.cpp b/src/quick/scenegraph/util/qsgrhiatlastexture.cpp index 82aa680faf..10c8f934f8 100644 --- a/src/quick/scenegraph/util/qsgrhiatlastexture.cpp +++ b/src/quick/scenegraph/util/qsgrhiatlastexture.cpp @@ -338,7 +338,7 @@ void Atlas::enqueueTextureUpload(TextureBase *t, QRhiResourceUpdateBatch *resour } TextureBase::TextureBase(AtlasBase *atlas, const QRect &textureRect) - : QSGTexture(*(new QSGTexturePrivate)) + : QSGTexture(*(new QSGTexturePrivate(this))) , m_allocated_rect(textureRect) , m_atlas(atlas) { |