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