diff --git a/effects/logout/logout.cpp b/effects/logout/logout.cpp index 59c078becc..34fa81d024 100644 --- a/effects/logout/logout.cpp +++ b/effects/logout/logout.cpp @@ -109,7 +109,10 @@ void LogoutEffect::prePaintScreen(ScreenPrePaintData& data, int time) // TODO: It seems that it is not possible to create a GLRenderTarget that has // a different size than the display right now. Most likely a KWin core bug. // Create texture and render target - blurTexture = new GLTexture(effects->virtualScreenSize()); + const QSize size = effects->virtualScreenSize(); + + // The fragment shader uses a LOD bias of 1.75, so we need 3 mipmap levels. + blurTexture = new GLTexture(size, 3); blurTexture->setFilter(GL_LINEAR_MIPMAP_LINEAR); blurTexture->setWrapMode(GL_CLAMP_TO_EDGE); diff --git a/effects/lookingglass/lookingglass.cpp b/effects/lookingglass/lookingglass.cpp index 784b303a66..e6b5c83316 100644 --- a/effects/lookingglass/lookingglass.cpp +++ b/effects/lookingglass/lookingglass.cpp @@ -35,6 +35,8 @@ along with this program. If not, see . #include +#include + namespace KWin { @@ -99,7 +101,8 @@ bool LookingGlassEffect::loadData() int texh = screenSize.height(); // Create texture and render target - m_texture = new GLTexture(texw, texh); + const int levels = std::log2(qMin(texw, texh)) + 1; + m_texture = new GLTexture(texw, texh, levels); m_texture->setFilter(GL_LINEAR_MIPMAP_LINEAR); m_texture->setWrapMode(GL_CLAMP_TO_EDGE); diff --git a/libkwineffects/kwingltexture.cpp b/libkwineffects/kwingltexture.cpp index 8eb8a82984..beed208232 100644 --- a/libkwineffects/kwingltexture.cpp +++ b/libkwineffects/kwingltexture.cpp @@ -77,15 +77,15 @@ GLTexture::GLTexture(const QImage& image, GLenum target) if (d->m_target != GL_TEXTURE_RECTANGLE_ARB) { d->m_scale.setWidth(1.0 / image.width()); d->m_scale.setHeight(1.0 / image.height()); - d->m_canUseMipmaps = true; } else { d->m_scale.setWidth(1.0); d->m_scale.setHeight(1.0); - d->m_canUseMipmaps = false; } d->m_size = image.size(); d->m_yInverted = true; + d->m_canUseMipmaps = false; + d->m_mipLevels = 1; d->updateMatrix(); @@ -94,6 +94,7 @@ GLTexture::GLTexture(const QImage& image, GLenum target) if (!GLPlatform::instance()->isGLES()) { const QImage im = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); + glTexParameteri(d->m_target, GL_TEXTURE_MAX_LEVEL, d->m_mipLevels - 1); glTexImage2D(d->m_target, 0, GL_RGBA8, im.width(), im.height(), 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, im.bits()); } else { @@ -122,7 +123,7 @@ GLTexture::GLTexture(const QString& fileName) { } -GLTexture::GLTexture(int width, int height) +GLTexture::GLTexture(int width, int height, int levels) : d_ptr(new GLTexturePrivate()) { Q_D(GLTexture); @@ -131,7 +132,10 @@ GLTexture::GLTexture(int width, int height) d->m_scale.setWidth(1.0 / width); d->m_scale.setHeight(1.0 / height); d->m_size = QSize(width, height); + d->m_canUseMipmaps = levels > 1; + d->m_mipLevels = levels; d->m_canUseMipmaps = true; + d->m_filter = levels > 1 ? GL_NEAREST_MIPMAP_LINEAR : GL_NEAREST; d->updateMatrix(); @@ -139,6 +143,7 @@ GLTexture::GLTexture(int width, int height) bind(); if (!GLPlatform::instance()->isGLES()) { + glTexParameteri(d->m_target, GL_TEXTURE_MAX_LEVEL, levels - 1); glTexImage2D(d->m_target, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, nullptr); } else { @@ -153,8 +158,8 @@ GLTexture::GLTexture(int width, int height) unbind(); } -GLTexture::GLTexture(const QSize &size) - : GLTexture(size.width(), size.height()) +GLTexture::GLTexture(const QSize &size, int levels) + : GLTexture(size.width(), size.height(), levels) { } @@ -176,6 +181,7 @@ GLTexturePrivate::GLTexturePrivate() m_wrapMode = GL_REPEAT; m_yInverted = false; m_canUseMipmaps = false; + m_mipLevels = 1; m_markedDirty = false; m_unnormalizeActive = 0; m_normalizeActive = 0; diff --git a/libkwineffects/kwingltexture.h b/libkwineffects/kwingltexture.h index d559ab0bbe..3b9b012977 100644 --- a/libkwineffects/kwingltexture.h +++ b/libkwineffects/kwingltexture.h @@ -55,8 +55,8 @@ public: explicit GLTexture(const QImage& image, GLenum target = GL_TEXTURE_2D); explicit GLTexture(const QPixmap& pixmap, GLenum target = GL_TEXTURE_2D); explicit GLTexture(const QString& fileName); - GLTexture(int width, int height); - explicit GLTexture(const QSize &size); + GLTexture(int width, int height, int levels = 1); + explicit GLTexture(const QSize &size, int levels = 1); virtual ~GLTexture(); GLTexture & operator = (const GLTexture& tex); diff --git a/libkwineffects/kwingltexture_p.h b/libkwineffects/kwingltexture_p.h index 3cbb0bb12e..d44b20d698 100644 --- a/libkwineffects/kwingltexture_p.h +++ b/libkwineffects/kwingltexture_p.h @@ -58,6 +58,7 @@ public: bool m_markedDirty; bool m_filterChanged; bool m_wrapModeChanged; + int m_mipLevels; int m_unnormalizeActive; // 0 - no, otherwise refcount int m_normalizeActive; // 0 - no, otherwise refcount