Fix multimonitor blur

Summary:
On wayland blur on secondary monitor would not render correctly.

BUG: 393723
Depends on D12452

Test Plan:
 - use more than one output
 - log in in a wayland session
 - open a transparent window (for example: Konsole with transparent and blur enabled profile)
 - drag the window to another screen
 - blurs the content under the window corretly

Reviewers: #kwin, graesslin, davidedmundson

Reviewed By: #kwin, davidedmundson

Subscribers: apol, zzag, davidedmundson, kwin, #kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D12678
master
Alex Nemeth 6 years ago
parent 8342cdd3b6
commit 99532fb95c

@ -610,13 +610,25 @@ void BlurEffect::generateNoiseTexture()
void BlurEffect::doBlur(const QRegion& shape, const QRect& screen, const float opacity, const QMatrix4x4 &screenProjection, bool isDock, QRect windowRect)
{
QRegion expandedBlurRegion = expand(shape) & expand(screen);
// Blur would not render correctly on a secondary monitor because of wrong coordinates
// BUG: 393723
const int xTranslate = -screen.x();
const int yTranslate = effects->virtualScreenSize().height() - screen.height() - screen.y();
const QRegion expandedBlurRegion = expand(shape) & expand(screen);
// Upload geometry for the down and upsample iterations
GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer();
uploadGeometry(vbo, expandedBlurRegion, shape);
uploadGeometry(vbo, expandedBlurRegion.translated(xTranslate, yTranslate), shape);
vbo->bindArrays();
const QRect sourceRect = expandedBlurRegion.boundingRect() & screen;
const QRect destRect = sourceRect.translated(xTranslate, yTranslate);
GLRenderTarget::pushRenderTargets(m_renderTargetStack);
int blurRectCount = expandedBlurRegion.rectCount() * 6;
/*
* If the window is a dock or panel we avoid the "extended blur" effect.
* Extended blur is when windows that are not under the blurred area affect
@ -624,26 +636,12 @@ void BlurEffect::doBlur(const QRegion& shape, const QRect& screen, const float o
* We want to avoid this on panels, because it looks really weird and ugly
* when maximized windows or windows near the panel affect the dock blur.
*/
isDock ? m_renderTextures.last().bind() : m_renderTextures[0].bind();
QRect copyRect = expandedBlurRegion.boundingRect() & screen;
glCopyTexSubImage2D(
GL_TEXTURE_2D,
0,
copyRect.x(),
effects->virtualScreenSize().height() - copyRect.y() - copyRect.height(),
copyRect.x(),
effects->virtualScreenSize().height() - copyRect.y() - copyRect.height(),
copyRect.width(),
copyRect.height()
);
GLRenderTarget::pushRenderTargets(m_renderTargetStack);
int blurRectCount = expandedBlurRegion.rectCount() * 6;
if (isDock) {
copyScreenSampleTexture(vbo, blurRectCount, shape, screen.size(), screenProjection);
m_renderTargets.last()->blitFromFramebuffer(sourceRect, destRect);
copyScreenSampleTexture(vbo, blurRectCount, shape.translated(xTranslate, yTranslate), screenProjection);
} else {
m_renderTargets.first()->blitFromFramebuffer(sourceRect, destRect);
// Remove the m_renderTargets[0] from the top of the stack that we will not use
GLRenderTarget::popRenderTarget();
}
@ -750,18 +748,19 @@ void BlurEffect::upSampleTexture(GLVertexBuffer *vbo, int blurRectCount)
m_shader->unbind();
}
void BlurEffect::copyScreenSampleTexture(GLVertexBuffer *vbo, int blurRectCount, QRegion blurShape, QSize screenSize, QMatrix4x4 screenProjection)
void BlurEffect::copyScreenSampleTexture(GLVertexBuffer *vbo, int blurRectCount, QRegion blurShape, QMatrix4x4 screenProjection)
{
m_shader->bind(BlurShader::CopySampleType);
m_shader->setModelViewProjectionMatrix(screenProjection);
m_shader->setTargetTextureSize(screenSize);
m_shader->setTargetTextureSize(effects->virtualScreenSize());
/*
* This '1' sized adjustment is necessary do avoid windows affecting the blur that are
* right next to this window.
*/
m_shader->setBlurRect(blurShape.boundingRect().adjusted(1, 1, -1, -1), screenSize);
m_shader->setBlurRect(blurShape.boundingRect().adjusted(1, 1, -1, -1), effects->virtualScreenSize());
m_renderTextures.last().bind();
vbo->draw(GL_TRIANGLES, 0, blurRectCount);
GLRenderTarget::popRenderTarget();

@ -91,7 +91,7 @@ private:
void upscaleRenderToScreen(GLVertexBuffer *vbo, int vboStart, int blurRectCount, QMatrix4x4 screenProjection, QPoint windowPosition);
void downSampleTexture(GLVertexBuffer *vbo, int blurRectCount);
void upSampleTexture(GLVertexBuffer *vbo, int blurRectCount);
void copyScreenSampleTexture(GLVertexBuffer *vbo, int blurRectCount, QRegion blurShape, QSize screenSize, QMatrix4x4 screenProjection);
void copyScreenSampleTexture(GLVertexBuffer *vbo, int blurRectCount, QRegion blurShape, QMatrix4x4 screenProjection);
private:
BlurShader *m_shader;

@ -197,16 +197,14 @@ void GLSLBlurShader::setTexturePosition(QPoint texPos)
void GLSLBlurShader::setBlurRect(QRect blurRect, QSize screenSize)
{
if (!isValid() || blurRect == m_blurRectCopysample)
if (!isValid())
return;
m_blurRectCopysample = blurRect;
QVector4D rect = QVector4D(
blurRect.bottomLeft().x() / float(screenSize.width()),
1.0 - blurRect.bottomLeft().y() / float(screenSize.height()),
blurRect.topRight().x() / float(screenSize.width()),
1.0 - blurRect.topRight().y() / float(screenSize.height())
1.0 - blurRect.bottomLeft().y() / float(screenSize.height()),
blurRect.topRight().x() / float(screenSize.width()),
1.0 - blurRect.topRight().y() / float(screenSize.height())
);
m_shaderCopysample->setUniform(m_blurRectLocationCopysample, rect);
@ -474,7 +472,6 @@ void GLSLBlurShader::init()
m_matrixUpsample = QMatrix4x4();
m_matrixCopysample = QMatrix4x4();
m_blurRectCopysample = QRect();
m_offsetNoisesample = 0.0;
m_noiseTextureSizeNoisesample = QVector2D();

@ -133,7 +133,6 @@ private:
QMatrix4x4 m_matrixUpsample;
QMatrix4x4 m_matrixCopysample;
QRect m_blurRectCopysample;
float m_offsetNoisesample;
QVector2D m_noiseTextureSizeNoisesample;

Loading…
Cancel
Save