diff options
Diffstat (limited to 'src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc')
-rw-r--r-- | src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc | 242 |
1 files changed, 209 insertions, 33 deletions
diff --git a/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc b/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc index 6e9d963d8d..099c7eb443 100644 --- a/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc +++ b/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the documentation of the Qt Toolkit. @@ -51,7 +51,7 @@ reduction like this can greatly improve performance on some hardware. The scene graph is closely tied to Qt Quick 2.0 and can not be used stand-alone. The scene graph is managed and rendered by the -QQuickWindow class and custom Item elements can add their graphical +QQuickWindow class and custom Item types can add their graphical primitives into the scene graph through a call to QQuickItem::updatePaintNode(). @@ -63,54 +63,212 @@ graph will even be rendered on a dedicated render thread while the GUI thread is preparing the next frame's state. +\section1 Qt Quick Scene Graph Structure -\section1 Scene Graph Nodes +The scene graph is composed of a number of predefined node types, each +serving a dedicated purpose. Although we refer to it as a scene graph, +a more precise definition is node tree. The tree is built from +QQuickItem types in the QML scene and internally the scene is then +processed by a renderer which draws the scene. The nodes themselves do +\b not contain any active drawing code nor virtual \c paint() +function. -The scene graph can only contain a predefined set of node types, each -serving a dedicated purpose. +Even though the node tree is mostly built internally by the existing +Qt Quick QML types, it is possible for users to also add complete +subtrees with their own content, including subtrees that represent 3D +models. -\list -\li QSGGeometryNode - for all rendered content in the scene -graph. In most cases, it will be enough for a custom QQuickItem object to -simply return a single QSGGeometryNode object from the -QQuickItem::updatePaintNode() call. +\section2 Nodes -\li QSGTransformNode - implements transformations in the scene -graph. Nested transforms are multiplied together. +The most important node for users is the \l QSGGeometryNode. It is +used to define custom graphics by defining its geometry and +material. The geometry is defined using \l QSGGeometry and describes +the shape or mesh of the graphical primitive. It can be a line, a +rectangle, a polygon, many disconnected rectangles, or complex 3D +mesh. The material defines how the pixels in this shape are filled. -\li QSGOpacityNode - for node opacity changes. Nested opacity nodes have -cumulative effect. +A node can have any number of children and geometry nodes will be +rendered so they appear in child-order with parents behind their +children. \note This does not say anything about the actual rendering +order in the renderer. Only the visual output is guaranteed. -\li QSGClipNode - implements clipping in the scene graph. Nested clips -are intersected. +The available nodes are: +\annotatedlist{qtquick-scenegraph-nodes} -\li QSGNode - base class for all nodes in the scene graph. Its primary purpose -is provide the ability to insert nodes into the scene graph that do not affect -the rendering, such as the shared root for a subtree of geometry nodes. +Custom nodes are added to the scene graph by subclassing +QQuickItem::updatePaintNode() and setting the +\l {QQuickItem::ItemHasContents} flag. -\endlist +\warning It is crucial that OpenGL operations and interaction with the +scene graph happens exclusively on the render thread, primarily +during the updatePaintNode() call. The rule of thumb is to only +use classes with the "QSG" prefix inside the +QQuickItem::updatePaintNode() function. + +For more details, see the \l {Custom Geometry Example}. + +\section3 Preprocessing + +Nodes have a virtual QSGNode::preprocess() function, which will be +called before the scene graph is rendered. Node subclasses can set the +flag \l QSGNode::UsePreprocess and override the QSGNode::preprocess() +function to do final preparation of their node. For example, dividing a +bezier curve into the correct level of detail for the current scale +factor or updating a section of a texture. + +\section3 Node Ownership Ownership of the nodes is either done explicitly by the creator or by -the scene graph by setting the flag \l QSGNode::OwnedByParent on -it. Assigning ownership to the scene graph is often preferable as it +the scene graph by setting the flag \l QSGNode::OwnedByParent. +Assigning ownership to the scene graph is often preferable as it simplifies cleanup when the scene graph lives outside the GUI thread. +\section2 Materials + +The material describes how the interior of a geometry in a \l +QSGGeometryNode is filled. It encapsulates an OpenGL shader program +and provides ample flexibility in what can be achieved, though most of +the Qt Quick items themselves only use very basic materials, such as +solid color and texture fills. + +For users who just want to apply custom shading to a QML Item type, +it is possible to do this directly in QML using the \l ShaderEffect +type. -\section1 Rendering +Below is a complete list of material classes: +\annotatedlist{qtquick-scenegraph-materials} + +For more details, see the \l {Simple Material Example} + + +\section2 Convenience Nodes + +The scene graph API is very low-level and focuses on performance +rather than convenience. Writing custom geometries and materials from +scratch, even the most basic ones, requires a non-trivial amount of +code. For this reason, the API includes a few convenience classes to +make the most common custom nodes readily available. + +\list +\li \l QSGSimpleRectNode - a QSGGeometryNode subclass which defines a +rectangular geometry with a solid color material. + +\li \l QSGSimpleTextureNode - a QSGGeometryNode subclass which defines +a rectangular geometry with a texture material. +\endlist + + + +\section1 Scene Graph and Rendering The rendering of the scene graph happens internally in the -QQuickWindow class and is described under the \l{Scene Graph and -Rendering} section. +QQuickWindow class, and there is no public API to access it. There are +however, a few places in the rendering pipeline where the user can +attach application code. This can be to add custom scene graph +content or render raw OpenGL content. The integration points are +defined by the render loop. + + +\section2 Threaded Render Loop + +On many configurations, the scene graph rendering will happen on a +dedicated render thread. This is done to increase parallelism of +multi-core processors and make better use of stall times such as +waiting for a blocking swap buffer call. This offers significant +performance improvements, but imposes certain restrictions on where +and when interaction with the scene graph can happen. -How to integrate QPainter based graphics is explained in \l{Custom -Items using QPainter}. +The following is a simple outline of how a frame gets +composed with the threaded render loop. -\section1 Mixing Scene Graph and OpenGL +\image sg-renderloop-threaded.jpg + +\list 1 + +\li A change occurs in the QML scene, causing \c QQuickItem::update() +to be called. This can be the result of for instance an animation or +user input. An event is posted to the render thread to initiate a new +frame. + +\li The render thread prepares to draw a new frame and makes the +OpenGL context current and initiates a blocks on the GUI thread. + +\li While the render thread is preparing the new frame, the GUI thread +calls QQuickItem::updatePolish() to do final touch-up of items before +they are rendered. + +\li GUI thread is blocked. + +\li The QQuickWindow::beforeSynchronizing() signal is emitted. +Applications can make direct connections (using Qt::DirectConnection) +to this signal to do any preparation required before calls to +QQuickItem::updatePaintNode(). -The scene graph offers two methods for integrating OpenGL -content. +\li Synchronization of the QML state into the scene graph. This is +done by calling the QQuickItem::updatePaintNode() function on all +items that have changed since the previous frame. This is the only +time the QML items and the nodes in the scene graph interact. + +\li GUI thread block is released. + +\li The scene graph is rendered: + \list 1 + + \li The QQuickWindow::beforeRendering() signal is + emitted. Applications can make direct connections + (using Qt::DirectConnection) to this signal to use custom OpenGL calls + which will then stack visually beneath the QML scene. + + \li Items that have specified QSGNode::UsePreprocess, will have their + QSGNode::preprocess() function invoked. + + \li The renderer processes the nodes and calls OpenGL functions. + + \li The QQuickWindow::afterRendering() signal is + emitted. Applications can make direct connections + (using Qt::DirectConnection) to this signal to use custom OpenGL calls + which will then stack visually over the QML scene. + + \li The rendered frame is swapped and QQuickWindow::frameSwapped() + is emitted. + + \endlist + +\li While the render thread is rendering, the GUI is free to advance +animations, process events, etc. + +\endlist + +The threaded renderer is currently used by default on Linux, Mac OS X +and EGLFS based QPA platforms, but this is subject to change. It is +possible to force use of the threaded renderer by setting \c +{QML_FORCE_THREADED_RENDERER=1} in the environment. + + +\section2 Non-threaded Render Loop + +The non-threaded render loop is currently used by default on Windows +and non-EGLFS based embedded platforms. This is mostly a precautionary +measure, as not all combinations of OpenGL drivers and windowing +systems have been tested. + +Even when using the non-threaded render loop, you should write your +code as if you are using the threaded renderer, as failing to do so +will make the code non-portable. + +The following is a simplified illustration of the frame rendering +sequence in the non-threaded renderer. + +\image sg-renderloop-singlethreaded.jpg + + +\section2 Mixing Scene Graph and OpenGL + +The scene graph offers two methods for integrating OpenGL content: +by calling OpenGL commands directly and by creating a textured node +in the scene graph. By connecting to the \l QQuickWindow::beforeRendering() and \l QQuickWindow::afterRendering() signals, applications can make OpenGL @@ -122,6 +280,10 @@ needed to perform the rendering. The downside is that Qt Quick decides when to call the signals and this is the only time the OpenGL application is allowed to draw. +The \l {OpenGL Under QML} example gives an example on how to use use +these signals. + + The other alternative is to create a FramebufferObject, render into it and use the result as a textured node in the scene graph, for instance using a QSGSimpleTextureNode. A simple way of doing the same is to use @@ -131,7 +293,8 @@ the OpenGL rendering and QPainter::endNativePainting() after. When OpenGL content is integrated with a texture and FramebufferObject, the application has more control over when the content is rendered. For instance, the application can create a second QOpenGLContext on the -GUI thread which shares memory with the scene graph's OpenGL context and drive the rendering manually. +GUI thread which shares memory with the scene graph's OpenGL context +and drive the rendering manually. \warning When mixing OpenGL content with scene graph rendering, it is important the application does not leave the OpenGL context in a state @@ -143,6 +306,19 @@ behavior. rendering might be happening outside the GUI thread. +\section2 Custom Items using QPainter + +The QQuickItem provides a subclass, QQuickPaintedItem, which allows +the users to render content using QPainter. + +\warning Using QQuickPaintedItem uses an indirect 2D surface to render +its content, either using software rasterization or using an OpenGL +framebuffer object (FBO), so the rendering is a two-step +operation. First rasterize the surface, then draw the surface. Using +scene graph API directly is always significantly faster. + + + \section1 Scene Graph Backend In addition to the public API, the scene graph has an adaptation layer @@ -155,7 +331,7 @@ It includes: \li Custom textures; specifically the implementation of QQuickWindow::createTextureFromImage and the internal representation -of the texture used by \l Image and \l BorderImage elements. +of the texture used by \l Image and \l BorderImage types. \li Custom renderer; the adaptation layer lets the plugin decide how the scene graph is traversed and rendered, making it possible to @@ -163,7 +339,7 @@ optimize the rendering algorithm for a specific hardware or to make use of extensions which improve performance. \li Custom scene graph implementation of many of the default QML -elements, including its text and font rendering. +types, including its text and font rendering. \li Custom animation driver; allows the animation system to hook into the low-level display vertical refresh to get smooth rendering. |