44QSGSoftwareRenderableNode::QSGSoftwareRenderableNode(NodeType type, QSGNode *node)
48 , m_hasClipRegion(
false)
52 case QSGSoftwareRenderableNode::SimpleRect:
53 m_handle.simpleRectNode =
static_cast<QSGSimpleRectNode*>(node);
55 case QSGSoftwareRenderableNode::SimpleTexture:
56 m_handle.simpleTextureNode =
static_cast<QSGSimpleTextureNode*>(node);
58 case QSGSoftwareRenderableNode::Image:
59 m_handle.imageNode =
static_cast<QSGSoftwareInternalImageNode*>(node);
61 case QSGSoftwareRenderableNode::Painter:
62 m_handle.painterNode =
static_cast<QSGSoftwarePainterNode*>(node);
64 case QSGSoftwareRenderableNode::Rectangle:
65 m_handle.rectangleNode =
static_cast<QSGSoftwareInternalRectangleNode*>(node);
67 case QSGSoftwareRenderableNode::Glyph:
68 m_handle.glpyhNode =
static_cast<QSGSoftwareGlyphNode*>(node);
70 case QSGSoftwareRenderableNode::NinePatch:
71 m_handle.ninePatchNode =
static_cast<QSGSoftwareNinePatchNode*>(node);
73 case QSGSoftwareRenderableNode::SimpleRectangle:
74 m_handle.simpleRectangleNode =
static_cast<QSGRectangleNode*>(node);
76 case QSGSoftwareRenderableNode::SimpleImage:
77 m_handle.simpleImageNode =
static_cast<QSGImageNode*>(node);
79#if QT_CONFIG(quick_sprite)
80 case QSGSoftwareRenderableNode::SpriteNode:
81 m_handle.spriteNode =
static_cast<QSGSoftwareSpriteNode*>(node);
84 case QSGSoftwareRenderableNode::RenderNode:
85 m_handle.renderNode =
static_cast<QSGRenderNode*>(node);
87 case QSGSoftwareRenderableNode::Invalid:
88 m_handle.simpleRectNode =
nullptr;
98void QSGSoftwareRenderableNode::update()
106 switch (m_nodeType) {
107 case QSGSoftwareRenderableNode::SimpleRect:
108 if (m_handle.simpleRectNode->color().alpha() == 255)
111 boundingRect = m_handle.simpleRectNode->rect();
113 case QSGSoftwareRenderableNode::SimpleTexture:
114 if (!m_handle.simpleTextureNode->texture()->hasAlphaChannel())
117 boundingRect = m_handle.simpleTextureNode->rect();
119 case QSGSoftwareRenderableNode::Image:
120 m_isOpaque = !m_handle.imageNode->pixmap().hasAlphaChannel();
122 boundingRect = m_handle.imageNode->rect().toRect();
124 case QSGSoftwareRenderableNode::Painter:
125 if (m_handle.painterNode->opaquePainting())
128 boundingRect = QRectF(0, 0, m_handle.painterNode->size().width(), m_handle.painterNode->size().height());
130 case QSGSoftwareRenderableNode::Rectangle:
131 if (m_handle.rectangleNode->isOpaque())
134 boundingRect = m_handle.rectangleNode->rect();
136 case QSGSoftwareRenderableNode::Glyph:
138 boundingRect = m_handle.glpyhNode->boundingRect();
140 case QSGSoftwareRenderableNode::NinePatch:
141 m_isOpaque = m_handle.ninePatchNode->isOpaque();
143 boundingRect = m_handle.ninePatchNode->bounds();
145 case QSGSoftwareRenderableNode::SimpleRectangle:
146 if (m_handle.simpleRectangleNode->color().alpha() == 255)
149 boundingRect = m_handle.simpleRectangleNode->rect();
151 case QSGSoftwareRenderableNode::SimpleImage:
152 if (!m_handle.simpleImageNode->texture()->hasAlphaChannel())
155 boundingRect = m_handle.simpleImageNode->rect();
157#if QT_CONFIG(quick_sprite)
158 case QSGSoftwareRenderableNode::SpriteNode:
159 m_isOpaque = m_handle.spriteNode->isOpaque();
160 boundingRect = m_handle.spriteNode->rect();
163 case QSGSoftwareRenderableNode::RenderNode:
164 if (m_handle.renderNode->flags().testFlag(QSGRenderNode::OpaqueRendering))
167 boundingRect = m_handle.renderNode->rect();
173 if (m_transform.isRotating())
176 const QRectF transformedRect = m_transform.mapRect(boundingRect);
177 m_boundingRectMin = toRectMin(transformedRect);
178 m_boundingRectMax = toRectMax(transformedRect);
180 if (m_hasClipRegion && m_clipRegion.rectCount() <= 1) {
182 if (m_clipRegion.isEmpty()) {
183 m_boundingRectMin = QRect();
184 m_boundingRectMax = QRect();
186 const auto rects = m_clipRegion.begin();
187 m_boundingRectMin = m_boundingRectMin.intersected(rects[0]);
188 m_boundingRectMax = m_boundingRectMax.intersected(rects[0]);
193 if (m_opacity < 1.0f)
196 m_dirtyRegion = QRegion(m_boundingRectMax);
211QRegion QSGSoftwareRenderableNode::renderNode(QPainter *painter,
bool forceOpaquePainting)
216 if (m_nodeType != RenderNode) {
217 if (!m_isDirty || qFuzzyIsNull(m_opacity) || m_dirtyRegion.isEmpty()) {
219 m_dirtyRegion = QRegion();
223 if (!m_isDirty || qFuzzyIsNull(m_opacity)) {
225 m_dirtyRegion = QRegion();
228 QSGRenderNodePrivate *rd = QSGRenderNodePrivate::get(m_handle.renderNode);
229 rd->m_localMatrix = m_transform;
230 rd->m_matrix = &rd->m_localMatrix;
231 rd->m_opacity = m_opacity;
234 QRegion cr = m_dirtyRegion;
235 if (m_clipRegion.rectCount() > 1)
241 m_handle.renderNode->render(&rs);
244 const QRect br = m_handle.renderNode->flags().testFlag(QSGRenderNode::BoundedRectRendering)
246 : QRect(0, 0, painter->device()->width(), painter->device()->height());
247 m_previousDirtyRegion = QRegion(br);
249 m_dirtyRegion = QRegion();
255 painter->setOpacity(m_opacity);
259 painter->setClipRegion(m_dirtyRegion, Qt::ReplaceClip);
260 if (m_clipRegion.rectCount() > 1)
261 painter->setClipRegion(m_clipRegion, Qt::IntersectClip);
263 painter->setTransform(m_transform,
false);
264 if (forceOpaquePainting || m_isOpaque)
265 painter->setCompositionMode(QPainter::CompositionMode_Source);
267 switch (m_nodeType) {
268 case QSGSoftwareRenderableNode::SimpleRect:
269 painter->fillRect(m_handle.simpleRectNode->rect(), m_handle.simpleRectNode->color());
271 case QSGSoftwareRenderableNode::SimpleTexture:
273 QSGTexture *texture = m_handle.simpleTextureNode->texture();
274 if (QSGSoftwarePixmapTexture *pt = qobject_cast<QSGSoftwarePixmapTexture *>(texture)) {
275 const QPixmap &pm = pt->pixmap();
276 painter->drawPixmap(m_handle.simpleTextureNode->rect(), pm, m_handle.simpleTextureNode->sourceRect());
277 }
else if (QSGPlainTexture *pt = qobject_cast<QSGPlainTexture *>(texture)) {
278 const QImage &im = pt->image();
279 painter->drawImage(m_handle.simpleTextureNode->rect(), im, m_handle.simpleTextureNode->sourceRect());
283 case QSGSoftwareRenderableNode::Image:
284 m_handle.imageNode->paint(painter);
286 case QSGSoftwareRenderableNode::Painter:
287 m_handle.painterNode->paint(painter);
289 case QSGSoftwareRenderableNode::Rectangle:
290 m_handle.rectangleNode->paint(painter);
292 case QSGSoftwareRenderableNode::Glyph:
293 m_handle.glpyhNode->paint(painter);
295 case QSGSoftwareRenderableNode::NinePatch:
296 m_handle.ninePatchNode->paint(painter);
298 case QSGSoftwareRenderableNode::SimpleRectangle:
299 static_cast<QSGSoftwareRectangleNode *>(m_handle.simpleRectangleNode)->paint(painter);
301 case QSGSoftwareRenderableNode::SimpleImage:
302 static_cast<QSGSoftwareImageNode *>(m_handle.simpleImageNode)->paint(painter);
304#if QT_CONFIG(quick_sprite)
305 case QSGSoftwareRenderableNode::SpriteNode:
306 static_cast<QSGSoftwareSpriteNode *>(m_handle.spriteNode)->paint(painter);
315 QRegion areaToBeFlushed = m_dirtyRegion;
316 m_previousDirtyRegion = QRegion(m_boundingRectMax);
318 m_dirtyRegion = QRegion();
320 return areaToBeFlushed;