Details
-
Bug
-
Resolution: Unresolved
-
P2: Important
-
None
-
5.11, 5.12.4, 5.13.0
-
None
Description
Short description: in customer project of the company I work for there is a case of drawing a scene using QtQuick Shapes where world coordinates vary from 0 to 100000. The world coordinates are converted to the screen coordinates using the property "transform" and Matrix4x4. This crashes on Windows with rendererType = Shape.GeometryRenderer because the coordinates are greater than 65536.
Long description: There is a peculiar detail in the implementation of the QtQuick Shapes plugin which is neither documented in the Shapes documentation itself nor described in the QPainter that can be implicitly used to triangulate the shapes (at least I couldn't find any mention of it).
Recently I've implemented a visualization of a real object that consists of multiple moving parts. The geometry of these parts is configurable, is given by a technical specification and their position is received from an external data source.
So I naturally decided to draw the whole scene with QtQuick Shapes in the object's real world coordinate system because it would be easier for the customer to operate the object's real sizes. The world coordinate system is then transformed to the screen coordinates using the "transform" property of the parent QML Item. The sizes can vary from somewhat around 100 millimeters to 100 meters, so I used 1 mm as the unit length.
This approach worked both on my development Windows PC with an NVIDIA graphics card and on the target hardware with an IMX6 processor.
On a customer's PC this didn't work though with an assertion error:
ASSERT: "qAbs(m_vertices.at.x) < (1 << 21)" in file painting\qtriangulator.cpp, line 790
After some research and debugging I found out the customer's Windows PC had an integrated Intel graphics, and the Qt QPainter's triangulator was used by default (Qt 5.11) instead of the NVIDIA extension (unlike my PC). The QPainter's triangulator requires that the coordinates are not greater than 2 bytes (this 1<<21 assertion is preceeded by multiplying all coordinates with 32 in the internals of the triangulator) which is, as mentioned above, is not stated in the documentation.
I tested the behavior of the Shape with the following code snippet:
import QtQuick 2.11 import QtQuick.Window 2.11 import QtQuick.Shapes 1.11 Window { visible: true width: 640 height: 480 title: qsTr("Hello World") Item { anchors.fill: parent Shape { anchors.fill: parent vendorExtensionsEnabled: false ShapePath { strokeColor: "black" strokeWidth: 2 startX: 320 startY: 240 PathLine { // offending line x: (1<<16) y: 240 } } } } }
The code snipped above crashes on Windows with Qt 5.11, 5.12, 5.13 with
ASSERT: "qAbs(m_vertices.at.x) < (1 << 21)" in file painting\qtriangulator.cpp, line 790
After running some tests in a Linux virtual machine with apparently software rendering backend other than that on Windows I found out that 1<<16 are okay, and the coordinates above (1<<32) just flip the direction of drawing.
Both Windows and Linux versions had the property rendererType of the shape set to Shape.GeometryRenderer
Proposal:
- Change the QtQuick Shape drawing backend so that any valid qreal value can be used (probably unrealistic), or
- Change the documentation to state explicitly that the coordinates of the shapes cannot be greater than 65536 even when using Transform