summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYoann Lopes <yoann.lopes@nokia.com>2010-11-22 10:37:19 +0100
committerYoann Lopes <yoann.lopes@nokia.com>2010-11-22 10:37:19 +0100
commit556db38aeee02db1b09378ce47fb835c5bcd268d (patch)
tree55d0699914a31d1974870c06b2ea6d8c9e8b7647
parent6734621437ebcc17224693338f1c7afb497f9935 (diff)
Build render lists only when needed.
-rw-r--r--src/scenegraph/coreapi/qmlrenderer.cpp55
-rw-r--r--src/scenegraph/coreapi/qmlrenderer.h10
2 files changed, 47 insertions, 18 deletions
diff --git a/src/scenegraph/coreapi/qmlrenderer.cpp b/src/scenegraph/coreapi/qmlrenderer.cpp
index eada040..056418d 100644
--- a/src/scenegraph/coreapi/qmlrenderer.cpp
+++ b/src/scenegraph/coreapi/qmlrenderer.cpp
@@ -122,6 +122,9 @@ T Heap<T, prealloc>::pop()
QMLRenderer::QMLRenderer()
: Renderer()
+ , m_rebuild_lists(false)
+ , m_needs_sorting(false)
+ , m_currentRenderOrder(1)
{
QStringList args = qApp->arguments();
#if defined(QML_RUNTIME_TESTING)
@@ -131,6 +134,19 @@ QMLRenderer::QMLRenderer()
GeometryDataUploader::setUseBuffers(!args.contains("--no-vbo"));
}
+void QMLRenderer::nodeChanged(Node *node, Node::DirtyFlags flags)
+{
+ Renderer::nodeChanged(node, flags);
+
+ quint32 rebuildFlags = Node::DirtyNodeAdded | Node::DirtyNodeRemoved | Node::DirtyMaterial | Node::DirtySubtreeEnabled;
+
+ if (flags & rebuildFlags)
+ m_rebuild_lists = true;
+
+ if (flags & (rebuildFlags | Node::DirtyClipList))
+ m_needs_sorting = true;
+}
+
void QMLRenderer::render()
{
#if defined (QML_RUNTIME_TESTING)
@@ -173,28 +189,35 @@ void QMLRenderer::render()
m_currentProgram = 0;
m_currentMatrix = 0;
- m_opaqueNodes.clear();
- m_transparentNodes.clear();
- int currentRenderOrder = 1;
- buildLists(rootNode(), &currentRenderOrder);
+ if (m_rebuild_lists) {
+ m_opaqueNodes.clear();
+ m_transparentNodes.clear();
+ m_currentRenderOrder = 1;
+ buildLists(rootNode());
+ m_rebuild_lists = false;
+ }
+
+ if (m_needs_sorting) {
+ qSort(m_opaqueNodes.begin(), m_opaqueNodes.end(), nodeLessThan);
+ m_needs_sorting = false;
+ }
m_renderOrderMatrix.setToIdentity();
- m_renderOrderMatrix.scale(1, 1, qreal(1) / currentRenderOrder);
+ m_renderOrderMatrix.scale(1, 1, qreal(1) / m_currentRenderOrder);
glDisable(GL_BLEND);
glDepthMask(true);
- qSort(m_opaqueNodes.begin(), m_opaqueNodes.end(), nodeLessThan);
#ifdef QML_RUNTIME_TESTING
if (m_render_opaque_nodes)
#endif
- renderNodes(m_opaqueNodes, currentRenderOrder);
+ renderNodes(m_opaqueNodes);
glEnable(GL_BLEND);
glDepthMask(false);
#ifdef QML_RUNTIME_TESTING
if (m_render_alpha_nodes)
#endif
- renderNodes(m_transparentNodes, currentRenderOrder);
+ renderNodes(m_transparentNodes);
if (m_currentProgram)
m_currentProgram->deactivate();
@@ -210,7 +233,7 @@ public:
bool operator < (const Foo &other) const { return nodeLessThan(second, other.second); }
};
-void QMLRenderer::buildLists(Node *node, int *currentRenderOrder)
+void QMLRenderer::buildLists(Node *node)
{
if (!node->isSubtreeEnabled())
return;
@@ -227,12 +250,12 @@ void QMLRenderer::buildLists(Node *node, int *currentRenderOrder)
#else
if (geomNode->material()->flags() & AbstractEffect::Blending) {
#endif
- geomNode->setRenderOrder(*currentRenderOrder - 1);
+ geomNode->setRenderOrder(m_currentRenderOrder - 1);
m_transparentNodes.append(geomNode);
} else {
- geomNode->setRenderOrder(*currentRenderOrder);
+ geomNode->setRenderOrder(m_currentRenderOrder);
m_opaqueNodes.append(geomNode);
- *currentRenderOrder += 2;
+ m_currentRenderOrder += 2;
}
}
}
@@ -253,7 +276,7 @@ void QMLRenderer::buildLists(Node *node, int *currentRenderOrder)
int baseCount = m_transparentNodes.size();
for (int i = 0; i < count; ++i) {
beginIndices[i] = m_transparentNodes.size();
- buildLists(node->childAtIndex(i), currentRenderOrder);
+ buildLists(node->childAtIndex(i));
endIndices[i] = m_transparentNodes.size();
}
@@ -280,13 +303,13 @@ void QMLRenderer::buildLists(Node *node, int *currentRenderOrder)
m_transparentNodes << m_tempNodes;
} else {
for (int i = 0; i < count; ++i)
- buildLists(node->childAtIndex(i), currentRenderOrder);
+ buildLists(node->childAtIndex(i));
}
}
-void QMLRenderer::renderNodes(const QVector<GeometryNode *> &list, int renderOrders)
+void QMLRenderer::renderNodes(const QVector<GeometryNode *> &list)
{
- const float scale = 1.0f / renderOrders;
+ const float scale = 1.0f / m_currentRenderOrder;
int count = list.count();
int currentRenderOrder = 0x80000000;
diff --git a/src/scenegraph/coreapi/qmlrenderer.h b/src/scenegraph/coreapi/qmlrenderer.h
index d2dd6f3..fbb97d3 100644
--- a/src/scenegraph/coreapi/qmlrenderer.h
+++ b/src/scenegraph/coreapi/qmlrenderer.h
@@ -52,9 +52,11 @@ public:
void render();
+ void nodeChanged(Node *node, Node::DirtyFlags flags);
+
private:
- void buildLists(Node *node, int *currentRenderOrder);
- void renderNodes(const QVector <GeometryNode *> &list, int renderOrders);
+ void buildLists(Node *node);
+ void renderNodes(const QVector <GeometryNode *> &list);
const ClipNode *m_currentClip;
AbstractEffect *m_currentMaterial;
@@ -65,6 +67,10 @@ private:
QVector<GeometryNode *> m_transparentNodes;
QVector<GeometryNode *> m_tempNodes;
+ bool m_rebuild_lists;
+ bool m_needs_sorting;
+ int m_currentRenderOrder;
+
#ifdef QML_RUNTIME_TESTING
bool m_render_opaque_nodes;
bool m_render_alpha_nodes;