kwin/blur: Upload the geometry for both passes at the same time

Reviewed-by: Philipp Knechtges <philipp-dev@knechtges.com>
This commit is contained in:
Fredrik Höglund 2013-03-24 17:00:11 +01:00
parent e1e997eda4
commit 1cc0dba243
2 changed files with 36 additions and 13 deletions

View file

@ -226,13 +226,8 @@ QRegion BlurEffect::blurRegion(const EffectWindow *w) const
return region;
}
void BlurEffect::drawRegion(const QRegion &region)
void BlurEffect::uploadRegion(QVector2D *&map, const QRegion &region)
{
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 &region)
*(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 &region)
{ 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) {

View file

@ -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 &region);
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 &region);
void uploadGeometry(GLVertexBuffer *vbo, const QRegion &horizontal, const QRegion &vertical);
private:
BlurShader *shader;