From 74b65fcd00c2778af7888bf7d408c6f30bacc65f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=B6glund?= Date: Wed, 10 Dec 2014 20:31:53 +0100 Subject: [PATCH] Add support for GL_ARB_texture_storage Use glTexStorage2D() to allocate storage for the texture. The structure of the resulting texture becomes immutable and the texture is always mipmap complete. This allows the driver to skip the mipmap consistency checks when validating the texture at draw time. --- libkwineffects/kwingltexture.cpp | 29 +++++++++++++++++++++++------ libkwineffects/kwingltexture_p.h | 2 ++ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/libkwineffects/kwingltexture.cpp b/libkwineffects/kwingltexture.cpp index beed208232..ba30926a8b 100644 --- a/libkwineffects/kwingltexture.cpp +++ b/libkwineffects/kwingltexture.cpp @@ -45,6 +45,7 @@ namespace KWin bool GLTexturePrivate::s_supportsFramebufferObjects = false; bool GLTexturePrivate::s_supportsARGB32 = false; bool GLTexturePrivate::s_supportsUnpack = false; +bool GLTexturePrivate::s_supportsTextureStorage = false; uint GLTexturePrivate::s_textureObjectCounter = 0; uint GLTexturePrivate::s_fbo = 0; @@ -94,9 +95,17 @@ 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()); + + if (d->s_supportsTextureStorage) { + glTexStorage2D(d->m_target, 1, GL_RGBA8, im.width(), im.height()); + glTexSubImage2D(d->m_target, 0, 0, 0, im.width(), im.height(), + GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, im.bits()); + d->m_immutable = true; + } else { + 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 { if (d->s_supportsARGB32) { const QImage im = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); @@ -143,9 +152,14 @@ GLTexture::GLTexture(int width, int height, int levels) 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); + if (d->s_supportsTextureStorage) { + glTexStorage2D(d->m_target, levels, GL_RGBA8, width, height); + d->m_immutable = true; + } else { + 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 { // The format parameter in glTexSubImage() must match the internal format // of the texture, so it's important that we allocate the texture with @@ -182,6 +196,7 @@ GLTexturePrivate::GLTexturePrivate() m_yInverted = false; m_canUseMipmaps = false; m_mipLevels = 1; + m_immutable = false; m_markedDirty = false; m_unnormalizeActive = 0; m_normalizeActive = 0; @@ -211,10 +226,12 @@ void GLTexturePrivate::initStatic() if (!GLPlatform::instance()->isGLES()) { s_supportsFramebufferObjects = hasGLVersion(3, 0) || hasGLExtension("GL_ARB_framebuffer_object") || hasGLExtension(QByteArrayLiteral("GL_EXT_framebuffer_object")); + s_supportsTextureStorage = hasGLVersion(4, 2) || hasGLExtension(QByteArrayLiteral("GL_ARB_texture_storage")); s_supportsARGB32 = true; s_supportsUnpack = true; } else { s_supportsFramebufferObjects = true; + s_supportsTextureStorage = hasGLVersion(3, 0) || hasGLExtension(QByteArrayLiteral("GL_EXT_texture_storage")); // QImage::Format_ARGB32_Premultiplied is a packed-pixel format, so it's only // equivalent to GL_BGRA/GL_UNSIGNED_BYTE on little-endian systems. diff --git a/libkwineffects/kwingltexture_p.h b/libkwineffects/kwingltexture_p.h index d44b20d698..a6eabee3b4 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; + bool m_immutable; int m_mipLevels; int m_unnormalizeActive; // 0 - no, otherwise refcount @@ -70,6 +71,7 @@ public: static bool s_supportsFramebufferObjects; static bool s_supportsARGB32; static bool s_supportsUnpack; + static bool s_supportsTextureStorage; static GLuint s_fbo; static uint s_textureObjectCounter; private: