diff options
Diffstat (limited to 'src/declarative/scenegraph')
63 files changed, 0 insertions, 16705 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 diff --git a/src/declarative/scenegraph/qsgadaptationlayer.cpp b/src/declarative/scenegraph/qsgadaptationlayer.cpp deleted file mode 100644 index 966a24acd3..0000000000 --- a/src/declarative/scenegraph/qsgadaptationlayer.cpp +++ /dev/null @@ -1,315 +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 "qsgadaptationlayer_p.h" - -#include <qmath.h> -#include <private/qsgdistancefieldutil_p.h> -#include <private/qsgdistancefieldglyphnode_p.h> -#include <private/qrawfont_p.h> -#include <QtGui/qguiapplication.h> -#include <qdir.h> - -QT_BEGIN_NAMESPACE - - -QHash<QString, QOpenGLMultiGroupSharedResource> QSGDistanceFieldGlyphCache::m_caches_data; - -QSGDistanceFieldGlyphCache::QSGDistanceFieldGlyphCache(QSGDistanceFieldGlyphCacheManager *man, QOpenGLContext *c, const QRawFont &font) - : ctx(c) - , m_manager(man) -{ - Q_ASSERT(font.isValid()); - m_font = font; - - m_cacheData = cacheData(); - - QRawFontPrivate *fontD = QRawFontPrivate::get(m_font); - m_glyphCount = fontD->fontEngine->glyphCount(); - - m_cacheData->doubleGlyphResolution = qt_fontHasNarrowOutlines(font) && m_glyphCount < QT_DISTANCEFIELD_HIGHGLYPHCOUNT; - - m_referenceFont = m_font; - m_referenceFont.setPixelSize(QT_DISTANCEFIELD_BASEFONTSIZE(m_cacheData->doubleGlyphResolution)); - Q_ASSERT(m_referenceFont.isValid()); -} - -QSGDistanceFieldGlyphCache::~QSGDistanceFieldGlyphCache() -{ -} - -QSGDistanceFieldGlyphCache::GlyphCacheData *QSGDistanceFieldGlyphCache::cacheData() -{ - QString key = QString::fromLatin1("%1_%2_%3_%4") - .arg(m_font.familyName()) - .arg(m_font.styleName()) - .arg(m_font.weight()) - .arg(m_font.style()); - return m_caches_data[key].value<QSGDistanceFieldGlyphCache::GlyphCacheData>(ctx); -} - -qreal QSGDistanceFieldGlyphCache::fontScale() const -{ - return qreal(m_font.pixelSize()) / QT_DISTANCEFIELD_BASEFONTSIZE(m_cacheData->doubleGlyphResolution); -} - -int QSGDistanceFieldGlyphCache::distanceFieldRadius() const -{ - return QT_DISTANCEFIELD_DEFAULT_RADIUS / QT_DISTANCEFIELD_SCALE(m_cacheData->doubleGlyphResolution); -} - -QSGDistanceFieldGlyphCache::Metrics QSGDistanceFieldGlyphCache::glyphMetrics(glyph_t glyph) -{ - QHash<glyph_t, Metrics>::iterator metric = m_metrics.find(glyph); - if (metric == m_metrics.end()) { - QPainterPath path = m_font.pathForGlyph(glyph); - QRectF br = path.boundingRect(); - - Metrics m; - m.width = br.width(); - m.height = br.height(); - m.baselineX = br.x(); - m.baselineY = -br.y(); - - metric = m_metrics.insert(glyph, m); - } - - return metric.value(); -} - -QSGDistanceFieldGlyphCache::TexCoord QSGDistanceFieldGlyphCache::glyphTexCoord(glyph_t glyph) const -{ - return m_cacheData->texCoords.value(glyph); -} - -static QSGDistanceFieldGlyphCache::Texture g_emptyTexture; - -const QSGDistanceFieldGlyphCache::Texture *QSGDistanceFieldGlyphCache::glyphTexture(glyph_t glyph) const -{ - QHash<glyph_t, Texture*>::const_iterator it = m_cacheData->glyphTextures.find(glyph); - if (it == m_cacheData->glyphTextures.constEnd()) - return &g_emptyTexture; - return it.value(); -} - -void QSGDistanceFieldGlyphCache::populate(const QVector<glyph_t> &glyphs) -{ - QSet<glyph_t> newGlyphs; - int count = glyphs.count(); - for (int i = 0; i < count; ++i) { - glyph_t glyphIndex = glyphs.at(i); - if ((int) glyphIndex >= glyphCount()) { - qWarning("Warning: distance-field glyph is not available with index %d", glyphIndex); - continue; - } - - if (m_cacheData->texCoords.contains(glyphIndex) || newGlyphs.contains(glyphIndex)) - continue; - - QPainterPath path = m_referenceFont.pathForGlyph(glyphIndex); - m_cacheData->glyphPaths.insert(glyphIndex, path); - if (path.isEmpty()) { - TexCoord c; - c.width = 0; - c.height = 0; - m_cacheData->texCoords.insert(glyphIndex, c); - continue; - } - - newGlyphs.insert(glyphIndex); - } - - if (newGlyphs.isEmpty()) - return; - - QVector<glyph_t> glyphsVec; - QSet<glyph_t>::const_iterator it = newGlyphs.constBegin(); - while (it != newGlyphs.constEnd()) { - glyphsVec.append(*it); - ++it; - } - requestGlyphs(glyphsVec); -} - -void QSGDistanceFieldGlyphCache::release(const QVector<glyph_t> &glyphs) -{ - releaseGlyphs(glyphs); -} - -void QSGDistanceFieldGlyphCache::update() -{ - if (m_cacheData->pendingGlyphs.isEmpty()) - return; - - QHash<glyph_t, QImage> distanceFields; - - // ### Remove before final release - static bool cacheDistanceFields = QGuiApplication::arguments().contains(QLatin1String("--cache-distance-fields")); - - QString tmpPath = QString::fromLatin1("%1/.qt/").arg(QDir::tempPath()); - QString keyBase = QString::fromLatin1("%1%2%3_%4_%5_%6.fontblob") - .arg(tmpPath) - .arg(m_font.familyName()) - .arg(m_font.styleName()) - .arg(m_font.weight()) - .arg(m_font.style()); - - if (cacheDistanceFields && !QFile::exists(tmpPath)) - QDir(tmpPath).mkpath(tmpPath); - - for (int i = 0; i < m_cacheData->pendingGlyphs.size(); ++i) { - glyph_t glyphIndex = m_cacheData->pendingGlyphs.at(i); - - if (cacheDistanceFields) { - QString key = keyBase.arg(glyphIndex); - QFile file(key); - if (file.open(QFile::ReadOnly)) { - int fileSize = file.size(); - int dim = sqrt(float(fileSize)); - QByteArray blob = file.readAll(); - QImage df(dim, dim, QImage::Format_Indexed8); - memcpy(df.bits(), blob.constData(), fileSize); - distanceFields.insert(glyphIndex, df); - continue; - } - } - - QImage distanceField = qt_renderDistanceFieldGlyph(m_font, glyphIndex, m_cacheData->doubleGlyphResolution); - distanceFields.insert(glyphIndex, distanceField); - - if (cacheDistanceFields) { - QString key = keyBase.arg(glyphIndex); - QFile file(key); - file.open(QFile::WriteOnly); - file.write((const char *) distanceField.constBits(), distanceField.width() * distanceField.height()); - } - } - - m_cacheData->pendingGlyphs.reset(); - - storeGlyphs(distanceFields); -} - -void QSGDistanceFieldGlyphCache::addGlyphPositions(const QList<GlyphPosition> &glyphs) -{ - int count = glyphs.count(); - for (int i = 0; i < count; ++i) { - GlyphPosition glyph = glyphs.at(i); - - QPainterPath path = m_cacheData->glyphPaths.value(glyph.glyph); - QRectF br = path.boundingRect(); - TexCoord c; - c.xMargin = QT_DISTANCEFIELD_RADIUS(m_cacheData->doubleGlyphResolution) / qreal(QT_DISTANCEFIELD_SCALE(m_cacheData->doubleGlyphResolution)); - c.yMargin = QT_DISTANCEFIELD_RADIUS(m_cacheData->doubleGlyphResolution) / qreal(QT_DISTANCEFIELD_SCALE(m_cacheData->doubleGlyphResolution)); - c.x = glyph.position.x(); - c.y = glyph.position.y(); - c.width = br.width(); - c.height = br.height(); - - m_cacheData->texCoords.insert(glyph.glyph, c); - } -} - -void QSGDistanceFieldGlyphCache::addGlyphTextures(const QVector<glyph_t> &glyphs, const Texture &tex) -{ - int i = m_cacheData->textures.indexOf(tex); - if (i == -1) { - m_cacheData->textures.append(tex); - i = m_cacheData->textures.size() - 1; - } else { - m_cacheData->textures[i].size = tex.size; - } - Texture *texture = &(m_cacheData->textures[i]); - - int count = glyphs.count(); - for (int j = 0; j < count; ++j) - m_cacheData->glyphTextures.insert(glyphs.at(j), texture); - - QLinkedList<QSGDistanceFieldGlyphNode *>::iterator it = m_cacheData->m_registeredNodes.begin(); - while (it != m_cacheData->m_registeredNodes.end()) { - (*it)->updateGeometry(); - ++it; - } -} - -void QSGDistanceFieldGlyphCache::markGlyphsToRender(const QVector<glyph_t> &glyphs) -{ - int count = glyphs.count(); - for (int i = 0; i < count; ++i) - m_cacheData->pendingGlyphs.add(glyphs.at(i)); -} - -void QSGDistanceFieldGlyphCache::removeGlyph(glyph_t glyph) -{ - m_cacheData->texCoords.remove(glyph); - m_cacheData->glyphTextures.remove(glyph); -} - -void QSGDistanceFieldGlyphCache::updateTexture(GLuint oldTex, GLuint newTex, const QSize &newTexSize) -{ - int count = m_cacheData->textures.count(); - for (int i = 0; i < count; ++i) { - Texture &tex = m_cacheData->textures[i]; - if (tex.textureId == oldTex) { - tex.textureId = newTex; - tex.size = newTexSize; - return; - } - } -} - -bool QSGDistanceFieldGlyphCache::containsGlyph(glyph_t glyph) const -{ - return m_cacheData->texCoords.contains(glyph); -} - -void QSGDistanceFieldGlyphCache::registerGlyphNode(QSGDistanceFieldGlyphNode *node) -{ - m_cacheData->m_registeredNodes.append(node); -} - -void QSGDistanceFieldGlyphCache::unregisterGlyphNode(QSGDistanceFieldGlyphNode *node) -{ - m_cacheData->m_registeredNodes.removeOne(node); -} - - -QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/qsgadaptationlayer_p.h b/src/declarative/scenegraph/qsgadaptationlayer_p.h deleted file mode 100644 index 82e0c7cf42..0000000000 --- a/src/declarative/scenegraph/qsgadaptationlayer_p.h +++ /dev/null @@ -1,257 +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 ADAPTATIONINTERFACES_H -#define ADAPTATIONINTERFACES_H - -#include "qsgnode.h" -#include "qsgtexture.h" -#include <QtCore/qobject.h> -#include <QtCore/qrect.h> -#include <QtGui/qbrush.h> -#include <QtGui/qcolor.h> -#include <QtCore/qsharedpointer.h> -#include <QtGui/qglyphrun.h> -#include <QtCore/qurl.h> -#include <private/qfontengine_p.h> -#include <QtGui/private/qdatabuffer_p.h> -#include <private/qopenglcontext_p.h> - -// ### remove -#include <private/qquicktext_p.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class QSGNode; -class QImage; -class TextureReference; -class QSGDistanceFieldGlyphCacheManager; -class QSGDistanceFieldGlyphNode; - -// TODO: Rename from XInterface to AbstractX. -class Q_DECLARATIVE_EXPORT QSGRectangleNode : public QSGGeometryNode -{ -public: - virtual void setRect(const QRectF &rect) = 0; - virtual void setColor(const QColor &color) = 0; - virtual void setPenColor(const QColor &color) = 0; - virtual void setPenWidth(qreal width) = 0; - virtual void setGradientStops(const QGradientStops &stops) = 0; - virtual void setRadius(qreal radius) = 0; - virtual void setAligned(bool aligned) = 0; - - virtual void update() = 0; -}; - - -class Q_DECLARATIVE_EXPORT QSGImageNode : public QSGGeometryNode -{ -public: - virtual void setTargetRect(const QRectF &rect) = 0; - virtual void setSourceRect(const QRectF &rect) = 0; - virtual void setTexture(QSGTexture *texture) = 0; - - virtual void setMipmapFiltering(QSGTexture::Filtering filtering) = 0; - virtual void setFiltering(QSGTexture::Filtering filtering) = 0; - virtual void setHorizontalWrapMode(QSGTexture::WrapMode wrapMode) = 0; - virtual void setVerticalWrapMode(QSGTexture::WrapMode wrapMode) = 0; - - virtual void update() = 0; -}; - - -class Q_DECLARATIVE_EXPORT QSGGlyphNode : public QSGGeometryNode -{ -public: - enum AntialiasingMode - { - GrayAntialiasing, - LowQualitySubPixelAntialiasing, - HighQualitySubPixelAntialiasing - }; - - virtual void setGlyphs(const QPointF &position, const QGlyphRun &glyphs) = 0; - virtual void setColor(const QColor &color) = 0; - virtual void setStyle(QQuickText::TextStyle style) = 0; - virtual void setStyleColor(const QColor &color) = 0; - virtual QPointF baseLine() const = 0; - - virtual QRectF boundingRect() const { return m_bounding_rect; } - virtual void setBoundingRect(const QRectF &bounds) { m_bounding_rect = bounds; } - - virtual void setPreferredAntialiasingMode(AntialiasingMode) = 0; - - virtual void update() = 0; - -protected: - QRectF m_bounding_rect; -}; - -class Q_DECLARATIVE_EXPORT QSGDistanceFieldGlyphCache -{ -public: - QSGDistanceFieldGlyphCache(QSGDistanceFieldGlyphCacheManager *man, QOpenGLContext *c, const QRawFont &font); - virtual ~QSGDistanceFieldGlyphCache(); - - struct Metrics { - qreal width; - qreal height; - qreal baselineX; - qreal baselineY; - - bool isNull() const { return width == 0 || height == 0; } - }; - - struct TexCoord { - qreal x; - qreal y; - qreal width; - qreal height; - qreal xMargin; - qreal yMargin; - - TexCoord() : x(0), y(0), width(-1), height(-1), xMargin(0), yMargin(0) { } - - bool isNull() const { return width <= 0 || height <= 0; } - bool isValid() const { return width >= 0 && height >= 0; } - }; - - struct Texture { - GLuint textureId; - QSize size; - - Texture() : textureId(0), size(QSize()) { } - bool operator == (const Texture &other) const { return textureId == other.textureId; } - }; - - const QSGDistanceFieldGlyphCacheManager *manager() const { return m_manager; } - - const QRawFont &font() const { return m_font; } - - qreal fontScale() const; - int distanceFieldRadius() const; - int glyphCount() const { return m_glyphCount; } - bool doubleGlyphResolution() const { return m_cacheData->doubleGlyphResolution; } - - Metrics glyphMetrics(glyph_t glyph); - TexCoord glyphTexCoord(glyph_t glyph) const; - const Texture *glyphTexture(glyph_t glyph) const; - - void populate(const QVector<glyph_t> &glyphs); - void release(const QVector<glyph_t> &glyphs); - - void update(); - - void registerGlyphNode(QSGDistanceFieldGlyphNode *node); - void unregisterGlyphNode(QSGDistanceFieldGlyphNode *node); - -protected: - struct GlyphPosition { - glyph_t glyph; - QPointF position; - }; - - virtual void requestGlyphs(const QVector<glyph_t> &glyphs) = 0; - virtual void storeGlyphs(const QHash<glyph_t, QImage> &glyphs) = 0; - virtual void releaseGlyphs(const QVector<glyph_t> &glyphs) = 0; - - void addGlyphPositions(const QList<GlyphPosition> &glyphs); - void addGlyphTextures(const QVector<glyph_t> &glyphs, const Texture &tex); - void markGlyphsToRender(const QVector<glyph_t> &glyphs); - void removeGlyph(glyph_t glyph); - - void updateTexture(GLuint oldTex, GLuint newTex, const QSize &newTexSize); - - bool containsGlyph(glyph_t glyph) const; - - QOpenGLContext *ctx; - -private: - struct GlyphCacheData : public QOpenGLSharedResource { - QList<Texture> textures; - QHash<glyph_t, Texture*> glyphTextures; - QHash<glyph_t, TexCoord> texCoords; - QDataBuffer<glyph_t> pendingGlyphs; - QHash<glyph_t, QPainterPath> glyphPaths; - bool doubleGlyphResolution; - QLinkedList<QSGDistanceFieldGlyphNode*> m_registeredNodes; - - GlyphCacheData(QOpenGLContext *ctx) - : QOpenGLSharedResource(ctx->shareGroup()) - , pendingGlyphs(64) - , doubleGlyphResolution(false) - {} - - void invalidateResource() - { - textures.clear(); - glyphTextures.clear(); - texCoords.clear(); - } - - void freeResource(QOpenGLContext *) - { - } - }; - - QSGDistanceFieldGlyphCacheManager *m_manager; - - QRawFont m_font; - QRawFont m_referenceFont; - - int m_glyphCount; - QHash<glyph_t, Metrics> m_metrics; - - GlyphCacheData *cacheData(); - GlyphCacheData *m_cacheData; - static QHash<QString, QOpenGLMultiGroupSharedResource> m_caches_data; -}; - - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/declarative/scenegraph/qsgcontext.cpp b/src/declarative/scenegraph/qsgcontext.cpp deleted file mode 100644 index 1545303d4a..0000000000 --- a/src/declarative/scenegraph/qsgcontext.cpp +++ /dev/null @@ -1,512 +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 <private/qsgcontext_p.h> -#include <private/qsgrenderer_p.h> -#include "qsgnode.h" - -#include <private/qdeclarativepixmapcache_p.h> - -#include <private/qsgdefaultrenderer_p.h> - -#include <private/qsgdistancefieldutil_p.h> -#include <private/qsgdefaultdistancefieldglyphcache_p.h> -#include <private/qsgdefaultrectanglenode_p.h> -#include <private/qsgdefaultimagenode_p.h> -#include <private/qsgdefaultglyphnode_p.h> -#include <private/qsgdistancefieldglyphnode_p.h> - -#include <private/qsgtexture_p.h> -#include <QGuiApplication> -#include <QOpenGLContext> - -#include <QDeclarativeImageProvider> - -#include <private/qobject_p.h> -#include <qmutex.h> - -DEFINE_BOOL_CONFIG_OPTION(qmlFlashMode, QML_FLASH_MODE) -DEFINE_BOOL_CONFIG_OPTION(qmlTranslucentMode, QML_TRANSLUCENT_MODE) -DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD) - -/* - Comments about this class from Gunnar: - - The QSGContext class is right now two things.. The first is the - adaptation layer and central storage ground for all the things - in the scene graph, like textures and materials. This part really - belongs inside the scene graph coreapi. - - The other part is the QML adaptation classes, like how to implement - rectangle nodes. This is not part of the scene graph core API, but - more part of the QML adaptation of scene graph. - - If we ever move the scene graph core API into its own thing, this class - needs to be split in two. Right now its one because we're lazy when it comes - to defining plugin interfaces.. -*/ - - -QT_BEGIN_NAMESPACE - -class QSGContextPrivate : public QObjectPrivate -{ -public: - QSGContextPrivate() - : rootNode(0) - , renderer(0) - , gl(0) - , distanceFieldCacheManager(0) - , flashMode(qmlFlashMode()) - , distanceFieldDisabled(qmlDisableDistanceField()) - { - renderAlpha = qmlTranslucentMode() ? 0.5 : 1; - } - - ~QSGContextPrivate() - { - } - - QSGRootNode *rootNode; - QSGRenderer *renderer; - - QOpenGLContext *gl; - - QHash<QSGMaterialType *, QSGMaterialShader *> materials; - QHash<QDeclarativeTextureFactory *, QSGTexture *> textures; - - QSGDistanceFieldGlyphCacheManager *distanceFieldCacheManager; - - bool flashMode; - float renderAlpha; - bool distanceFieldDisabled; -}; - - -/*! - \class QSGContext - - \brief The QSGContext holds the scene graph entry points for one QML engine. - - The context is not ready for use until it has a QOpenGLContext. Once that happens, - the scene graph population can start. - - \internal - */ - -QSGContext::QSGContext(QObject *parent) : - QObject(*(new QSGContextPrivate), parent) -{ -} - - -QSGContext::~QSGContext() -{ - Q_D(QSGContext); - qDeleteAll(d->textures.values()); - d->textures.clear(); - delete d->renderer; - delete d->rootNode; - qDeleteAll(d->materials.values()); - delete d->distanceFieldCacheManager; -} - - -QSGTexture *QSGContext::textureForFactory(QDeclarativeTextureFactory *factory) -{ - Q_D(QSGContext); - if (!factory) - return 0; - - QSGTexture *texture = d->textures.value(factory); - if (!texture) { - if (QDeclarativeDefaultTextureFactory *dtf = qobject_cast<QDeclarativeDefaultTextureFactory *>(factory)) - texture = createTexture(dtf->image()); - else - texture = factory->createTexture(); - d->textures.insert(factory, texture); - connect(factory, SIGNAL(destroyed(QObject *)), this, SLOT(textureFactoryDestroyed(QObject *))); - } - return texture; -} - - -void QSGContext::textureFactoryDestroyed(QObject *o) -{ - Q_D(QSGContext); - QDeclarativeTextureFactory *f = static_cast<QDeclarativeTextureFactory *>(o); - - // This function will only be called on the scene graph thread, so it is - // safe to directly delete the texture here. - delete d->textures.take(f); -} - - - -/*! - Returns the renderer. The renderer instance is created through the adaptation layer. - */ -QSGRenderer *QSGContext::renderer() const -{ - Q_D(const QSGContext); - return d->renderer; -} - - -/*! - Returns the root node. The root node instance is only created once the scene graph - context becomes ready. - */ -QSGRootNode *QSGContext::rootNode() const -{ - Q_D(const QSGContext); - return d->rootNode; -} - - -QOpenGLContext *QSGContext::glContext() const -{ - Q_D(const QSGContext); - return d->gl; -} - -/*! - Initializes the scene graph context with the GL context \a context. This also - emits the ready() signal so that the QML graph can start building scene graph nodes. - */ -void QSGContext::initialize(QOpenGLContext *context) -{ - Q_D(QSGContext); - - Q_ASSERT(!d->gl); - - d->gl = context; - - d->renderer = createRenderer(); - d->renderer->setClearColor(Qt::white); - - d->rootNode = new QSGRootNode(); - d->renderer->setRootNode(d->rootNode); - - emit ready(); -} - - -/*! - Returns if the scene graph context is ready or not, meaning that it has a valid - GL context. - */ -bool QSGContext::isReady() const -{ - Q_D(const QSGContext); - return d->gl; -} - - -void QSGContext::renderNextFrame(QOpenGLFramebufferObject *fbo) -{ - Q_D(QSGContext); - - if (fbo) { - QSGBindableFbo bindable(fbo); - d->renderer->renderScene(bindable); - } else { - d->renderer->renderScene(); - } - -} - -/*! - Factory function for scene graph backends of the Rectangle element. - */ -QSGRectangleNode *QSGContext::createRectangleNode() -{ - return new QSGDefaultRectangleNode(this); -} - -/*! - Factory function for scene graph backends of the Image element. - */ -QSGImageNode *QSGContext::createImageNode() -{ - return new QSGDefaultImageNode; -} - -/*! - Factory function for scene graph backends of the distance-field glyph cache. - */ -QSGDistanceFieldGlyphCache *QSGContext::createDistanceFieldGlyphCache(const QRawFont &font) -{ - Q_D(QSGContext); - return new QSGDefaultDistanceFieldGlyphCache(d->distanceFieldCacheManager, glContext(), font); -} - -/*! - Factory function for scene graph backends of the Text elements; - */ -QSGGlyphNode *QSGContext::createGlyphNode() -{ - Q_D(QSGContext); - - // ### Do something with these before final release... - static bool doSubpixel = qApp->arguments().contains(QLatin1String("--text-subpixel-antialiasing")); - static bool doLowQualSubpixel = qApp->arguments().contains(QLatin1String("--text-subpixel-antialiasing-lowq")); - static bool doGray = qApp->arguments().contains(QLatin1String("--text-gray-antialiasing")); - - if (d->distanceFieldDisabled) { - return new QSGDefaultGlyphNode; - } else { - if (!d->distanceFieldCacheManager) { - d->distanceFieldCacheManager = new QSGDistanceFieldGlyphCacheManager(this); - if (doSubpixel) - d->distanceFieldCacheManager->setDefaultAntialiasingMode(QSGGlyphNode::HighQualitySubPixelAntialiasing); - else if (doLowQualSubpixel) - d->distanceFieldCacheManager->setDefaultAntialiasingMode(QSGGlyphNode::LowQualitySubPixelAntialiasing); - else if (doGray) - d->distanceFieldCacheManager->setDefaultAntialiasingMode(QSGGlyphNode::GrayAntialiasing); - } - - QSGGlyphNode *node = new QSGDistanceFieldGlyphNode(d->distanceFieldCacheManager); - return node; - } -} - -/*! - Factory function for the scene graph renderers. - - The renderers are used for the toplevel renderer and once for every - QQuickShaderEffectSource used in the QML scene. - */ -QSGRenderer *QSGContext::createRenderer() -{ - // ### Do something with this before release... - static bool doFrontToBack = qApp->arguments().contains(QLatin1String("--opaque-front-to-back")); - QSGDefaultRenderer *renderer = new QSGDefaultRenderer(this); - if (doFrontToBack) { - printf("QSGContext: Sorting opaque nodes front to back...\n"); - renderer->setSortFrontToBackEnabled(true); - } - return renderer; -} - - - -/*! - Return true if the image provider supports direct decoding of images, - straight into textures without going through a QImage first. - - If the implementation returns true from this function, the decodeImageToTexture() function - will be called to read data from a QIODevice, rather than QML decoding - the image using QImageReader and passing the result to setImage(). - - \warning This function will be called from outside the GUI and rendering threads - and must not make use of OpenGL. - */ - -bool QSGContext::canDecodeImageToTexture() const -{ - return true; -} - - - -/*! - Decode the data in \a dev directly to a texture provider of \a requestSize size. - The size of the decoded data should be written to \a impsize. - - If the implementation fails to decode the image data, it should return 0. The - image data will then be decoded normally. - - \warning This function will be called from outside the GUI and renderer threads - and must not make use of GL calls. - */ - -QSGTexture *QSGContext::decodeImageToTexture(QIODevice *dev, - QSize *size, - const QSize &requestSize) -{ - Q_UNUSED(dev); - Q_UNUSED(size); - Q_UNUSED(requestSize); - return 0; -} - - - -QSurfaceFormat QSGContext::defaultSurfaceFormat() const -{ - QSurfaceFormat format; - format.setDepthBufferSize(24); - format.setStencilBufferSize(8); - format.setSamples(16); - return format; -} - - -/*! - Factory function for texture objects. - - If \a image is a valid image, the QSGTexture::setImage function - will be called with \a image as argument. - */ - -QSGTexture *QSGContext::createTexture(const QImage &image) const -{ - QSGPlainTexture *t = new QSGPlainTexture(); - if (!image.isNull()) - t->setImage(image); - return t; -} - - - -/*! - Returns the minimum supported framebuffer object size. - */ - -QSize QSGContext::minimumFBOSize() const -{ -#ifdef Q_OS_MAC - return QSize(33, 33); -#else - return QSize(1, 1); -#endif -} - - - -/*! - Returns a material shader for the given material. - */ - -QSGMaterialShader *QSGContext::prepareMaterial(QSGMaterial *material) -{ - Q_D(QSGContext); - QSGMaterialType *type = material->type(); - QSGMaterialShader *shader = d->materials.value(type); - if (shader) - return shader; - - shader = material->createShader(); - shader->compile(); - shader->initialize(); - d->materials[type] = shader; - - return shader; -} - - - -/*! - Sets whether the scene graph should render with flashing update rectangles or not - */ - -void QSGContext::setFlashModeEnabled(bool enabled) -{ - d_func()->flashMode = enabled; -} - - -/*! - Returns true if the scene graph should be rendered with flashing update rectangles - */ -bool QSGContext::isFlashModeEnabled() const -{ - return d_func()->flashMode; -} - - -/*! - Sets the toplevel opacity for rendering. This value will be multiplied into all - drawing calls where possible. - - The default value is 1. Any other value will cause artifacts and is primarily - useful for debugging. - */ -void QSGContext::setRenderAlpha(qreal renderAlpha) -{ - d_func()->renderAlpha = renderAlpha; -} - - -/*! - Returns the toplevel opacity used for rendering. - - The default value is 1. - - \sa setRenderAlpha() - */ -qreal QSGContext::renderAlpha() const -{ - return d_func()->renderAlpha; -} - - -/*! - Sets whether or not the scene graph should use the distance field technique to render text - */ -void QSGContext::setDistanceFieldEnabled(bool enabled) -{ - d_func()->distanceFieldDisabled = !enabled; -} - - -/*! - Returns true if the scene graph uses the distance field technique to render text - */ -bool QSGContext::isDistanceFieldEnabled() const -{ - return !d_func()->distanceFieldDisabled; -} - - - -/*! - Creates a new animation driver. - */ - -QAnimationDriver *QSGContext::createAnimationDriver(QObject *parent) -{ - return new QAnimationDriver(parent); -} - - -QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/qsgcontext_p.h b/src/declarative/scenegraph/qsgcontext_p.h deleted file mode 100644 index ed1654b8fc..0000000000 --- a/src/declarative/scenegraph/qsgcontext_p.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 QSGCONTEXT_H -#define QSGCONTEXT_H - -#include <QtCore/QObject> -#include <QtCore/qabstractanimation.h> - -#include <QtGui/QImage> -#include <QtGui/QSurfaceFormat> - -#include <private/qrawfont_p.h> - -#include "qsgnode.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class QSGContextPrivate; -class QSGRectangleNode; -class QSGImageNode; -class QSGGlyphNode; -class QSGRenderer; -class QSGDistanceFieldGlyphCache; - -class QSGTexture; -class QSGMaterial; -class QSGMaterialShader; -class QSGEngine; - -class QOpenGLContext; -class QOpenGLFramebufferObject; - -class QDeclarativeTextureFactory; - -class Q_DECLARATIVE_EXPORT QSGContext : public QObject -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QSGContext) - -public: - explicit QSGContext(QObject *parent = 0); - ~QSGContext(); - - virtual void initialize(QOpenGLContext *context); - - QSGRenderer *renderer() const; - - void setRootNode(QSGRootNode *node); - QSGRootNode *rootNode() const; - - QOpenGLContext *glContext() const; - - bool isReady() const; - - QSGMaterialShader *prepareMaterial(QSGMaterial *material); - - virtual void renderNextFrame(QOpenGLFramebufferObject *fbo = 0); - - virtual QSGDistanceFieldGlyphCache *createDistanceFieldGlyphCache(const QRawFont &font); - - virtual QSGRectangleNode *createRectangleNode(); - virtual QSGImageNode *createImageNode(); - virtual QSGGlyphNode *createGlyphNode(); - virtual QSGRenderer *createRenderer(); - - virtual bool canDecodeImageToTexture() const; - virtual QSGTexture *decodeImageToTexture(QIODevice *dev, - QSize *size, - const QSize &requestSize); - virtual QSGTexture *createTexture(const QImage &image = QImage()) const; - virtual QSize minimumFBOSize() const; - - virtual QSurfaceFormat defaultSurfaceFormat() const; - - QSGTexture *textureForFactory(QDeclarativeTextureFactory *factory); - - static QSGContext *createDefaultContext(); - - void setFlashModeEnabled(bool enabled); - bool isFlashModeEnabled() const; - - void setRenderAlpha(qreal renderAlpha); - qreal renderAlpha() const; - - void setDistanceFieldEnabled(bool enabled); - bool isDistanceFieldEnabled() const; - - virtual QAnimationDriver *createAnimationDriver(QObject *parent); - -signals: - void ready(); - -public slots: - void textureFactoryDestroyed(QObject *o); -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QSGCONTEXT_H diff --git a/src/declarative/scenegraph/qsgcontextplugin.cpp b/src/declarative/scenegraph/qsgcontextplugin.cpp deleted file mode 100644 index 79bcbf9c04..0000000000 --- a/src/declarative/scenegraph/qsgcontextplugin.cpp +++ /dev/null @@ -1,104 +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 "qsgcontextplugin_p.h" -#include <private/qsgcontext_p.h> -#include <QtGui/qguiapplication.h> -#include <QtCore/private/qfactoryloader_p.h> -#include <QtCore/qlibraryinfo.h> - -QT_BEGIN_NAMESPACE - -QSGContextPlugin::QSGContextPlugin(QObject *parent) - : QObject(parent) -{ -} - -QSGContextPlugin::~QSGContextPlugin() -{ -} - -#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) -Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, - (QSGContextFactoryInterface_iid, QLatin1String("/scenegraph"))) -#endif - -/*! - \fn QSGContext *QSGContext::createDefaultContext() - - Creates a default scene graph context for the current hardware. - This may load a device-specific plugin. -*/ -QSGContext *QSGContext::createDefaultContext() -{ - const QStringList args = QGuiApplication::arguments(); - QString device; - for (int index = 0; index < args.count(); ++index) { - if (args.at(index).startsWith(QLatin1String("--device="))) { - device = args.at(index).mid(9); - break; - } - } - if (device.isEmpty()) - device = QString::fromLocal8Bit(qgetenv("QMLSCENE_DEVICE")); - if (device.isEmpty()) - return new QSGContext(); - -#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) - if (QSGContextFactoryInterface *factory - = qobject_cast<QSGContextFactoryInterface*> - (loader()->instance(device))) { - QSGContext *context = factory->create(device); - if (context) - return context; - } -#ifndef QT_NO_DEBUG - qWarning("Could not create scene graph context for device '%s'" - " - check that plugins are installed correctly in %s", - qPrintable(device), - qPrintable(QLibraryInfo::location(QLibraryInfo::PluginsPath))); -#endif -#endif // QT_NO_LIBRARY || QT_NO_SETTINGS - - return new QSGContext(); -} - -QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/qsgcontextplugin_p.h b/src/declarative/scenegraph/qsgcontextplugin_p.h deleted file mode 100644 index 78c4a25372..0000000000 --- a/src/declarative/scenegraph/qsgcontextplugin_p.h +++ /dev/null @@ -1,81 +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 QSGCONTEXTPLUGIN_H -#define QSGCONTEXTPLUGIN_H - -#include <QtCore/qplugin.h> -#include <QtCore/qfactoryinterface.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class QSGContext; - -struct Q_DECLARATIVE_EXPORT QSGContextFactoryInterface : public QFactoryInterface -{ - virtual QSGContext *create(const QString &key) const = 0; -}; - -#define QSGContextFactoryInterface_iid \ - "com.trolltech.Qt.QSGContextFactoryInterface" -Q_DECLARE_INTERFACE(QSGContextFactoryInterface, QSGContextFactoryInterface_iid) - -class Q_DECLARATIVE_EXPORT QSGContextPlugin : public QObject, public QSGContextFactoryInterface -{ - Q_OBJECT - Q_INTERFACES(QSGContextFactoryInterface:QFactoryInterface) -public: - explicit QSGContextPlugin(QObject *parent = 0); - virtual ~QSGContextPlugin(); - - virtual QStringList keys() const = 0; - virtual QSGContext *create(const QString &key) const = 0; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QSGCONTEXTPLUGIN_H diff --git a/src/declarative/scenegraph/qsgdefaultdistancefieldglyphcache.cpp b/src/declarative/scenegraph/qsgdefaultdistancefieldglyphcache.cpp deleted file mode 100644 index 3dfa1bd269..0000000000 --- a/src/declarative/scenegraph/qsgdefaultdistancefieldglyphcache.cpp +++ /dev/null @@ -1,324 +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 "qsgdefaultdistancefieldglyphcache_p.h" - -#include <private/qsgdistancefieldutil_p.h> -#include <qopenglfunctions.h> - -QT_BEGIN_NAMESPACE - -QHash<QString, QOpenGLMultiGroupSharedResource> QSGDefaultDistanceFieldGlyphCache::m_textures_data; - -QSGDefaultDistanceFieldGlyphCache::DistanceFieldTextureData *QSGDefaultDistanceFieldGlyphCache::textureData(QOpenGLContext *c) -{ - QString key = QString::fromLatin1("%1_%2_%3_%4") - .arg(font().familyName()) - .arg(font().styleName()) - .arg(font().weight()) - .arg(font().style()); - return m_textures_data[key].value<QSGDefaultDistanceFieldGlyphCache::DistanceFieldTextureData>(c); -} - -QSGDefaultDistanceFieldGlyphCache::QSGDefaultDistanceFieldGlyphCache(QSGDistanceFieldGlyphCacheManager *man, QOpenGLContext *c, const QRawFont &font) - : QSGDistanceFieldGlyphCache(man, c, font) - , m_maxTextureSize(0) -{ - m_textureData = textureData(c); -} - -void QSGDefaultDistanceFieldGlyphCache::requestGlyphs(const QVector<glyph_t> &glyphs) -{ - int count = glyphs.count(); - - // Avoid useless and costly glyph re-generation - if (cacheIsFull() && !m_textureData->unusedGlyphs.isEmpty()) { - for (int i = 0; i < count; ++i) { - glyph_t glyphIndex = glyphs.at(i); - if (containsGlyph(glyphIndex) && m_textureData->unusedGlyphs.contains(glyphIndex)) - m_textureData->unusedGlyphs.remove(glyphIndex); - } - } - - QList<GlyphPosition> glyphPositions; - QVector<glyph_t> glyphsToRender; - - for (int i = 0; i < count; ++i) { - glyph_t glyphIndex = glyphs.at(i); - - if (++m_textureData->glyphRefCount[glyphIndex] == 1) - m_textureData->unusedGlyphs.remove(glyphIndex); - - if (cacheIsFull() && m_textureData->unusedGlyphs.isEmpty()) - continue; - - GlyphPosition p; - p.glyph = glyphIndex; - p.position = QPointF(m_textureData->currX, m_textureData->currY); - - if (!cacheIsFull()) { - m_textureData->currX += QT_DISTANCEFIELD_TILESIZE(doubleGlyphResolution()); - if (m_textureData->currX >= maxTextureSize()) { - m_textureData->currX = 0; - m_textureData->currY += QT_DISTANCEFIELD_TILESIZE(doubleGlyphResolution()); - } - } else { - // Recycle glyphs - if (!m_textureData->unusedGlyphs.isEmpty()) { - glyph_t unusedGlyph = *m_textureData->unusedGlyphs.constBegin(); - TexCoord unusedCoord = glyphTexCoord(unusedGlyph); - p.position = QPointF(unusedCoord.x, unusedCoord.y); - m_textureData->unusedGlyphs.remove(unusedGlyph); - removeGlyph(unusedGlyph); - } - } - - if (p.position.y() < maxTextureSize()) { - glyphPositions.append(p); - glyphsToRender.append(glyphIndex); - } - } - - addGlyphPositions(glyphPositions); - markGlyphsToRender(glyphsToRender); -} - -void QSGDefaultDistanceFieldGlyphCache::storeGlyphs(const QHash<glyph_t, QImage> &glyphs) -{ - int requiredWidth = maxTextureSize(); - int rows = 128 / (requiredWidth / QT_DISTANCEFIELD_TILESIZE(doubleGlyphResolution())); // Enough rows to fill the latin1 set by default.. - int requiredHeight = qMin(maxTextureSize(), - qMax(m_textureData->currY + QT_DISTANCEFIELD_TILESIZE(doubleGlyphResolution()), - QT_DISTANCEFIELD_TILESIZE(doubleGlyphResolution()) * rows)); - - resizeTexture((requiredWidth), (requiredHeight)); - glBindTexture(GL_TEXTURE_2D, m_textureData->texture); - - QVector<glyph_t> glyphTextures; - - QHash<glyph_t, QImage>::const_iterator it; - for (it = glyphs.constBegin(); it != glyphs.constEnd(); ++it) { - glyph_t glyphIndex = it.key(); - TexCoord c = glyphTexCoord(glyphIndex); - - glyphTextures.append(glyphIndex); - - QImage glyph = it.value(); - - if (useWorkaroundBrokenFBOReadback()) { - uchar *inBits = glyph.scanLine(0); - uchar *outBits = m_textureData->image.scanLine(int(c.y)) + int(c.x); - for (int y = 0; y < glyph.height(); ++y) { - qMemCopy(outBits, inBits, glyph.width()); - inBits += glyph.bytesPerLine(); - outBits += m_textureData->image.bytesPerLine(); - } - } - - glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, glyph.width(), glyph.height(), GL_ALPHA, GL_UNSIGNED_BYTE, glyph.constBits()); - } - - Texture t; - t.textureId = m_textureData->texture; - t.size = m_textureData->size; - addGlyphTextures(glyphTextures, t); -} - -void QSGDefaultDistanceFieldGlyphCache::releaseGlyphs(const QVector<glyph_t> &glyphs) -{ - int count = glyphs.count(); - for (int i = 0; i < count; ++i) { - glyph_t glyphIndex = glyphs.at(i); - if (--m_textureData->glyphRefCount[glyphIndex] == 0 && !glyphTexCoord(glyphIndex).isNull()) - m_textureData->unusedGlyphs.insert(glyphIndex); - } -} - -void QSGDefaultDistanceFieldGlyphCache::createTexture(int width, int height) -{ - if (useWorkaroundBrokenFBOReadback() && m_textureData->image.isNull()) - m_textureData->image = QImage(width, height, QImage::Format_Indexed8); - - while (glGetError() != GL_NO_ERROR) { } - - glGenTextures(1, &m_textureData->texture); - glBindTexture(GL_TEXTURE_2D, m_textureData->texture); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - m_textureData->size = QSize(width, height); - - GLuint error = glGetError(); - if (error != GL_NO_ERROR) { - glBindTexture(GL_TEXTURE_2D, 0); - glDeleteTextures(1, &m_textureData->texture); - m_textureData->texture = 0; - } - -} - -void QSGDefaultDistanceFieldGlyphCache::resizeTexture(int width, int height) -{ - int oldWidth = m_textureData->size.width(); - int oldHeight = m_textureData->size.height(); - if (width == oldWidth && height == oldHeight) - return; - - GLuint oldTexture = m_textureData->texture; - createTexture(width, height); - - if (!oldTexture) - return; - - updateTexture(oldTexture, m_textureData->texture, m_textureData->size); - - if (useWorkaroundBrokenFBOReadback()) { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, oldWidth, oldHeight, GL_ALPHA, GL_UNSIGNED_BYTE, m_textureData->image.constBits()); - m_textureData->image = m_textureData->image.copy(0, 0, width, height); - glDeleteTextures(1, &oldTexture); - return; - } - - if (!m_textureData->blitProgram) - m_textureData->createBlitProgram(); - - Q_ASSERT(m_textureData->blitProgram); - - if (!m_textureData->fbo) - ctx->functions()->glGenFramebuffers(1, &m_textureData->fbo); - ctx->functions()->glBindFramebuffer(GL_FRAMEBUFFER, m_textureData->fbo); - - GLuint tmp_texture; - glGenTextures(1, &tmp_texture); - glBindTexture(GL_TEXTURE_2D, tmp_texture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, oldWidth, oldHeight, 0, - GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glBindTexture(GL_TEXTURE_2D, 0); - ctx->functions()->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, tmp_texture, 0); - - ctx->functions()->glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, oldTexture); - - // save current render states - GLboolean stencilTestEnabled; - GLboolean depthTestEnabled; - GLboolean scissorTestEnabled; - GLboolean blendEnabled; - GLint viewport[4]; - GLint oldProgram; - glGetBooleanv(GL_STENCIL_TEST, &stencilTestEnabled); - glGetBooleanv(GL_DEPTH_TEST, &depthTestEnabled); - glGetBooleanv(GL_SCISSOR_TEST, &scissorTestEnabled); - glGetBooleanv(GL_BLEND, &blendEnabled); - glGetIntegerv(GL_VIEWPORT, &viewport[0]); - glGetIntegerv(GL_CURRENT_PROGRAM, &oldProgram); - - glDisable(GL_STENCIL_TEST); - glDisable(GL_DEPTH_TEST); - glDisable(GL_SCISSOR_TEST); - glDisable(GL_BLEND); - - glViewport(0, 0, oldWidth, oldHeight); - - ctx->functions()->glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, m_textureData->blitVertexCoordinateArray); - ctx->functions()->glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, m_textureData->blitTextureCoordinateArray); - - m_textureData->blitProgram->bind(); - m_textureData->blitProgram->enableAttributeArray(int(QT_VERTEX_COORDS_ATTR)); - m_textureData->blitProgram->enableAttributeArray(int(QT_TEXTURE_COORDS_ATTR)); - m_textureData->blitProgram->disableAttributeArray(int(QT_OPACITY_ATTR)); - m_textureData->blitProgram->setUniformValue("imageTexture", GLuint(0)); - - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - glBindTexture(GL_TEXTURE_2D, m_textureData->texture); - - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, oldWidth, oldHeight); - - ctx->functions()->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_RENDERBUFFER, 0); - glDeleteTextures(1, &tmp_texture); - glDeleteTextures(1, &oldTexture); - - ctx->functions()->glBindFramebuffer(GL_FRAMEBUFFER, 0); - - // restore render states - if (stencilTestEnabled) - glEnable(GL_STENCIL_TEST); - if (depthTestEnabled) - glEnable(GL_DEPTH_TEST); - if (scissorTestEnabled) - glEnable(GL_SCISSOR_TEST); - if (blendEnabled) - glEnable(GL_BLEND); - glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); - ctx->functions()->glUseProgram(oldProgram); -} - -bool QSGDefaultDistanceFieldGlyphCache::useWorkaroundBrokenFBOReadback() const -{ - static bool set = false; - static bool useWorkaround = false; - if (!set) { - QOpenGLContextPrivate *ctx_p = static_cast<QOpenGLContextPrivate *>(QOpenGLContextPrivate::get(ctx)); - useWorkaround = ctx_p->workaround_brokenFBOReadBack; - set = true; - } - return useWorkaround; -} - -int QSGDefaultDistanceFieldGlyphCache::maxTextureSize() const -{ - if (!m_maxTextureSize) - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize); - return m_maxTextureSize; -} - -QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/qsgdefaultdistancefieldglyphcache_p.h b/src/declarative/scenegraph/qsgdefaultdistancefieldglyphcache_p.h deleted file mode 100644 index 28860912c8..0000000000 --- a/src/declarative/scenegraph/qsgdefaultdistancefieldglyphcache_p.h +++ /dev/null @@ -1,165 +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 QSGDEFAULTDISTANCEFIELDGLYPHCACHE_H -#define QSGDEFAULTDISTANCEFIELDGLYPHCACHE_H - -#include <QtGui/qopenglfunctions.h> -#include <private/qsgadaptationlayer_p.h> -#include <qopenglshaderprogram.h> -#include <QtGui/private/qopenglengineshadersource_p.h> - -QT_BEGIN_NAMESPACE - -class Q_DECLARATIVE_EXPORT QSGDefaultDistanceFieldGlyphCache : public QSGDistanceFieldGlyphCache -{ -public: - QSGDefaultDistanceFieldGlyphCache(QSGDistanceFieldGlyphCacheManager *man, QOpenGLContext *c, const QRawFont &font); - - void requestGlyphs(const QVector<glyph_t> &glyphs); - void storeGlyphs(const QHash<glyph_t, QImage> &glyphs); - void releaseGlyphs(const QVector<glyph_t> &glyphs); - - bool cacheIsFull() const { return m_textureData->currY >= maxTextureSize(); } - bool useWorkaroundBrokenFBOReadback() const; - int maxTextureSize() const; - -private: - void createTexture(int width, int height); - void resizeTexture(int width, int height); - - mutable int m_maxTextureSize; - - struct DistanceFieldTextureData : public QOpenGLSharedResource { - GLuint texture; - GLuint fbo; - QSize size; - QHash<glyph_t, quint32> glyphRefCount; - QSet<glyph_t> unusedGlyphs; - int currX; - int currY; - QImage image; - - QOpenGLShaderProgram *blitProgram; - GLfloat blitVertexCoordinateArray[8]; - GLfloat blitTextureCoordinateArray[8]; - - DistanceFieldTextureData(QOpenGLContext *ctx) - : QOpenGLSharedResource(ctx->shareGroup()) - , texture(0) - , fbo(0) - , currX(0) - , currY(0) - , blitProgram(0) - { - blitVertexCoordinateArray[0] = -1.0f; - blitVertexCoordinateArray[1] = -1.0f; - blitVertexCoordinateArray[2] = 1.0f; - blitVertexCoordinateArray[3] = -1.0f; - blitVertexCoordinateArray[4] = 1.0f; - blitVertexCoordinateArray[5] = 1.0f; - blitVertexCoordinateArray[6] = -1.0f; - blitVertexCoordinateArray[7] = 1.0f; - - blitTextureCoordinateArray[0] = 0.0f; - blitTextureCoordinateArray[1] = 0.0f; - blitTextureCoordinateArray[2] = 1.0f; - blitTextureCoordinateArray[3] = 0.0f; - blitTextureCoordinateArray[4] = 1.0f; - blitTextureCoordinateArray[5] = 1.0f; - blitTextureCoordinateArray[6] = 0.0f; - blitTextureCoordinateArray[7] = 1.0f; - } - - void invalidateResource() - { - texture = 0; - fbo = 0; - size = QSize(); - delete blitProgram; - blitProgram = 0; - } - - void freeResource(QOpenGLContext *ctx) - { - glDeleteTextures(1, &texture); - ctx->functions()->glDeleteFramebuffers(1, &fbo); - delete blitProgram; - blitProgram = 0; - } - - void createBlitProgram() - { - blitProgram = new QOpenGLShaderProgram; - { - QString source; - source.append(QLatin1String(qopenglslMainWithTexCoordsVertexShader)); - source.append(QLatin1String(qopenglslUntransformedPositionVertexShader)); - - QOpenGLShader *vertexShader = new QOpenGLShader(QOpenGLShader::Vertex, blitProgram); - vertexShader->compileSourceCode(source); - - blitProgram->addShader(vertexShader); - } - { - QString source; - source.append(QLatin1String(qopenglslMainFragmentShader)); - source.append(QLatin1String(qopenglslImageSrcFragmentShader)); - - QOpenGLShader *fragmentShader = new QOpenGLShader(QOpenGLShader::Fragment, blitProgram); - fragmentShader->compileSourceCode(source); - - blitProgram->addShader(fragmentShader); - } - blitProgram->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); - blitProgram->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); - blitProgram->link(); - } - }; - - DistanceFieldTextureData *textureData(QOpenGLContext *c); - DistanceFieldTextureData *m_textureData; - static QHash<QString, QOpenGLMultiGroupSharedResource> m_textures_data; -}; - -QT_END_NAMESPACE - -#endif // QSGDEFAULTDISTANCEFIELDGLYPHCACHE_H diff --git a/src/declarative/scenegraph/qsgdefaultglyphnode.cpp b/src/declarative/scenegraph/qsgdefaultglyphnode.cpp deleted file mode 100644 index f41fbe486a..0000000000 --- a/src/declarative/scenegraph/qsgdefaultglyphnode.cpp +++ /dev/null @@ -1,95 +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 "qsgdefaultglyphnode_p.h" -#include "qsgdefaultglyphnode_p_p.h" - -#include <qopenglshaderprogram.h> -#include <private/qfont_p.h> - -QT_BEGIN_NAMESPACE - -QSGDefaultGlyphNode::QSGDefaultGlyphNode() - : m_material(0) - , m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 0) -{ - m_geometry.setDrawingMode(GL_TRIANGLES); - setGeometry(&m_geometry); -} - -QSGDefaultGlyphNode::~QSGDefaultGlyphNode() -{ - delete m_material; -} - -void QSGDefaultGlyphNode::setColor(const QColor &color) -{ - m_color = color; - if (m_material != 0) { - m_material->setColor(color); - markDirty(DirtyMaterial); - } -} - -void QSGDefaultGlyphNode::setGlyphs(const QPointF &position, const QGlyphRun &glyphs) -{ - if (m_material != 0) - delete m_material; - - QRawFont font = glyphs.rawFont(); - m_material = new QSGTextMaskMaterial(font); - m_material->setColor(m_color); - - QRectF boundingRect; - m_material->populate(position, glyphs.glyphIndexes(), glyphs.positions(), geometry(), - &boundingRect, &m_baseLine); - - setMaterial(m_material); - setBoundingRect(boundingRect); - - markDirty(DirtyGeometry); - -#ifdef QML_RUNTIME_TESTING - description = QLatin1String("glyphs"); -#endif -} - -QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/qsgdefaultglyphnode_p.cpp b/src/declarative/scenegraph/qsgdefaultglyphnode_p.cpp deleted file mode 100644 index 3476ab1665..0000000000 --- a/src/declarative/scenegraph/qsgdefaultglyphnode_p.cpp +++ /dev/null @@ -1,306 +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 "qsgdefaultglyphnode_p_p.h" - -#include <qopenglshaderprogram.h> - -#include <QtGui/private/qopengltextureglyphcache_p.h> -#include <private/qfontengine_p.h> -#include <private/qopenglextensions_p.h> - -#include <private/qsgtexture_p.h> - -#include <private/qrawfont_p.h> - -QT_BEGIN_NAMESPACE - -class QSGTextMaskMaterialData : public QSGMaterialShader -{ -public: - QSGTextMaskMaterialData(); - - virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect); - virtual char const *const *attributeNames() const; -private: - virtual void initialize(); - virtual const char *vertexShader() const; - virtual const char *fragmentShader() const; - - int m_matrix_id; - int m_color_id; - int m_textureScale_id; -}; - -const char *QSGTextMaskMaterialData::vertexShader() const { - return - "uniform highp mat4 matrix; \n" - "uniform highp vec2 textureScale; \n" - "attribute highp vec4 vCoord; \n" - "attribute highp vec2 tCoord; \n" - "varying highp vec2 sampleCoord; \n" - "void main() { \n" - " sampleCoord = tCoord * textureScale; \n" - " gl_Position = matrix * vCoord; \n" - "}"; -} - -const char *QSGTextMaskMaterialData::fragmentShader() const { - return - "varying highp vec2 sampleCoord; \n" - "uniform sampler2D texture; \n" - "uniform lowp vec4 color; \n" - "void main() { \n" - " gl_FragColor = color * texture2D(texture, sampleCoord).a; \n" - "}"; -} - -char const *const *QSGTextMaskMaterialData::attributeNames() const -{ - static char const *const attr[] = { "vCoord", "tCoord", 0 }; - return attr; -} - -QSGTextMaskMaterialData::QSGTextMaskMaterialData() -{ -} - -void QSGTextMaskMaterialData::initialize() -{ - m_matrix_id = program()->uniformLocation("matrix"); - m_color_id = program()->uniformLocation("color"); - m_textureScale_id = program()->uniformLocation("textureScale"); -} - -void QSGTextMaskMaterialData::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) -{ - Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type()); - QSGTextMaskMaterial *material = static_cast<QSGTextMaskMaterial *>(newEffect); - QSGTextMaskMaterial *oldMaterial = static_cast<QSGTextMaskMaterial *>(oldEffect); - - if (oldMaterial == 0 || material->color() != oldMaterial->color() || state.isOpacityDirty()) { - QVector4D color(material->color().redF(), material->color().greenF(), - material->color().blueF(), material->color().alphaF()); - color *= state.opacity(); - program()->setUniformValue(m_color_id, color); - } - - bool updated = material->ensureUpToDate(); - Q_ASSERT(material->texture()); - - Q_ASSERT(oldMaterial == 0 || oldMaterial->texture()); - if (updated - || oldMaterial == 0 - || oldMaterial->texture()->textureId() != material->texture()->textureId()) { - program()->setUniformValue(m_textureScale_id, QVector2D(1.0 / material->cacheTextureWidth(), - 1.0 / material->cacheTextureHeight())); - glBindTexture(GL_TEXTURE_2D, material->texture()->textureId()); - - // Set the mag/min filters to be linear. We only need to do this when the texture - // has been recreated. - if (updated) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } - } - - if (state.isMatrixDirty()) - program()->setUniformValue(m_matrix_id, state.combinedMatrix()); -} - -QSGTextMaskMaterial::QSGTextMaskMaterial(const QRawFont &font) - : m_texture(0), m_glyphCache(), m_font(font) -{ - init(); -} - -QSGTextMaskMaterial::~QSGTextMaskMaterial() -{ -} - -void QSGTextMaskMaterial::init() -{ - Q_ASSERT(m_font.isValid()); - - QFontEngineGlyphCache::Type type = QFontEngineGlyphCache::Raster_A8; - setFlag(Blending, true); - - QOpenGLContext *ctx = const_cast<QOpenGLContext *>(QOpenGLContext::currentContext()); - Q_ASSERT(ctx != 0); - - QRawFontPrivate *fontD = QRawFontPrivate::get(m_font); - if (fontD->fontEngine != 0) { - m_glyphCache = fontD->fontEngine->glyphCache(ctx, type, QTransform()); - if (!m_glyphCache || m_glyphCache->cacheType() != type) { - m_glyphCache = new QOpenGLTextureGlyphCache(type, QTransform()); - fontD->fontEngine->setGlyphCache(ctx, m_glyphCache.data()); - } - } -} - -void QSGTextMaskMaterial::populate(const QPointF &p, - const QVector<quint32> &glyphIndexes, - const QVector<QPointF> &glyphPositions, - QSGGeometry *geometry, - QRectF *boundingRect, - QPointF *baseLine) -{ - Q_ASSERT(m_font.isValid()); - QVector<QFixedPoint> fixedPointPositions; - for (int i=0; i<glyphPositions.size(); ++i) - fixedPointPositions.append(QFixedPoint::fromPointF(glyphPositions.at(i))); - - QTextureGlyphCache *cache = glyphCache(); - - QRawFontPrivate *fontD = QRawFontPrivate::get(m_font); - cache->populate(fontD->fontEngine, glyphIndexes.size(), glyphIndexes.constData(), - fixedPointPositions.data()); - cache->fillInPendingGlyphs(); - - int margin = cache->glyphMargin(); - - Q_ASSERT(geometry->indexType() == GL_UNSIGNED_SHORT); - geometry->allocate(glyphIndexes.size() * 4, glyphIndexes.size() * 6); - QVector4D *vp = (QVector4D *)geometry->vertexDataAsTexturedPoint2D(); - Q_ASSERT(geometry->sizeOfVertex() == sizeof(QVector4D)); - ushort *ip = geometry->indexDataAsUShort(); - - QPointF position(p.x(), p.y() - m_font.ascent()); - bool supportsSubPixelPositions = fontD->fontEngine->supportsSubPixelPositions(); - for (int i=0; i<glyphIndexes.size(); ++i) { - QFixed subPixelPosition; - if (supportsSubPixelPositions) - subPixelPosition = fontD->fontEngine->subPixelPositionForX(QFixed::fromReal(glyphPositions.at(i).x())); - - QTextureGlyphCache::GlyphAndSubPixelPosition glyph(glyphIndexes.at(i), subPixelPosition); - const QTextureGlyphCache::Coord &c = cache->coords.value(glyph); - - QPointF glyphPosition = glyphPositions.at(i) + position; - int x = qRound(glyphPosition.x()) + c.baseLineX - margin; - int y = qRound(glyphPosition.y()) - c.baseLineY - margin; - - *boundingRect |= QRectF(x + margin, y + margin, c.w, c.h); - - float cx1 = x; - float cx2 = x + c.w; - float cy1 = y; - float cy2 = y + c.h; - - float tx1 = c.x; - float tx2 = (c.x + c.w); - float ty1 = c.y; - float ty2 = (c.y + c.h); - - if (baseLine->isNull()) - *baseLine = glyphPosition; - - vp[4 * i + 0] = QVector4D(cx1, cy1, tx1, ty1); - vp[4 * i + 1] = QVector4D(cx2, cy1, tx2, ty1); - vp[4 * i + 2] = QVector4D(cx1, cy2, tx1, ty2); - vp[4 * i + 3] = QVector4D(cx2, cy2, tx2, ty2); - - int o = i * 4; - ip[6 * i + 0] = o + 0; - ip[6 * i + 1] = o + 2; - ip[6 * i + 2] = o + 3; - ip[6 * i + 3] = o + 3; - ip[6 * i + 4] = o + 1; - ip[6 * i + 5] = o + 0; - } -} - -QSGMaterialType *QSGTextMaskMaterial::type() const -{ - static QSGMaterialType type; - return &type; -} - -QOpenGLTextureGlyphCache *QSGTextMaskMaterial::glyphCache() const -{ - return static_cast<QOpenGLTextureGlyphCache*>(m_glyphCache.data()); -} - -QSGMaterialShader *QSGTextMaskMaterial::createShader() const -{ - return new QSGTextMaskMaterialData; -} - -int QSGTextMaskMaterial::compare(const QSGMaterial *o) const -{ - Q_ASSERT(o && type() == o->type()); - const QSGTextMaskMaterial *other = static_cast<const QSGTextMaskMaterial *>(o); - if (m_glyphCache != other->m_glyphCache) - return m_glyphCache - other->m_glyphCache; - QRgb c1 = m_color.rgba(); - QRgb c2 = other->m_color.rgba(); - return int(c2 < c1) - int(c1 < c2); -} - -bool QSGTextMaskMaterial::ensureUpToDate() -{ - QSize glyphCacheSize(glyphCache()->width(), glyphCache()->height()); - if (glyphCacheSize != m_size) { - if (m_texture) - delete m_texture; - m_texture = new QSGPlainTexture(); - m_texture->setTextureId(glyphCache()->texture()); - m_texture->setTextureSize(QSize(glyphCache()->width(), glyphCache()->height())); - m_texture->setOwnsTexture(false); - - m_size = glyphCacheSize; - - return true; - } else { - return false; - } -} - -int QSGTextMaskMaterial::cacheTextureWidth() const -{ - return glyphCache()->width(); -} - -int QSGTextMaskMaterial::cacheTextureHeight() const -{ - return glyphCache()->height(); -} - -QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/qsgdefaultglyphnode_p.h b/src/declarative/scenegraph/qsgdefaultglyphnode_p.h deleted file mode 100644 index f9d163c425..0000000000 --- a/src/declarative/scenegraph/qsgdefaultglyphnode_p.h +++ /dev/null @@ -1,87 +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 DEFAULT_GLYPHNODE_H -#define DEFAULT_GLYPHNODE_H - -#include <private/qsgadaptationlayer_p.h> -#include <qsgnode.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class QGlyphs; -class QSGTextMaskMaterial; -class QSGDefaultGlyphNode: public QSGGlyphNode -{ -public: - QSGDefaultGlyphNode(); - ~QSGDefaultGlyphNode(); - - virtual QPointF baseLine() const { return m_baseLine; } - virtual void setGlyphs(const QPointF &position, const QGlyphRun &glyphs); - virtual void setColor(const QColor &color); - - virtual void setPreferredAntialiasingMode(AntialiasingMode) { } - virtual void setStyle(QQuickText::TextStyle) { } - virtual void setStyleColor(const QColor &) { } - - virtual void update() { } - -private: - QGlyphRun m_glyphs; - QPointF m_position; - QColor m_color; - - QPointF m_baseLine; - QSGTextMaskMaterial *m_material; - - QSGGeometry m_geometry; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // DEFAULT_GLYPHNODE_H diff --git a/src/declarative/scenegraph/qsgdefaultglyphnode_p_p.h b/src/declarative/scenegraph/qsgdefaultglyphnode_p_p.h deleted file mode 100644 index d22bc33fea..0000000000 --- a/src/declarative/scenegraph/qsgdefaultglyphnode_p_p.h +++ /dev/null @@ -1,96 +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 TEXTMASKMATERIAL_H -#define TEXTMASKMATERIAL_H - -#include <qcolor.h> -#include <qsgmaterial.h> -#include <qsgtexture.h> -#include <qsggeometry.h> -#include <qshareddata.h> -#include <private/qsgtexture_p.h> -#include <qrawfont.h> - -QT_BEGIN_NAMESPACE - -class QFontEngineGlyphCache; -class QOpenGLTextureGlyphCache; -class QFontEngine; -class Geometry; -class QSGTextMaskMaterial: public QSGMaterial -{ -public: - QSGTextMaskMaterial(const QRawFont &font); - ~QSGTextMaskMaterial(); - - virtual QSGMaterialType *type() const; - virtual QSGMaterialShader *createShader() const; - virtual int compare(const QSGMaterial *other) const; - - void setColor(const QColor &color) { m_color = color; } - const QColor &color() const { return m_color; } - - QSGTexture *texture() const { return m_texture; } - - int cacheTextureWidth() const; - int cacheTextureHeight() const; - - bool ensureUpToDate(); - - QOpenGLTextureGlyphCache *glyphCache() const; - void populate(const QPointF &position, - const QVector<quint32> &glyphIndexes, const QVector<QPointF> &glyphPositions, - QSGGeometry *geometry, QRectF *boundingRect, QPointF *baseLine); - -private: - void init(); - - QSGPlainTexture *m_texture; - QExplicitlySharedDataPointer<QFontEngineGlyphCache> m_glyphCache; - QRawFont m_font; - QColor m_color; - QSize m_size; -}; - -QT_END_NAMESPACE - -#endif // TEXTMASKMATERIAL_H diff --git a/src/declarative/scenegraph/qsgdefaultimagenode.cpp b/src/declarative/scenegraph/qsgdefaultimagenode.cpp deleted file mode 100644 index f30a7e2675..0000000000 --- a/src/declarative/scenegraph/qsgdefaultimagenode.cpp +++ /dev/null @@ -1,293 +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 "qsgdefaultimagenode_p.h" - -#include <private/qsgtextureprovider_p.h> - -#include <QtCore/qvarlengtharray.h> -#include <QtCore/qmath.h> -#include <QtGui/qopenglfunctions.h> - -QT_BEGIN_NAMESPACE - -QSGDefaultImageNode::QSGDefaultImageNode() - : m_sourceRect(0, 0, 1, 1) - , m_dirtyGeometry(false) - , m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4) -{ - setMaterial(&m_materialO); - setOpaqueMaterial(&m_material); - setGeometry(&m_geometry); - -#ifdef QML_RUNTIME_TESTING - description = QLatin1String("image"); -#endif -} - -void QSGDefaultImageNode::setTargetRect(const QRectF &rect) -{ - if (rect == m_targetRect) - return; - m_targetRect = rect; - m_dirtyGeometry = true; -} - -void QSGDefaultImageNode::setSourceRect(const QRectF &rect) -{ - if (rect == m_sourceRect) - return; - m_sourceRect = rect; - m_dirtyGeometry = true; -} - - -void QSGDefaultImageNode::setFiltering(QSGTexture::Filtering filtering) -{ - if (m_material.filtering() == filtering) - return; - - m_material.setFiltering(filtering); - m_materialO.setFiltering(filtering); - markDirty(DirtyMaterial); -} - - -void QSGDefaultImageNode::setMipmapFiltering(QSGTexture::Filtering filtering) -{ - if (m_material.mipmapFiltering() == filtering) - return; - - m_material.setMipmapFiltering(filtering); - m_materialO.setMipmapFiltering(filtering); - markDirty(DirtyMaterial); -} - -void QSGDefaultImageNode::setVerticalWrapMode(QSGTexture::WrapMode wrapMode) -{ - if (m_material.verticalWrapMode() == wrapMode) - return; - - m_material.setVerticalWrapMode(wrapMode); - m_materialO.setVerticalWrapMode(wrapMode); - markDirty(DirtyMaterial); -} - -void QSGDefaultImageNode::setHorizontalWrapMode(QSGTexture::WrapMode wrapMode) -{ - if (m_material.horizontalWrapMode() == wrapMode) - return; - - m_material.setHorizontalWrapMode(wrapMode); - m_materialO.setHorizontalWrapMode(wrapMode); - markDirty(DirtyMaterial); -} - - -void QSGDefaultImageNode::setTexture(QSGTexture *texture) -{ - if (texture == m_material.texture()) - return; - - m_material.setTexture(texture); - m_materialO.setTexture(texture); - // Texture cleanup -// if (!texture.isNull()) -// m_material.setBlending(texture->hasAlphaChannel()); - markDirty(DirtyMaterial); - - // Because the texture can be a different part of the atlas, we need to update it... - m_dirtyGeometry = true; -} - -void QSGDefaultImageNode::update() -{ - if (m_dirtyGeometry) - updateGeometry(); -} - -void QSGDefaultImageNode::preprocess() -{ - bool doDirty = false; - QSGDynamicTexture *t = qobject_cast<QSGDynamicTexture *>(m_material.texture()); - if (t) { - doDirty = t->updateTexture(); - updateGeometry(); - } -// ### texture cleanup -// bool alpha = m_material.blending(); -// if (!m_material->texture().isNull() && alpha != m_material.texture()->hasAlphaChannel()) { -// m_material.setBlending(!alpha); -// doDirty = true; -// } - - if (doDirty) - markDirty(DirtyMaterial); -} - -inline static bool isPowerOfTwo(int x) -{ - // Assumption: x >= 1 - return x == (x & -x); -} - -namespace { - struct X { float x, tx; }; - struct Y { float y, ty; }; -} - -void QSGDefaultImageNode::updateGeometry() -{ - const QSGTexture *t = m_material.texture(); - if (!t) { - m_geometry.allocate(4); - m_geometry.setDrawingMode(GL_TRIANGLE_STRIP); - QSGGeometry::updateTexturedRectGeometry(&m_geometry, QRectF(), QRectF()); - } else { - QRectF textureRect = t->textureSubRect(); - - bool isSubRect = textureRect != QRectF(0, 0, 1, 1); - const int ceilRight = qCeil(m_sourceRect.right()); - const int floorLeft = qFloor(m_sourceRect.left()); - const int ceilBottom = qCeil(m_sourceRect.bottom()); - const int floorTop = qFloor(m_sourceRect.top()); - const int hCells = ceilRight - floorLeft; - const int vCells = ceilBottom - floorTop; - bool isRepeating = hCells > 1 || vCells > 1; - -#ifdef QT_OPENGL_ES_2 - QOpenGLContext *ctx = QOpenGLContext::currentContext(); - bool npotSupported = ctx->functions()->hasOpenGLFeature(QOpenGLFunctions::NPOTTextures); - - QSize size = t->textureSize(); - bool isNpot = !isPowerOfTwo(size.width()) || !isPowerOfTwo(size.height()); - - if (isRepeating && (isSubRect || (isNpot && !npotSupported))) { -#else - if (isRepeating && isSubRect) { -#endif - m_geometry.allocate(hCells * vCells * 4, hCells * vCells * 6); - m_geometry.setDrawingMode(GL_TRIANGLES); - QVarLengthArray<X, 32> xData(2 * hCells); - QVarLengthArray<Y, 32> yData(2 * vCells); - X *xs = xData.data(); - Y *ys = yData.data(); - - xs->x = m_targetRect.left(); - xs->tx = textureRect.x() + (m_sourceRect.left() - floorLeft) * textureRect.width(); - ++xs; - ys->y = m_targetRect.top(); - ys->ty = textureRect.y() + (m_sourceRect.top() - floorTop) * textureRect.height(); - ++ys; - - float a, b; - b = m_targetRect.width() / m_sourceRect.width(); - a = m_targetRect.x() - m_sourceRect.x() * b; - - float tex_x1 = textureRect.x(); - float tex_x2 = textureRect.right(); - float tex_y1 = textureRect.y(); - float tex_y2 = textureRect.bottom(); - for (int i = floorLeft + 1; i <= ceilRight - 1; ++i) { - xs[0].x = xs[1].x = a + b * i; - xs[0].tx = tex_x2; - xs[1].tx = tex_x1; - xs += 2; - } - b = m_targetRect.height() / m_sourceRect.height(); - a = m_targetRect.y() - m_sourceRect.y() * b; - for (int i = floorTop + 1; i <= ceilBottom - 1; ++i) { - ys[0].y = ys[1].y = a + b * i; - ys[0].ty = tex_y2; - ys[1].ty = tex_y1; - ys += 2; - } - - xs->x = m_targetRect.right(); - xs->tx = textureRect.x() + (m_sourceRect.right() - ceilRight + 1) * textureRect.width(); - - ys->y = m_targetRect.bottom(); - ys->ty = textureRect.y() + (m_sourceRect.bottom() - ceilBottom + 1) * textureRect.height(); - - QSGGeometry::TexturedPoint2D *vertices = m_geometry.vertexDataAsTexturedPoint2D(); - ys = yData.data(); - for (int j = 0; j < vCells; ++j, ys += 2) { - xs = xData.data(); - for (int i = 0; i < hCells; ++i, xs += 2) { - vertices[0].x = vertices[2].x = xs[0].x; - vertices[0].tx = vertices[2].tx = xs[0].tx; - vertices[1].x = vertices[3].x = xs[1].x; - vertices[1].tx = vertices[3].tx = xs[1].tx; - - vertices[0].y = vertices[1].y = ys[0].y; - vertices[0].ty = vertices[1].ty = ys[0].ty; - vertices[2].y = vertices[3].y = ys[1].y; - vertices[2].ty = vertices[3].ty = ys[1].ty; - - vertices += 4; - } - } - - quint16 *indices = m_geometry.indexDataAsUShort(); - for (int i = 0; i < 4 * vCells * hCells; i += 4) { - *indices++ = i; - *indices++ = i + 2; - *indices++ = i + 3; - *indices++ = i + 3; - *indices++ = i + 1; - *indices++ = i; - } - } else { - QRectF sr(textureRect.x() + m_sourceRect.x() * textureRect.width(), - textureRect.y() + m_sourceRect.y() * textureRect.height(), - m_sourceRect.width() * textureRect.width(), - m_sourceRect.height() * textureRect.height()); - - m_geometry.allocate(4); - m_geometry.setDrawingMode(GL_TRIANGLE_STRIP); - QSGGeometry::updateTexturedRectGeometry(&m_geometry, m_targetRect, sr); - } - } - markDirty(DirtyGeometry); - m_dirtyGeometry = false; -} - -QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/qsgdefaultimagenode_p.h b/src/declarative/scenegraph/qsgdefaultimagenode_p.h deleted file mode 100644 index db11cd9181..0000000000 --- a/src/declarative/scenegraph/qsgdefaultimagenode_p.h +++ /dev/null @@ -1,90 +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 DEFAULT_PIXMAPNODE_H -#define DEFAULT_PIXMAPNODE_H - -#include <private/qsgadaptationlayer_p.h> - -#include "qsgtexturematerial.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class QSGDefaultImageNode : public QSGImageNode -{ -public: - QSGDefaultImageNode(); - virtual void setTargetRect(const QRectF &rect); - virtual void setSourceRect(const QRectF &rect); - virtual void setTexture(QSGTexture *t); - virtual void update(); - - virtual void setMipmapFiltering(QSGTexture::Filtering filtering); - virtual void setFiltering(QSGTexture::Filtering filtering); - virtual void setHorizontalWrapMode(QSGTexture::WrapMode wrapMode); - virtual void setVerticalWrapMode(QSGTexture::WrapMode wrapMode); - - virtual void preprocess(); - -private: - void updateGeometry(); - - QRectF m_targetRect; - QRectF m_sourceRect; - - QSGOpaqueTextureMaterial m_material; - QSGTextureMaterial m_materialO; - - uint m_dirtyGeometry : 1; - - QSGGeometry m_geometry; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/declarative/scenegraph/qsgdefaultrectanglenode.cpp b/src/declarative/scenegraph/qsgdefaultrectanglenode.cpp deleted file mode 100644 index 4753b6021e..0000000000 --- a/src/declarative/scenegraph/qsgdefaultrectanglenode.cpp +++ /dev/null @@ -1,548 +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 "qsgdefaultrectanglenode_p.h" - -#include <qsgvertexcolormaterial.h> -#include "qsgtexturematerial.h" - -#include <private/qsgcontext_p.h> - -#include <QtCore/qmath.h> -#include <QtCore/qvarlengtharray.h> - -QT_BEGIN_NAMESPACE - -QSGDefaultRectangleNode::QSGDefaultRectangleNode(QSGContext *context) - : m_border(0) - , m_radius(0) - , m_pen_width(0) - , m_aligned(true) - , m_gradient_is_opaque(true) - , m_dirty_geometry(false) - , m_default_geometry(QSGGeometry::defaultAttributes_Point2D(), 4) - , m_context(context) -{ - setGeometry(&m_default_geometry); - setMaterial(&m_fill_material); - m_border_material.setColor(QColor(0, 0, 0)); - - m_material_type = TypeFlat; - -#ifdef QML_RUNTIME_TESTING - description = QLatin1String("rectangle"); -#endif -} - -QSGDefaultRectangleNode::~QSGDefaultRectangleNode() -{ - if (m_material_type == TypeVertexGradient) - delete material(); - delete m_border; -} - -QSGGeometryNode *QSGDefaultRectangleNode::border() -{ - if (!m_border) { - m_border = new QSGGeometryNode; - m_border->setMaterial(&m_border_material); - QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 0); - m_border->setGeometry(geometry); - m_border->setFlag(QSGNode::OwnsGeometry); - } - return m_border; -} - -void QSGDefaultRectangleNode::setRect(const QRectF &rect) -{ - if (rect == m_rect) - return; - m_rect = rect; - m_dirty_geometry = true; -} - -void QSGDefaultRectangleNode::setColor(const QColor &color) -{ - if (color == m_fill_material.color()) - return; - m_fill_material.setColor(color); - if (m_gradient_stops.isEmpty()) { - Q_ASSERT(m_material_type == TypeFlat); - markDirty(DirtyMaterial); - } -} - -void QSGDefaultRectangleNode::setPenColor(const QColor &color) -{ - if (color == m_border_material.color()) - return; - m_border_material.setColor(color); - if (m_border) - m_border->markDirty(DirtyMaterial); -} - -void QSGDefaultRectangleNode::setPenWidth(qreal width) -{ - if (width == m_pen_width) - return; - m_pen_width = width; - if (m_pen_width <= 0 && m_border && m_border->parent()) - removeChildNode(m_border); - else if (m_pen_width > 0 && !border()->parent()) - appendChildNode(m_border); - m_dirty_geometry = true; -} - - -void QSGDefaultRectangleNode::setGradientStops(const QGradientStops &stops) -{ - if (stops.constData() == m_gradient_stops.constData()) - return; - - m_gradient_stops = stops; - - m_gradient_is_opaque = true; - for (int i = 0; i < stops.size(); ++i) - m_gradient_is_opaque &= stops.at(i).second.alpha() == 0xff; - - if (stops.isEmpty()) { - // No gradient specified, use flat color. - if (m_material_type != TypeFlat) { - delete material(); - - setMaterial(&m_fill_material); - m_material_type = TypeFlat; - - setGeometry(&m_default_geometry); - setFlag(OwnsGeometry, false); - } - } else { - if (m_material_type == TypeFlat) { - QSGVertexColorMaterial *material = new QSGVertexColorMaterial; - setMaterial(material); - m_material_type = TypeVertexGradient; - QSGGeometry *g = new QSGGeometry(QSGGeometry::defaultAttributes_ColoredPoint2D(), 0); - setGeometry(g); - setFlag(OwnsGeometry); - } - static_cast<QSGVertexColorMaterial *>(material())->setFlag(QSGMaterial::Blending, !m_gradient_is_opaque); - } - - m_dirty_geometry = true; -} - -void QSGDefaultRectangleNode::setRadius(qreal radius) -{ - if (radius == m_radius) - return; - m_radius = radius; - m_dirty_geometry = true; -} - -void QSGDefaultRectangleNode::setAligned(bool aligned) -{ - if (aligned == m_aligned) - return; - m_aligned = aligned; - m_dirty_geometry = true; -} - -void QSGDefaultRectangleNode::update() -{ - if (m_dirty_geometry) { - updateGeometry(); - m_dirty_geometry = false; - } -} - -struct Color4ub -{ - unsigned char r, g, b, a; -}; - -Color4ub operator *(Color4ub c, float t) { c.a *= t; c.r *= t; c.g *= t; c.b *= t; return c; } -Color4ub operator +(Color4ub a, Color4ub b) { a.a += b.a; a.r += b.r; a.g += b.g; a.b += b.b; return a; } - -static inline Color4ub colorToColor4ub(const QColor &c) -{ - Color4ub color = { uchar(c.redF() * c.alphaF() * 255), - uchar(c.greenF() * c.alphaF() * 255), - uchar(c.blueF() * c.alphaF() * 255), - uchar(c.alphaF() * 255) - }; - return color; -} - -struct Vertex -{ - QVector2D position; -}; - -struct ColorVertex -{ - QVector2D position; - Color4ub color; -}; - -void QSGDefaultRectangleNode::updateGeometry() -{ - qreal penWidth = m_aligned ? qreal(qRound(m_pen_width)) : m_pen_width; - - // fast path for the simple case... - if ((penWidth == 0 || m_border_material.color().alpha() == 0) - && m_radius == 0 - && m_material_type == TypeFlat) { - QSGGeometry::updateRectGeometry(&m_default_geometry, m_rect); - return; - } - - QSGGeometry *fill = geometry(); - - // Check that the vertex type matches the material. - Q_ASSERT(m_material_type != TypeFlat || fill->sizeOfVertex() == sizeof(Vertex)); - Q_ASSERT(m_material_type != TypeVertexGradient || fill->sizeOfVertex() == sizeof(ColorVertex)); - - QSGGeometry *borderGeometry = 0; - if (m_border) { - borderGeometry = m_border->geometry(); - Q_ASSERT(borderGeometry->sizeOfVertex() == sizeof(Vertex)); - } - - int fillVertexCount = 0; - - // Preallocate arrays for a rectangle with 18 segments per corner and 3 gradient stops. - uchar *fillVertices = 0; - Vertex *borderVertices = 0; - - Color4ub fillColor = colorToColor4ub(m_fill_material.color()); - const QGradientStops &stops = m_gradient_stops; - - if (m_radius > 0) { - // Rounded corners. - - // Radius should never exceeds half of the width or half of the height - qreal radius = qMin(qMin(m_rect.width() * qreal(0.5), m_rect.height() * qreal(0.5)), m_radius); - QRectF innerRect = m_rect; - innerRect.adjust(radius, radius, -radius, -radius); - if (m_aligned && (int(penWidth) & 1)) { - // Pen width is odd, so add the offset as documented. - innerRect.moveLeft(innerRect.left() + qreal(0.5)); - innerRect.moveTop(innerRect.top() + qreal(0.5)); - } - - qreal innerRadius = radius - penWidth * qreal(0.5); - qreal outerRadius = radius + penWidth * qreal(0.5); - - // Number of segments per corner, approximately one per 3 pixels. - int segments = qBound(3, qCeil(outerRadius * (M_PI / 6)), 18); - - /* - - --+-__ - | segment - | _+ - --+-__ _- \ - -+ segment - --------+ \ <- gradient line - +-----+ - | | - - */ - - int nextGradientStop = 0; - qreal gradientPos = (radius - innerRadius) / (innerRect.height() + 2 * radius); - while (nextGradientStop < stops.size() && stops.at(nextGradientStop).first <= gradientPos) - ++nextGradientStop; - int lastGradientStop = stops.size() - 1; - qreal lastGradientPos = (innerRect.height() + radius + innerRadius) / (innerRect.height() + 2 * radius); - while (lastGradientStop >= nextGradientStop && stops.at(lastGradientStop).first >= lastGradientPos) - --lastGradientStop; - - int borderVertexHead = 0; - int borderVertexTail = 0; - if (penWidth) { - // The reason I add extra vertices where the gradient lines intersect the border is - // to avoid pixel sized gaps between the fill and the border caused by floating point - // inaccuracies. - borderGeometry->allocate((segments + 1) * 2 * 4 + (lastGradientStop - nextGradientStop + 1) * 4 + 2); - borderVertexHead = borderVertexTail = (borderGeometry->vertexCount() >> 1) - 1; - borderVertices = (Vertex *)borderGeometry->vertexData(); - } - - fill->allocate((segments + 1) * 4 + (lastGradientStop - nextGradientStop + 1) * 2); - fillVertices = (uchar *)fill->vertexData(); - - qreal py = 0; // previous inner y-coordinate. - qreal plx = 0; // previous inner left x-coordinate. - qreal prx = 0; // previous inner right x-coordinate. - - qreal angle = qreal(0.5) * M_PI / qreal(segments); - qreal cosStep = qFastCos(angle); - qreal sinStep = qFastSin(angle); - - for (int part = 0; part < 2; ++part) { - qreal c = 1 - part; - qreal s = part; - for (int i = 0; i <= segments; ++i) { - qreal y, lx, rx; - if (innerRadius > 0) { - y = (part ? innerRect.bottom() : innerRect.top()) - innerRadius * c; // current inner y-coordinate. - lx = innerRect.left() - innerRadius * s; // current inner left x-coordinate. - rx = innerRect.right() + innerRadius * s; // current inner right x-coordinate. - gradientPos = ((part ? innerRect.height() : 0) + radius - innerRadius * c) / (innerRect.height() + 2 * radius); - } else { - y = (part ? innerRect.bottom() + innerRadius : innerRect.top() - innerRadius); // current inner y-coordinate. - lx = innerRect.left() - innerRadius; // current inner left x-coordinate. - rx = innerRect.right() + innerRadius; // current inner right x-coordinate. - gradientPos = ((part ? innerRect.height() + innerRadius : -innerRadius) + radius) / (innerRect.height() + 2 * radius); - } - qreal Y = (part ? innerRect.bottom() : innerRect.top()) - outerRadius * c; // current outer y-coordinate. - qreal lX = innerRect.left() - outerRadius * s; // current outer left x-coordinate. - qreal rX = innerRect.right() + outerRadius * s; // current outer right x-coordinate. - - while (nextGradientStop <= lastGradientStop && stops.at(nextGradientStop).first <= gradientPos) { - // Insert vertices at gradient stops. - qreal gy = (innerRect.top() - radius) + stops.at(nextGradientStop).first * (innerRect.height() + 2 * radius); - Q_ASSERT(fillVertexCount >= 2); - qreal t = (gy - py) / (y - py); - qreal glx = plx * (1 - t) + t * lx; - qreal grx = prx * (1 - t) + t * rx; - - if (penWidth) { - const Vertex &first = borderVertices[borderVertexHead]; - borderVertices[--borderVertexHead].position = QVector2D(glx, gy); - borderVertices[--borderVertexHead] = first; - - const Vertex &last = borderVertices[borderVertexTail - 2]; - borderVertices[borderVertexTail++] = last; - borderVertices[borderVertexTail++].position = QVector2D(grx, gy); - } - - ColorVertex *vertices = (ColorVertex *)fillVertices; - - fillColor = colorToColor4ub(stops.at(nextGradientStop).second); - vertices[fillVertexCount].position = QVector2D(grx, gy); - vertices[fillVertexCount].color = fillColor; - ++fillVertexCount; - vertices[fillVertexCount].position = QVector2D(glx, gy); - vertices[fillVertexCount].color = fillColor; - ++fillVertexCount; - - ++nextGradientStop; - } - - if (penWidth) { - borderVertices[--borderVertexHead].position = QVector2D(lx, y); - borderVertices[--borderVertexHead].position = QVector2D(lX, Y); - borderVertices[borderVertexTail++].position = QVector2D(rX, Y); - borderVertices[borderVertexTail++].position = QVector2D(rx, y); - } - - if (stops.isEmpty()) { - Q_ASSERT(m_material_type == TypeFlat); - Vertex *vertices = (Vertex *)fillVertices; - vertices[fillVertexCount++].position = QVector2D(rx, y); - vertices[fillVertexCount++].position = QVector2D(lx, y); - } else { - if (nextGradientStop == 0) { - fillColor = colorToColor4ub(stops.at(0).second); - } else if (nextGradientStop == stops.size()) { - fillColor = colorToColor4ub(stops.last().second); - } else { - const QGradientStop &prev = stops.at(nextGradientStop - 1); - const QGradientStop &next = stops.at(nextGradientStop); - qreal t = (gradientPos - prev.first) / (next.first - prev.first); - fillColor = (colorToColor4ub(prev.second) * (1 - t) + colorToColor4ub(next.second) * t); - } - - ColorVertex *vertices = (ColorVertex *)fillVertices; - vertices[fillVertexCount].position = QVector2D(rx, y); - vertices[fillVertexCount].color = fillColor; - ++fillVertexCount; - vertices[fillVertexCount].position = QVector2D(lx, y); - vertices[fillVertexCount].color = fillColor; - ++fillVertexCount; - } - py = y; - plx = lx; - prx = rx; - - // Rotate - qreal tmp = c; - c = c * cosStep - s * sinStep; - s = s * cosStep + tmp * sinStep; - } - } - - if (penWidth) { - // Close border. - const Vertex &first = borderVertices[borderVertexHead]; - const Vertex &second = borderVertices[borderVertexHead + 1]; - borderVertices[borderVertexTail++] = first; - borderVertices[borderVertexTail++] = second; - - Q_ASSERT(borderVertexHead == 0 && borderVertexTail == borderGeometry->vertexCount()); - } - Q_ASSERT(fillVertexCount == fill->vertexCount()); - - } else { - - // Straight corners. - QRectF innerRect = m_rect; - QRectF outerRect = m_rect; - - qreal halfPenWidth = 0; - if (penWidth) { - if (m_aligned && (int(penWidth) & 1)) { - // Pen width is odd, so add the offset as documented. - innerRect.moveLeft(innerRect.left() + qreal(0.5)); - innerRect.moveTop(innerRect.top() + qreal(0.5)); - outerRect = innerRect; - } - halfPenWidth = penWidth * qreal(0.5); - innerRect.adjust(halfPenWidth, halfPenWidth, -halfPenWidth, -halfPenWidth); - outerRect.adjust(-halfPenWidth, -halfPenWidth, halfPenWidth, halfPenWidth); - } - - int nextGradientStop = 0; - qreal gradientPos = halfPenWidth / m_rect.height(); - while (nextGradientStop < stops.size() && stops.at(nextGradientStop).first <= gradientPos) - ++nextGradientStop; - int lastGradientStop = stops.size() - 1; - qreal lastGradientPos = (m_rect.height() - halfPenWidth) / m_rect.height(); - while (lastGradientStop >= nextGradientStop && stops.at(lastGradientStop).first >= lastGradientPos) - --lastGradientStop; - - int borderVertexCount = 0; - if (penWidth) { - borderGeometry->allocate((1 + lastGradientStop - nextGradientStop) * 4 + 10); - borderVertices = (Vertex *)borderGeometry->vertexData(); - } - fill->allocate((3 + lastGradientStop - nextGradientStop) * 2); - fillVertices = (uchar *)fill->vertexData(); - - QVarLengthArray<qreal, 16> ys(3 + lastGradientStop - nextGradientStop); - int yCount = 0; - - for (int part = 0; part < 2; ++part) { - qreal y = (part ? innerRect.bottom() : innerRect.top()); - gradientPos = (y - innerRect.top() + halfPenWidth) / m_rect.height(); - - while (nextGradientStop <= lastGradientStop && stops.at(nextGradientStop).first <= gradientPos) { - // Insert vertices at gradient stops. - qreal gy = (innerRect.top() - halfPenWidth) + stops.at(nextGradientStop).first * m_rect.height(); - Q_ASSERT(fillVertexCount >= 2); - - ColorVertex *vertices = (ColorVertex *)fillVertices; - - fillColor = colorToColor4ub(stops.at(nextGradientStop).second); - vertices[fillVertexCount].position = QVector2D(innerRect.right(), gy); - vertices[fillVertexCount].color = fillColor; - ++fillVertexCount; - vertices[fillVertexCount].position = QVector2D(innerRect.left(), gy); - vertices[fillVertexCount].color = fillColor; - ++fillVertexCount; - - ys[yCount++] = gy; - - ++nextGradientStop; - } - - if (stops.isEmpty()) { - Q_ASSERT(m_material_type == TypeFlat); - Vertex *vertices = (Vertex *)fillVertices; - vertices[fillVertexCount++].position = QVector2D(innerRect.right(), y); - vertices[fillVertexCount++].position = QVector2D(innerRect.left(), y); - } else { - if (nextGradientStop == 0) { - fillColor = colorToColor4ub(stops.at(0).second); - } else if (nextGradientStop == stops.size()) { - fillColor = colorToColor4ub(stops.last().second); - } else { - const QGradientStop &prev = stops.at(nextGradientStop - 1); - const QGradientStop &next = stops.at(nextGradientStop); - qreal t = (gradientPos - prev.first) / (next.first - prev.first); - fillColor = (colorToColor4ub(prev.second) * (1 - t) + colorToColor4ub(next.second) * t); - } - - ColorVertex *vertices = (ColorVertex *)fillVertices; - vertices[fillVertexCount].position = QVector2D(innerRect.right(), y); - vertices[fillVertexCount].color = fillColor; - ++fillVertexCount; - vertices[fillVertexCount].position = QVector2D(innerRect.left(), y); - vertices[fillVertexCount].color = fillColor; - ++fillVertexCount; - } - - ys[yCount++] = y; - } - - if (penWidth) { - borderVertices[borderVertexCount++].position = QVector2D(outerRect.right(), outerRect.top()); - borderVertices[borderVertexCount++].position = QVector2D(innerRect.right(), ys[0]); - for (int i = 1; i < fillVertexCount / 2; ++i) { - borderVertices[borderVertexCount++].position = QVector2D(outerRect.right(), outerRect.bottom()); - borderVertices[borderVertexCount++].position = QVector2D(innerRect.right(), ys[i]); - } - - borderVertices[borderVertexCount++].position = QVector2D(outerRect.left(), outerRect.bottom()); - borderVertices[borderVertexCount++].position = QVector2D(innerRect.left(), ys[fillVertexCount / 2 - 1]); - for (int i = fillVertexCount / 2 - 2; i >= 0; --i) { - borderVertices[borderVertexCount++].position = QVector2D(outerRect.left(), outerRect.top()); - borderVertices[borderVertexCount++].position = QVector2D(innerRect.left(), ys[i]); - } - - borderVertices[borderVertexCount++].position = QVector2D(outerRect.right(), outerRect.top()); - borderVertices[borderVertexCount++].position = QVector2D(innerRect.right(), innerRect.top()); - - Q_ASSERT(borderVertexCount == borderGeometry->vertexCount()); - } - Q_ASSERT(fillVertexCount == fill->vertexCount()); - } - - markDirty(DirtyGeometry); -} - - -QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/qsgdefaultrectanglenode_p.h b/src/declarative/scenegraph/qsgdefaultrectanglenode_p.h deleted file mode 100644 index 6a197136cf..0000000000 --- a/src/declarative/scenegraph/qsgdefaultrectanglenode_p.h +++ /dev/null @@ -1,108 +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 DEFAULT_RECTANGLENODE_H -#define DEFAULT_RECTANGLENODE_H - -#include <private/qsgadaptationlayer_p.h> - -#include "qsgflatcolormaterial.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class QSGMaterial; -class QSGContext; - -class QSGDefaultRectangleNode : public QSGRectangleNode -{ -public: - QSGDefaultRectangleNode(QSGContext *context); - ~QSGDefaultRectangleNode(); - - virtual void setRect(const QRectF &rect); - virtual void setColor(const QColor &color); - virtual void setPenColor(const QColor &color); - virtual void setPenWidth(qreal width); - virtual void setGradientStops(const QGradientStops &stops); - virtual void setRadius(qreal radius); - virtual void setAligned(bool aligned); - virtual void update(); - -private: - enum { - TypeFlat, - TypeVertexGradient - }; - QSGGeometryNode *border(); - - void updateGeometry(); - void updateGradientTexture(); - - QSGGeometryNode *m_border; - QSGFlatColorMaterial m_border_material; - QSGFlatColorMaterial m_fill_material; - - QRectF m_rect; - QGradientStops m_gradient_stops; - qreal m_radius; - qreal m_pen_width; - - uint m_aligned : 1; - uint m_gradient_is_opaque : 1; - uint m_dirty_geometry : 1; - - uint m_material_type : 2; // Only goes up to 3 - - QSGGeometry m_default_geometry; - - QSGContext *m_context; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/declarative/scenegraph/qsgdistancefieldglyphnode.cpp b/src/declarative/scenegraph/qsgdistancefieldglyphnode.cpp deleted file mode 100644 index e4a39e484b..0000000000 --- a/src/declarative/scenegraph/qsgdistancefieldglyphnode.cpp +++ /dev/null @@ -1,316 +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 "qsgdistancefieldglyphnode_p.h" -#include "qsgdistancefieldglyphnode_p_p.h" -#include <private/qsgdistancefieldutil_p.h> -#include <private/qsgcontext_p.h> - -QT_BEGIN_NAMESPACE - -QSGDistanceFieldGlyphNode::QSGDistanceFieldGlyphNode(QSGDistanceFieldGlyphCacheManager *cacheManager) - : m_material(0) - , m_glyph_cacheManager(cacheManager) - , m_glyph_cache(0) - , m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 0) - , m_style(QQuickText::Normal) - , m_antialiasingMode(GrayAntialiasing) - , m_dirtyGeometry(false) - , m_dirtyMaterial(false) -{ - m_geometry.setDrawingMode(GL_TRIANGLES); - setGeometry(&m_geometry); - setPreferredAntialiasingMode(cacheManager->defaultAntialiasingMode()); -#ifdef QML_RUNTIME_TESTING - description = QLatin1String("glyphs"); -#endif -} - -QSGDistanceFieldGlyphNode::~QSGDistanceFieldGlyphNode() -{ - delete m_material; - if (m_glyph_cache) { - m_glyph_cache->release(m_glyphs.glyphIndexes()); - m_glyph_cache->unregisterGlyphNode(this); - } -} - -void QSGDistanceFieldGlyphNode::setColor(const QColor &color) -{ - m_color = color; - if (m_material != 0) { - m_material->setColor(color); - markDirty(DirtyMaterial); - } -} - -void QSGDistanceFieldGlyphNode::setPreferredAntialiasingMode(AntialiasingMode mode) -{ - if (mode == m_antialiasingMode) - return; - m_antialiasingMode = mode; - m_dirtyMaterial = true; -} - -void QSGDistanceFieldGlyphNode::setGlyphs(const QPointF &position, const QGlyphRun &glyphs) -{ - QRawFont font = glyphs.rawFont(); - m_position = QPointF(position.x(), position.y() - font.ascent()); - m_glyphs = glyphs; - - QSGDistanceFieldGlyphCache *oldCache = m_glyph_cache; - m_glyph_cache = m_glyph_cacheManager->cache(m_glyphs.rawFont()); - if (m_glyph_cache != oldCache) { - if (oldCache) - oldCache->unregisterGlyphNode(this); - m_glyph_cache->registerGlyphNode(this); - } - m_glyph_cache->populate(glyphs.glyphIndexes()); - - const QVector<quint32> &glyphIndexes = m_glyphs.glyphIndexes(); - const QVector<QPointF> &glyphPositions = m_glyphs.positions(); - for (int i = 0; i < glyphIndexes.size(); ++i) { - GlyphInfo g; - g.glyphIndex = glyphIndexes.at(i); - g.position = glyphPositions.at(i); - m_glyphsToAdd.append(g); - } - - m_dirtyGeometry = true; - m_dirtyMaterial = true; -} - -void QSGDistanceFieldGlyphNode::setStyle(QQuickText::TextStyle style) -{ - if (m_style == style) - return; - m_style = style; - m_dirtyMaterial = true; -} - -void QSGDistanceFieldGlyphNode::setStyleColor(const QColor &color) -{ - if (m_styleColor == color) - return; - m_styleColor = color; - m_dirtyMaterial = true; -} - -void QSGDistanceFieldGlyphNode::update() -{ - if (m_dirtyMaterial) - updateMaterial(); - if (m_dirtyGeometry) - updateGeometry(); -} - -void QSGDistanceFieldGlyphNode::updateGeometry() -{ - Q_ASSERT(m_glyph_cache); - - if (m_glyphsToAdd.isEmpty()) - return; - - QSGGeometry *g = geometry(); - - Q_ASSERT(g->indexType() == GL_UNSIGNED_SHORT); - - int oldVertexCount = g->vertexCount(); - int oldIndexCount = g->indexCount(); - - QVector<QSGGeometry::TexturedPoint2D> vp; - vp.reserve(m_glyphsToAdd.size() * 4); - QVector<ushort> ip; - ip.reserve(m_glyphsToAdd.size() * 6); - - QPointF margins(2, 2); - QPointF texMargins = margins / m_glyph_cache->fontScale(); - - const QSGDistanceFieldGlyphCache::Texture *textureToUse = 0; - - QLinkedList<GlyphInfo>::iterator it = m_glyphsToAdd.begin(); - while (it != m_glyphsToAdd.end()) { - quint32 glyphIndex = it->glyphIndex; - QSGDistanceFieldGlyphCache::TexCoord c = m_glyph_cache->glyphTexCoord(glyphIndex); - - if (c.isNull()) { - if (!c.isValid()) - ++it; - else - it = m_glyphsToAdd.erase(it); - continue; - } - - const QSGDistanceFieldGlyphCache::Texture *texture = m_glyph_cache->glyphTexture(glyphIndex); - if (!texture->textureId) { - ++it; - continue; - } - - QSGDistanceFieldGlyphCache::Metrics metrics = m_glyph_cache->glyphMetrics(glyphIndex); - - if (!textureToUse) - textureToUse = texture; - - metrics.width += margins.x() * 2; - metrics.height += margins.y() * 2; - metrics.baselineX -= margins.x(); - metrics.baselineY += margins.y(); - c.xMargin -= texMargins.x(); - c.yMargin -= texMargins.y(); - c.width += texMargins.x() * 2; - c.height += texMargins.y() * 2; - - const QPointF &glyphPosition = it->position; - qreal x = glyphPosition.x() + metrics.baselineX + m_position.x(); - qreal y = glyphPosition.y() - metrics.baselineY + m_position.y(); - - m_boundingRect |= QRectF(x, y, metrics.width, metrics.height); - - float cx1 = x; - float cx2 = x + metrics.width; - float cy1 = y; - float cy2 = y + metrics.height; - - float tx1 = c.x + c.xMargin; - float tx2 = tx1 + c.width; - float ty1 = c.y + c.yMargin; - float ty2 = ty1 + c.height; - - if (m_baseLine.isNull()) - m_baseLine = glyphPosition; - - int i = vp.size(); - - QSGGeometry::TexturedPoint2D v1; - v1.set(cx1, cy1, tx1, ty1); - QSGGeometry::TexturedPoint2D v2; - v2.set(cx2, cy1, tx2, ty1); - QSGGeometry::TexturedPoint2D v3; - v3.set(cx1, cy2, tx1, ty2); - QSGGeometry::TexturedPoint2D v4; - v4.set(cx2, cy2, tx2, ty2); - vp.append(v1); - vp.append(v2); - vp.append(v3); - vp.append(v4); - - int o = i + oldVertexCount; - ip.append(o + 0); - ip.append(o + 2); - ip.append(o + 3); - ip.append(o + 3); - ip.append(o + 1); - ip.append(o + 0); - - it = m_glyphsToAdd.erase(it); - } - - if (vp.isEmpty()) - return; - - void *data = 0; - if (oldVertexCount && oldIndexCount) { - int byteSize = oldVertexCount * sizeof(QSGGeometry::TexturedPoint2D) - + oldIndexCount * sizeof(quint16); - data = qMalloc(byteSize); - memcpy(data, g->vertexData(), byteSize); - } - - g->allocate(oldVertexCount + vp.size(), oldIndexCount + ip.size()); - - if (data) { - memcpy(g->vertexData(), data, oldVertexCount * sizeof(QSGGeometry::TexturedPoint2D)); - memcpy(g->indexData(), ((char *) data) + oldVertexCount * sizeof(QSGGeometry::TexturedPoint2D), - oldIndexCount * sizeof(quint16)); - qFree(data); - } - - memcpy(g->vertexDataAsTexturedPoint2D() + oldVertexCount, vp.constData(), vp.size() * sizeof(QSGGeometry::TexturedPoint2D)); - memcpy(g->indexDataAsUShort() + oldIndexCount, ip.constData(), ip.size() * sizeof(quint16)); - - setBoundingRect(m_boundingRect); - markDirty(DirtyGeometry); - m_dirtyGeometry = false; - - m_material->setTexture(textureToUse); -} - -void QSGDistanceFieldGlyphNode::updateMaterial() -{ - delete m_material; - - if (m_style == QQuickText::Normal) { - switch (m_antialiasingMode) { - case HighQualitySubPixelAntialiasing: - m_material = new QSGHiQSubPixelDistanceFieldTextMaterial; - break; - case LowQualitySubPixelAntialiasing: - m_material = new QSGLoQSubPixelDistanceFieldTextMaterial; - break; - case GrayAntialiasing: - default: - m_material = new QSGDistanceFieldTextMaterial; - break; - } - } else { - QSGDistanceFieldStyledTextMaterial *material; - if (m_style == QQuickText::Outline) { - material = new QSGDistanceFieldOutlineTextMaterial; - } else { - QSGDistanceFieldShiftedStyleTextMaterial *sMaterial = new QSGDistanceFieldShiftedStyleTextMaterial; - if (m_style == QQuickText::Raised) - sMaterial->setShift(QPointF(0.0, 1.0)); - else - sMaterial->setShift(QPointF(0.0, -1.0)); - material = sMaterial; - } - material->setStyleColor(m_styleColor); - m_material = material; - } - - m_material->setGlyphCache(m_glyph_cache); - m_material->setColor(m_color); - setMaterial(m_material); - m_dirtyMaterial = false; -} - -QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/qsgdistancefieldglyphnode_p.cpp b/src/declarative/scenegraph/qsgdistancefieldglyphnode_p.cpp deleted file mode 100644 index a506e23cc1..0000000000 --- a/src/declarative/scenegraph/qsgdistancefieldglyphnode_p.cpp +++ /dev/null @@ -1,725 +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 "qsgdistancefieldglyphnode_p_p.h" -#include <private/qsgdistancefieldutil_p.h> -#include <private/qsgtexture_p.h> -#include <QtGui/qopenglfunctions.h> -#include <qmath.h> - -QT_BEGIN_NAMESPACE - -class QSGDistanceFieldTextMaterialShader : public QSGMaterialShader -{ -public: - QSGDistanceFieldTextMaterialShader(); - - virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect); - virtual char const *const *attributeNames() const; - -protected: - virtual void initialize(); - virtual const char *vertexShader() const; - virtual const char *fragmentShader() const; - - void updateAlphaRange(ThresholdFunc thresholdFunc, AntialiasingSpreadFunc spreadFunc); - - float m_fontScale; - float m_matrixScale; - - int m_matrix_id; - int m_textureScale_id; - int m_alphaMin_id; - int m_alphaMax_id; - int m_color_id; -}; - -const char *QSGDistanceFieldTextMaterialShader::vertexShader() const { - return - "uniform highp mat4 matrix; \n" - "uniform highp vec2 textureScale; \n" - "attribute highp vec4 vCoord; \n" - "attribute highp vec2 tCoord; \n" - "varying highp vec2 sampleCoord; \n" - "void main() { \n" - " sampleCoord = tCoord * textureScale; \n" - " gl_Position = matrix * vCoord; \n" - "}"; -} - -const char *QSGDistanceFieldTextMaterialShader::fragmentShader() const { - return - "varying highp vec2 sampleCoord; \n" - "uniform sampler2D texture; \n" - "uniform lowp vec4 color; \n" - "uniform highp float alphaMin; \n" - "uniform highp float alphaMax; \n" - "void main() { \n" - " gl_FragColor = color * smoothstep(alphaMin, \n" - " alphaMax, \n" - " texture2D(texture, sampleCoord).a); \n" - "}"; -} - -char const *const *QSGDistanceFieldTextMaterialShader::attributeNames() const { - static char const *const attr[] = { "vCoord", "tCoord", 0 }; - return attr; -} - -QSGDistanceFieldTextMaterialShader::QSGDistanceFieldTextMaterialShader() - : m_fontScale(1.0) - , m_matrixScale(1.0) -{ -} - -void QSGDistanceFieldTextMaterialShader::updateAlphaRange(ThresholdFunc thresholdFunc, AntialiasingSpreadFunc spreadFunc) -{ - float combinedScale = m_fontScale * m_matrixScale; - float base = thresholdFunc(combinedScale); - float range = spreadFunc(combinedScale); - - float alphaMin = qMax(0.0f, base - range); - float alphaMax = qMin(base + range, 1.0f); - program()->setUniformValue(m_alphaMin_id, GLfloat(alphaMin)); - program()->setUniformValue(m_alphaMax_id, GLfloat(alphaMax)); -} - -void QSGDistanceFieldTextMaterialShader::initialize() -{ - QSGMaterialShader::initialize(); - m_matrix_id = program()->uniformLocation("matrix"); - m_textureScale_id = program()->uniformLocation("textureScale"); - m_color_id = program()->uniformLocation("color"); - m_alphaMin_id = program()->uniformLocation("alphaMin"); - m_alphaMax_id = program()->uniformLocation("alphaMax"); -} - -void QSGDistanceFieldTextMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) -{ - Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type()); - QSGDistanceFieldTextMaterial *material = static_cast<QSGDistanceFieldTextMaterial *>(newEffect); - QSGDistanceFieldTextMaterial *oldMaterial = static_cast<QSGDistanceFieldTextMaterial *>(oldEffect); - - bool updated = material->updateCache(); - - if (oldMaterial == 0 - || material->color() != oldMaterial->color() - || state.isOpacityDirty()) { - QVector4D color(material->color().redF(), material->color().greenF(), - material->color().blueF(), material->color().alphaF()); - color *= state.opacity(); - program()->setUniformValue(m_color_id, color); - } - - bool updateRange = false; - if (oldMaterial == 0 - || material->glyphCache()->fontScale() != oldMaterial->glyphCache()->fontScale()) { - m_fontScale = material->glyphCache()->fontScale(); - updateRange = true; - } - if (state.isMatrixDirty()) { - program()->setUniformValue(m_matrix_id, state.combinedMatrix()); - m_matrixScale = qSqrt(qAbs(state.modelViewMatrix().determinant())); - updateRange = true; - } - if (updateRange) { - updateAlphaRange(material->glyphCache()->manager()->thresholdFunc(), - material->glyphCache()->manager()->antialiasingSpreadFunc()); - } - - Q_ASSERT(material->glyphCache()); - - if (updated - || oldMaterial == 0 - || oldMaterial->texture()->textureId != material->texture()->textureId) { - program()->setUniformValue(m_textureScale_id, QVector2D(1.0 / material->textureSize().width(), - 1.0 / material->textureSize().height())); - glBindTexture(GL_TEXTURE_2D, material->texture()->textureId); - - if (updated) { - // Set the mag/min filters to be linear. We only need to do this when the texture - // has been recreated. - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - } - } -} - -QSGDistanceFieldTextMaterial::QSGDistanceFieldTextMaterial() - : m_glyph_cache(0) - , m_texture(0) -{ - setFlag(Blending, true); -} - -QSGDistanceFieldTextMaterial::~QSGDistanceFieldTextMaterial() -{ -} - -QSGMaterialType *QSGDistanceFieldTextMaterial::type() const -{ - static QSGMaterialType type; - return &type; -} - -QSGMaterialShader *QSGDistanceFieldTextMaterial::createShader() const -{ - return new QSGDistanceFieldTextMaterialShader; -} - -bool QSGDistanceFieldTextMaterial::updateCache() -{ - m_glyph_cache->update(); - if (!m_texture) - m_texture = m_glyph_cache->glyphTexture(-1); // invalid texture - QSize glyphCacheSize = m_texture->size; - if (glyphCacheSize != m_size) { - m_size = glyphCacheSize; - - return true; - } else { - return false; - } -} - -int QSGDistanceFieldTextMaterial::compare(const QSGMaterial *o) const -{ - Q_ASSERT(o && type() == o->type()); - const QSGDistanceFieldTextMaterial *other = static_cast<const QSGDistanceFieldTextMaterial *>(o); - if (m_glyph_cache != other->m_glyph_cache) - return m_glyph_cache - other->m_glyph_cache; - if (m_glyph_cache->fontScale() != other->m_glyph_cache->fontScale()) { - qreal s1 = m_glyph_cache->fontScale(); - qreal s2 = other->m_glyph_cache->fontScale(); - return int(s2 < s1) - int(s1 < s2); - } - QRgb c1 = m_color.rgba(); - QRgb c2 = other->m_color.rgba(); - return int(c2 < c1) - int(c1 < c2); -} - - -class DistanceFieldStyledTextMaterialShader : public QSGDistanceFieldTextMaterialShader -{ -public: - DistanceFieldStyledTextMaterialShader(); - - virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect); - -protected: - virtual void initialize(); - virtual const char *fragmentShader() const = 0; - - int m_styleColor_id; -}; - -DistanceFieldStyledTextMaterialShader::DistanceFieldStyledTextMaterialShader() - : QSGDistanceFieldTextMaterialShader() -{ -} - -void DistanceFieldStyledTextMaterialShader::initialize() -{ - QSGDistanceFieldTextMaterialShader::initialize(); - m_styleColor_id = program()->uniformLocation("styleColor"); -} - -void DistanceFieldStyledTextMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) -{ - QSGDistanceFieldTextMaterialShader::updateState(state, newEffect, oldEffect); - - QSGDistanceFieldStyledTextMaterial *material = static_cast<QSGDistanceFieldStyledTextMaterial *>(newEffect); - QSGDistanceFieldStyledTextMaterial *oldMaterial = static_cast<QSGDistanceFieldStyledTextMaterial *>(oldEffect); - - if (oldMaterial == 0 - || material->styleColor() != oldMaterial->styleColor() - || (state.isOpacityDirty())) { - QVector4D color(material->styleColor().redF(), material->styleColor().greenF(), - material->styleColor().blueF(), material->styleColor().alphaF()); - color *= state.opacity(); - program()->setUniformValue(m_styleColor_id, color); - } -} - -QSGDistanceFieldStyledTextMaterial::QSGDistanceFieldStyledTextMaterial() - : QSGDistanceFieldTextMaterial() -{ -} - -QSGDistanceFieldStyledTextMaterial::~QSGDistanceFieldStyledTextMaterial() -{ -} - -int QSGDistanceFieldStyledTextMaterial::compare(const QSGMaterial *o) const -{ - Q_ASSERT(o && type() == o->type()); - const QSGDistanceFieldStyledTextMaterial *other = static_cast<const QSGDistanceFieldStyledTextMaterial *>(o); - if (m_styleColor != other->m_styleColor) { - QRgb c1 = m_styleColor.rgba(); - QRgb c2 = other->m_styleColor.rgba(); - return int(c2 < c1) - int(c1 < c2); - } - return QSGDistanceFieldTextMaterial::compare(o); -} - - -class DistanceFieldOutlineTextMaterialShader : public DistanceFieldStyledTextMaterialShader -{ -public: - DistanceFieldOutlineTextMaterialShader(); - - virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect); - -protected: - virtual void initialize(); - virtual const char *fragmentShader() const; - - void updateOutlineAlphaRange(int dfRadius); - - int m_outlineAlphaMax0_id; - int m_outlineAlphaMax1_id; -}; - -const char *DistanceFieldOutlineTextMaterialShader::fragmentShader() const { - return - "varying highp vec2 sampleCoord; \n" - "uniform sampler2D texture; \n" - "uniform lowp vec4 color; \n" - "uniform lowp vec4 styleColor; \n" - "uniform highp float alphaMin; \n" - "uniform highp float alphaMax; \n" - "uniform highp float outlineAlphaMax0; \n" - "uniform highp float outlineAlphaMax1; \n" - "void main() { \n" - " mediump float d = texture2D(texture, sampleCoord).a; \n" - " gl_FragColor = mix(styleColor, color, smoothstep(alphaMin, alphaMax, d)) \n" - " * smoothstep(outlineAlphaMax0, outlineAlphaMax1, d); \n" - "}"; -} - -DistanceFieldOutlineTextMaterialShader::DistanceFieldOutlineTextMaterialShader() - : DistanceFieldStyledTextMaterialShader() -{ -} - -void DistanceFieldOutlineTextMaterialShader::initialize() -{ - DistanceFieldStyledTextMaterialShader::initialize(); - m_outlineAlphaMax0_id = program()->uniformLocation("outlineAlphaMax0"); - m_outlineAlphaMax1_id = program()->uniformLocation("outlineAlphaMax1"); -} - -void DistanceFieldOutlineTextMaterialShader::updateOutlineAlphaRange(int dfRadius) -{ - qreal outlineLimit = qMax(qreal(0.2), qreal(0.5 - 0.5 / dfRadius / m_fontScale)); - - qreal combinedScale = m_fontScale * m_matrixScale; - qreal alphaMin = qMax(0.0, 0.5 - 0.07 / combinedScale); - qreal styleAlphaMin0 = qMax(0.0, outlineLimit - 0.07 / combinedScale); - qreal styleAlphaMin1 = qMin(qreal(outlineLimit + 0.07 / combinedScale), alphaMin); - program()->setUniformValue(m_outlineAlphaMax0_id, GLfloat(styleAlphaMin0)); - program()->setUniformValue(m_outlineAlphaMax1_id, GLfloat(styleAlphaMin1)); -} - -void DistanceFieldOutlineTextMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) -{ - DistanceFieldStyledTextMaterialShader::updateState(state, newEffect, oldEffect); - - QSGDistanceFieldOutlineTextMaterial *material = static_cast<QSGDistanceFieldOutlineTextMaterial *>(newEffect); - QSGDistanceFieldOutlineTextMaterial *oldMaterial = static_cast<QSGDistanceFieldOutlineTextMaterial *>(oldEffect); - - if (oldMaterial == 0 - || material->glyphCache()->fontScale() != oldMaterial->glyphCache()->fontScale() - || state.isMatrixDirty()) - updateOutlineAlphaRange(material->glyphCache()->distanceFieldRadius()); -} - - -QSGDistanceFieldOutlineTextMaterial::QSGDistanceFieldOutlineTextMaterial() - : QSGDistanceFieldStyledTextMaterial() -{ -} - -QSGDistanceFieldOutlineTextMaterial::~QSGDistanceFieldOutlineTextMaterial() -{ -} - -QSGMaterialType *QSGDistanceFieldOutlineTextMaterial::type() const -{ - static QSGMaterialType type; - return &type; -} - -QSGMaterialShader *QSGDistanceFieldOutlineTextMaterial::createShader() const -{ - return new DistanceFieldOutlineTextMaterialShader; -} - - -class DistanceFieldShiftedStyleTextMaterialShader : public DistanceFieldStyledTextMaterialShader -{ -public: - DistanceFieldShiftedStyleTextMaterialShader(); - - virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect); - -protected: - virtual void initialize(); - virtual const char *vertexShader() const; - virtual const char *fragmentShader() const; - - void updateShift(const QSGDistanceFieldGlyphCache *cache, const QPointF& shift); - - int m_shift_id; -}; - -DistanceFieldShiftedStyleTextMaterialShader::DistanceFieldShiftedStyleTextMaterialShader() - : DistanceFieldStyledTextMaterialShader() -{ -} - -void DistanceFieldShiftedStyleTextMaterialShader::initialize() -{ - DistanceFieldStyledTextMaterialShader::initialize(); - m_shift_id = program()->uniformLocation("shift"); -} - -void DistanceFieldShiftedStyleTextMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) -{ - DistanceFieldStyledTextMaterialShader::updateState(state, newEffect, oldEffect); - - QSGDistanceFieldShiftedStyleTextMaterial *material = static_cast<QSGDistanceFieldShiftedStyleTextMaterial *>(newEffect); - QSGDistanceFieldShiftedStyleTextMaterial *oldMaterial = static_cast<QSGDistanceFieldShiftedStyleTextMaterial *>(oldEffect); - - if (oldMaterial == 0 - || oldMaterial->glyphCache()->fontScale() != material->glyphCache()->fontScale() - || oldMaterial->shift() != material->shift() - || oldMaterial->textureSize() != material->textureSize()) { - updateShift(material->glyphCache(), material->shift()); - } -} - -void DistanceFieldShiftedStyleTextMaterialShader::updateShift(const QSGDistanceFieldGlyphCache *cache, const QPointF &shift) -{ - QPointF texel(1.0 / cache->fontScale() * shift.x(), - 1.0 / cache->fontScale() * shift.y()); - program()->setUniformValue(m_shift_id, texel); -} - -const char *DistanceFieldShiftedStyleTextMaterialShader::vertexShader() const -{ - return - "uniform highp mat4 matrix; \n" - "uniform highp vec2 textureScale; \n" - "attribute highp vec4 vCoord; \n" - "attribute highp vec2 tCoord; \n" - "uniform highp vec2 shift; \n" - "varying highp vec2 sampleCoord; \n" - "varying highp vec2 shiftedSampleCoord; \n" - "void main() { \n" - " sampleCoord = tCoord * textureScale; \n" - " shiftedSampleCoord = (tCoord - shift) * textureScale; \n" - " gl_Position = matrix * vCoord; \n" - "}"; -} - -const char *DistanceFieldShiftedStyleTextMaterialShader::fragmentShader() const { - return - "varying highp vec2 sampleCoord; \n" - "varying highp vec2 shiftedSampleCoord; \n" - "uniform sampler2D texture; \n" - "uniform lowp vec4 color; \n" - "uniform lowp vec4 styleColor; \n" - "uniform highp float alphaMin; \n" - "uniform highp float alphaMax; \n" - "void main() { \n" - " highp float a = smoothstep(alphaMin, alphaMax, texture2D(texture, sampleCoord).a);\n" - " highp vec4 shifted = styleColor * smoothstep(alphaMin, \n" - " alphaMax, \n" - " texture2D(texture, shiftedSampleCoord).a); \n" - " gl_FragColor = mix(shifted, color, a); \n" - "}"; -} - -QSGDistanceFieldShiftedStyleTextMaterial::QSGDistanceFieldShiftedStyleTextMaterial() - : QSGDistanceFieldStyledTextMaterial() -{ -} - -QSGDistanceFieldShiftedStyleTextMaterial::~QSGDistanceFieldShiftedStyleTextMaterial() -{ -} - -QSGMaterialType *QSGDistanceFieldShiftedStyleTextMaterial::type() const -{ - static QSGMaterialType type; - return &type; -} - -QSGMaterialShader *QSGDistanceFieldShiftedStyleTextMaterial::createShader() const -{ - return new DistanceFieldShiftedStyleTextMaterialShader; -} - - -class QSGHiQSubPixelDistanceFieldTextMaterialShader : public QSGDistanceFieldTextMaterialShader -{ -public: - virtual void initialize(); - virtual void activate(); - virtual void deactivate(); - virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect); - -protected: - virtual const char *vertexShader() const; - virtual const char *fragmentShader() const; - -private: - int m_fontScale_id; - int m_vecDelta_id; -}; - -const char *QSGHiQSubPixelDistanceFieldTextMaterialShader::vertexShader() const { - return - "uniform highp mat4 matrix; \n" - "uniform highp vec2 textureScale; \n" - "uniform highp float fontScale; \n" - "uniform highp vec4 vecDelta; \n" - "attribute highp vec4 vCoord; \n" - "attribute highp vec2 tCoord; \n" - "varying highp vec2 sampleCoord; \n" - "varying highp vec3 sampleFarLeft; \n" - "varying highp vec3 sampleNearLeft; \n" - "varying highp vec3 sampleNearRight; \n" - "varying highp vec3 sampleFarRight; \n" - "void main() { \n" - " sampleCoord = tCoord * textureScale; \n" - " gl_Position = matrix * vCoord; \n" - // Calculate neighbour pixel position in item space. - " highp vec3 wDelta = gl_Position.w * vecDelta.xyw; \n" - " highp vec3 farLeft = vCoord.xyw - 0.667 * wDelta; \n" - " highp vec3 nearLeft = vCoord.xyw - 0.333 * wDelta; \n" - " highp vec3 nearRight = vCoord.xyw + 0.333 * wDelta; \n" - " highp vec3 farRight = vCoord.xyw + 0.667 * wDelta; \n" - // Calculate neighbour texture coordinate. - " highp vec2 scale = textureScale / fontScale; \n" - " highp vec2 base = sampleCoord - scale * vCoord.xy; \n" - " sampleFarLeft = vec3(base * farLeft.z + scale * farLeft.xy, farLeft.z); \n" - " sampleNearLeft = vec3(base * nearLeft.z + scale * nearLeft.xy, nearLeft.z); \n" - " sampleNearRight = vec3(base * nearRight.z + scale * nearRight.xy, nearRight.z); \n" - " sampleFarRight = vec3(base * farRight.z + scale * farRight.xy, farRight.z); \n" - "}"; -} - -const char *QSGHiQSubPixelDistanceFieldTextMaterialShader::fragmentShader() const { - return - "varying highp vec2 sampleCoord; \n" - "varying highp vec3 sampleFarLeft; \n" - "varying highp vec3 sampleNearLeft; \n" - "varying highp vec3 sampleNearRight; \n" - "varying highp vec3 sampleFarRight; \n" - "uniform sampler2D texture; \n" - "uniform lowp vec4 color; \n" - "uniform highp float alphaMin; \n" - "uniform highp float alphaMax; \n" - "void main() { \n" - " highp vec4 n; \n" - " n.x = texture2DProj(texture, sampleFarLeft).a; \n" - " n.y = texture2DProj(texture, sampleNearLeft).a; \n" - " highp float c = texture2D(texture, sampleCoord).a; \n" - " n.z = texture2DProj(texture, sampleNearRight).a; \n" - " n.w = texture2DProj(texture, sampleFarRight).a; \n" -#if 0 - // Blurrier, faster. - " n = smoothstep(alphaMin, alphaMax, n); \n" - " c = smoothstep(alphaMin, alphaMax, c); \n" -#else - // Sharper, slower. - " highp vec2 d = min(abs(n.yw - n.xz) * 2., 0.67); \n" - " highp vec2 lo = mix(vec2(alphaMin), vec2(0.5), d); \n" - " highp vec2 hi = mix(vec2(alphaMax), vec2(0.5), d); \n" - " n = smoothstep(lo.xxyy, hi.xxyy, n); \n" - " c = smoothstep(lo.x + lo.y, hi.x + hi.y, 2. * c); \n" -#endif - " gl_FragColor = vec4(0.333 * (n.xyz + n.yzw + c), c) * color.w; \n" - "}"; -} - -//const char *QSGHiQSubPixelDistanceFieldTextMaterialShader::fragmentShader() const { -// return -// "#extension GL_OES_standard_derivatives: enable \n" -// "varying highp vec2 sampleCoord; \n" -// "uniform sampler2D texture; \n" -// "uniform lowp vec4 color; \n" -// "uniform highp float alphaMin; \n" -// "uniform highp float alphaMax; \n" -// "void main() { \n" -// " highp vec2 delta = dFdx(sampleCoord); \n" -// " highp vec4 n; \n" -// " n.x = texture2D(texture, sampleCoord - 0.667 * delta).a; \n" -// " n.y = texture2D(texture, sampleCoord - 0.333 * delta).a; \n" -// " highp float c = texture2D(texture, sampleCoord).a; \n" -// " n.z = texture2D(texture, sampleCoord + 0.333 * delta).a; \n" -// " n.w = texture2D(texture, sampleCoord + 0.667 * delta).a; \n" -// " n = smoothstep(alphaMin, alphaMax, n); \n" -// " c = smoothstep(alphaMin, alphaMax, c); \n" -// " gl_FragColor = vec4(0.333 * (n.xyz + n.yzw + c), c) * color.w; \n" -// "}"; -//} - -void QSGHiQSubPixelDistanceFieldTextMaterialShader::initialize() -{ - QSGDistanceFieldTextMaterialShader::initialize(); - m_fontScale_id = program()->uniformLocation("fontScale"); - m_vecDelta_id = program()->uniformLocation("vecDelta"); -} - -void QSGHiQSubPixelDistanceFieldTextMaterialShader::activate() -{ - QSGDistanceFieldTextMaterialShader::activate(); - glBlendFunc(GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR); -} - -void QSGHiQSubPixelDistanceFieldTextMaterialShader::deactivate() -{ - QSGDistanceFieldTextMaterialShader::deactivate(); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); -} - -void QSGHiQSubPixelDistanceFieldTextMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) -{ - Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type()); - QSGDistanceFieldTextMaterial *material = static_cast<QSGDistanceFieldTextMaterial *>(newEffect); - QSGDistanceFieldTextMaterial *oldMaterial = static_cast<QSGDistanceFieldTextMaterial *>(oldEffect); - - if (oldMaterial == 0 || material->color() != oldMaterial->color()) { - QColor c = material->color(); - state.context()->functions()->glBlendColor(c.redF(), c.greenF(), c.blueF(), 1.0f); - } - - if (oldMaterial == 0 || material->glyphCache()->fontScale() != oldMaterial->glyphCache()->fontScale()) - program()->setUniformValue(m_fontScale_id, GLfloat(material->glyphCache()->fontScale())); - - if (oldMaterial == 0 || state.isMatrixDirty()) { - int viewportWidth = state.viewportRect().width(); - QMatrix4x4 mat = state.combinedMatrix().inverted(); - program()->setUniformValue(m_vecDelta_id, mat.column(0) * (qreal(2) / viewportWidth)); - } - - QSGDistanceFieldTextMaterialShader::updateState(state, newEffect, oldEffect); -} - -QSGMaterialType *QSGHiQSubPixelDistanceFieldTextMaterial::type() const -{ - static QSGMaterialType type; - return &type; -} - -QSGMaterialShader *QSGHiQSubPixelDistanceFieldTextMaterial::createShader() const -{ - return new QSGHiQSubPixelDistanceFieldTextMaterialShader; -} - - -class QSGLoQSubPixelDistanceFieldTextMaterialShader : public QSGHiQSubPixelDistanceFieldTextMaterialShader -{ -protected: - virtual const char *vertexShader() const; - virtual const char *fragmentShader() const; -}; - -const char *QSGLoQSubPixelDistanceFieldTextMaterialShader::vertexShader() const { - return - "uniform highp mat4 matrix; \n" - "uniform highp vec2 textureScale; \n" - "uniform highp float fontScale; \n" - "uniform highp vec4 vecDelta; \n" - "attribute highp vec4 vCoord; \n" - "attribute highp vec2 tCoord; \n" - "varying highp vec3 sampleNearLeft; \n" - "varying highp vec3 sampleNearRight; \n" - "void main() { \n" - " highp vec2 sampleCoord = tCoord * textureScale; \n" - " gl_Position = matrix * vCoord; \n" - // Calculate neighbour pixel position in item space. - " highp vec3 wDelta = gl_Position.w * vecDelta.xyw; \n" - " highp vec3 nearLeft = vCoord.xyw - 0.25 * wDelta; \n" - " highp vec3 nearRight = vCoord.xyw + 0.25 * wDelta; \n" - // Calculate neighbour texture coordinate. - " highp vec2 scale = textureScale / fontScale; \n" - " highp vec2 base = sampleCoord - scale * vCoord.xy; \n" - " sampleNearLeft = vec3(base * nearLeft.z + scale * nearLeft.xy, nearLeft.z); \n" - " sampleNearRight = vec3(base * nearRight.z + scale * nearRight.xy, nearRight.z); \n" - "}"; -} - -const char *QSGLoQSubPixelDistanceFieldTextMaterialShader::fragmentShader() const { - return - "varying highp vec3 sampleNearLeft; \n" - "varying highp vec3 sampleNearRight; \n" - "uniform sampler2D texture; \n" - "uniform lowp vec4 color; \n" - "uniform highp float alphaMin; \n" - "uniform highp float alphaMax; \n" - "void main() { \n" - " highp vec2 n; \n" - " n.x = texture2DProj(texture, sampleNearLeft).a; \n" - " n.y = texture2DProj(texture, sampleNearRight).a; \n" - " n = smoothstep(alphaMin, alphaMax, n); \n" - " highp float c = 0.5 * (n.x + n.y); \n" - " gl_FragColor = vec4(n.x, c, n.y, c) * color.w; \n" - "}"; -} - -QSGMaterialType *QSGLoQSubPixelDistanceFieldTextMaterial::type() const -{ - static QSGMaterialType type; - return &type; -} - -QSGMaterialShader *QSGLoQSubPixelDistanceFieldTextMaterial::createShader() const -{ - return new QSGLoQSubPixelDistanceFieldTextMaterialShader; -} - -QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/qsgdistancefieldglyphnode_p.h b/src/declarative/scenegraph/qsgdistancefieldglyphnode_p.h deleted file mode 100644 index f4877b0a1d..0000000000 --- a/src/declarative/scenegraph/qsgdistancefieldglyphnode_p.h +++ /dev/null @@ -1,107 +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 DISTANCEFIELD_GLYPHNODE_H -#define DISTANCEFIELD_GLYPHNODE_H - -#include <private/qsgadaptationlayer_p.h> -#include "qsgtexture.h" - -#include <private/qquicktext_p.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class QSGDistanceFieldGlyphCacheManager; -class QSGDistanceFieldTextMaterial; -class QSGDistanceFieldGlyphNode: public QSGGlyphNode -{ -public: - QSGDistanceFieldGlyphNode(QSGDistanceFieldGlyphCacheManager *cacheManager); - ~QSGDistanceFieldGlyphNode(); - - virtual QPointF baseLine() const { return m_baseLine; } - virtual void setGlyphs(const QPointF &position, const QGlyphRun &glyphs); - virtual void setColor(const QColor &color); - - virtual void setPreferredAntialiasingMode(AntialiasingMode mode); - - virtual void setStyle(QQuickText::TextStyle style); - virtual void setStyleColor(const QColor &color); - - virtual void update(); - - void updateGeometry(); - -private: - void updateMaterial(); - - QColor m_color; - QPointF m_baseLine; - QSGDistanceFieldTextMaterial *m_material; - QPointF m_position; - QGlyphRun m_glyphs; - QSGDistanceFieldGlyphCacheManager *m_glyph_cacheManager; - QSGDistanceFieldGlyphCache *m_glyph_cache; - QSGGeometry m_geometry; - QQuickText::TextStyle m_style; - QColor m_styleColor; - AntialiasingMode m_antialiasingMode; - QRectF m_boundingRect; - - struct GlyphInfo { - quint32 glyphIndex; - QPointF position; - }; - QLinkedList<GlyphInfo> m_glyphsToAdd; - - uint m_dirtyGeometry: 1; - uint m_dirtyMaterial: 1; -}; - -QT_END_HEADER - -QT_END_NAMESPACE - -#endif // DISTANCEFIELD_GLYPHNODE_H diff --git a/src/declarative/scenegraph/qsgdistancefieldglyphnode_p_p.h b/src/declarative/scenegraph/qsgdistancefieldglyphnode_p_p.h deleted file mode 100644 index c8c73bfac0..0000000000 --- a/src/declarative/scenegraph/qsgdistancefieldglyphnode_p_p.h +++ /dev/null @@ -1,140 +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 DISTANCEFIELDTEXTMATERIAL_H -#define DISTANCEFIELDTEXTMATERIAL_H - -#include <qsgmaterial.h> -#include "qsgdistancefieldglyphnode_p.h" -#include "qsgadaptationlayer_p.h" - -QT_BEGIN_NAMESPACE - -class QSGDistanceFieldTextMaterial: public QSGMaterial -{ -public: - QSGDistanceFieldTextMaterial(); - ~QSGDistanceFieldTextMaterial(); - - virtual QSGMaterialType *type() const; - virtual QSGMaterialShader *createShader() const; - virtual int compare(const QSGMaterial *other) const; - - void setColor(const QColor &color) { m_color = color; } - const QColor &color() const { return m_color; } - - void setGlyphCache(QSGDistanceFieldGlyphCache *a) { m_glyph_cache = a; } - QSGDistanceFieldGlyphCache *glyphCache() const { return m_glyph_cache; } - - void setTexture(const QSGDistanceFieldGlyphCache::Texture * tex) { m_texture = tex; } - const QSGDistanceFieldGlyphCache::Texture * texture() const { return m_texture; } - - QSize textureSize() const { return m_size; } - - bool updateCache(); - -protected: - QSize m_size; - QColor m_color; - QSGDistanceFieldGlyphCache *m_glyph_cache; - const QSGDistanceFieldGlyphCache::Texture *m_texture; -}; - -class QSGDistanceFieldStyledTextMaterial : public QSGDistanceFieldTextMaterial -{ -public: - QSGDistanceFieldStyledTextMaterial(); - ~QSGDistanceFieldStyledTextMaterial(); - - virtual QSGMaterialType *type() const = 0; - virtual QSGMaterialShader *createShader() const = 0; - virtual int compare(const QSGMaterial *other) const; - - void setStyleColor(const QColor &color) { m_styleColor = color; } - const QColor &styleColor() const { return m_styleColor; } - -protected: - QColor m_styleColor; -}; - -class QSGDistanceFieldOutlineTextMaterial : public QSGDistanceFieldStyledTextMaterial -{ -public: - QSGDistanceFieldOutlineTextMaterial(); - ~QSGDistanceFieldOutlineTextMaterial(); - - virtual QSGMaterialType *type() const; - virtual QSGMaterialShader *createShader() const; -}; - -class QSGDistanceFieldShiftedStyleTextMaterial : public QSGDistanceFieldStyledTextMaterial -{ -public: - QSGDistanceFieldShiftedStyleTextMaterial(); - ~QSGDistanceFieldShiftedStyleTextMaterial(); - - virtual QSGMaterialType *type() const; - virtual QSGMaterialShader *createShader() const; - - void setShift(const QPointF &shift) { m_shift = shift; } - const QPointF &shift() const { return m_shift; } - -protected: - QPointF m_shift; -}; - -class QSGHiQSubPixelDistanceFieldTextMaterial : public QSGDistanceFieldTextMaterial -{ -public: - virtual QSGMaterialType *type() const; - virtual QSGMaterialShader *createShader() const; -}; - -class QSGLoQSubPixelDistanceFieldTextMaterial : public QSGDistanceFieldTextMaterial -{ -public: - virtual QSGMaterialType *type() const; - virtual QSGMaterialShader *createShader() const; -}; - -QT_END_NAMESPACE - -#endif // DISTANCEFIELDTEXTMATERIAL_H diff --git a/src/declarative/scenegraph/qsgflashnode.cpp b/src/declarative/scenegraph/qsgflashnode.cpp deleted file mode 100644 index 9546e91ee1..0000000000 --- a/src/declarative/scenegraph/qsgflashnode.cpp +++ /dev/null @@ -1,62 +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 "qsgflashnode_p.h" - -QT_BEGIN_NAMESPACE - -QSGFlashNode::QSGFlashNode() - : m_counter(1) -{ - setFlag(UsePreprocess); - setColor(QColor(rand()%56 + 200, rand()%56 + 200, rand()%156 + 100)); // A random, mostly yellow, color -} - -void QSGFlashNode::preprocess() -{ - if (m_counter) { - --m_counter; - } else { - delete this; - } -} - -QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/qsgflashnode_p.h b/src/declarative/scenegraph/qsgflashnode_p.h deleted file mode 100644 index 0967fa8901..0000000000 --- a/src/declarative/scenegraph/qsgflashnode_p.h +++ /dev/null @@ -1,69 +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 QSGFLASHNODE_H -#define QSGFLASHNODE_H - -#include <QSGSimpleRectNode> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class QSGFlashNode : public QSGSimpleRectNode -{ -public: - QSGFlashNode(); - - void preprocess(); - -private: - int m_counter; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QSGFLASHNODE_H - diff --git a/src/declarative/scenegraph/qsgpathsimplifier.cpp b/src/declarative/scenegraph/qsgpathsimplifier.cpp deleted file mode 100644 index 9e851bf434..0000000000 --- a/src/declarative/scenegraph/qsgpathsimplifier.cpp +++ /dev/null @@ -1,1673 +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 "qsgpathsimplifier_p.h" - -#include <QtCore/qvarlengtharray.h> -#include <QtCore/qglobal.h> -#include <QtCore/qpoint.h> -#include <QtCore/qalgorithms.h> - -#include <math.h> - -#include <private/qopengl_p.h> -#include <private/qrbtree_p.h> - -QT_BEGIN_NAMESPACE - -#define Q_FIXED_POINT_SCALE 256 -#define Q_TRIANGULATE_END_OF_POLYGON quint32(-1) - - -namespace { - -//============================================================================// -// QPoint // -//============================================================================// - -inline bool operator < (const QPoint &a, const QPoint &b) -{ - return a.y() < b.y() || (a.y() == b.y() && a.x() < b.x()); -} - -inline bool operator > (const QPoint &a, const QPoint &b) -{ - return b < a; -} - -inline bool operator <= (const QPoint &a, const QPoint &b) -{ - return !(a > b); -} - -inline bool operator >= (const QPoint &a, const QPoint &b) -{ - return !(a < b); -} - -inline int cross(const QPoint &u, const QPoint &v) -{ - return u.x() * v.y() - u.y() * v.x(); -} - -inline int dot(const QPoint &u, const QPoint &v) -{ - return u.x() * v.x() + u.y() * v.y(); -} - -//============================================================================// -// Fraction // -//============================================================================// - -// Fraction must be in the range [0, 1) -struct Fraction -{ - bool isValid() const { return denominator != 0; } - - // numerator and denominator must not have common denominators. - unsigned int numerator, denominator; -}; - -inline unsigned int gcd(unsigned int x, unsigned int y) -{ - while (y != 0) { - unsigned int z = y; - y = x % y; - x = z; - } - return x; -} - -// Fraction must be in the range [0, 1) -// Assume input is valid. -Fraction fraction(unsigned int n, unsigned int d) { - Fraction result; - if (n == 0) { - result.numerator = 0; - result.denominator = 1; - } else { - unsigned int g = gcd(n, d); - result.numerator = n / g; - result.denominator = d / g; - } - return result; -} - -//============================================================================// -// Rational // -//============================================================================// - -struct Rational -{ - bool isValid() const { return fraction.isValid(); } - int integer; - Fraction fraction; -}; - -//============================================================================// -// IntersectionPoint // -//============================================================================// - -struct IntersectionPoint -{ - bool isValid() const { return x.fraction.isValid() && y.fraction.isValid(); } - QPoint round() const; - bool isAccurate() const { return x.fraction.numerator == 0 && y.fraction.numerator == 0; } - - Rational x; // 8:8 signed, 32/32 - Rational y; // 8:8 signed, 32/32 -}; - -QPoint IntersectionPoint::round() const -{ - QPoint result(x.integer, y.integer); - if (2 * x.fraction.numerator >= x.fraction.denominator) - ++result.rx(); - if (2 * y.fraction.numerator >= y.fraction.denominator) - ++result.ry(); - return result; -} - -// Return positive value if 'p' is to the right of the line 'v1'->'v2', negative if left of the -// line and zero if exactly on the line. -// The returned value is the z-component of the qCross product between 'v2-v1' and 'p-v1', -// which is twice the signed area of the triangle 'p'->'v1'->'v2' (positive for CW order). -inline int pointDistanceFromLine(const QPoint &p, const QPoint &v1, const QPoint &v2) -{ - return cross(v2 - v1, p - v1); -} - -IntersectionPoint intersectionPoint(const QPoint &u1, const QPoint &u2, - const QPoint &v1, const QPoint &v2) -{ - IntersectionPoint result = {{0, {0, 0}}, {0, {0, 0}}}; - - QPoint u = u2 - u1; - QPoint v = v2 - v1; - int d1 = cross(u, v1 - u1); - int d2 = cross(u, v2 - u1); - int det = d2 - d1; - int d3 = cross(v, u1 - v1); - int d4 = d3 - det; //qCross(v, u2 - v1); - - // Check that the math is correct. - Q_ASSERT(d4 == cross(v, u2 - v1)); - - // The intersection point can be expressed as: - // v1 - v * d1/det - // v2 - v * d2/det - // u1 + u * d3/det - // u2 + u * d4/det - - // I'm only interested in lines that are crossing, so ignore parallel lines even if they overlap. - if (det == 0) - return result; - - if (det < 0) { - det = -det; - d1 = -d1; - d2 = -d2; - d3 = -d3; - d4 = -d4; - } - - // I'm only interested in lines intersecting at their interior, not at their end points. - // The lines intersect at their interior if and only if 'd1 < 0', 'd2 > 0', 'd3 < 0' and 'd4 > 0'. - if (d1 >= 0 || d2 <= 0 || d3 <= 0 || d4 >= 0) - return result; - - // Calculate the intersection point as follows: - // v1 - v * d1/det | v1 <= v2 (component-wise) - // v2 - v * d2/det | v2 < v1 (component-wise) - - // Assuming 16 bits per vector component. - if (v.x() >= 0) { - result.x.integer = v1.x() + int(qint64(-v.x()) * d1 / det); - result.x.fraction = fraction((unsigned int)(qint64(-v.x()) * d1 % det), (unsigned int)det); - } else { - result.x.integer = v2.x() + int(qint64(-v.x()) * d2 / det); - result.x.fraction = fraction((unsigned int)(qint64(-v.x()) * d2 % det), (unsigned int)det); - } - - if (v.y() >= 0) { - result.y.integer = v1.y() + int(qint64(-v.y()) * d1 / det); - result.y.fraction = fraction((unsigned int)(qint64(-v.y()) * d1 % det), (unsigned int)det); - } else { - result.y.integer = v2.y() + int(qint64(-v.y()) * d2 / det); - result.y.fraction = fraction((unsigned int)(qint64(-v.y()) * d2 % det), (unsigned int)det); - } - - Q_ASSERT(result.x.fraction.isValid()); - Q_ASSERT(result.y.fraction.isValid()); - return result; -} - -//============================================================================// -// PathSimplifier // -//============================================================================// - -class PathSimplifier -{ -public: - PathSimplifier(const QVectorPath &path, QDataBuffer<QPoint> &vertices, - QDataBuffer<quint32> &indices, const QTransform &matrix); - -private: - struct Element; - - class BoundingVolumeHierarchy - { - public: - struct Node - { - enum Type - { - Leaf, - Split - }; - Type type; - QPoint minimum; - QPoint maximum; - union { - Element *element; // type == Leaf - Node *left; // type == Split - }; - Node *right; - }; - - BoundingVolumeHierarchy(); - ~BoundingVolumeHierarchy(); - void allocate(int nodeCount); - void free(); - Node *newNode(); - - Node *root; - private: - void freeNode(Node *n); - - Node *nodeBlock; - int blockSize; - int firstFree; - }; - - struct Element - { - enum Degree - { - Line = 1, - Quadratic = 2, - Cubic = 3 - }; - - quint32 &upperIndex() { return indices[pointingUp ? degree : 0]; } - quint32 &lowerIndex() { return indices[pointingUp ? 0 : degree]; } - quint32 upperIndex() const { return indices[pointingUp ? degree : 0]; } - quint32 lowerIndex() const { return indices[pointingUp ? 0 : degree]; } - void flip(); - - QPoint middle; - quint32 indices[4]; // index to points - Element *next, *previous; // used in connectElements() - int winding; // used in connectElements() - union { - QRBTree<Element *>::Node *edgeNode; // used in connectElements() - BoundingVolumeHierarchy::Node *bvhNode; - }; - Degree degree : 8; - uint processed : 1; // initially false, true when the element has been checked for intersections. - uint pointingUp : 1; // used in connectElements() - uint originallyPointingUp : 1; // used in connectElements() - }; - - class ElementAllocator - { - public: - ElementAllocator(); - ~ElementAllocator(); - void allocate(int count); - Element *newElement(); - private: - struct ElementBlock - { - ElementBlock *next; - int blockSize; - int firstFree; - Element elements[1]; - } *blocks; - }; - - struct Event - { - enum Type { Upper, Lower }; - bool operator < (const Event &other) const; - - QPoint point; - Type type; - Element *element; - }; - - typedef QRBTree<Element *>::Node RBNode; - typedef BoundingVolumeHierarchy::Node BVHNode; - - void initElements(const QVectorPath &path, const QTransform &matrix); - void removeIntersections(); - void connectElements(); - void fillIndices(); - BVHNode *buildTree(Element **elements, int elementCount); - bool intersectNodes(QDataBuffer<Element *> &elements, BVHNode *elementNode, BVHNode *treeNode); - bool equalElements(const Element *e1, const Element *e2); - bool splitLineAt(QDataBuffer<Element *> &elements, BVHNode *node, quint32 pointIndex, bool processAgain); - void appendSeparatingAxes(QVarLengthArray<QPoint, 12> &axes, Element *element); - QPair<int, int> calculateSeparatingAxisRange(const QPoint &axis, Element *element); - void splitCurve(QDataBuffer<Element *> &elements, BVHNode *node); - bool setElementToQuadratic(Element *element, quint32 pointIndex1, const QPoint &ctrl, quint32 pointIndex2); - bool setElementToCubic(Element *element, quint32 pointIndex1, const QPoint &ctrl1, const QPoint &ctrl2, quint32 pointIndex2); - void setElementToCubicAndSimplify(Element *element, quint32 pointIndex1, const QPoint &ctrl1, const QPoint &ctrl2, quint32 pointIndex2); - RBNode *findElementLeftOf(const Element *element, const QPair<RBNode *, RBNode *> &bounds); - bool elementIsLeftOf(const Element *left, const Element *right); - QPair<RBNode *, RBNode *> outerBounds(const QPoint &point); - static bool flattenQuadratic(const QPoint &u, const QPoint &v, const QPoint &w); - static bool flattenCubic(const QPoint &u, const QPoint &v, const QPoint &w, const QPoint &q); - static bool splitQuadratic(const QPoint &u, const QPoint &v, const QPoint &w, QPoint *result); - static bool splitCubic(const QPoint &u, const QPoint &v, const QPoint &w, const QPoint &q, QPoint *result); - void subDivQuadratic(const QPoint &u, const QPoint &v, const QPoint &w); - void subDivCubic(const QPoint &u, const QPoint &v, const QPoint &w, const QPoint &q); - static void sortEvents(Event *events, int count); - - ElementAllocator m_elementAllocator; - QDataBuffer<Element *> m_elements; - QDataBuffer<QPoint> *m_points; - BoundingVolumeHierarchy m_bvh; - QDataBuffer<quint32> *m_indices; - QRBTree<Element *> m_elementList; - uint m_hints; -}; - -inline PathSimplifier::BoundingVolumeHierarchy::BoundingVolumeHierarchy() - : root(0) - , nodeBlock(0) - , blockSize(0) - , firstFree(0) -{ -} - -inline PathSimplifier::BoundingVolumeHierarchy::~BoundingVolumeHierarchy() -{ - free(); -} - -inline void PathSimplifier::BoundingVolumeHierarchy::allocate(int nodeCount) -{ - Q_ASSERT(nodeBlock == 0); - Q_ASSERT(firstFree == 0); - nodeBlock = new Node[blockSize = nodeCount]; -} - -inline void PathSimplifier::BoundingVolumeHierarchy::free() -{ - freeNode(root); - delete[] nodeBlock; - nodeBlock = 0; - firstFree = blockSize = 0; - root = 0; -} - -inline PathSimplifier::BVHNode *PathSimplifier::BoundingVolumeHierarchy::newNode() -{ - if (firstFree < blockSize) - return &nodeBlock[firstFree++]; - return new Node; -} - -inline void PathSimplifier::BoundingVolumeHierarchy::freeNode(Node *n) -{ - if (!n) - return; - Q_ASSERT(n->type == Node::Split || n->type == Node::Leaf); - if (n->type == Node::Split) { - freeNode(n->left); - freeNode(n->right); - } - if (!(n >= nodeBlock && n < nodeBlock + blockSize)) - delete n; -} - -inline PathSimplifier::ElementAllocator::ElementAllocator() - : blocks(0) -{ -} - -inline PathSimplifier::ElementAllocator::~ElementAllocator() -{ - while (blocks) { - ElementBlock *block = blocks; - blocks = blocks->next; - qFree(block); - } -} - -inline void PathSimplifier::ElementAllocator::allocate(int count) -{ - Q_ASSERT(blocks == 0); - Q_ASSERT(count > 0); - blocks = (ElementBlock *)qMalloc(sizeof(ElementBlock) + (count - 1) * sizeof(Element)); - blocks->blockSize = count; - blocks->next = 0; - blocks->firstFree = 0; -} - -inline PathSimplifier::Element *PathSimplifier::ElementAllocator::newElement() -{ - Q_ASSERT(blocks); - if (blocks->firstFree < blocks->blockSize) - return &blocks->elements[blocks->firstFree++]; - ElementBlock *oldBlock = blocks; - blocks = (ElementBlock *)qMalloc(sizeof(ElementBlock) + (oldBlock->blockSize - 1) * sizeof(Element)); - blocks->blockSize = oldBlock->blockSize; - blocks->next = oldBlock; - blocks->firstFree = 0; - return &blocks->elements[blocks->firstFree++]; -} - - -inline bool PathSimplifier::Event::operator < (const Event &other) const -{ - if (point == other.point) - return type < other.type; - return other.point < point; -} - -inline void PathSimplifier::Element::flip() -{ - for (int i = 0; i < (degree + 1) >> 1; ++i) { - Q_ASSERT(degree >= Line && degree <= Cubic); - Q_ASSERT(i >= 0 && i < degree); - qSwap(indices[i], indices[degree - i]); - } - pointingUp = !pointingUp; - Q_ASSERT(next == 0 && previous == 0); -} - -PathSimplifier::PathSimplifier(const QVectorPath &path, QDataBuffer<QPoint> &vertices, - QDataBuffer<quint32> &indices, const QTransform &matrix) - : m_elements(0) - , m_points(&vertices) - , m_indices(&indices) -{ - m_points->reset(); - m_indices->reset(); - initElements(path, matrix); - if (!m_elements.isEmpty()) { - removeIntersections(); - connectElements(); - fillIndices(); - } -} - -void PathSimplifier::initElements(const QVectorPath &path, const QTransform &matrix) -{ - m_hints = path.hints(); - int pathElementCount = path.elementCount(); - if (pathElementCount == 0) - return; - m_elements.reserve(2 * pathElementCount); - m_elementAllocator.allocate(2 * pathElementCount); - m_points->reserve(2 * pathElementCount); - const QPainterPath::ElementType *e = path.elements(); - const qreal *p = path.points(); - if (e) { - qreal x, y; - quint32 moveToIndex = 0; - quint32 previousIndex = 0; - for (int i = 0; i < pathElementCount; ++i, ++e, p += 2) { - switch (*e) { - case QPainterPath::MoveToElement: - { - if (!m_points->isEmpty()) { - const QPoint &from = m_points->at(previousIndex); - const QPoint &to = m_points->at(moveToIndex); - if (from != to) { - Element *element = m_elementAllocator.newElement(); - element->degree = Element::Line; - element->indices[0] = previousIndex; - element->indices[1] = moveToIndex; - element->middle.rx() = (from.x() + to.x()) >> 1; - element->middle.ry() = (from.y() + to.y()) >> 1; - m_elements.add(element); - } - } - previousIndex = moveToIndex = m_points->size(); - matrix.map(p[0], p[1], &x, &y); - QPoint to(qRound(x * Q_FIXED_POINT_SCALE), qRound(y * Q_FIXED_POINT_SCALE)); - m_points->add(to); - } - break; - case QPainterPath::LineToElement: - Q_ASSERT(!m_points->isEmpty()); - { - matrix.map(p[0], p[1], &x, &y); - QPoint to(qRound(x * Q_FIXED_POINT_SCALE), qRound(y * Q_FIXED_POINT_SCALE)); - const QPoint &from = m_points->last(); - if (to != from) { - Element *element = m_elementAllocator.newElement(); - element->degree = Element::Line; - element->indices[0] = previousIndex; - element->indices[1] = quint32(m_points->size()); - element->middle.rx() = (from.x() + to.x()) >> 1; - element->middle.ry() = (from.y() + to.y()) >> 1; - m_elements.add(element); - previousIndex = m_points->size(); - m_points->add(to); - } - } - break; - case QPainterPath::CurveToElement: - Q_ASSERT(i + 2 < pathElementCount); - Q_ASSERT(!m_points->isEmpty()); - Q_ASSERT(e[1] == QPainterPath::CurveToDataElement); - Q_ASSERT(e[2] == QPainterPath::CurveToDataElement); - { - quint32 startPointIndex = previousIndex; - matrix.map(p[4], p[5], &x, &y); - QPoint end(qRound(x * Q_FIXED_POINT_SCALE), qRound(y * Q_FIXED_POINT_SCALE)); - previousIndex = m_points->size(); - m_points->add(end); - - // See if this cubic bezier is really quadratic. - qreal x1 = p[-2] + qreal(1.5) * (p[0] - p[-2]); - qreal y1 = p[-1] + qreal(1.5) * (p[1] - p[-1]); - qreal x2 = p[4] + qreal(1.5) * (p[2] - p[4]); - qreal y2 = p[5] + qreal(1.5) * (p[3] - p[5]); - - Element *element = m_elementAllocator.newElement(); - if (qAbs(x1 - x2) < qreal(1e-3) && qAbs(y1 - y2) < qreal(1e-3)) { - // The bezier curve is quadratic. - matrix.map(x1, y1, &x, &y); - QPoint ctrl(qRound(x * Q_FIXED_POINT_SCALE), - qRound(y * Q_FIXED_POINT_SCALE)); - setElementToQuadratic(element, startPointIndex, ctrl, previousIndex); - } else { - // The bezier curve is cubic. - matrix.map(p[0], p[1], &x, &y); - QPoint ctrl1(qRound(x * Q_FIXED_POINT_SCALE), - qRound(y * Q_FIXED_POINT_SCALE)); - matrix.map(p[2], p[3], &x, &y); - QPoint ctrl2(qRound(x * Q_FIXED_POINT_SCALE), - qRound(y * Q_FIXED_POINT_SCALE)); - setElementToCubicAndSimplify(element, startPointIndex, ctrl1, ctrl2, - previousIndex); - } - m_elements.add(element); - } - i += 2; - e += 2; - p += 4; - - break; - default: - Q_ASSERT_X(0, "QSGPathSimplifier::initialize", "Unexpected element type."); - break; - } - } - if (!m_points->isEmpty()) { - const QPoint &from = m_points->at(previousIndex); - const QPoint &to = m_points->at(moveToIndex); - if (from != to) { - Element *element = m_elementAllocator.newElement(); - element->degree = Element::Line; - element->indices[0] = previousIndex; - element->indices[1] = moveToIndex; - element->middle.rx() = (from.x() + to.x()) >> 1; - element->middle.ry() = (from.y() + to.y()) >> 1; - m_elements.add(element); - } - } - } else { - qreal x, y; - - for (int i = 0; i < pathElementCount; ++i, p += 2) { - matrix.map(p[0], p[1], &x, &y); - QPoint to(qRound(x * Q_FIXED_POINT_SCALE), qRound(y * Q_FIXED_POINT_SCALE)); - if (to != m_points->last()) - m_points->add(to); - } - - while (!m_points->isEmpty() && m_points->last() == m_points->first()) - m_points->pop_back(); - - if (m_points->isEmpty()) - return; - - quint32 prev = quint32(m_points->size() - 1); - for (int i = 0; i < m_points->size(); ++i) { - QPoint &to = m_points->at(i); - QPoint &from = m_points->at(prev); - Element *element = m_elementAllocator.newElement(); - element->degree = Element::Line; - element->indices[0] = prev; - element->indices[1] = quint32(i); - element->middle.rx() = (from.x() + to.x()) >> 1; - element->middle.ry() = (from.y() + to.y()) >> 1; - m_elements.add(element); - prev = i; - } - } - - for (int i = 0; i < m_elements.size(); ++i) - m_elements.at(i)->processed = false; -} - -void PathSimplifier::removeIntersections() -{ - Q_ASSERT(!m_elements.isEmpty()); - QDataBuffer<Element *> elements(m_elements.size()); - for (int i = 0; i < m_elements.size(); ++i) - elements.add(m_elements.at(i)); - m_bvh.allocate(2 * m_elements.size()); - m_bvh.root = buildTree(elements.data(), elements.size()); - - elements.reset(); - for (int i = 0; i < m_elements.size(); ++i) - elements.add(m_elements.at(i)); - - while (!elements.isEmpty()) { - Element *element = elements.last(); - elements.pop_back(); - BVHNode *node = element->bvhNode; - Q_ASSERT(node->type == BVHNode::Leaf); - Q_ASSERT(node->element == element); - if (!element->processed) { - if (!intersectNodes(elements, node, m_bvh.root)) - element->processed = true; - } - } - - m_bvh.free(); // The bounding volume hierarchy is not needed anymore. -} - -void PathSimplifier::connectElements() -{ - Q_ASSERT(!m_elements.isEmpty()); - QDataBuffer<Event> events(m_elements.size() * 2); - for (int i = 0; i < m_elements.size(); ++i) { - Element *element = m_elements.at(i); - element->next = element->previous = 0; - element->winding = 0; - element->edgeNode = 0; - const QPoint &u = m_points->at(element->indices[0]); - const QPoint &v = m_points->at(element->indices[element->degree]); - if (u != v) { - element->pointingUp = element->originallyPointingUp = v < u; - - Event event; - event.element = element; - event.point = u; - event.type = element->pointingUp ? Event::Lower : Event::Upper; - events.add(event); - event.point = v; - event.type = element->pointingUp ? Event::Upper : Event::Lower; - events.add(event); - } - } - QVarLengthArray<Element *, 8> orderedElements; - if (!events.isEmpty()) - sortEvents(events.data(), events.size()); - while (!events.isEmpty()) { - const Event *event = &events.last(); - QPoint eventPoint = event->point; - - // Find all elements passing through the event point. - QPair<RBNode *, RBNode *> bounds = outerBounds(eventPoint); - - // Special case: single element above and single element below event point. - int eventCount = events.size(); - if (event->type == Event::Lower && eventCount > 2) { - QPair<RBNode *, RBNode *> range; - range.first = bounds.first ? m_elementList.next(bounds.first) - : m_elementList.front(m_elementList.root); - range.second = bounds.second ? m_elementList.previous(bounds.second) - : m_elementList.back(m_elementList.root); - - const Event *event2 = &events.at(eventCount - 2); - const Event *event3 = &events.at(eventCount - 3); - Q_ASSERT(event2->point == eventPoint); // There are always at least two events at a point. - if (range.first == range.second && event2->type == Event::Upper && event3->point != eventPoint) { - Element *element = event->element; - Element *element2 = event2->element; - element->edgeNode->data = event2->element; - element2->edgeNode = element->edgeNode; - element->edgeNode = 0; - - events.pop_back(); - events.pop_back(); - - if (element2->pointingUp != element->pointingUp) - element2->flip(); - element2->winding = element->winding; - int winding = element->winding; - if (element->originallyPointingUp) - ++winding; - if (winding == 0 || winding == 1) { - if (element->pointingUp) { - element->previous = event2->element; - element2->next = event->element; - } else { - element->next = event2->element; - element2->previous = event->element; - } - } - continue; - } - } - orderedElements.clear(); - - // First, find the ones above the event point. - if (m_elementList.root) { - RBNode *current = bounds.first ? m_elementList.next(bounds.first) - : m_elementList.front(m_elementList.root); - while (current != bounds.second) { - Element *element = current->data; - Q_ASSERT(element->edgeNode == current); - int winding = element->winding; - if (element->originallyPointingUp) - ++winding; - const QPoint &lower = m_points->at(element->lowerIndex()); - if (lower == eventPoint) { - if (winding == 0 || winding == 1) - orderedElements.append(current->data); - } else { - // The element is passing through 'event.point'. - Q_ASSERT(m_points->at(element->upperIndex()) != eventPoint); - Q_ASSERT(element->degree == Element::Line); - // Split the line. - Element *eventElement = event->element; - int indexIndex = (event->type == Event::Upper) == eventElement->pointingUp - ? eventElement->degree : 0; - quint32 pointIndex = eventElement->indices[indexIndex]; - Q_ASSERT(eventPoint == m_points->at(pointIndex)); - - Element *upperElement = m_elementAllocator.newElement(); - *upperElement = *element; - upperElement->lowerIndex() = element->upperIndex() = pointIndex; - upperElement->edgeNode = 0; - element->next = element->previous = 0; - if (upperElement->next) - upperElement->next->previous = upperElement; - else if (upperElement->previous) - upperElement->previous->next = upperElement; - if (element->pointingUp != element->originallyPointingUp) - element->flip(); - if (winding == 0 || winding == 1) - orderedElements.append(upperElement); - m_elements.add(upperElement); - } - current = m_elementList.next(current); - } - } - while (!events.isEmpty() && events.last().point == eventPoint) { - event = &events.last(); - if (event->type == Event::Upper) { - Q_ASSERT(event->point == m_points->at(event->element->upperIndex())); - RBNode *left = findElementLeftOf(event->element, bounds); - RBNode *node = m_elementList.newNode(); - node->data = event->element; - Q_ASSERT(event->element->edgeNode == 0); - event->element->edgeNode = node; - m_elementList.attachAfter(left, node); - } else { - Q_ASSERT(event->type == Event::Lower); - Q_ASSERT(event->point == m_points->at(event->element->lowerIndex())); - Element *element = event->element; - Q_ASSERT(element->edgeNode); - m_elementList.deleteNode(element->edgeNode); - Q_ASSERT(element->edgeNode == 0); - } - events.pop_back(); - } - - if (m_elementList.root) { - RBNode *current = bounds.first ? m_elementList.next(bounds.first) - : m_elementList.front(m_elementList.root); - int winding = bounds.first ? bounds.first->data->winding : 0; - - // Calculate winding numbers and flip elements if necessary. - while (current != bounds.second) { - Element *element = current->data; - Q_ASSERT(element->edgeNode == current); - int ccw = winding & 1; - Q_ASSERT(element->pointingUp == element->originallyPointingUp); - if (element->originallyPointingUp) { - --winding; - } else { - ++winding; - ccw ^= 1; - } - element->winding = winding; - if (ccw == 0) - element->flip(); - current = m_elementList.next(current); - } - - // Pick elements with correct winding number. - current = bounds.second ? m_elementList.previous(bounds.second) - : m_elementList.back(m_elementList.root); - while (current != bounds.first) { - Element *element = current->data; - Q_ASSERT(element->edgeNode == current); - Q_ASSERT(m_points->at(element->upperIndex()) == eventPoint); - int winding = element->winding; - if (element->originallyPointingUp) - ++winding; - if (winding == 0 || winding == 1) - orderedElements.append(current->data); - current = m_elementList.previous(current); - } - } - - if (!orderedElements.isEmpty()) { - Q_ASSERT((orderedElements.size() & 1) == 0); - int i = 0; - Element *firstElement = orderedElements.at(0); - if (m_points->at(firstElement->indices[0]) != eventPoint) { - orderedElements.append(firstElement); - i = 1; - } - for (; i < orderedElements.size(); i += 2) { - Q_ASSERT(i + 1 < orderedElements.size()); - Element *next = orderedElements.at(i); - Element *previous = orderedElements.at(i + 1); - Q_ASSERT(next->previous == 0); - Q_ASSERT(previous->next == 0); - next->previous = previous; - previous->next = next; - } - } - } -#ifndef QT_NO_DEBUG - for (int i = 0; i < m_elements.size(); ++i) { - const Element *element = m_elements.at(i); - Q_ASSERT(element->next == 0 || element->next->previous == element); - Q_ASSERT(element->previous == 0 || element->previous->next == element); - Q_ASSERT((element->next == 0) == (element->previous == 0)); - } -#endif -} - -void PathSimplifier::fillIndices() -{ - for (int i = 0; i < m_elements.size(); ++i) - m_elements.at(i)->processed = false; - for (int i = 0; i < m_elements.size(); ++i) { - Element *element = m_elements.at(i); - if (element->processed || element->next == 0) - continue; - do { - m_indices->add(element->indices[0]); - switch (element->degree) { - case Element::Quadratic: - { - QPoint pts[] = { - m_points->at(element->indices[0]), - m_points->at(element->indices[1]), - m_points->at(element->indices[2]) - }; - subDivQuadratic(pts[0], pts[1], pts[2]); - } - break; - case Element::Cubic: - { - QPoint pts[] = { - m_points->at(element->indices[0]), - m_points->at(element->indices[1]), - m_points->at(element->indices[2]), - m_points->at(element->indices[3]) - }; - subDivCubic(pts[0], pts[1], pts[2], pts[3]); - } - break; - default: - break; - } - Q_ASSERT(element->next); - element->processed = true; - element = element->next; - } while (element != m_elements.at(i)); - m_indices->add(Q_TRIANGULATE_END_OF_POLYGON); - } -} - -PathSimplifier::BVHNode *PathSimplifier::buildTree(Element **elements, int elementCount) -{ - Q_ASSERT(elementCount > 0); - BVHNode *node = m_bvh.newNode(); - if (elementCount == 1) { - Element *element = *elements; - element->bvhNode = node; - node->type = BVHNode::Leaf; - node->element = element; - node->minimum = node->maximum = m_points->at(element->indices[0]); - for (int i = 1; i <= element->degree; ++i) { - const QPoint &p = m_points->at(element->indices[i]); - node->minimum.rx() = qMin(node->minimum.x(), p.x()); - node->minimum.ry() = qMin(node->minimum.y(), p.y()); - node->maximum.rx() = qMax(node->maximum.x(), p.x()); - node->maximum.ry() = qMax(node->maximum.y(), p.y()); - } - return node; - } - - node->type = BVHNode::Split; - - QPoint minimum, maximum; - minimum = maximum = elements[0]->middle; - - for (int i = 1; i < elementCount; ++i) { - const QPoint &p = elements[i]->middle; - minimum.rx() = qMin(minimum.x(), p.x()); - minimum.ry() = qMin(minimum.y(), p.y()); - maximum.rx() = qMax(maximum.x(), p.x()); - maximum.ry() = qMax(maximum.y(), p.y()); - } - - int comp, pivot; - if (maximum.x() - minimum.x() > maximum.y() - minimum.y()) { - comp = 0; - pivot = (maximum.x() + minimum.x()) >> 1; - } else { - comp = 1; - pivot = (maximum.y() + minimum.y()) >> 1; - } - - int lo = 0; - int hi = elementCount - 1; - while (lo < hi) { - while (lo < hi && (&elements[lo]->middle.rx())[comp] <= pivot) - ++lo; - while (lo < hi && (&elements[hi]->middle.rx())[comp] > pivot) - --hi; - if (lo < hi) - qSwap(elements[lo], elements[hi]); - } - - if (lo == elementCount) { - // All points are the same. - Q_ASSERT(minimum.x() == maximum.x() && minimum.y() == maximum.y()); - lo = elementCount >> 1; - } - - node->left = buildTree(elements, lo); - node->right = buildTree(elements + lo, elementCount - lo); - - const BVHNode *left = node->left; - const BVHNode *right = node->right; - node->minimum.rx() = qMin(left->minimum.x(), right->minimum.x()); - node->minimum.ry() = qMin(left->minimum.y(), right->minimum.y()); - node->maximum.rx() = qMax(left->maximum.x(), right->maximum.x()); - node->maximum.ry() = qMax(left->maximum.y(), right->maximum.y()); - - return node; -} - -bool PathSimplifier::intersectNodes(QDataBuffer<Element *> &elements, BVHNode *elementNode, - BVHNode *treeNode) -{ - if (elementNode->minimum.x() >= treeNode->maximum.x() - || elementNode->minimum.y() >= treeNode->maximum.y() - || elementNode->maximum.x() <= treeNode->minimum.x() - || elementNode->maximum.y() <= treeNode->minimum.y()) - { - return false; - } - - Q_ASSERT(elementNode->type == BVHNode::Leaf); - Element *element = elementNode->element; - Q_ASSERT(!element->processed); - - if (treeNode->type == BVHNode::Leaf) { - Element *nodeElement = treeNode->element; - if (!nodeElement->processed) - return false; - - if (treeNode->element == elementNode->element) - return false; - - if (equalElements(treeNode->element, elementNode->element)) - return false; // element doesn't split itself. - - if (element->degree == Element::Line && nodeElement->degree == Element::Line) { - const QPoint &u1 = m_points->at(element->indices[0]); - const QPoint &u2 = m_points->at(element->indices[1]); - const QPoint &v1 = m_points->at(nodeElement->indices[0]); - const QPoint &v2 = m_points->at(nodeElement->indices[1]); - IntersectionPoint intersection = intersectionPoint(u1, u2, v1, v2); - if (!intersection.isValid()) - return false; - - Q_ASSERT(intersection.x.integer >= qMin(u1.x(), u2.x())); - Q_ASSERT(intersection.y.integer >= qMin(u1.y(), u2.y())); - Q_ASSERT(intersection.x.integer >= qMin(v1.x(), v2.x())); - Q_ASSERT(intersection.y.integer >= qMin(v1.y(), v2.y())); - - Q_ASSERT(intersection.x.integer <= qMax(u1.x(), u2.x())); - Q_ASSERT(intersection.y.integer <= qMax(u1.y(), u2.y())); - Q_ASSERT(intersection.x.integer <= qMax(v1.x(), v2.x())); - Q_ASSERT(intersection.y.integer <= qMax(v1.y(), v2.y())); - - m_points->add(intersection.round()); - splitLineAt(elements, treeNode, m_points->size() - 1, !intersection.isAccurate()); - return splitLineAt(elements, elementNode, m_points->size() - 1, false); - } else { - QVarLengthArray<QPoint, 12> axes; - appendSeparatingAxes(axes, elementNode->element); - appendSeparatingAxes(axes, treeNode->element); - for (int i = 0; i < axes.size(); ++i) { - QPair<int, int> range1 = calculateSeparatingAxisRange(axes.at(i), elementNode->element); - QPair<int, int> range2 = calculateSeparatingAxisRange(axes.at(i), treeNode->element); - if (range1.first >= range2.second || range1.second <= range2.first) { - return false; // Separating axis found. - } - } - // Bounding areas overlap. - if (nodeElement->degree > Element::Line) - splitCurve(elements, treeNode); - if (element->degree > Element::Line) { - splitCurve(elements, elementNode); - } else { - // The element was not split, so it can be processed further. - if (intersectNodes(elements, elementNode, treeNode->left)) - return true; - if (intersectNodes(elements, elementNode, treeNode->right)) - return true; - return false; - } - return true; - } - } else { - if (intersectNodes(elements, elementNode, treeNode->left)) - return true; - if (intersectNodes(elements, elementNode, treeNode->right)) - return true; - return false; - } -} - -bool PathSimplifier::equalElements(const Element *e1, const Element *e2) -{ - Q_ASSERT(e1 != e2); - if (e1->degree != e2->degree) - return false; - - // Possibly equal and in the same direction. - bool equalSame = true; - for (int i = 0; i <= e1->degree; ++i) - equalSame &= m_points->at(e1->indices[i]) == m_points->at(e2->indices[i]); - - // Possibly equal and in opposite directions. - bool equalOpposite = true; - for (int i = 0; i <= e1->degree; ++i) - equalOpposite &= m_points->at(e1->indices[e1->degree - i]) == m_points->at(e2->indices[i]); - - return equalSame || equalOpposite; -} - -bool PathSimplifier::splitLineAt(QDataBuffer<Element *> &elements, BVHNode *node, - quint32 pointIndex, bool processAgain) -{ - Q_ASSERT(node->type == BVHNode::Leaf); - Element *element = node->element; - Q_ASSERT(element->degree == Element::Line); - const QPoint &u = m_points->at(element->indices[0]); - const QPoint &v = m_points->at(element->indices[1]); - const QPoint &p = m_points->at(pointIndex); - if (u == p || v == p) - return false; // No split needed. - - if (processAgain) - element->processed = false; // Needs to be processed again. - - Element *first = node->element; - Element *second = m_elementAllocator.newElement(); - *second = *first; - first->indices[1] = second->indices[0] = pointIndex; - first->middle.rx() = (u.x() + p.x()) >> 1; - first->middle.ry() = (u.y() + p.y()) >> 1; - second->middle.rx() = (v.x() + p.x()) >> 1; - second->middle.ry() = (v.y() + p.y()) >> 1; - m_elements.add(second); - - BVHNode *left = m_bvh.newNode(); - BVHNode *right = m_bvh.newNode(); - left->type = right->type = BVHNode::Leaf; - left->element = first; - right->element = second; - left->minimum = right->minimum = node->minimum; - left->maximum = right->maximum = node->maximum; - if (u.x() < v.x()) - left->maximum.rx() = right->minimum.rx() = p.x(); - else - left->minimum.rx() = right->maximum.rx() = p.x(); - if (u.y() < v.y()) - left->maximum.ry() = right->minimum.ry() = p.y(); - else - left->minimum.ry() = right->maximum.ry() = p.y(); - left->element->bvhNode = left; - right->element->bvhNode = right; - - node->type = BVHNode::Split; - node->left = left; - node->right = right; - - if (!first->processed) { - elements.add(left->element); - elements.add(right->element); - } - return true; -} - -void PathSimplifier::appendSeparatingAxes(QVarLengthArray<QPoint, 12> &axes, Element *element) -{ - switch (element->degree) { - case Element::Cubic: - { - const QPoint &u = m_points->at(element->indices[0]); - const QPoint &v = m_points->at(element->indices[1]); - const QPoint &w = m_points->at(element->indices[2]); - const QPoint &q = m_points->at(element->indices[3]); - QPoint ns[] = { - QPoint(u.y() - v.y(), v.x() - u.x()), - QPoint(v.y() - w.y(), w.x() - v.x()), - QPoint(w.y() - q.y(), q.x() - w.x()), - QPoint(q.y() - u.y(), u.x() - q.x()), - QPoint(u.y() - w.y(), w.x() - u.x()), - QPoint(v.y() - q.y(), q.x() - v.x()) - }; - for (int i = 0; i < 6; ++i) { - if (ns[i].x() || ns[i].y()) - axes.append(ns[i]); - } - } - break; - case Element::Quadratic: - { - const QPoint &u = m_points->at(element->indices[0]); - const QPoint &v = m_points->at(element->indices[1]); - const QPoint &w = m_points->at(element->indices[2]); - QPoint ns[] = { - QPoint(u.y() - v.y(), v.x() - u.x()), - QPoint(v.y() - w.y(), w.x() - v.x()), - QPoint(w.y() - u.y(), u.x() - w.x()) - }; - for (int i = 0; i < 3; ++i) { - if (ns[i].x() || ns[i].y()) - axes.append(ns[i]); - } - } - break; - case Element::Line: - { - const QPoint &u = m_points->at(element->indices[0]); - const QPoint &v = m_points->at(element->indices[1]); - QPoint n(u.y() - v.y(), v.x() - u.x()); - if (n.x() || n.y()) - axes.append(n); - } - break; - default: - Q_ASSERT_X(0, "QSGPathSimplifier::appendSeparatingAxes", "Unexpected element type."); - break; - } -} - -QPair<int, int> PathSimplifier::calculateSeparatingAxisRange(const QPoint &axis, Element *element) -{ - QPair<int, int> range(0x7fffffff, -0x7fffffff); - for (int i = 0; i <= element->degree; ++i) { - const QPoint &p = m_points->at(element->indices[i]); - int dist = dot(axis, p); - range.first = qMin(range.first, dist); - range.second = qMax(range.second, dist); - } - return range; -} - -void PathSimplifier::splitCurve(QDataBuffer<Element *> &elements, BVHNode *node) -{ - Q_ASSERT(node->type == BVHNode::Leaf); - - Element *first = node->element; - Element *second = m_elementAllocator.newElement(); - *second = *first; - m_elements.add(second); - Q_ASSERT(first->degree > Element::Line); - - bool accurate = true; - const QPoint &u = m_points->at(first->indices[0]); - const QPoint &v = m_points->at(first->indices[1]); - const QPoint &w = m_points->at(first->indices[2]); - - if (first->degree == Element::Quadratic) { - QPoint pts[3]; - accurate = splitQuadratic(u, v, w, pts); - int pointIndex = m_points->size(); - m_points->add(pts[1]); - accurate &= setElementToQuadratic(first, first->indices[0], pts[0], pointIndex); - accurate &= setElementToQuadratic(second, pointIndex, pts[2], second->indices[2]); - } else { - Q_ASSERT(first->degree == Element::Cubic); - const QPoint &q = m_points->at(first->indices[3]); - QPoint pts[5]; - accurate = splitCubic(u, v, w, q, pts); - int pointIndex = m_points->size(); - m_points->add(pts[2]); - accurate &= setElementToCubic(first, first->indices[0], pts[0], pts[1], pointIndex); - accurate &= setElementToCubic(second, pointIndex, pts[3], pts[4], second->indices[3]); - } - - if (!accurate) - first->processed = second->processed = false; // Needs to be processed again. - - BVHNode *left = m_bvh.newNode(); - BVHNode *right = m_bvh.newNode(); - left->type = right->type = BVHNode::Leaf; - left->element = first; - right->element = second; - - left->minimum.rx() = left->minimum.ry() = right->minimum.rx() = right->minimum.ry() = INT_MAX; - left->maximum.rx() = left->maximum.ry() = right->maximum.rx() = right->maximum.ry() = INT_MIN; - - for (int i = 0; i <= first->degree; ++i) { - QPoint &p = m_points->at(first->indices[i]); - left->minimum.rx() = qMin(left->minimum.x(), p.x()); - left->minimum.ry() = qMin(left->minimum.y(), p.y()); - left->maximum.rx() = qMax(left->maximum.x(), p.x()); - left->maximum.ry() = qMax(left->maximum.y(), p.y()); - } - for (int i = 0; i <= second->degree; ++i) { - QPoint &p = m_points->at(second->indices[i]); - right->minimum.rx() = qMin(right->minimum.x(), p.x()); - right->minimum.ry() = qMin(right->minimum.y(), p.y()); - right->maximum.rx() = qMax(right->maximum.x(), p.x()); - right->maximum.ry() = qMax(right->maximum.y(), p.y()); - } - left->element->bvhNode = left; - right->element->bvhNode = right; - - node->type = BVHNode::Split; - node->left = left; - node->right = right; - - if (!first->processed) { - elements.add(left->element); - elements.add(right->element); - } -} - -bool PathSimplifier::setElementToQuadratic(Element *element, quint32 pointIndex1, - const QPoint &ctrl, quint32 pointIndex2) -{ - const QPoint &p1 = m_points->at(pointIndex1); - const QPoint &p2 = m_points->at(pointIndex2); - if (flattenQuadratic(p1, ctrl, p2)) { - // Insert line. - element->degree = Element::Line; - element->indices[0] = pointIndex1; - element->indices[1] = pointIndex2; - element->middle.rx() = (p1.x() + p2.x()) >> 1; - element->middle.ry() = (p1.y() + p2.y()) >> 1; - return false; - } else { - // Insert bezier. - element->degree = Element::Quadratic; - element->indices[0] = pointIndex1; - element->indices[1] = m_points->size(); - element->indices[2] = pointIndex2; - element->middle.rx() = (p1.x() + ctrl.x() + p2.x()) / 3; - element->middle.ry() = (p1.y() + ctrl.y() + p2.y()) / 3; - m_points->add(ctrl); - return true; - } -} - -bool PathSimplifier::setElementToCubic(Element *element, quint32 pointIndex1, const QPoint &v, - const QPoint &w, quint32 pointIndex2) -{ - const QPoint &u = m_points->at(pointIndex1); - const QPoint &q = m_points->at(pointIndex2); - if (flattenCubic(u, v, w, q)) { - // Insert line. - element->degree = Element::Line; - element->indices[0] = pointIndex1; - element->indices[1] = pointIndex2; - element->middle.rx() = (u.x() + q.x()) >> 1; - element->middle.ry() = (u.y() + q.y()) >> 1; - return false; - } else { - // Insert bezier. - element->degree = Element::Cubic; - element->indices[0] = pointIndex1; - element->indices[1] = m_points->size(); - element->indices[2] = m_points->size() + 1; - element->indices[3] = pointIndex2; - element->middle.rx() = (u.x() + v.x() + w.x() + q.x()) >> 2; - element->middle.ry() = (u.y() + v.y() + w.y() + q.y()) >> 2; - m_points->add(v); - m_points->add(w); - return true; - } -} - -void PathSimplifier::setElementToCubicAndSimplify(Element *element, quint32 pointIndex1, - const QPoint &v, const QPoint &w, - quint32 pointIndex2) -{ - const QPoint &u = m_points->at(pointIndex1); - const QPoint &q = m_points->at(pointIndex2); - if (flattenCubic(u, v, w, q)) { - // Insert line. - element->degree = Element::Line; - element->indices[0] = pointIndex1; - element->indices[1] = pointIndex2; - element->middle.rx() = (u.x() + q.x()) >> 1; - element->middle.ry() = (u.y() + q.y()) >> 1; - return; - } - - bool intersecting = (u == q) || intersectionPoint(u, v, w, q).isValid(); - if (!intersecting) { - // Insert bezier. - element->degree = Element::Cubic; - element->indices[0] = pointIndex1; - element->indices[1] = m_points->size(); - element->indices[2] = m_points->size() + 1; - element->indices[3] = pointIndex2; - element->middle.rx() = (u.x() + v.x() + w.x() + q.x()) >> 2; - element->middle.ry() = (u.y() + v.y() + w.y() + q.y()) >> 2; - m_points->add(v); - m_points->add(w); - return; - } - - QPoint pts[5]; - splitCubic(u, v, w, q, pts); - int pointIndex = m_points->size(); - m_points->add(pts[2]); - Element *element2 = m_elementAllocator.newElement(); - m_elements.add(element2); - setElementToCubicAndSimplify(element, pointIndex1, pts[0], pts[1], pointIndex); - setElementToCubicAndSimplify(element2, pointIndex, pts[3], pts[4], pointIndex2); -} - -PathSimplifier::RBNode *PathSimplifier::findElementLeftOf(const Element *element, - const QPair<RBNode *, RBNode *> &bounds) -{ - if (!m_elementList.root) - return 0; - RBNode *current = bounds.first; - Q_ASSERT(!current || !elementIsLeftOf(element, current->data)); - if (!current) - current = m_elementList.front(m_elementList.root); - Q_ASSERT(current); - RBNode *result = 0; - while (current != bounds.second && !elementIsLeftOf(element, current->data)) { - result = current; - current = m_elementList.next(current); - } - return result; -} - -bool PathSimplifier::elementIsLeftOf(const Element *left, const Element *right) -{ - const QPoint &leftU = m_points->at(left->upperIndex()); - const QPoint &leftL = m_points->at(left->lowerIndex()); - const QPoint &rightU = m_points->at(right->upperIndex()); - const QPoint &rightL = m_points->at(right->lowerIndex()); - Q_ASSERT(leftL >= rightU && rightL >= leftU); - if (leftU.x() < qMin(rightL.x(), rightU.x())) - return true; - if (leftU.x() > qMax(rightL.x(), rightU.x())) - return false; - int d = pointDistanceFromLine(leftU, rightL, rightU); - // d < 0: left, d > 0: right, d == 0: on top - if (d == 0) { - d = pointDistanceFromLine(leftL, rightL, rightU); - if (d == 0) { - if (right->degree > Element::Line) { - d = pointDistanceFromLine(leftL, rightL, m_points->at(right->indices[1])); - if (d == 0) - d = pointDistanceFromLine(leftL, rightL, m_points->at(right->indices[2])); - } else if (left->degree > Element::Line) { - d = pointDistanceFromLine(m_points->at(left->indices[1]), rightL, rightU); - if (d == 0) - d = pointDistanceFromLine(m_points->at(left->indices[2]), rightL, rightU); - } - } - } - return d < 0; -} - -QPair<PathSimplifier::RBNode *, PathSimplifier::RBNode *> PathSimplifier::outerBounds(const QPoint &point) -{ - RBNode *current = m_elementList.root; - QPair<RBNode *, RBNode *> result(0, 0); - - while (current) { - const Element *element = current->data; - Q_ASSERT(element->edgeNode == current); - const QPoint &v1 = m_points->at(element->lowerIndex()); - const QPoint &v2 = m_points->at(element->upperIndex()); - Q_ASSERT(point >= v2 && point <= v1); - if (point == v1 || point == v2) - break; - int d = pointDistanceFromLine(point, v1, v2); - if (d == 0) { - if (element->degree == Element::Line) - break; - d = pointDistanceFromLine(point, v1, m_points->at(element->indices[1])); - if (d == 0) - d = pointDistanceFromLine(point, v1, m_points->at(element->indices[2])); - Q_ASSERT(d != 0); - } - if (d < 0) { - result.second = current; - current = current->left; - } else { - result.first = current; - current = current->right; - } - } - - if (!current) - return result; - - RBNode *mid = current; - - current = mid->left; - while (current) { - const Element *element = current->data; - Q_ASSERT(element->edgeNode == current); - const QPoint &v1 = m_points->at(element->lowerIndex()); - const QPoint &v2 = m_points->at(element->upperIndex()); - Q_ASSERT(point >= v2 && point <= v1); - bool equal = (point == v1 || point == v2); - if (!equal) { - int d = pointDistanceFromLine(point, v1, v2); - Q_ASSERT(d >= 0); - equal = (d == 0 && element->degree == Element::Line); - } - if (equal) { - current = current->left; - } else { - result.first = current; - current = current->right; - } - } - - current = mid->right; - while (current) { - const Element *element = current->data; - Q_ASSERT(element->edgeNode == current); - const QPoint &v1 = m_points->at(element->lowerIndex()); - const QPoint &v2 = m_points->at(element->upperIndex()); - Q_ASSERT(point >= v2 && point <= v1); - bool equal = (point == v1 || point == v2); - if (!equal) { - int d = pointDistanceFromLine(point, v1, v2); - Q_ASSERT(d <= 0); - equal = (d == 0 && element->degree == Element::Line); - } - if (equal) { - current = current->right; - } else { - result.second = current; - current = current->left; - } - } - - return result; -} - -inline bool PathSimplifier::flattenQuadratic(const QPoint &u, const QPoint &v, const QPoint &w) -{ - QPoint deltas[2] = { v - u, w - v }; - int d = qAbs(cross(deltas[0], deltas[1])); - int l = qAbs(deltas[0].x()) + qAbs(deltas[0].y()) + qAbs(deltas[1].x()) + qAbs(deltas[1].y()); - return d < (Q_FIXED_POINT_SCALE * Q_FIXED_POINT_SCALE * 3 / 2) || l <= Q_FIXED_POINT_SCALE * 2; -} - -inline bool PathSimplifier::flattenCubic(const QPoint &u, const QPoint &v, - const QPoint &w, const QPoint &q) -{ - QPoint deltas[] = { v - u, w - v, q - w, q - u }; - int d = qAbs(cross(deltas[0], deltas[1])) + qAbs(cross(deltas[1], deltas[2])) - + qAbs(cross(deltas[0], deltas[3])) + qAbs(cross(deltas[3], deltas[2])); - int l = qAbs(deltas[0].x()) + qAbs(deltas[0].y()) + qAbs(deltas[1].x()) + qAbs(deltas[1].y()) - + qAbs(deltas[2].x()) + qAbs(deltas[2].y()); - return d < (Q_FIXED_POINT_SCALE * Q_FIXED_POINT_SCALE * 3) || l <= Q_FIXED_POINT_SCALE * 2; -} - -inline bool PathSimplifier::splitQuadratic(const QPoint &u, const QPoint &v, - const QPoint &w, QPoint *result) -{ - result[0] = u + v; - result[2] = v + w; - result[1] = result[0] + result[2]; - bool accurate = ((result[0].x() | result[0].y() | result[2].x() | result[2].y()) & 1) == 0 - && ((result[1].x() | result[1].y()) & 3) == 0; - result[0].rx() >>= 1; - result[0].ry() >>= 1; - result[1].rx() >>= 2; - result[1].ry() >>= 2; - result[2].rx() >>= 1; - result[2].ry() >>= 1; - return accurate; -} - -inline bool PathSimplifier::splitCubic(const QPoint &u, const QPoint &v, - const QPoint &w, const QPoint &q, QPoint *result) -{ - result[0] = u + v; - result[2] = v + w; - result[4] = w + q; - result[1] = result[0] + result[2]; - result[3] = result[2] + result[4]; - result[2] = result[1] + result[3]; - bool accurate = ((result[0].x() | result[0].y() | result[4].x() | result[4].y()) & 1) == 0 - && ((result[1].x() | result[1].y() | result[3].x() | result[3].y()) & 3) == 0 - && ((result[2].x() | result[2].y()) & 7) == 0; - result[0].rx() >>= 1; - result[0].ry() >>= 1; - result[1].rx() >>= 2; - result[1].ry() >>= 2; - result[2].rx() >>= 3; - result[2].ry() >>= 3; - result[3].rx() >>= 2; - result[3].ry() >>= 2; - result[4].rx() >>= 1; - result[4].ry() >>= 1; - return accurate; -} - -inline void PathSimplifier::subDivQuadratic(const QPoint &u, const QPoint &v, const QPoint &w) -{ - if (flattenQuadratic(u, v, w)) - return; - QPoint pts[3]; - splitQuadratic(u, v, w, pts); - subDivQuadratic(u, pts[0], pts[1]); - m_indices->add(m_points->size()); - m_points->add(pts[1]); - subDivQuadratic(pts[1], pts[2], w); -} - -inline void PathSimplifier::subDivCubic(const QPoint &u, const QPoint &v, - const QPoint &w, const QPoint &q) -{ - if (flattenCubic(u, v, w, q)) - return; - QPoint pts[5]; - splitCubic(u, v, w, q, pts); - subDivCubic(u, pts[0], pts[1], pts[2]); - m_indices->add(m_points->size()); - m_points->add(pts[2]); - subDivCubic(pts[2], pts[3], pts[4], q); -} - -void PathSimplifier::sortEvents(Event *events, int count) -{ - // Bucket sort + insertion sort. - Q_ASSERT(count > 0); - QDataBuffer<Event> buffer(count); - buffer.resize(count); - QScopedArrayPointer<int> bins(new int[count]); - int counts[0x101]; - memset(counts, 0, sizeof(counts)); - - int minimum, maximum; - minimum = maximum = events[0].point.y(); - for (int i = 1; i < count; ++i) { - minimum = qMin(minimum, events[i].point.y()); - maximum = qMax(maximum, events[i].point.y()); - } - - for (int i = 0; i < count; ++i) { - bins[i] = ((maximum - events[i].point.y()) << 8) / (maximum - minimum + 1); - Q_ASSERT(bins[i] >= 0 && bins[i] < 0x100); - ++counts[bins[i]]; - } - - for (int i = 1; i < 0x100; ++i) - counts[i] += counts[i - 1]; - counts[0x100] = counts[0xff]; - Q_ASSERT(counts[0x100] == count); - - for (int i = 0; i < count; ++i) - buffer.at(--counts[bins[i]]) = events[i]; - - int j = 0; - for (int i = 0; i < 0x100; ++i) { - for (; j < counts[i + 1]; ++j) { - int k = j; - while (k > 0 && (buffer.at(j) < events[k - 1])) { - events[k] = events[k - 1]; - --k; - } - events[k] = buffer.at(j); - } - } -} - -} // end anonymous namespace - - -void qSimplifyPath(const QVectorPath &path, QDataBuffer<QPoint> &vertices, - QDataBuffer<quint32> &indices, const QTransform &matrix) -{ - PathSimplifier(path, vertices, indices, matrix); -} - -void qSimplifyPath(const QPainterPath &path, QDataBuffer<QPoint> &vertices, - QDataBuffer<quint32> &indices, const QTransform &matrix) -{ - qSimplifyPath(qtVectorPathForPath(path), vertices, indices, matrix); -} - - -QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/qsgpathsimplifier_p.h b/src/declarative/scenegraph/qsgpathsimplifier_p.h deleted file mode 100644 index 0639c4f622..0000000000 --- a/src/declarative/scenegraph/qsgpathsimplifier_p.h +++ /dev/null @@ -1,68 +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 QSGPATHSIMPLIFIER_P_H -#define QSGPATHSIMPLIFIER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtGui/qpainterpath.h> -#include <QtGui/private/qdatabuffer_p.h> -#include <QtGui/private/qvectorpath_p.h> - -QT_BEGIN_NAMESPACE - -// The returned vertices are in 8:8 fixed point format. The path is assumed to be in the range (-128, 128)x(-128, 128). -void qSimplifyPath(const QVectorPath &path, QDataBuffer<QPoint> &vertices, QDataBuffer<quint32> &indices, const QTransform &matrix = QTransform()); -void qSimplifyPath(const QPainterPath &path, QDataBuffer<QPoint> &vertices, QDataBuffer<quint32> &indices, const QTransform &matrix = QTransform()); - -QT_END_NAMESPACE - -#endif diff --git a/src/declarative/scenegraph/scenegraph.pri b/src/declarative/scenegraph/scenegraph.pri deleted file mode 100644 index 0adc20502d..0000000000 --- a/src/declarative/scenegraph/scenegraph.pri +++ /dev/null @@ -1,86 +0,0 @@ -!contains(QT_CONFIG, egl):DEFINES += QT_NO_EGL - -# Core API -HEADERS += \ - $$PWD/coreapi/qsgdefaultrenderer_p.h \ - $$PWD/coreapi/qsggeometry.h \ - $$PWD/coreapi/qsgmaterial.h \ - $$PWD/coreapi/qsgnode.h \ - $$PWD/coreapi/qsgnodeupdater_p.h \ - $$PWD/coreapi/qsgrenderer_p.h \ - $$PWD/coreapi/qsggeometry_p.h - -SOURCES += \ - $$PWD/coreapi/qsgdefaultrenderer.cpp \ - $$PWD/coreapi/qsggeometry.cpp \ - $$PWD/coreapi/qsgmaterial.cpp \ - $$PWD/coreapi/qsgnode.cpp \ - $$PWD/coreapi/qsgnodeupdater.cpp \ - $$PWD/coreapi/qsgrenderer.cpp - - -# Util API -HEADERS += \ - $$PWD/util/qsgareaallocator_p.h \ - $$PWD/util/qsgengine.h \ - $$PWD/util/qsgflatcolormaterial.h \ - $$PWD/util/qsgsimplematerial.h \ - $$PWD/util/qsgsimplerectnode.h \ - $$PWD/util/qsgsimpletexturenode.h \ - $$PWD/util/qsgtexturematerial.h \ - $$PWD/util/qsgtexturematerial_p.h \ - $$PWD/util/qsgvertexcolormaterial.h \ - $$PWD/util/qsgtexture.h \ - $$PWD/util/qsgtexture_p.h \ - $$PWD/util/qsgtextureprovider_p.h \ - $$PWD/util/qsgpainternode_p.h \ - $$PWD/util/qsgdistancefieldutil_p.h - -SOURCES += \ - $$PWD/util/qsgareaallocator.cpp \ - $$PWD/util/qsgengine.cpp \ - $$PWD/util/qsgflatcolormaterial.cpp \ - $$PWD/util/qsgsimplerectnode.cpp \ - $$PWD/util/qsgsimpletexturenode.cpp \ - $$PWD/util/qsgtexturematerial.cpp \ - $$PWD/util/qsgvertexcolormaterial.cpp \ - $$PWD/util/qsgtexture.cpp \ - $$PWD/util/qsgtextureprovider.cpp \ - $$PWD/util/qsgpainternode.cpp \ - $$PWD/util/qsgdistancefieldutil.cpp - - -# QML / Adaptations API -HEADERS += \ - $$PWD/qsgadaptationlayer_p.h \ - $$PWD/qsgcontext_p.h \ - $$PWD/qsgcontextplugin_p.h \ - $$PWD/qsgdefaultglyphnode_p.h \ - $$PWD/qsgdefaultdistancefieldglyphcache_p.h \ - $$PWD/qsgdistancefieldglyphnode_p.h \ - $$PWD/qsgdistancefieldglyphnode_p_p.h \ - $$PWD/qsgdefaultglyphnode_p_p.h \ - $$PWD/qsgdefaultimagenode_p.h \ - $$PWD/qsgdefaultrectanglenode_p.h \ - $$PWD/qsgflashnode_p.h \ - $$PWD/qsgpathsimplifier_p.h - -SOURCES += \ - $$PWD/qsgadaptationlayer.cpp \ - $$PWD/qsgcontext.cpp \ - $$PWD/qsgcontextplugin.cpp \ - $$PWD/qsgdefaultglyphnode.cpp \ - $$PWD/qsgdefaultglyphnode_p.cpp \ - $$PWD/qsgdefaultdistancefieldglyphcache.cpp \ - $$PWD/qsgdistancefieldglyphnode.cpp \ - $$PWD/qsgdistancefieldglyphnode_p.cpp \ - $$PWD/qsgdefaultimagenode.cpp \ - $$PWD/qsgdefaultrectanglenode.cpp \ - $$PWD/qsgflashnode.cpp \ - $$PWD/qsgpathsimplifier.cpp - - - - - - diff --git a/src/declarative/scenegraph/util/qsgareaallocator.cpp b/src/declarative/scenegraph/util/qsgareaallocator.cpp deleted file mode 100644 index c5171f1c93..0000000000 --- a/src/declarative/scenegraph/util/qsgareaallocator.cpp +++ /dev/null @@ -1,290 +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 "qsgareaallocator_p.h" - -#include <QtCore/qglobal.h> -#include <QtCore/qrect.h> -#include <QtCore/qpoint.h> - -QT_BEGIN_NAMESPACE - -namespace -{ - enum SplitType - { - VerticalSplit, - HorizontalSplit - }; - - static const int maxMargin = 2; -} - -struct QSGAreaAllocatorNode -{ - QSGAreaAllocatorNode(QSGAreaAllocatorNode *parent); - ~QSGAreaAllocatorNode(); - inline bool isLeaf(); - - QSGAreaAllocatorNode *parent; - QSGAreaAllocatorNode *left; - QSGAreaAllocatorNode *right; - int split; // only valid for inner nodes. - SplitType splitType; - bool isOccupied; // only valid for leaf nodes. -}; - -QSGAreaAllocatorNode::QSGAreaAllocatorNode(QSGAreaAllocatorNode *parent) - : parent(parent) - , left(0) - , right(0) - , isOccupied(false) -{ -} - -QSGAreaAllocatorNode::~QSGAreaAllocatorNode() -{ - delete left; - delete right; -} - -bool QSGAreaAllocatorNode::isLeaf() -{ - Q_ASSERT((left != 0) == (right != 0)); - return !left; -} - - -QSGAreaAllocator::QSGAreaAllocator(const QSize &size) : m_size(size) -{ - m_root = new QSGAreaAllocatorNode(0); -} - -QSGAreaAllocator::~QSGAreaAllocator() -{ - delete m_root; -} - -QRect QSGAreaAllocator::allocate(const QSize &size) -{ - QPoint point; - bool result = allocateInNode(size, point, QRect(QPoint(0, 0), m_size), m_root); - return result ? QRect(point, size) : QRect(); -} - -bool QSGAreaAllocator::deallocate(const QRect &rect) -{ - return deallocateInNode(rect.topLeft(), m_root); -} - -bool QSGAreaAllocator::allocateInNode(const QSize &size, QPoint &result, const QRect ¤tRect, QSGAreaAllocatorNode *node) -{ - if (size.width() > currentRect.width() || size.height() > currentRect.height()) - return false; - - if (node->isLeaf()) { - if (node->isOccupied) - return false; - if (size.width() + maxMargin >= currentRect.width() && size.height() + maxMargin >= currentRect.height()) { - //Snug fit, occupy entire rectangle. - node->isOccupied = true; - result = currentRect.topLeft(); - return true; - } - // TODO: Reuse nodes. - // Split node. - node->left = new QSGAreaAllocatorNode(node); - node->right = new QSGAreaAllocatorNode(node); - QRect splitRect = currentRect; - if ((currentRect.width() - size.width()) * currentRect.height() < (currentRect.height() - size.height()) * currentRect.width()) { - node->splitType = HorizontalSplit; - node->split = currentRect.top() + size.height(); - splitRect.setHeight(size.height()); - } else { - node->splitType = VerticalSplit; - node->split = currentRect.left() + size.width(); - splitRect.setWidth(size.width()); - } - return allocateInNode(size, result, splitRect, node->left); - } else { - // TODO: avoid unnecessary recursion. - // has been split. - QRect leftRect = currentRect; - QRect rightRect = currentRect; - if (node->splitType == HorizontalSplit) { - leftRect.setHeight(node->split - leftRect.top()); - rightRect.setTop(node->split); - } else { - leftRect.setWidth(node->split - leftRect.left()); - rightRect.setLeft(node->split); - } - if (allocateInNode(size, result, leftRect, node->left)) - return true; - if (allocateInNode(size, result, rightRect, node->right)) - return true; - return false; - } -} - -bool QSGAreaAllocator::deallocateInNode(const QPoint &pos, QSGAreaAllocatorNode *node) -{ - while (!node->isLeaf()) { - // has been split. - int cmp = node->splitType == HorizontalSplit ? pos.y() : pos.x(); - node = cmp < node->split ? node->left : node->right; - } - if (!node->isOccupied) - return false; - node->isOccupied = false; - mergeNodeWithNeighbors(node); - return true; -} - -void QSGAreaAllocator::mergeNodeWithNeighbors(QSGAreaAllocatorNode *node) -{ - bool done = false; - QSGAreaAllocatorNode *parent = 0; - QSGAreaAllocatorNode *current = 0; - QSGAreaAllocatorNode *sibling; - while (!done) { - Q_ASSERT(node->isLeaf()); - Q_ASSERT(!node->isOccupied); - if (node->parent == 0) - return; // No neighbours. - - SplitType splitType = SplitType(node->parent->splitType); - done = true; - - /* Special case. Might be faster than going through the general code path. - // Merge with sibling. - parent = node->parent; - sibling = (node == parent->left ? parent->right : parent->left); - if (sibling->isLeaf() && !sibling->isOccupied) { - Q_ASSERT(!sibling->right); - node = parent; - parent->isOccupied = false; - delete parent->left; - delete parent->right; - parent->left = parent->right = 0; - done = false; - continue; - } - */ - - // Merge with left neighbour. - current = node; - parent = current->parent; - while (parent && current == parent->left && parent->splitType == splitType) { - current = parent; - parent = parent->parent; - } - - if (parent && parent->splitType == splitType) { - Q_ASSERT(current == parent->right); - Q_ASSERT(parent->left); - - QSGAreaAllocatorNode *neighbor = parent->left; - while (neighbor->right && neighbor->splitType == splitType) - neighbor = neighbor->right; - - if (neighbor->isLeaf() && neighbor->parent->splitType == splitType && !neighbor->isOccupied) { - // Left neighbour can be merged. - parent->split = neighbor->parent->split; - - parent = neighbor->parent; - sibling = neighbor == parent->left ? parent->right : parent->left; - QSGAreaAllocatorNode **nodeRef = &m_root; - if (parent->parent) { - if (parent == parent->parent->left) - nodeRef = &parent->parent->left; - else - nodeRef = &parent->parent->right; - } - sibling->parent = parent->parent; - *nodeRef = sibling; - parent->left = parent->right = 0; - delete parent; - delete neighbor; - done = false; - } - } - - // Merge with right neighbour. - current = node; - parent = current->parent; - while (parent && current == parent->right && parent->splitType == splitType) { - current = parent; - parent = parent->parent; - } - - if (parent && parent->splitType == splitType) { - Q_ASSERT(current == parent->left); - Q_ASSERT(parent->right); - - QSGAreaAllocatorNode *neighbor = parent->right; - while (neighbor->left && neighbor->splitType == splitType) - neighbor = neighbor->left; - - if (neighbor->isLeaf() && neighbor->parent->splitType == splitType && !neighbor->isOccupied) { - // Right neighbour can be merged. - parent->split = neighbor->parent->split; - - parent = neighbor->parent; - sibling = neighbor == parent->left ? parent->right : parent->left; - QSGAreaAllocatorNode **nodeRef = &m_root; - if (parent->parent) { - if (parent == parent->parent->left) - nodeRef = &parent->parent->left; - else - nodeRef = &parent->parent->right; - } - sibling->parent = parent->parent; - *nodeRef = sibling; - parent->left = parent->right = 0; - delete parent; - delete neighbor; - done = false; - } - } - } // end while(!done) -} - -QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/util/qsgareaallocator_p.h b/src/declarative/scenegraph/util/qsgareaallocator_p.h deleted file mode 100644 index fd79d4c67a..0000000000 --- a/src/declarative/scenegraph/util/qsgareaallocator_p.h +++ /dev/null @@ -1,73 +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 AREAALLOCATOR_H -#define AREAALLOCATOR_H - -#include <QtCore/qsize.h> - -QT_BEGIN_NAMESPACE - -class QRect; -class QPoint; -struct QSGAreaAllocatorNode; -class Q_DECLARATIVE_EXPORT QSGAreaAllocator -{ -public: - QSGAreaAllocator(const QSize &size); - ~QSGAreaAllocator(); - - QRect allocate(const QSize &size); - bool deallocate(const QRect &rect); - bool isEmpty() const { return m_root == 0; } - QSize size() const { return m_size; } -private: - bool allocateInNode(const QSize &size, QPoint &result, const QRect ¤tRect, QSGAreaAllocatorNode *node); - bool deallocateInNode(const QPoint &pos, QSGAreaAllocatorNode *node); - void mergeNodeWithNeighbors(QSGAreaAllocatorNode *node); - - QSGAreaAllocatorNode *m_root; - QSize m_size; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/declarative/scenegraph/util/qsgdistancefieldutil.cpp b/src/declarative/scenegraph/util/qsgdistancefieldutil.cpp deleted file mode 100644 index 3429162d6b..0000000000 --- a/src/declarative/scenegraph/util/qsgdistancefieldutil.cpp +++ /dev/null @@ -1,805 +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 "qsgdistancefieldutil_p.h" - -#include <qmath.h> -#include <private/qsgpathsimplifier_p.h> -#include <private/qsgadaptationlayer_p.h> -#include <QtGui/private/qopenglengineshadersource_p.h> -#include <private/qsgcontext_p.h> - -QT_BEGIN_NAMESPACE - -static float defaultThresholdFunc(float glyphScale) -{ - static float base = qgetenv("QT_DF_BASE").isEmpty() ? 0.5f : qgetenv("QT_DF_BASE").toFloat(); - static float baseDev = qgetenv("QT_DF_BASEDEVIATION").isEmpty() ? 0.065f : qgetenv("QT_DF_BASEDEVIATION").toFloat(); - static float devScaleMin = qgetenv("QT_DF_SCALEFORMAXDEV").isEmpty() ? 0.15f : qgetenv("QT_DF_SCALEFORMAXDEV").toFloat(); - static float devScaleMax = qgetenv("QT_DF_SCALEFORNODEV").isEmpty() ? 0.3f : qgetenv("QT_DF_SCALEFORNODEV").toFloat(); - return base - ((qBound(devScaleMin, glyphScale, devScaleMax) - devScaleMin) / (devScaleMax - devScaleMin) * -baseDev + baseDev); -} - -static float defaultAntialiasingSpreadFunc(float glyphScale) -{ - static float range = qgetenv("QT_DF_RANGE").isEmpty() ? 0.06f : qgetenv("QT_DF_RANGE").toFloat(); - return range / glyphScale; -} - -namespace -{ - enum FillHDir - { - LeftToRight, - RightToLeft - }; - - enum FillVDir - { - TopDown, - BottomUp - }; - - enum FillClip - { - NoClip, - Clip - }; -} - -template <FillClip clip, FillHDir dir> -inline void fillLine(qint32 *, int, int, int, qint32, qint32) -{ -} - -template <> -inline void fillLine<Clip, LeftToRight>(qint32 *line, int width, int lx, int rx, qint32 d, qint32 dd) -{ - int fromX = qMax(0, lx >> 8); - int toX = qMin(width, rx >> 8); - int x = toX - fromX; - if (x <= 0) - return; - qint32 val = d + (((fromX << 8) + 0xff - lx) * dd >> 8); - line += fromX; - do { - *line = abs(val) < abs(*line) ? val : *line; - val += dd; - ++line; - } while (--x); -} - -template <> -inline void fillLine<Clip, RightToLeft>(qint32 *line, int width, int lx, int rx, qint32 d, qint32 dd) -{ - int fromX = qMax(0, lx >> 8); - int toX = qMin(width, rx >> 8); - int x = toX - fromX; - if (x <= 0) - return; - qint32 val = d + (((toX << 8) + 0xff - rx) * dd >> 8); - line += toX; - do { - val -= dd; - --line; - *line = abs(val) < abs(*line) ? val : *line; - } while (--x); -} - -template <> -inline void fillLine<NoClip, LeftToRight>(qint32 *line, int, int lx, int rx, qint32 d, qint32 dd) -{ - int fromX = lx >> 8; - int toX = rx >> 8; - int x = toX - fromX; - if (x <= 0) - return; - qint32 val = d + ((~lx & 0xff) * dd >> 8); - line += fromX; - do { - *line = abs(val) < abs(*line) ? val : *line; - val += dd; - ++line; - } while (--x); -} - -template <> -inline void fillLine<NoClip, RightToLeft>(qint32 *line, int, int lx, int rx, qint32 d, qint32 dd) -{ - int fromX = lx >> 8; - int toX = rx >> 8; - int x = toX - fromX; - if (x <= 0) - return; - qint32 val = d + ((~rx & 0xff) * dd >> 8); - line += toX; - do { - val -= dd; - --line; - *line = abs(val) < abs(*line) ? val : *line; - } while (--x); -} - -template <FillClip clip, FillVDir vDir, FillHDir hDir> -inline void fillLines(qint32 *bits, int width, int height, int upperY, int lowerY, - int &lx, int ldx, int &rx, int rdx, qint32 &d, qint32 ddy, qint32 ddx) -{ - Q_UNUSED(height); - Q_ASSERT(upperY < lowerY); - int y = lowerY - upperY; - if (vDir == TopDown) { - qint32 *line = bits + upperY * width; - do { - fillLine<clip, hDir>(line, width, lx, rx, d, ddx); - lx += ldx; - d += ddy; - rx += rdx; - line += width; - } while (--y); - } else { - qint32 *line = bits + lowerY * width; - do { - lx -= ldx; - d -= ddy; - rx -= rdx; - line -= width; - fillLine<clip, hDir>(line, width, lx, rx, d, ddx); - } while (--y); - } -} - -template <FillClip clip> -void drawTriangle(qint32 *bits, int width, int height, const QPoint *center, - const QPoint *v1, const QPoint *v2, qint32 value) -{ - const int y1 = clip == Clip ? qBound(0, v1->y() >> 8, height) : v1->y() >> 8; - const int y2 = clip == Clip ? qBound(0, v2->y() >> 8, height) : v2->y() >> 8; - const int yC = clip == Clip ? qBound(0, center->y() >> 8, height) : center->y() >> 8; - - const int v1Frac = clip == Clip ? (y1 << 8) + 0xff - v1->y() : ~v2->y() & 0xff; - const int v2Frac = clip == Clip ? (y2 << 8) + 0xff - v2->y() : ~v1->y() & 0xff; - const int centerFrac = clip == Clip ? (yC << 8) + 0xff - center->y() : ~center->y() & 0xff; - - int dx1 = 0, x1 = 0, dx2 = 0, x2 = 0; - qint32 dd1, d1, dd2, d2; - if (v1->y() != center->y()) { - dx1 = ((v1->x() - center->x()) << 8) / (v1->y() - center->y()); - x1 = center->x() + centerFrac * (v1->x() - center->x()) / (v1->y() - center->y()); - } - if (v2->y() != center->y()) { - dx2 = ((v2->x() - center->x()) << 8) / (v2->y() - center->y()); - x2 = center->x() + centerFrac * (v2->x() - center->x()) / (v2->y() - center->y()); - } - - const qint32 div = (v2->x() - center->x()) * (v1->y() - center->y()) - - (v2->y() - center->y()) * (v1->x() - center->x()); - const qint32 dd = div ? qint32((qint64(value * (v1->y() - v2->y())) << 8) / div) : 0; - - if (y2 < yC) { - if (y1 < yC) { - // Center at the bottom. - if (y2 < y1) { - // y2 < y1 < yC - // Long right edge. - d1 = centerFrac * value / (v1->y() - center->y()); - dd1 = ((value << 8) / (v1->y() - center->y())); - fillLines<clip, BottomUp, LeftToRight>(bits, width, height, y1, yC, x1, dx1, - x2, dx2, d1, dd1, dd); - dx1 = ((v1->x() - v2->x()) << 8) / (v1->y() - v2->y()); - x1 = v1->x() + v1Frac * (v1->x() - v2->x()) / (v1->y() - v2->y()); - fillLines<clip, BottomUp, LeftToRight>(bits, width, height, y2, y1, x1, dx1, - x2, dx2, value, 0, dd); - } else { - // y1 <= y2 < yC - // Long left edge. - d2 = centerFrac * value / (v2->y() - center->y()); - dd2 = ((value << 8) / (v2->y() - center->y())); - fillLines<clip, BottomUp, RightToLeft>(bits, width, height, y2, yC, x1, dx1, - x2, dx2, d2, dd2, dd); - if (y1 != y2) { - dx2 = ((v1->x() - v2->x()) << 8) / (v1->y() - v2->y()); - x2 = v2->x() + v2Frac * (v1->x() - v2->x()) / (v1->y() - v2->y()); - fillLines<clip, BottomUp, RightToLeft>(bits, width, height, y1, y2, x1, dx1, - x2, dx2, value, 0, dd); - } - } - } else { - // y2 < yC <= y1 - // Center to the right. - int dx = ((v1->x() - v2->x()) << 8) / (v1->y() - v2->y()); - int xUp, xDn; - xUp = xDn = v2->x() + (clip == Clip ? (yC << 8) + 0xff - v2->y() - : (center->y() | 0xff) - v2->y()) - * (v1->x() - v2->x()) / (v1->y() - v2->y()); - fillLines<clip, BottomUp, LeftToRight>(bits, width, height, y2, yC, xUp, dx, - x2, dx2, value, 0, dd); - if (yC != y1) - fillLines<clip, TopDown, LeftToRight>(bits, width, height, yC, y1, xDn, dx, - x1, dx1, value, 0, dd); - } - } else { - if (y1 < yC) { - // y1 < yC <= y2 - // Center to the left. - int dx = ((v1->x() - v2->x()) << 8) / (v1->y() - v2->y()); - int xUp, xDn; - xUp = xDn = v1->x() + (clip == Clip ? (yC << 8) + 0xff - v1->y() - : (center->y() | 0xff) - v1->y()) - * (v1->x() - v2->x()) / (v1->y() - v2->y()); - fillLines<clip, BottomUp, RightToLeft>(bits, width, height, y1, yC, x1, dx1, - xUp, dx, value, 0, dd); - if (yC != y2) - fillLines<clip, TopDown, RightToLeft>(bits, width, height, yC, y2, x2, dx2, - xDn, dx, value, 0, dd); - } else { - // Center at the top. - if (y2 < y1) { - // yC <= y2 < y1 - // Long right edge. - if (yC != y2) { - d2 = centerFrac * value / (v2->y() - center->y()); - dd2 = ((value << 8) / (v2->y() - center->y())); - fillLines<clip, TopDown, LeftToRight>(bits, width, height, yC, y2, x2, dx2, - x1, dx1, d2, dd2, dd); - } - dx2 = ((v1->x() - v2->x()) << 8) / (v1->y() - v2->y()); - x2 = v2->x() + v2Frac * (v1->x() - v2->x()) / (v1->y() - v2->y()); - fillLines<clip, TopDown, LeftToRight>(bits, width, height, y2, y1, x2, dx2, - x1, dx1, value, 0, dd); - } else { - // Long left edge. - // yC <= y1 <= y2 - if (yC != y1) { - d1 = centerFrac * value / (v1->y() - center->y()); - dd1 = ((value << 8) / (v1->y() - center->y())); - fillLines<clip, TopDown, RightToLeft>(bits, width, height, yC, y1, x2, dx2, - x1, dx1, d1, dd1, dd); - } - if (y1 != y2) { - dx1 = ((v1->x() - v2->x()) << 8) / (v1->y() - v2->y()); - x1 = v1->x() + v1Frac * (v1->x() - v2->x()) / (v1->y() - v2->y()); - fillLines<clip, TopDown, RightToLeft>(bits, width, height, y1, y2, x2, dx2, - x1, dx1, value, 0, dd); - } - } - } - } -} - -template <FillClip clip> -void drawRectangle(qint32 *bits, int width, int height, - const QPoint *int1, const QPoint *center1, const QPoint *ext1, - const QPoint *int2, const QPoint *center2, const QPoint *ext2, - qint32 extValue) -{ - if (center1->y() > center2->y()) { - qSwap(center1, center2); - qSwap(int1, ext2); - qSwap(ext1, int2); - extValue = -extValue; - } - - Q_ASSERT(ext1->x() - center1->x() == center1->x() - int1->x()); - Q_ASSERT(ext1->y() - center1->y() == center1->y() - int1->y()); - Q_ASSERT(ext2->x() - center2->x() == center2->x() - int2->x()); - Q_ASSERT(ext2->y() - center2->y() == center2->y() - int2->y()); - - const int yc1 = clip == Clip ? qBound(0, center1->y() >> 8, height) : center1->y() >> 8; - const int yc2 = clip == Clip ? qBound(0, center2->y() >> 8, height) : center2->y() >> 8; - const int yi1 = clip == Clip ? qBound(0, int1->y() >> 8, height) : int1->y() >> 8; - const int yi2 = clip == Clip ? qBound(0, int2->y() >> 8, height) : int2->y() >> 8; - const int ye1 = clip == Clip ? qBound(0, ext1->y() >> 8, height) : ext1->y() >> 8; - const int ye2 = clip == Clip ? qBound(0, ext2->y() >> 8, height) : ext2->y() >> 8; - - const int center1Frac = clip == Clip ? (yc1 << 8) + 0xff - center1->y() : ~center1->y() & 0xff; - const int center2Frac = clip == Clip ? (yc2 << 8) + 0xff - center2->y() : ~center2->y() & 0xff; - const int int1Frac = clip == Clip ? (yi1 << 8) + 0xff - int1->y() : ~int1->y() & 0xff; - const int ext1Frac = clip == Clip ? (ye1 << 8) + 0xff - ext1->y() : ~ext1->y() & 0xff; - - int dxC = 0, dxE = 0; // cap slope, edge slope - qint32 ddC = 0; - if (ext1->y() != int1->y()) { - dxC = ((ext1->x() - int1->x()) << 8) / (ext1->y() - int1->y()); - ddC = (extValue << 9) / (ext1->y() - int1->y()); - } - if (ext1->y() != ext2->y()) - dxE = ((ext1->x() - ext2->x()) << 8) / (ext1->y() - ext2->y()); - - const qint32 div = (ext1->x() - int1->x()) * (ext2->y() - int1->y()) - - (ext1->y() - int1->y()) * (ext2->x() - int1->x()); - const qint32 dd = div ? qint32((qint64(extValue * (ext2->y() - ext1->y())) << 9) / div) : 0; - - int xe1, xe2, xc1, xc2; - qint32 d; - - qint32 intValue = -extValue; - - if (center2->x() < center1->x()) { - // Leaning to the right. '/' - if (int1->y() < ext2->y()) { - // Mostly vertical. - Q_ASSERT(ext1->y() != ext2->y()); - xe1 = ext1->x() + ext1Frac * (ext1->x() - ext2->x()) / (ext1->y() - ext2->y()); - xe2 = int1->x() + int1Frac * (ext1->x() - ext2->x()) / (ext1->y() - ext2->y()); - if (ye1 != yi1) { - xc2 = center1->x() + center1Frac * (ext1->x() - int1->x()) / (ext1->y() - int1->y()); - xc2 += (ye1 - yc1) * dxC; - fillLines<clip, TopDown, LeftToRight>(bits, width, height, ye1, yi1, xe1, dxE, - xc2, dxC, extValue, 0, dd); - } - if (yi1 != ye2) - fillLines<clip, TopDown, LeftToRight>(bits, width, height, yi1, ye2, xe1, dxE, - xe2, dxE, extValue, 0, dd); - if (ye2 != yi2) { - xc1 = center2->x() + center2Frac * (ext1->x() - int1->x()) / (ext1->y() - int1->y()); - xc1 += (ye2 - yc2) * dxC; - fillLines<clip, TopDown, RightToLeft>(bits, width, height, ye2, yi2, xc1, dxC, - xe2, dxE, intValue, 0, dd); - } - } else { - // Mostly horizontal. - Q_ASSERT(ext1->y() != int1->y()); - xc1 = center2->x() + center2Frac * (ext1->x() - int1->x()) / (ext1->y() - int1->y()); - xc2 = center1->x() + center1Frac * (ext1->x() - int1->x()) / (ext1->y() - int1->y()); - xc1 += (ye2 - yc2) * dxC; - xc2 += (ye1 - yc1) * dxC; - if (ye1 != ye2) { - xe1 = ext1->x() + ext1Frac * (ext1->x() - ext2->x()) / (ext1->y() - ext2->y()); - fillLines<clip, TopDown, LeftToRight>(bits, width, height, ye1, ye2, xe1, dxE, - xc2, dxC, extValue, 0, dd); - } - if (ye2 != yi1) { - d = (clip == Clip ? (ye2 << 8) + 0xff - center2->y() - : (ext2->y() | 0xff) - center2->y()) - * 2 * extValue / (ext1->y() - int1->y()); - fillLines<clip, TopDown, LeftToRight>(bits, width, height, ye2, yi1, xc1, dxC, - xc2, dxC, d, ddC, dd); - } - if (yi1 != yi2) { - xe2 = int1->x() + int1Frac * (ext1->x() - ext2->x()) / (ext1->y() - ext2->y()); - fillLines<clip, TopDown, RightToLeft>(bits, width, height, yi1, yi2, xc1, dxC, - xe2, dxE, intValue, 0, dd); - } - } - } else { - // Leaning to the left. '\' - if (ext1->y() < int2->y()) { - // Mostly vertical. - Q_ASSERT(ext1->y() != ext2->y()); - xe1 = ext1->x() + ext1Frac * (ext1->x() - ext2->x()) / (ext1->y() - ext2->y()); - xe2 = int1->x() + int1Frac * (ext1->x() - ext2->x()) / (ext1->y() - ext2->y()); - if (yi1 != ye1) { - xc1 = center1->x() + center1Frac * (ext1->x() - int1->x()) / (ext1->y() - int1->y()); - xc1 += (yi1 - yc1) * dxC; - fillLines<clip, TopDown, RightToLeft>(bits, width, height, yi1, ye1, xc1, dxC, - xe2, dxE, intValue, 0, dd); - } - if (ye1 != yi2) - fillLines<clip, TopDown, RightToLeft>(bits, width, height, ye1, yi2, xe1, dxE, - xe2, dxE, intValue, 0, dd); - if (yi2 != ye2) { - xc2 = center2->x() + center2Frac * (ext1->x() - int1->x()) / (ext1->y() - int1->y()); - xc2 += (yi2 - yc2) * dxC; - fillLines<clip, TopDown, LeftToRight>(bits, width, height, yi2, ye2, xe1, dxE, - xc2, dxC, extValue, 0, dd); - } - } else { - // Mostly horizontal. - Q_ASSERT(ext1->y() != int1->y()); - xc1 = center1->x() + center1Frac * (ext1->x() - int1->x()) / (ext1->y() - int1->y()); - xc2 = center2->x() + center2Frac * (ext1->x() - int1->x()) / (ext1->y() - int1->y()); - xc1 += (yi1 - yc1) * dxC; - xc2 += (yi2 - yc2) * dxC; - if (yi1 != yi2) { - xe2 = int1->x() + int1Frac * (ext1->x() - ext2->x()) / (ext1->y() - ext2->y()); - fillLines<clip, TopDown, RightToLeft>(bits, width, height, yi1, yi2, xc1, dxC, - xe2, dxE, intValue, 0, dd); - } - if (yi2 != ye1) { - d = (clip == Clip ? (yi2 << 8) + 0xff - center2->y() - : (int2->y() | 0xff) - center2->y()) - * 2 * extValue / (ext1->y() - int1->y()); - fillLines<clip, TopDown, RightToLeft>(bits, width, height, yi2, ye1, xc1, dxC, - xc2, dxC, d, ddC, dd); - } - if (ye1 != ye2) { - xe1 = ext1->x() + ext1Frac * (ext1->x() - ext2->x()) / (ext1->y() - ext2->y()); - fillLines<clip, TopDown, LeftToRight>(bits, width, height, ye1, ye2, xe1, dxE, - xc2, dxC, extValue, 0, dd); - } - } - } -} - -static void drawPolygons(qint32 *bits, int width, int height, const QPoint *vertices, - const quint32 *indices, int indexCount, qint32 value) -{ - Q_ASSERT(indexCount != 0); - Q_ASSERT(height <= 128); - QVarLengthArray<quint8, 16> scans[128]; - int first = 0; - for (int i = 1; i < indexCount; ++i) { - quint32 idx1 = indices[i - 1]; - quint32 idx2 = indices[i]; - Q_ASSERT(idx1 != quint32(-1)); - if (idx2 == quint32(-1)) { - idx2 = indices[first]; - Q_ASSERT(idx2 != quint32(-1)); - first = ++i; - } - const QPoint *v1 = &vertices[idx1]; - const QPoint *v2 = &vertices[idx2]; - if (v2->y() < v1->y()) - qSwap(v1, v2); - int fromY = qMax(0, v1->y() >> 8); - int toY = qMin(height, v2->y() >> 8); - if (fromY >= toY) - continue; - int dx = ((v2->x() - v1->x()) << 8) / (v2->y() - v1->y()); - int x = v1->x() + ((fromY << 8) + 0xff - v1->y()) * (v2->x() - v1->x()) / (v2->y() - v1->y()); - for (int y = fromY; y < toY; ++y) { - quint32 c = quint32(x >> 8); - if (c < quint32(width)) - scans[y].append(quint8(c)); - x += dx; - } - } - for (int i = 0; i < height; ++i) { - quint8 *scanline = scans[i].data(); - int size = scans[i].size(); - for (int j = 1; j < size; ++j) { - int k = j; - quint8 value = scanline[k]; - for (; k != 0 && value < scanline[k - 1]; --k) - scanline[k] = scanline[k - 1]; - scanline[k] = value; - } - qint32 *line = bits + i * width; - int j = 0; - for (; j + 1 < size; j += 2) { - for (quint8 x = scanline[j]; x < scanline[j + 1]; ++x) - line[x] = value; - } - if (j < size) { - for (int x = scanline[j]; x < width; ++x) - line[x] = value; - } - } -} - -static QImage makeDistanceField(int imgSize, const QPainterPath &path, int dfScale, int offs) -{ - QImage image(imgSize, imgSize, QImage::Format_Indexed8); - - if (path.isEmpty()) { - image.fill(0); - return image; - } - - QTransform transform; - transform.translate(offs, offs); - transform.scale(qreal(1) / dfScale, qreal(1) / dfScale); - - QDataBuffer<quint32> pathIndices(0); - QDataBuffer<QPoint> pathVertices(0); - qSimplifyPath(path, pathVertices, pathIndices, transform); - - const qint32 interiorColor = -0x7f80; // 8:8 signed format, -127.5 - const qint32 exteriorColor = 0x7f80; // 8:8 signed format, 127.5 - - QScopedArrayPointer<qint32> bits(new qint32[imgSize * imgSize]); - for (int i = 0; i < imgSize * imgSize; ++i) - bits[i] = exteriorColor; - - const qreal angleStep = qreal(15 * 3.141592653589793238 / 180); - const QPoint rotation(qRound(cos(angleStep) * 0x4000), - qRound(sin(angleStep) * 0x4000)); // 2:14 signed - - const quint32 *indices = pathIndices.data(); - QVarLengthArray<QPoint> normals; - QVarLengthArray<QPoint> vertices; - QVarLengthArray<bool> isConvex; - QVarLengthArray<bool> needsClipping; - - drawPolygons(bits.data(), imgSize, imgSize, pathVertices.data(), indices, pathIndices.size(), - interiorColor); - - int index = 0; - - while (index < pathIndices.size()) { - normals.clear(); - vertices.clear(); - needsClipping.clear(); - - // Find end of polygon. - int end = index; - while (indices[end] != quint32(-1)) - ++end; - - // Calculate vertex normals. - for (int next = index, prev = end - 1; next < end; prev = next++) { - quint32 fromVertexIndex = indices[prev]; - quint32 toVertexIndex = indices[next]; - - const QPoint &from = pathVertices.at(fromVertexIndex); - const QPoint &to = pathVertices.at(toVertexIndex); - - QPoint n(to.y() - from.y(), from.x() - to.x()); - if (n.x() == 0 && n.y() == 0) - continue; - int scale = qRound((offs << 16) / sqrt(qreal(n.x() * n.x() + n.y() * n.y()))); // 8:16 - n.rx() = n.x() * scale >> 8; - n.ry() = n.y() * scale >> 8; - normals.append(n); - QPoint v(to.x() + 0x7f, to.y() + 0x7f); - vertices.append(v); - needsClipping.append((to.x() < offs << 8) || (to.x() >= (imgSize - offs) << 8) - || (to.y() < offs << 8) || (to.y() >= (imgSize - offs) << 8)); - } - - isConvex.resize(normals.count()); - for (int next = 0, prev = normals.count() - 1; next < normals.count(); prev = next++) { - isConvex[prev] = normals.at(prev).x() * normals.at(next).y() - - normals.at(prev).y() * normals.at(next).x() < 0; - } - - // Draw quads. - for (int next = 0, prev = normals.count() - 1; next < normals.count(); prev = next++) { - QPoint n = normals.at(next); - QPoint intPrev = vertices.at(prev); - QPoint extPrev = vertices.at(prev); - QPoint intNext = vertices.at(next); - QPoint extNext = vertices.at(next); - - extPrev.rx() -= n.x(); - extPrev.ry() -= n.y(); - intPrev.rx() += n.x(); - intPrev.ry() += n.y(); - extNext.rx() -= n.x(); - extNext.ry() -= n.y(); - intNext.rx() += n.x(); - intNext.ry() += n.y(); - - if (needsClipping[prev] || needsClipping[next]) { - drawRectangle<Clip>(bits.data(), imgSize, imgSize, - &intPrev, &vertices.at(prev), &extPrev, - &intNext, &vertices.at(next), &extNext, - exteriorColor); - } else { - drawRectangle<NoClip>(bits.data(), imgSize, imgSize, - &intPrev, &vertices.at(prev), &extPrev, - &intNext, &vertices.at(next), &extNext, - exteriorColor); - } - - if (isConvex.at(prev)) { - QPoint p = extPrev; - if (needsClipping[prev]) { - for (;;) { - QPoint rn((n.x() * rotation.x() - n.y() * rotation.y()) >> 14, - (n.y() * rotation.x() + n.x() * rotation.y()) >> 14); - n = rn; - if (n.x() * normals.at(prev).y() - n.y() * normals.at(prev).x() <= 0) { - p.rx() = vertices.at(prev).x() - normals.at(prev).x(); - p.ry() = vertices.at(prev).y() - normals.at(prev).y(); - drawTriangle<Clip>(bits.data(), imgSize, imgSize, &vertices.at(prev), - &extPrev, &p, exteriorColor); - break; - } - - p.rx() = vertices.at(prev).x() - n.x(); - p.ry() = vertices.at(prev).y() - n.y(); - drawTriangle<Clip>(bits.data(), imgSize, imgSize, &vertices.at(prev), - &extPrev, &p, exteriorColor); - extPrev = p; - } - } else { - for (;;) { - QPoint rn((n.x() * rotation.x() - n.y() * rotation.y()) >> 14, - (n.y() * rotation.x() + n.x() * rotation.y()) >> 14); - n = rn; - if (n.x() * normals.at(prev).y() - n.y() * normals.at(prev).x() <= 0) { - p.rx() = vertices.at(prev).x() - normals.at(prev).x(); - p.ry() = vertices.at(prev).y() - normals.at(prev).y(); - drawTriangle<NoClip>(bits.data(), imgSize, imgSize, &vertices.at(prev), - &extPrev, &p, exteriorColor); - break; - } - - p.rx() = vertices.at(prev).x() - n.x(); - p.ry() = vertices.at(prev).y() - n.y(); - drawTriangle<NoClip>(bits.data(), imgSize, imgSize, &vertices.at(prev), - &extPrev, &p, exteriorColor); - extPrev = p; - } - } - } else { - QPoint p = intPrev; - if (needsClipping[prev]) { - for (;;) { - QPoint rn((n.x() * rotation.x() + n.y() * rotation.y()) >> 14, - (n.y() * rotation.x() - n.x() * rotation.y()) >> 14); - n = rn; - if (n.x() * normals.at(prev).y() - n.y() * normals.at(prev).x() >= 0) { - p.rx() = vertices.at(prev).x() + normals.at(prev).x(); - p.ry() = vertices.at(prev).y() + normals.at(prev).y(); - drawTriangle<Clip>(bits.data(), imgSize, imgSize, &vertices.at(prev), - &p, &intPrev, interiorColor); - break; - } - - p.rx() = vertices.at(prev).x() + n.x(); - p.ry() = vertices.at(prev).y() + n.y(); - drawTriangle<Clip>(bits.data(), imgSize, imgSize, &vertices.at(prev), - &p, &intPrev, interiorColor); - intPrev = p; - } - } else { - for (;;) { - QPoint rn((n.x() * rotation.x() + n.y() * rotation.y()) >> 14, - (n.y() * rotation.x() - n.x() * rotation.y()) >> 14); - n = rn; - if (n.x() * normals.at(prev).y() - n.y() * normals.at(prev).x() >= 0) { - p.rx() = vertices.at(prev).x() + normals.at(prev).x(); - p.ry() = vertices.at(prev).y() + normals.at(prev).y(); - drawTriangle<NoClip>(bits.data(), imgSize, imgSize, &vertices.at(prev), - &p, &intPrev, interiorColor); - break; - } - - p.rx() = vertices.at(prev).x() + n.x(); - p.ry() = vertices.at(prev).y() + n.y(); - drawTriangle<NoClip>(bits.data(), imgSize, imgSize, &vertices.at(prev), - &p, &intPrev, interiorColor); - intPrev = p; - } - } - } - } - - index = end + 1; - } - - const qint32 *inLine = bits.data(); - uchar *outLine = image.bits(); - int padding = image.bytesPerLine() - image.width(); - for (int y = 0; y < imgSize; ++y) { - for (int x = 0; x < imgSize; ++x, ++inLine, ++outLine) - *outLine = uchar((0x7f80 - *inLine) >> 8); - outLine += padding; - } - - return image; -} - -bool qt_fontHasNarrowOutlines(const QRawFont &f) -{ - QRawFont font = f; - font.setPixelSize(QT_DISTANCEFIELD_DEFAULT_BASEFONTSIZE); - Q_ASSERT(font.isValid()); - - QVector<quint32> glyphIndices = font.glyphIndexesForString(QLatin1String("O")); - if (glyphIndices.size() < 1) - return false; - - QImage im = font.alphaMapForGlyph(glyphIndices.at(0), QRawFont::PixelAntialiasing); - if (im.isNull()) - return false; - - int minHThick = 999; - int minVThick = 999; - - int thick = 0; - bool in = false; - int y = (im.height() + 1) / 2; - for (int x = 0; x < im.width(); ++x) { - int a = qAlpha(im.pixel(x, y)); - if (a > 127) { - in = true; - ++thick; - } else if (in) { - in = false; - minHThick = qMin(minHThick, thick); - thick = 0; - } - } - - thick = 0; - in = false; - int x = (im.width() + 1) / 2; - for (int y = 0; y < im.height(); ++y) { - int a = qAlpha(im.pixel(x, y)); - if (a > 127) { - in = true; - ++thick; - } else if (in) { - in = false; - minVThick = qMin(minVThick, thick); - thick = 0; - } - } - - return minHThick == 1 || minVThick == 1; -} - -QImage qt_renderDistanceFieldGlyph(const QRawFont &font, glyph_t glyph, bool doubleResolution) -{ - QRawFont renderFont = font; - renderFont.setPixelSize(QT_DISTANCEFIELD_BASEFONTSIZE(doubleResolution) * QT_DISTANCEFIELD_SCALE(doubleResolution)); - - QPainterPath path = renderFont.pathForGlyph(glyph); - path.translate(-path.boundingRect().topLeft()); - path.setFillRule(Qt::WindingFill); - - QImage im = makeDistanceField(QT_DISTANCEFIELD_TILESIZE(doubleResolution), - path, - QT_DISTANCEFIELD_SCALE(doubleResolution), - QT_DISTANCEFIELD_RADIUS(doubleResolution) / QT_DISTANCEFIELD_SCALE(doubleResolution)); - return im; -} - -QSGDistanceFieldGlyphCacheManager::QSGDistanceFieldGlyphCacheManager(QSGContext *c) - : sgCtx(c) - , m_threshold_func(defaultThresholdFunc) - , m_antialiasingSpread_func(defaultAntialiasingSpreadFunc) -{ -#ifndef QT_OPENGL_ES - m_defaultAntialiasingMode = QSGGlyphNode::HighQualitySubPixelAntialiasing; -#else - m_defaultAntialiasingMode = QSGGlyphNode::GrayAntialiasing; -#endif -} - -QSGDistanceFieldGlyphCacheManager::~QSGDistanceFieldGlyphCacheManager() -{ - qDeleteAll(m_caches.values()); -} - -QSGDistanceFieldGlyphCache *QSGDistanceFieldGlyphCacheManager::cache(const QRawFont &font) -{ - QRawFontPrivate *fontD = QRawFontPrivate::get(font); - QHash<QFontEngine *, QSGDistanceFieldGlyphCache *>::iterator cache = m_caches.find(fontD->fontEngine); - if (cache == m_caches.end()) - cache = m_caches.insert(fontD->fontEngine, sgCtx->createDistanceFieldGlyphCache(font)); - return cache.value(); -} - -QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/util/qsgdistancefieldutil_p.h b/src/declarative/scenegraph/util/qsgdistancefieldutil_p.h deleted file mode 100644 index 93dffab76e..0000000000 --- a/src/declarative/scenegraph/util/qsgdistancefieldutil_p.h +++ /dev/null @@ -1,111 +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 QSGDISTANCEFIELDUTIL_H -#define QSGDISTANCEFIELDUTIL_H - -#include <qrawfont.h> -#include <private/qfontengine_p.h> -#include <private/qsgadaptationlayer_p.h> - -QT_BEGIN_NAMESPACE - -#define QT_DISTANCEFIELD_DEFAULT_BASEFONTSIZE 54 -#define QT_DISTANCEFIELD_DEFAULT_TILESIZE 64 -#define QT_DISTANCEFIELD_DEFAULT_SCALE 16 -#define QT_DISTANCEFIELD_DEFAULT_RADIUS 80 -#define QT_DISTANCEFIELD_HIGHGLYPHCOUNT 2000 - -#define QT_DISTANCEFIELD_BASEFONTSIZE(NarrowOutlineFont) \ - (NarrowOutlineFont ? QT_DISTANCEFIELD_DEFAULT_BASEFONTSIZE * 2 : \ - QT_DISTANCEFIELD_DEFAULT_BASEFONTSIZE) -#define QT_DISTANCEFIELD_TILESIZE(NarrowOutlineFont) \ - (NarrowOutlineFont ? QT_DISTANCEFIELD_DEFAULT_TILESIZE * 2 : \ - QT_DISTANCEFIELD_DEFAULT_TILESIZE) -#define QT_DISTANCEFIELD_SCALE(NarrowOutlineFont) \ - (NarrowOutlineFont ? QT_DISTANCEFIELD_DEFAULT_SCALE / 2 : \ - QT_DISTANCEFIELD_DEFAULT_SCALE) -#define QT_DISTANCEFIELD_RADIUS(NarrowOutlineFont) \ - (NarrowOutlineFont ? QT_DISTANCEFIELD_DEFAULT_RADIUS / 2 : \ - QT_DISTANCEFIELD_DEFAULT_RADIUS) - - -typedef float (*ThresholdFunc)(float glyphScale); -typedef float (*AntialiasingSpreadFunc)(float glyphScale); - -bool qt_fontHasNarrowOutlines(const QRawFont &f); -QImage qt_renderDistanceFieldGlyph(const QRawFont &font, glyph_t glyph, bool doubleResolution); - - -class QOpenGLShaderProgram; -class QSGDistanceFieldGlyphCache; -class QSGContext; - -class Q_DECLARATIVE_EXPORT QSGDistanceFieldGlyphCacheManager -{ -public: - QSGDistanceFieldGlyphCacheManager(QSGContext *c); - ~QSGDistanceFieldGlyphCacheManager(); - - QSGDistanceFieldGlyphCache *cache(const QRawFont &font); - - QSGGlyphNode::AntialiasingMode defaultAntialiasingMode() const { return m_defaultAntialiasingMode; } - void setDefaultAntialiasingMode(QSGGlyphNode::AntialiasingMode mode) { m_defaultAntialiasingMode = mode; } - - ThresholdFunc thresholdFunc() const { return m_threshold_func; } - void setThresholdFunc(ThresholdFunc func) { m_threshold_func = func; } - - AntialiasingSpreadFunc antialiasingSpreadFunc() const { return m_antialiasingSpread_func; } - void setAntialiasingSpreadFunc(AntialiasingSpreadFunc func) { m_antialiasingSpread_func = func; } - -private: - QHash<QFontEngine *, QSGDistanceFieldGlyphCache *> m_caches; - - QSGContext *sgCtx; - - QSGGlyphNode::AntialiasingMode m_defaultAntialiasingMode; - ThresholdFunc m_threshold_func; - AntialiasingSpreadFunc m_antialiasingSpread_func; -}; - -QT_END_NAMESPACE - -#endif // QSGDISTANCEFIELDUTIL_H diff --git a/src/declarative/scenegraph/util/qsgengine.cpp b/src/declarative/scenegraph/util/qsgengine.cpp deleted file mode 100644 index 88eeebc472..0000000000 --- a/src/declarative/scenegraph/util/qsgengine.cpp +++ /dev/null @@ -1,115 +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 "qsgengine.h" - -#include <qquickcanvas.h> - -#include <private/qobject_p.h> -#include <QtGui/QColor> - -QT_BEGIN_NAMESPACE - -class QSGEnginePrivate : public QObjectPrivate -{ -public: - QSGEnginePrivate() - : canvas(0) - { - } - - QQuickCanvas *canvas; -}; - -/*! - \class QSGEngine - \deprecated - */ - -QSGEngine::QSGEngine(QObject *parent) : - QObject(*(new QSGEnginePrivate), parent) -{ -} - - -QSGEngine::~QSGEngine() -{ -} - - -void QSGEngine::setCanvas(QQuickCanvas *canvas) -{ - d_func()->canvas = canvas; - connect(canvas, SIGNAL(afterRendering()), this, SIGNAL(afterRendering())); - connect(canvas, SIGNAL(beforeRendering()), this, SIGNAL(beforeRendering())); -} - -void QSGEngine::setClearBeforeRendering(bool enabled) -{ - d_func()->canvas->setClearBeforeRendering(enabled); -} - -bool QSGEngine::clearBeforeRendering() const -{ - return d_func()->canvas->clearBeforeRendering(); -} - -QSGTexture *QSGEngine::createTextureFromImage(const QImage &image) const -{ - return d_func()->canvas->createTextureFromImage(image); -} - -QSGTexture *QSGEngine::createTextureFromId(uint id, const QSize &size, TextureOptions options) const -{ - return d_func()->canvas->createTextureFromId(id, size, QQuickCanvas::CreateTextureOptions((int) options)); -} - -void QSGEngine::setClearColor(const QColor &color) -{ - d_func()->canvas->setClearColor(color); -} - -QColor QSGEngine::clearColor() const -{ - return d_func()->canvas->clearColor(); -} - -QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/util/qsgengine.h b/src/declarative/scenegraph/util/qsgengine.h deleted file mode 100644 index 0cbbcddfec..0000000000 --- a/src/declarative/scenegraph/util/qsgengine.h +++ /dev/null @@ -1,102 +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 QSGENGINE_H -#define QSGENGINE_H - -#include <QObject> - -#include <qsgtexture.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class QSGEnginePrivate; - -class QQuickCanvas; - -class Q_DECLARATIVE_EXPORT QSGEngine : public QObject -{ - Q_OBJECT - - Q_DECLARE_PRIVATE(QSGEngine) - -public: - - enum TextureOption { - TextureHasAlphaChannel = 0x0001, - TextureHasMipmaps = 0x0002, - TextureOwnsGLTexture = 0x0004 - }; - Q_DECLARE_FLAGS(TextureOptions, TextureOption) - - QSGTexture *createTextureFromImage(const QImage &image) const; - QSGTexture *createTextureFromId(uint id, const QSize &size, TextureOptions options = TextureOption(0)) const; - - void setClearBeforeRendering(bool enabled); - bool clearBeforeRendering() const; - - void setClearColor(const QColor &color); - QColor clearColor() const; - -Q_SIGNALS: - void beforeRendering(); - void afterRendering(); - -private: - QSGEngine(QObject *parent = 0); - ~QSGEngine(); - - friend class QSGContext; - friend class QSGContextPrivate; - friend class QQuickCanvasPrivate; - void setCanvas(QQuickCanvas *canvas); - -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QSGENGINE_H diff --git a/src/declarative/scenegraph/util/qsgflatcolormaterial.cpp b/src/declarative/scenegraph/util/qsgflatcolormaterial.cpp deleted file mode 100644 index ee73616e4f..0000000000 --- a/src/declarative/scenegraph/util/qsgflatcolormaterial.cpp +++ /dev/null @@ -1,202 +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 "qsgflatcolormaterial.h" - -#include <qopenglshaderprogram.h> - -QT_BEGIN_NAMESPACE - -class FlatColorMaterialShader : public QSGMaterialShader -{ -public: - virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect); - virtual char const *const *attributeNames() const; - - static QSGMaterialType type; - -private: - virtual void initialize(); - virtual const char *vertexShader() const; - virtual const char *fragmentShader() const; - - int m_matrix_id; - int m_color_id; -}; - -QSGMaterialType FlatColorMaterialShader::type; - -void FlatColorMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) -{ - Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type()); - - QSGFlatColorMaterial *oldMaterial = static_cast<QSGFlatColorMaterial *>(oldEffect); - QSGFlatColorMaterial *newMaterial = static_cast<QSGFlatColorMaterial *>(newEffect); - - const QColor &c = newMaterial->color(); - - if (oldMaterial == 0 || c != oldMaterial->color() || state.isOpacityDirty()) { - float opacity = state.opacity(); - QVector4D v(c.redF() * c.alphaF() * opacity, - c.greenF() * c.alphaF() * opacity, - c.blueF() * c.alphaF() * opacity, - c.alphaF() * opacity); - program()->setUniformValue(m_color_id, v); - } - - if (state.isMatrixDirty()) - program()->setUniformValue(m_matrix_id, state.combinedMatrix()); -} - -char const *const *FlatColorMaterialShader::attributeNames() const -{ - static char const *const attr[] = { "vCoord", 0 }; - return attr; -} - -void FlatColorMaterialShader::initialize() -{ - m_matrix_id = program()->uniformLocation("matrix"); - m_color_id = program()->uniformLocation("color"); -} - -const char *FlatColorMaterialShader::vertexShader() const { - return - "attribute highp vec4 vCoord; \n" - "uniform highp mat4 matrix; \n" - "void main() { \n" - " gl_Position = matrix * vCoord; \n" - "}"; -} - -const char *FlatColorMaterialShader::fragmentShader() const { - return - "uniform lowp vec4 color; \n" - "void main() { \n" - " gl_FragColor = color; \n" - "}"; -} - - - -/*! - \class QSGFlatColorMaterial - \brief The QSGFlatColorMaterial class provides a convenient way of rendering - solid colored geometry in the scene graph. - - \inmodule QtDeclarative - - The flat color material will fill every pixel in a geometry using - a solid color. The color can contain transparency. - - The geometry to be rendered with a flat color material requires - vertices in attribute location 0 in the QSGGeometry object to render - correctly. The QSGGeometry::defaultAttributes_Point2D() returns an attribute - set compatible with this material. - - The flat color material respects both current opacity and current matrix - when updating it's rendering state. - */ - - -/*! - Constructs a new flat color material. - - The default color is white. - */ - -QSGFlatColorMaterial::QSGFlatColorMaterial() : m_color(QColor(255, 255, 255)) -{ -} - - - -/*! - \fn QColor QSGFlatColorMaterial::color() const - - Returns this flat color material's color. - - The default color is white. - */ - - - -/*! - Sets this flat color material's color to \a color. - */ - -void QSGFlatColorMaterial::setColor(const QColor &color) -{ - m_color = color; - setFlag(Blending, m_color.alpha() != 0xff); -} - - - -/*! - \internal - */ - -QSGMaterialType *QSGFlatColorMaterial::type() const -{ - return &FlatColorMaterialShader::type; -} - - - -/*! - \internal - */ - -QSGMaterialShader *QSGFlatColorMaterial::createShader() const -{ - return new FlatColorMaterialShader; -} - - -int QSGFlatColorMaterial::compare(const QSGMaterial *other) const -{ - const QSGFlatColorMaterial *flat = static_cast<const QSGFlatColorMaterial *>(other); - return m_color.rgba() - flat->color().rgba(); - -} - -QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/util/qsgflatcolormaterial.h b/src/declarative/scenegraph/util/qsgflatcolormaterial.h deleted file mode 100644 index f6345b6483..0000000000 --- a/src/declarative/scenegraph/util/qsgflatcolormaterial.h +++ /dev/null @@ -1,74 +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 FLATCOLORMATERIAL_H -#define FLATCOLORMATERIAL_H - -#include <qsgmaterial.h> -#include <qcolor.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class Q_DECLARATIVE_EXPORT QSGFlatColorMaterial : public QSGMaterial -{ -public: - QSGFlatColorMaterial(); - virtual QSGMaterialType *type() const; - virtual QSGMaterialShader *createShader() const; - - void setColor(const QColor &color); - const QColor &color() const { return m_color; } - - int compare(const QSGMaterial *other) const; - -private: - QColor m_color; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // FLATCOLORMATERIAL_H diff --git a/src/declarative/scenegraph/util/qsgpainternode.cpp b/src/declarative/scenegraph/util/qsgpainternode.cpp deleted file mode 100644 index f3e5202241..0000000000 --- a/src/declarative/scenegraph/util/qsgpainternode.cpp +++ /dev/null @@ -1,464 +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 "qsgpainternode_p.h" - -#include <private/qquickpainteditem_p.h> - -#include <private/qsgcontext_p.h> -#include <private/qopenglextensions_p.h> -#include <qopenglframebufferobject.h> -#include <qopenglfunctions.h> -#include <qopenglpaintdevice.h> -#include <qmath.h> -#include <qpainter.h> - -QT_BEGIN_NAMESPACE - -#define QT_MINIMUM_DYNAMIC_FBO_SIZE 64 - -static inline int qt_next_power_of_two(int v) -{ - v--; - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - ++v; - return v; -} - -QSGPainterTexture::QSGPainterTexture() - : QSGPlainTexture() -{ - -} - -void QSGPainterTexture::bind() -{ - if (m_dirty_rect.isNull()) { - QSGPlainTexture::bind(); - return; - } - - bool oldMipmapsGenerated = m_mipmaps_generated; - m_mipmaps_generated = true; - QSGPlainTexture::bind(); - m_mipmaps_generated = oldMipmapsGenerated; - - QImage subImage = m_image.copy(m_dirty_rect); - - int w = m_dirty_rect.width(); - int h = m_dirty_rect.height(); - -#ifdef QT_OPENGL_ES - glTexSubImage2D(GL_TEXTURE_2D, 0, m_dirty_rect.x(), m_dirty_rect.y(), w, h, - GL_RGBA, GL_UNSIGNED_BYTE, subImage.constBits()); -#else - glTexSubImage2D(GL_TEXTURE_2D, 0, m_dirty_rect.x(), m_dirty_rect.y(), w, h, - GL_BGRA, GL_UNSIGNED_BYTE, subImage.constBits()); -#endif - - if (m_has_mipmaps && !m_mipmaps_generated) { - QOpenGLContext *ctx = QOpenGLContext::currentContext(); - ctx->functions()->glGenerateMipmap(GL_TEXTURE_2D); - m_mipmaps_generated = true; - } - - m_dirty_texture = false; - m_dirty_bind_options = false; - - m_dirty_rect = QRect(); -} - -QSGPainterNode::QSGPainterNode(QQuickPaintedItem *item) - : QSGGeometryNode() - , m_preferredRenderTarget(QQuickPaintedItem::Image) - , m_actualRenderTarget(QQuickPaintedItem::Image) - , m_item(item) - , m_fbo(0) - , m_multisampledFbo(0) - , m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4) - , m_texture(0) - , m_gl_device(0) - , m_size(1, 1) - , m_dirtyContents(false) - , m_opaquePainting(false) - , m_linear_filtering(false) - , m_mipmapping(false) - , m_smoothPainting(false) - , m_extensionsChecked(false) - , m_multisamplingSupported(false) - , m_fastFBOResizing(false) - , m_fillColor(Qt::transparent) - , m_contentsScale(1.0) - , m_dirtyGeometry(false) - , m_dirtyRenderTarget(false) - , m_dirtyTexture(false) -{ - m_context = static_cast<QQuickPaintedItemPrivate *>(QObjectPrivate::get(item))->sceneGraphContext(); - - setMaterial(&m_materialO); - setOpaqueMaterial(&m_material); - setGeometry(&m_geometry); -} - -QSGPainterNode::~QSGPainterNode() -{ - delete m_texture; - delete m_fbo; - delete m_multisampledFbo; - delete m_gl_device; -} - -void QSGPainterNode::paint() -{ - QRect dirtyRect = m_dirtyRect.isNull() ? QRect(0, 0, m_size.width(), m_size.height()) : m_dirtyRect; - - QPainter painter; - if (m_actualRenderTarget == QQuickPaintedItem::Image) - painter.begin(&m_image); - else { - if (!m_gl_device) { - m_gl_device = new QOpenGLPaintDevice(m_fboSize); - m_gl_device->setPaintFlipped(true); - } - - if (m_multisampledFbo) - m_multisampledFbo->bind(); - else - m_fbo->bind(); - - painter.begin(m_gl_device); - } - - if (m_smoothPainting) { - painter.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing - | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform); - } - - painter.scale(m_contentsScale, m_contentsScale); - - QRect sclip(qFloor(dirtyRect.x()/m_contentsScale), - qFloor(dirtyRect.y()/m_contentsScale), - qCeil(dirtyRect.width()/m_contentsScale+dirtyRect.x()/m_contentsScale-qFloor(dirtyRect.x()/m_contentsScale)), - qCeil(dirtyRect.height()/m_contentsScale+dirtyRect.y()/m_contentsScale-qFloor(dirtyRect.y()/m_contentsScale))); - - if (!m_dirtyRect.isNull()) - painter.setClipRect(sclip); - - painter.setCompositionMode(QPainter::CompositionMode_Source); - painter.fillRect(sclip, m_fillColor); - painter.setCompositionMode(QPainter::CompositionMode_SourceOver); - - m_item->paint(&painter); - painter.end(); - - if (m_actualRenderTarget == QQuickPaintedItem::Image) { - m_texture->setImage(m_image); - m_texture->setDirtyRect(dirtyRect); - } else if (m_multisampledFbo) { - QOpenGLFramebufferObject::blitFramebuffer(m_fbo, dirtyRect, m_multisampledFbo, dirtyRect); - } - - if (m_multisampledFbo) - m_multisampledFbo->release(); - else if (m_fbo) - m_fbo->release(); - - m_dirtyRect = QRect(); -} - -void QSGPainterNode::update() -{ - if (m_dirtyRenderTarget) - updateRenderTarget(); - if (m_dirtyGeometry) - updateGeometry(); - if (m_dirtyTexture) - updateTexture(); - - if (m_dirtyContents) - paint(); - - m_dirtyGeometry = false; - m_dirtyRenderTarget = false; - m_dirtyTexture = false; - m_dirtyContents = false; -} - -void QSGPainterNode::updateTexture() -{ - m_texture->setHasMipmaps(m_mipmapping); - m_texture->setHasAlphaChannel(!m_opaquePainting); - m_material.setTexture(m_texture); - m_materialO.setTexture(m_texture); - - markDirty(DirtyMaterial); -} - -void QSGPainterNode::updateGeometry() -{ - QRectF source; - if (m_actualRenderTarget == QQuickPaintedItem::Image) - source = QRectF(0, 0, 1, 1); - else - source = QRectF(0, 0, qreal(m_size.width()) / m_fboSize.width(), qreal(m_size.height()) / m_fboSize.height()); - QRectF dest(0, 0, m_size.width(), m_size.height()); - if (m_actualRenderTarget == QQuickPaintedItem::InvertedYFramebufferObject) - dest = QRectF(QPointF(0, m_size.height()), QPointF(m_size.width(), 0)); - QSGGeometry::updateTexturedRectGeometry(&m_geometry, - dest, - source); - markDirty(DirtyGeometry); -} - -void QSGPainterNode::updateRenderTarget() -{ - if (!m_extensionsChecked) { - QList<QByteArray> extensions = QByteArray((const char *)glGetString(GL_EXTENSIONS)).split(' '); - m_multisamplingSupported = extensions.contains("GL_EXT_framebuffer_multisample") - && extensions.contains("GL_EXT_framebuffer_blit"); - m_extensionsChecked = true; - } - - m_dirtyContents = true; - - QQuickPaintedItem::RenderTarget oldTarget = m_actualRenderTarget; - if (m_preferredRenderTarget == QQuickPaintedItem::Image) { - m_actualRenderTarget = QQuickPaintedItem::Image; - } else { - if (!m_multisamplingSupported && m_smoothPainting) - m_actualRenderTarget = QQuickPaintedItem::Image; - else - m_actualRenderTarget = m_preferredRenderTarget; - } - if (oldTarget != m_actualRenderTarget) { - m_image = QImage(); - delete m_fbo; - delete m_multisampledFbo; - m_fbo = m_multisampledFbo = 0; - } - - if (m_actualRenderTarget == QQuickPaintedItem::FramebufferObject || - m_actualRenderTarget == QQuickPaintedItem::InvertedYFramebufferObject) { - const QOpenGLContext *ctx = m_context->glContext(); - if (m_fbo && !m_dirtyGeometry && (!ctx->format().samples() || !m_multisamplingSupported)) - return; - - if (m_fboSize.isEmpty()) - updateFBOSize(); - - delete m_fbo; - delete m_multisampledFbo; - m_fbo = m_multisampledFbo = 0; - - if (m_smoothPainting && ctx->format().samples() && m_multisamplingSupported) { - { - QOpenGLFramebufferObjectFormat format; - format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); - format.setSamples(8); - m_multisampledFbo = new QOpenGLFramebufferObject(m_fboSize, format); - } - { - QOpenGLFramebufferObjectFormat format; - format.setAttachment(QOpenGLFramebufferObject::NoAttachment); - m_fbo = new QOpenGLFramebufferObject(m_fboSize, format); - } - } else { - QOpenGLFramebufferObjectFormat format; - format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); - m_fbo = new QOpenGLFramebufferObject(m_fboSize, format); - } - } else { - if (!m_image.isNull() && !m_dirtyGeometry) - return; - - m_image = QImage(m_size, QImage::Format_ARGB32_Premultiplied); - m_image.fill(Qt::transparent); - } - - QSGPainterTexture *texture = new QSGPainterTexture; - if (m_actualRenderTarget == QQuickPaintedItem::Image) { - texture->setOwnsTexture(true); - texture->setTextureSize(m_size); - } else { - texture->setTextureId(m_fbo->texture()); - texture->setOwnsTexture(false); - texture->setTextureSize(m_fboSize); - } - - if (m_texture) - delete m_texture; - - texture->setTextureSize(m_size); - m_texture = texture; -} - -void QSGPainterNode::updateFBOSize() -{ - int fboWidth; - int fboHeight; - if (m_fastFBOResizing) { - fboWidth = qMax(QT_MINIMUM_DYNAMIC_FBO_SIZE, qt_next_power_of_two(m_size.width())); - fboHeight = qMax(QT_MINIMUM_DYNAMIC_FBO_SIZE, qt_next_power_of_two(m_size.height())); - } else { - QSize minimumFBOSize = m_context->minimumFBOSize(); - fboWidth = qMax(minimumFBOSize.width(), m_size.width()); - fboHeight = qMax(minimumFBOSize.height(), m_size.height()); - } - - m_fboSize = QSize(fboWidth, fboHeight); -} - -void QSGPainterNode::setPreferredRenderTarget(QQuickPaintedItem::RenderTarget target) -{ - if (m_preferredRenderTarget == target) - return; - - m_preferredRenderTarget = target; - - m_dirtyRenderTarget = true; - m_dirtyGeometry = true; - m_dirtyTexture = true; -} - -void QSGPainterNode::setSize(const QSize &size) -{ - if (size == m_size) - return; - - m_size = size; - updateFBOSize(); - - if (m_fbo) - m_dirtyRenderTarget = m_fbo->size() != m_fboSize || m_dirtyRenderTarget; - else - m_dirtyRenderTarget = true; - m_dirtyGeometry = true; - m_dirtyTexture = true; -} - -void QSGPainterNode::setDirty(const QRect &dirtyRect) -{ - m_dirtyContents = true; - m_dirtyRect = dirtyRect; - - if (m_mipmapping) - m_dirtyTexture = true; - - markDirty(DirtyMaterial); -} - -void QSGPainterNode::setOpaquePainting(bool opaque) -{ - if (opaque == m_opaquePainting) - return; - - m_opaquePainting = opaque; - m_dirtyTexture = true; -} - -void QSGPainterNode::setLinearFiltering(bool linearFiltering) -{ - if (linearFiltering == m_linear_filtering) - return; - - m_linear_filtering = linearFiltering; - - m_material.setFiltering(linearFiltering ? QSGTexture::Linear : QSGTexture::Nearest); - m_materialO.setFiltering(linearFiltering ? QSGTexture::Linear : QSGTexture::Nearest); - markDirty(DirtyMaterial); -} - -void QSGPainterNode::setMipmapping(bool mipmapping) -{ - if (mipmapping == m_mipmapping) - return; - - m_mipmapping = mipmapping; - m_material.setMipmapFiltering(mipmapping ? QSGTexture::Linear : QSGTexture::None); - m_materialO.setMipmapFiltering(mipmapping ? QSGTexture::Linear : QSGTexture::None); - m_dirtyTexture = true; -} - -void QSGPainterNode::setSmoothPainting(bool s) -{ - if (s == m_smoothPainting) - return; - - m_smoothPainting = s; - m_dirtyRenderTarget = true; -} - -void QSGPainterNode::setFillColor(const QColor &c) -{ - if (c == m_fillColor) - return; - - m_fillColor = c; - markDirty(DirtyMaterial); -} - -void QSGPainterNode::setContentsScale(qreal s) -{ - if (s == m_contentsScale) - return; - - m_contentsScale = s; - markDirty(DirtyMaterial); -} - -void QSGPainterNode::setFastFBOResizing(bool dynamic) -{ - m_fastFBOResizing = dynamic; -} - -QImage QSGPainterNode::toImage() const -{ - if (m_actualRenderTarget == QQuickPaintedItem::Image) - return m_image; - else - return m_fbo->toImage(); -} - -QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/util/qsgpainternode_p.h b/src/declarative/scenegraph/util/qsgpainternode_p.h deleted file mode 100644 index 8e95107efc..0000000000 --- a/src/declarative/scenegraph/util/qsgpainternode_p.h +++ /dev/null @@ -1,160 +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 QSGPAINTERNODE_P_H -#define QSGPAINTERNODE_P_H - -#include "qsgnode.h" -#include "qsgtexturematerial.h" -#include "qsgtexture_p.h" - -#include <qquickpainteditem.h> - -#include <QtGui/qcolor.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class QOpenGLFramebufferObject; -class QOpenGLPaintDevice; - -class Q_DECLARATIVE_EXPORT QSGPainterTexture : public QSGPlainTexture -{ -public: - QSGPainterTexture(); - - void setDirtyRect(const QRect &rect) { m_dirty_rect = rect; } - - void bind(); - -private: - QRect m_dirty_rect; -}; - -class Q_DECLARATIVE_EXPORT QSGPainterNode : public QSGGeometryNode -{ -public: - QSGPainterNode(QQuickPaintedItem *item); - virtual ~QSGPainterNode(); - - void setPreferredRenderTarget(QQuickPaintedItem::RenderTarget target); - - void setSize(const QSize &size); - QSize size() const { return m_size; } - - void setDirty(const QRect &dirtyRect = QRect()); - - void setOpaquePainting(bool opaque); - bool opaquePainting() const { return m_opaquePainting; } - - void setLinearFiltering(bool linearFiltering); - bool linearFiltering() const { return m_linear_filtering; } - - void setMipmapping(bool mipmapping); - bool mipmapping() const { return m_mipmapping; } - - void setSmoothPainting(bool s); - bool smoothPainting() const { return m_smoothPainting; } - - void setFillColor(const QColor &c); - QColor fillColor() const { return m_fillColor; } - - void setContentsScale(qreal s); - qreal contentsScale() const { return m_contentsScale; } - - void setFastFBOResizing(bool dynamic); - bool fastFBOResizing() const { return m_fastFBOResizing; } - - QImage toImage() const; - void update(); - - void paint(); - -private: - void updateTexture(); - void updateGeometry(); - void updateRenderTarget(); - void updateFBOSize(); - - QSGContext *m_context; - - QQuickPaintedItem::RenderTarget m_preferredRenderTarget; - QQuickPaintedItem::RenderTarget m_actualRenderTarget; - - QQuickPaintedItem *m_item; - - QOpenGLFramebufferObject *m_fbo; - QOpenGLFramebufferObject *m_multisampledFbo; - QImage m_image; - - QSGOpaqueTextureMaterial m_material; - QSGTextureMaterial m_materialO; - QSGGeometry m_geometry; - QSGPainterTexture *m_texture; - QOpenGLPaintDevice *m_gl_device; - - QSize m_size; - QSize m_fboSize; - bool m_dirtyContents; - QRect m_dirtyRect; - bool m_opaquePainting; - bool m_linear_filtering; - bool m_mipmapping; - bool m_smoothPainting; - bool m_extensionsChecked; - bool m_multisamplingSupported; - bool m_fastFBOResizing; - QColor m_fillColor; - qreal m_contentsScale; - - bool m_dirtyGeometry; - bool m_dirtyRenderTarget; - bool m_dirtyTexture; -}; - -QT_END_HEADER - -QT_END_NAMESPACE - -#endif // QSGPAINTERNODE_P_H diff --git a/src/declarative/scenegraph/util/qsgsimplematerial.h b/src/declarative/scenegraph/util/qsgsimplematerial.h deleted file mode 100644 index b9e453abec..0000000000 --- a/src/declarative/scenegraph/util/qsgsimplematerial.h +++ /dev/null @@ -1,222 +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 QSGSIMPLEMATERIAL_H -#define QSGSIMPLEMATERIAL_H - -#include <qsgmaterial.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -template <typename State> -class QSGSimpleMaterialShader : public QSGMaterialShader -{ -public: - void initialize() { - QSGMaterialShader::initialize(); - - m_id_matrix = program()->uniformLocation(uniformMatrixName()); - if (m_id_matrix < 0) { - qFatal("QSGSimpleMaterialShader does not implement 'uniform highp mat4 %s;' in its vertex shader", - uniformMatrixName()); - } - - const char *opacity = uniformOpacityName(); - if (opacity) { - m_id_opacity = program()->uniformLocation(uniformOpacityName()); - if (m_id_opacity < 0) { - qFatal("QSGSimpleMaterialShader does not implement 'uniform lowp float %s' in its fragment shader", - uniformOpacityName()); - } - } else { - m_id_opacity = -1; - } - - resolveUniforms(); - } - - const char *uniformMatrixName() const { return "qt_Matrix"; } - const char *uniformOpacityName() const { return "qt_Opacity"; } - - void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial); - - virtual void updateState(const State *newState, const State *oldState) = 0; - - virtual void resolveUniforms() {} - - virtual QList<QByteArray> attributes() const = 0; - - char const *const *attributeNames() const - { - if (m_attribute_pointers.size()) - return m_attribute_pointers.constData(); - - QList<QByteArray> names = attributes(); - - // Calculate the total number of bytes needed, so we don't get rellocs and - // bad pointers while copying over the individual names. - // Add an extra byte pr entry for the '\0' char. - int total = 0; - for (int i=0; i<names.size(); ++i) - total += names.at(i).size() + 1; - m_attribute_name_data.reserve(total); - - // Copy over the names - for (int i=0; i<names.size(); ++i) { - m_attribute_pointers << m_attribute_name_data.constData() + m_attribute_name_data.size(); - m_attribute_name_data.append(names.at(i)); - m_attribute_name_data.append('\0'); - } - - // Append the "null" terminator - m_attribute_pointers << 0; - - return m_attribute_pointers.constData(); - } - -private: - int m_id_matrix; - int m_id_opacity; - - mutable QByteArray m_attribute_name_data; - mutable QVector<const char *> m_attribute_pointers; -}; - -#define QSG_DECLARE_SIMPLE_SHADER(Shader, State) \ -static QSGMaterialShader *createShader() \ -{ \ - return new Shader; \ -} \ -public: \ -static QSGSimpleMaterial<State> *createMaterial() \ -{ \ - return new QSGSimpleMaterial<State>(createShader); \ -} - - -typedef QSGMaterialShader *(*PtrShaderCreateFunc)(); - - -template <typename State> -class QSGSimpleMaterial : public QSGMaterial -{ - -public: - QSGSimpleMaterial(const State &state, PtrShaderCreateFunc func) - : m_state(state) - , m_func(func) - { - } - - QSGSimpleMaterial(PtrShaderCreateFunc func) - : m_func(func) - { - } - - QSGMaterialShader *createShader() const { return m_func(); } - QSGMaterialType *type() const { return &m_type; } - - State *state() { return &m_state; } - const State *state() const { return &m_state; } - -private: - static QSGMaterialType m_type; - State m_state; - PtrShaderCreateFunc m_func; -}; - -#define QSG_DECLARE_SIMPLE_COMPARABLE_SHADER(Shader, State) \ -static QSGMaterialShader *createShader() \ -{ \ - return new Shader; \ -} \ -public: \ -static QSGSimpleMaterialComparableMaterial<State> *createMaterial() \ -{ \ - return new QSGSimpleMaterialComparableMaterial<State>(createShader); \ -} - -template <typename State> -class QSGSimpleMaterialComparableMaterial : public QSGSimpleMaterial<State> -{ - -public: - QSGSimpleMaterialComparableMaterial(const State &state, PtrShaderCreateFunc func) - : QSGSimpleMaterial<State>(state, func) {} - - QSGSimpleMaterialComparableMaterial(PtrShaderCreateFunc func) - : QSGSimpleMaterial<State>(func) {} - - int compare(const QSGMaterial *other) const { - return QSGSimpleMaterialComparableMaterial<State>::state()->compare(static_cast<const QSGSimpleMaterialComparableMaterial<State> *>(other)->state()); - } -}; - - -template <typename State> -QSGMaterialType QSGSimpleMaterial<State>::m_type; - - -template <typename State> -Q_INLINE_TEMPLATE void QSGSimpleMaterialShader<State>::updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) -{ - if (state.isMatrixDirty()) - program()->setUniformValue(m_id_matrix, state.combinedMatrix()); - if (state.isOpacityDirty() && m_id_opacity >= 0) - program()->setUniformValue(m_id_opacity, state.opacity()); - - State *ns = static_cast<QSGSimpleMaterial<State> *>(newMaterial)->state(); - State *old = 0; - if (oldMaterial) - old = static_cast<QSGSimpleMaterial<State> *>(oldMaterial)->state(); - updateState(ns, old); -} - -QT_END_NAMESPACE - -QT_END_HEADER - - -#endif diff --git a/src/declarative/scenegraph/util/qsgsimplerectnode.cpp b/src/declarative/scenegraph/util/qsgsimplerectnode.cpp deleted file mode 100644 index c3dc5354ca..0000000000 --- a/src/declarative/scenegraph/util/qsgsimplerectnode.cpp +++ /dev/null @@ -1,132 +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 "qsgsimplerectnode.h" -#include "qsgflatcolormaterial.h" - -QT_BEGIN_NAMESPACE - -/*! - \class QSGSimpleRectNode - - \brief The QSGSimpleRectNode class is a convenience class for drawing - solid filled rectangles using scenegraph. - - */ - - - -/*! - Constructs a QSGSimpleRectNode instance which is spanning \a rect with - the color \a color. - */ -QSGSimpleRectNode::QSGSimpleRectNode(const QRectF &rect, const QColor &color) - : m_geometry(QSGGeometry::defaultAttributes_Point2D(), 4) -{ - QSGGeometry::updateRectGeometry(&m_geometry, rect); - m_material.setColor(color); - setMaterial(&m_material); - setGeometry(&m_geometry); -} - - - -/*! - Constructs a QSGSimpleRectNode instance with an empty rectangle and - white color. - */ -QSGSimpleRectNode::QSGSimpleRectNode() - : m_geometry(QSGGeometry::defaultAttributes_Point2D(), 4) -{ - QSGGeometry::updateRectGeometry(&m_geometry, QRectF()); - setMaterial(&m_material); - setGeometry(&m_geometry); -} - - - -/*! - Sets the rectangle of this rect node to \a rect. - */ -void QSGSimpleRectNode::setRect(const QRectF &rect) -{ - QSGGeometry::updateRectGeometry(&m_geometry, rect); - markDirty(QSGNode::DirtyGeometry); -} - - - -/*! - Returns the rectangle that this rect node covers. - */ -QRectF QSGSimpleRectNode::rect() const -{ - const QSGGeometry::Point2D *pts = m_geometry.vertexDataAsPoint2D(); - return QRectF(pts[0].x, - pts[0].y, - pts[3].x - pts[0].x, - pts[3].y - pts[0].y); -} - - -/*! - Sets the color of this rectangle to \a color. The default - color will be white. - */ -void QSGSimpleRectNode::setColor(const QColor &color) -{ - if (color != m_material.color()) { - m_material.setColor(color); - markDirty(QSGNode::DirtyMaterial); - } -} - - - -/*! - Returns the color of this rectangle. - */ -QColor QSGSimpleRectNode::color() const -{ - return m_material.color(); -} - -QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/util/qsgsimplerectnode.h b/src/declarative/scenegraph/util/qsgsimplerectnode.h deleted file mode 100644 index c06db07f93..0000000000 --- a/src/declarative/scenegraph/util/qsgsimplerectnode.h +++ /dev/null @@ -1,77 +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 SOLIDRECTNODE_H -#define SOLIDRECTNODE_H - -#include "qsgnode.h" -#include "qsgflatcolormaterial.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class Q_DECLARATIVE_EXPORT QSGSimpleRectNode : public QSGGeometryNode -{ -public: - QSGSimpleRectNode(const QRectF &rect, const QColor &color); - QSGSimpleRectNode(); - - void setRect(const QRectF &rect); - inline void setRect(qreal x, qreal y, qreal w, qreal h) { setRect(QRectF(x, y, w, h)); } - QRectF rect() const; - - void setColor(const QColor &color); - QColor color() const; - -private: - QSGFlatColorMaterial m_material; - QSGGeometry m_geometry; - void *reserved; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // SOLIDRECTNODE_H diff --git a/src/declarative/scenegraph/util/qsgsimpletexturenode.cpp b/src/declarative/scenegraph/util/qsgsimpletexturenode.cpp deleted file mode 100644 index a0d6616371..0000000000 --- a/src/declarative/scenegraph/util/qsgsimpletexturenode.cpp +++ /dev/null @@ -1,154 +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 "qsgsimpletexturenode.h" - -QT_BEGIN_NAMESPACE - -static void qsgsimpletexturenode_update(QSGGeometry *g, - QSGTexture *texture, - const QRectF &rect) -{ - if (!texture) - return; - - QSize ts = texture->textureSize(); - QRectF sourceRect(0, 0, ts.width(), ts.height()); - QSGGeometry::updateTexturedRectGeometry(g, rect, texture->convertToNormalizedSourceRect(sourceRect)); -} - -/*! - \class QSGSimpleTextureNode - \brief The QSGSimpleTextureNode class is provided for convenience to easily draw - textured content using the QML scene graph. - - \inmodule QtDeclarative - - \warning The simple texture node class must have a texture before being - added to the scene graph to be rendered. -*/ - -/*! - Constructs a new simple texture node - */ -QSGSimpleTextureNode::QSGSimpleTextureNode() - : m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4) -{ - setGeometry(&m_geometry); - setMaterial(&m_material); - setOpaqueMaterial(&m_opaque_material); -} - -/*! - Sets the filtering to be used for this texture node to \a filtering. - - For smooth scaling, use QSGTexture::Linear; for normal scaling, use - QSGTexture::Nearest. - */ -void QSGSimpleTextureNode::setFiltering(QSGTexture::Filtering filtering) -{ - if (m_material.filtering() == filtering) - return; - - m_material.setFiltering(filtering); - m_opaque_material.setFiltering(filtering); - markDirty(DirtyMaterial); -} - - -/*! - Returns the filtering currently set on this texture node - */ -QSGTexture::Filtering QSGSimpleTextureNode::filtering() const -{ - return m_material.filtering(); -} - - -/*! - Sets the target rect of this texture node to \a r - */ -void QSGSimpleTextureNode::setRect(const QRectF &r) -{ - if (m_rect == r) - return; - m_rect = r; - qsgsimpletexturenode_update(&m_geometry, texture(), m_rect); - markDirty(DirtyGeometry); -} - - -/*! - Returns the target rect of this texture node. - */ -QRectF QSGSimpleTextureNode::rect() const -{ - return m_rect; -} - -/*! - Sets the texture of this texture node to \a texture. - - \warning A texture node must have a texture before being added - to the scenegraph to be rendered. - */ -void QSGSimpleTextureNode::setTexture(QSGTexture *texture) -{ - if (m_material.texture() == texture) - return; - m_material.setTexture(texture); - m_opaque_material.setTexture(texture); - qsgsimpletexturenode_update(&m_geometry, texture, m_rect); - markDirty(DirtyMaterial); -} - - - -/*! - Returns the texture for this texture node - */ -QSGTexture *QSGSimpleTextureNode::texture() const -{ - return m_material.texture(); -} - -QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/util/qsgsimpletexturenode.h b/src/declarative/scenegraph/util/qsgsimpletexturenode.h deleted file mode 100644 index db58c30b5f..0000000000 --- a/src/declarative/scenegraph/util/qsgsimpletexturenode.h +++ /dev/null @@ -1,82 +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 QSGSIMPLETEXTURENODE_H -#define QSGSIMPLETEXTURENODE_H - -#include "qsgnode.h" -#include "qsggeometry.h" -#include "qsgtexturematerial.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class Q_DECLARATIVE_EXPORT QSGSimpleTextureNode : public QSGGeometryNode -{ -public: - QSGSimpleTextureNode(); - - void setRect(const QRectF &rect); - inline void setRect(qreal x, qreal y, qreal w, qreal h) { setRect(QRectF(x, y, w, h)); } - QRectF rect() const; - - void setTexture(QSGTexture *texture); - QSGTexture *texture() const; - - void setFiltering(QSGTexture::Filtering filtering); - QSGTexture::Filtering filtering() const; - -private: - QSGGeometry m_geometry; - QSGOpaqueTextureMaterial m_opaque_material; - QSGTextureMaterial m_material; - - QRectF m_rect; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QSGSIMPLETEXTURENODE_H diff --git a/src/declarative/scenegraph/util/qsgtexture.cpp b/src/declarative/scenegraph/util/qsgtexture.cpp deleted file mode 100644 index e2219e54f5..0000000000 --- a/src/declarative/scenegraph/util/qsgtexture.cpp +++ /dev/null @@ -1,541 +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 <private/qsgtexture_p.h> -#include <qopenglfunctions.h> -#include <private/qsgcontext_p.h> -#include <qthread.h> -#include <private/qdeclarativedebugtrace_p.h> - -#if !defined(QT_NO_DEBUG) && (defined(Q_OS_LINUX) || defined(Q_OS_MAC)) -#include <execinfo.h> -#include <QHash> -#endif - -QT_BEGIN_NAMESPACE - -inline static bool isPowerOfTwo(int x) -{ - // Assumption: x >= 1 - return x == (x & -x); -} - -QSGTexturePrivate::QSGTexturePrivate() - : wrapChanged(false) - , filteringChanged(false) - , horizontalWrap(QSGTexture::ClampToEdge) - , verticalWrap(QSGTexture::ClampToEdge) - , mipmapMode(QSGTexture::None) - , filterMode(QSGTexture::Nearest) -{ -} - -#ifndef QT_NO_DEBUG - -static int qt_debug_texture_count = 0; - -#if defined(Q_OS_LINUX) || defined (Q_OS_MAC) -DEFINE_BOOL_CONFIG_OPTION(qmlDebugLeakBacktrace, QML_DEBUG_LEAK_BACKTRACE) - -#define BACKTRACE_SIZE 20 -class SGTextureTraceItem -{ -public: - void *backTrace[BACKTRACE_SIZE]; - size_t backTraceSize; -}; - -static QHash<QSGTexture*, SGTextureTraceItem*> qt_debug_allocated_textures; -#endif - -inline static void qt_debug_print_texture_count() -{ - qDebug("Number of leaked textures: %i", qt_debug_texture_count); - qt_debug_texture_count = -1; - -#if defined(Q_OS_LINUX) || defined (Q_OS_MAC) - if (qmlDebugLeakBacktrace()) { - while (!qt_debug_allocated_textures.isEmpty()) { - QHash<QSGTexture*, SGTextureTraceItem*>::Iterator it = qt_debug_allocated_textures.begin(); - QSGTexture* texture = it.key(); - SGTextureTraceItem* item = it.value(); - - qt_debug_allocated_textures.erase(it); - - qDebug() << "------"; - qDebug() << "Leaked" << texture << "backtrace:"; - - char** symbols = backtrace_symbols(item->backTrace, item->backTraceSize); - - if (symbols) { - for (int i=0; i<(int) item->backTraceSize; i++) - qDebug("Backtrace <%02d>: %s", i, symbols[i]); - free(symbols); - } - - qDebug() << "------"; - - delete item; - } - } -#endif -} - -inline static void qt_debug_add_texture(QSGTexture* texture) -{ -#if defined(Q_OS_LINUX) || defined (Q_OS_MAC) - if (qmlDebugLeakBacktrace()) { - SGTextureTraceItem* item = new SGTextureTraceItem; - item->backTraceSize = backtrace(item->backTrace, BACKTRACE_SIZE); - qt_debug_allocated_textures.insert(texture, item); - } -#else - Q_UNUSED(texture); -#endif // Q_OS_LINUX - - ++qt_debug_texture_count; - - static bool atexit_registered = false; - if (!atexit_registered) { - atexit(qt_debug_print_texture_count); - atexit_registered = true; - } -} - -static void qt_debug_remove_texture(QSGTexture* texture) -{ -#if defined(Q_OS_LINUX) || defined (Q_OS_MAC) - if (qmlDebugLeakBacktrace()) { - SGTextureTraceItem* item = qt_debug_allocated_textures.value(texture, 0); - if (item) { - qt_debug_allocated_textures.remove(texture); - delete item; - } - } -#else - Q_UNUSED(texture) -#endif - - --qt_debug_texture_count; - - if (qt_debug_texture_count < 0) - qDebug("Material destroyed after qt_debug_print_texture_count() was called."); -} - -#endif // QT_NO_DEBUG - - -QSGTexture::QSGTexture() - : QObject(*(new QSGTexturePrivate)) -{ -#ifndef QT_NO_DEBUG - qt_debug_add_texture(this); -#endif -} - -QSGTexture::~QSGTexture() -{ -#ifndef QT_NO_DEBUG - qt_debug_remove_texture(this); -#endif -} - - -/*! - \fn void QSGTexture::bind() - - Call this function to bind this texture to the current texture - target. - - Binding a texture may also include uploading the texture data from - a previously set QImage. - - \warning This function can only be called from the rendering thread. - */ - -/*! - This function returns a copy of the current texture which is removed - from its atlas. - - The current texture remains unchanged, so texture coordinates do not - need to be updated. - - Removing a texture from an atlas is primarily useful when passing - it to a shader that operates on the texture coordinates 0-1 instead - of the texture subrect inside the atlas. - - If the texture is not part of a texture atlas, this function returns 0. - - Implementations of this function are recommended to return the same instance - for multiple calls to limit memory usage. - - \warning This function can only be called from the rendering thread. - */ - -QSGTexture *QSGTexture::removedFromAtlas() const -{ - Q_ASSERT_X(!isAtlasTexture(), "QSGTexture::removedFromAtlas()", "Called on a non-atlas texture"); - return 0; -} - -/*! - Returns weither this texture is part of an atlas or not. - - The default implementation returns false. - */ -bool QSGTexture::isAtlasTexture() const -{ - return false; -} - -/*! - \fn int QSGTexture::textureId() const - - Returns the OpenGL texture id for this texture. - - The default value is 0, indicating that it is an invalid texture id. - - The function should at all times return the correct texture id. - - \warning This function can only be called from the rendering thread. - */ - - - -/*! - Returns the rectangle inside textureSize() that this texture - represents in normalized coordinates. - - The default implementation returns a rect at position (0, 0) with - width and height of 1. - */ -QRectF QSGTexture::textureSubRect() const -{ - return QRectF(0, 0, 1, 1); -} - -/*! - \fn bool QSGTexture::hasMipmaps() const - - Returns true if the texture data contains mipmap levels. - */ - - -/*! - Sets the mipmap sampling mode to be used for the upcoming bind() call to \a filter. - - Setting the mipmap filtering has no effect it the texture does not have mipmaps. - - \sa hasMipmaps() - */ -void QSGTexture::setMipmapFiltering(Filtering filter) -{ - Q_D(QSGTexture); - if (d->mipmapMode != (uint) filter) { - d->mipmapMode = filter; - d->filteringChanged = true; - } -} - -/*! - Returns whether mipmapping should be used when sampling from this texture. - */ -QSGTexture::Filtering QSGTexture::mipmapFiltering() const -{ - return (QSGTexture::Filtering) d_func()->mipmapMode; -} - - -/*! - Sets the sampling mode to be used for the upcoming bind() call to \a filter. - */ -void QSGTexture::setFiltering(QSGTexture::Filtering filter) -{ - Q_D(QSGTexture); - if (d->filterMode != (uint) filter) { - d->filterMode = filter; - d->filteringChanged = true; - } -} - -QSGTexture::Filtering QSGTexture::filtering() const -{ - return (QSGTexture::Filtering) d_func()->filterMode; -} - - - -/*! - Sets the horizontal wrap mode to be used for the upcoming bind() call to \a hwrap - */ - -void QSGTexture::setHorizontalWrapMode(WrapMode hwrap) -{ - Q_D(QSGTexture); - if ((uint) hwrap != d->horizontalWrap) { - d->horizontalWrap = hwrap; - d->wrapChanged = true; - } -} - -QSGTexture::WrapMode QSGTexture::horizontalWrapMode() const -{ - return (QSGTexture::WrapMode) d_func()->horizontalWrap; -} - - - -void QSGTexture::setVerticalWrapMode(WrapMode vwrap) -{ - Q_D(QSGTexture); - if ((uint) vwrap != d->verticalWrap) { - d->verticalWrap = vwrap; - d->wrapChanged = true; - } -} - -QSGTexture::WrapMode QSGTexture::verticalWrapMode() const -{ - return (QSGTexture::WrapMode) d_func()->verticalWrap; -} - - -/*! - Update the texture state to match the filtering, mipmap and wrap options - currently set. - - If \a force is true, all properties will be updated regardless of weither - they have changed or not. - */ -void QSGTexture::updateBindOptions(bool force) -{ - Q_D(QSGTexture); - if (force || d->filteringChanged) { - bool linear = d->filterMode == Linear; - GLint minFilter = linear ? GL_LINEAR : GL_NEAREST; - GLint magFilter = linear ? GL_LINEAR : GL_NEAREST; - - if (hasMipmaps()) { - if (d->mipmapMode == Nearest) - minFilter = linear ? GL_LINEAR_MIPMAP_NEAREST : GL_NEAREST_MIPMAP_NEAREST; - else if (d->mipmapMode == Linear) - minFilter = linear ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_LINEAR; - } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter); - d->filteringChanged = false; - } - - if (force || d->wrapChanged) { -#if !defined(QT_NO_DEBUG) && defined(QT_OPENGL_ES_2) - if (d->horizontalWrap == Repeat || d->verticalWrap == Repeat) { - bool npotSupported = QOpenGLFunctions(QOpenGLContext::currentContext()).hasOpenGLFeature(QOpenGLFunctions::NPOTTextures); - QSize size = textureSize(); - bool isNpot = !isPowerOfTwo(size.width()) || !isPowerOfTwo(size.height()); - if (!npotSupported && isNpot) - qWarning("Scene Graph: This system does not support the REPEAT wrap mode for non-power-of-two textures."); - } -#endif - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, d->horizontalWrap == Repeat ? GL_REPEAT : GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, d->verticalWrap == Repeat ? GL_REPEAT : GL_CLAMP_TO_EDGE); - d->wrapChanged = false; - } -} - -QSGPlainTexture::QSGPlainTexture() - : QSGTexture() - , m_texture_id(0) - , m_has_alpha(false) - , m_has_mipmaps(false) - , m_dirty_bind_options(false) - , m_owns_texture(true) - , m_mipmaps_generated(false) -{ -} - - -QSGPlainTexture::~QSGPlainTexture() -{ - if (m_texture_id && m_owns_texture) - glDeleteTextures(1, &m_texture_id); -} - -#ifdef QT_OPENGL_ES -static void swizzleBGRAToRGBA(QImage *image) -{ - const int width = image->width(); - const int height = image->height(); - for (int i = 0; i < height; ++i) { - uint *p = (uint *) image->scanLine(i); - for (int x = 0; x < width; ++x) - p[x] = ((p[x] << 16) & 0xff0000) | ((p[x] >> 16) & 0xff) | (p[x] & 0xff00ff00); - } -} -#endif - -void QSGPlainTexture::setImage(const QImage &image) -{ - m_image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); -#ifdef QT_OPENGL_ES - swizzleBGRAToRGBA(&m_image); -#endif - - m_texture_size = image.size(); - m_has_alpha = image.hasAlphaChannel(); - m_dirty_texture = true; - m_dirty_bind_options = true; - } - -int QSGPlainTexture::textureId() const -{ - if (m_dirty_texture) { - if (m_image.isNull()) { - // The actual texture and id will be updated/deleted in a later bind() - // or ~QSGPlainTexture so just keep it minimal here. - return 0; - } else { - // Generate a texture id for use later and return it. - glGenTextures(1, &const_cast<QSGPlainTexture *>(this)->m_texture_id); - return m_texture_id; - } - } - return m_texture_id; -} - -void QSGPlainTexture::setTextureId(int id) -{ - if (m_texture_id && m_owns_texture) - glDeleteTextures(1, &m_texture_id); - - m_texture_id = id; - m_dirty_texture = false; - m_dirty_bind_options = true; - m_image = QImage(); - m_mipmaps_generated = false; -} - -void QSGPlainTexture::setHasMipmaps(bool mm) -{ - m_has_mipmaps = mm; - m_mipmaps_generated = false; -} - - -void QSGPlainTexture::bind() -{ - if (!m_dirty_texture) { - glBindTexture(GL_TEXTURE_2D, m_texture_id); - if (m_has_mipmaps && !m_mipmaps_generated) { - QOpenGLContext *ctx = QOpenGLContext::currentContext(); - ctx->functions()->glGenerateMipmap(GL_TEXTURE_2D); - m_mipmaps_generated = true; - } - updateBindOptions(m_dirty_bind_options); - m_dirty_bind_options = false; - return; - } - - m_dirty_texture = false; - - - if (m_image.isNull()) { - if (m_texture_id && m_owns_texture) - glDeleteTextures(1, &m_texture_id); - m_texture_id = 0; - m_texture_size = QSize(); - m_has_mipmaps = false; - m_has_alpha = false; - return; - } - - if (m_texture_id == 0) - glGenTextures(1, &m_texture_id); - glBindTexture(GL_TEXTURE_2D, m_texture_id); - - // ### TODO: check for out-of-memory situations... - int w = m_image.width(); - int h = m_image.height(); - -#ifdef QT_OPENGL_ES - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_image.constBits()); -#else - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, m_image.constBits()); -#endif - - if (m_has_mipmaps) { - QOpenGLContext *ctx = QOpenGLContext::currentContext(); - ctx->functions()->glGenerateMipmap(GL_TEXTURE_2D); - m_mipmaps_generated = true; - } - - m_texture_size = QSize(w, h); - m_texture_rect = QRectF(0, 0, 1, 1); - - updateBindOptions(m_dirty_bind_options); - m_dirty_bind_options = false; -} - - -/*! - \class QSGDynamicTexture - \brief The QSGDynamicTexture class serves as a baseclass for dynamically changing textures, - such as content that is rendered to FBO's. - - To update the content of the texture, call updateTexture() explicitly. Simply calling bind() - will not update the texture. - */ - - -/*! - \fn bool QSGDynamicTexture::updateTexture() - - Call this function to explicitely update the dynamic texture. Calling bind() will bind - the content that was previously updated. - - The function returns true if the texture was changed as a resul of the update; otherwise - returns false. - */ - - - -QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/util/qsgtexture.h b/src/declarative/scenegraph/util/qsgtexture.h deleted file mode 100644 index 1a49fb941e..0000000000 --- a/src/declarative/scenegraph/util/qsgtexture.h +++ /dev/null @@ -1,133 +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 QSGTEXTURE_H -#define QSGTEXTURE_H - -#include <QObject> -#include <QImage> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class QSGTexturePrivate; -class Q_DECLARATIVE_EXPORT QSGTexture : public QObject -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QSGTexture) - -public: - QSGTexture(); - ~QSGTexture(); - - enum WrapMode { - Repeat, - ClampToEdge - }; - - enum Filtering { - None, - Nearest, - Linear - }; - - virtual int textureId() const = 0; - virtual QSize textureSize() const = 0; - virtual bool hasAlphaChannel() const = 0; - virtual bool hasMipmaps() const = 0; - - virtual QRectF textureSubRect() const; - - virtual bool isAtlasTexture() const; - - virtual QSGTexture *removedFromAtlas() const; - - virtual void bind() = 0; - void updateBindOptions(bool force = false); - - void setMipmapFiltering(Filtering filter); - QSGTexture::Filtering mipmapFiltering() const; - - void setFiltering(Filtering filter); - QSGTexture::Filtering filtering() const; - - void setHorizontalWrapMode(WrapMode hwrap); - QSGTexture::WrapMode horizontalWrapMode() const; - - void setVerticalWrapMode(WrapMode vwrap); - QSGTexture::WrapMode verticalWrapMode() const; - - inline QRectF convertToNormalizedSourceRect(const QRectF &rect) const; - -protected: - QSGTexture(QSGTexturePrivate &dd); -}; - -QRectF QSGTexture::convertToNormalizedSourceRect(const QRectF &rect) const -{ - QSize s = textureSize(); - QRectF r = textureSubRect(); - - qreal sx = r.width() / s.width(); - qreal sy = r.height() / s.height(); - - return QRectF(r.x() + rect.x() * sx, - r.y() + rect.y() * sy, - rect.width() * sx, - rect.height() * sy); -} - - -class Q_DECLARATIVE_EXPORT QSGDynamicTexture : public QSGTexture -{ - Q_OBJECT -public: - virtual bool updateTexture() = 0; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/declarative/scenegraph/util/qsgtexture_p.h b/src/declarative/scenegraph/util/qsgtexture_p.h deleted file mode 100644 index f14508fd25..0000000000 --- a/src/declarative/scenegraph/util/qsgtexture_p.h +++ /dev/null @@ -1,118 +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 QSGTEXTURE_P_H -#define QSGTEXTURE_P_H - -#include <private/qobject_p.h> - -#include <QtGui/qopengl.h> - -#include "qsgtexture.h" -#include <private/qsgcontext_p.h> - -QT_BEGIN_NAMESPACE - -class QSGTexturePrivate : public QObjectPrivate -{ - Q_DECLARE_PUBLIC(QSGTexture); -public: - QSGTexturePrivate(); - - uint wrapChanged : 1; - uint filteringChanged : 1; - - uint horizontalWrap : 1; - uint verticalWrap : 1; - uint mipmapMode : 2; - uint filterMode : 2; -}; - -class Q_DECLARATIVE_EXPORT QSGPlainTexture : public QSGTexture -{ - Q_OBJECT -public: - QSGPlainTexture(); - virtual ~QSGPlainTexture(); - - void setOwnsTexture(bool owns) { m_owns_texture = owns; } - bool ownsTexture() const { return m_owns_texture; } - - void setTextureId(int id); - int textureId() const; - void setTextureSize(const QSize &size) { m_texture_size = size; } - QSize textureSize() const { return m_texture_size; } - - void setHasAlphaChannel(bool alpha) { m_has_alpha = alpha; } - bool hasAlphaChannel() const { return m_has_alpha; } - - void setHasMipmaps(bool mm); - bool hasMipmaps() const { return m_has_mipmaps; } - - void setImage(const QImage &image); - const QImage &image() { return m_image; } - - virtual void bind(); - - static QSGPlainTexture *fromImage(const QImage &image) { - QSGPlainTexture *t = new QSGPlainTexture(); - t->setImage(image); - return t; - } - -protected: - QImage m_image; - - GLuint m_texture_id; - QSize m_texture_size; - QRectF m_texture_rect; - - uint m_has_alpha : 1; - uint m_has_mipmaps : 1; - uint m_dirty_texture : 1; - uint m_dirty_bind_options : 1; - uint m_owns_texture : 1; - uint m_mipmaps_generated : 1; -}; - -QT_END_NAMESPACE - -#endif // QSGTEXTURE_P_H diff --git a/src/declarative/scenegraph/util/qsgtexturematerial.cpp b/src/declarative/scenegraph/util/qsgtexturematerial.cpp deleted file mode 100644 index 0bee81993c..0000000000 --- a/src/declarative/scenegraph/util/qsgtexturematerial.cpp +++ /dev/null @@ -1,410 +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 "qsgtexturematerial_p.h" - -#include <QtGui/qopenglshaderprogram.h> -#include <QtGui/qopenglfunctions.h> - -QT_BEGIN_NAMESPACE - -inline static bool isPowerOfTwo(int x) -{ - // Assumption: x >= 1 - return x == (x & -x); -} - -const char qt_scenegraph_texture_material_vertex_code[] = - "uniform highp mat4 qt_Matrix; \n" - "attribute highp vec4 qt_VertexPosition; \n" - "attribute highp vec2 qt_VertexTexCoord; \n" - "varying highp vec2 qt_TexCoord; \n" - "void main() { \n" - " qt_TexCoord = qt_VertexTexCoord; \n" - " gl_Position = qt_Matrix * qt_VertexPosition; \n" - "}"; - -const char qt_scenegraph_texture_material_fragment[] = - "varying highp vec2 qt_TexCoord; \n" - "uniform sampler2D qt_Texture; \n" - "void main() { \n" - " gl_FragColor = texture2D(qt_Texture, qt_TexCoord);\n" - "}"; - - -const char *QSGOpaqueTextureMaterialShader::vertexShader() const -{ - return qt_scenegraph_texture_material_vertex_code; -} - -const char *QSGOpaqueTextureMaterialShader::fragmentShader() const -{ - return qt_scenegraph_texture_material_fragment; -} - -QSGMaterialType QSGOpaqueTextureMaterialShader::type; - -char const *const *QSGOpaqueTextureMaterialShader::attributeNames() const -{ - static char const *const attr[] = { "qt_VertexPosition", "qt_VertexTexCoord", 0 }; - return attr; -} - -void QSGOpaqueTextureMaterialShader::initialize() -{ - m_matrix_id = program()->uniformLocation("qt_Matrix"); -} - -void QSGOpaqueTextureMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) -{ - Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type()); - QSGOpaqueTextureMaterial *tx = static_cast<QSGOpaqueTextureMaterial *>(newEffect); - QSGOpaqueTextureMaterial *oldTx = static_cast<QSGOpaqueTextureMaterial *>(oldEffect); - - QSGTexture *t = tx->texture(); - - t->setFiltering(tx->filtering()); -#ifdef QT_OPENGL_ES_2 - bool npotSupported = QOpenGLFunctions(const_cast<QOpenGLContext *>(state.context())).hasOpenGLFeature(QOpenGLFunctions::NPOTTextures); - QSize size = t->textureSize(); - bool isNpot = !isPowerOfTwo(size.width()) || !isPowerOfTwo(size.height()); - if (!npotSupported && isNpot) { - t->setHorizontalWrapMode(QSGTexture::ClampToEdge); - t->setVerticalWrapMode(QSGTexture::ClampToEdge); - } else -#endif - { - t->setHorizontalWrapMode(tx->horizontalWrapMode()); - t->setVerticalWrapMode(tx->verticalWrapMode()); - } - t->setMipmapFiltering(tx->mipmapFiltering()); - - if (oldTx == 0 || oldTx->texture()->textureId() != t->textureId()) - t->bind(); - else - t->updateBindOptions(); - - if (state.isMatrixDirty()) - program()->setUniformValue(m_matrix_id, state.combinedMatrix()); -} - - -/*! - \class QSGOpaqueTextureMaterial - \brief The QSGOpaqueTextureMaterial class provides a convenient way of - rendering textured geometry in the scene graph. - - The opaque textured material will fill every pixel in a geometry with - the supplied texture. The material does not respect the opacity of the - QSGMaterialShader::RenderState, so opacity nodes in the parent chain - of nodes using this material, have no effect. - - The geometry to be rendered with an opaque texture material requires - vertices in attribute location 0 and texture coordinates in attribute - location 1. The texture coordinate is a 2-dimensional floating-point - tuple. The QSGGeometry::defaultAttributes_TexturedPoint2D returns an - attribute set compatible with this material. - - The texture to be rendered is can be set using setTexture(). How the - texure should be rendered can be specified using setMipmapFiltering(), - setFiltering(), setHorizontalWrapMode() and setVerticalWrapMode(). - The rendering state is set on the texture instance just before it - is bound. - - The opaque textured material respects the current matrix and the alpha - channel of the texture. It will disregard the accumulated opacity in - the scenegraph. - - A texture material must have a texture set before it is used as - a material in the scene graph. - */ - - - -/*! - Creates a new QSGOpaqueTextureMaterial. - - The default mipmap filtering and filtering mode is set to - QSGTexture::Nearest. The default wrap modes is set to - QSGTexture::ClampToEdge. - - */ -QSGOpaqueTextureMaterial::QSGOpaqueTextureMaterial() - : m_texture(0) - , m_filtering(QSGTexture::Nearest) - , m_mipmap_filtering(QSGTexture::Nearest) - , m_horizontal_wrap(QSGTexture::ClampToEdge) - , m_vertical_wrap(QSGTexture::ClampToEdge) -{ -} - - -/*! - \internal - */ -QSGMaterialType *QSGOpaqueTextureMaterial::type() const -{ - return &QSGOpaqueTextureMaterialShader::type; -} - -/*! - \internal - */ -QSGMaterialShader *QSGOpaqueTextureMaterial::createShader() const -{ - return new QSGOpaqueTextureMaterialShader; -} - - - -/*! - \fn QSGTexture *QSGOpaqueTextureMaterial::texture() const - - Returns this texture material's texture. - */ - - - -/*! - Sets the texture of this material to \a texture. - - The material does not take ownership over the texture. - */ - -void QSGOpaqueTextureMaterial::setTexture(QSGTexture *texture) -{ - m_texture = texture; - setFlag(Blending, m_texture ? m_texture->hasAlphaChannel() : false); -} - - - -/*! - \fn void QSGOpaqueTextureMaterial::setMipmapFiltering(QSGTexture::Filtering filtering) - - Sets the mipmap mode to \a filtering. - - The mipmap filtering mode is set on the texture instance just before the - texture is bound for rendering. - - If the texture does not have mipmapping support, enabling mipmapping has no - effect. - */ - - - -/*! - \fn QSGTexture::Filtering QSGOpaqueTextureMaterial::mipmapFiltering() const - - Returns this material's mipmap filtering mode. - - The default mipmap mode is QSGTexture::Nearest. - */ - - - -/*! - \fn void QSGOpaqueTextureMaterial::setFiltering(QSGTexture::Filtering filtering) - - Sets the filtering to \a filtering. - - The filtering mode is set on the texture instance just before the texture - is bound for rendering. - */ - - - -/*! - \fn QSGTexture::Filtering filtering() const - - Returns this material's filtering mode. - - The default filtering is QSGTexture::Nearest. - */ - - - -/*! - \fn void setHorizontalWrapMode(QSGTexture::WrapMode mode) - - Sets the horizontal wrap mode to \a mode. - - The horizontal wrap mode is set on the texture instance just before the texture - is bound for rendering. - */ - - - - /*! - \fn QSGTexture::WrapMode horizontalWrapMode() const - - Returns this material's horizontal wrap mode. - - The default horizontal wrap mode is QSGTexutre::ClampToEdge - */ - - - -/*! - \fn void setVerticalWrapMode(QSGTexture::WrapMode mode) - - Sets the vertical wrap mode to \a mode. - - The vertical wrap mode is set on the texture instance just before the texture - is bound for rendering. - */ - - - - /*! - \fn QSGTexture::WrapMode verticalWrapMode() const - - Returns this material's vertical wrap mode. - - The default vertical wrap mode is QSGTexutre::ClampToEdge - */ - - - -/*! - \internal - */ - -int QSGOpaqueTextureMaterial::compare(const QSGMaterial *o) const -{ - Q_ASSERT(o && type() == o->type()); - const QSGOpaqueTextureMaterial *other = static_cast<const QSGOpaqueTextureMaterial *>(o); - if (int diff = m_texture->textureId() - other->texture()->textureId()) - return diff; - return int(m_filtering) - int(other->m_filtering); -} - - - -/*! - \class QSGTextureMaterial - \brief The QSGTextureMaterial class provides a convenient way of - rendering textured geometry in the scene graph. - - The textured material will fill every pixel in a geometry with - the supplied texture. - - The geometry to be rendered with a texture material requires - vertices in attribute location 0 and texture coordinates in attribute - location 1. The texture coordinate is a 2-dimensional floating-point - tuple. The QSGGeometry::defaultAttributes_TexturedPoint2D returns an - attribute set compatible with this material. - - The texture to be rendered is set using setTexture(). How the - texure should be rendered can be specified using setMipmapFiltering(), - setFiltering(), setHorizontalWrapMode() and setVerticalWrapMode(). - The rendering state is set on the texture instance just before it - is bound. - - The textured material respects the current matrix and the alpha - channel of the texture. It will also respect the accumulated opacity - in the scenegraph. - - A texture material must have a texture set before it is used as - a material in the scene graph. - */ - -static const char qt_scenegraph_texture_material_opacity_fragment[] = - "varying highp vec2 qt_TexCoord; \n" - "uniform sampler2D qt_Texture; \n" - "uniform lowp float opacity; \n" - "void main() { \n" - " gl_FragColor = texture2D(qt_Texture, qt_TexCoord) * opacity; \n" - "}"; - -class QSGTextureMaterialShader : public QSGOpaqueTextureMaterialShader -{ -public: - virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect); - virtual void initialize(); - - static QSGMaterialType type; - -protected: - virtual const char *fragmentShader() const { return qt_scenegraph_texture_material_opacity_fragment; } - - int m_opacity_id; -}; -QSGMaterialType QSGTextureMaterialShader::type; - - - -/*! - \internal - */ - -QSGMaterialType *QSGTextureMaterial::type() const -{ - return &QSGTextureMaterialShader::type; -} - - - -/*! - \internal - */ - -QSGMaterialShader *QSGTextureMaterial::createShader() const -{ - return new QSGTextureMaterialShader; -} - -void QSGTextureMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) -{ - Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type()); - if (state.isOpacityDirty()) - program()->setUniformValue(m_opacity_id, state.opacity()); - - QSGOpaqueTextureMaterialShader::updateState(state, newEffect, oldEffect); -} - -void QSGTextureMaterialShader::initialize() -{ - QSGOpaqueTextureMaterialShader::initialize(); - m_opacity_id = program()->uniformLocation("opacity"); -} - -QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/util/qsgtexturematerial.h b/src/declarative/scenegraph/util/qsgtexturematerial.h deleted file mode 100644 index be6ba7a8ab..0000000000 --- a/src/declarative/scenegraph/util/qsgtexturematerial.h +++ /dev/null @@ -1,102 +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 TEXTUREMATERIAL_H -#define TEXTUREMATERIAL_H - -#include "qsgmaterial.h" -#include <qsgtexture.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - - -class Q_DECLARATIVE_EXPORT QSGOpaqueTextureMaterial : public QSGMaterial -{ -public: - QSGOpaqueTextureMaterial(); - - virtual QSGMaterialType *type() const; - virtual QSGMaterialShader *createShader() const; - virtual int compare(const QSGMaterial *other) const; - - void setTexture(QSGTexture *texture); - QSGTexture *texture() const { return m_texture; } - - void setMipmapFiltering(QSGTexture::Filtering filtering) { m_mipmap_filtering = filtering; } - QSGTexture::Filtering mipmapFiltering() const { return (QSGTexture::Filtering) m_mipmap_filtering; } - - void setFiltering(QSGTexture::Filtering filtering) { m_filtering = filtering; } - QSGTexture::Filtering filtering() const { return (QSGTexture::Filtering) m_filtering; } - - void setHorizontalWrapMode(QSGTexture::WrapMode mode) { m_horizontal_wrap = mode; } - QSGTexture::WrapMode horizontalWrapMode() const { return (QSGTexture::WrapMode) m_horizontal_wrap; } - - void setVerticalWrapMode(QSGTexture::WrapMode mode) { m_vertical_wrap = mode; } - QSGTexture::WrapMode verticalWrapMode() const { return (QSGTexture::WrapMode) m_vertical_wrap; } - -protected: - QSGTexture *m_texture; - - uint m_filtering: 2; - uint m_mipmap_filtering: 2; - uint m_horizontal_wrap : 1; - uint m_vertical_wrap: 1; - - uint m_reserved : 26; -}; - - -class Q_DECLARATIVE_EXPORT QSGTextureMaterial : public QSGOpaqueTextureMaterial -{ -public: - virtual QSGMaterialType *type() const; - virtual QSGMaterialShader *createShader() const; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // TEXTUREMATERIAL_H diff --git a/src/declarative/scenegraph/util/qsgtexturematerial_p.h b/src/declarative/scenegraph/util/qsgtexturematerial_p.h deleted file mode 100644 index a549f841d8..0000000000 --- a/src/declarative/scenegraph/util/qsgtexturematerial_p.h +++ /dev/null @@ -1,73 +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 TEXTUREMATERIAL_P_H -#define TEXTUREMATERIAL_P_H - -#include "qsgtexturematerial.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class Q_DECLARATIVE_EXPORT QSGOpaqueTextureMaterialShader : public QSGMaterialShader -{ -public: - virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect); - virtual char const *const *attributeNames() const; - - static QSGMaterialType type; - -protected: - virtual void initialize(); - virtual const char *vertexShader() const; - virtual const char *fragmentShader() const; - - int m_matrix_id; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QSGTEXTUREMATERIAL_P_H diff --git a/src/declarative/scenegraph/util/qsgtextureprovider.cpp b/src/declarative/scenegraph/util/qsgtextureprovider.cpp deleted file mode 100644 index 10faf2e5d4..0000000000 --- a/src/declarative/scenegraph/util/qsgtextureprovider.cpp +++ /dev/null @@ -1,59 +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 "qsgtextureprovider_p.h" - -#ifndef GL_CLAMP_TO_EDGE -#define GL_CLAMP_TO_EDGE 0x812F -#endif - -QT_BEGIN_NAMESPACE - -/*! - \class QSGTextureProvider - \brief The QSGTextureProvider class encapsulates texture based entities in QML. - - The QSGTextureProvider lives primarily in the scene graph rendering thread. - */ - - - -QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/util/qsgtextureprovider_p.h b/src/declarative/scenegraph/util/qsgtextureprovider_p.h deleted file mode 100644 index ebb6ca8507..0000000000 --- a/src/declarative/scenegraph/util/qsgtextureprovider_p.h +++ /dev/null @@ -1,68 +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 QSGTEXTUREPROVIDER_H -#define QSGTEXTUREPROVIDER_H - -#include "qsgtexture.h" -#include "qobject.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class Q_DECLARATIVE_EXPORT QSGTextureProvider : public QObject -{ - Q_OBJECT -public: - virtual QSGTexture *texture() const = 0; - -Q_SIGNALS: - void textureChanged(); -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/declarative/scenegraph/util/qsgvertexcolormaterial.cpp b/src/declarative/scenegraph/util/qsgvertexcolormaterial.cpp deleted file mode 100644 index 78cef55215..0000000000 --- a/src/declarative/scenegraph/util/qsgvertexcolormaterial.cpp +++ /dev/null @@ -1,173 +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 "qsgvertexcolormaterial.h" - -#include <qopenglshaderprogram.h> - -QT_BEGIN_NAMESPACE - -class QSGVertexColorMaterialShader : public QSGMaterialShader -{ -public: - virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect); - virtual char const *const *attributeNames() const; - - static QSGMaterialType type; - -private: - virtual void initialize(); - virtual const char *vertexShader() const; - virtual const char *fragmentShader() const; - - int m_matrix_id; - int m_opacity_id; -}; - -QSGMaterialType QSGVertexColorMaterialShader::type; - -void QSGVertexColorMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *) -{ - if (!(newEffect->flags() & QSGMaterial::Blending) || state.isOpacityDirty()) - program()->setUniformValue(m_opacity_id, state.opacity()); - - if (state.isMatrixDirty()) - program()->setUniformValue(m_matrix_id, state.combinedMatrix()); -} - -char const *const *QSGVertexColorMaterialShader::attributeNames() const -{ - static const char *const attr[] = { "vertexCoord", "vertexColor", 0 }; - return attr; -} - -void QSGVertexColorMaterialShader::initialize() -{ - m_matrix_id = program()->uniformLocation("matrix"); - m_opacity_id = program()->uniformLocation("opacity"); -} - -const char *QSGVertexColorMaterialShader::vertexShader() const { - return - "attribute highp vec4 vertexCoord; \n" - "attribute highp vec4 vertexColor; \n" - "uniform highp mat4 matrix; \n" - "uniform highp float opacity; \n" - "varying lowp vec4 color; \n" - "void main() { \n" - " gl_Position = matrix * vertexCoord; \n" - " color = vertexColor * opacity; \n" - "}"; -} - -const char *QSGVertexColorMaterialShader::fragmentShader() const { - return - "varying lowp vec4 color; \n" - "void main() { \n" - " gl_FragColor = color; \n" - "}"; -} - - - -/*! - \class QSGVertexColorMaterial - \brief The QSGVertexColorMaterial class provides a convenient way of rendering per-vertex - colored geometry in the scene graph. - - \inmodule QtDeclarative - - The vertex color material will give each vertex in a geometry a color. Pixels between - vertices will be linearly interpolated. The colors can contain transparency. - - The geometry to be rendered with vertex color must have the following layout. Attribute - position 0 must contain vertices. Attribute position 1 must contain colors, a tuple of - 4 values with RGBA layout. Both floats in the range of 0 to 1 and unsigned bytes in - the range 0 to 255 are valid for the color values. The - QSGGeometry::defaultAttributes_ColoredPoint2D() constructs an attribute set - compatible with this material. - - The vertex color material respects both current opacity and current matrix when - updating it's rendering state. - */ - - -QSGVertexColorMaterial::QSGVertexColorMaterial() -{ - setFlag(Blending, true); -} - - -/*! - int QSGVertexColorMaterial::compare() const - - As the vertex color material has all its state in the vertex attributes, - all materials will be equal. - - \internal - */ - -int QSGVertexColorMaterial::compare(const QSGMaterial * /* other */) const -{ - return 0; -} - -/*! - \internal - */ - -QSGMaterialType *QSGVertexColorMaterial::type() const -{ - return &QSGVertexColorMaterialShader::type; -} - - - -/*! - \internal - */ - -QSGMaterialShader *QSGVertexColorMaterial::createShader() const -{ - return new QSGVertexColorMaterialShader; -} - -QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/util/qsgvertexcolormaterial.h b/src/declarative/scenegraph/util/qsgvertexcolormaterial.h deleted file mode 100644 index c244f63834..0000000000 --- a/src/declarative/scenegraph/util/qsgvertexcolormaterial.h +++ /dev/null @@ -1,69 +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 VERTEXCOLORMATERIAL_H -#define VERTEXCOLORMATERIAL_H - -#include <qsgmaterial.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class Q_DECLARATIVE_EXPORT QSGVertexColorMaterial : public QSGMaterial -{ -public: - QSGVertexColorMaterial(); - - int compare(const QSGMaterial *other) const; - -protected: - virtual QSGMaterialType *type() const; - virtual QSGMaterialShader *createShader() const; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // VERTEXCOLORMATERIAL_H |