diff --git a/effects/blur/blur.h b/effects/blur/blur.h --- a/effects/blur/blur.h +++ b/effects/blur/blur.h @@ -91,7 +91,7 @@ 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; diff --git a/effects/blur/blur.cpp b/effects/blur/blur.cpp --- a/effects/blur/blur.cpp +++ b/effects/blur/blur.cpp @@ -610,40 +610,38 @@ 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 * the final blur result. * 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(); } @@ -712,7 +710,6 @@ for (int i = 1; i <= m_downSampleIterations; i++) { modelViewProjectionMatrix.setToIdentity(); modelViewProjectionMatrix.ortho(0, m_renderTextures[i].width(), m_renderTextures[i].height(), 0 , 0, 65535); - m_shader->setModelViewProjectionMatrix(modelViewProjectionMatrix); m_shader->setTargetTextureSize(m_renderTextures[i].size()); @@ -750,18 +747,19 @@ 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(); diff --git a/effects/blur/blurshader.h b/effects/blur/blurshader.h --- a/effects/blur/blurshader.h +++ b/effects/blur/blurshader.h @@ -133,7 +133,6 @@ QMatrix4x4 m_matrixUpsample; QMatrix4x4 m_matrixCopysample; - QRect m_blurRectCopysample; float m_offsetNoisesample; QVector2D m_noiseTextureSizeNoisesample; diff --git a/effects/blur/blurshader.cpp b/effects/blur/blurshader.cpp --- a/effects/blur/blurshader.cpp +++ b/effects/blur/blurshader.cpp @@ -197,16 +197,14 @@ 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 @@ m_matrixUpsample = QMatrix4x4(); m_matrixCopysample = QMatrix4x4(); - m_blurRectCopysample = QRect(); m_offsetNoisesample = 0.0; m_noiseTextureSizeNoisesample = QVector2D();