diff options
author | Gunnar Sletta <gunnar.sletta@nokia.com> | 2010-11-22 12:37:17 +0100 |
---|---|---|
committer | Gunnar Sletta <gunnar.sletta@nokia.com> | 2010-11-22 12:37:17 +0100 |
commit | 9a22b0987d916b7b12d0cf444bcae8f213c43cfa (patch) | |
tree | b7207cb5044540d0a42aad32cc1612ff866ba469 | |
parent | 600e0e08c20255e674b1102aa4d2d1c6ef49091d (diff) | |
parent | 15b2858d46a8291756bec29bf7dc0e7d804e708a (diff) |
Merge branch 'master' of scm.dev.nokia.troll.no:research/qt-scene-graph
-rw-r--r-- | src/adaptationlayers/default/default_rectanglenode.cpp | 17 | ||||
-rw-r--r-- | src/canvas/qxclipnode.cpp | 12 | ||||
-rw-r--r-- | src/graphicsitems/qxitem.cpp | 16 | ||||
-rw-r--r-- | src/graphicsitems/qxitem.h | 8 | ||||
-rw-r--r-- | src/graphicsitems/qxitem_p.h | 4 | ||||
-rw-r--r-- | src/scenegraph/coreapi/qmlrenderer.cpp | 55 | ||||
-rw-r--r-- | src/scenegraph/coreapi/qmlrenderer.h | 10 |
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(), ¤tRenderOrder); + 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; |