aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/scenegraph/coreapi
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2016-07-27 11:59:17 +0200
committerSimon Hausmann <simon.hausmann@qt.io>2016-08-02 16:15:31 +0000
commit44e86f701247a86da37e3a94b77853b57ab1b303 (patch)
tree109ece6b5393a159062e9b1eca906c176b66035b /src/quick/scenegraph/coreapi
parentcf186c441dd0d68dbfac416ee6d09d4f923a0a4c (diff)
Add optional flags and rect to QSGRenderNode
Having rendernodes triggering fullscreen updates with the software backend is not ideal. Therefore, introduce the option of reporting that the rendernode is well-behaving, meaning it only writes inside the reported bounding rectangle. Similarly, the OpenGL batch renderer can keep using the depth buffer when the rendernode is known to behave like the renderer expects. Change-Id: I6acc434432c2504776f26e8917b5434b44be293d Reviewed-by: Gunnar Sletta <gunnar@sletta.org>
Diffstat (limited to 'src/quick/scenegraph/coreapi')
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp8
-rw-r--r--src/quick/scenegraph/coreapi/qsgrendernode.cpp67
-rw-r--r--src/quick/scenegraph/coreapi/qsgrendernode.h10
3 files changed, 82 insertions, 3 deletions
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
index bee2015007..49bbbf0ba8 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
@@ -1033,11 +1033,13 @@ void Renderer::nodeWasAdded(QSGNode *node, Node *shadowParent)
m_rebuild |= FullRebuild;
} else if (node->type() == QSGNode::RenderNodeType) {
- RenderNodeElement *e = new RenderNodeElement(static_cast<QSGRenderNode *>(node));
+ QSGRenderNode *rn = static_cast<QSGRenderNode *>(node);
+ RenderNodeElement *e = new RenderNodeElement(rn);
snode->data = e;
- Q_ASSERT(!m_renderNodeElements.contains(static_cast<QSGRenderNode *>(node)));
+ Q_ASSERT(!m_renderNodeElements.contains(rn));
m_renderNodeElements.insert(e->renderNode, e);
- m_useDepthBuffer = false;
+ if (!rn->flags().testFlag(QSGRenderNode::DepthAwareRendering))
+ m_useDepthBuffer = false;
m_rebuild |= FullRebuild;
}
diff --git a/src/quick/scenegraph/coreapi/qsgrendernode.cpp b/src/quick/scenegraph/coreapi/qsgrendernode.cpp
index 365abd09e2..5915d51f2b 100644
--- a/src/quick/scenegraph/coreapi/qsgrendernode.cpp
+++ b/src/quick/scenegraph/coreapi/qsgrendernode.cpp
@@ -179,6 +179,11 @@ QSGRenderNode::StateFlags QSGRenderNode::changedStates() const
default value according to the OpenGL specification. For other APIs, see
the documentation for changedStates() for more information.
+ \note Depth writes are disabled when this function is called (for example,
+ glDepthMask(false) in case of OpenGL). Enabling depth writes can lead to
+ unexpected results, depending on the scenegraph backend in use, so nodes
+ should avoid this.
+
For APIs other than OpenGL, it will likely be necessary to query certain
API-specific resources (for example, the graphics device or the command
list/buffer to add the commands to). This is done via QSGRendererInterface.
@@ -211,6 +216,68 @@ void QSGRenderNode::releaseResources()
}
/*!
+ \enum QSGRenderNode::RenderingFlag
+
+ Possible values for the bitmask returned from flags().
+
+ \value BoundedRectRendering Indicates that the implementation of render()
+ does not render outside the area reported from rect() in item
+ coordinates. Such node implementations can lead to more efficient rendering,
+ depending on the scenegraph backend. For example, the software backend can
+ continue to use the more optimal partial update path when all render nodes
+ in the scene have this flag set.
+
+ \value DepthAwareRendering Indicates that the implementations of render()
+ conforms to scenegraph expectations by only generating a Z value of 0 in
+ scene coordinates which is then transformed by the matrices retrieved from
+ RenderState::projectionMatrix() and matrix(), as described in the notes for
+ render(). Such node implementations can lead to more efficient rendering,
+ depending on the scenegraph backend. For example, the batching OpenGL
+ renderer can continue to use a more optimal path when all render nodes in
+ the scene have this flag set.
+
+ \value OpaqueRendering Indicates that the implementation of render() writes
+ out opaque pixels for the entire area reported from rect(). By default the
+ renderers must assume that render() can also output semi or fully
+ transparent pixels. Setting this flag can improve performance in some
+ cases.
+
+ \sa render(), rect()
+ */
+
+/*!
+ \return flags describing the behavior of this render node.
+
+ The default implementation returns 0.
+
+ \sa RenderingFlag, rect()
+ */
+QSGRenderNode::RenderingFlags QSGRenderNode::flags() const
+{
+ return 0;
+}
+
+/*!
+ \return the bounding rectangle in item coordinates for the area render()
+ touches. The value is only in use when flags() includes
+ BoundedRectRendering, ignored otherwise.
+
+ Reporting the rectangle in combination with BoundedRectRendering is
+ particularly important with the \c software backend because otherwise
+ having a rendernode in the scene would trigger fullscreen updates, skipping
+ all partial update optimizations.
+
+ For rendernodes covering the entire area of a corresponding QQuickItem the
+ return value will be (0, 0, item->width(), item->height()).
+
+ \sa flags()
+*/
+QRectF QSGRenderNode::rect() const
+{
+ return QRectF();
+}
+
+/*!
\return pointer to the current model-view matrix.
*/
const QMatrix4x4 *QSGRenderNode::matrix() const
diff --git a/src/quick/scenegraph/coreapi/qsgrendernode.h b/src/quick/scenegraph/coreapi/qsgrendernode.h
index 6eb425c03b..f6bc40d3ee 100644
--- a/src/quick/scenegraph/coreapi/qsgrendernode.h
+++ b/src/quick/scenegraph/coreapi/qsgrendernode.h
@@ -61,6 +61,13 @@ public:
};
Q_DECLARE_FLAGS(StateFlags, StateFlag)
+ enum RenderingFlag {
+ BoundedRectRendering = 0x01,
+ DepthAwareRendering = 0x02,
+ OpaqueRendering = 0x04
+ };
+ Q_DECLARE_FLAGS(RenderingFlags, RenderingFlag)
+
struct Q_QUICK_EXPORT RenderState {
virtual ~RenderState();
virtual const QMatrix4x4 *projectionMatrix() const = 0;
@@ -78,6 +85,8 @@ public:
virtual StateFlags changedStates() const;
virtual void render(const RenderState *state) = 0;
virtual void releaseResources();
+ virtual RenderingFlags flags() const;
+ virtual QRectF rect() const;
const QMatrix4x4 *matrix() const;
const QSGClipNode *clipList() const;
@@ -89,6 +98,7 @@ private:
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QSGRenderNode::StateFlags)
+Q_DECLARE_OPERATORS_FOR_FLAGS(QSGRenderNode::RenderingFlags)
QT_END_NAMESPACE