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.
This commit is contained in:
Martin Gräßlin 2016-03-31 15:00:48 +02:00
parent 1a166f36e2
commit 54be622958

View file

@ -49,6 +49,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "screens.h"
#include "decorations/decoratedclient.h"
#include <KWayland/Server/subcompositor_interface.h>
#include <KWayland/Server/surface_interface.h>
#include <array>
#include <cmath>
#include <unistd.h>
@ -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<OpenGLWindowPixmap*>(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<SceneOpenGL2 *>(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<OpenGLWindowPixmap>()->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<OpenGLWindowPixmap*>(pixmap));
}
if (!data.shader)
ShaderManager::instance()->popShader();