Add a levels parameter to the GLTexture ctor
Prior to this commit we didn't know if mipmaps were going to be used when we created the GL texture, which meant that we couldn't tell the driver whether to allocate storage for mipmaps or not. This resulted in one of two things happening depending on the driver; either it would allocate storage for mipmaps that in most cases would never be used, or it wouldn't and would later be forced to reallocate the texture when mipmaps were added. By adding this parameter we can now explicitly tell the driver how many mipmap levels will be used. The parameter is only added to the non-image constructor for now. The image constructor is changed to only allocate a single level, which matches how textures created from images are used in kwin. This may need to be revisited in the future.
This commit is contained in:
parent
ccf1bad426
commit
450be6a378
5 changed files with 22 additions and 9 deletions
|
@ -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);
|
||||
|
||||
|
|
|
@ -35,6 +35,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
#include <kmessagebox.h>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue