Adding support for GL_EXT_texture_format_BGRA8888 in GLES
If extension is present texture format BGRA_EXT is used for loading textures from QImages. REVIEW: 109090
This commit is contained in:
parent
aa549f45d5
commit
9206f530ce
2 changed files with 63 additions and 50 deletions
|
@ -46,6 +46,7 @@ namespace KWin
|
|||
bool GLTexturePrivate::sNPOTTextureSupported = false;
|
||||
bool GLTexturePrivate::sFramebufferObjectSupported = false;
|
||||
bool GLTexturePrivate::sSaturationSupported = false;
|
||||
bool GLTexturePrivate::sTextureFormatBGRA = false;
|
||||
|
||||
GLTexture::GLTexture()
|
||||
: d_ptr(new GLTexturePrivate())
|
||||
|
@ -94,9 +95,11 @@ GLTexture::GLTexture(int width, int height)
|
|||
glGenTextures(1, &d->m_texture);
|
||||
bind();
|
||||
#ifdef KWIN_HAVE_OPENGLES
|
||||
// format and internal format have to match in ES, GL_RGBA8 and GL_BGRA are not available
|
||||
// see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glTexImage2D.xml
|
||||
glTexImage2D(d->m_target, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
if (GLTexturePrivate::sTextureFormatBGRA) {
|
||||
glTexImage2D(d->m_target, 0, GL_BGRA_EXT, width, height, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, 0);
|
||||
} else {
|
||||
glTexImage2D(d->m_target, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
}
|
||||
#else
|
||||
glTexImage2D(d->m_target, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, 0);
|
||||
#endif
|
||||
|
@ -146,12 +149,14 @@ void GLTexturePrivate::initStatic()
|
|||
sNPOTTextureSupported = true;
|
||||
sFramebufferObjectSupported = true;
|
||||
sSaturationSupported = true;
|
||||
sTextureFormatBGRA = hasGLExtension("GL_EXT_texture_format_BGRA8888");
|
||||
#else
|
||||
sNPOTTextureSupported = hasGLExtension("GL_ARB_texture_non_power_of_two");
|
||||
sFramebufferObjectSupported = hasGLExtension("GL_EXT_framebuffer_object");
|
||||
sSaturationSupported = ((hasGLExtension("GL_ARB_texture_env_crossbar")
|
||||
&& hasGLExtension("GL_ARB_texture_env_dot3")) || hasGLVersion(1, 4))
|
||||
&& (glTextureUnitsCount >= 4) && glActiveTexture != NULL;
|
||||
sTextureFormatBGRA = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -206,9 +211,11 @@ bool GLTexture::load(const QImage& image, GLenum target)
|
|||
}
|
||||
bind();
|
||||
#ifdef KWIN_HAVE_OPENGLES
|
||||
// format and internal format have to match in ES, GL_RGBA8 and GL_BGRA are not available
|
||||
// see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glTexImage2D.xml
|
||||
glTexImage2D(d->m_target, 0, GL_RGBA, img.width(), img.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
|
||||
if (GLTexturePrivate::sTextureFormatBGRA) {
|
||||
glTexImage2D(d->m_target, 0, GL_BGRA_EXT, img.width(), img.height(), 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, img.bits());
|
||||
} else {
|
||||
glTexImage2D(d->m_target, 0, GL_RGBA, img.width(), img.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
|
||||
}
|
||||
#else
|
||||
glTexImage2D(d->m_target, 0, GL_RGBA8, img.width(), img.height(), 0,
|
||||
GL_BGRA, GL_UNSIGNED_BYTE, img.bits());
|
||||
|
@ -248,9 +255,11 @@ void GLTexture::update(const QImage &image, const QPoint &offset, const QRect &s
|
|||
|
||||
bind();
|
||||
#ifdef KWIN_HAVE_OPENGLES
|
||||
// format and internal format have to match in ES, GL_RGBA8 and GL_BGRA are not available
|
||||
// see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glTexImage2D.xml
|
||||
glTexSubImage2D(d->m_target, 0, offset.x(), offset.y(), width, height, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
|
||||
if (GLTexturePrivate::sTextureFormatBGRA) {
|
||||
glTexSubImage2D(d->m_target, 0, offset.x(), offset.y(), width, height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, img.bits());
|
||||
} else {
|
||||
glTexSubImage2D(d->m_target, 0, offset.x(), offset.y(), width, height, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
|
||||
}
|
||||
#else
|
||||
glTexSubImage2D(d->m_target, 0, offset.x(), offset.y(), width, height, GL_BGRA, GL_UNSIGNED_BYTE, img.bits());
|
||||
#endif
|
||||
|
@ -454,37 +463,36 @@ QImage GLTexturePrivate::convertToGLFormat(const QImage& img) const
|
|||
{
|
||||
// Copied from Qt's QGLWidget::convertToGLFormat()
|
||||
QImage res;
|
||||
#ifdef KWIN_HAVE_OPENGLES
|
||||
res = QImage(img.size(), QImage::Format_ARGB32);
|
||||
QImage imgARGB32 = img.convertToFormat(QImage::Format_ARGB32_Premultiplied);
|
||||
|
||||
const int width = img.width();
|
||||
const int height = img.height();
|
||||
const uint32_t *p = (const uint32_t*) imgARGB32.scanLine(0);
|
||||
uint32_t *q = (uint32_t*) res.scanLine(0);
|
||||
if (sTextureFormatBGRA) {
|
||||
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
|
||||
res = QImage(img.size(), QImage::Format_ARGB32);
|
||||
QImage imgARGB32 = img.convertToFormat(QImage::Format_ARGB32_Premultiplied);
|
||||
|
||||
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
|
||||
for (int i = 0; i < height; ++i) {
|
||||
const uint32_t *end = p + width;
|
||||
while (p < end) {
|
||||
*q = (*p << 8) | ((*p >> 24) & 0xFF);
|
||||
p++;
|
||||
q++;
|
||||
const int width = img.width();
|
||||
const int height = img.height();
|
||||
const uint32_t *p = (const uint32_t*) imgARGB32.scanLine(0);
|
||||
uint32_t *q = (uint32_t*) res.scanLine(0);
|
||||
|
||||
// swizzle
|
||||
for (int i = 0; i < height; ++i) {
|
||||
const uint32_t *end = p + width;
|
||||
while (p < end) {
|
||||
*q = ((*p << 24) & 0xff000000)
|
||||
| ((*p >> 24) & 0x000000ff)
|
||||
| ((*p << 8) & 0x00ff0000)
|
||||
| ((*p >> 8) & 0x0000ff00);
|
||||
p++;
|
||||
q++;
|
||||
}
|
||||
}
|
||||
} else if (img.format() != QImage::Format_ARGB32_Premultiplied) {
|
||||
res = img.convertToFormat(QImage::Format_ARGB32_Premultiplied);
|
||||
} else {
|
||||
return img;
|
||||
}
|
||||
} else {
|
||||
// GL_BGRA -> GL_RGBA
|
||||
for (int i = 0; i < height; ++i) {
|
||||
const uint32_t *end = p + width;
|
||||
while (p < end) {
|
||||
*q = ((*p << 16) & 0xff0000) | ((*p >> 16) & 0xff) | (*p & 0xff00ff00);
|
||||
p++;
|
||||
q++;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
|
||||
#ifdef KWIN_HAVE_OPENGLES
|
||||
res = QImage(img.size(), QImage::Format_ARGB32);
|
||||
QImage imgARGB32 = img.convertToFormat(QImage::Format_ARGB32_Premultiplied);
|
||||
|
||||
|
@ -493,24 +501,28 @@ QImage GLTexturePrivate::convertToGLFormat(const QImage& img) const
|
|||
const uint32_t *p = (const uint32_t*) imgARGB32.scanLine(0);
|
||||
uint32_t *q = (uint32_t*) res.scanLine(0);
|
||||
|
||||
// swizzle
|
||||
for (int i = 0; i < height; ++i) {
|
||||
const uint32_t *end = p + width;
|
||||
while (p < end) {
|
||||
*q = ((*p << 24) & 0xff000000)
|
||||
| ((*p >> 24) & 0x000000ff)
|
||||
| ((*p << 8) & 0x00ff0000)
|
||||
| ((*p >> 8) & 0x0000ff00);
|
||||
p++;
|
||||
q++;
|
||||
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
|
||||
for (int i = 0; i < height; ++i) {
|
||||
const uint32_t *end = p + width;
|
||||
while (p < end) {
|
||||
*q = (*p << 8) | ((*p >> 24) & 0xFF);
|
||||
p++;
|
||||
q++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// GL_BGRA -> GL_RGBA
|
||||
for (int i = 0; i < height; ++i) {
|
||||
const uint32_t *end = p + width;
|
||||
while (p < end) {
|
||||
*q = ((*p << 16) & 0xff0000) | ((*p >> 16) & 0xff) | (*p & 0xff00ff00);
|
||||
p++;
|
||||
q++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (img.format() != QImage::Format_ARGB32_Premultiplied) {
|
||||
res = img.convertToFormat(QImage::Format_ARGB32_Premultiplied);
|
||||
} else {
|
||||
return img;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@ public:
|
|||
static bool sNPOTTextureSupported;
|
||||
static bool sFramebufferObjectSupported;
|
||||
static bool sSaturationSupported;
|
||||
static bool sTextureFormatBGRA;
|
||||
private:
|
||||
Q_DISABLE_COPY(GLTexturePrivate)
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue