summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar.sletta@nokia.com>2010-11-22 12:37:17 +0100
committerGunnar Sletta <gunnar.sletta@nokia.com>2010-11-22 12:37:17 +0100
commit9a22b0987d916b7b12d0cf444bcae8f213c43cfa (patch)
treeb7207cb5044540d0a42aad32cc1612ff866ba469
parent600e0e08c20255e674b1102aa4d2d1c6ef49091d (diff)
parent15b2858d46a8291756bec29bf7dc0e7d804e708a (diff)
Merge branch 'master' of scm.dev.nokia.troll.no:research/qt-scene-graph
-rw-r--r--src/adaptationlayers/default/default_rectanglenode.cpp17
-rw-r--r--src/canvas/qxclipnode.cpp12
-rw-r--r--src/graphicsitems/qxitem.cpp16
-rw-r--r--src/graphicsitems/qxitem.h8
-rw-r--r--src/graphicsitems/qxitem_p.h4
-rw-r--r--src/scenegraph/coreapi/qmlrenderer.cpp55
-rw-r--r--src/scenegraph/coreapi/qmlrenderer.h10
7 files changed, 85 insertions, 37 deletions
diff --git a/src/adaptationlayers/default/default_rectanglenode.cpp b/src/adaptationlayers/default/default_rectanglenode.cpp
index cb4f85d..70b9647 100644
--- a/src/adaptationlayers/default/default_rectanglenode.cpp
+++ b/src/adaptationlayers/default/default_rectanglenode.cpp
@@ -289,18 +289,21 @@ void DefaultRectangleNode::updateGeometry()
if (m_radius > 0) {
// Rounded corners.
+
+ // Radius should never exceeds half of the width or half of the height
+ qreal radius = qMin(qMin(m_rect.width() / 2, m_rect.height() / 2), m_radius);
QRectF innerRect = m_rect;
- innerRect.adjust(m_radius, m_radius, -m_radius, -m_radius);
+ innerRect.adjust(radius, radius, -radius, -radius);
if (m_pen_width & 1) {
// Pen width is odd, so add the offset as documented.
innerRect.moveLeft(innerRect.left() + qreal(0.5));
innerRect.moveTop(innerRect.top() + qreal(0.5));
}
- qreal innerRadius = m_radius - m_pen_width * qreal(0.5);
- qreal outerRadius = m_radius + m_pen_width * qreal(0.5);
+ qreal innerRadius = radius - m_pen_width * qreal(0.5);
+ qreal outerRadius = radius + m_pen_width * qreal(0.5);
- int segments = qMin(15, qCeil(outerRadius)); // Number of segments per corner.
+ int segments = qMin(30, qCeil(outerRadius)); // Number of segments per corner.
/*
@@ -332,7 +335,7 @@ void DefaultRectangleNode::updateGeometry()
QList<ushort> borderIndices;
int nextGradientStop = 0;
- qreal gradientPos = (m_radius - innerRadius) / (innerRect.height() + 2 * m_radius);
+ qreal gradientPos = (radius - innerRadius) / (innerRect.height() + 2 * radius);
while (nextGradientStop < stops.size() && stops.at(nextGradientStop).first <= gradientPos)
++nextGradientStop;
@@ -353,10 +356,10 @@ void DefaultRectangleNode::updateGeometry()
qreal lX = innerRect.left() - outerRadius * s; // current outer left x-coordinate.
qreal rX = innerRect.right() + outerRadius * s; // current outer right x-coordinate.
- gradientPos = ((part ? innerRect.height() : 0) + m_radius - innerRadius * c) / (innerRect.height() + 2 * m_radius);
+ gradientPos = ((part ? innerRect.height() : 0) + radius - innerRadius * c) / (innerRect.height() + 2 * radius);
while (nextGradientStop < stops.size() && stops.at(nextGradientStop).first <= gradientPos) {
// Insert vertices at gradient stops.
- qreal gy = (innerRect.top() - m_radius) + stops.at(nextGradientStop).first * (innerRect.height() + 2 * m_radius);
+ qreal gy = (innerRect.top() - radius) + stops.at(nextGradientStop).first * (innerRect.height() + 2 * radius);
Q_ASSERT(fillVertexCount >= 2);
qreal t = (gy - py) / (y - py);
qreal glx = plx * (1 - t) + t * lx;
diff --git a/src/canvas/qxclipnode.cpp b/src/canvas/qxclipnode.cpp
index aded473..4e3df53 100644
--- a/src/canvas/qxclipnode.cpp
+++ b/src/canvas/qxclipnode.cpp
@@ -88,10 +88,12 @@ void QxClipNode::updateGeometry()
Geometry *g = geometry();
int vertexCount = 0;
+ // Radius should never exceeds half of the width or half of the height
+ qreal radius = qMin(qMin(m_rect.width() / 2, m_rect.height() / 2), m_radius);
QRectF rect = m_rect;
- rect.adjust(m_radius, m_radius, -m_radius, -m_radius);
+ rect.adjust(radius, radius, -radius, -radius);
- int segments = qMin(15, qCeil(m_radius)); // Number of segments per corner.
+ int segments = qMin(30, qCeil(radius)); // Number of segments per corner.
// Overestimate the number of vertices and indices, reduce afterwards when the actual numbers are known.
g->setVertexCount((segments + 1) * 4);
@@ -105,9 +107,9 @@ void QxClipNode::updateGeometry()
qreal angle = qreal(0.5 * M_PI) * (part + i / qreal(segments));
qreal s = qFastSin(angle);
qreal c = qFastCos(angle);
- qreal y = (part ? rect.bottom() : rect.top()) - m_radius * c; // current inner y-coordinate.
- qreal lx = rect.left() - m_radius * s; // current inner left x-coordinate.
- qreal rx = rect.right() + m_radius * s; // current inner right x-coordinate.
+ qreal y = (part ? rect.bottom() : rect.top()) - radius * c; // current inner y-coordinate.
+ qreal lx = rect.left() - radius * s; // current inner left x-coordinate.
+ qreal rx = rect.right() + radius * s; // current inner right x-coordinate.
vertices[vertexCount++].position = QVector2D(rx, y);
vertices[vertexCount++].position = QVector2D(lx, y);
diff --git a/src/graphicsitems/qxitem.cpp b/src/graphicsitems/qxitem.cpp
index 7101215..eb05b0c 100644
--- a/src/graphicsitems/qxitem.cpp
+++ b/src/graphicsitems/qxitem.cpp
@@ -765,6 +765,22 @@ QPointF QxItem::mapFromItem(QxItem *item, const QPointF &point) const
return mapFromScene(point);
}
+bool QxItem::isEnabled() const
+{
+ Q_D(const QxItem);
+ return d->enabled;
+}
+
+void QxItem::setEnabled(bool e)
+{
+ Q_D(QxItem);
+ if (e == d->enabled)
+ return;
+
+ d->enabled = e;
+ emit enabledChanged();
+}
+
bool QxItem::isVisible() const
{
Q_D(const QxItem);
diff --git a/src/graphicsitems/qxitem.h b/src/graphicsitems/qxitem.h
index 2e95fce..818458f 100644
--- a/src/graphicsitems/qxitem.h
+++ b/src/graphicsitems/qxitem.h
@@ -124,12 +124,8 @@ public:
QPointF mapToItem(QxItem *, const QPointF &) const;
QPointF mapFromItem(QxItem *, const QPointF &) const;
- bool isEnabled() const { return true; }
- void setEnabled(bool e)
- {
- Q_UNUSED(e);
- emit enabledChanged();
- }
+ bool isEnabled() const;
+ void setEnabled(bool e);
bool isVisible() const;
void setVisible(bool);
diff --git a/src/graphicsitems/qxitem_p.h b/src/graphicsitems/qxitem_p.h
index 5a85618..e54a6f7 100644
--- a/src/graphicsitems/qxitem_p.h
+++ b/src/graphicsitems/qxitem_p.h
@@ -133,6 +133,7 @@ public:
, widthValid(0)
, heightValid(0)
, transformNodeAttached(0)
+ , enabled(1)
, visible(1)
, clip(0)
, filtersChildMouse(0)
@@ -198,6 +199,7 @@ public:
quint32 widthValid:1;
quint32 heightValid:1;
quint32 transformNodeAttached:1;
+ quint32 enabled:1;
quint32 visible:1;
quint32 clip:1;
quint32 filtersChildMouse:1;
@@ -210,7 +212,7 @@ public:
quint32 smooth:1;
quint32 transformOriginDirty : 1;
quint32 doneEventPreHandler : 1;
- quint32 padding: 16;
+ quint32 padding: 15;
void attachTransformNode();
void detachTransformNode();
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;