aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/scenegraph/adaptations
diff options
context:
space:
mode:
authorAndy Nichols <andy.nichols@theqtcompany.com>2016-06-27 13:30:05 +0200
committerAndy Nichols <andy.nichols@qt.io>2016-06-28 10:17:47 +0000
commit261675f8a404b6d19df72a7d6c3432cc58fbafe6 (patch)
treec1b03c1b6466b74588e5c23f16be555ca4e3711c /src/quick/scenegraph/adaptations
parenta0aadc3226d99d6d950359383df596928f300001 (diff)
Software Adaptation: Improve clip node handling
This commit solves two issues that were coming up with nested clip nodes. The first was that determining the intersection of two or more nested clip nodes was calculated incorrectly. This was fixed by making sure the calculated clip region was in the correct coordinate space. The second issue was because there was no distinction between an empty unclipped region, and a completely clipped region. So a property was added to specify when a RenderableNode had a clipRegion so that the empty QRegion could be interpreted correctly. This makes sure that we don't end up drawing nodes that were culled. Change-Id: Id7af092f7fc6a4602b44b585b7dee14084136962 Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
Diffstat (limited to 'src/quick/scenegraph/adaptations')
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp14
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode_p.h3
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp13
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater_p.h4
4 files changed, 25 insertions, 9 deletions
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp
index 7cfbc2dfda..385b257e44 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp
@@ -58,6 +58,7 @@ QSGSoftwareRenderableNode::QSGSoftwareRenderableNode(NodeType type, QSGNode *nod
: m_nodeType(type)
, m_isOpaque(true)
, m_isDirty(true)
+ , m_hasClipRegion(false)
, m_opacity(1.0f)
{
switch (m_nodeType) {
@@ -179,8 +180,12 @@ void QSGSoftwareRenderableNode::update()
m_boundingRect = m_transform.mapRect(boundingRect);
- if (m_clipRegion.rectCount() == 1) {
- m_boundingRect = m_boundingRect.intersected(m_clipRegion.rects().first());
+ if (m_hasClipRegion && m_clipRegion.rectCount() <= 1) {
+ // If there is a clipRegion, and it is empty, the item wont be rendered
+ if (m_clipRegion.isEmpty())
+ m_boundingRect = QRect();
+ else
+ m_boundingRect = m_boundingRect.intersected(m_clipRegion.rects().first());
}
// Overrides
@@ -284,12 +289,13 @@ void QSGSoftwareRenderableNode::setTransform(const QTransform &transform)
update();
}
-void QSGSoftwareRenderableNode::setClipRegion(const QRegion &clipRect)
+void QSGSoftwareRenderableNode::setClipRegion(const QRegion &clipRect, bool hasClipRegion)
{
- if (m_clipRegion == clipRect)
+ if (m_clipRegion == clipRect && m_hasClipRegion == hasClipRegion)
return;
m_clipRegion = clipRect;
+ m_hasClipRegion = hasClipRegion;
update();
}
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode_p.h
index d1a71cd580..fcbea7391a 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode_p.h
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode_p.h
@@ -97,7 +97,7 @@ public:
bool isDirtyRegionEmpty() const;
void setTransform(const QTransform &transform);
- void setClipRegion(const QRegion &clipRegion);
+ void setClipRegion(const QRegion &clipRegion, bool hasClipRegion = true);
void setOpacity(float opacity);
QTransform transform() const { return m_transform; }
QRegion clipRegion() const { return m_clipRegion; }
@@ -136,6 +136,7 @@ private:
QTransform m_transform;
QRegion m_clipRegion;
+ bool m_hasClipRegion;
float m_opacity;
QRect m_boundingRect;
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp
index 1681f3c06b..f13edb87fb 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp
@@ -58,6 +58,7 @@ QSGSoftwareRenderableNodeUpdater::QSGSoftwareRenderableNodeUpdater(QSGAbstractSo
m_opacityState.push(1.0f);
// Invalid RectF by default for no clip
m_clipState.push(QRegion());
+ m_hasClip = false;
m_transformState.push(QTransform());
}
@@ -81,10 +82,13 @@ void QSGSoftwareRenderableNodeUpdater::endVisit(QSGTransformNode *)
bool QSGSoftwareRenderableNodeUpdater::visit(QSGClipNode *node)
{
// Make sure to translate the clip rect into world coordinates
- if (m_clipState.top().isEmpty()) {
+ if (m_clipState.count() == 1) {
m_clipState.push(m_transformState.top().map(QRegion(node->clipRect().toRect())));
- } else
- m_clipState.push(m_transformState.top().map(QRegion(node->clipRect().toRect()).intersected(m_clipState.top())));
+ m_hasClip = true;
+ } else {
+ const QRegion transformedClipRect = m_transformState.top().map(QRegion(node->clipRect().toRect()));
+ m_clipState.push(transformedClipRect.intersected(m_clipState.top()));
+ }
m_stateMap[node] = currentState(node);
return true;
}
@@ -92,6 +96,8 @@ bool QSGSoftwareRenderableNodeUpdater::visit(QSGClipNode *node)
void QSGSoftwareRenderableNodeUpdater::endVisit(QSGClipNode *)
{
m_clipState.pop();
+ if (m_clipState.count() == 1)
+ m_hasClip = false;
}
bool QSGSoftwareRenderableNodeUpdater::visit(QSGGeometryNode *node)
@@ -264,6 +270,7 @@ QSGSoftwareRenderableNodeUpdater::NodeState QSGSoftwareRenderableNodeUpdater::cu
NodeState state;
state.opacity = m_opacityState.top();
state.clip = m_clipState.top();
+ state.hasClip = m_hasClip;
state.transform = m_transformState.top();
state.parent = node->parent();
return state;
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater_p.h
index 97492d4347..d7c12e8b02 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater_p.h
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater_p.h
@@ -93,6 +93,7 @@ private:
struct NodeState {
float opacity;
QRegion clip;
+ bool hasClip;
QTransform transform;
QSGNode *parent;
};
@@ -105,6 +106,7 @@ private:
QSGAbstractSoftwareRenderer *m_renderer;
QStack<float> m_opacityState;
QStack<QRegion> m_clipState;
+ bool m_hasClip;
QStack<QTransform> m_transformState;
QHash<QSGNode*,NodeState> m_stateMap;
};
@@ -122,7 +124,7 @@ bool QSGSoftwareRenderableNodeUpdater::updateRenderableNode(QSGSoftwareRenderabl
//Update the node
renderableNode->setTransform(m_transformState.top());
renderableNode->setOpacity(m_opacityState.top());
- renderableNode->setClipRegion(m_clipState.top());
+ renderableNode->setClipRegion(m_clipState.top(), m_hasClip);
renderableNode->update();
m_stateMap[node] = currentState(node);