aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar.sletta@nokia.com>2012-03-19 20:23:02 +0100
committerQt by Nokia <qt-info@nokia.com>2012-03-20 10:12:49 +0100
commite20c3516945269a43d070809c08e9797c329306d (patch)
tree09990702ffa65192702664d1555e15c655e97955 /src
parent04327298604fc9efa242669afda281ad461c0536 (diff)
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: Samuel Rødal <samuel.rodal@nokia.com>
Diffstat (limited to 'src')
-rw-r--r--src/quick/items/qquickcanvas.cpp123
-rw-r--r--src/quick/items/qquickcanvas.h6
-rw-r--r--src/quick/items/qquickcanvas_p.h5
3 files changed, 134 insertions, 0 deletions
diff --git a/src/quick/items/qquickcanvas.cpp b/src/quick/items/qquickcanvas.cpp
index a5d3250b41..7f512028fd 100644
--- a/src/quick/items/qquickcanvas.cpp
+++ b/src/quick/items/qquickcanvas.cpp
@@ -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()
@@ -776,6 +836,69 @@ void QQuickCanvas::releaseResources()
/*!
+ Controls whether the OpenGL context can be released as a part of a call to
+ releaseResources().
+
+ The OpenGL context might still be released when the user makes an explicit
+ call to hide().
+
+ \sa setPersistentSceneGraph()
+ */
+
+void QQuickCanvas::setPersistentOpenGLContext(bool persistent)
+{
+ Q_D(QQuickCanvas);
+ d->persistentGLContext = persistent;
+}
+
+
+/*!
+ Returns whether the OpenGL context can be released as a part of a call to
+ releaseResources().
+ */
+
+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)
+{
+ Q_D(QQuickCanvas);
+ 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.
A QQuickCanvas always has a single invisible root item. To add items to this canvas,
diff --git a/src/quick/items/qquickcanvas.h b/src/quick/items/qquickcanvas.h
index 4ac9509896..787bb7e3c7 100644
--- a/src/quick/items/qquickcanvas.h
+++ b/src/quick/items/qquickcanvas.h
@@ -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;
Q_SIGNALS:
diff --git a/src/quick/items/qquickcanvas_p.h b/src/quick/items/qquickcanvas_p.h
index 0ecdf1fa70..643d694400 100644
--- a/src/quick/items/qquickcanvas_p.h
+++ b/src/quick/items/qquickcanvas_p.h
@@ -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;