diff options
Diffstat (limited to 'src/declarative/scenegraph/coreapi')
-rw-r--r-- | src/declarative/scenegraph/coreapi/qsgdefaultrenderer.cpp | 527 | ||||
-rw-r--r-- | src/declarative/scenegraph/coreapi/qsgdefaultrenderer_p.h | 123 | ||||
-rw-r--r-- | src/declarative/scenegraph/coreapi/qsggeometry.cpp | 466 | ||||
-rw-r--r-- | src/declarative/scenegraph/coreapi/qsggeometry.h | 295 | ||||
-rw-r--r-- | src/declarative/scenegraph/coreapi/qsggeometry_p.h | 73 | ||||
-rw-r--r-- | src/declarative/scenegraph/coreapi/qsgmaterial.cpp | 535 | ||||
-rw-r--r-- | src/declarative/scenegraph/coreapi/qsgmaterial.h | 144 | ||||
-rw-r--r-- | src/declarative/scenegraph/coreapi/qsgnode.cpp | 1264 | ||||
-rw-r--r-- | src/declarative/scenegraph/coreapi/qsgnode.h | 348 | ||||
-rw-r--r-- | src/declarative/scenegraph/coreapi/qsgnodeupdater.cpp | 287 | ||||
-rw-r--r-- | src/declarative/scenegraph/coreapi/qsgnodeupdater_p.h | 86 | ||||
-rw-r--r-- | src/declarative/scenegraph/coreapi/qsgrenderer.cpp | 743 | ||||
-rw-r--r-- | src/declarative/scenegraph/coreapi/qsgrenderer_p.h | 234 |
13 files changed, 0 insertions, 5125 deletions
diff --git a/src/declarative/scenegraph/coreapi/qsgdefaultrenderer.cpp b/src/declarative/scenegraph/coreapi/qsgdefaultrenderer.cpp deleted file mode 100644 index 56a6e0e5d9..0000000000 --- a/src/declarative/scenegraph/coreapi/qsgdefaultrenderer.cpp +++ /dev/null @@ -1,527 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#define GL_GLEXT_PROTOTYPES - -#include "qsgdefaultrenderer_p.h" -#include "qsgmaterial.h" - -#include <QtCore/qvarlengtharray.h> -#include <QtGui/qguiapplication.h> -#include <QtCore/qpair.h> -#include <QtCore/QElapsedTimer> - -//#define FORCE_NO_REORDER - -// #define RENDERER_DEBUG -#ifdef RENDERER_DEBUG -#define DEBUG_THRESHOLD 0 -QElapsedTimer debugTimer; -int materialChanges; -int geometryNodesDrawn; -#endif - -QT_BEGIN_NAMESPACE - -static bool nodeLessThan(QSGGeometryNode *a, QSGGeometryNode *b) -{ - // Sort by clip... - if (a->clipList() != b->clipList()) - return a->clipList() < b->clipList(); - - // Sort by material definition - QSGMaterialType *aDef = a->material()->type(); - QSGMaterialType *bDef = b->material()->type(); - - if (aDef != bDef) - return aDef < bDef; - - // Sort by material state - int cmp = a->material()->compare(b->material()); - if (cmp != 0) - return cmp < 0; - - return a->matrix() < b->matrix(); -} - -static bool nodeLessThanWithRenderOrder(QSGGeometryNode *a, QSGGeometryNode *b) -{ - // Sort by clip... - if (a->clipList() != b->clipList()) - return a->clipList() < b->clipList(); - - // Sort by material definition - QSGMaterialType *aDef = a->material()->type(); - QSGMaterialType *bDef = b->material()->type(); - - if (!(a->material()->flags() & QSGMaterial::Blending)) { - int aOrder = a->renderOrder(); - int bOrder = b->renderOrder(); - if (aOrder != bOrder) - return aOrder > bOrder; - } - - if (aDef != bDef) - return aDef < bDef; - - // Sort by material state - int cmp = a->material()->compare(b->material()); - if (cmp != 0) - return cmp < 0; - - return a->matrix() < b->matrix(); -} - - -QSGDefaultRenderer::IndexGeometryNodePair::IndexGeometryNodePair(int i, QSGGeometryNode *node) - : QPair<int, QSGGeometryNode *>(i, node) -{ -} - -bool QSGDefaultRenderer::IndexGeometryNodePair::operator < (const QSGDefaultRenderer::IndexGeometryNodePair &other) const -{ - return nodeLessThan(second, other.second); -} - - -QSGDefaultRenderer::IndexGeometryNodePairHeap::IndexGeometryNodePairHeap() - : v(64) -{ -} - -void QSGDefaultRenderer::IndexGeometryNodePairHeap::insert(const QSGDefaultRenderer::IndexGeometryNodePair &x) -{ - int i = v.size(); - v.add(x); - while (i != 0 && v.at(i) < v.at(parent(i))) { - qSwap(v.at(parent(i)), v.at(i)); - i = parent(i); - } -} - -QSGDefaultRenderer::IndexGeometryNodePair QSGDefaultRenderer::IndexGeometryNodePairHeap::pop() -{ - IndexGeometryNodePair x = top(); - if (v.size() > 1) - qSwap(v.first(), v.last()); - v.pop_back(); - int i = 0; - while (left(i) < v.size()) { - int low = left(i); - if (right(i) < v.size() && v.at(right(i)) < v.at(low)) - low = right(i); - if (!(v.at(low) < v.at(i))) - break; - qSwap(v.at(i), v.at(low)); - i = low; - } - return x; -} - - -QSGDefaultRenderer::QSGDefaultRenderer(QSGContext *context) - : QSGRenderer(context) - , m_opaqueNodes(64) - , m_transparentNodes(64) - , m_tempNodes(64) - , m_rebuild_lists(false) - , m_needs_sorting(false) - , m_sort_front_to_back(false) - , m_currentRenderOrder(1) -{ - QStringList args = qApp->arguments(); -#if defined(QML_RUNTIME_TESTING) - m_render_opaque_nodes = !args.contains(QLatin1String("--no-opaque-nodes")); - m_render_alpha_nodes = !args.contains(QLatin1String("--no-alpha-nodes")); -#endif -} - -void QSGDefaultRenderer::nodeChanged(QSGNode *node, QSGNode::DirtyFlags flags) -{ - QSGRenderer::nodeChanged(node, flags); - - quint32 rebuildFlags = QSGNode::DirtyNodeAdded | QSGNode::DirtyNodeRemoved - | QSGNode::DirtyMaterial | QSGNode::DirtyOpacity - | QSGNode::DirtyForceUpdate; - - if (flags & rebuildFlags) - m_rebuild_lists = true; - - if (flags & (rebuildFlags | QSGNode::DirtyClipList)) - m_needs_sorting = true; -} - -void QSGDefaultRenderer::render() -{ -#if defined (QML_RUNTIME_TESTING) - static bool dumpTree = qApp->arguments().contains(QLatin1String("--dump-tree")); - if (dumpTree) { - printf("\n\n"); - QSGNodeDumper::dump(rootNode()); - } -#endif - -#ifdef RENDERER_DEBUG - debugTimer.invalidate(); - debugTimer.start(); - geometryNodesDrawn = 0; - materialChanges = 0; -#endif - - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_BLEND); - - glFrontFace(isMirrored() ? GL_CW : GL_CCW); - glDisable(GL_CULL_FACE); - - glEnable(GL_DEPTH_TEST); - glDepthMask(true); - glDepthFunc(GL_GREATER); -#if defined(QT_OPENGL_ES) - glClearDepthf(0); -#else - glClearDepth(0); -#endif - - glDisable(GL_SCISSOR_TEST); - glClearColor(m_clear_color.redF(), m_clear_color.greenF(), m_clear_color.blueF(), m_clear_color.alphaF()); - -#ifdef RENDERER_DEBUG - int debugtimeSetup = debugTimer.elapsed(); -#endif - - bindable()->clear(clearMode()); - -#ifdef RENDERER_DEBUG - int debugtimeClear = debugTimer.elapsed(); -#endif - - QRect r = viewportRect(); - glViewport(r.x(), deviceRect().bottom() - r.bottom(), r.width(), r.height()); - m_current_projection_matrix = projectionMatrix(); - m_current_model_view_matrix.setToIdentity(); - - m_currentClip = 0; - glDisable(GL_STENCIL_TEST); - - m_currentMaterial = 0; - m_currentProgram = 0; - m_currentMatrix = 0; - - if (m_rebuild_lists) { - m_opaqueNodes.reset(); - m_transparentNodes.reset(); - m_currentRenderOrder = 1; - buildLists(rootNode()); - m_rebuild_lists = false; - } - -#ifdef RENDERER_DEBUG - int debugtimeLists = debugTimer.elapsed(); -#endif - - - if (m_needs_sorting) { - if (!m_opaqueNodes.isEmpty()) { - qSort(&m_opaqueNodes.first(), &m_opaqueNodes.first() + m_opaqueNodes.size(), - m_sort_front_to_back - ? nodeLessThanWithRenderOrder - : nodeLessThan); - } - m_needs_sorting = false; - } - -#ifdef RENDERER_DEBUG - int debugtimeSorting = debugTimer.elapsed(); -#endif - - m_renderOrderMatrix.setToIdentity(); - m_renderOrderMatrix.scale(1, 1, qreal(1) / m_currentRenderOrder); - - glDisable(GL_BLEND); - glDepthMask(true); -#ifdef QML_RUNTIME_TESTING - if (m_render_opaque_nodes) -#endif - { -#if defined (QML_RUNTIME_TESTING) - if (dumpTree) - qDebug() << "Opaque Nodes:"; -#endif - renderNodes(m_opaqueNodes); - } - -#ifdef RENDERER_DEBUG - int debugtimeOpaque = debugTimer.elapsed(); - int opaqueNodes = geometryNodesDrawn; - int opaqueMaterialChanges = materialChanges; -#endif - - glEnable(GL_BLEND); - glDepthMask(false); -#ifdef QML_RUNTIME_TESTING - if (m_render_alpha_nodes) -#endif - { -#if defined (QML_RUNTIME_TESTING) - if (dumpTree) - qDebug() << "Alpha Nodes:"; -#endif - renderNodes(m_transparentNodes); - } - -#ifdef RENDERER_DEBUG - int debugtimeAlpha = debugTimer.elapsed(); -#endif - - - if (m_currentProgram) - m_currentProgram->deactivate(); - -#ifdef RENDERER_DEBUG - if (debugTimer.elapsed() > DEBUG_THRESHOLD) { - printf(" --- Renderer breakdown:\n" - " - setup=%d, clear=%d, building=%d, sorting=%d, opaque=%d, alpha=%d\n" - " - material changes: opaque=%d, alpha=%d, total=%d\n" - " - geometry ndoes: opaque=%d, alpha=%d, total=%d\n", - debugtimeSetup, - debugtimeClear - debugtimeSetup, - debugtimeLists - debugtimeClear, - debugtimeSorting - debugtimeLists, - debugtimeOpaque - debugtimeSorting, - debugtimeAlpha - debugtimeOpaque, - opaqueMaterialChanges, materialChanges - opaqueMaterialChanges, materialChanges, - opaqueNodes, geometryNodesDrawn - opaqueNodes, geometryNodesDrawn); - } -#endif - -} - -void QSGDefaultRenderer::setSortFrontToBackEnabled(bool sort) -{ - printf("setting sorting to... %d\n", sort); - m_sort_front_to_back = sort; -} - -bool QSGDefaultRenderer::isSortFrontToBackEnabled() const -{ - return m_sort_front_to_back; -} - -void QSGDefaultRenderer::buildLists(QSGNode *node) -{ - if (node->isSubtreeBlocked()) - return; - - if (node->type() == QSGNode::GeometryNodeType) { - QSGGeometryNode *geomNode = static_cast<QSGGeometryNode *>(node); - qreal opacity = geomNode->inheritedOpacity(); - QSGMaterial *m = geomNode->activeMaterial(); - -#ifdef FORCE_NO_REORDER - if (true) { -#else - if ((m->flags() & QSGMaterial::Blending) || opacity < 1) { -#endif - geomNode->setRenderOrder(m_currentRenderOrder - 1); - m_transparentNodes.add(geomNode); - } else { - geomNode->setRenderOrder(m_currentRenderOrder); - m_opaqueNodes.add(geomNode); - m_currentRenderOrder += 2; - } - } - - if (!node->firstChild()) - return; - -#ifdef FORCE_NO_REORDER - static bool reorder = false; -#else - static bool reorder = qApp->arguments().contains(QLatin1String("--reorder")); -#endif - - if (reorder && node->firstChild() != node->lastChild() && (node->flags() & QSGNode::ChildrenDoNotOverlap)) { - QVarLengthArray<int, 16> beginIndices; - QVarLengthArray<int, 16> endIndices; - int baseCount = m_transparentNodes.size(); - int count = 0; - for (QSGNode *c = node->firstChild(); c; c = c->nextSibling()) { - beginIndices.append(m_transparentNodes.size()); - buildLists(c); - endIndices.append(m_transparentNodes.size()); - ++count; - } - - int childNodeCount = m_transparentNodes.size() - baseCount; - if (childNodeCount) { - m_tempNodes.reset(); - m_tempNodes.reserve(childNodeCount); - while (childNodeCount) { - for (int i = 0; i < count; ++i) { - if (beginIndices[i] != endIndices[i]) - m_heap.insert(IndexGeometryNodePair(i, m_transparentNodes.at(beginIndices[i]++))); - } - while (!m_heap.isEmpty()) { - IndexGeometryNodePair pair = m_heap.pop(); - m_tempNodes.add(pair.second); - --childNodeCount; - int i = pair.first; - if (beginIndices[i] != endIndices[i] && !nodeLessThan(m_transparentNodes.at(beginIndices[i]), pair.second)) - m_heap.insert(IndexGeometryNodePair(i, m_transparentNodes.at(beginIndices[i]++))); - } - } - Q_ASSERT(m_tempNodes.size() == m_transparentNodes.size() - baseCount); - - qMemCopy(&m_transparentNodes.at(baseCount), &m_tempNodes.at(0), m_tempNodes.size() * sizeof(QSGGeometryNode *)); - } - } else { - for (QSGNode *c = node->firstChild(); c; c = c->nextSibling()) - buildLists(c); - } -} - -void QSGDefaultRenderer::renderNodes(const QDataBuffer<QSGGeometryNode *> &list) -{ - const float scale = 1.0f / m_currentRenderOrder; - int count = list.size(); - int currentRenderOrder = 0x80000000; - m_current_projection_matrix.setColumn(2, scale * projectionMatrix().column(2)); - - //int clipChangeCount = 0; - //int programChangeCount = 0; - //int materialChangeCount = 0; - - for (int i = 0; i < count; ++i) { - QSGGeometryNode *geomNode = list.at(i); - - QSGMaterialShader::RenderState::DirtyStates updates; - -#if defined (QML_RUNTIME_TESTING) - static bool dumpTree = qApp->arguments().contains(QLatin1String("--dump-tree")); - if (dumpTree) - qDebug() << geomNode; -#endif - - bool changeMatrix = m_currentMatrix != geomNode->matrix(); - - if (changeMatrix) { - m_currentMatrix = geomNode->matrix(); - if (m_currentMatrix) - m_current_model_view_matrix = *m_currentMatrix; - else - m_current_model_view_matrix.setToIdentity(); - updates |= QSGMaterialShader::RenderState::DirtyMatrix; - } - - bool changeOpacity = m_current_opacity != geomNode->inheritedOpacity(); - if (changeOpacity) { - updates |= QSGMaterialShader::RenderState::DirtyOpacity; - m_current_opacity = geomNode->inheritedOpacity(); - } - - Q_ASSERT(geomNode->activeMaterial()); - - QSGMaterial *material = geomNode->activeMaterial(); - QSGMaterialShader *program = m_context->prepareMaterial(material); - Q_ASSERT(program->program()->isLinked()); - - bool changeClip = geomNode->clipList() != m_currentClip; - QSGRenderer::ClipType clipType = QSGRenderer::NoClip; - if (changeClip) { - // The clip function relies on there not being any depth testing.. - glDisable(GL_DEPTH_TEST); - clipType = updateStencilClip(geomNode->clipList()); - glEnable(GL_DEPTH_TEST); - m_currentClip = geomNode->clipList(); -#ifdef FORCE_NO_REORDER - glDepthMask(false); -#else - glDepthMask((material->flags() & QSGMaterial::Blending) == 0 && m_current_opacity == 1); -#endif - //++clipChangeCount; - } - - bool changeProgram = (changeClip && clipType == QSGRenderer::StencilClip) || m_currentProgram != program; - if (changeProgram) { - if (m_currentProgram) - m_currentProgram->deactivate(); - m_currentProgram = program; - m_currentProgram->activate(); - //++programChangeCount; - updates |= (QSGMaterialShader::RenderState::DirtyMatrix | QSGMaterialShader::RenderState::DirtyOpacity); - -#ifdef RENDERER_DEBUG - materialChanges++; -#endif - } - - bool changeRenderOrder = currentRenderOrder != geomNode->renderOrder(); - if (changeRenderOrder) { - currentRenderOrder = geomNode->renderOrder(); - m_current_projection_matrix.setColumn(3, projectionMatrix().column(3) - + currentRenderOrder - * m_current_projection_matrix.column(2)); - updates |= QSGMaterialShader::RenderState::DirtyMatrix; - } - - if (changeProgram || m_currentMaterial != material) { - program->updateState(state(updates), material, changeProgram ? 0 : m_currentMaterial); - m_currentMaterial = material; - //++materialChangeCount; - } - - //glDepthRange((geomNode->renderOrder() + 0.1) * scale, (geomNode->renderOrder() + 0.9) * scale); - - const QSGGeometry *g = geomNode->geometry(); - draw(program, g); - -#ifdef RENDERER_DEBUG - geometryNodesDrawn++; -#endif - } - //qDebug("Clip: %i, shader program: %i, material: %i times changed while drawing %s items", - // clipChangeCount, programChangeCount, materialChangeCount, - // &list == &m_transparentNodes ? "transparent" : "opaque"); -} - -QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/coreapi/qsgdefaultrenderer_p.h b/src/declarative/scenegraph/coreapi/qsgdefaultrenderer_p.h deleted file mode 100644 index 45cebdd7b9..0000000000 --- a/src/declarative/scenegraph/coreapi/qsgdefaultrenderer_p.h +++ /dev/null @@ -1,123 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QMLRENDERER_H -#define QMLRENDERER_H - -#include "qsgrenderer_p.h" - -#include <QtGui/private/qdatabuffer_p.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - - - -class QSGDefaultRenderer : public QSGRenderer -{ - Q_OBJECT -public: - class IndexGeometryNodePair : public QPair<int, QSGGeometryNode *> - { - public: - IndexGeometryNodePair(int i, QSGGeometryNode *n); - bool operator < (const IndexGeometryNodePair &other) const; - }; - - - // Minimum heap. - class IndexGeometryNodePairHeap - { - public: - IndexGeometryNodePairHeap(); - void insert(const IndexGeometryNodePair &x); - const IndexGeometryNodePair &top() const { return v.first(); } - IndexGeometryNodePair pop(); - bool isEmpty() const { return v.isEmpty(); } - private: - static int parent(int i) { return (i - 1) >> 1; } - static int left(int i) { return (i << 1) | 1; } - static int right(int i) { return (i + 1) << 1; } - QDataBuffer<IndexGeometryNodePair> v; - }; - - QSGDefaultRenderer(QSGContext *context); - - void render(); - - void nodeChanged(QSGNode *node, QSGNode::DirtyFlags flags); - - void setSortFrontToBackEnabled(bool sort); - bool isSortFrontToBackEnabled() const; - -private: - void buildLists(QSGNode *node); - void renderNodes(const QDataBuffer<QSGGeometryNode *> &list); - - const QSGClipNode *m_currentClip; - QSGMaterial *m_currentMaterial; - QSGMaterialShader *m_currentProgram; - const QMatrix4x4 *m_currentMatrix; - QMatrix4x4 m_renderOrderMatrix; - QDataBuffer<QSGGeometryNode *> m_opaqueNodes; - QDataBuffer<QSGGeometryNode *> m_transparentNodes; - QDataBuffer<QSGGeometryNode *> m_tempNodes; - IndexGeometryNodePairHeap m_heap; - - bool m_rebuild_lists; - bool m_needs_sorting; - bool m_sort_front_to_back; - int m_currentRenderOrder; - -#ifdef QML_RUNTIME_TESTING - bool m_render_opaque_nodes; - bool m_render_alpha_nodes; -#endif -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QMLRENDERER_H diff --git a/src/declarative/scenegraph/coreapi/qsggeometry.cpp b/src/declarative/scenegraph/coreapi/qsggeometry.cpp deleted file mode 100644 index 8661c9af93..0000000000 --- a/src/declarative/scenegraph/coreapi/qsggeometry.cpp +++ /dev/null @@ -1,466 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Qt scene graph research project. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsggeometry.h" -#include "qsggeometry_p.h" - -#include <qopenglcontext.h> -#include <qopenglfunctions.h> -#include <private/qopenglextensions_p.h> - -QT_BEGIN_NAMESPACE - - -QSGGeometry::Attribute QSGGeometry::Attribute::create(int attributeIndex, int tupleSize, int primitiveType, bool isPrimitive) -{ - Attribute a = { attributeIndex, tupleSize, primitiveType, isPrimitive, 0 }; - return a; -} - - -/*! - Convenience function which returns attributes to be used for 2D solid - color drawing. - */ - -const QSGGeometry::AttributeSet &QSGGeometry::defaultAttributes_Point2D() -{ - static Attribute data[] = { - QSGGeometry::Attribute::create(0, 2, GL_FLOAT, true) - }; - static AttributeSet attrs = { 1, sizeof(float) * 2, data }; - return attrs; -} - -/*! - Convenience function which returns attributes to be used for textured 2D drawing. - */ - -const QSGGeometry::AttributeSet &QSGGeometry::defaultAttributes_TexturedPoint2D() -{ - static Attribute data[] = { - QSGGeometry::Attribute::create(0, 2, GL_FLOAT, true), - QSGGeometry::Attribute::create(1, 2, GL_FLOAT) - }; - static AttributeSet attrs = { 2, sizeof(float) * 4, data }; - return attrs; -} - -/*! - Convenience function which returns attributes to be used for per vertex colored 2D drawing. - */ - -const QSGGeometry::AttributeSet &QSGGeometry::defaultAttributes_ColoredPoint2D() -{ - static Attribute data[] = { - QSGGeometry::Attribute::create(0, 2, GL_FLOAT, true), - QSGGeometry::Attribute::create(1, 4, GL_UNSIGNED_BYTE) - }; - static AttributeSet attrs = { 2, 2 * sizeof(float) + 4 * sizeof(char), data }; - return attrs; -} - - -/*! - \class QSGGeometry - \brief The QSGGeometry class provides low-level storage for graphics primitives - in the QML Scene Graph. - - The QSGGeometry class provides a few convenience attributes and attribute accessors - by default. The defaultAttributes_Point2D() function returns attributes to be used - in normal solid color rectangles, while the defaultAttributes_TexturedPoint2D function - returns attributes to be used for the common pixmap usecase. - */ - - -/*! - Constructs a geometry object based on \a attributes. - - The object allocate space for \a vertexCount vertices based on the accumulated - size in \a attributes and for \a indexCount. - - Geometry objects are constructed with GL_TRIANGLE_STRIP as default drawing mode. - - The attribute structure is assumed to be POD and the geometry object - assumes this will not go away. There is no memory management involved. - */ - -QSGGeometry::QSGGeometry(const QSGGeometry::AttributeSet &attributes, - int vertexCount, - int indexCount, - int indexType) - : m_drawing_mode(GL_TRIANGLE_STRIP) - , m_vertex_count(0) - , m_index_count(0) - , m_index_type(indexType) - , m_attributes(attributes) - , m_data(0) - , m_index_data_offset(-1) - , m_server_data(0) - , m_owns_data(false) - , m_index_usage_pattern(AlwaysUploadPattern) - , m_vertex_usage_pattern(AlwaysUploadPattern) -{ - Q_ASSERT(m_attributes.count > 0); - Q_ASSERT(m_attributes.stride > 0); - - Q_ASSERT_X(indexType != GL_UNSIGNED_INT - || static_cast<QOpenGLExtensions *>(QOpenGLContext::currentContext()->functions()) - ->hasOpenGLExtension(QOpenGLExtensions::ElementIndexUint), - "QSGGeometry::QSGGeometry", - "GL_UNSIGNED_INT is not supported, geometry will not render" - ); - - if (indexType != GL_UNSIGNED_BYTE - && indexType != GL_UNSIGNED_SHORT - && indexType != GL_UNSIGNED_INT) { - qFatal("QSGGeometry: Unsupported index type, %x.\n", indexType); - } - - - // Because allocate reads m_vertex_count, m_index_count and m_owns_data, these - // need to be set before calling allocate... - allocate(vertexCount, indexCount); -} - -/*! - \fn int QSGGeometry::sizeOfVertex() const - - Returns the size in bytes of one vertex. - - This value comes from the attributes. - */ - -/*! - \fn int QSGGeometry::sizeOfIndex() const - - Returns the byte size of the index type. - - This value is either 1 when index type is GL_UNSIGNED_BYTE or 2 when - index type is GL_UNSIGNED_SHORT. For Desktop OpenGL, GL_UNSIGNED_INT - with the value 4 is also supported. - */ - -QSGGeometry::~QSGGeometry() -{ - if (m_owns_data) - qFree(m_data); - - if (m_server_data) - delete m_server_data; -} - -/*! - \fn int QSGGeometry::vertexCount() const - - Returns the number of vertices in this geometry object. - */ - -/*! - \fn int QSGGeometry::indexCount() const - - Returns the number of indices in this geometry object. - */ - - - -/*! - \fn void *QSGGeometry::vertexData() - - Returns a pointer to the raw vertex data of this geometry object. - - \sa vertexDataAsPoint2D(), vertexDataAsTexturedPoint2D - */ - -/*! - \fn const void *QSGGeometry::vertexData() const - - Returns a pointer to the raw vertex data of this geometry object. - - \sa vertexDataAsPoint2D(), vertexDataAsTexturedPoint2D - */ - -/*! - Returns a pointer to the raw index data of this geometry object. - - \sa indexDataAsUShort(), indexDataAsUInt() - */ -void *QSGGeometry::indexData() -{ - return m_index_data_offset < 0 - ? 0 - : ((char *) m_data + m_index_data_offset); -} - -/*! - Returns a pointer to the raw index data of this geometry object. - - \sa indexDataAsUShort(), indexDataAsUInt() - */ -const void *QSGGeometry::indexData() const -{ - return m_index_data_offset < 0 - ? 0 - : ((char *) m_data + m_index_data_offset); -} - -/*! - Sets the drawing mode to be used for this geometry. - - The default value is GL_TRIANGLE_STRIP. - */ -void QSGGeometry::setDrawingMode(GLenum mode) -{ - m_drawing_mode = mode; -} - -/*! - \fn int QSGGeometry::drawingMode() const - - Returns the drawing mode of this geometry. - - The default value is GL_TRIANGLE_STRIP. - */ - -/*! - \fn int QSGGeometry::indexType() const - - Returns the primitive type used for indices in this - geometry object. - */ - - -/*! - Resizes the vertex and index data of this geometry object to fit \a vertexCount - vertices and \a indexCount indices. - - Vertex and index data will be invalidated after this call and the caller must - */ -void QSGGeometry::allocate(int vertexCount, int indexCount) -{ - if (vertexCount == m_vertex_count && indexCount == m_index_count) - return; - - m_vertex_count = vertexCount; - m_index_count = indexCount; - - bool canUsePrealloc = m_index_count <= 0; - int vertexByteSize = m_attributes.stride * m_vertex_count; - - if (m_owns_data) - qFree(m_data); - - if (canUsePrealloc && vertexByteSize <= (int) sizeof(m_prealloc)) { - m_data = (void *) &m_prealloc[0]; - m_index_data_offset = -1; - m_owns_data = false; - } else { - Q_ASSERT(m_index_type == GL_UNSIGNED_INT || m_index_type == GL_UNSIGNED_SHORT); - int indexByteSize = indexCount * (m_index_type == GL_UNSIGNED_SHORT ? sizeof(quint16) : sizeof(quint32)); - m_data = (void *) qMalloc(vertexByteSize + indexByteSize); - m_index_data_offset = vertexByteSize; - m_owns_data = true; - } - - // If we have associated vbo data we could potentially crash later if - // the old buffers are used with the new vertex and index count, so we force - // an update in the renderer in that case. This is really the users responsibility - // but it is cheap for us to enforce this, so why not... - if (m_server_data) { - markIndexDataDirty(); - markVertexDataDirty(); - } - -} - -/*! - Updates the geometry \a g with the coordinates in \a rect. - - The function assumes the geometry object contains a single triangle strip - of QSGGeometry::Point2D vertices - */ -void QSGGeometry::updateRectGeometry(QSGGeometry *g, const QRectF &rect) -{ - Point2D *v = g->vertexDataAsPoint2D(); - v[0].x = rect.left(); - v[0].y = rect.top(); - - v[1].x = rect.left(); - v[1].y = rect.bottom(); - - v[2].x = rect.right(); - v[2].y = rect.top(); - - v[3].x = rect.right(); - v[3].y = rect.bottom(); -} - -/*! - Updates the geometry \a g with the coordinates in \a rect and texture - coordinates from \a textureRect. - - \a textureRect should be in normalized coordinates. - - \a g is assumed to be a triangle strip of four vertices of type - QSGGeometry::TexturedPoint2D. - */ -void QSGGeometry::updateTexturedRectGeometry(QSGGeometry *g, const QRectF &rect, const QRectF &textureRect) -{ - TexturedPoint2D *v = g->vertexDataAsTexturedPoint2D(); - v[0].x = rect.left(); - v[0].y = rect.top(); - v[0].tx = textureRect.left(); - v[0].ty = textureRect.top(); - - v[1].x = rect.left(); - v[1].y = rect.bottom(); - v[1].tx = textureRect.left(); - v[1].ty = textureRect.bottom(); - - v[2].x = rect.right(); - v[2].y = rect.top(); - v[2].tx = textureRect.right(); - v[2].ty = textureRect.top(); - - v[3].x = rect.right(); - v[3].y = rect.bottom(); - v[3].tx = textureRect.right(); - v[3].ty = textureRect.bottom(); -} - - - -/*! - \enum QSGGeometry::DataPattern - - The DataPattern enum is used to specify the use pattern for the vertex - and index data in a geometry object. - - \value AlwaysUploadPattern The data is always uploaded. This means that - the user does not need to explicitly mark index and vertex data as - dirty after changing it. This is the default. - - \value DynamicPattern The data is modified repeatedly and drawn many times. - This is a hint that may provide better performance. When set - the user must make sure to mark the data as dirty after changing it. - - \value StaticPattern The data is modified once and drawn many times. This is - a hint that may provide better performance. When set the user must make sure - to mark the data as dirty after changing it. - */ - - -/*! - \fn QSGGeometry::DataPattern QSGGeometry::indexDataPattern() const - - Returns the usage pattern for indices in this geometry. The default - pattern is AlwaysUploadPattern. - */ - -/*! - Sets the usage pattern for indices to \a p. - - The default is AlwaysUploadPattern. When set to anything other than - the default, the user must call markIndexDataDirty() after changing - the index data. - */ - -void QSGGeometry::setIndexDataPattern(DataPattern p) -{ - m_index_usage_pattern = p; -} - - - - -/*! - \fn QSGGeometry::DataPattern QSGGeometry::vertexDataPattern() const - - Returns the usage pattern for vertices in this geometry. The default - pattern is AlwaysUploadPattern. - */ - -/*! - Sets the usage pattern for vertices to \a p. - - The default is AlwaysUploadPattern. When set to anything other than - the default, the user must call markVertexDataDirty() after changing - the vertex data. - */ - -void QSGGeometry::setVertexDataPattern(DataPattern p) -{ - m_vertex_usage_pattern = p; -} - - - - -/*! - Mark that the vertices in this geometry has changed and must be uploaded - again. - - This function only has an effect when the usage pattern for vertices is - StaticData and the renderer that renders this geometry uploads the geometry - into Vertex Buffer Objects (VBOs). - */ -void QSGGeometry::markIndexDataDirty() -{ - m_dirty_index_data = true; -} - - - -/*! - Mark that the vertices in this geometry has changed and must be uploaded - again. - - This function only has an effect when the usage pattern for vertices is - StaticData and the renderer that renders this geometry uploads the geometry - into Vertex Buffer Objects (VBOs). - */ -void QSGGeometry::markVertexDataDirty() -{ - m_dirty_vertex_data = true; -} - - -QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/coreapi/qsggeometry.h b/src/declarative/scenegraph/coreapi/qsggeometry.h deleted file mode 100644 index d7b343c108..0000000000 --- a/src/declarative/scenegraph/coreapi/qsggeometry.h +++ /dev/null @@ -1,295 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Qt scene graph research project. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSGGEOMETRY_H -#define QSGGEOMETRY_H - -#include <QtGui/qopengl.h> -#include <QRectF> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class QSGGeometryData; - -class Q_DECLARATIVE_EXPORT QSGGeometry -{ -public: - - struct Attribute - { - int position; - int tupleSize; - int type; - - uint isVertexCoordinate : 1; - uint migrateYourCodeToUseTheCreateFunction: 31; // ### Remove before release - - static Attribute create(int pos, int tupleSize, int primitiveType, bool isPosition = false); - }; - - struct AttributeSet { - int count; - int stride; - const Attribute *attributes; - }; - - struct Point2D { - float x, y; - void set(float nx, float ny) { - x = nx; y = ny; - } - }; - struct TexturedPoint2D { - float x, y; - float tx, ty; - void set(float nx, float ny, float ntx, float nty) { - x = nx; y = ny; tx = ntx; ty = nty; - } - }; - struct ColoredPoint2D { - float x, y; - unsigned char r, g, b, a; - void set(float nx, float ny, uchar nr, uchar ng, uchar nb, uchar na) { - x = nx; y = ny; - r = nr; g = ng, b = nb; a = na; - } - }; - - static const AttributeSet &defaultAttributes_Point2D(); - static const AttributeSet &defaultAttributes_TexturedPoint2D(); - static const AttributeSet &defaultAttributes_ColoredPoint2D(); - - enum DataPattern { - AlwaysUploadPattern = 0, - StreamPattern = 1, - DynamicPattern = 2, - StaticPattern = 3 - }; - - QSGGeometry(const QSGGeometry::AttributeSet &attribs, - int vertexCount, - int indexCount = 0, - int indexType = GL_UNSIGNED_SHORT); - virtual ~QSGGeometry(); - - void setDrawingMode(GLenum mode); - inline GLenum drawingMode() const { return m_drawing_mode; } - - void allocate(int vertexCount, int indexCount = 0); - - int vertexCount() const { return m_vertex_count; } - - void *vertexData() { return m_data; } - inline Point2D *vertexDataAsPoint2D(); - inline TexturedPoint2D *vertexDataAsTexturedPoint2D(); - inline ColoredPoint2D *vertexDataAsColoredPoint2D(); - - inline const void *vertexData() const { return m_data; } - inline const Point2D *vertexDataAsPoint2D() const; - inline const TexturedPoint2D *vertexDataAsTexturedPoint2D() const; - inline const ColoredPoint2D *vertexDataAsColoredPoint2D() const; - - inline int indexType() const { return m_index_type; } - - int indexCount() const { return m_index_count; } - - void *indexData(); - inline uint *indexDataAsUInt(); - inline quint16 *indexDataAsUShort(); - - inline int sizeOfIndex() const; - - const void *indexData() const; - inline const uint *indexDataAsUInt() const; - inline const quint16 *indexDataAsUShort() const; - - inline int attributeCount() const { return m_attributes.count; } - inline const Attribute *attributes() const { return m_attributes.attributes; } - inline int sizeOfVertex() const { return m_attributes.stride; } - - static void updateRectGeometry(QSGGeometry *g, const QRectF &rect); - static void updateTexturedRectGeometry(QSGGeometry *g, const QRectF &rect, const QRectF &sourceRect); - - void setIndexDataPattern(DataPattern p); - DataPattern indexDataPattern() const { return (DataPattern) m_index_usage_pattern; } - - void setVertexDataPattern(DataPattern p); - DataPattern vertexDataPattern() const { return (DataPattern) m_vertex_usage_pattern; } - - void markIndexDataDirty(); - void markVertexDataDirty(); - -private: - friend class QSGGeometryData; - - int m_drawing_mode; - int m_vertex_count; - int m_index_count; - int m_index_type; - const AttributeSet &m_attributes; - void *m_data; - int m_index_data_offset; - - QSGGeometryData *m_server_data; - - uint m_owns_data : 1; - uint m_index_usage_pattern : 2; - uint m_vertex_usage_pattern : 2; - uint m_dirty_index_data : 1; - uint m_dirty_vertex_data : 1; - uint m_reserved_bits : 27; - - float m_prealloc[16]; -}; - -inline uint *QSGGeometry::indexDataAsUInt() -{ - Q_ASSERT(m_index_type == GL_UNSIGNED_INT); - return (uint *) indexData(); -} - -inline quint16 *QSGGeometry::indexDataAsUShort() -{ - Q_ASSERT(m_index_type == GL_UNSIGNED_SHORT); - return (quint16 *) indexData(); -} - -inline const uint *QSGGeometry::indexDataAsUInt() const -{ - Q_ASSERT(m_index_type == GL_UNSIGNED_INT); - return (uint *) indexData(); -} - -inline const quint16 *QSGGeometry::indexDataAsUShort() const -{ - Q_ASSERT(m_index_type == GL_UNSIGNED_SHORT); - return (quint16 *) indexData(); -} - -inline QSGGeometry::Point2D *QSGGeometry::vertexDataAsPoint2D() -{ - Q_ASSERT(m_attributes.count == 1); - Q_ASSERT(m_attributes.stride == 2 * sizeof(float)); - Q_ASSERT(m_attributes.attributes[0].tupleSize == 2); - Q_ASSERT(m_attributes.attributes[0].type == GL_FLOAT); - Q_ASSERT(m_attributes.attributes[0].position == 0); - return (Point2D *) m_data; -} - -inline QSGGeometry::TexturedPoint2D *QSGGeometry::vertexDataAsTexturedPoint2D() -{ - Q_ASSERT(m_attributes.count == 2); - Q_ASSERT(m_attributes.stride == 4 * sizeof(float)); - Q_ASSERT(m_attributes.attributes[0].position == 0); - Q_ASSERT(m_attributes.attributes[0].tupleSize == 2); - Q_ASSERT(m_attributes.attributes[0].type == GL_FLOAT); - Q_ASSERT(m_attributes.attributes[1].position == 1); - Q_ASSERT(m_attributes.attributes[1].tupleSize == 2); - Q_ASSERT(m_attributes.attributes[1].type == GL_FLOAT); - return (TexturedPoint2D *) m_data; -} - -inline QSGGeometry::ColoredPoint2D *QSGGeometry::vertexDataAsColoredPoint2D() -{ - Q_ASSERT(m_attributes.count == 2); - Q_ASSERT(m_attributes.stride == 2 * sizeof(float) + 4 * sizeof(char)); - Q_ASSERT(m_attributes.attributes[0].position == 0); - Q_ASSERT(m_attributes.attributes[0].tupleSize == 2); - Q_ASSERT(m_attributes.attributes[0].type == GL_FLOAT); - Q_ASSERT(m_attributes.attributes[1].position == 1); - Q_ASSERT(m_attributes.attributes[1].tupleSize == 4); - Q_ASSERT(m_attributes.attributes[1].type == GL_UNSIGNED_BYTE); - return (ColoredPoint2D *) m_data; -} - -inline const QSGGeometry::Point2D *QSGGeometry::vertexDataAsPoint2D() const -{ - Q_ASSERT(m_attributes.count == 1); - Q_ASSERT(m_attributes.stride == 2 * sizeof(float)); - Q_ASSERT(m_attributes.attributes[0].tupleSize == 2); - Q_ASSERT(m_attributes.attributes[0].type == GL_FLOAT); - Q_ASSERT(m_attributes.attributes[0].position == 0); - return (const Point2D *) m_data; -} - -inline const QSGGeometry::TexturedPoint2D *QSGGeometry::vertexDataAsTexturedPoint2D() const -{ - Q_ASSERT(m_attributes.count == 2); - Q_ASSERT(m_attributes.stride == 4 * sizeof(float)); - Q_ASSERT(m_attributes.attributes[0].position == 0); - Q_ASSERT(m_attributes.attributes[0].tupleSize == 2); - Q_ASSERT(m_attributes.attributes[0].type == GL_FLOAT); - Q_ASSERT(m_attributes.attributes[1].position == 1); - Q_ASSERT(m_attributes.attributes[1].tupleSize == 2); - Q_ASSERT(m_attributes.attributes[1].type == GL_FLOAT); - return (const TexturedPoint2D *) m_data; -} - -inline const QSGGeometry::ColoredPoint2D *QSGGeometry::vertexDataAsColoredPoint2D() const -{ - Q_ASSERT(m_attributes.count == 2); - Q_ASSERT(m_attributes.stride == 2 * sizeof(float) + 4 * sizeof(char)); - Q_ASSERT(m_attributes.attributes[0].position == 0); - Q_ASSERT(m_attributes.attributes[0].tupleSize == 2); - Q_ASSERT(m_attributes.attributes[0].type == GL_FLOAT); - Q_ASSERT(m_attributes.attributes[1].position == 1); - Q_ASSERT(m_attributes.attributes[1].tupleSize == 4); - Q_ASSERT(m_attributes.attributes[1].type == GL_UNSIGNED_BYTE); - return (const ColoredPoint2D *) m_data; -} - -int QSGGeometry::sizeOfIndex() const -{ - if (m_index_type == GL_UNSIGNED_SHORT) return 2; - else if (m_index_type == GL_UNSIGNED_BYTE) return 1; - else if (m_index_type == GL_UNSIGNED_INT) return 4; - return 0; -} - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QSGGEOMETRY_H diff --git a/src/declarative/scenegraph/coreapi/qsggeometry_p.h b/src/declarative/scenegraph/coreapi/qsggeometry_p.h deleted file mode 100644 index ef2935ae4c..0000000000 --- a/src/declarative/scenegraph/coreapi/qsggeometry_p.h +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSGGEOMETRY_P_H -#define QSGGEOMETRY_P_H - -#include "qsggeometry.h" - -QT_BEGIN_NAMESPACE - -class QSGGeometryData -{ -public: - virtual ~QSGGeometryData() {} - - static inline QSGGeometryData *data(const QSGGeometry *g) { - return g->m_server_data; - } - - static inline void install(const QSGGeometry *g, QSGGeometryData *data) { - Q_ASSERT(!g->m_server_data); - const_cast<QSGGeometry *>(g)->m_server_data = data; - } - - static bool inline hasDirtyVertexData(const QSGGeometry *g) { return g->m_dirty_vertex_data; } - static void inline clearDirtyVertexData(const QSGGeometry *g) { const_cast<QSGGeometry *>(g)->m_dirty_vertex_data = false; } - - static bool inline hasDirtyIndexData(const QSGGeometry *g) { return g->m_dirty_vertex_data; } - static void inline clearDirtyIndexData(const QSGGeometry *g) { const_cast<QSGGeometry *>(g)->m_dirty_index_data = false; } - -}; - -QT_END_NAMESPACE - -#endif // QSGGEOMETRY_P_H diff --git a/src/declarative/scenegraph/coreapi/qsgmaterial.cpp b/src/declarative/scenegraph/coreapi/qsgmaterial.cpp deleted file mode 100644 index 36b50e89b6..0000000000 --- a/src/declarative/scenegraph/coreapi/qsgmaterial.cpp +++ /dev/null @@ -1,535 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsgmaterial.h" -#include "qsgrenderer_p.h" - -QT_BEGIN_NAMESPACE - - -/*! - \class QSGMaterialShader - \brief The QSGMaterialShader class implements a material renders geometry. - - The QSGMaterial and QSGMaterialShader form a tight relationship. For one - scene graph (including nested graphs), there is one unique QSGMaterialShader - instance which encapsulates the QOpenGLShaderProgram the scene graph uses - to render that material, such as a shader to flat coloring of geometry. - Each QSGGeometryNode can have a unique QSGMaterial containing the - how the shader should be configured when drawing that node, such as - the actual color to used to render the geometry. - - An instance of QSGMaterialShader is never created explicitely by the user, - it will be created on demand by the scene graph through - QSGMaterial::createShader(). The scene graph will make sure that there - is only one instance of each shader implementation through a scene graph. - - The source code returned from vertexShader() is used to control what the - material does with the vertiex data that comes in from the geometry. - The source code returned from the fragmentShader() is used to control - what how the material should fill each individual pixel in the geometry. - The vertex and fragment source code is queried once during initialization, - changing what is returned from these functions later will not have - any effect. - - The activate() function is called by the scene graph when a shader is - is starting to be used. The deactivate function is called by the scene - graph when the shader is no longer going to be used. While active, - the scene graph may make one or more calls to updateState() which - will update the state of the shader for each individual geometry to - render. - - The attributeNames() returns the name of the attributes used in the - vertexShader(). These are used in the default implementation of - activate() and deactive() to decide whice vertex registers are enabled. - - The initialize() function is called during program creation to allow - subclasses to prepare for use, such as resolve uniform names in the - vertexShader() and fragmentShader(). - - A minimal example: - \code - class Shader : public QSGMaterialShader - { - public: - const char *vertexShader() const { - return - "attribute highp vec4 vertex; \n" - "uniform highp mat4 matrix; \n" - "void main() { \n" - " gl_Position = matrix * vertex; \n" - "}"; - } - - const char *fragmentShader() const { - return - "uniform lowp float opacity; \n" - "void main() { \n" - " gl_FragColor = vec4(1, 0, 0, 1) * opacity; \n" - "}"; - } - - char const *const *attributeNames() const - { - static char const *const names[] = { "vertex", 0 }; - return names; - } - - void initialize() - { - QSGMaterialShader::initialize(); - m_id_matrix = program()->uniformLocation("matrix"); - m_id_opacity = program()->uniformLocation("opacity"); - } - - void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) - { - Q_ASSERT(program()->isLinked()); - if (state.isMatrixDirty()) - program()->setUniformValue(m_id_matrix, state.combinedMatrix()); - if (state.isOpacityDirty()) - program()->setUniformValue(m_id_opacity, state.opacity()); - } - - private: - int m_id_matrix; - int m_id_opacity; - }; - \endcode - - \warning Instances of QSGMaterialShader belongs to the Scene Graph rendering - thread, and cannot be used from the GUI thread. - - */ - - - -/*! - Creates a new QSGMaterialShader. - */ -QSGMaterialShader::QSGMaterialShader() -{ -} - - - -/*! - \fn QOpenGLShaderProgram *QSGMaterialShader::program() const - - Returns the shader program used by this QSGMaterialShader. - */ - - - -/*! - This function is called by the scene graph to indicate that geometry is - about to be rendered using this shader. - - State that is global for all uses of the shader, independent of the geometry - that is being drawn, can be setup in this function. - - If reimplemented, make sure to either call the base class implementation to - enable the vertex attribute registers. - */ - -void QSGMaterialShader::activate() -{ - Q_ASSERT(program()->isLinked()); - - program()->bind(); - char const *const *attr = attributeNames(); - for (int i = 0; attr[i]; ++i) { - if (*attr[i]) - program()->enableAttributeArray(i); - } -} - - - -/*! - This function is called by the scene graph to indicate that geometry will - no longer to be rendered using this shader. - - If reimplemented, make sure to either call the base class implementation to - disable the vertex attribute registers. - */ - -void QSGMaterialShader::deactivate() -{ - char const *const *attr = attributeNames(); - for (int i = 0; attr[i]; ++i) { - if (*attr[i]) - program()->disableAttributeArray(i); - } -} - - - -/*! - This function is called by the scene graph before geometry is rendered - to make sure the shader is in the right state. - - The current rendering \a state is passed from the scene graph. If the state - indicates that any state is dirty, the updateState implementation must - update accordingly for the geometry to render correctly. - - The subclass specific state, such as the color of a flat color material, should - be extracted from \a newMaterial to update the color uniforms accordingly. - - The \a oldMaterial can be used to minimze state changes when updating - material states. The \a oldMaterial is 0 if this shader was just activated. - - \sa activate(), deactivate() - */ - -void QSGMaterialShader::updateState(const RenderState & /* state */, QSGMaterial * /* newMaterial */, QSGMaterial * /* oldMaterial */) -{ -} - - - -/*! - This function is called when the shader is initialized to compile the - actual QOpenGLShaderProgram. Do not call it explicitely. - - The default implementation will extract the vertexShader() and - fragmentShader() and bind the names returned from attributeNames() - to consecutive vertex attribute registers starting at 0. - */ - -void QSGMaterialShader::compile() -{ - Q_ASSERT_X(!m_program.isLinked(), "QSGSMaterialShader::compile()", "Compile called multiple times!"); - - program()->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShader()); - program()->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShader()); - - char const *const *attr = attributeNames(); -#ifndef QT_NO_DEBUG - int maxVertexAttribs = 0; - glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs); - for (int i = 0; attr[i]; ++i) { - if (i >= maxVertexAttribs) { - qFatal("List of attribute names is either too long or not null-terminated.\n" - "Maximum number of attributes on this hardware is %i.\n" - "Vertex shader:\n%s\n" - "Fragment shader:\n%s\n", - maxVertexAttribs, vertexShader(), fragmentShader()); - } - if (*attr[i]) - program()->bindAttributeLocation(attr[i], i); - } -#else - for (int i = 0; attr[i]; ++i) { - if (*attr[i]) - program()->bindAttributeLocation(attr[i], i); - } -#endif - - if (!program()->link()) { - qWarning("QSGMaterialShader: Shader compilation failed:"); - qWarning() << program()->log(); - } -} - - - -/*! - \class QSGMaterialShader::RenderState - \brief The QSGMaterialShader::RenderState encapsulates the current rendering state - during a call to QSGMaterialShader::updateState(). - - The render state contains a number of accessors that the shader needs to respect - in order to conform to the current state of the scene graph. - - The instance is only valid inside a call to QSGMaterialShader::updateState() and - should not be used outisde this function. - */ - - - -/*! - \enum QSGMaterialShader::RenderState::DirtyState - - \value DirtyMatrix Used to indicate that the matrix has changed and must be updated. - - \value DirtyOpacity Used to indicate that the opacity has changed and must be updated. - */ - - - -/*! - \fn bool QSGMaterialShader::RenderState::isMatrixDirty() const - - Convenience function to check if the dirtyStates() indicates that the matrix - needs to be updated. - */ - - - -/*! - \fn bool QSGMaterialShader::RenderState::isOpacityDirty() const - - Conveience function to check if the dirtyStates() indicates that the opacity - needs to be updated. - */ - - - -/*! - \fn QSGMaterialShader::RenderState::DirtyStates QSGMaterialShader::RenderState::dirtyStates() const - - Returns which rendering states that have changed and needs to be updated - for geometry rendered with this material to conform to the current - rendering state. - */ - - - -/*! - Returns the accumulated opacity to be used for rendering - */ - -float QSGMaterialShader::RenderState::opacity() const -{ - Q_ASSERT(m_data); - return static_cast<const QSGRenderer *>(m_data)->currentOpacity(); -} - - - -/*! - Returns the matrix combined of modelview matrix and project matrix. - */ - -QMatrix4x4 QSGMaterialShader::RenderState::combinedMatrix() const -{ - Q_ASSERT(m_data); - return static_cast<const QSGRenderer *>(m_data)->currentCombinedMatrix(); -} - - - -/*! - Returns the model view matrix. - */ - -QMatrix4x4 QSGMaterialShader::RenderState::modelViewMatrix() const -{ - Q_ASSERT(m_data); - return static_cast<const QSGRenderer *>(m_data)->currentModelViewMatrix(); -} - - - -/*! - Returns the viewport rect of the surface being rendered to. - */ - -QRect QSGMaterialShader::RenderState::viewportRect() const -{ - Q_ASSERT(m_data); - return static_cast<const QSGRenderer *>(m_data)->viewportRect(); -} - - - -/*! - Returns the device rect of the surface being rendered to - */ - -QRect QSGMaterialShader::RenderState::deviceRect() const -{ - Q_ASSERT(m_data); - return static_cast<const QSGRenderer *>(m_data)->deviceRect(); -} - - - -/*! - Returns the QOpenGLContext that is being used for rendering - */ - -QOpenGLContext *QSGMaterialShader::RenderState::context() const -{ - return static_cast<const QSGRenderer *>(m_data)->glContext(); -} - - -#ifndef QT_NO_DEBUG -static int qt_material_count = 0; - -static void qt_print_material_count() -{ - qDebug("Number of leaked materials: %i", qt_material_count); - qt_material_count = -1; -} -#endif - -/*! - \class QSGMaterialType - \brief The QSGMaterialType class is used as a unique type token in combination with QSGMaterial. - - It serves no purpose outside the QSGMaterial::type() function. - */ - -/*! - \class QSGMaterial - \brief The QSGMaterial class encapsulates rendering state for a shader program. - - The QSGMaterial and QSGMaterialShader subclasses form a tight relationship. For - one scene graph (including nested graphs), there is one unique QSGMaterialShader - instance which encapsulates the QOpenGLShaderProgram the scene graph uses - to render that material, such as a shader to flat coloring of geometry. - Each QSGGeometryNode can have a unique QSGMaterial containing the - how the shader should be configured when drawing that node, such as - the actual color to used to render the geometry. - - The QSGMaterial has two virtual functions that both need to be implemented. - The function type() should return a unique instance for all instances of a - specific subclass. The createShader() function should return a new instance - of QSGMaterialShader, specific to the subclass of QSGMaterial. - - A minimal QSGMaterial implementation could look like this: - \code - class Material : public QSGMaterial - { - public: - QSGMaterialType *type() const { static QSGMaterialType type; return &type; } - QSGMaterialShader *createShader() const { return new Shader; } - }; - \endcode - - \warning Instances of QSGMaterial belongs to the Scene Graph rendering thread, - and cannot be used from the GUI thread. - */ - -QSGMaterial::QSGMaterial() - : m_flags(0) -{ -#ifndef QT_NO_DEBUG - ++qt_material_count; - static bool atexit_registered = false; - if (!atexit_registered) { - atexit(qt_print_material_count); - atexit_registered = true; - } -#endif -} - -QSGMaterial::~QSGMaterial() -{ -#ifndef QT_NO_DEBUG - --qt_material_count; - if (qt_material_count < 0) - qDebug("Material destroyed after qt_print_material_count() was called."); -#endif -} - - - -/*! - \enum QSGMaterial::Flag - - \value Blending Set this flag to true if the material requires GL_BLEND to be - enabled during rendering. - */ - - - -/*! - Sets the flags \a flags on this material if \a on is true; - otherwise clears the attribute. -*/ - -void QSGMaterial::setFlag(Flags flags, bool on) -{ - if (on) - m_flags |= flags; - else - m_flags &= ~flags; -} - - - -/*! - Compares this material to \a other and returns 0 if they are equal; -1 if - this material should sort before \a other and 1 if \a other should sort - before. - - The scene graph can reorder geometry nodes to minimize state changes. - The compare function is called during the sorting process so that - the materials can be sorted to minimize state changes in each - call to QSGMaterialShader::updateState(). - - The this pointer and \a other is guaranteed to have the same type(). - */ - -int QSGMaterial::compare(const QSGMaterial *other) const -{ - Q_ASSERT(other && type() == other->type()); - return qint64(this) - qint64(other); -} - - - -/*! - \fn QSGMaterialType QSGMaterial::type() const - - This function is called by the scene graph to return a unique instance - per subclass. - */ - - - -/*! - \fn QSGMaterialShader *QSGMaterial::createShader() const - - This function returns a new instance of a the QSGMaterialShader - implementatation used to render geometry for a specifc implementation - of QSGMaterial. - - The function will be called only once for each material type that - exists in the scene graph and will be cached internally. -*/ - - -QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/coreapi/qsgmaterial.h b/src/declarative/scenegraph/coreapi/qsgmaterial.h deleted file mode 100644 index 084219bfba..0000000000 --- a/src/declarative/scenegraph/coreapi/qsgmaterial.h +++ /dev/null @@ -1,144 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MATERIAL_H -#define MATERIAL_H - -#include <qopenglshaderprogram.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class QSGMaterial; - -class Q_DECLARATIVE_EXPORT QSGMaterialShader -{ -public: - class Q_DECLARATIVE_EXPORT RenderState { - public: - enum DirtyState - { - DirtyMatrix = 0x0001, - DirtyOpacity = 0x0002 - }; - Q_DECLARE_FLAGS(DirtyStates, DirtyState) - - inline DirtyStates dirtyStates() const { return m_dirty; } - - inline bool isMatrixDirty() const { return m_dirty & DirtyMatrix; } - inline bool isOpacityDirty() const { return m_dirty & DirtyOpacity; } - - float opacity() const; - QMatrix4x4 combinedMatrix() const; - QMatrix4x4 modelViewMatrix() const; - QRect viewportRect() const; - QRect deviceRect() const; - - QOpenGLContext *context() const; - - private: - friend class QSGRenderer; - DirtyStates m_dirty; - const void *m_data; - }; - - QSGMaterialShader(); - - virtual void activate(); - virtual void deactivate(); - // First time a material is used, oldMaterial is null. - virtual void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial); - virtual char const *const *attributeNames() const = 0; // Array must end with null. - - inline QOpenGLShaderProgram *program() { return &m_program; } - -protected: - - friend class QSGContext; - - virtual void compile(); - virtual void initialize() { } - - virtual const char *vertexShader() const = 0; - virtual const char *fragmentShader() const = 0; - -private: - QOpenGLShaderProgram m_program; - void *m_reserved; -}; - -struct QSGMaterialType { }; - -class Q_DECLARATIVE_EXPORT QSGMaterial -{ -public: - enum Flag { - Blending = 0x0001 - }; - Q_DECLARE_FLAGS(Flags, Flag) - - QSGMaterial(); - virtual ~QSGMaterial(); - - virtual QSGMaterialType *type() const = 0; - virtual QSGMaterialShader *createShader() const = 0; - virtual int compare(const QSGMaterial *other) const; - - QSGMaterial::Flags flags() const { return m_flags; } - void setFlag(Flags flags, bool on = true); - -private: - Flags m_flags; - void *m_reserved; - Q_DISABLE_COPY(QSGMaterial) -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(QSGMaterial::Flags) -Q_DECLARE_OPERATORS_FOR_FLAGS(QSGMaterialShader::RenderState::DirtyStates) - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/declarative/scenegraph/coreapi/qsgnode.cpp b/src/declarative/scenegraph/coreapi/qsgnode.cpp deleted file mode 100644 index 764071c190..0000000000 --- a/src/declarative/scenegraph/coreapi/qsgnode.cpp +++ /dev/null @@ -1,1264 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsgnode.h" -#include "qsgrenderer_p.h" -#include "qsgnodeupdater_p.h" -#include "qsgmaterial.h" - -#include "limits.h" - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_DEBUG -static int qt_node_count = 0; - -static void qt_print_node_count() -{ - qDebug("Number of leaked nodes: %i", qt_node_count); - qt_node_count = -1; -} -#endif - -/*! - \class QSGNode - \brief The QSGNode class is the base class for all nodes in the scene graph. - - \inmodule QtDeclarative - - The QSGNode class can be used as a child container. Children are added with - the appendChildNode(), prependChildNode(), insertChildNodeBefore() and - insertChildNodeAfter(). Ordering of nodes is important as geometry nodes - will be rendered in the order they are added to the scene graph. - Actually, the scene may reorder nodes freely, but the resulting visual - order is still guaranteed. - - If nodes change every frame, the preprocess() function can be used to - apply changes to a node for every frame its rendered. The use of preprocess() - must be explicitly enabled by setting the QSGNode::UsePreprocess flag - on the node. - - The virtual isSubtreeBlocked() function can be used to disable a subtree all - together. Nodes in a blocked subtree will not be preprocessed() and not - rendered. - - Anything related to QSGNode should happen on the scene graph rendering thread. - */ - -QSGNode::QSGNode() - : m_parent(0) - , m_type(BasicNodeType) - , m_firstChild(0) - , m_lastChild(0) - , m_nextSibling(0) - , m_previousSibling(0) - , m_subtreeGeometryCount(0) - , m_nodeFlags(OwnedByParent) - , m_flags(0) -{ - init(); -} - -QSGNode::QSGNode(NodeType type) - : m_parent(0) - , m_type(type) - , m_firstChild(0) - , m_lastChild(0) - , m_nextSibling(0) - , m_previousSibling(0) - , m_subtreeGeometryCount(type == GeometryNodeType ? 1 : 0) - , m_nodeFlags(OwnedByParent) - , m_flags(0) -{ - init(); -} - -void QSGNode::init() -{ -#ifndef QT_NO_DEBUG - ++qt_node_count; - static bool atexit_registered = false; - if (!atexit_registered) { - atexit(qt_print_node_count); - atexit_registered = true; - } -#endif -} - -QSGNode::~QSGNode() -{ -#ifndef QT_NO_DEBUG - --qt_node_count; - if (qt_node_count < 0) - qDebug("Node destroyed after qt_print_node_count() was called."); -#endif - destroy(); -} - - -/*! - \fn void QSGNode::preprocess() - - Override this function to do processing on the node before it is rendered. - - Preprocessing needs to be explicitly enabled by setting the flag - QSGNode::UsePreprocess. The flag needs to be set before the node is added - to the scene graph and will cause the preprocess() function to be called - for every frame the node is rendered. - - The preprocess function is called before the update pass that propegates - opacity and transformations through the scene graph. That means that - functions like QSGOpacityNode::combinedOpacity() and - QSGTransformNode::combinedMatrix() will not contain up-to-date values. - If such values are changed during the preprocess, these changes will be - propegated through the scene graph before it is rendered. - - \warning Beware of deleting nodes while they are being preprocessed. It is - possible, with a small performance hit, to delete a single node during its - own preprocess call. Deleting a subtree which has nodes that also use - preprocessing may result in a segmentation fault. This is done for - performance reasons. - */ - - - - -/*! - Returns whether this node and its subtree is available for use. - - Blocked subtrees will not get their dirty states updated and they - will not be rendered. - - The QSGOpacityNode will return a blocked subtree when accumulated opacity - is 0, for instance. - */ - -bool QSGNode::isSubtreeBlocked() const -{ - return m_subtreeGeometryCount == 0; -} - -/*! - \internal - Detaches the node from the scene graph and deletes any children it owns. - - This function is called from QSGNode's and QSGRootNode's destructor. It - should not be called explicitly in user code. QSGRootNode needs to call - destroy() because destroy() calls removeChildNode() which in turn calls - markDirty() which type-casts the node to QSGRootNode. This type-cast is not - valid at the time QSGNode's destructor is called because the node will - already be partially destroyed at that point. -*/ - -void QSGNode::destroy() -{ - if (m_parent) { - m_parent->removeChildNode(this); - Q_ASSERT(m_parent == 0); - } - while (m_firstChild) { - QSGNode *child = m_firstChild; - removeChildNode(child); - Q_ASSERT(child->m_parent == 0); - if (child->flags() & OwnedByParent) - delete child; - } - - Q_ASSERT(m_firstChild == 0 && m_lastChild == 0); -} - - -/*! - Prepends \a node to this node's the list of children. - - Ordering of nodes is important as geometry nodes will be rendered in the - order they are added to the scene graph. - */ - -void QSGNode::prependChildNode(QSGNode *node) -{ - //Q_ASSERT_X(!m_children.contains(node), "QSGNode::prependChildNode", "QSGNode is already a child!"); - Q_ASSERT_X(!node->m_parent, "QSGNode::prependChildNode", "QSGNode already has a parent"); - -#ifndef QT_NO_DEBUG - if (node->type() == QSGNode::GeometryNodeType) { - QSGGeometryNode *g = static_cast<QSGGeometryNode *>(node); - Q_ASSERT_X(g->material(), "QSGNode::prependChildNode", "QSGGeometryNode is missing material"); - Q_ASSERT_X(g->geometry(), "QSGNode::prependChildNode", "QSGGeometryNode is missing geometry"); - } -#endif - - if (m_firstChild) - m_firstChild->m_previousSibling = node; - else - m_lastChild = node; - node->m_nextSibling = m_firstChild; - m_firstChild = node; - node->m_parent = this; - - node->markDirty(DirtyNodeAdded); -} - -/*! - Appends \a node to this node's list of children. - - Ordering of nodes is important as geometry nodes will be rendered in the - order they are added to the scene graph. - */ - -void QSGNode::appendChildNode(QSGNode *node) -{ - //Q_ASSERT_X(!m_children.contains(node), "QSGNode::appendChildNode", "QSGNode is already a child!"); - Q_ASSERT_X(!node->m_parent, "QSGNode::appendChildNode", "QSGNode already has a parent"); - -#ifndef QT_NO_DEBUG - if (node->type() == QSGNode::GeometryNodeType) { - QSGGeometryNode *g = static_cast<QSGGeometryNode *>(node); - Q_ASSERT_X(g->material(), "QSGNode::appendChildNode", "QSGGeometryNode is missing material"); - Q_ASSERT_X(g->geometry(), "QSGNode::appendChildNode", "QSGGeometryNode is missing geometry"); - } -#endif - - if (m_lastChild) - m_lastChild->m_nextSibling = node; - else - m_firstChild = node; - node->m_previousSibling = m_lastChild; - m_lastChild = node; - node->m_parent = this; - - node->markDirty(DirtyNodeAdded); -} - - - -/*! - Inserts \a node to this node's list of children before the node specified with \a before. - - Ordering of nodes is important as geometry nodes will be rendered in the - order they are added to the scene graph. - */ - -void QSGNode::insertChildNodeBefore(QSGNode *node, QSGNode *before) -{ - //Q_ASSERT_X(!m_children.contains(node), "QSGNode::insertChildNodeBefore", "QSGNode is already a child!"); - Q_ASSERT_X(!node->m_parent, "QSGNode::insertChildNodeBefore", "QSGNode already has a parent"); - Q_ASSERT_X(before && before->m_parent == this, "QSGNode::insertChildNodeBefore", "The parent of \'before\' is wrong"); - -#ifndef QT_NO_DEBUG - if (node->type() == QSGNode::GeometryNodeType) { - QSGGeometryNode *g = static_cast<QSGGeometryNode *>(node); - Q_ASSERT_X(g->material(), "QSGNode::insertChildNodeBefore", "QSGGeometryNode is missing material"); - Q_ASSERT_X(g->geometry(), "QSGNode::insertChildNodeBefore", "QSGGeometryNode is missing geometry"); - } -#endif - - QSGNode *previous = before->m_previousSibling; - if (previous) - previous->m_nextSibling = node; - else - m_firstChild = node; - node->m_previousSibling = previous; - node->m_nextSibling = before; - before->m_previousSibling = node; - node->m_parent = this; - - node->markDirty(DirtyNodeAdded); -} - - - -/*! - Inserts \a node to this node's list of children after the node specified with \a after. - - Ordering of nodes is important as geometry nodes will be rendered in the - order they are added to the scene graph. - */ - -void QSGNode::insertChildNodeAfter(QSGNode *node, QSGNode *after) -{ - //Q_ASSERT_X(!m_children.contains(node), "QSGNode::insertChildNodeAfter", "QSGNode is already a child!"); - Q_ASSERT_X(!node->m_parent, "QSGNode::insertChildNodeAfter", "QSGNode already has a parent"); - Q_ASSERT_X(after && after->m_parent == this, "QSGNode::insertChildNodeBefore", "The parent of \'before\' is wrong"); - -#ifndef QT_NO_DEBUG - if (node->type() == QSGNode::GeometryNodeType) { - QSGGeometryNode *g = static_cast<QSGGeometryNode *>(node); - Q_ASSERT_X(g->material(), "QSGNode::insertChildNodeAfter", "QSGGeometryNode is missing material"); - Q_ASSERT_X(g->geometry(), "QSGNode::insertChildNodeAfter", "QSGGeometryNode is missing geometry"); - } -#endif - - QSGNode *next = after->m_nextSibling; - if (next) - next->m_previousSibling = node; - else - m_lastChild = node; - node->m_nextSibling = next; - node->m_previousSibling = after; - after->m_nextSibling = node; - node->m_parent = this; - - node->markDirty(DirtyNodeAdded); -} - - - -/*! - Removes \a node from this node's list of children. - */ - -void QSGNode::removeChildNode(QSGNode *node) -{ - //Q_ASSERT(m_children.contains(node)); - Q_ASSERT(node->parent() == this); - - QSGNode *previous = node->m_previousSibling; - QSGNode *next = node->m_nextSibling; - if (previous) - previous->m_nextSibling = next; - else - m_firstChild = next; - if (next) - next->m_previousSibling = previous; - else - m_lastChild = previous; - node->m_previousSibling = 0; - node->m_nextSibling = 0; - - node->markDirty(DirtyNodeRemoved); - node->m_parent = 0; -} - - -/*! - Removes all child nodes from this node's list of children. - */ - -void QSGNode::removeAllChildNodes() -{ - while (m_firstChild) { - QSGNode *node = m_firstChild; - m_firstChild = node->m_nextSibling; - node->m_nextSibling = 0; - if (m_firstChild) - m_firstChild->m_previousSibling = 0; - else - m_lastChild = 0; - node->markDirty(DirtyNodeRemoved); - node->m_parent = 0; - } -} - - -int QSGNode::childCount() const -{ - int count = 0; - QSGNode *n = m_firstChild; - while (n) { - ++count; - n = n->m_nextSibling; - } - return count; -} - - -QSGNode *QSGNode::childAtIndex(int i) const -{ - QSGNode *n = m_firstChild; - while (i && n) { - --i; - n = n->m_nextSibling; - } - return n; -} - - -/*! - Sets the flag \a f on this node if \a enabled is true; - otherwise clears the flag. - - \sa flags() -*/ - -void QSGNode::setFlag(Flag f, bool enabled) -{ - if (enabled) - m_nodeFlags |= f; - else - m_nodeFlags &= ~f; -} - - -/*! - Sets the flags \a f on this node if \a enabled is true; - otherwise clears the flags. - - \sa flags() -*/ - -void QSGNode::setFlags(Flags f, bool enabled) -{ - if (enabled) - m_nodeFlags |= f; - else - m_nodeFlags &= ~f; -} - - - -/*! - Marks this node with the states in \a flags as dirty. - - When a node is marked dirty, it recursively mark the parent chain - as dirty and notify all connected renderers that the has dirty states. - */ - -void QSGNode::markDirty(DirtyFlags flags) -{ - m_flags |= (flags & DirtyPropagationMask); - - DirtyFlags subtreeFlags = DirtyFlags((flags & DirtyPropagationMask) << 16); - - int geometryCountDiff = 0; - if (flags & DirtyNodeAdded) - geometryCountDiff += m_subtreeGeometryCount; - if (flags & DirtyNodeRemoved) - geometryCountDiff -= m_subtreeGeometryCount; - - QSGNode *p = m_parent; - while (p) { - p->m_flags |= subtreeFlags; - p->m_subtreeGeometryCount += geometryCountDiff; - if (p->type() == RootNodeType) - static_cast<QSGRootNode *>(p)->notifyNodeChange(this, flags); - p = p->m_parent; - } -} - - - -/*! - \class QSGBasicGeometryNode - \brief The QSGBasicGeometryNode class serves as a baseclass for geometry based nodes - - \inmodule QtDeclarative - - The QSGBasicGeometryNode class should not be used by itself. It is only encapsulates - shared functionality between the QSGGeometryNode and QSGClipNode classes. - */ - - -/*! - Creates a new basic geometry node. - */ -QSGBasicGeometryNode::QSGBasicGeometryNode(NodeType type) - : QSGNode(type) - , m_geometry(0) - , m_matrix(0) - , m_clip_list(0) -{ -} - - -/*! - Deletes this QSGBasicGeometryNode. - - If the node has the flag QSGNode::OwnsGeometry set, it will also delete the - geometry object it is pointing to. This flag is not set by default. - */ - -QSGBasicGeometryNode::~QSGBasicGeometryNode() -{ - if (flags() & OwnsGeometry) - delete m_geometry; -} - - -/*! - \fn QSGGeometry *QSGBasicGeometryNode::geometry() const - - Returns this node's geometry. - - The geometry is null by default. - */ - - -/*! - Sets the geometry of this node to \a geometry. - - If the node has the flag QSGNode::OwnsGeometry set, it will also delete the - geometry object it is pointing to. This flag is not set by default. - */ - -void QSGBasicGeometryNode::setGeometry(QSGGeometry *geometry) -{ - if (flags() & OwnsGeometry) - delete m_geometry; - m_geometry = geometry; - markDirty(DirtyGeometry); -} - - - -/*! - \class QSGGeometryNode - \brief The QSGGeometryNode class is used for all rendered content in the scene graph. - - \inmodule QtDeclarative - - The QSGGeometryNode consists of geometry and material. The geometry defines the mesh, - the vertices and their structure, to be drawn. The Material defines how the shape is - filled. - - A geometry node must have both geometry and a normal material before it is added to - the scene graph. - - The geometry node supports two types of materials, the opaqueMaterial and the normal - material. The opaqueMaterial is used when the accumulated scene graph opacity at the - time of rendering is 1. The primary usecase is to special case opaque rendering - to avoid an extra operation in the fragment shader can have significant performance - impact on embedded graphics chips. The opaque material is optional. - - */ - - -/*! - Creates a new geometry node without geometry and material. - */ - -QSGGeometryNode::QSGGeometryNode() - : QSGBasicGeometryNode(GeometryNodeType) - , m_render_order(0) - , m_material(0) - , m_opaque_material(0) - , m_opacity(1) -{ -} - - -/*! - Deletes this geometry node. - - The flags QSGNode::OwnsMaterial, QSGNode::OwnsOpaqueMaterial and - QSGNode::OwnsGeometry decides weither the geometry node should also - delete the materials and geometry. By default, these flags are disabled. - */ - -QSGGeometryNode::~QSGGeometryNode() -{ - if (flags() & OwnsMaterial) - delete m_material; - if (flags() & OwnsOpaqueMaterial) - delete m_opaque_material; -} - - - -/*! - \fn int QSGGeometryNode::renderOrder() const - - Returns the render order of this geometry node. - - \internal - */ - - -/*! - Sets the render order of this node to be \a order. - - GeometryNodes are rendered in an order that visually looks like - low order nodes are rendered prior to high order nodes. For opaque - geometry there is little difference as z-testing will handle - the discard, but for translucent objects, the rendering should - normally be specified in the order of back-to-front. - - The default render order is 0. - - \internal - */ -void QSGGeometryNode::setRenderOrder(int order) -{ - m_render_order = order; -} - - - -/*! - Sets the material of this geometry node to \a material. - - Geometry nodes must have a material before they can be added to the - scene graph. - */ -void QSGGeometryNode::setMaterial(QSGMaterial *material) -{ - if (flags() & OwnsMaterial) - delete m_material; - m_material = material; -#ifndef QT_NO_DEBUG - if (m_material != 0 && m_opaque_material == m_material) - qWarning("QSGGeometryNode: using same material for both opaque and translucent"); -#endif - markDirty(DirtyMaterial); -} - - - -/*! - Sets the opaque material of this geometry to \a material. - - The opaque material will be preferred by the renderer over the - default material, as returned by the material() function, if - it is not null and the geometry item has an inherited opacity of - 1. - - The opaqueness refers to scene graph opacity, the material is still - allowed to set QSGMaterial::Blending to true and draw transparent - pixels. - */ -void QSGGeometryNode::setOpaqueMaterial(QSGMaterial *material) -{ - if (flags() & OwnsOpaqueMaterial) - delete m_opaque_material; - m_opaque_material = material; -#ifndef QT_NO_DEBUG - if (m_opaque_material != 0 && m_opaque_material == m_material) - qWarning("QSGGeometryNode: using same material for both opaque and translucent"); -#endif - - markDirty(DirtyMaterial); -} - - - -/*! - Returns the material which should currently be used for geometry node. - - If the inherited opacity of the node is 1 and there is an opaque material - set on this node, it will be returned; otherwise, the default material - will be returned. - - \warning This function requires the scene graph above this item to be - completely free of dirty states, so it can only be called during rendering - - \internal - - \sa setMaterial, setOpaqueMaterial - */ -QSGMaterial *QSGGeometryNode::activeMaterial() const -{ - Q_ASSERT_X(dirtyFlags() == 0, "QSGGeometryNode::activeMaterial()", "function assumes that all dirty states are cleaned up"); - if (m_opaque_material && m_opacity > 0.999) - return m_opaque_material; - return m_material; -} - - -/*! - Sets the inherited opacity of this geometry to \a opacity. - - This function is meant to be called by the node preprocessing - prior to rendering the tree, so it will not mark the tree as - dirty. - - \internal - */ -void QSGGeometryNode::setInheritedOpacity(qreal opacity) -{ - Q_ASSERT(opacity >= 0 && opacity <= 1); - m_opacity = opacity; -} - - -/*! - \class QSGClipNode - \brief The QSGClipNode class implements the clipping functionality in the scene graph. - - \inmodule QtDeclarative - - Clipping applies to the node's subtree and can be nested. Multiple clip nodes will be - accumulated by intersecting all their geometries. The accumulation happens - as part of the rendering. - - Clip nodes must have a geometry before they can be added to the scene graph. - - Clipping is usually implemented by using the stencil buffer. - */ - - - -/*! - Creates a new QSGClipNode without a geometry. - - The clip node must have a geometry before it can be added to the - scene graph. - */ - -QSGClipNode::QSGClipNode() - : QSGBasicGeometryNode(ClipNodeType) -{ -} - - - -/*! - Deletes this QSGClipNode. - - If the flag QSGNode::OwnsGeometry is set, the geometry will also be - deleted. - */ - -QSGClipNode::~QSGClipNode() -{ -} - - - -/*! - \fn bool QSGClipNode::isRectangular() const - - Returns if this clip node has a rectangular clip. - */ - - - -/*! - Sets whether this clip node has a rectangular clip to \a rectHint. - - This is an optimization hint which means that the renderer can - use scissoring instead of stencil, which is significnatly faster. - - When this hint is and it is applicable, the clip region will be - generated from clipRect() rather than geometry(). - */ - -void QSGClipNode::setIsRectangular(bool rectHint) -{ - m_is_rectangular = rectHint; -} - - - -/*! - \fn void QSGClipNode::clipRect() const - - Returns the clip rect of this node. - */ - - -/*! - Sets the clip rect of this clip node to \a rect. - - When a rectangular clip is set in combination with setIsRectangular - the renderer may in some cases use a more optimal clip method. - */ -void QSGClipNode::setClipRect(const QRectF &rect) -{ - m_clip_rect = rect; -} - - -/*! - \class QSGTransformNode - \brief The QSGTransformNode class implements transformations in the scene graph - - \inmodule QtDeclarative - - Transformations apply the node's subtree and can be nested. Multiple transform nodes - will be accumulated by intersecting all their matrices. The accumulation happens - as part of the rendering. - - The transform nodes implement a 4x4 matrix which in theory supports full 3D - transformations. However, because the renderer optimizes for 2D use-cases rather - than 3D use-cases, rendering a scene with full 3D transformations needs to - be done with some care. - */ - -QSGTransformNode::QSGTransformNode() - : QSGNode(TransformNodeType) -{ -} - - - -/*! - Deletes this transform node. - */ - -QSGTransformNode::~QSGTransformNode() -{ -} - - - -/*! - \fn QMatrix4x4 QSGTransformNode::matrix() const - - Returns this transform node's matrix. - */ - - - -/*! - Sets this transform node's matrix to \a matrix. - */ - -void QSGTransformNode::setMatrix(const QMatrix4x4 &matrix) -{ - m_matrix = matrix; - markDirty(DirtyMatrix); -} - - -/*! - Sets the combined matrix of this matrix to \a transform. - - This function is meant to be called by the node preprocessing - prior to rendering the tree, so it will not mark the tree as - dirty. - - \internal - */ -void QSGTransformNode::setCombinedMatrix(const QMatrix4x4 &matrix) -{ - m_combined_matrix = matrix; -} - - - -/*! - \class QSGRootNode - \brief The QSGRootNode is the toplevel root of any scene graph. - - The root node is used to attach a scene graph to a renderer. - - \internal - */ - - - -/*! - \fn QSGRootNode::QSGRootNode() - - Creates a new root node. - */ - -QSGRootNode::QSGRootNode() - : QSGNode(RootNodeType) -{ -} - - -/*! - Deletes the root node. - - When a root node is deleted it removes itself from all of renderers - that are referencing it. - */ - -QSGRootNode::~QSGRootNode() -{ - while (!m_renderers.isEmpty()) - m_renderers.last()->setRootNode(0); - destroy(); // Must call destroy() here because markDirty() casts this to QSGRootNode. -} - - - -/*! - Called to notify all renderers that \a node has been marked as dirty - with \a flags. - */ - -void QSGRootNode::notifyNodeChange(QSGNode *node, DirtyFlags flags) -{ - for (int i=0; i<m_renderers.size(); ++i) { - m_renderers.at(i)->nodeChanged(node, flags); - } -} - - - -/*! - \class QSGOpacityNode - \brief The QSGOpacityNode class is used to change opacity of nodes. - - \inmodule QtDeclarative - - Opacity applies to its subtree and can be nested. Multiple opacity nodes - will be accumulated by multiplying their opacity. The accumulation happens - as part of the rendering. - - When nested opacity gets below a certain threshold, the subtree might - be marked as blocked, causing isSubtreeBlocked() to return true. This - is done for performance reasons. - - */ - - - -/*! - Constructs an opacity node with a default opacity of 1. - - Opacity accumulates downwards in the scene graph so a node with two - QSGOpacityNode instances above it, both with opacity of 0.5, will have - effective opacity of 0.25. - - The default opacity of nodes is 1. - */ -QSGOpacityNode::QSGOpacityNode() - : QSGNode(OpacityNodeType) - , m_opacity(1) - , m_combined_opacity(1) -{ -} - - - -/*! - Deletes the opacity node. - */ - -QSGOpacityNode::~QSGOpacityNode() -{ -} - - - -/*! - \fn qreal QSGOpacityNode::opacity() const - - Returns this opacity node's opacity. - */ - - - -/*! - Sets the opacity of this node to \a opacity. - - Before rendering the graph, the renderer will do an update pass - over the subtree to propegate the opacity to its children. - - The value will be bounded to the range 0 to 1. - */ - -void QSGOpacityNode::setOpacity(qreal opacity) -{ - opacity = qBound<qreal>(0, opacity, 1); - if (m_opacity == opacity) - return; - m_opacity = opacity; - markDirty(DirtyOpacity); -} - - - -/*! - \fn qreal QSGOpacityNode::combinedOpacity() const - - Returns this node's accumulated opacity. - - This vaule is calculated during rendering and only stored - in the opacity node temporarily. - - \internal - */ - - - -/*! - Sets the combined opacity of this node to \a opacity. - - This function is meant to be called by the node preprocessing - prior to rendering the tree, so it will not mark the tree as - dirty. - - \internal - */ - -void QSGOpacityNode::setCombinedOpacity(qreal opacity) -{ - m_combined_opacity = opacity; -} - - - -/*! - For performance reasons, we block the subtree when the opacity - is below a certain threshold. - - \internal - */ - -bool QSGOpacityNode::isSubtreeBlocked() const -{ - return QSGNode::isSubtreeBlocked() || m_opacity < 0.001; -} - - -/*! - \class QSGNodeVisitor - \brief The QSGNodeVisitor class is a helper class for traversing the scene graph. - - \internal - */ - -QSGNodeVisitor::~QSGNodeVisitor() -{ - -} - - -void QSGNodeVisitor::visitNode(QSGNode *n) -{ - switch (n->type()) { - case QSGNode::TransformNodeType: { - QSGTransformNode *t = static_cast<QSGTransformNode *>(n); - enterTransformNode(t); - visitChildren(t); - leaveTransformNode(t); - break; } - case QSGNode::GeometryNodeType: { - QSGGeometryNode *g = static_cast<QSGGeometryNode *>(n); - enterGeometryNode(g); - visitChildren(g); - leaveGeometryNode(g); - break; } - case QSGNode::ClipNodeType: { - QSGClipNode *c = static_cast<QSGClipNode *>(n); - enterClipNode(c); - visitChildren(c); - leaveClipNode(c); - break; } - case QSGNode::OpacityNodeType: { - QSGOpacityNode *o = static_cast<QSGOpacityNode *>(n); - enterOpacityNode(o); - visitChildren(o); - leaveOpacityNode(o); - break; } - default: - visitChildren(n); - break; - } -} - -void QSGNodeVisitor::visitChildren(QSGNode *n) -{ - for (QSGNode *c = n->firstChild(); c; c = c->nextSibling()) - visitNode(c); -} - - - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const QSGGeometryNode *n) -{ - if (!n) { - d << "QSGGeometryNode(null)"; - return d; - } - d << "QSGGeometryNode(" << hex << (void *) n << dec; - - const QSGGeometry *g = n->geometry(); - - if (!g) { - d << "no geometry"; - } else { - - switch (g->drawingMode()) { - case GL_TRIANGLE_STRIP: d << "strip"; break; - case GL_TRIANGLE_FAN: d << "fan"; break; - case GL_TRIANGLES: d << "triangles"; break; - default: break; - } - - d << g->vertexCount(); - - if (g->attributeCount() > 0 && g->attributes()->type == GL_FLOAT) { - float x1 = 1e10, x2 = -1e10, y1=1e10, y2=-1e10; - int stride = g->sizeOfVertex(); - for (int i = 0; i < g->vertexCount(); ++i) { - float x = ((float *)((char *)const_cast<QSGGeometry *>(g)->vertexData() + i * stride))[0]; - float y = ((float *)((char *)const_cast<QSGGeometry *>(g)->vertexData() + i * stride))[1]; - - x1 = qMin(x1, x); - x2 = qMax(x2, x); - y1 = qMin(y1, y); - y2 = qMax(y2, y); - } - - d << "x1=" << x1 << "y1=" << y1 << "x2=" << x2 << "y2=" << y2; - } - } - - d << "order=" << n->renderOrder(); - if (n->material()) - d << "effect=" << n->material() << "type=" << n->material()->type(); - - - d << ")"; -#ifdef QML_RUNTIME_TESTING - d << n->description; -#endif - d << "dirty=" << hex << (int) n->dirtyFlags() << dec; - return d; -} - -QDebug operator<<(QDebug d, const QSGClipNode *n) -{ - if (!n) { - d << "QSGClipNode(null)"; - return d; - } - d << "QSGClipNode(" << hex << (void *) n << dec; - - if (n->childCount()) - d << "children=" << n->childCount(); - - d << "is rect?" << (n->isRectangular() ? "yes" : "no"); - - d << ")"; -#ifdef QML_RUNTIME_TESTING - d << n->description; -#endif - d << "dirty=" << hex << (int) n->dirtyFlags() << dec << (n->isSubtreeBlocked() ? "*BLOCKED*" : ""); - return d; -} - -QDebug operator<<(QDebug d, const QSGTransformNode *n) -{ - if (!n) { - d << "QSGTransformNode(null)"; - return d; - } - const QMatrix4x4 m = n->matrix(); - d << "QSGTransformNode("; - d << hex << (void *) n << dec; - if (m.isIdentity()) - d << "identity"; - else if (m.determinant() == 1 && m(0, 0) == 1 && m(1, 1) == 1 && m(2, 2) == 1) - d << "translate" << m(0, 3) << m(1, 3) << m(2, 3); - else - d << "det=" << n->matrix().determinant(); -#ifdef QML_RUNTIME_TESTING - d << n->description; -#endif - d << "dirty=" << hex << (int) n->dirtyFlags() << dec << (n->isSubtreeBlocked() ? "*BLOCKED*" : ""); - d << ")"; - return d; -} - -QDebug operator<<(QDebug d, const QSGOpacityNode *n) -{ - if (!n) { - d << "QSGOpacityNode(null)"; - return d; - } - d << "QSGOpacityNode("; - d << hex << (void *) n << dec; - d << "opacity=" << n->opacity() - << "combined=" << n->combinedOpacity() - << (n->isSubtreeBlocked() ? "*BLOCKED*" : ""); -#ifdef QML_RUNTIME_TESTING - d << n->description; -#endif - d << "dirty=" << hex << (int) n->dirtyFlags() << dec; - d << ")"; - return d; -} - - -QDebug operator<<(QDebug d, const QSGRootNode *n) -{ - if (!n) { - d << "QSGRootNode(null)"; - return d; - } - d << "QSGRootNode" << hex << (void *) n << "dirty=" << (int) n->dirtyFlags() << dec - << (n->isSubtreeBlocked() ? "*BLOCKED*" : ""); -#ifdef QML_RUNTIME_TESTING - d << n->description; -#endif - d << ")"; - return d; -} - - - -QDebug operator<<(QDebug d, const QSGNode *n) -{ - if (!n) { - d << "QSGNode(null)"; - return d; - } - switch (n->type()) { - case QSGNode::GeometryNodeType: - d << static_cast<const QSGGeometryNode *>(n); - break; - case QSGNode::TransformNodeType: - d << static_cast<const QSGTransformNode *>(n); - break; - case QSGNode::ClipNodeType: - d << static_cast<const QSGClipNode *>(n); - break; - case QSGNode::RootNodeType: - d << static_cast<const QSGRootNode *>(n); - break; - case QSGNode::OpacityNodeType: - d << static_cast<const QSGOpacityNode *>(n); - break; - default: - d << "QSGNode(" << hex << (void *) n << dec - << "dirty=" << hex << (int) n->dirtyFlags() - << "flags=" << (int) n->flags() << dec - << (n->isSubtreeBlocked() ? "*BLOCKED*" : ""); -#ifdef QML_RUNTIME_TESTING - d << n->description; -#endif - d << ")"; - break; - } - return d; -} - -#endif - -QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/coreapi/qsgnode.h b/src/declarative/scenegraph/coreapi/qsgnode.h deleted file mode 100644 index 58afff4bc7..0000000000 --- a/src/declarative/scenegraph/coreapi/qsgnode.h +++ /dev/null @@ -1,348 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef NODE_H -#define NODE_H - -#include "qsggeometry.h" -#include <QtGui/QMatrix4x4> - -#include <float.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -#define QML_RUNTIME_TESTING - -class QSGRenderer; - -class QSGNode; -class QSGRootNode; -class QSGGeometryNode; -class QSGTransformNode; -class QSGClipNode; - -class Q_DECLARATIVE_EXPORT QSGNode -{ -public: - enum NodeType { - BasicNodeType, - RootNodeType, - GeometryNodeType, - TransformNodeType, - ClipNodeType, - OpacityNodeType, - UserNodeType = 1024 - }; - - enum DirtyFlag { - DirtyMatrix = 0x0001, - DirtyClipList = 0x0002, - DirtyNodeAdded = 0x0004, - DirtyNodeRemoved = 0x0008, - DirtyGeometry = 0x0010, - DirtyMaterial = 0x0040, - DirtyOpacity = 0x0080, - DirtyForceUpdate = 0x0100, - - DirtyPropagationMask = DirtyMatrix - | DirtyClipList - | DirtyNodeAdded - | DirtyOpacity - | DirtyForceUpdate - - }; - Q_DECLARE_FLAGS(DirtyFlags, DirtyFlag) - - enum Flag { - // Lower 16 bites reserved for general node - OwnedByParent = 0x0001, - UsePreprocess = 0x0002, - ChildrenDoNotOverlap = 0x0004, - - // Upper 16 bits reserved for node subclasses - - // QSGBasicGeometryNode - OwnsGeometry = 0x00010000, - OwnsMaterial = 0x00020000, - OwnsOpaqueMaterial = 0x00040000 - }; - Q_DECLARE_FLAGS(Flags, Flag) - - QSGNode(); - virtual ~QSGNode(); - - QSGNode *parent() const { return m_parent; } - - void removeChildNode(QSGNode *node); - void removeAllChildNodes(); - void prependChildNode(QSGNode *node); - void appendChildNode(QSGNode *node); - void insertChildNodeBefore(QSGNode *node, QSGNode *before); - void insertChildNodeAfter(QSGNode *node, QSGNode *after); - - int childCount() const; - QSGNode *childAtIndex(int i) const; - QSGNode *firstChild() const { return m_firstChild; } - QSGNode *lastChild() const { return m_lastChild; } - QSGNode *nextSibling() const { return m_nextSibling; } - QSGNode* previousSibling() const { return m_previousSibling; } - - inline NodeType type() const { return m_type; } - - void clearDirty() { m_flags = 0; } - void markDirty(DirtyFlags flags); - DirtyFlags dirtyFlags() const { return m_flags; } - - virtual bool isSubtreeBlocked() const; - - Flags flags() const { return m_nodeFlags; } - void setFlag(Flag, bool = true); - void setFlags(Flags, bool = true); - - virtual void preprocess() { } - -#ifdef QML_RUNTIME_TESTING - QString description; -#endif - -protected: - QSGNode(NodeType type); - -private: - friend class QSGRootNode; - - void init(); - void destroy(); - - QSGNode *m_parent; - NodeType m_type; - QSGNode *m_firstChild; - QSGNode *m_lastChild; - QSGNode *m_nextSibling; - QSGNode *m_previousSibling; - int m_subtreeGeometryCount; - - Flags m_nodeFlags; - DirtyFlags m_flags; - - void *m_reserved; -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(QSGNode::DirtyFlags) -Q_DECLARE_OPERATORS_FOR_FLAGS(QSGNode::Flags) - -class Q_DECLARATIVE_EXPORT QSGBasicGeometryNode : public QSGNode -{ -public: -// enum UsagePattern { -// Static, -// Dynamic, -// Stream -// }; -// void setUsagePattern(UsagePattern pattern); -// UsagePattern usagePattern() const { return m_pattern; } - - ~QSGBasicGeometryNode(); - - void setGeometry(QSGGeometry *geometry); - const QSGGeometry *geometry() const { return m_geometry; } - QSGGeometry *geometry() { return m_geometry; } - - const QMatrix4x4 *matrix() const { return m_matrix; } - const QSGClipNode *clipList() const { return m_clip_list; } - -protected: - QSGBasicGeometryNode(NodeType type); - -private: - friend class QSGNodeUpdater; - QSGGeometry *m_geometry; - - int m_reserved_start_index; - int m_reserved_end_index; - - const QMatrix4x4 *m_matrix; - const QSGClipNode *m_clip_list; - -// UsagePattern m_pattern; -}; - -class QSGMaterial; - -class Q_DECLARATIVE_EXPORT QSGGeometryNode : public QSGBasicGeometryNode -{ -public: - QSGGeometryNode(); - ~QSGGeometryNode(); - - void setMaterial(QSGMaterial *material); - QSGMaterial *material() const { return m_material; } - - void setOpaqueMaterial(QSGMaterial *material); - QSGMaterial *opaqueMaterial() const { return m_opaque_material; } - - QSGMaterial *activeMaterial() const; - - void setRenderOrder(int order); - int renderOrder() const { return m_render_order; } - - void setInheritedOpacity(qreal opacity); - qreal inheritedOpacity() const { return m_opacity; } - -private: - friend class QSGNodeUpdater; - - int m_render_order; - QSGMaterial *m_material; - QSGMaterial *m_opaque_material; - - qreal m_opacity; -}; - -class Q_DECLARATIVE_EXPORT QSGClipNode : public QSGBasicGeometryNode -{ -public: - QSGClipNode(); - ~QSGClipNode(); - - void setIsRectangular(bool rectHint); - bool isRectangular() const { return m_is_rectangular; } - - void setClipRect(const QRectF &); - QRectF clipRect() const { return m_clip_rect; } - -private: - uint m_is_rectangular : 1; - uint m_reserved : 31; - - QRectF m_clip_rect; -}; - - -class Q_DECLARATIVE_EXPORT QSGTransformNode : public QSGNode -{ -public: - QSGTransformNode(); - ~QSGTransformNode(); - - void setMatrix(const QMatrix4x4 &matrix); - const QMatrix4x4 &matrix() const { return m_matrix; } - - void setCombinedMatrix(const QMatrix4x4 &matrix); - const QMatrix4x4 &combinedMatrix() const { return m_combined_matrix; } - -private: - QMatrix4x4 m_matrix; - QMatrix4x4 m_combined_matrix; -}; - - -class Q_DECLARATIVE_EXPORT QSGRootNode : public QSGNode -{ -public: - QSGRootNode(); - ~QSGRootNode(); - -private: - void notifyNodeChange(QSGNode *node, DirtyFlags flags); - - friend class QSGRenderer; - friend class QSGNode; - friend class QSGGeometryNode; - - QList<QSGRenderer *> m_renderers; -}; - - -class Q_DECLARATIVE_EXPORT QSGOpacityNode : public QSGNode -{ -public: - QSGOpacityNode(); - ~QSGOpacityNode(); - - void setOpacity(qreal opacity); - qreal opacity() const { return m_opacity; } - - void setCombinedOpacity(qreal opacity); - qreal combinedOpacity() const { return m_combined_opacity; } - - bool isSubtreeBlocked() const; - -private: - qreal m_opacity; - qreal m_combined_opacity; -}; - -class Q_DECLARATIVE_EXPORT QSGNodeVisitor { -public: - virtual ~QSGNodeVisitor(); - -protected: - virtual void enterTransformNode(QSGTransformNode *) {} - virtual void leaveTransformNode(QSGTransformNode *) {} - virtual void enterClipNode(QSGClipNode *) {} - virtual void leaveClipNode(QSGClipNode *) {} - virtual void enterGeometryNode(QSGGeometryNode *) {} - virtual void leaveGeometryNode(QSGGeometryNode *) {} - virtual void enterOpacityNode(QSGOpacityNode *) {} - virtual void leaveOpacityNode(QSGOpacityNode *) {} - virtual void visitNode(QSGNode *n); - virtual void visitChildren(QSGNode *n); -}; - -#ifndef QT_NO_DEBUG_STREAM -Q_DECLARATIVE_EXPORT QDebug operator<<(QDebug, const QSGNode *n); -Q_DECLARATIVE_EXPORT QDebug operator<<(QDebug, const QSGGeometryNode *n); -Q_DECLARATIVE_EXPORT QDebug operator<<(QDebug, const QSGTransformNode *n); -Q_DECLARATIVE_EXPORT QDebug operator<<(QDebug, const QSGOpacityNode *n); -Q_DECLARATIVE_EXPORT QDebug operator<<(QDebug, const QSGRootNode *n); - -#endif - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // NODE_H diff --git a/src/declarative/scenegraph/coreapi/qsgnodeupdater.cpp b/src/declarative/scenegraph/coreapi/qsgnodeupdater.cpp deleted file mode 100644 index a7e5b08dc1..0000000000 --- a/src/declarative/scenegraph/coreapi/qsgnodeupdater.cpp +++ /dev/null @@ -1,287 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsgnodeupdater_p.h" - -QT_BEGIN_NAMESPACE - -// #define QSG_UPDATER_DEBUG - -QSGNodeUpdater::QSGNodeUpdater() - : m_combined_matrix_stack(64) - , m_opacity_stack(64) - , m_current_clip(0) - , m_force_update(0) -{ - m_opacity_stack.add(1); -} - -void QSGNodeUpdater::updateStates(QSGNode *n) -{ - m_current_clip = 0; - m_force_update = 0; - - Q_ASSERT(m_opacity_stack.size() == 1); // The one we added in the constructr... - Q_ASSERT(m_combined_matrix_stack.isEmpty()); - - visitNode(n); -} - -/*! - \fn void QSGNodeUpdater::setToplevelOpacity(qreal opacity) - - Sets the toplevel opacity that will be multiplied with the - - The default opacity is 1. Any other value will cause artifacts, and is - primarily useful for debug purposes. - - The changing the value during an update pass will have undefined results - */ - -/*! - \fn qreal QSGNodeUpdater::toplevelOpacity() const - - Returns the toplevel opacity for the node updater. The default - value is 1. - */ - - -/*! - Returns true if \a node is has something that blocks it in the chain from - \a node to \a root doing a full state update pass. - - This function does not process dirty states, simply does a simple traversion - up to the top. - - The function assumes that \a root exists in the parent chain of \a node. - */ - -bool QSGNodeUpdater::isNodeBlocked(QSGNode *node, QSGNode *root) const -{ - qreal opacity = 1; - while (node != root) { - if (node->type() == QSGNode::OpacityNodeType) { - opacity *= static_cast<QSGOpacityNode *>(node)->opacity(); - if (opacity < 0.001) - return true; - } - node = node->parent(); - - Q_ASSERT_X(node, "QSGNodeUpdater::isNodeBlocked", "node is not in the subtree of root"); - } - - return false; -} - - -void QSGNodeUpdater::enterTransformNode(QSGTransformNode *t) -{ - if (t->dirtyFlags() & QSGNode::DirtyMatrix) - ++m_force_update; - -#ifdef QSG_UPDATER_DEBUG - qDebug() << "enter transform:" << t << "force=" << m_force_update; -#endif - - if (!t->matrix().isIdentity()) { - if (!m_combined_matrix_stack.isEmpty()) { - t->setCombinedMatrix(*m_combined_matrix_stack.last() * t->matrix()); - } else { - t->setCombinedMatrix(t->matrix()); - } - m_combined_matrix_stack.add(&t->combinedMatrix()); - } else { - if (!m_combined_matrix_stack.isEmpty()) { - t->setCombinedMatrix(*m_combined_matrix_stack.last()); - } else { - t->setCombinedMatrix(QMatrix4x4()); - } - } -} - - -void QSGNodeUpdater::leaveTransformNode(QSGTransformNode *t) -{ -#ifdef QSG_UPDATER_DEBUG - qDebug() << "leave transform:" << t; -#endif - - if (t->dirtyFlags() & QSGNode::DirtyMatrix) - --m_force_update; - - if (!t->matrix().isIdentity()) { - m_combined_matrix_stack.pop_back(); - } - -} - - -void QSGNodeUpdater::enterClipNode(QSGClipNode *c) -{ -#ifdef QSG_UPDATER_DEBUG - qDebug() << "enter clip:" << c; -#endif - - if (c->dirtyFlags() & QSGNode::DirtyClipList) - ++m_force_update; - - c->m_matrix = m_combined_matrix_stack.isEmpty() ? 0 : m_combined_matrix_stack.last(); - c->m_clip_list = m_current_clip; - m_current_clip = c; -} - - -void QSGNodeUpdater::leaveClipNode(QSGClipNode *c) -{ -#ifdef QSG_UPDATER_DEBUG - qDebug() << "leave clip:" << c; -#endif - - if (c->dirtyFlags() & QSGNode::DirtyClipList) - --m_force_update; - - m_current_clip = c->m_clip_list; -} - - -void QSGNodeUpdater::enterGeometryNode(QSGGeometryNode *g) -{ -#ifdef QSG_UPDATER_DEBUG - qDebug() << "enter geometry:" << g; -#endif - - g->m_matrix = m_combined_matrix_stack.isEmpty() ? 0 : m_combined_matrix_stack.last(); - g->m_clip_list = m_current_clip; - g->setInheritedOpacity(m_opacity_stack.last()); -} - -void QSGNodeUpdater::leaveGeometryNode(QSGGeometryNode *g) -{ -#ifdef QSG_UPDATER_DEBUG - qDebug() << "leave geometry" << g; -#else - Q_UNUSED(g) -#endif -} - -void QSGNodeUpdater::enterOpacityNode(QSGOpacityNode *o) -{ - if (o->dirtyFlags() & QSGNode::DirtyOpacity) - ++m_force_update; - - qreal opacity = m_opacity_stack.last() * o->opacity(); - o->setCombinedOpacity(opacity); - m_opacity_stack.add(opacity); - -#ifdef QSG_UPDATER_DEBUG - qDebug() << "enter opacity" << o; -#endif -} - -void QSGNodeUpdater::leaveOpacityNode(QSGOpacityNode *o) -{ -#ifdef QSG_UPDATER_DEBUG - qDebug() << "leave opacity" << o; -#endif - if (o->flags() & QSGNode::DirtyOpacity) - --m_force_update; - - m_opacity_stack.pop_back(); -} - -void QSGNodeUpdater::visitChildren(QSGNode *n) -{ - for (QSGNode *c = n->firstChild(); c; c = c->nextSibling()) - visitNode(c); -} - -void QSGNodeUpdater::visitNode(QSGNode *n) -{ -#ifdef QSG_UPDATER_DEBUG - qDebug() << "enter:" << n; -#endif - - if (!n->dirtyFlags() && !m_force_update) - return; - if (n->isSubtreeBlocked()) - return; - - bool forceUpdate = n->dirtyFlags() & (QSGNode::DirtyNodeAdded | QSGNode::DirtyForceUpdate); - if (forceUpdate) - ++m_force_update; - - switch (n->type()) { - case QSGNode::TransformNodeType: { - QSGTransformNode *t = static_cast<QSGTransformNode *>(n); - enterTransformNode(t); - visitChildren(t); - leaveTransformNode(t); - break; } - case QSGNode::GeometryNodeType: { - QSGGeometryNode *g = static_cast<QSGGeometryNode *>(n); - enterGeometryNode(g); - visitChildren(g); - leaveGeometryNode(g); - break; } - case QSGNode::ClipNodeType: { - QSGClipNode *c = static_cast<QSGClipNode *>(n); - enterClipNode(c); - visitChildren(c); - leaveClipNode(c); - break; } - case QSGNode::OpacityNodeType: { - QSGOpacityNode *o = static_cast<QSGOpacityNode *>(n); - enterOpacityNode(o); - visitChildren(o); - leaveOpacityNode(o); - break; } - default: - visitChildren(n); - break; - } - - if (forceUpdate) - --m_force_update; - - n->clearDirty(); -} - -QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/coreapi/qsgnodeupdater_p.h b/src/declarative/scenegraph/coreapi/qsgnodeupdater_p.h deleted file mode 100644 index 25d7c11fa1..0000000000 --- a/src/declarative/scenegraph/coreapi/qsgnodeupdater_p.h +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef NODEUPDATER_P_H -#define NODEUPDATER_P_H - -#include "qsgnode.h" -#include <QtGui/private/qdatabuffer_p.h> - -QT_BEGIN_NAMESPACE - -class Q_DECLARATIVE_EXPORT QSGNodeUpdater -{ -public: - QSGNodeUpdater(); - - virtual void updateStates(QSGNode *n); - virtual bool isNodeBlocked(QSGNode *n, QSGNode *root) const; - - void setToplevelOpacity(qreal alpha) { m_opacity_stack.last() = alpha; } - qreal toplevelOpacity() const { return m_opacity_stack.last(); } - -protected: - virtual void enterTransformNode(QSGTransformNode *); - virtual void leaveTransformNode(QSGTransformNode *); - void enterClipNode(QSGClipNode *c); - void leaveClipNode(QSGClipNode *c); - void enterOpacityNode(QSGOpacityNode *o); - void leaveOpacityNode(QSGOpacityNode *o); - void enterGeometryNode(QSGGeometryNode *); - void leaveGeometryNode(QSGGeometryNode *); - - void visitNode(QSGNode *n); - void visitChildren(QSGNode *n); - - - QDataBuffer<const QMatrix4x4 *> m_combined_matrix_stack; - QDataBuffer<qreal> m_opacity_stack; - const QSGClipNode *m_current_clip; - - int m_force_update; - - qreal m_toplevel_alpha; -}; - -QT_END_NAMESPACE - -#endif // NODEUPDATER_P_H diff --git a/src/declarative/scenegraph/coreapi/qsgrenderer.cpp b/src/declarative/scenegraph/coreapi/qsgrenderer.cpp deleted file mode 100644 index b22631afae..0000000000 --- a/src/declarative/scenegraph/coreapi/qsgrenderer.cpp +++ /dev/null @@ -1,743 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsgrenderer_p.h" -#include "qsgnode.h" -#include "qsgmaterial.h" -#include "qsgnodeupdater_p.h" -#include "qsggeometry_p.h" - -#include <private/qsgadaptationlayer_p.h> - -#include <QOpenGLShaderProgram> -#include <qopenglframebufferobject.h> -#include <QtGui/qguiapplication.h> - -#include <qdatetime.h> - -QT_BEGIN_NAMESPACE - -//#define RENDERER_DEBUG -//#define QT_GL_NO_SCISSOR_TEST - - - -#define QSG_RENDERER_TIMING -#ifdef QSG_RENDERER_TIMING -static bool qsg_render_timing = !qgetenv("QML_RENDERER_TIMING").isEmpty(); -static QTime frameTimer; -static int preprocessTime; -static int updatePassTime; -#endif - -void QSGBindable::clear(QSGRenderer::ClearMode mode) const -{ - GLuint bits = 0; - if (mode & QSGRenderer::ClearColorBuffer) bits |= GL_COLOR_BUFFER_BIT; - if (mode & QSGRenderer::ClearDepthBuffer) bits |= GL_DEPTH_BUFFER_BIT; - if (mode & QSGRenderer::ClearStencilBuffer) bits |= GL_STENCIL_BUFFER_BIT; - glClear(bits); -} - -// Reactivate the color buffer after switching to the stencil. -void QSGBindable::reactivate() const -{ - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); -} - -QSGBindableFbo::QSGBindableFbo(QOpenGLFramebufferObject *fbo) : m_fbo(fbo) -{ -} - - -void QSGBindableFbo::bind() const -{ - m_fbo->bind(); -} - -/*! - \class QSGRenderer - \brief The renderer class is the abstract baseclass use for rendering the - QML scene graph. - - The renderer is not tied to any particular surface. It expects a context to - be current and will render into that surface according to how the device rect, - viewport rect and projection transformation are set up. - - Rendering is a sequence of steps initiated by calling renderScene(). This will - effectively draw the scene graph starting at the root node. The QSGNode::preprocess() - function will be called for all the nodes in the graph, followed by an update - pass which updates all matrices, opacity, clip states and similar in the graph. - Because the update pass is called after preprocess, it is safe to modify the graph - during preprocess. To run a custom update pass over the graph, install a custom - QSGNodeUpdater using setNodeUpdater(). Once all the graphs dirty states are updated, - the virtual render() function is called. - - The render() function is implemented by QSGRenderer subclasses to render the graph - in the most optimal way for a given hardware. - - The renderer can make use of stencil, depth and color buffers in addition to the - scissor rect. - - \internal - */ - - -QSGRenderer::QSGRenderer(QSGContext *context) - : QObject() - , m_clear_color(Qt::transparent) - , m_clear_mode(ClearColorBuffer | ClearDepthBuffer) - , m_current_opacity(1) - , m_context(context) - , m_root_node(0) - , m_node_updater(0) - , m_bindable(0) - , m_changed_emitted(false) - , m_mirrored(false) - , m_is_rendering(false) - , m_vertex_buffer_bound(false) - , m_index_buffer_bound(false) -{ - initializeGLFunctions(); -} - - -QSGRenderer::~QSGRenderer() -{ - setRootNode(0); - delete m_node_updater; -} - -/*! - Returns the scene graph context for this renderer. - - \internal - */ - -QSGContext *QSGRenderer::context() -{ - return m_context; -} - - - - -/*! - Returns the node updater that this renderer uses to update states in the - scene graph. - - If no updater is specified a default one is constructed. - */ - -QSGNodeUpdater *QSGRenderer::nodeUpdater() const -{ - if (!m_node_updater) - const_cast<QSGRenderer *>(this)->m_node_updater = new QSGNodeUpdater(); - return m_node_updater; -} - - -/*! - Sets the node updater that this renderer uses to update states in the - scene graph. - - This will delete and override any existing node updater - */ -void QSGRenderer::setNodeUpdater(QSGNodeUpdater *updater) -{ - if (m_node_updater) - delete m_node_updater; - m_node_updater = updater; -} - - -void QSGRenderer::setRootNode(QSGRootNode *node) -{ - if (m_root_node == node) - return; - if (m_root_node) { - m_root_node->m_renderers.removeOne(this); - nodeChanged(m_root_node, QSGNode::DirtyNodeRemoved); - } - m_root_node = node; - if (m_root_node) { - Q_ASSERT(!m_root_node->m_renderers.contains(this)); - m_root_node->m_renderers << this; - nodeChanged(m_root_node, QSGNode::DirtyNodeAdded); - } -} - - -void QSGRenderer::renderScene() -{ - class B : public QSGBindable - { - public: - void bind() const { QOpenGLFramebufferObject::bindDefault(); } - } b; - renderScene(b); -} - -void QSGRenderer::renderScene(const QSGBindable &bindable) -{ - if (!m_root_node) - return; - - m_is_rendering = true; - - -#ifdef QSG_RENDERER_TIMING - if (qsg_render_timing) - frameTimer.start(); - int bindTime; - int renderTime; -#endif - - m_bindable = &bindable; - preprocess(); - - bindable.bind(); -#ifdef QSG_RENDERER_TIMING - if (qsg_render_timing) - bindTime = frameTimer.elapsed(); -#endif - -#ifndef QT_NO_DEBUG - // Sanity check that attribute registers are disabled - { - GLint count; - glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &count); - GLint enabled; - for (int i=0; i<count; ++i) { - glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &enabled); - if (enabled) { - qWarning("QSGRenderer: attribute %d is enabled, this can lead to memory corruption and crashes.", i); - } - } - } -#endif - - render(); -#ifdef QSG_RENDERER_TIMING - if (qsg_render_timing) - renderTime = frameTimer.elapsed(); -#endif - - glDisable(GL_SCISSOR_TEST); - m_is_rendering = false; - m_changed_emitted = false; - m_bindable = 0; - - if (m_vertex_buffer_bound) { - glBindBuffer(GL_ARRAY_BUFFER, 0); - m_vertex_buffer_bound = false; - } - - if (m_index_buffer_bound) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - m_index_buffer_bound = false; - } - -#ifdef QSG_RENDERER_TIMING - if (qsg_render_timing) { - printf(" - Breakdown of frametime: preprocess=%d, updates=%d, binding=%d, render=%d, total=%d\n", - preprocessTime, - updatePassTime - preprocessTime, - bindTime - updatePassTime, - renderTime - bindTime, - renderTime); - } -#endif -} - -void QSGRenderer::setProjectionMatrixToDeviceRect() -{ - setProjectionMatrixToRect(m_device_rect); -} - -void QSGRenderer::setProjectionMatrixToRect(const QRectF &rect) -{ - QMatrix4x4 matrix; - matrix.ortho(rect.x(), - rect.x() + rect.width(), - rect.y() + rect.height(), - rect.y(), - qreal(0.01), - -1); - setProjectionMatrix(matrix); -} - -void QSGRenderer::setProjectionMatrix(const QMatrix4x4 &matrix) -{ - m_projection_matrix = matrix; - // Mirrored relative to the usual Qt coordinate system with origin in the top left corner. - m_mirrored = matrix(0, 0) * matrix(1, 1) - matrix(0, 1) * matrix(1, 0) > 0; -} - -void QSGRenderer::setClearColor(const QColor &color) -{ - m_clear_color = color; -} - -/*! - Updates internal data structures and emits the sceneGraphChanged() signal. - - If \a flags contains the QSGNode::DirtyNodeRemoved flag, the node might be - in the process of being destroyed. It is then not safe to downcast the node - pointer. -*/ - -void QSGRenderer::nodeChanged(QSGNode *node, QSGNode::DirtyFlags flags) -{ - Q_UNUSED(node); - Q_UNUSED(flags); - - if (flags & QSGNode::DirtyNodeAdded) - addNodesToPreprocess(node); - if (flags & QSGNode::DirtyNodeRemoved) - removeNodesToPreprocess(node); - - if (!m_changed_emitted && !m_is_rendering) { - // Premature overoptimization to avoid excessive signal emissions - m_changed_emitted = true; - emit sceneGraphChanged(); - } -} - -void QSGRenderer::materialChanged(QSGGeometryNode *, QSGMaterial *, QSGMaterial *) -{ -} - -void QSGRenderer::preprocess() -{ - Q_ASSERT(m_root_node); - - // We need to take a copy here, in case any of the preprocess calls deletes a node that - // is in the preprocess list and thus, changes the m_nodes_to_preprocess behind our backs - // For the default case, when this does not happen, the cost is neglishible. - QSet<QSGNode *> items = m_nodes_to_preprocess; - - for (QSet<QSGNode *>::const_iterator it = items.constBegin(); - it != items.constEnd(); ++it) { - QSGNode *n = *it; - if (!nodeUpdater()->isNodeBlocked(n, m_root_node)) { - n->preprocess(); - } - } - -#ifdef QSG_RENDERER_TIMING - if (qsg_render_timing) - preprocessTime = frameTimer.elapsed(); -#endif - - nodeUpdater()->setToplevelOpacity(context()->renderAlpha()); - nodeUpdater()->updateStates(m_root_node); - -#ifdef QSG_RENDERER_TIMING - if (qsg_render_timing) - updatePassTime = frameTimer.elapsed(); -#endif - -} - -void QSGRenderer::addNodesToPreprocess(QSGNode *node) -{ - for (QSGNode *c = node->firstChild(); c; c = c->nextSibling()) - addNodesToPreprocess(c); - if (node->flags() & QSGNode::UsePreprocess) - m_nodes_to_preprocess.insert(node); -} - -void QSGRenderer::removeNodesToPreprocess(QSGNode *node) -{ - for (QSGNode *c = node->firstChild(); c; c = c->nextSibling()) - removeNodesToPreprocess(c); - if (node->flags() & QSGNode::UsePreprocess) - m_nodes_to_preprocess.remove(node); -} - - -/*! - Convenience function to set up the stencil buffer for clipping based on \a clip. - - If the clip is a pixel aligned rectangle, this function will use glScissor instead - of stencil. - */ - -QSGRenderer::ClipType QSGRenderer::updateStencilClip(const QSGClipNode *clip) -{ - if (!clip) { - glDisable(GL_STENCIL_TEST); - glDisable(GL_SCISSOR_TEST); - return NoClip; - } - - bool stencilEnabled = false; - bool scissorEnabled = false; - - glDisable(GL_SCISSOR_TEST); - - int clipDepth = 0; - QRect clipRect; - while (clip) { - QMatrix4x4 m = m_current_projection_matrix; - if (clip->matrix()) - m *= *clip->matrix(); - - // TODO: Check for multisampling and pixel grid alignment. - bool isRectangleWithNoPerspective = clip->isRectangular() - && qFuzzyIsNull(m(3, 0)) && qFuzzyIsNull(m(3, 1)); - bool noRotate = qFuzzyIsNull(m(0, 1)) && qFuzzyIsNull(m(1, 0)); - bool isRotate90 = qFuzzyIsNull(m(0, 0)) && qFuzzyIsNull(m(1, 1)); - - if (isRectangleWithNoPerspective && (noRotate || isRotate90)) { - QRectF bbox = clip->clipRect(); - qreal invW = 1 / m(3, 3); - qreal fx1, fy1, fx2, fy2; - if (noRotate) { - fx1 = (bbox.left() * m(0, 0) + m(0, 3)) * invW; - fy1 = (bbox.bottom() * m(1, 1) + m(1, 3)) * invW; - fx2 = (bbox.right() * m(0, 0) + m(0, 3)) * invW; - fy2 = (bbox.top() * m(1, 1) + m(1, 3)) * invW; - } else { - Q_ASSERT(isRotate90); - fx1 = (bbox.bottom() * m(0, 1) + m(0, 3)) * invW; - fy1 = (bbox.left() * m(1, 0) + m(1, 3)) * invW; - fx2 = (bbox.top() * m(0, 1) + m(0, 3)) * invW; - fy2 = (bbox.right() * m(1, 0) + m(1, 3)) * invW; - } - - if (fx1 > fx2) - qSwap(fx1, fx2); - if (fy1 > fy2) - qSwap(fy1, fy2); - - GLint ix1 = qRound((fx1 + 1) * m_device_rect.width() * qreal(0.5)); - GLint iy1 = qRound((fy1 + 1) * m_device_rect.height() * qreal(0.5)); - GLint ix2 = qRound((fx2 + 1) * m_device_rect.width() * qreal(0.5)); - GLint iy2 = qRound((fy2 + 1) * m_device_rect.height() * qreal(0.5)); - - if (!scissorEnabled) { - clipRect = QRect(ix1, iy1, ix2 - ix1, iy2 - iy1); - glEnable(GL_SCISSOR_TEST); - scissorEnabled = true; - } else { - clipRect &= QRect(ix1, iy1, ix2 - ix1, iy2 - iy1); - } - - glScissor(clipRect.x(), clipRect.y(), clipRect.width(), clipRect.height()); - } else { - if (!stencilEnabled) { - if (!m_clip_program.isLinked()) { - m_clip_program.addShaderFromSourceCode(QOpenGLShader::Vertex, - "attribute highp vec4 vCoord; \n" - "uniform highp mat4 matrix; \n" - "void main() { \n" - " gl_Position = matrix * vCoord; \n" - "}"); - m_clip_program.addShaderFromSourceCode(QOpenGLShader::Fragment, - "void main() { \n" - " gl_FragColor = vec4(0.81, 0.83, 0.12, 1.0); \n" // Trolltech green ftw! - "}"); - m_clip_program.bindAttributeLocation("vCoord", 0); - m_clip_program.link(); - m_clip_matrix_id = m_clip_program.uniformLocation("matrix"); - } - - glStencilMask(0xff); // write mask - glClearStencil(0); - glClear(GL_STENCIL_BUFFER_BIT); - glEnable(GL_STENCIL_TEST); - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - glDepthMask(GL_FALSE); - - m_clip_program.bind(); - m_clip_program.enableAttributeArray(0); - - stencilEnabled = true; - } - - glStencilFunc(GL_EQUAL, clipDepth, 0xff); // stencil test, ref, test mask - glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); // stencil fail, z fail, z pass - - const QSGGeometry *g = clip->geometry(); - Q_ASSERT(g->attributeCount() > 0); - const QSGGeometry::Attribute *a = g->attributes(); - glVertexAttribPointer(0, a->tupleSize, a->type, GL_FALSE, g->sizeOfVertex(), g->vertexData()); - - m_clip_program.setUniformValue(m_clip_matrix_id, m); - if (g->indexCount()) { - glDrawElements(g->drawingMode(), g->indexCount(), g->indexType(), g->indexData()); - } else { - glDrawArrays(g->drawingMode(), 0, g->vertexCount()); - } - - ++clipDepth; - } - - clip = clip->clipList(); - } - - if (stencilEnabled) { - m_clip_program.disableAttributeArray(0); - glStencilFunc(GL_EQUAL, clipDepth, 0xff); // stencil test, ref, test mask - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // stencil fail, z fail, z pass - glStencilMask(0); // write mask - bindable()->reactivate(); - } else { - glDisable(GL_STENCIL_TEST); - } - - if (!scissorEnabled) - glDisable(GL_SCISSOR_TEST); - - return stencilEnabled ? StencilClip : ScissorClip; -} - - - -static inline int size_of_type(GLenum type) -{ - static int sizes[] = { - sizeof(char), - sizeof(unsigned char), - sizeof(short), - sizeof(unsigned short), - sizeof(int), - sizeof(unsigned int), - sizeof(float), - 2, - 3, - 4, - sizeof(double) - }; - Q_ASSERT(type >= GL_BYTE && type <= 0x140A); // the value of GL_DOUBLE - return sizes[type - GL_BYTE]; -} - - -class QSGRendererVBOGeometryData : public QSGGeometryData -{ -public: - QSGRendererVBOGeometryData() - : vertexBuffer(0) - , indexBuffer(0) - { - } - - ~QSGRendererVBOGeometryData() - { - QOpenGLContext *ctx = QOpenGLContext::currentContext(); - if (!ctx) - return; - QOpenGLFunctions *func = ctx->functions(); - if (vertexBuffer) - func->glDeleteBuffers(1, &vertexBuffer); - if (indexBuffer) - func->glDeleteBuffers(1, &indexBuffer); - } - - GLuint vertexBuffer; - GLuint indexBuffer; - - static QSGRendererVBOGeometryData *get(const QSGGeometry *g) { - QSGRendererVBOGeometryData *gd = static_cast<QSGRendererVBOGeometryData *>(QSGGeometryData::data(g)); - if (!gd) { - gd = new QSGRendererVBOGeometryData; - QSGGeometryData::install(g, gd); - } - return gd; - } - -}; - -static inline GLenum qt_drawTypeForPattern(QSGGeometry::DataPattern p) -{ - Q_ASSERT(p > 0 && p <= 3); - static GLenum drawTypes[] = { 0, - GL_STREAM_DRAW, - GL_DYNAMIC_DRAW, - GL_STATIC_DRAW - }; - return drawTypes[p]; -} - - -/*! - Issues the GL draw call for the geometry \a g using the material \a shader. - - The function assumes that attributes have been bound and set up prior - to making this call. - - \internal - */ - -void QSGRenderer::draw(const QSGMaterialShader *shader, const QSGGeometry *g) -{ - // ### remove before final release... - static bool use_vbo = !QGuiApplication::arguments().contains(QLatin1String("--no-vbo")); - - const void *vertexData; - int vertexByteSize = g->vertexCount() * g->sizeOfVertex(); - if (use_vbo && g->vertexDataPattern() != QSGGeometry::AlwaysUploadPattern && vertexByteSize > 1024) { - - // The base pointer for a VBO is 0 - vertexData = 0; - - bool updateData = QSGGeometryData::hasDirtyVertexData(g); - QSGRendererVBOGeometryData *gd = QSGRendererVBOGeometryData::get(g); - if (!gd->vertexBuffer) { - glGenBuffers(1, &gd->vertexBuffer); - updateData = true; - } - - glBindBuffer(GL_ARRAY_BUFFER, gd->vertexBuffer); - m_vertex_buffer_bound = true; - - if (updateData) { - glBufferData(GL_ARRAY_BUFFER, vertexByteSize, g->vertexData(), - qt_drawTypeForPattern(g->vertexDataPattern())); - QSGGeometryData::clearDirtyVertexData(g); - } - - } else { - if (m_vertex_buffer_bound) { - glBindBuffer(GL_ARRAY_BUFFER, 0); - m_vertex_buffer_bound = false; - } - vertexData = g->vertexData(); - } - - // Bind the vertices to attributes... - char const *const *attrNames = shader->attributeNames(); - int offset = 0; - for (int j = 0; attrNames[j]; ++j) { - if (!*attrNames[j]) - continue; - Q_ASSERT_X(j < g->attributeCount(), "QSGRenderer::bindGeometry()", "Geometry lacks attribute required by material"); - const QSGGeometry::Attribute &a = g->attributes()[j]; - Q_ASSERT_X(j == a.position, "QSGRenderer::bindGeometry()", "Geometry does not have continuous attribute positions"); - -#if defined(QT_OPENGL_ES_2) - GLboolean normalize = a.type != GL_FLOAT; -#else - GLboolean normalize = a.type != GL_FLOAT && a.type != GL_DOUBLE; -#endif - glVertexAttribPointer(a.position, a.tupleSize, a.type, normalize, g->sizeOfVertex(), (char *) vertexData + offset); - offset += a.tupleSize * size_of_type(a.type); - } - - // Set up the indices... - const void *indexData; - if (use_vbo && g->indexDataPattern() != QSGGeometry::AlwaysUploadPattern && g->indexCount() > 512) { - - // Base pointer for a VBO is 0 - indexData = 0; - - bool updateData = QSGGeometryData::hasDirtyIndexData(g); - QSGRendererVBOGeometryData *gd = QSGRendererVBOGeometryData::get(g); - if (!gd->indexBuffer) { - glGenBuffers(1, &gd->indexBuffer); - updateData = true; - } - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gd->indexBuffer); - m_index_buffer_bound = true; - - if (updateData) { - glBufferData(GL_ELEMENT_ARRAY_BUFFER, - g->indexCount() * g->sizeOfIndex(), - g->indexData(), - qt_drawTypeForPattern(g->indexDataPattern())); - QSGGeometryData::clearDirtyIndexData(g); - } - - } else { - if (m_index_buffer_bound) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - m_index_buffer_bound = false; - } - indexData = g->indexData(); - } - - - // draw the stuff... - if (g->indexCount()) { - glDrawElements(g->drawingMode(), g->indexCount(), g->indexType(), indexData); - } else { - glDrawArrays(g->drawingMode(), 0, g->vertexCount()); - } - - // We leave buffers bound for now... They will be reset by bind on next draw() or - // set back to 0 if next draw is not using VBOs - -} - -/*! - \class QSGNodeDumper - \brief The QSGNodeDumper class provides a way of dumping a scene grahp to the console. - - This class is solely for debugging purposes. - - \internal - */ - -void QSGNodeDumper::dump(QSGNode *n) -{ - QSGNodeDumper dump; - dump.visitNode(n); -} - -void QSGNodeDumper::visitNode(QSGNode *n) -{ - qDebug() << QString(m_indent * 2, QLatin1Char(' ')) << n; - QSGNodeVisitor::visitNode(n); -} - -void QSGNodeDumper::visitChildren(QSGNode *n) -{ - ++m_indent; - QSGNodeVisitor::visitChildren(n); - --m_indent; -} - - -QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/coreapi/qsgrenderer_p.h b/src/declarative/scenegraph/coreapi/qsgrenderer_p.h deleted file mode 100644 index 05fb9b42fd..0000000000 --- a/src/declarative/scenegraph/coreapi/qsgrenderer_p.h +++ /dev/null @@ -1,234 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef RENDERER_H -#define RENDERER_H - -#include <qset.h> -#include <qhash.h> - -#include <qcolor.h> -#include <qopenglfunctions.h> -#include <qopenglshaderprogram.h> - -#include "qsgnode.h" -#include "qsgmaterial.h" -#include "qsgtexture.h" - -#include <private/qsgcontext_p.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class QSGMaterialShader; -struct QSGMaterialType; -class QOpenGLFramebufferObject; -class TextureReference; -class QSGBindable; -class QSGNodeUpdater; - -class Q_DECLARATIVE_EXPORT QSGRenderer : public QObject, public QOpenGLFunctions -{ - Q_OBJECT -public: - enum ClipType - { - NoClip, - ScissorClip, - StencilClip - }; - - enum ClearModeBit - { - ClearColorBuffer = 0x0001, - ClearDepthBuffer = 0x0002, - ClearStencilBuffer = 0x0004 - }; - Q_DECLARE_FLAGS(ClearMode, ClearModeBit) - - QSGRenderer(QSGContext *context); - virtual ~QSGRenderer(); - - void setRootNode(QSGRootNode *node); - QSGRootNode *rootNode() const { return m_root_node; } - - void setDeviceRect(const QRect &rect) { m_device_rect = rect; } - inline void setDeviceRect(const QSize &size) { setDeviceRect(QRect(QPoint(), size)); } - QRect deviceRect() const { return m_device_rect; } - - void setViewportRect(const QRect &rect) { m_viewport_rect = rect; } - inline void setViewportRect(const QSize &size) { setViewportRect(QRect(QPoint(), size)); } - QRect viewportRect() const { return m_viewport_rect; } - - // Accessed by QSGMaterialShader::RenderState. - QMatrix4x4 currentProjectionMatrix() const { return m_current_projection_matrix; } - QMatrix4x4 currentModelViewMatrix() const { return m_current_model_view_matrix; } - QMatrix4x4 currentCombinedMatrix() const { return m_current_projection_matrix * m_current_model_view_matrix; } - qreal currentOpacity() const { return m_current_opacity; } - - void setProjectionMatrixToDeviceRect(); - void setProjectionMatrixToRect(const QRectF &rect); - void setProjectionMatrix(const QMatrix4x4 &matrix); - QMatrix4x4 projectionMatrix() const { return m_projection_matrix; } - bool isMirrored() const { return m_mirrored; } - - void setClearColor(const QColor &color); - QColor clearColor() const { return m_clear_color; } - - QOpenGLContext *glContext() const { Q_ASSERT(m_context); return m_context->glContext(); } - - QSGContext *context(); - - void renderScene(); - void renderScene(const QSGBindable &bindable); - virtual void nodeChanged(QSGNode *node, QSGNode::DirtyFlags flags); - virtual void materialChanged(QSGGeometryNode *node, QSGMaterial *from, QSGMaterial *to); - - QSGNodeUpdater *nodeUpdater() const; - void setNodeUpdater(QSGNodeUpdater *updater); - - inline QSGMaterialShader::RenderState state(QSGMaterialShader::RenderState::DirtyStates dirty) const; - - void setClearMode(ClearMode mode) { m_clear_mode = mode; } - ClearMode clearMode() const { return m_clear_mode; } - -signals: - void sceneGraphChanged(); // Add, remove, ChangeFlags changes... - -protected: - void draw(const QSGMaterialShader *material, const QSGGeometry *g); - - virtual void render() = 0; - QSGRenderer::ClipType updateStencilClip(const QSGClipNode *clip); - - const QSGBindable *bindable() const { return m_bindable; } - - virtual void preprocess(); - - void addNodesToPreprocess(QSGNode *node); - void removeNodesToPreprocess(QSGNode *node); - - - QColor m_clear_color; - ClearMode m_clear_mode; - QMatrix4x4 m_current_projection_matrix; - QMatrix4x4 m_current_model_view_matrix; - qreal m_current_opacity; - - QSGContext *m_context; - -private: - QSGRootNode *m_root_node; - QSGNodeUpdater *m_node_updater; - - QRect m_device_rect; - QRect m_viewport_rect; - - QSet<QSGNode *> m_nodes_to_preprocess; - - QMatrix4x4 m_projection_matrix; - QOpenGLShaderProgram m_clip_program; - int m_clip_matrix_id; - - const QSGBindable *m_bindable; - - uint m_changed_emitted : 1; - uint m_mirrored : 1; - uint m_is_rendering : 1; - - uint m_vertex_buffer_bound : 1; - uint m_index_buffer_bound : 1; -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(QSGRenderer::ClearMode) - -class Q_DECLARATIVE_EXPORT QSGBindable -{ -public: - virtual ~QSGBindable() { } - virtual void bind() const = 0; - virtual void clear(QSGRenderer::ClearMode mode) const; - virtual void reactivate() const; -}; - -class QSGBindableFbo : public QSGBindable -{ -public: - QSGBindableFbo(QOpenGLFramebufferObject *fbo); - virtual void bind() const; -private: - QOpenGLFramebufferObject *m_fbo; -}; - - - -QSGMaterialShader::RenderState QSGRenderer::state(QSGMaterialShader::RenderState::DirtyStates dirty) const -{ - QSGMaterialShader::RenderState s; - s.m_dirty = dirty; - s.m_data = this; - return s; -} - - -class Q_DECLARATIVE_EXPORT QSGNodeDumper : public QSGNodeVisitor { - -public: - static void dump(QSGNode *n); - - QSGNodeDumper() : m_indent(0) {} - void visitNode(QSGNode *n); - void visitChildren(QSGNode *n); - -private: - int m_indent; -}; - - - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // RENDERER_H |