diff options
author | Gunnar Sletta <gunnar.sletta@digia.com> | 2013-11-06 10:06:27 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-11-09 22:46:47 +0100 |
commit | afee694ce5d65518e5908b97e9a691c03fe0a844 (patch) | |
tree | be6e714703b799791cdacbea4b315471ab9b6a03 /src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp | |
parent | 7b75c3e63e7842c2667f58d43d44e21ff57ac0c8 (diff) |
Avoid using huge floating point values in the renderer.
We pretransform vertices relative to their batch root and upload these
using single-precision floats. If the offsets are huge then the
floating point numbers start to get unstable and we get rendering
artifacts as a result. This typically happens for lists/tables with
huge models.
Task-number: QTBUG-34312
Change-Id: I2516f2b4fa93f44a1288659d05458fb1af0df943
Reviewed-by: Laszlo Agocs <laszlo.agocs@digia.com>
Diffstat (limited to 'src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp')
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp | 24 |
1 files changed, 20 insertions, 4 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; |