From dd6598c1ff930157848a49e6f45cca432c0afd5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Wed, 2 Oct 2013 14:54:43 +0200 Subject: [PATCH] [aurorae] Hack to get Aurorae work with compositing This is a temporary solution! A proper solution needs changes in libkdecoration and paint redirector. The hack redirects the rendering into an FBO. After each rendering we get a QImage from the FBO and store that in a buffer. As we unfortunately do not know what changed, we schedule a complete update on the deco's widget. Once we get the paint event we just render the buffer on the widget. And thus we have copied the content to a place where it integrates with the paint redirector. As already written, this is a horrible hack and I'm not proud about it. There are just too many copies involved. So how to improve? * deco should be able to just provide a QImage to the PaintRedirector without the paint to the QWidget. * only do the FBO -> QImage step if it is needed by the compositor, that is compress the events * for OpenGL compositing it would be totally awesome if we could just make the contexts sharing so that we can just reuse the texture from the FBO directly. --- clients/aurorae/src/aurorae.cpp | 25 +++++++++++++++++++++++++ clients/aurorae/src/aurorae.h | 3 +++ 2 files changed, 28 insertions(+) diff --git a/clients/aurorae/src/aurorae.cpp b/clients/aurorae/src/aurorae.cpp index 24cb7714e7..6cf8ce2c3d 100644 --- a/clients/aurorae/src/aurorae.cpp +++ b/clients/aurorae/src/aurorae.cpp @@ -21,6 +21,8 @@ along with this program. If not, see . #include #include +#include +#include #include #include #include @@ -259,6 +261,24 @@ void AuroraeClient::init() widget()->setAttribute(Qt::WA_NoSystemBackground); widget()->installEventFilter(this); m_view = new QQuickWindow(); + if (compositingActive()) { + connect(m_view, &QQuickWindow::beforeRendering, [this]() { + if (m_fbo.isNull() || m_fbo->size() != QSize(width(), height())) { + m_fbo.reset(new QOpenGLFramebufferObject(QSize(width(), height()), QOpenGLFramebufferObject::CombinedDepthStencil)); + if (!m_fbo->isValid()) { + qWarning() << "Creating FBO as render target failed"; + m_fbo.reset(); + return; + } + } + m_view->setRenderTarget(m_fbo.data()); + }); + connect(m_view, &QQuickWindow::afterRendering, [this]{ + m_buffer = m_fbo->toImage(); + }); + connect(m_view, &QQuickWindow::afterRendering, widget(), + static_cast(&QWidget::update), Qt::QueuedConnection); + } m_view->setColor(Qt::transparent); m_container = QWidget::createWindowContainer(m_view, widget(), Qt::X11BypassWindowManagerHint); m_container->setAttribute(Qt::WA_TranslucentBackground); @@ -275,6 +295,11 @@ void AuroraeClient::init() bool AuroraeClient::eventFilter(QObject *object, QEvent *event) { + if (compositingActive() && !m_fbo.isNull() && object == widget() && QEvent::Paint) { + QPainter painter(widget()); + painter.drawImage(QPoint(0, 0), m_buffer); + return false; + } // we need to filter the wheel events on the decoration // QML does not yet provide a way to accept wheel events, this will change with Qt 5 // TODO: remove in KDE5 diff --git a/clients/aurorae/src/aurorae.h b/clients/aurorae/src/aurorae.h index ca20a6dcf0..bb5ffed47c 100644 --- a/clients/aurorae/src/aurorae.h +++ b/clients/aurorae/src/aurorae.h @@ -23,6 +23,7 @@ along with this program. If not, see . #include #include +class QOpenGLFramebufferObject; class QQmlComponent; class QQmlEngine; class QQuickItem; @@ -160,6 +161,8 @@ private: QQuickWindow *m_view; QQuickItem *m_item; QWidget *m_container; + QScopedPointer m_fbo; + QImage m_buffer; }; }