From 54be622958b655715bb1c7a75126d0ca18ce9f80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Thu, 31 Mar 2016 15:00:48 +0200 Subject: [PATCH] Render sub-surfaces in OpenGL compositor This is more a hack than an actual implementation. It just renders all sub-surfaces after the main window got rendered. But it does not: * use window quads (e.g. splitting not supported) * is not combined with rendering of the main surface * does not support previous pixmap Still it renders, which is the main goal at the moment. --- scene_opengl.cpp | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/scene_opengl.cpp b/scene_opengl.cpp index 727526706a..0ef83c3746 100644 --- a/scene_opengl.cpp +++ b/scene_opengl.cpp @@ -49,6 +49,9 @@ along with this program. If not, see . #include "screens.h" #include "decorations/decoratedclient.h" +#include +#include + #include #include #include @@ -1505,6 +1508,29 @@ QMatrix4x4 SceneOpenGL2Window::modelViewProjectionMatrix(int mask, const WindowP return scene->projectionMatrix() * mvMatrix; } +static void renderSubSurface(GLShader *shader, const QMatrix4x4 &mvp, const QMatrix4x4 &windowMatrix, OpenGLWindowPixmap *pixmap) +{ + QMatrix4x4 newWindowMatrix = windowMatrix; + newWindowMatrix.translate(pixmap->subSurface()->position().x(), pixmap->subSurface()->position().y()); + + if (!pixmap->texture()->isNull()) { + // render this texture + shader->setUniform(GLShader::ModelViewProjectionMatrix, mvp * newWindowMatrix); + auto texture = pixmap->texture(); + texture->bind(); + texture->render(QRegion(), QRect(0, 0, texture->width(), texture->height())); + texture->unbind(); + } + + const auto &children = pixmap->children(); + for (auto pixmap : children) { + if (pixmap->subSurface().isNull() || pixmap->subSurface()->surface().isNull() || !pixmap->subSurface()->surface()->isMapped()) { + continue; + } + renderSubSurface(shader, mvp, newWindowMatrix, static_cast(pixmap)); + } +} + void SceneOpenGL2Window::performPaint(int mask, QRegion region, WindowPaintData data) { if (!beginRenderWindow(mask, region, data)) @@ -1512,8 +1538,9 @@ void SceneOpenGL2Window::performPaint(int mask, QRegion region, WindowPaintData SceneOpenGL2 *scene = static_cast(m_scene); - const QMatrix4x4 windowMatrix = transformation(mask, data); - const QMatrix4x4 mvpMatrix = modelViewProjectionMatrix(mask, data) * windowMatrix; + QMatrix4x4 windowMatrix = transformation(mask, data); + const QMatrix4x4 modelViewProjection = modelViewProjectionMatrix(mask, data); + const QMatrix4x4 mvpMatrix = modelViewProjection * windowMatrix; GLShader *shader = data.shader; if (!shader) { @@ -1641,6 +1668,16 @@ void SceneOpenGL2Window::performPaint(int mask, QRegion region, WindowPaintData setBlendEnabled(false); + // render sub-surfaces + const auto &children = windowPixmap()->children(); + windowMatrix.translate(toplevel->clientPos().x(), toplevel->clientPos().y()); + for (auto pixmap : children) { + if (pixmap->subSurface().isNull() || pixmap->subSurface()->surface().isNull() || !pixmap->subSurface()->surface()->isMapped()) { + continue; + } + renderSubSurface(shader, modelViewProjection, windowMatrix, static_cast(pixmap)); + } + if (!data.shader) ShaderManager::instance()->popShader();