6#include "QskPaintedNode.h"
8#include "QskTextureRenderer.h"
10#include <qsgimagenode.h>
11#include <qquickwindow.h>
16#include <private/qsgplaintexture_p.h>
19static inline QSGImageNode::TextureCoordinatesTransformMode
20 qskEffectiveTransformMode(
const Qt::Orientations mirrored )
22 QSGImageNode::TextureCoordinatesTransformMode mode;
24 if ( mirrored & Qt::Vertical )
25 mode |= QSGImageNode::MirrorVertically;
27 if ( mirrored & Qt::Horizontal )
28 mode |= QSGImageNode::MirrorHorizontally;
35 const quint8 imageRole = 250;
37 inline QSGImageNode* findImageNode(
const QSGNode* parentNode )
39 auto node = QskSGNode::findChildNode(
40 const_cast< QSGNode*
>( parentNode ), imageRole );
42 return static_cast< QSGImageNode*
>( node );
46QskPaintedNode::QskPaintedNode()
50QskPaintedNode::~QskPaintedNode()
54void QskPaintedNode::setRenderHint( RenderHint renderHint )
56 m_renderHint = renderHint;
59QskPaintedNode::RenderHint QskPaintedNode::renderHint()
const
64void QskPaintedNode::setMirrored( Qt::Orientations orientations )
66 if ( orientations != m_mirrored )
68 m_mirrored = orientations;
70 if (
auto imageNode = findImageNode(
this ) )
72 imageNode->setTextureCoordinatesTransform(
73 qskEffectiveTransformMode( orientations ) );
78Qt::Orientations QskPaintedNode::mirrored()
const
83QSize QskPaintedNode::textureSize()
const
85 if (
const auto imageNode = findImageNode(
this ) )
87 if (
auto texture = imageNode->texture() )
88 return texture->textureSize();
94QRectF QskPaintedNode::rect()
const
96 const auto imageNode = findImageNode(
this );
97 return imageNode ? imageNode->rect() : QRectF();
100void QskPaintedNode::update( QQuickWindow* window,
101 const QRectF& rect,
const QSizeF& size,
const void* nodeData )
103 auto imageNode = findImageNode(
this );
105 if ( rect.isEmpty() )
109 removeChildNode( imageNode );
116 if ( imageNode ==
nullptr )
118 imageNode = window->createImageNode();
120 imageNode->setOwnsTexture(
true );
121 QskSGNode::setNodeRole( imageNode, imageRole );
123 appendChildNode( imageNode );
129 auto scaledSize = size.isEmpty() ? rect.size() : size;
130 scaledSize *= window->effectiveDevicePixelRatio();
132 imageSize = scaledSize.toSize();
135 bool isTextureDirty =
false;
137 const auto newHash = hash( nodeData );
138 if ( ( newHash == 0 ) || ( newHash != m_hash ) )
141 isTextureDirty =
true;
145 isTextureDirty = ( imageSize != textureSize() );
149 if ( isTextureDirty )
150 updateTexture( window, imageSize, nodeData );
152 imageNode->setRect( rect );
153 imageNode->setTextureCoordinatesTransform(
154 qskEffectiveTransformMode( m_mirrored ) );
157void QskPaintedNode::updateTexture( QQuickWindow* window,
158 const QSize& size,
const void* nodeData )
160 auto imageNode = findImageNode(
this );
162 if ( ( m_renderHint == OpenGL ) && QskTextureRenderer::isOpenGLWindow( window ) )
164 const auto textureId = createTextureGL( window, size, nodeData );
166 auto texture = qobject_cast< QSGPlainTexture* >( imageNode->texture() );
167 if ( texture ==
nullptr )
169 texture =
new QSGPlainTexture;
170 texture->setHasAlphaChannel(
true );
171 texture->setOwnsTexture(
true );
173 imageNode->setTexture( texture );
176 QskTextureRenderer::setTextureId( window, textureId, size, texture );
180 const auto image = createImage( window, size, nodeData );
182 if (
auto texture = qobject_cast< QSGPlainTexture* >( imageNode->texture() ) )
183 texture->setImage( image );
185 imageNode->setTexture( window->createTextureFromImage( image ) );
189QImage QskPaintedNode::createImage( QQuickWindow* window,
190 const QSize& size,
const void* nodeData )
192 QImage image( size, QImage::Format_RGBA8888_Premultiplied );
193 image.fill( Qt::transparent );
195 QPainter painter( &image );
201 const auto ratio = window->effectiveDevicePixelRatio();
202 painter.scale( ratio, ratio );
204 paint( &painter, size / ratio, nodeData );
211quint32 QskPaintedNode::createTextureGL(
212 QQuickWindow* window,
const QSize& size,
const void* nodeData )
219 , m_nodeData( nodeData )
223 void paint( QPainter* painter,
const QSize& size )
override
225 m_node->paint( painter, size, m_nodeData );
230 const void* m_nodeData;
233 PaintHelper helper(
this, nodeData );
234 return createPaintedTextureGL( window, size, &helper );