6#include "QskPaintedNode.h"
8#include "QskTextureRenderer.h"
9#include "QskInternalMacros.h"
11#include <qsgimagenode.h>
12#include <qquickwindow.h>
17#include <private/qsgplaintexture_p.h>
20static inline QSGImageNode::TextureCoordinatesTransformMode
21 qskEffectiveTransformMode(
const Qt::Orientations mirrored )
23 QSGImageNode::TextureCoordinatesTransformMode mode;
25 if ( mirrored & Qt::Vertical )
26 mode |= QSGImageNode::MirrorVertically;
28 if ( mirrored & Qt::Horizontal )
29 mode |= QSGImageNode::MirrorHorizontally;
36 const quint8 imageRole = 250;
38 inline QSGImageNode* findImageNode(
const QSGNode* parentNode )
40 auto node = QskSGNode::findChildNode(
41 const_cast< QSGNode*
>( parentNode ), imageRole );
43 return static_cast< QSGImageNode*
>( node );
47QskPaintedNode::QskPaintedNode()
51QskPaintedNode::~QskPaintedNode()
55void QskPaintedNode::setRenderHint( RenderHint renderHint )
57 m_renderHint = renderHint;
60QskPaintedNode::RenderHint QskPaintedNode::renderHint()
const
65void QskPaintedNode::setMirrored( Qt::Orientations orientations )
67 if ( orientations != m_mirrored )
69 m_mirrored = orientations;
71 if (
auto imageNode = findImageNode(
this ) )
73 imageNode->setTextureCoordinatesTransform(
74 qskEffectiveTransformMode( orientations ) );
79Qt::Orientations QskPaintedNode::mirrored()
const
84QSize QskPaintedNode::textureSize()
const
86 if (
const auto imageNode = findImageNode(
this ) )
88 if (
auto texture = imageNode->texture() )
89 return texture->textureSize();
95QRectF QskPaintedNode::rect()
const
97 const auto imageNode = findImageNode(
this );
98 return imageNode ? imageNode->rect() : QRectF();
101void QskPaintedNode::update( QQuickWindow* window,
102 const QRectF& rect,
const QSizeF& size,
const void* nodeData )
104 auto imageNode = findImageNode(
this );
106 if ( rect.isEmpty() )
110 removeChildNode( imageNode );
117 if ( imageNode ==
nullptr )
119 imageNode = window->createImageNode();
121 imageNode->setOwnsTexture(
true );
122 QskSGNode::setNodeRole( imageNode, imageRole );
124 appendChildNode( imageNode );
130 auto scaledSize = size.isEmpty() ? rect.size() : size;
131 scaledSize *= window->effectiveDevicePixelRatio();
133 imageSize = scaledSize.toSize();
136 bool isTextureDirty =
false;
138 const auto newHash = hash( nodeData );
139 if ( ( newHash == 0 ) || ( newHash != m_hash ) )
142 isTextureDirty =
true;
146 isTextureDirty = ( imageSize != textureSize() );
150 if ( isTextureDirty )
151 updateTexture( window, imageSize, nodeData );
153 imageNode->setRect( rect );
154 imageNode->setTextureCoordinatesTransform(
155 qskEffectiveTransformMode( m_mirrored ) );
158void QskPaintedNode::updateTexture( QQuickWindow* window,
159 const QSize& size,
const void* nodeData )
161 auto imageNode = findImageNode(
this );
163 if ( ( m_renderHint == OpenGL ) && QskTextureRenderer::isOpenGLWindow( window ) )
165 const auto textureId = createTextureGL( window, size, nodeData );
167 auto texture = qobject_cast< QSGPlainTexture* >( imageNode->texture() );
168 if ( texture ==
nullptr )
170 texture =
new QSGPlainTexture;
171 texture->setHasAlphaChannel(
true );
172 texture->setOwnsTexture(
true );
174 imageNode->setTexture( texture );
177 QskTextureRenderer::setTextureId( window, textureId, size, texture );
181 const auto image = createImage( window, size, nodeData );
183 if (
auto texture = qobject_cast< QSGPlainTexture* >( imageNode->texture() ) )
184 texture->setImage( image );
186 imageNode->setTexture( window->createTextureFromImage( image ) );
190QImage QskPaintedNode::createImage( QQuickWindow* window,
191 const QSize& size,
const void* nodeData )
193 QImage image( size, QImage::Format_RGBA8888_Premultiplied );
194 image.fill( Qt::transparent );
196 QPainter painter( &image );
202 const auto ratio = window->effectiveDevicePixelRatio();
203 painter.scale( ratio, ratio );
205 paint( &painter, size / ratio, nodeData );
212quint32 QskPaintedNode::createTextureGL(
213 QQuickWindow* window,
const QSize& size,
const void* nodeData )
220 , m_nodeData( nodeData )
224 void paint( QPainter* painter,
const QSize& size )
override
226 m_node->paint( painter, size, m_nodeData );
231 const void* m_nodeData;
234 PaintHelper helper(
this, nodeData );
235 return createPaintedTextureGL( window, size, &helper );