diff options
author | Gunnar Sletta <gunnar.sletta@digia.com> | 2013-08-30 08:38:24 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-09-06 10:27:13 +0200 |
commit | bedd2b43782b919ad8646238d43623b539af25cd (patch) | |
tree | 711e20c578790db25d80c335a4a10afe8e3a6647 /src | |
parent | 39c8c8b682c1af858cd4bfc0543057da5c9e1e07 (diff) |
Prefer multisample antialiasing when we have a msaa context
Task-number: QTBUG-32699
Change-Id: Id4382c154954cb114af2cc29b075ddab8df9f387
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc | 64 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgcontext.cpp | 37 |
2 files changed, 99 insertions, 2 deletions
diff --git a/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc b/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc index 4939868d1c..edb99b03e8 100644 --- a/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc +++ b/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc @@ -607,6 +607,70 @@ with multiple windows. stream and \c dynamic. Changing this value is mostly useful for platform vendors. + \section1 Antialiasing + + The scene graph supports two types of antialiasing. By default, primitives + such as rectangles and images will be antialiased by adding more + vertices along the edge of the primitives so that the edges fade + to transparent. We call this method \e {vertex antialiasing}. If the + user requests a multisampled OpenGL context, by setting a QSurfaceFormat + with samples greater than \c 0 using QQuickWindow::setFormat(), the + scene graph will prefer multisample based antialiasing (MSAA). + The two techniques will affect how the rendering happens internally + and have different limitations. + + It is also possible to override the antialiasing method used by + setting the environment variable \c {QSG_ANTIALIASING_METHOD} + to either \c vertex or \c {msaa}. + + Vertex antialiasing can produce seams between edges of adjacent + primitives, even when the two edges are mathmatically the same. + Multisample antialiasing does not. + + + \section2 Vertex Antialiasing + + Vertex antialiasing can be enabled and disabled on a per-item basis + using the Item::antialiasing property. It will work regardless of + what the underlying hardware supports and produces higher quality + antialiasing, both for normally rendered primitives and also for + primitives captured into framebuffer objects, for instance using + the ShaderEffectSource type. + + The downside to using vertex antialiasing is that each primitive + with antialiasing enabled will have to be blended. In terms of + batching, this means that the renderer needs to do more work to + figure out if the primitive can be batched or not and due to overlaps + with other elements in the scene, it may also result in less batching, + which could impact performance. + + On low-end hardware blending can also be quite expensive so for an + image or rounded rectangle that covers most of the screen, the amount + of blending needed for the interior of these primitives can result + in significant performance loss as the entire primitive must be blended. + + \section2 Multisample Antialiasing + + Multisample antialiasing is a hardware feature where the hardware + calculates a coverage value per pixel in the primitive. Some hardware + can multisample at a very low cost, while other hardware may + need both more memory and more GPU cycles to render a frame. + + Using multisample antialiasing, many primitives, such as rounded + rectangles and image elements can be antialiased and still be + \e opaque in the scene graph. This means the renderer has an easier + job when creating batches and can rely on early-z to avoid overdraw. + + When multisample antialiasing is used, content rendered into + framebuffer objects, need additional extensions to support multisampling + of framebuffers. Typically \c GL_EXT_framebuffer_multisample and + \c GL_EXT_framebuffer_blit. Most desktop chips have these extensions + present, but they are less common in embedded chips. When framebuffer + multisampling is not available in the hardware, content rendered into + framebuffer objects will not be antialiased, including the content of + a ShaderEffectSource. + + \section1 Performance As stated in the beginning, understanding the finer details of the diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp index 070a8422d0..4c2cb8a877 100644 --- a/src/quick/scenegraph/qsgcontext.cpp +++ b/src/quick/scenegraph/qsgcontext.cpp @@ -118,6 +118,7 @@ public: , atlasManager(0) , flashMode(qmlFlashMode()) , distanceFieldDisabled(qmlDisableDistanceField()) + , msaa(false) { renderAlpha = qmlTranslucentMode() ? 0.5 : 1; } @@ -141,6 +142,8 @@ public: bool flashMode; float renderAlpha; bool distanceFieldDisabled; + + bool msaa; }; class QSGTextureCleanupEvent : public QEvent @@ -151,6 +154,20 @@ public: QSGTexture *texture; }; +namespace QSGMultisampleAntialiasing { + class ImageNode : public QSGDefaultImageNode { + public: + void setAntialiasing(bool) { } + }; + + + class RectangleNode : public QSGDefaultRectangleNode { + public: + void setAntialiasing(bool) { } + }; +} + + /*! \class QSGContext @@ -275,6 +292,18 @@ void QSGContext::initialize(QOpenGLContext *context) { Q_D(QSGContext); + QByteArray aaType = qgetenv("QSG_ANTIALIASING_METHOD"); + if (aaType == "msaa") { + d->msaa = true; + } else if (aaType == "vertex") { + d->msaa = false; + } else { + if (context->format().samples() > 0) + d->msaa = true; + else + d->msaa = false; + } + // Sanity check the surface format, in case it was overridden by the application QSurfaceFormat requested = defaultSurfaceFormat(); QSurfaceFormat actual = context->format(); @@ -345,7 +374,9 @@ void QSGContext::renderNextFrame(QSGRenderer *renderer, GLuint fboId) */ QSGRectangleNode *QSGContext::createRectangleNode() { - return new QSGDefaultRectangleNode; + Q_D(QSGContext); + return d->msaa ? new QSGMultisampleAntialiasing::RectangleNode + : new QSGDefaultRectangleNode; } /*! @@ -353,7 +384,9 @@ QSGRectangleNode *QSGContext::createRectangleNode() */ QSGImageNode *QSGContext::createImageNode() { - return new QSGDefaultImageNode; + Q_D(QSGContext); + return d->msaa ? new QSGMultisampleAntialiasing::ImageNode + : new QSGDefaultImageNode; } /*! |