diff options
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp | 24 | ||||
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h | 13 | ||||
-rw-r--r-- | tests/auto/quick/scenegraph/data/render_OutOfFloatRange.qml | 108 | ||||
-rw-r--r-- | tests/auto/quick/scenegraph/scenegraph.pro | 3 | ||||
-rw-r--r-- | tests/auto/quick/scenegraph/tst_scenegraph.cpp | 1 |
5 files changed, 144 insertions, 5 deletions
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index bb98682b20..3ea4b2ee1e 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -562,6 +562,8 @@ void Element::computeBounds() bounds.br.x = FLT_MAX; if (!qIsFinite(bounds.br.y)) bounds.br.y = FLT_MAX; + + boundsOutsideFloatRange = bounds.isOutsideFloatRange(); } RenderNodeElement::~RenderNodeElement() @@ -662,12 +664,26 @@ bool Batch::isTranslateOnlyToRoot() const { /* * Iterates through all the nodes in the batch and returns true if the - * nodes are all "2D safe" meaning that they can be merged and that - * the value in the z coordinate is of no consequence. + * nodes are all safe to batch. There are two separate criteria: + * + * - The matrix is such that the z component of the result is of no + * consequence. + * + * - The bounds are inside the stable floating point range. This applies + * to desktop only where we in this case can trigger a fallback to + * unmerged in which case we pass the geometry straight through and + * just apply the matrix. + * + * NOTE: This also means a slight performance impact for geometries which + * are defined to be outside the stable floating point range and still + * use single precision float, but given that this implicitly fixes + * huge lists and tables, it is worth it. */ -bool Batch::allMatricesAre2DSafe() const { +bool Batch::isSafeToBatch() const { Element *e = first; while (e) { + if (e->boundsOutsideFloatRange) + return false; if (!QMatrix4x4_Accessor::is2DSafe(*e->node->matrix())) return false; e = e->nextInBatch; @@ -1637,7 +1653,7 @@ void Renderer::uploadBatch(Batch *b) && (((gn->activeMaterial()->flags() & QSGMaterial::RequiresDeterminant) == 0) || (((gn->activeMaterial()->flags() & QSGMaterial_RequiresFullMatrixBit) == 0) && b->isTranslateOnlyToRoot()) ) - && b->allMatricesAre2DSafe(); + && b->isSafeToBatch(); b->merged = canMerge; diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h index 23985729ef..6d95f83d7a 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h @@ -53,6 +53,8 @@ QT_BEGIN_NAMESPACE namespace QSGBatchRenderer { +#define QSG_RENDERER_COORD_LIMIT 1000000.0f + struct Vec; struct Rect; struct Buffer; @@ -136,6 +138,13 @@ struct Rect { bool yOverlap = r.tl.y < br.y && r.br.y > tl.y; return xOverlap && yOverlap; } + + bool isOutsideFloatRange() const { + return tl.x < -QSG_RENDERER_COORD_LIMIT + || tl.y < -QSG_RENDERER_COORD_LIMIT + || br.x > QSG_RENDERER_COORD_LIMIT + || br.y > QSG_RENDERER_COORD_LIMIT; + } }; inline QDebug operator << (QDebug d, const Rect &r) { @@ -158,6 +167,7 @@ struct Element { , root(0) , order(0) , boundsComputed(false) + , boundsOutsideFloatRange(false) , translateOnlyToRoot(false) , removed(false) , orphaned(false) @@ -181,6 +191,7 @@ struct Element { int order; uint boundsComputed : 1; + uint boundsOutsideFloatRange : 1; uint translateOnlyToRoot : 1; uint removed : 1; uint orphaned : 1; @@ -242,7 +253,7 @@ struct Batch void cleanupRemovedElements(); bool isTranslateOnlyToRoot() const; - bool allMatricesAre2DSafe() const; + bool isSafeToBatch() const; // pseudo-constructor... void init() { diff --git a/tests/auto/quick/scenegraph/data/render_OutOfFloatRange.qml b/tests/auto/quick/scenegraph/data/render_OutOfFloatRange.qml new file mode 100644 index 0000000000..60caa4d561 --- /dev/null +++ b/tests/auto/quick/scenegraph/data/render_OutOfFloatRange.qml @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, 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, Digia gives you certain additional +** rights. These rights are described in the Digia 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. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.2 + +/* + The test verifies that batching does not interfere with overlapping + regions. + + #samples: 8 + PixelPos R G B Error-tolerance + #base: 10 10 1.0 0.0 0.0 0.0 + #base: 10 110 1.0 0.0 0.0 0.0 + #base: 10 11 0.0 0.0 1.0 0.0 + #base: 10 111 0.0 0.0 1.0 0.0 + + #final: 10 10 1.0 0.0 0.0 0.05 + #final: 10 110 1.0 0.0 0.0 0.05 + #final: 10 11 0.0 0.0 1.0 0.05 + #final: 10 111 0.0 0.0 1.0 0.05 +*/ + +RenderTestBase +{ + id: root + property real offset: 0; + property real farAway: 10000000; + + Item { + y: -root.offset + 10 + x: 10 + Repeater { + model: 200 + Rectangle { + x: index % 100 + y: root.offset + (index < 100 ? 0 : 1); + width: 1 + height: 1 + color: index < 100 ? "red" : "blue" + antialiasing: true; + } + } + } + + Item { + y: -root.offset + 110 + x: 10 + Item { + y: root.offset + + Repeater { + model: 200 + Rectangle { + x: index % 100 + y: (index < 100 ? 0 : 1); + width: 1 + height: 1 + color: index < 100 ? "red" : "blue" + antialiasing: true; + } + } + } + } + + onEnterFinalStage: { + root.offset = root.farAway; + root.finalStageComplete = true; + } + +} diff --git a/tests/auto/quick/scenegraph/scenegraph.pro b/tests/auto/quick/scenegraph/scenegraph.pro index 7e7a8eb162..105221b7f4 100644 --- a/tests/auto/quick/scenegraph/scenegraph.pro +++ b/tests/auto/quick/scenegraph/scenegraph.pro @@ -9,3 +9,6 @@ macx:CONFIG -= app_bundle QT += core-private gui-private qml-private quick-private testlib DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 + +OTHER_FILES += \ + data/render_OutOfFloatRange.qml diff --git a/tests/auto/quick/scenegraph/tst_scenegraph.cpp b/tests/auto/quick/scenegraph/tst_scenegraph.cpp index 656e1c5a58..755cec460d 100644 --- a/tests/auto/quick/scenegraph/tst_scenegraph.cpp +++ b/tests/auto/quick/scenegraph/tst_scenegraph.cpp @@ -322,6 +322,7 @@ void tst_SceneGraph::render_data() << "data/render_Overlap.qml" << "data/render_MovingOverlap.qml" << "data/render_BreakOpacityBatch.qml" + << "data/render_OutOfFloatRange.qml" ; QRegExp sampleCount("#samples: *(\\d+)"); |