diff options
Diffstat (limited to 'src/gui/opengl/qopengltexturecache.cpp')
-rw-r--r-- | src/gui/opengl/qopengltexturecache.cpp | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/src/gui/opengl/qopengltexturecache.cpp b/src/gui/opengl/qopengltexturecache.cpp index 4238f63cd8..750264935b 100644 --- a/src/gui/opengl/qopengltexturecache.cpp +++ b/src/gui/opengl/qopengltexturecache.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qopengltexturecache_p.h" +#include <qopenglfunctions.h> #include <private/qopenglcontext_p.h> #include <private/qimagepixmapcleanuphooks_p.h> #include <qpa/qplatformpixmap.h> @@ -128,6 +129,20 @@ GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, const QPixmap & return id; } +// returns the highest number closest to v, which is a power of 2 +// NB! assumes 32 bit ints +static int qt_next_power_of_two(int v) +{ + v--; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + ++v; + return v; +} + GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, const QImage &image) { if (image.isNull()) @@ -144,7 +159,19 @@ GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, const QImage &i } } - GLuint id = bindTexture(context, key, image); + QImage img = image; + if (!context->functions()->hasOpenGLFeature(QOpenGLFunctions::NPOTTextures)) { + // Scale the pixmap if needed. GL textures needs to have the + // dimensions 2^n+2(border) x 2^m+2(border), unless we're using GL + // 2.0 or use the GL_TEXTURE_RECTANGLE texture target + int tx_w = qt_next_power_of_two(image.width()); + int tx_h = qt_next_power_of_two(image.height()); + if (tx_w != image.width() || tx_h != image.height()) { + img = img.scaled(tx_w, tx_h); + } + } + + GLuint id = bindTexture(context, key, img); if (id > 0) QImagePixmapCleanupHooks::enableCleanupHooks(image); |