summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@digia.com>2014-08-07 12:19:32 +0200
committerLaszlo Agocs <laszlo.agocs@digia.com>2014-08-11 13:19:53 +0200
commit00f3f5c0a65e053c4075b92487fc77cfc33f2d5d (patch)
treeae68d9623cafda6d764ba32913518187cbb5deb6 /src
parent9ba3145f797f09e69a07fb265cda257c56cf72ba (diff)
Fix msaa in QOpenGLWidget
Take the correct number of samples from the widget's context, not the tlw's context. The original implementation did the blit only after paintGL(). This is not sufficient for applications that override paintEvent() and do QPainter calls in there (e.g. the 2dpainting example). Therefore the approach is changed to perform the resolving of the samples in a function that is invoked by QWidgetPrivate every time a paint event is sent. Change-Id: Iae0b2c30f6070ec75201339a848854e4582a9c0c Reviewed-by: Gunnar Sletta <gunnar.sletta@jollamobile.com>
Diffstat (limited to 'src')
-rw-r--r--src/widgets/kernel/qopenglwidget.cpp33
-rw-r--r--src/widgets/kernel/qwidget.cpp5
-rw-r--r--src/widgets/kernel/qwidget_p.h2
3 files changed, 34 insertions, 6 deletions
diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp
index 1d86d2e8d9..68e3082c14 100644
--- a/src/widgets/kernel/qopenglwidget.cpp
+++ b/src/widgets/kernel/qopenglwidget.cpp
@@ -228,6 +228,18 @@ QT_BEGIN_NAMESPACE
regarding stacking orders for example. QOpenGLWidget avoids this by not
creating a separate native window.
+ \section1 Multisampling
+
+ To enable multisampling, set the number of requested samples on the
+ QSurfaceFormat that is passed to setFormat(). On systems that do not support
+ it the request may get ignored.
+
+ Multisampling support requires support for multisampled renderbuffers and
+ framebuffer blits. On OpenGL ES 2.0 implementations it is likely that these
+ will not be present. This means that multisampling will not be available. With
+ modern OpenGL versions and OpenGL ES 3.0 and up this is usually not a problem
+ anymore.
+
\section1 Threading
Performing offscreen rendering on worker threads, for example to generate
@@ -435,6 +447,7 @@ public:
void beginCompose() Q_DECL_OVERRIDE;
void endCompose() Q_DECL_OVERRIDE;
void resizeViewportFramebuffer() Q_DECL_OVERRIDE;
+ void resolveSamples() Q_DECL_OVERRIDE;
QOpenGLContext *context;
QOpenGLFramebufferObject *fbo;
@@ -491,9 +504,11 @@ void QOpenGLWidgetPrivate::recreateFbo()
context->makeCurrent(surface);
delete fbo;
+ fbo = 0;
delete resolvedFbo;
+ resolvedFbo = 0;
- int samples = get(q->window())->shareContext()->format().samples();
+ int samples = context->format().samples();
QOpenGLExtensions *extfuncs = static_cast<QOpenGLExtensions *>(context->functions());
if (!extfuncs->hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample))
samples = 0;
@@ -570,6 +585,16 @@ void QOpenGLWidgetPrivate::initialize()
q->initializeGL();
}
+void QOpenGLWidgetPrivate::resolveSamples()
+{
+ Q_Q(QOpenGLWidget);
+ if (resolvedFbo) {
+ q->makeCurrent();
+ QRect rect(QPoint(0, 0), fbo->size());
+ QOpenGLFramebufferObject::blitFramebuffer(resolvedFbo, rect, fbo, rect);
+ }
+}
+
void QOpenGLWidgetPrivate::invokeUserPaint()
{
Q_Q(QOpenGLWidget);
@@ -577,11 +602,6 @@ void QOpenGLWidgetPrivate::invokeUserPaint()
f->glViewport(0, 0, q->width() * q->devicePixelRatio(), q->height() * q->devicePixelRatio());
q->paintGL();
-
- if (resolvedFbo) {
- QRect rect(QPoint(0, 0), fbo->size());
- QOpenGLFramebufferObject::blitFramebuffer(resolvedFbo, rect, fbo, rect);
- }
}
void QOpenGLWidgetPrivate::render()
@@ -605,6 +625,7 @@ QImage QOpenGLWidgetPrivate::grabFramebuffer()
return QImage();
render();
+ resolveSamples();
q->makeCurrent();
QImage res = qt_gl_read_framebuffer(q->size() * q->devicePixelRatio(), false, false);
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 95964bfb9d..57169edb9d 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -5595,6 +5595,11 @@ void QWidgetPrivate::sendPaintEvent(const QRegion &toBePainted)
Q_Q(QWidget);
QPaintEvent e(toBePainted);
QCoreApplication::sendSpontaneousEvent(q, &e);
+
+#ifndef QT_NO_OPENGL
+ if (renderToTexture)
+ resolveSamples();
+#endif // QT_NO_OPENGL
}
void QWidgetPrivate::render(QPaintDevice *target, const QPoint &targetOffset,
diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h
index 011d456a39..1a34ee504c 100644
--- a/src/widgets/kernel/qwidget_p.h
+++ b/src/widgets/kernel/qwidget_p.h
@@ -653,6 +653,8 @@ public:
// filtered away from the widget. This is fine for QGLWidget but bad for QOpenGLWidget
// since the fbo must be resized. We need an alternative way to notify.
virtual void resizeViewportFramebuffer() { }
+ // Called after each paint event.
+ virtual void resolveSamples() { }
#endif
// Variables.