diff options
author | Laszlo Agocs <[email protected]> | 2014-06-04 15:05:00 +0200 |
---|---|---|
committer | The Qt Project <[email protected]> | 2014-06-06 12:25:43 +0200 |
commit | 2e4a40a6ccf466802ea6b3a1cbbd85869228e3fc (patch) | |
tree | a5fc7fc8564df7759155bfb07bf606c66e467e60 | |
parent | 0d3dc8c9e4ee07895c952d48faa55cf4f4b00b7b (diff) |
Add support for multisampling in QQuickWidget
Use a multisampled fbo when the requested format has samples > 0.
Resolving happens after each rendering of the scene.
The blit to the temporary non-multisampled fbo could be avoided,
in theory, by sending the fbo instead of the texture id down the
stack and performing a blit directly to fbo #0. This however
involves a number of potential issues, for example due to the
non-sharability of FBOs between contexts. Hence it is left as a
future exercise.
Task-number: QTBUG-39187
Change-Id: Iae98b969bcbc3bb57e6d73288496f5428913c826
Reviewed-by: Paul Olav Tvete <[email protected]>
Reviewed-by: Gunnar Sletta <[email protected]>
-rw-r--r-- | examples/quick/quickwidgets/quickwidget/main.cpp | 6 | ||||
-rw-r--r-- | src/quickwidgets/qquickwidget.cpp | 32 | ||||
-rw-r--r-- | src/quickwidgets/qquickwidget_p.h | 1 |
3 files changed, 32 insertions, 7 deletions
diff --git a/examples/quick/quickwidgets/quickwidget/main.cpp b/examples/quick/quickwidgets/quickwidget/main.cpp index 61c54735cf..3850dde157 100644 --- a/examples/quick/quickwidgets/quickwidget/main.cpp +++ b/examples/quick/quickwidgets/quickwidget/main.cpp @@ -58,12 +58,14 @@ private: MainWindow::MainWindow() : m_quickWidget(new QQuickWidget) { + QSurfaceFormat format; if (QCoreApplication::arguments().contains(QStringLiteral("--coreprofile"))) { - QSurfaceFormat format; format.setVersion(4, 4); format.setProfile(QSurfaceFormat::CoreProfile); - m_quickWidget->setFormat(format); } + if (QCoreApplication::arguments().contains(QStringLiteral("--multisample"))) + format.setSamples(4); + m_quickWidget->setFormat(format); QMdiArea *centralWidget = new QMdiArea; diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp index 30c35c55dd..439b039266 100644 --- a/src/quickwidgets/qquickwidget.cpp +++ b/src/quickwidgets/qquickwidget.cpp @@ -143,6 +143,7 @@ QQuickWidgetPrivate::QQuickWidgetPrivate() , offscreenSurface(0) , renderControl(0) , fbo(0) + , resolvedFbo(0) , context(0) , resizeMode(QQuickWidget::SizeViewToRootObject) , initialSize(0,0) @@ -163,6 +164,7 @@ QQuickWidgetPrivate::~QQuickWidgetPrivate() Q_ASSERT(!context || (QOpenGLContext::currentContext() == context && context->surface() == offscreenSurface)); delete offscreenWindow; delete renderControl; + delete resolvedFbo; delete fbo; destroyContext(); @@ -226,6 +228,12 @@ void QQuickWidgetPrivate::renderSceneGraph() renderControl->sync(); renderControl->render(); glFlush(); + + if (resolvedFbo) { + QRect rect(QPoint(0, 0), fbo->size()); + QOpenGLFramebufferObject::blitFramebuffer(resolvedFbo, rect, fbo, rect); + } + context->doneCurrent(); q->update(); } @@ -669,11 +677,23 @@ void QQuickWidget::createFramebufferObject() context->makeCurrent(d->offscreenSurface); + int samples = d->offscreenWindow->requestedFormat().samples(); + if (!QOpenGLExtensions(context).hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) + samples = 0; + + QOpenGLFramebufferObjectFormat format; + format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); + format.setSamples(samples); + + QSize fboSize = size() * window()->devicePixelRatio(); + delete d->fbo; - d->fbo = new QOpenGLFramebufferObject(size() * window()->devicePixelRatio()); - d->fbo->setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); + d->fbo = new QOpenGLFramebufferObject(fboSize, format); d->offscreenWindow->setRenderTarget(d->fbo); + if (samples > 0) + d->resolvedFbo = new QOpenGLFramebufferObject(fboSize); + // Sanity check: The window must not have an underlying platform window. // Having one would mean create() was called and platforms that only support // a single native window were in trouble. @@ -683,9 +703,10 @@ void QQuickWidget::createFramebufferObject() void QQuickWidget::destroyFramebufferObject() { Q_D(QQuickWidget); - if (d->fbo) - delete d->fbo; + delete d->fbo; d->fbo = 0; + delete d->resolvedFbo; + d->resolvedFbo = 0; } QQuickWidget::ResizeMode QQuickWidget::resizeMode() const @@ -770,7 +791,8 @@ GLuint QQuickWidgetPrivate::textureId() const << "Consider setting Qt::AA_DontCreateNativeWidgetSiblings"; return 0; } - return fbo ? fbo->texture() : 0; + return resolvedFbo ? resolvedFbo->texture() + : (fbo ? fbo->texture() : 0); } /*! diff --git a/src/quickwidgets/qquickwidget_p.h b/src/quickwidgets/qquickwidget_p.h index d7652432b7..356c34e7f5 100644 --- a/src/quickwidgets/qquickwidget_p.h +++ b/src/quickwidgets/qquickwidget_p.h @@ -107,6 +107,7 @@ public: QOffscreenSurface *offscreenSurface; QQuickRenderControl *renderControl; QOpenGLFramebufferObject *fbo; + QOpenGLFramebufferObject *resolvedFbo; QOpenGLContext *context; QQuickWidget::ResizeMode resizeMode; |