hiding the devicePixelRato scaling in the nodes

This commit is contained in:
Uwe Rathmann 2021-12-13 16:43:34 +01:00
parent e4ffc3f074
commit 738de14d4c
8 changed files with 61 additions and 56 deletions

View File

@ -125,7 +125,7 @@ bool Benchmark::run( const QString& dirName )
using namespace QskTextureRenderer;
const auto textureId = createTextureFromGraphic(
OpenGL, targetSize, graphics[ i ], colorFilter,
nullptr, OpenGL, targetSize, graphics[ i ], colorFilter,
Qt::IgnoreAspectRatio );
if ( textureId == 0 )
@ -151,7 +151,7 @@ bool Benchmark::run( const QString& dirName )
using namespace QskTextureRenderer;
const auto textureId = createTextureFromGraphic(
Raster, targetSize, graphics[ i ], colorFilter,
nullptr, Raster, targetSize, graphics[ i ], colorFilter,
Qt::IgnoreAspectRatio );
if ( textureId == 0 )

View File

@ -26,6 +26,28 @@
#include <qquickwindow.h>
#include <qsgsimplerectnode.h>
static inline QRectF qskSceneAlignedRect( const QQuickItem* item , const QRectF& rect )
{
/*
Aligning rect according to scene coordinates, so that
we don't run into rounding issues downstream, where values
will be floored/ceiled ending up with a slightly different
aspect ratio.
*/
const auto ratio = item->window()->devicePixelRatio();
const auto pos = item->mapToScene( rect.topLeft() ) * ratio;
const auto size = rect.size() * ratio;
const qreal x = qRound( pos.x() ) / ratio;
const qreal y = qRound( pos.y() ) / ratio;
const qreal w = qRound( size.width() ) / ratio;
const qreal h = qRound( size.height() ) / ratio;
return QRectF( item->mapFromScene( QPointF( x, y ) ), QSizeF( w, h ) );
}
static inline QRectF qskSubControlRect( const QskSkinlet* skinlet,
const QskSkinnable* skinnable, QskAspect::Subcontrol subControl )
{
@ -59,19 +81,7 @@ static inline QSGNode* qskUpdateGraphicNode(
if ( control->testUpdateFlag( QskControl::PreferRasterForTextures ) )
mode = QskTextureRenderer::Raster;
/*
Aligning the rect according to scene coordinates, so that
we don't run into rounding issues downstream, where values
will be floored/ceiled ending up with a slightly different
aspect ratio.
*/
QRectF r(
control->mapToScene( rect.topLeft() ),
rect.size() * control->window()->effectiveDevicePixelRatio() );
r = qskInnerRect( r );
r.moveTopLeft( control->mapFromScene( r.topLeft() ) );
const auto r = qskSceneAlignedRect( control, rect );
graphicNode->setGraphic( control->window(), graphic,
colorFilter, mode, r, mirrored );
@ -161,20 +171,7 @@ static inline QSGNode* qskUpdateArcNode(
if ( arcNode == nullptr )
arcNode = new QskArcNode();
auto r = rect;
#if 1
{
/*
Fiddling around with the pixel ratio should be hidden below QskArcNode.
Code will break once QskArcNode is not texture based anymore. TODO ...
*/
const auto ratio = control->window()->effectiveDevicePixelRatio();
absoluteMetrics.setWidth( absoluteMetrics.width() * ratio );
r.setSize( r.size() * ratio );
}
#endif
const auto r = qskSceneAlignedRect( control, rect );
arcNode->setArcData( r, absoluteMetrics, fillGradient, control->window() );
return arcNode;

View File

@ -60,7 +60,7 @@ QSGTexture* QskGraphicTextureFactory::createTexture( QQuickWindow* window ) cons
using namespace QskTextureRenderer;
const uint textureId = createTextureFromGraphic(
QskTextureRenderer::OpenGL, m_size, m_graphic, m_colorFilter,
window, QskTextureRenderer::OpenGL, m_size, m_graphic, m_colorFilter,
Qt::IgnoreAspectRatio );
return textureFromId( window, textureId, m_size );

View File

@ -78,7 +78,7 @@ void QskGraphicNode::setGraphic(
if ( isTextureDirty )
{
textureId = QskTextureRenderer::createTextureFromGraphic(
renderMode, textureSize, graphic, colorFilter, Qt::IgnoreAspectRatio );
window, renderMode, textureSize, graphic, colorFilter, Qt::IgnoreAspectRatio );
}
QskTextureNode::setTexture( window, rect, textureId, mirrored );

View File

@ -56,7 +56,7 @@ void QskPaintedNode::update( QQuickWindow* window,
{
PaintHelper helper( this );
textureId = QskTextureRenderer::createTexture(
renderMode, rect.size(), &helper );
window, renderMode, rect.size(), &helper );
}
QskTextureNode::setTexture( window, rect, textureId );

View File

@ -1,5 +1,5 @@
#include "QskTextureNode.h"
#include "QskTextureRenderer.h"
#include "QskFunctions.h"
#include <qopenglfunctions.h>
#include <qsggeometry.h>
@ -237,7 +237,7 @@ class QskTextureNodePrivate final : public QSGGeometryNodePrivate
void setTextureId( QQuickWindow*, uint id );
void updateTextureGeometry( const QQuickWindow* window )
void updateTextureGeometry()
{
QRectF r( 0, 0, 1, 1 );
@ -253,15 +253,7 @@ class QskTextureNodePrivate final : public QSGGeometryNodePrivate
r.setBottom( 0 );
}
const qreal ratio = window->effectiveDevicePixelRatio();
const qreal x = int( rect.x() / ratio ) * ratio;
const qreal y = int( rect.y() / ratio ) * ratio;
const qreal w = rect.width() / ratio;
const qreal h = rect.height() / ratio;
QSGGeometry::updateTexturedRectGeometry(
&geometry, QRectF( x, y, w, h ), r );
QSGGeometry::updateTexturedRectGeometry( &geometry, rect, r );
}
QSGGeometry geometry;
@ -301,7 +293,7 @@ void QskTextureNode::setTexture( QQuickWindow* window,
d->rect = rect;
d->mirrored = mirrored;
d->updateTextureGeometry( window );
d->updateTextureGeometry();
markDirty( DirtyGeometry );
}

View File

@ -25,11 +25,13 @@
#include <qsgtexture_platform.h>
#endif
static uint qskCreateTextureOpenGL(
static uint qskCreateTextureOpenGL( QQuickWindow* window,
const QSize& size, QskTextureRenderer::PaintHelper* helper )
{
const int width = size.width();
const int height = size.height();
const auto ratio = window ? window->effectiveDevicePixelRatio() : 1.0;
const int width = ratio * size.width();
const int height = ratio * size.height();
QOpenGLFramebufferObjectFormat format1;
format1.setAttachment( QOpenGLFramebufferObject::CombinedDepthStencil );
@ -44,6 +46,7 @@ static uint qskCreateTextureOpenGL(
{
QPainter painter( &pd );
painter.scale( ratio, ratio );
painter.setCompositionMode( QPainter::CompositionMode_Source );
painter.fillRect( 0, 0, width, height, Qt::transparent );
@ -77,15 +80,26 @@ static uint qskCreateTextureOpenGL(
return fbo.takeTexture();
}
static uint qskCreateTextureRaster(
static uint qskCreateTextureRaster( QQuickWindow* window,
const QSize& size, QskTextureRenderer::PaintHelper* helper )
{
QImage image( size, QImage::Format_RGBA8888_Premultiplied );
const auto ratio = window ? window->effectiveDevicePixelRatio() : 1.0;
QImage image( size * ratio, QImage::Format_RGBA8888_Premultiplied );
image.fill( Qt::transparent );
{
QPainter painter( &image );
/*
setting a devicePixelRatio for the image only works for
value >= 1.0. So we have to scale manually.
*/
painter.scale( ratio, ratio );
helper->paint( &painter, size );
image.save( "/tmp/xx.png" );
}
const auto target = QOpenGLTexture::Target2D;
@ -165,7 +179,8 @@ QskTextureRenderer::PaintHelper::~PaintHelper()
}
uint QskTextureRenderer::createTexture(
RenderMode renderMode, const QSize& size, PaintHelper* helper )
QQuickWindow* window, RenderMode renderMode,
const QSize& size, PaintHelper* helper )
{
#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
// Qt6.0.0 is buggy when using FBOs. So let's disable it for the moment TODO ...
@ -180,13 +195,13 @@ uint QskTextureRenderer::createTexture(
}
if ( renderMode == Raster )
return qskCreateTextureRaster( size, helper );
return qskCreateTextureRaster( window, size, helper );
else
return qskCreateTextureOpenGL( size, helper );
return qskCreateTextureOpenGL( window, size, helper );
}
uint QskTextureRenderer::createTextureFromGraphic(
RenderMode renderMode, const QSize& size,
QQuickWindow* window, RenderMode renderMode, const QSize& size,
const QskGraphic& graphic, const QskColorFilter& colorFilter,
Qt::AspectRatioMode aspectRatioMode )
{
@ -214,5 +229,5 @@ uint QskTextureRenderer::createTextureFromGraphic(
};
PaintHelper helper( graphic, colorFilter, aspectRatioMode );
return createTexture( renderMode, size, &helper );
return createTexture( window, renderMode, size, &helper );
}

View File

@ -42,10 +42,11 @@ namespace QskTextureRenderer
virtual void paint( QPainter*, const QSize& ) = 0;
};
QSK_EXPORT uint createTexture( RenderMode, const QSize&, PaintHelper* );
QSK_EXPORT uint createTexture(
QQuickWindow*, RenderMode, const QSize&, PaintHelper* );
QSK_EXPORT uint createTextureFromGraphic(
RenderMode, const QSize&, const QskGraphic&,
QQuickWindow*, RenderMode, const QSize&, const QskGraphic&,
const QskColorFilter&, Qt::AspectRatioMode );
QSK_EXPORT QSGTexture* textureFromId(