diff --git a/src/controls/QskQuick.cpp b/src/controls/QskQuick.cpp index e252ff5e..d988820c 100644 --- a/src/controls/QskQuick.cpp +++ b/src/controls/QskQuick.cpp @@ -29,6 +29,25 @@ QRhi* qskRenderingHardwareInterface( const QQuickWindow* window ) return nullptr; } +bool qskIsOpenGLWindow( const QQuickWindow* window ) +{ + if ( window == nullptr ) + return false; + + const auto renderer = window->rendererInterface(); + switch( renderer->graphicsApi() ) + { + case QSGRendererInterface::OpenGL: +#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) + case QSGRendererInterface::OpenGLRhi: +#endif + return true; + + default: + return false; + } +} + QRectF qskItemRect( const QQuickItem* item ) { auto d = QQuickItemPrivate::get( item ); diff --git a/src/controls/QskQuick.h b/src/controls/QskQuick.h index 165bec4b..7befde16 100644 --- a/src/controls/QskQuick.h +++ b/src/controls/QskQuick.h @@ -27,6 +27,7 @@ template< typename T > class QList; */ QSK_EXPORT QRhi* qskRenderingHardwareInterface( const QQuickWindow* ); +QSK_EXPORT bool qskIsOpenGLWindow( const QQuickWindow* ); QSK_EXPORT bool qskIsItemInDestructor( const QQuickItem* ); QSK_EXPORT bool qskIsItemComplete( const QQuickItem* ); diff --git a/src/graphic/QskGraphicTextureFactory.cpp b/src/graphic/QskGraphicTextureFactory.cpp index 24cff214..efaae47e 100644 --- a/src/graphic/QskGraphicTextureFactory.cpp +++ b/src/graphic/QskGraphicTextureFactory.cpp @@ -5,9 +5,38 @@ #include "QskGraphicTextureFactory.h" #include "QskTextureRenderer.h" +#include "QskQuick.h" +#include "QskInternalMacros.h" #include +QSK_QT_PRIVATE_BEGIN +#include +QSK_QT_PRIVATE_END + +static QSGTexture* qskCreatePaintedTexture( QQuickWindow* window, + const QSize& size, QskTextureRenderer::PaintHelper* helper ) +{ + using namespace QskTextureRenderer; + + if ( qskIsOpenGLWindow( window ) ) + { + const auto textureId = createTextureGL( window, size, helper ); + + auto texture = new QSGPlainTexture; + texture->setHasAlphaChannel( true ); + texture->setOwnsTexture( true ); + + setTextureId( window, textureId, size, texture ); + + return texture; + } + else + { + return createTextureRaster( window, size, helper ); + } +} + QskGraphicTextureFactory::QskGraphicTextureFactory() { } @@ -77,7 +106,7 @@ QSGTexture* QskGraphicTextureFactory::createTexture( QQuickWindow* window ) cons }; PaintHelper helper( m_graphic, m_colorFilter ); - return QskTextureRenderer::createPaintedTexture( window, m_size, &helper ); + return qskCreatePaintedTexture( window, m_size, &helper ); } QSize QskGraphicTextureFactory::textureSize() const diff --git a/src/nodes/QskPaintedNode.cpp b/src/nodes/QskPaintedNode.cpp index 101a6f23..56fbfb95 100644 --- a/src/nodes/QskPaintedNode.cpp +++ b/src/nodes/QskPaintedNode.cpp @@ -7,6 +7,7 @@ #include "QskSGNode.h" #include "QskTextureRenderer.h" #include "QskInternalMacros.h" +#include "QskQuick.h" #include #include @@ -160,7 +161,7 @@ void QskPaintedNode::updateTexture( QQuickWindow* window, { auto imageNode = findImageNode( this ); - if ( ( m_renderHint == OpenGL ) && QskTextureRenderer::isOpenGLWindow( window ) ) + if ( ( m_renderHint == OpenGL ) && qskIsOpenGLWindow( window ) ) { const auto textureId = createTextureGL( window, size, nodeData ); @@ -232,5 +233,5 @@ quint32 QskPaintedNode::createTextureGL( }; PaintHelper helper( this, nodeData ); - return QskTextureRenderer::createPaintedTextureGL( window, size, &helper ); + return QskTextureRenderer::createTextureGL( window, size, &helper ); } diff --git a/src/nodes/QskTextureRenderer.cpp b/src/nodes/QskTextureRenderer.cpp index 77ba70cd..2628c5ef 100644 --- a/src/nodes/QskTextureRenderer.cpp +++ b/src/nodes/QskTextureRenderer.cpp @@ -30,8 +30,12 @@ static GLuint qskTakeTexture( QOpenGLFramebufferObject& fbo ) /* See https://bugreports.qt.io/browse/QTBUG-103929 - As we create a FBO for each update of a node we can't live - without having this ( ugly ) workaround. + QOpenGLFramebufferObject::takeTexture produces a memory leak + that can't be accepted as we create an FBO each time we update + a texture. + + The suggested workarond is to call QOpenGLSharedResourceGuard::invalidateResource() + manually. Unfortunately this is a protected method and we need this nasty hack. */ class MyFBO { @@ -64,25 +68,6 @@ static GLuint qskTakeTexture( QOpenGLFramebufferObject& fbo ) return textureId; } -bool QskTextureRenderer::isOpenGLWindow( const QQuickWindow* window ) -{ - if ( window == nullptr ) - return false; - - const auto renderer = window->rendererInterface(); - switch( renderer->graphicsApi() ) - { - case QSGRendererInterface::OpenGL: -#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) - case QSGRendererInterface::OpenGLRhi: -#endif - return true; - - default: - return false; - } -} - void QskTextureRenderer::setTextureId( QQuickWindow* window, quint32 textureId, const QSize& size, QSGTexture* texture ) { @@ -116,8 +101,8 @@ void QskTextureRenderer::setTextureId( QQuickWindow* window, #endif } -quint32 QskTextureRenderer::createPaintedTextureGL( - QQuickWindow* window, const QSize& size, QskTextureRenderer::PaintHelper* helper ) +quint32 QskTextureRenderer::createTextureGL( + QQuickWindow* window, const QSize& size, PaintHelper* helper ) { /* Binding GL_ARRAY_BUFFER/GL_ELEMENT_ARRAY_BUFFER to 0 seems to be enough. @@ -194,8 +179,8 @@ quint32 QskTextureRenderer::createPaintedTextureGL( return qskTakeTexture( fbo ); } -static QSGTexture* qskCreateTextureRaster( QQuickWindow* window, - const QSize& size, QskTextureRenderer::PaintHelper* helper ) +QSGTexture* QskTextureRenderer::createTextureRaster( QQuickWindow* window, + const QSize& size, PaintHelper* helper ) { const auto ratio = window ? window->effectiveDevicePixelRatio() : 1.0; @@ -216,24 +201,3 @@ static QSGTexture* qskCreateTextureRaster( QQuickWindow* window, return window->createTextureFromImage( image, QQuickWindow::TextureHasAlphaChannel ); } - -QSGTexture* QskTextureRenderer::createPaintedTexture( - QQuickWindow* window, const QSize& size, PaintHelper* helper ) -{ - if ( isOpenGLWindow( window ) ) - { - const auto textureId = createPaintedTextureGL( window, size, helper ); - - auto texture = new QSGPlainTexture; - texture->setHasAlphaChannel( true ); - texture->setOwnsTexture( true ); - - setTextureId( window, textureId, size, texture ); - - return texture; - } - else - { - return qskCreateTextureRaster( window, size, helper ); - } -} diff --git a/src/nodes/QskTextureRenderer.h b/src/nodes/QskTextureRenderer.h index 3b907ab2..470c5cc1 100644 --- a/src/nodes/QskTextureRenderer.h +++ b/src/nodes/QskTextureRenderer.h @@ -27,16 +27,11 @@ namespace QskTextureRenderer Q_DISABLE_COPY( PaintHelper ) }; - bool isOpenGLWindow( const QQuickWindow* ); - void setTextureId( QQuickWindow*, quint32 textureId, const QSize&, QSGTexture* ); - quint32 createPaintedTextureGL( - QQuickWindow*, const QSize&, QskTextureRenderer::PaintHelper* ); - - QSK_EXPORT QSGTexture* createPaintedTexture( - QQuickWindow* window, const QSize& size, PaintHelper* helper ); + quint32 createTextureGL( QQuickWindow*, const QSize&, PaintHelper* ); + QSGTexture* createTextureRaster( QQuickWindow*, const QSize&, PaintHelper* ); } #endif