Description
The current (preliminary) qt 5 scenegraph integration uses the QSGPainted item to put the 3D content into an FBO which is then composited in to the 2D by the sg engine. This is fine for small pieces of simple 3D content.
For larger scenes, and especially ones where 3D content is predominant in the window, a more efficient technique without the extra FBO is needed. This is GL under, where the renderer is intercepted before it draws anything else, and GL content is painted into the context. The maps team have already implemented this, and we can follow their example:
// This way your 'beforeRendering' will execute in the QSG rendering thread. // Avoids the moveToThread in the earlier code below void QDeclarative3DGraphicsGeoMap::sceneGraphInitialized() { QSGEngine* engine = canvas_->sceneGraphEngine(); if (!engine) { qmlInfo(this) << tr("Unable to get QSGEngine. Will not be able to render the map."); return; } connect((QObject*)engine, SIGNAL(beforeRendering()), this, SLOT(beforeRendering()), Qt::DirectConnection); engine->setClearBeforeRendering(false); }
Also from the maps team, an earlier comment (might have been improved on so check their sources):
// Added new method into the QSG implementation: QThread* QSGCanvas::renderingThread(); // In QDeclarative3DGraphicsGeoMap::ItemChange() make a renderer object in the SG thread: renderer_ = new Map3DRenderer(this, canvas_); // In that renderer_ class constructor I move to the rendering thread: Map3DRenderer::Map3DRenderer(QDeclarative3DGraphicsGeoMap* map, QSGCanvas *canvas): QObject(), canvas_(canvas), map_(map) { if (canvas_ && canvas_->renderingThread()) { this->moveToThread(canvas_->renderingThread()); connect(canvas_, SIGNAL(sceneGraphInitialized()), this, SLOT(sceneGraphInitialized())); } } // And then when Map3DRenderer::beforeRendering() is invoked, render. // Call directly the QDeclarative3DGraphicsGeoMap::paint() function in the QSG thread.