aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp24
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h13
-rw-r--r--tests/auto/quick/scenegraph/data/render_OutOfFloatRange.qml108
-rw-r--r--tests/auto/quick/scenegraph/scenegraph.pro3
-rw-r--r--tests/auto/quick/scenegraph/tst_scenegraph.cpp1
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+)");