From 54b36325f71788c14ede265984b32cdc6483b0b3 Mon Sep 17 00:00:00 2001 From: David Edmundson Date: Wed, 1 Nov 2017 15:44:57 +0000 Subject: [PATCH] Support software QtQuickRendering in Aurorae Summary: For software QtQuick rendering we want to create a pixmap buffer and render our contents in there. m_rendercontrol->grab does this, but also covers the GL side in pretty much the same way that we were currently doing. In doing so I found a bug in Qt, that's submitted upstream, and also worked round. Test Plan: Tested with forced software mode, could see an Aurorae decorations Tested without (so normal code), could see an Aurorae decorations Tested wayland on nvidia with software rendering, didn't freeze Whether we then end up using GL, painter or xrender rendering is irrelevant (but I tested two of them anyway) Reviewers: #plasma, graesslin Reviewed By: #plasma, graesslin Subscribers: graesslin, apol, plasma-devel, kwin, #kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D8039 --- plugins/kdecorations/aurorae/src/aurorae.cpp | 70 +++++++++++--------- 1 file changed, 40 insertions(+), 30 deletions(-) diff --git a/plugins/kdecorations/aurorae/src/aurorae.cpp b/plugins/kdecorations/aurorae/src/aurorae.cpp index 00632c35a0..4c5879be2e 100644 --- a/plugins/kdecorations/aurorae/src/aurorae.cpp +++ b/plugins/kdecorations/aurorae/src/aurorae.cpp @@ -324,47 +324,55 @@ void Decoration::init() m_item->setParentItem(visualParent.value()); visualParent.value()->setProperty("drawBackground", false); } else { - // first create the context - QSurfaceFormat format; - format.setDepthBufferSize(16); - format.setStencilBufferSize(8); - m_context.reset(new QOpenGLContext); - m_context->setFormat(format); - m_context->create(); - // and the offscreen surface - m_offscreenSurface.reset(new QOffscreenSurface); - m_offscreenSurface->setFormat(m_context->format()); - m_offscreenSurface->create(); - m_renderControl = new QQuickRenderControl(this); m_view = new QQuickWindow(m_renderControl); + bool usingGL = m_view->rendererInterface()->graphicsApi() == QSGRendererInterface::OpenGL; m_view->setColor(Qt::transparent); m_view->setFlags(Qt::FramelessWindowHint); + if (usingGL) { + // first create the context + QSurfaceFormat format; + format.setDepthBufferSize(16); + format.setStencilBufferSize(8); + m_context.reset(new QOpenGLContext); + m_context->setFormat(format); + m_context->create(); + // and the offscreen surface + m_offscreenSurface.reset(new QOffscreenSurface); + m_offscreenSurface->setFormat(m_context->format()); + m_offscreenSurface->create(); + } + + //workaround for https://codereview.qt-project.org/#/c/207198/ +#if (QT_VERSION < QT_VERSION_CHECK(5, 10, 0)) + if (!usingGL) { + m_renderControl->sync(); + } +#endif // delay rendering a little bit for better performance m_updateTimer.reset(new QTimer); m_updateTimer->setSingleShot(true); m_updateTimer->setInterval(5); connect(m_updateTimer.data(), &QTimer::timeout, this, - [this] { - if (!m_context->makeCurrent(m_offscreenSurface.data())) { - return; - } - if (m_fbo.isNull() || m_fbo->size() != m_view->size()) { - m_fbo.reset(new QOpenGLFramebufferObject(m_view->size(), QOpenGLFramebufferObject::CombinedDepthStencil)); - if (!m_fbo->isValid()) { - qCWarning(AURORAE) << "Creating FBO as render target failed"; - m_fbo.reset(); + [this, usingGL] { + if (usingGL) { + if (!m_context->makeCurrent(m_offscreenSurface.data())) { return; } + if (m_fbo.isNull() || m_fbo->size() != m_view->size()) { + m_fbo.reset(new QOpenGLFramebufferObject(m_view->size(), QOpenGLFramebufferObject::CombinedDepthStencil)); + if (!m_fbo->isValid()) { + qCWarning(AURORAE) << "Creating FBO as render target failed"; + m_fbo.reset(); + return; + } + } + m_view->setRenderTarget(m_fbo.data()); + m_view->resetOpenGLState(); } - m_view->setRenderTarget(m_fbo.data()); - m_renderControl->polishItems(); - m_renderControl->sync(); - m_renderControl->render(); - m_view->resetOpenGLState(); - m_buffer = m_fbo->toImage(); + m_buffer = m_renderControl->grab(); m_contentRect = QRect(QPoint(0, 0), m_buffer.size()); if (m_padding && @@ -389,9 +397,11 @@ void Decoration::init() m_item->setParentItem(m_view->contentItem()); - m_context->makeCurrent(m_offscreenSurface.data()); - m_renderControl->initialize(m_context.data()); - m_context->doneCurrent(); + if (usingGL) { + m_context->makeCurrent(m_offscreenSurface.data()); + m_renderControl->initialize(m_context.data()); + m_context->doneCurrent(); + } } setupBorders(m_item); if (m_extendedBorders) {