20QSGAbstractSoftwareRenderer::QSGAbstractSoftwareRenderer(QSGRenderContext *context)
21 : QSGRenderer(context)
22 , m_background(
new QSGSimpleRectNode)
23 , m_nodeUpdater(
new QSGSoftwareRenderableNodeUpdater(
this))
26 auto backgroundRenderable =
new QSGSoftwareRenderableNode(QSGSoftwareRenderableNode::SimpleRect, m_background);
27 addNodeMapping(m_background, backgroundRenderable);
61void QSGAbstractSoftwareRenderer::nodeChanged(QSGNode *node, QSGNode::DirtyState state)
63 if (state & QSGNode::DirtyGeometry) {
64 nodeGeometryUpdated(node);
66 if (state & QSGNode::DirtyMaterial) {
67 nodeMaterialUpdated(node);
69 if (state & QSGNode::DirtyMatrix) {
70 nodeMatrixUpdated(node);
72 if (state & QSGNode::DirtyNodeAdded) {
75 if (state & QSGNode::DirtyNodeRemoved) {
78 if (state & QSGNode::DirtyOpacity) {
79 nodeOpacityUpdated(node);
81 if (state & QSGNode::DirtySubtreeBlocked) {
82 m_nodeUpdater->updateNodes(node);
84 if (state & QSGNode::DirtyForceUpdate) {
85 m_nodeUpdater->updateNodes(node);
87 QSGRenderer::nodeChanged(node, state);
90QRegion QSGAbstractSoftwareRenderer::renderNodes(QPainter *painter)
94 if (m_renderableNodes.isEmpty())
97 auto iterator = m_renderableNodes.begin();
99 if (m_clearColorEnabled) {
100 auto backgroundNode = *iterator;
101 dirtyRegion += backgroundNode->renderNode(painter,
true);
105 for (; iterator != m_renderableNodes.end(); ++iterator) {
106 auto node = *iterator;
107 dirtyRegion += node->renderNode(painter);
113void QSGAbstractSoftwareRenderer::buildRenderList()
116 m_renderableNodes.clear();
118 m_renderableNodes.append(renderableNode(m_background));
120 QSGSoftwareRenderListBuilder(
this).visitChildren(rootNode());
123QRegion QSGAbstractSoftwareRenderer::optimizeRenderList()
127 for (
auto i = m_renderableNodes.rbegin(); i != m_renderableNodes.rend(); ++i) {
132 const bool wasDirty = node->isDirty();
133 if (!m_dirtyRegion.isEmpty()) {
135 node->addDirtyRegion(m_dirtyRegion,
true);
138 if (!m_obscuredRegion.isEmpty()) {
140 node->subtractDirtyRegion(m_obscuredRegion);
144 if (node->isOpaque()) {
145 m_obscuredRegion += node->boundingRectMin();
148 if (node->isDirty()) {
150 if (!m_background->rect().toRect().contains(node->boundingRectMax(),
true)) {
152 QRegion renderArea(m_background->rect().toRect());
153 QRegion outsideRegions = node->dirtyRegion().subtracted(renderArea);
154 if (!outsideRegions.isEmpty())
155 node->subtractDirtyRegion(outsideRegions);
159 if (node->isOpaque()) {
165 m_dirtyRegion += node->boundingRectMax();
166 m_dirtyRegion -= node->boundingRectMin();
169 m_dirtyRegion += node->dirtyRegion();
176 QRegion prevDirty = node->previousDirtyRegion();
177 if (!prevDirty.isNull())
178 m_dirtyRegion += prevDirty;
182 if (m_obscuredRegion.contains(m_background->rect().toAlignedRect())) {
189 m_dirtyRegion = QRegion();
190 m_obscuredRegion = QRegion();
194 for (
auto j = m_renderableNodes.begin(); j != m_renderableNodes.end(); ++j) {
197 if ((!node->isOpaque() || node->boundingRectMax() != node->boundingRectMin()) && !m_dirtyRegion.isEmpty()) {
203 node->addDirtyRegion(m_dirtyRegion,
true);
206 m_dirtyRegion += node->dirtyRegion();
209 QRegion updateRegion = m_dirtyRegion;
212 m_dirtyRegion = QRegion();
213 m_obscuredRegion = QRegion();
226void QSGAbstractSoftwareRenderer::setBackgroundRect(
const QRect &rect, qreal devicePixelRatio)
228 if (m_background->rect().toRect() == rect && m_devicePixelRatio == devicePixelRatio)
230 m_background->setRect(rect);
231 m_devicePixelRatio = devicePixelRatio;
232 renderableNode(m_background)->markGeometryDirty();