43QSGSoftwareRenderableNode::QSGSoftwareRenderableNode(NodeType type, QSGNode *node)
47 , m_hasClipRegion(
false)
51 case QSGSoftwareRenderableNode::SimpleRect:
52 m_handle.simpleRectNode =
static_cast<QSGSimpleRectNode*>(node);
54 case QSGSoftwareRenderableNode::SimpleTexture:
55 m_handle.simpleTextureNode =
static_cast<QSGSimpleTextureNode*>(node);
57 case QSGSoftwareRenderableNode::Image:
58 m_handle.imageNode =
static_cast<QSGSoftwareInternalImageNode*>(node);
60 case QSGSoftwareRenderableNode::Painter:
61 m_handle.painterNode =
static_cast<QSGSoftwarePainterNode*>(node);
63 case QSGSoftwareRenderableNode::Rectangle:
64 m_handle.rectangleNode =
static_cast<QSGSoftwareInternalRectangleNode*>(node);
66 case QSGSoftwareRenderableNode::Glyph:
67 m_handle.glpyhNode =
static_cast<QSGSoftwareGlyphNode*>(node);
69 case QSGSoftwareRenderableNode::NinePatch:
70 m_handle.ninePatchNode =
static_cast<QSGSoftwareNinePatchNode*>(node);
72 case QSGSoftwareRenderableNode::SimpleRectangle:
73 m_handle.simpleRectangleNode =
static_cast<QSGRectangleNode*>(node);
75 case QSGSoftwareRenderableNode::SimpleImage:
76 m_handle.simpleImageNode =
static_cast<QSGImageNode*>(node);
78#if QT_CONFIG(quick_sprite)
79 case QSGSoftwareRenderableNode::SpriteNode:
80 m_handle.spriteNode =
static_cast<QSGSoftwareSpriteNode*>(node);
83 case QSGSoftwareRenderableNode::RenderNode:
84 m_handle.renderNode =
static_cast<QSGRenderNode*>(node);
86 case QSGSoftwareRenderableNode::Invalid:
87 m_handle.simpleRectNode =
nullptr;
97void QSGSoftwareRenderableNode::update()
105 switch (m_nodeType) {
106 case QSGSoftwareRenderableNode::SimpleRect:
107 if (m_handle.simpleRectNode->color().alpha() == 255)
110 boundingRect = m_handle.simpleRectNode->rect();
112 case QSGSoftwareRenderableNode::SimpleTexture:
113 if (!m_handle.simpleTextureNode->texture()->hasAlphaChannel())
116 boundingRect = m_handle.simpleTextureNode->rect();
118 case QSGSoftwareRenderableNode::Image:
119 m_isOpaque = !m_handle.imageNode->pixmap().hasAlphaChannel();
121 boundingRect = m_handle.imageNode->rect().toRect();
123 case QSGSoftwareRenderableNode::Painter:
124 if (m_handle.painterNode->opaquePainting())
127 boundingRect = QRectF(0, 0, m_handle.painterNode->size().width(), m_handle.painterNode->size().height());
129 case QSGSoftwareRenderableNode::Rectangle:
130 if (m_handle.rectangleNode->isOpaque())
133 boundingRect = m_handle.rectangleNode->rect();
135 case QSGSoftwareRenderableNode::Glyph:
137 boundingRect = m_handle.glpyhNode->boundingRect();
139 case QSGSoftwareRenderableNode::NinePatch:
140 m_isOpaque = m_handle.ninePatchNode->isOpaque();
142 boundingRect = m_handle.ninePatchNode->bounds();
144 case QSGSoftwareRenderableNode::SimpleRectangle:
145 if (m_handle.simpleRectangleNode->color().alpha() == 255)
148 boundingRect = m_handle.simpleRectangleNode->rect();
150 case QSGSoftwareRenderableNode::SimpleImage:
151 if (!m_handle.simpleImageNode->texture()->hasAlphaChannel())
154 boundingRect = m_handle.simpleImageNode->rect();
156#if QT_CONFIG(quick_sprite)
157 case QSGSoftwareRenderableNode::SpriteNode:
158 m_isOpaque = m_handle.spriteNode->isOpaque();
159 boundingRect = m_handle.spriteNode->rect();
162 case QSGSoftwareRenderableNode::RenderNode:
163 if (m_handle.renderNode->flags().testFlag(QSGRenderNode::OpaqueRendering))
166 boundingRect = m_handle.renderNode->rect();
172 if (m_transform.isRotating())
175 const QRectF transformedRect = m_transform.mapRect(boundingRect);
176 m_boundingRectMin = toRectMin(transformedRect);
177 m_boundingRectMax = toRectMax(transformedRect);
179 if (m_hasClipRegion && m_clipRegion.rectCount() <= 1) {
181 if (m_clipRegion.isEmpty()) {
182 m_boundingRectMin = QRect();
183 m_boundingRectMax = QRect();
185 const auto rects = m_clipRegion.begin();
186 m_boundingRectMin = m_boundingRectMin.intersected(rects[0]);
187 m_boundingRectMax = m_boundingRectMax.intersected(rects[0]);
192 if (m_opacity < 1.0f)
195 m_dirtyRegion = QRegion(m_boundingRectMax);
210QRegion QSGSoftwareRenderableNode::renderNode(QPainter *painter,
bool forceOpaquePainting)
215 if (m_nodeType != RenderNode) {
216 if (!m_isDirty || qFuzzyIsNull(m_opacity) || m_dirtyRegion.isEmpty()) {
218 m_dirtyRegion = QRegion();
222 if (!m_isDirty || qFuzzyIsNull(m_opacity)) {
224 m_dirtyRegion = QRegion();
227 QSGRenderNodePrivate *rd = QSGRenderNodePrivate::get(m_handle.renderNode);
228 rd->m_localMatrix = m_transform;
229 rd->m_matrix = &rd->m_localMatrix;
230 rd->m_opacity = m_opacity;
233 QRegion cr = m_dirtyRegion;
234 if (m_clipRegion.rectCount() > 1)
240 m_handle.renderNode->render(&rs);
243 const QRect br = m_handle.renderNode->flags().testFlag(QSGRenderNode::BoundedRectRendering)
245 : QRect(0, 0, painter->device()->width(), painter->device()->height());
246 m_previousDirtyRegion = QRegion(br);
248 m_dirtyRegion = QRegion();
254 painter->setOpacity(m_opacity);
258 painter->setClipRegion(m_dirtyRegion, Qt::ReplaceClip);
259 if (m_clipRegion.rectCount() > 1)
260 painter->setClipRegion(m_clipRegion, Qt::IntersectClip);
262 painter->setTransform(m_transform,
false);
263 if (forceOpaquePainting || m_isOpaque)
264 painter->setCompositionMode(QPainter::CompositionMode_Source);
266 switch (m_nodeType) {
267 case QSGSoftwareRenderableNode::SimpleRect:
268 painter->fillRect(m_handle.simpleRectNode->rect(), m_handle.simpleRectNode->color());
270 case QSGSoftwareRenderableNode::SimpleTexture:
272 QSGTexture *texture = m_handle.simpleTextureNode->texture();
273 if (QSGSoftwarePixmapTexture *pt = qobject_cast<QSGSoftwarePixmapTexture *>(texture)) {
274 const QPixmap &pm = pt->pixmap();
275 painter->drawPixmap(m_handle.simpleTextureNode->rect(), pm, m_handle.simpleTextureNode->sourceRect());
276 }
else if (QSGPlainTexture *pt = qobject_cast<QSGPlainTexture *>(texture)) {
277 const QImage &im = pt->image();
278 painter->drawImage(m_handle.simpleTextureNode->rect(), im, m_handle.simpleTextureNode->sourceRect());
282 case QSGSoftwareRenderableNode::Image:
283 m_handle.imageNode->paint(painter);
285 case QSGSoftwareRenderableNode::Painter:
286 m_handle.painterNode->paint(painter);
288 case QSGSoftwareRenderableNode::Rectangle:
289 m_handle.rectangleNode->paint(painter);
291 case QSGSoftwareRenderableNode::Glyph:
292 m_handle.glpyhNode->paint(painter);
294 case QSGSoftwareRenderableNode::NinePatch:
295 m_handle.ninePatchNode->paint(painter);
297 case QSGSoftwareRenderableNode::SimpleRectangle:
298 static_cast<QSGSoftwareRectangleNode *>(m_handle.simpleRectangleNode)->paint(painter);
300 case QSGSoftwareRenderableNode::SimpleImage:
301 static_cast<QSGSoftwareImageNode *>(m_handle.simpleImageNode)->paint(painter);
303#if QT_CONFIG(quick_sprite)
304 case QSGSoftwareRenderableNode::SpriteNode:
305 static_cast<QSGSoftwareSpriteNode *>(m_handle.spriteNode)->paint(painter);
314 QRegion areaToBeFlushed = m_dirtyRegion;
315 m_previousDirtyRegion = QRegion(m_boundingRectMax);
317 m_dirtyRegion = QRegion();
319 return areaToBeFlushed;