Commit e20c3516 authored by Gunnar Sletta's avatar Gunnar Sletta Committed by Qt by Nokia

Allow SG and GL resources to survive a releaseResources.

The presence of these functions required some documentation so I
added some.

Change-Id: Id66bb6704b3db788ed612ebd6497a5c16ee8b2ca
Reviewed-by: 's avatarSamuel Rødal <>
parent 04327298
......@@ -306,6 +306,8 @@ QQuickCanvasPrivate::QQuickCanvasPrivate()
, windowManager(0)
, clearColor(Qt::white)
, clearBeforeRendering(true)
, persistentGLContext(false)
, persistentSceneGraph(false)
, renderTarget(0)
, renderTargetId(0)
, incubationController(0)
......@@ -728,6 +730,55 @@ void QQuickCanvasPrivate::cleanup(QSGNode *n)
reparent the items to the root item or to an existing item in the scene.
For easily displaying a scene from a QML file, see \l{QQuickView}.
\section1 Scene Graph and Rendering
The QQuickCanvas uses a scene graph on top of OpenGL to render. This scene graph is disconnected
from the QML scene and potentially lives in another thread, depending on the platform
implementation. Since the rendering scene graph lives independently from the QML scene, it can
also be completely released without affecting the state of the QML scene.
The sceneGraphInitialized() signal is emitted on the rendering thread before the QML scene is
rendered to the screen for the first time. If the rendering scene graph has been released
the signal will be emitted again before the next frame is rendered.
Rendering is done by first copying the QML scene's state into the rendering scene graph. This is
done by calling QQuickItem::updatePaintNode() functions on all items that have changed. This phase
is run on the rendering thread with the GUI thread blocked, when a separate rendering thread
is being used. The scene can then be rendered.
Before the scene graph is rendered, the beforeRendering() signal is emitted. The OpenGL context
is bound at this point and the application is free to do its own rendering. Also
make sure to disable the clearing of the color buffer, using setClearBeforeRendering(). The
default clear color is white and can be changed with setClearColor(). After the scene has
been rendered, the afterRendering() signal is emitted. The application can use this to render
OpenGL on top of a QML application. Once the frame is fully done and has been swapped,
the frameSwapped() signal is emitted.
While the scene graph is being rendered on the rendering thread, the GUI will process animations
for the next frame. This means that as long as users are not using scene graph API
directly, the added complexity of a rendering thread can be completely ignored.
When a QQuickCanvas is programatically hidden with hide() or setVisible(false), it will
stop rendering and its scene graph and OpenGL context might be released. The
sceneGraphInvalidated() signal will be emitted when this happens.
\warning It is crucial that OpenGL operations and interaction with the scene graph happens
exclusively on the rendering thread, primarily during the updatePaintNode() phase.
\warning As signals related to rendering might be emitted from the rendering thread,
connections should be made using Qt::DirectConnection
\section1 Resource Management
QML will typically try to cache images, scene graph nodes, etc to improve performance, but in
some low-memory scenarios it might be required to aggressively release these resources. The
releaseResources() can be used to force clean up of certain resources. Calling releaseResources()
may result in the entire scene graph and its OpenGL context being deleted. The
sceneGraphInvalidated() signal will be emitted when this happens.
QQuickCanvas::QQuickCanvas(QWindow *parent)
: QWindow(*(new QQuickCanvasPrivate), parent)
......@@ -764,6 +815,15 @@ QQuickCanvas::~QQuickCanvas()
This function tries to release redundant resources currently held by the QML scene.
Calling this function might result in the scene graph and the OpenGL context used
for rendering being released to release graphics memory. If this happens, the
sceneGraphInvalidated() signal will be called, allowing users to clean up their
own graphics resources. The setPersistentOpenGLContext() and setPersistentSceneGraph()
functions can be used to prevent this from happening, if handling the cleanup is
not feasible in the application, at the cost of higher memory usage.
\sa sceneGraphInvalidated(), setPersistentOpenGLContext(), setPersistentSceneGraph().
void QQuickCanvas::releaseResources()
......@@ -775,6 +835,69 @@ void QQuickCanvas::releaseResources()
Controls whether the OpenGL context can be released as a part of a call to
The OpenGL context might still be released when the user makes an explicit
call to hide().
\sa setPersistentSceneGraph()
void QQuickCanvas::setPersistentOpenGLContext(bool persistent)
d->persistentGLContext = persistent;
Returns whether the OpenGL context can be released as a part of a call to
bool QQuickCanvas::isPersistentOpenGLContext() const
Q_D(const QQuickCanvas);
return d->persistentGLContext;
Controls whether the scene graph nodes and resources can be released as a
part of a call to releaseResources().
The scene graph nodes and resources might still be released when the user
makes an explicit call to hide().
\sa setPersistentOpenGLContext()
void QQuickCanvas::setPersistentSceneGraph(bool persistent)
d->persistentSceneGraph = persistent;
Returns whether the scene graph nodes and resources can be released as a part
of a call to releaseResources().
bool QQuickCanvas::isPersistentSceneGraph() const
Q_D(const QQuickCanvas);
return d->persistentSceneGraph;
Returns the invisible root item of the scene.
......@@ -114,6 +114,12 @@ public:
void setClearColor(const QColor &color);
QColor clearColor() const;
void setPersistentOpenGLContext(bool persistent);
bool isPersistentOpenGLContext() const;
void setPersistentSceneGraph(bool persistent);
bool isPersistentSceneGraph() const;
QOpenGLContext *openglContext() const;
......@@ -184,6 +184,11 @@ public:
uint clearBeforeRendering : 1;
// Currently unused in the default implementation, as we're not stopping
// rendering when obscured as we should...
uint persistentGLContext : 1;
uint persistentSceneGraph : 1;
QOpenGLFramebufferObject *renderTarget;
uint renderTargetId;
QSize renderTargetSize;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment