diff --git a/src/controls/QskSkinlet.cpp b/src/controls/QskSkinlet.cpp index 5be9f326..5d583c82 100644 --- a/src/controls/QskSkinlet.cpp +++ b/src/controls/QskSkinlet.cpp @@ -22,6 +22,8 @@ #include "QskGraphicTextureFactory.h" #include "QskFunctions.h" +#include +#include #include #include @@ -59,6 +61,17 @@ static inline QSGNode* qskFindNodeByFlag( QSGNode* parent, int nodeRole ) return nullptr; } +static qreal qskDevicePixelRatio( const QskSkinnable* skinnable ) +{ + if ( auto control = skinnable->owningControl() ) + { + if ( auto window = control->window() ) + return window->effectiveDevicePixelRatio(); + } + + return qGuiApp->devicePixelRatio(); +} + static inline QSGNode* qskUpdateGraphicNode( const QskSkinnable* skinnable, QSGNode* node, const QskGraphic& graphic, const QskColorFilter& colorFilter, @@ -69,7 +82,7 @@ static inline QSGNode* qskUpdateGraphicNode( auto mode = QskGraphicTextureFactory::OpenGL; - const QskControl* control = skinnable->owningControl(); + const auto control = skinnable->owningControl(); if ( control && control->testControlFlag( QskControl::PreferRasterForTextures ) ) mode = QskGraphicTextureFactory::Raster; @@ -77,7 +90,11 @@ static inline QSGNode* qskUpdateGraphicNode( if ( graphicNode == nullptr ) graphicNode = new QskGraphicNode(); - graphicNode->setGraphic( graphic, colorFilter, mode, rect ); + const qreal ratio = qskDevicePixelRatio( skinnable ); + const QRect r( rect.x(), rect.y(), ratio * rect.width(), ratio * rect.height() ); + + graphicNode->setGraphic( graphic, colorFilter, mode, r ); + return graphicNode; } diff --git a/src/graphic/QskGraphicTextureFactory.cpp b/src/graphic/QskGraphicTextureFactory.cpp index 8805cd91..82bf370d 100644 --- a/src/graphic/QskGraphicTextureFactory.cpp +++ b/src/graphic/QskGraphicTextureFactory.cpp @@ -24,7 +24,6 @@ #include #include -#include #include static uint qskTextureFBO( @@ -36,17 +35,15 @@ static uint qskTextureFBO( // ### TODO: get samples from window instead format1.setSamples( QOpenGLContext::currentContext()->format().samples() ); - const auto dpr = qGuiApp->devicePixelRatio(); - const QRect sourceRect( QPoint(), rect.size() * dpr ); + const QRect sourceRect( QPoint(), rect.size() ); QOpenGLFramebufferObject multisampledFbo( sourceRect.size(), format1 ); QOpenGLPaintDevice pd( sourceRect.size() ); - pd.setDevicePixelRatio( dpr ); QPainter painter( &pd ); - graphic.render( &painter, rect, filter, scalingMode ); + graphic.render( &painter, sourceRect, filter, scalingMode ); #if 1 if ( format1.samples() > 0 ) @@ -81,11 +78,9 @@ static uint qskTextureRaster( const QRect& rect, Qt::AspectRatioMode scalingMode, const QskGraphic& graphic, const QskColorFilter& filter ) { - QImage image( rect.size() * qGuiApp->devicePixelRatio(), - QImage::Format_RGBA8888_Premultiplied ); - - image.setDevicePixelRatio( qGuiApp->devicePixelRatio() ); + QImage image( rect.size(), QImage::Format_RGBA8888_Premultiplied ); image.fill( Qt::transparent ); + { QPainter painter( &image ); graphic.render( &painter, rect, filter, scalingMode ); @@ -148,7 +143,7 @@ QImage QskGraphicTextureFactory::image() const return m_graphic.toImage( m_size, Qt::KeepAspectRatio ); } -// ### TODO: pass in window and get the DPR and FBO samples from it +// ### TODO: get the FBO samples from the window uint QskGraphicTextureFactory::createTexture( RenderMode mode, const QRect& rect, Qt::AspectRatioMode scalingMode, const QskGraphic& graphic, const QskColorFilter& filter ) diff --git a/src/nodes/QskTextureNode.cpp b/src/nodes/QskTextureNode.cpp index 5a7f8b31..ee7d829f 100644 --- a/src/nodes/QskTextureNode.cpp +++ b/src/nodes/QskTextureNode.cpp @@ -7,6 +7,42 @@ #include +#if 1 + +#include +#include +#include +#include +#include + +static inline qreal qskDevicePixelRatio() +{ + qreal ratio = 1.0; + + const auto context = QOpenGLContext::currentContext(); + + 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 + { + if ( context->screen() ) + ratio = context->screen()->devicePixelRatio(); + else + ratio = qGuiApp->devicePixelRatio(); + } + + return ratio; +} + +#endif + namespace { class MaterialShader final : public QSGMaterialShader @@ -76,7 +112,8 @@ namespace auto* materialOld = static_cast< Material* >( oldMaterial ); auto* materialNew = static_cast< Material* >( newMaterial ); - if ( ( materialOld == nullptr ) || ( materialOld->textureId() != materialNew->textureId() ) ) + if ( ( materialOld == nullptr ) + || ( materialOld->textureId() != materialNew->textureId() ) ) { auto funcs = QOpenGLContext::currentContext()->functions(); funcs->glBindTexture( GL_TEXTURE_2D, materialNew->textureId() ); @@ -281,5 +318,11 @@ void QskTextureNode::updateTexture() r.setBottom( 0 ); } - QSGGeometry::updateTexturedRectGeometry( &d->geometry, d->rect, r ); +#if 1 + const qreal ratio = qskDevicePixelRatio(); + const QRect rect( d->rect.x(), d->rect.y(), + d->rect.width() / ratio, d->rect.height() / ratio ); +#endif + + QSGGeometry::updateTexturedRectGeometry( &d->geometry, rect, r ); }