diff --git a/src/controls/QskGraphicLabelSkinlet.cpp b/src/controls/QskGraphicLabelSkinlet.cpp index 18b2bccf..173e21fc 100644 --- a/src/controls/QskGraphicLabelSkinlet.cpp +++ b/src/controls/QskGraphicLabelSkinlet.cpp @@ -85,21 +85,19 @@ QSGNode* QskGraphicLabelSkinlet::updateGraphicNode( const auto colorFilter = label->graphicFilter(); const auto rect = label->subControlRect( QskGraphicLabel::Graphic ); + Qt::Orientations mirrored; + if ( label->mirror() ) + mirrored = Qt::Horizontal; + if ( label->fillMode() == QskGraphicLabel::Stretch ) { node = QskSkinlet::updateGraphicNode( label, node, - label->graphic(), colorFilter, rect ); + label->graphic(), colorFilter, rect, mirrored ); } else { node = QskSkinlet::updateGraphicNode( label, node, - label->graphic(), colorFilter, rect, Qt::AlignCenter ); - } - - if ( node && label->mirror() ) - { - auto textureNode = static_cast< QskTextureNode* >( node ); - textureNode->setMirrored( Qt::Horizontal ); + label->graphic(), colorFilter, rect, Qt::AlignCenter, mirrored ); } return node; diff --git a/src/controls/QskSkinlet.cpp b/src/controls/QskSkinlet.cpp index 5f943e5e..ce859c88 100644 --- a/src/controls/QskSkinlet.cpp +++ b/src/controls/QskSkinlet.cpp @@ -73,7 +73,7 @@ static inline QRectF qskSubControlRect( const QskSkinlet* skinlet, static inline QSGNode* qskUpdateGraphicNode( const QskSkinnable* skinnable, QSGNode* node, const QskGraphic& graphic, const QskColorFilter& colorFilter, - const QRectF& rect ) + const QRectF& rect, Qt::Orientations mirrored ) { if ( rect.isEmpty() ) return nullptr; @@ -99,12 +99,13 @@ static inline QSGNode* qskUpdateGraphicNode( */ QRectF r( control->mapToScene( rect.topLeft() ), - rect.size() * QskTextureRenderer::devicePixelRatio() ); + rect.size() * control->window()->effectiveDevicePixelRatio() ); r = qskInnerRect( r ); r.moveTopLeft( control->mapFromScene( r.topLeft() ) ); - graphicNode->setGraphic( graphic, colorFilter, mode, r ); + graphicNode->setGraphic( control->window(), graphic, + colorFilter, mode, r, mirrored ); return graphicNode; } @@ -551,7 +552,8 @@ QSGNode* QskSkinlet::updateTextNode( QSGNode* QskSkinlet::updateGraphicNode( const QskSkinnable* skinnable, QSGNode* node, - const QskGraphic& graphic, QskAspect::Subcontrol subcontrol ) const + const QskGraphic& graphic, QskAspect::Subcontrol subcontrol, + Qt::Orientations mirrored ) const { const QRectF rect = qskSubControlRect( this, skinnable, subcontrol ); @@ -561,13 +563,13 @@ QSGNode* QskSkinlet::updateGraphicNode( const auto colorFilter = skinnable->effectiveGraphicFilter( subcontrol ); return updateGraphicNode( skinnable, node, - graphic, colorFilter, rect, alignment ); + graphic, colorFilter, rect, alignment, mirrored ); } QSGNode* QskSkinlet::updateGraphicNode( const QskSkinnable* skinnable, QSGNode* node, const QskGraphic& graphic, const QskColorFilter& colorFilter, - const QRectF& rect, Qt::Alignment alignment ) + const QRectF& rect, Qt::Alignment alignment, Qt::Orientations mirrored ) { if ( graphic.isNull() ) return nullptr; @@ -576,18 +578,18 @@ QSGNode* QskSkinlet::updateGraphicNode( rect.size(), Qt::KeepAspectRatio ); const QRectF r = qskAlignedRectF( rect, size.width(), size.height(), alignment ); - return qskUpdateGraphicNode( skinnable, node, graphic, colorFilter, r ); + return qskUpdateGraphicNode( skinnable, node, graphic, colorFilter, r, mirrored ); } QSGNode* QskSkinlet::updateGraphicNode( const QskSkinnable* skinnable, QSGNode* node, const QskGraphic& graphic, const QskColorFilter& colorFilter, - const QRectF& rect ) + const QRectF& rect, Qt::Orientations mirrored ) { if ( graphic.isNull() ) return nullptr; - return qskUpdateGraphicNode( skinnable, node, graphic, colorFilter, rect ); + return qskUpdateGraphicNode( skinnable, node, graphic, colorFilter, rect, mirrored ); } #include "moc_QskSkinlet.cpp" diff --git a/src/controls/QskSkinlet.h b/src/controls/QskSkinlet.h index b0212a6a..363ed3b6 100644 --- a/src/controls/QskSkinlet.h +++ b/src/controls/QskSkinlet.h @@ -66,11 +66,12 @@ class QSK_EXPORT QskSkinlet // keeping the aspect ratio static QSGNode* updateGraphicNode( const QskSkinnable*, QSGNode*, const QskGraphic&, const QskColorFilter&, - const QRectF&, Qt::Alignment ); + const QRectF&, Qt::Alignment, Qt::Orientations mirrored = Qt::Orientations() ); // stretching to fit static QSGNode* updateGraphicNode( const QskSkinnable*, QSGNode*, - const QskGraphic&, const QskColorFilter&, const QRectF& ); + const QskGraphic&, const QskColorFilter&, const QRectF&, + Qt::Orientations mirrored = Qt::Orientations() ); static QSGNode* updateBoxClipNode( const QskSkinnable*, QSGNode*, const QRectF&, QskAspect::Subcontrol ); @@ -98,7 +99,8 @@ class QSK_EXPORT QskSkinlet const QString&, const QskTextOptions&, QskAspect::Subcontrol ) const; QSGNode* updateGraphicNode( const QskSkinnable*, QSGNode*, - const QskGraphic&, QskAspect::Subcontrol ) const; + const QskGraphic&, QskAspect::Subcontrol, + Qt::Orientations mirrored = Qt::Orientations() ) const; void insertRemoveNodes( QSGNode* parentNode, QSGNode* oldNode, QSGNode* newNode, quint8 nodeRole ) const; diff --git a/src/nodes/QskGraphicNode.cpp b/src/nodes/QskGraphicNode.cpp index 87e455c5..72c6895d 100644 --- a/src/nodes/QskGraphicNode.cpp +++ b/src/nodes/QskGraphicNode.cpp @@ -47,8 +47,9 @@ QskGraphicNode::~QskGraphicNode() } void QskGraphicNode::setGraphic( - const QskGraphic& graphic, const QskColorFilter& colorFilter, - QskTextureRenderer::RenderMode renderMode, const QRectF& rect ) + QQuickWindow* window, const QskGraphic& graphic, const QskColorFilter& colorFilter, + QskTextureRenderer::RenderMode renderMode, const QRectF& rect, + Qt::Orientations mirrored ) { bool isTextureDirty = isNull(); @@ -75,20 +76,20 @@ void QskGraphicNode::setGraphic( } } - QskTextureNode::setRect( rect ); - - const uint hash = qskHash( graphic, colorFilter, renderMode ); + const auto hash = qskHash( graphic, colorFilter, renderMode ); if ( hash != m_hash ) { m_hash = hash; isTextureDirty = true; } + auto textureId = QskTextureNode::textureId(); + if ( isTextureDirty ) { - const uint textureId = QskTextureRenderer::createTextureFromGraphic( + textureId = QskTextureRenderer::createTextureFromGraphic( renderMode, textureSize, graphic, colorFilter, Qt::IgnoreAspectRatio ); - - QskTextureNode::setTextureId( textureId ); } + + QskTextureNode::setTexture( window, rect, textureId, mirrored ); } diff --git a/src/nodes/QskGraphicNode.h b/src/nodes/QskGraphicNode.h index 3c139adf..1e814513 100644 --- a/src/nodes/QskGraphicNode.h +++ b/src/nodes/QskGraphicNode.h @@ -11,6 +11,7 @@ class QskGraphic; class QskColorFilter; +class QQuickWindow; class QSK_EXPORT QskGraphicNode : public QskTextureNode { @@ -18,12 +19,14 @@ class QSK_EXPORT QskGraphicNode : public QskTextureNode QskGraphicNode(); ~QskGraphicNode() override; - void setGraphic( const QskGraphic&, const QskColorFilter&, - QskTextureRenderer::RenderMode, const QRectF& ); + void setGraphic( QQuickWindow*, + const QskGraphic&, const QskColorFilter&, + QskTextureRenderer::RenderMode, const QRectF&, + Qt::Orientations mirrored = Qt::Orientations() ); private: - void setTextureId( int ) = delete; - void setRect( const QRectF& ) = delete; + void setTexture( QQuickWindow*, + const QRectF&, uint id, Qt::Orientations ) = delete; uint m_hash; }; diff --git a/src/nodes/QskPaintedNode.cpp b/src/nodes/QskPaintedNode.cpp index 64c85285..2f029ded 100644 --- a/src/nodes/QskPaintedNode.cpp +++ b/src/nodes/QskPaintedNode.cpp @@ -31,7 +31,7 @@ QskPaintedNode::~QskPaintedNode() { } -void QskPaintedNode::update( +void QskPaintedNode::update( QQuickWindow* window, QskTextureRenderer::RenderMode renderMode, const QRect& rect ) { bool isTextureDirty = isNull(); @@ -43,21 +43,21 @@ void QskPaintedNode::update( ( rect.height() != static_cast< int >( oldRect.height() ) ); } - QskTextureNode::setRect( rect ); - - const uint newHash = hash(); + const auto newHash = hash(); if ( ( newHash == 0 ) || ( newHash != m_hash ) ) { m_hash = newHash; isTextureDirty = true; } + auto textureId = QskTextureNode::textureId(); + if ( isTextureDirty ) { PaintHelper helper( this ); - const uint textureId = - QskTextureRenderer::createTexture( renderMode, rect.size(), &helper ); - - QskTextureNode::setTextureId( textureId ); + textureId = QskTextureRenderer::createTexture( + renderMode, rect.size(), &helper ); } + + QskTextureNode::setTexture( window, rect, textureId ); } diff --git a/src/nodes/QskPaintedNode.h b/src/nodes/QskPaintedNode.h index 410c4742..020c2d49 100644 --- a/src/nodes/QskPaintedNode.h +++ b/src/nodes/QskPaintedNode.h @@ -15,7 +15,8 @@ class QSK_EXPORT QskPaintedNode : public QskTextureNode QskPaintedNode(); ~QskPaintedNode() override; - void update( QskTextureRenderer::RenderMode, const QRect& ); + void update( QQuickWindow*, + QskTextureRenderer::RenderMode, const QRect& ); protected: virtual void paint( QPainter*, const QSizeF& ) = 0; @@ -26,8 +27,8 @@ class QSK_EXPORT QskPaintedNode : public QskTextureNode private: class PaintHelper; - void setTextureId( int ) = delete; - void setRect( const QRectF& ) = delete; + void setTexture( QQuickWindow*, + const QRectF&, uint id, Qt::Orientations ) = delete; uint m_hash; }; diff --git a/src/nodes/QskTextureNode.cpp b/src/nodes/QskTextureNode.cpp index 361fa535..fd1207f1 100644 --- a/src/nodes/QskTextureNode.cpp +++ b/src/nodes/QskTextureNode.cpp @@ -4,8 +4,12 @@ #include #include #include +#include +QSK_QT_PRIVATE_BEGIN #include +QSK_QT_PRIVATE_END + namespace { @@ -148,23 +152,25 @@ class QskTextureNodePrivate final : public QSGGeometryNodePrivate { } - void updateTextureGeometry() + void setTextureId( QQuickWindow*, uint id ); + + void updateTextureGeometry( const QQuickWindow* window ) { QRectF r( 0, 0, 1, 1 ); - if ( this->mirrorOrientations & Qt::Horizontal ) + if ( this->mirrored & Qt::Horizontal ) { r.setLeft( 1 ); r.setRight( 0 ); } - if ( mirrorOrientations & Qt::Vertical ) + if ( mirrored & Qt::Vertical ) { r.setTop( 1 ); r.setBottom( 0 ); } - const qreal ratio = QskTextureRenderer::devicePixelRatio(); + const qreal ratio = window->effectiveDevicePixelRatio(); const QRectF scaledRect( rect.x(), rect.y(), rect.width() / ratio, rect.height() / ratio ); @@ -178,7 +184,7 @@ class QskTextureNodePrivate final : public QSGGeometryNodePrivate Material material; QRectF rect; - Qt::Orientations mirrorOrientations; + Qt::Orientations mirrored; }; QskTextureNode::QskTextureNode() @@ -212,63 +218,41 @@ QskTextureNode::~QskTextureNode() } } -void QskTextureNode::setRect( const QRectF& r ) +void QskTextureNode::setTexture( QQuickWindow* window, + const QRectF& rect, uint textureId, + Qt::Orientations mirrored ) { Q_D( QskTextureNode ); - if ( d->rect != r ) + if ( d->rect != rect || d->mirrored != mirrored ) { - d->rect = r; - d->updateTextureGeometry(); + d->rect = rect; + d->mirrored = mirrored; + + d->updateTextureGeometry( window ); markDirty( DirtyGeometry ); } -} -QRectF QskTextureNode::rect() const -{ - Q_D( const QskTextureNode ); - return d->rect; -} - -void QskTextureNode::setMirrored( Qt::Orientations orientations ) -{ - Q_D( QskTextureNode ); - - if ( d->mirrorOrientations != orientations ) + if ( textureId != this->textureId() ) { - d->mirrorOrientations = orientations; - d->updateTextureGeometry(); - + d->setTextureId( window, textureId ); markDirty( DirtyMaterial ); } } -Qt::Orientations QskTextureNode::mirrored() const +void QskTextureNodePrivate::setTextureId( QQuickWindow*, uint textureId ) { - Q_D( const QskTextureNode ); - return d->mirrorOrientations; -} - -void QskTextureNode::setTextureId( uint textureId ) -{ - Q_D( QskTextureNode ); - - if ( textureId == d->material.textureId() ) - return; - - if ( d->material.textureId() > 0 ) + if ( this->material.textureId() > 0 ) { - GLuint id = d->material.textureId(); + GLuint id = this->material.textureId(); auto funcs = QOpenGLContext::currentContext()->functions(); funcs->glDeleteTextures( 1, &id ); } - d->material.setTextureId( textureId ); - d->opaqueMaterial.setTextureId( textureId ); - - markDirty( DirtyMaterial ); + this->material.setTextureId( textureId ); + this->opaqueMaterial.setTextureId( textureId ); } uint QskTextureNode::textureId() const @@ -277,9 +261,19 @@ uint QskTextureNode::textureId() const return d->material.textureId(); } - bool QskTextureNode::isNull() const { - Q_D( const QskTextureNode ); - return d->material.textureId() == 0; + return textureId() == 0; +} + +QRectF QskTextureNode::rect() const +{ + Q_D( const QskTextureNode ); + return d->rect; +} + +Qt::Orientations QskTextureNode::mirrored() const +{ + Q_D( const QskTextureNode ); + return d->mirrored; } diff --git a/src/nodes/QskTextureNode.h b/src/nodes/QskTextureNode.h index 8add3ccf..39868a63 100644 --- a/src/nodes/QskTextureNode.h +++ b/src/nodes/QskTextureNode.h @@ -11,6 +11,7 @@ #include #include +class QQuickWindow; class QskTextureNodePrivate; class QSK_EXPORT QskTextureNode : public QSGGeometryNode @@ -21,13 +22,11 @@ class QSK_EXPORT QskTextureNode : public QSGGeometryNode bool isNull() const; - void setRect( const QRectF& ); - QRectF rect() const; + void setTexture( QQuickWindow*, const QRectF&, uint id, + Qt::Orientations mirrored = Qt::Orientations() ); - void setTextureId( uint id ); uint textureId() const; - - void setMirrored( Qt::Orientations ); + QRectF rect() const; Qt::Orientations mirrored() const; private: diff --git a/src/nodes/QskTextureRenderer.cpp b/src/nodes/QskTextureRenderer.cpp index 9c79b603..2baa043d 100644 --- a/src/nodes/QskTextureRenderer.cpp +++ b/src/nodes/QskTextureRenderer.cpp @@ -18,11 +18,7 @@ #include #include -#include #include -#include -#include - #include #if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) @@ -220,36 +216,3 @@ uint QskTextureRenderer::createTextureFromGraphic( PaintHelper helper( graphic, colorFilter, aspectRatioMode ); return createTexture( renderMode, size, &helper ); } - -static inline qreal qskOffscreenBufferRatio( const QOpenGLContext* context ) -{ - if ( context->screen() ) - return context->screen()->devicePixelRatio(); - - return qGuiApp->devicePixelRatio(); -} - -qreal QskTextureRenderer::devicePixelRatio( const QOpenGLContext* context ) -{ - if ( context == nullptr ) - context = QOpenGLContext::currentContext(); - - qreal ratio = 1.0; - - if ( context->surface()->surfaceClass() == QSurface::Window ) - { - auto* window = static_cast< QWindow* >( context->surface() ); - - if ( auto* quickWindow = qobject_cast< QQuickWindow* >( window ) ) - ratio = quickWindow->effectiveDevicePixelRatio(); - else - ratio = window->devicePixelRatio(); - } - else - { - ratio = qskOffscreenBufferRatio( context ); - } - - return ratio; -} - diff --git a/src/nodes/QskTextureRenderer.h b/src/nodes/QskTextureRenderer.h index a15e90de..04af439d 100644 --- a/src/nodes/QskTextureRenderer.h +++ b/src/nodes/QskTextureRenderer.h @@ -14,7 +14,6 @@ class QskColorFilter; class QPainter; class QSize; -class QOpenGLContext; class QSGTexture; class QQuickWindow; @@ -52,8 +51,6 @@ namespace QskTextureRenderer QSK_EXPORT QSGTexture* textureFromId( QQuickWindow*, uint textureId, const QSize& ); - - QSK_EXPORT qreal devicePixelRatio( const QOpenGLContext* = nullptr ); } #endif