diff --git a/src/opengl/gltexture.cpp b/src/opengl/gltexture.cpp index 37b3fa837d..6c24d7f8f0 100644 --- a/src/opengl/gltexture.cpp +++ b/src/opengl/gltexture.cpp @@ -547,53 +547,59 @@ std::unique_ptr GLTexture::upload(const QImage &image) qCWarning(KWIN_OPENGL, "generating OpenGL texture handle failed"); return nullptr; } - glBindTexture(GL_TEXTURE_2D, texture); const auto context = OpenGlContext::currentContext(); GLenum internalFormat; + GLenum format; + GLenum type; + QImage::Format uploadFormat; if (!context->isOpenGLES()) { - QImage im; - GLenum format; - GLenum type; - const QImage::Format index = image.format(); - if (index < sizeof(formatTable) / sizeof(formatTable[0]) && formatTable[index].internalFormat && !(formatTable[index].type == GL_UNSIGNED_SHORT && !context->supports16BitTextures())) { internalFormat = formatTable[index].internalFormat; format = formatTable[index].format; type = formatTable[index].type; - im = image; + uploadFormat = index; } else { - im = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); internalFormat = GL_RGBA8; format = GL_BGRA; type = GL_UNSIGNED_INT_8_8_8_8_REV; - } - - if (context->supportsTextureStorage()) { - glTexStorage2D(GL_TEXTURE_2D, 1, internalFormat, im.width(), im.height()); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, im.width(), im.height(), - format, type, im.constBits()); - } else { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); - glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, im.width(), im.height(), 0, - format, type, im.constBits()); + uploadFormat = QImage::Format_ARGB32_Premultiplied; } } else { - internalFormat = GL_RGBA8; - if (context->supportsARGB32Textures()) { - const QImage im = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); - glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, im.width(), im.height(), - 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, im.constBits()); + internalFormat = GL_BGRA_EXT; + format = GL_BGRA_EXT; + type = GL_UNSIGNED_BYTE; + uploadFormat = QImage::Format_ARGB32_Premultiplied; } else { - const QImage im = image.convertToFormat(QImage::Format_RGBA8888_Premultiplied); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, im.width(), im.height(), - 0, GL_RGBA, GL_UNSIGNED_BYTE, im.constBits()); + internalFormat = GL_RGBA; + format = GL_RGBA; + type = GL_UNSIGNED_BYTE; + uploadFormat = QImage::Format_RGBA8888_Premultiplied; } } + + QImage im = image; + if (im.format() != uploadFormat) { + im.convertTo(uploadFormat); + } + + glBindTexture(GL_TEXTURE_2D, texture); + if (!context->isOpenGLES()) { + if (context->supportsTextureStorage()) { + glTexStorage2D(GL_TEXTURE_2D, 1, internalFormat, im.width(), im.height()); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, im.width(), im.height(), format, type, im.constBits()); + } else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, im.width(), im.height(), 0, format, type, im.constBits()); + } + } else { + glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, im.width(), im.height(), 0, format, type, im.constBits()); + } glBindTexture(GL_TEXTURE_2D, 0); + return std::unique_ptr(new GLTexture(GL_TEXTURE_2D, texture, internalFormat, image.size(), 1, true, OutputTransform::FlipY)); }