19QSGAbstractSoftwareRenderer::QSGAbstractSoftwareRenderer(QSGRenderContext *context)
20 : QSGRenderer(context)
21 , m_background(
new QSGSimpleRectNode)
22 , m_nodeUpdater(
new QSGSoftwareRenderableNodeUpdater(
this))
25 auto backgroundRenderable =
new QSGSoftwareRenderableNode(QSGSoftwareRenderableNode::SimpleRect, m_background);
26 addNodeMapping(m_background, backgroundRenderable);
60void QSGAbstractSoftwareRenderer::nodeChanged(QSGNode *node, QSGNode::DirtyState state)
62 if (state & QSGNode::DirtyGeometry) {
63 nodeGeometryUpdated(node);
65 if (state & QSGNode::DirtyMaterial) {
66 nodeMaterialUpdated(node);
68 if (state & QSGNode::DirtyMatrix) {
69 nodeMatrixUpdated(node);
71 if (state & QSGNode::DirtyNodeAdded) {
74 if (state & QSGNode::DirtyNodeRemoved) {
77 if (state & QSGNode::DirtyOpacity) {
78 nodeOpacityUpdated(node);
80 if (state & QSGNode::DirtySubtreeBlocked) {
81 m_nodeUpdater->updateNodes(node);
83 if (state & QSGNode::DirtyForceUpdate) {
84 m_nodeUpdater->updateNodes(node);
86 QSGRenderer::nodeChanged(node, state);
89QRegion QSGAbstractSoftwareRenderer::renderNodes(QPainter *painter)
93 if (m_renderableNodes.isEmpty())
96 auto iterator = m_renderableNodes.begin();
98 if (m_clearColorEnabled) {
99 auto backgroundNode = *iterator;
100 dirtyRegion += backgroundNode->renderNode(painter,
true);
104 for (; iterator != m_renderableNodes.end(); ++iterator) {
105 auto node = *iterator;
106 dirtyRegion += node->renderNode(painter);
112void QSGAbstractSoftwareRenderer::buildRenderList()
115 m_renderableNodes.clear();
117 m_renderableNodes.append(renderableNode(m_background));
119 QSGSoftwareRenderListBuilder(
this).visitChildren(rootNode());
122QRegion QSGAbstractSoftwareRenderer::optimizeRenderList()
126 for (
auto i = m_renderableNodes.rbegin(); i != m_renderableNodes.rend(); ++i) {
131 const bool wasDirty = node->isDirty();
132 if (!m_dirtyRegion.isEmpty()) {
134 node->addDirtyRegion(m_dirtyRegion,
true);
137 if (!m_obscuredRegion.isEmpty()) {
139 node->subtractDirtyRegion(m_obscuredRegion);
143 if (node->isOpaque()) {
144 m_obscuredRegion += node->boundingRectMin();
147 if (node->isDirty()) {
149 if (!m_background->rect().toRect().contains(node->boundingRectMax(),
true)) {
151 QRegion renderArea(m_background->rect().toRect());
152 QRegion outsideRegions = node->dirtyRegion().subtracted(renderArea);
153 if (!outsideRegions.isEmpty())
154 node->subtractDirtyRegion(outsideRegions);
158 if (node->isOpaque()) {
160 m_dirtyRegion -= node->boundingRectMin();
163 m_dirtyRegion += node->dirtyRegion();
170 QRegion prevDirty = node->previousDirtyRegion();
171 if (!prevDirty.isNull())
172 m_dirtyRegion += prevDirty;
176 if (m_obscuredRegion.contains(m_background->rect().toAlignedRect())) {
183 m_dirtyRegion = QRegion();
184 m_obscuredRegion = QRegion();
188 for (
auto j = m_renderableNodes.begin(); j != m_renderableNodes.end(); ++j) {
191 if ((!node->isOpaque() || node->boundingRectMax() != node->boundingRectMin()) && !m_dirtyRegion.isEmpty()) {
197 node->addDirtyRegion(m_dirtyRegion,
true);
200 m_dirtyRegion += node->dirtyRegion();
203 QRegion updateRegion = m_dirtyRegion;
206 m_dirtyRegion = QRegion();
207 m_obscuredRegion = QRegion();
220void QSGAbstractSoftwareRenderer::setBackgroundRect(
const QRect &rect, qreal devicePixelRatio)
222 if (m_background->rect().toRect() == rect && m_devicePixelRatio == devicePixelRatio)
224 m_background->setRect(rect);
225 m_devicePixelRatio = devicePixelRatio;
226 renderableNode(m_background)->markGeometryDirty();