diff --git a/effects/blur/blur.cpp b/effects/blur/blur.cpp index 9b4f066fea..985493077d 100644 --- a/effects/blur/blur.cpp +++ b/effects/blur/blur.cpp @@ -226,13 +226,8 @@ QRegion BlurEffect::blurRegion(const EffectWindow *w) const return region; } -void BlurEffect::drawRegion(const QRegion ®ion) +void BlurEffect::uploadRegion(QVector2D *&map, const QRegion ®ion) { - const int vertexCount = region.rectCount() * 6; - GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer(); - - QVector2D *map = (QVector2D *) vbo->map(vertexCount * sizeof(QVector2D)); - foreach (const QRect &r, region.rects()) { const QVector2D topLeft(r.x(), r.y()); const QVector2D topRight(r.x() + r.width(), r.y()); @@ -249,7 +244,15 @@ void BlurEffect::drawRegion(const QRegion ®ion) *(map++) = bottomRight; *(map++) = topRight; } +} +void BlurEffect::uploadGeometry(GLVertexBuffer *vbo, const QRegion &horizontal, const QRegion &vertical) +{ + const int vertexCount = (horizontal.rectCount() + vertical.rectCount()) * 6; + + QVector2D *map = (QVector2D *) vbo->map(vertexCount * sizeof(QVector2D)); + uploadRegion(map, horizontal); + uploadRegion(map, vertical); vbo->unmap(); const GLVertexAttrib layout[] = { @@ -257,9 +260,7 @@ void BlurEffect::drawRegion(const QRegion ®ion) { VA_TexCoord, 2, GL_FLOAT, 0 } }; - vbo->setVertexCount(vertexCount); vbo->setAttribLayout(layout, 2, sizeof(QVector2D)); - vbo->render(GL_TRIANGLES); } void BlurEffect::prePaintScreen(ScreenPrePaintData &data, int time) @@ -443,6 +444,11 @@ void BlurEffect::doBlur(const QRegion& shape, const QRect& screen, const float o const QRegion expanded = expand(shape) & screen; const QRect r = expanded.boundingRect(); + // Upload geometry for the horizontal and vertical passes + GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer(); + uploadGeometry(vbo, expanded, shape); + vbo->bindArrays(); + // Create a scratch texture and copy the area in the back buffer that we're // going to blur into it GLTexture scratch(r.width(), r.height()); @@ -475,7 +481,7 @@ void BlurEffect::doBlur(const QRegion& shape, const QRect& screen, const float o loadMatrix(textureMatrix); shader->setTextureMatrix(textureMatrix); - drawRegion(expanded); + vbo->draw(GL_TRIANGLES, 0, expanded.rectCount() * 6); GLRenderTarget::popRenderTarget(); scratch.unbind(); @@ -503,7 +509,8 @@ void BlurEffect::doBlur(const QRegion& shape, const QRect& screen, const float o loadMatrix(textureMatrix); shader->setTextureMatrix(textureMatrix); - drawRegion(shape); + vbo->draw(GL_TRIANGLES, expanded.rectCount() * 6, shape.rectCount() * 6); + vbo->unbindArrays(); #ifdef KWIN_HAVE_OPENGL_1 if (effects->compositingType() == OpenGL1Compositing) { @@ -599,6 +606,20 @@ void BlurEffect::doCachedBlur(EffectWindow *w, const QRegion& region, const floa const QRegion updateBackground = damagedRegion & region; const QRegion validUpdate = damagedRegion - expand(damagedRegion - region); + const QRegion horizontal = validUpdate.isEmpty() ? QRegion() : (updateBackground & screen); + const QRegion vertical = blurredRegion & region; + + const int horizontalOffset = 0; + const int horizontalCount = horizontal.rectCount() * 6; + + const int verticalOffset = horizontalCount; + const int verticalCount = vertical.rectCount() * 6; + + GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer(); + uploadGeometry(vbo, horizontal, vertical); + + vbo->bindArrays(); + if (!validUpdate.isEmpty()) { const QRect updateRect = (expand(updateBackground) & expanded).boundingRect(); // First we have to copy the background from the frontbuffer @@ -633,7 +654,7 @@ void BlurEffect::doCachedBlur(EffectWindow *w, const QRegion& region, const floa #endif shader->setTextureMatrix(textureMatrix); - drawRegion(updateBackground & screen); + vbo->draw(GL_TRIANGLES, horizontalOffset, horizontalCount); GLRenderTarget::popRenderTarget(); tex.unbind(); @@ -674,7 +695,8 @@ void BlurEffect::doCachedBlur(EffectWindow *w, const QRegion& region, const floa #endif shader->setTextureMatrix(textureMatrix); - drawRegion(blurredRegion & region); + vbo->draw(GL_TRIANGLES, verticalOffset, verticalCount); + vbo->unbindArrays(); #ifdef KWIN_HAVE_OPENGL_1 if (effects->compositingType() == OpenGL1Compositing) { diff --git a/effects/blur/blur.h b/effects/blur/blur.h index 396e3e6c11..d12c692016 100644 --- a/effects/blur/blur.h +++ b/effects/blur/blur.h @@ -69,9 +69,10 @@ private: QRegion blurRegion(const EffectWindow *w) const; bool shouldBlur(const EffectWindow *w, int mask, const WindowPaintData &data) const; void updateBlurRegion(EffectWindow *w) const; - void drawRegion(const QRegion ®ion); void doBlur(const QRegion &shape, const QRect &screen, const float opacity); void doCachedBlur(EffectWindow *w, const QRegion& region, const float opacity); + void uploadRegion(QVector2D *&map, const QRegion ®ion); + void uploadGeometry(GLVertexBuffer *vbo, const QRegion &horizontal, const QRegion &vertical); private: BlurShader *shader;