aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar.sletta@digia.com>2013-08-30 08:38:24 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-06 10:27:13 +0200
commitbedd2b43782b919ad8646238d43623b539af25cd (patch)
tree711e20c578790db25d80c335a4a10afe8e3a6647 /src
parent39c8c8b682c1af858cd4bfc0543057da5c9e1e07 (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.qdoc64
-rw-r--r--src/quick/scenegraph/qsgcontext.cpp37
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;
}
/*!