From 0d519164f29eb04208eac8bb7dd85443e2b282e1 Mon Sep 17 00:00:00 2001 From: aavit Date: Tue, 6 Nov 2012 09:26:09 +0100 Subject: Simplify and speed up OpenGL framebuffer grabbing. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If possible, let glReadPixels() itself provide the pixel format that QImage requires, so we can drop the pixel manipulation afterwards. Change-Id: I6c9226003c15d49548fa00696f31d0b2e26c0783 Reviewed-by: Samuel Rødal --- src/gui/opengl/qopenglframebufferobject.cpp | 67 ++++++----------------------- 1 file changed, 13 insertions(+), 54 deletions(-) diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp index 380ada37e0..1e0a9e025b 100644 --- a/src/gui/opengl/qopenglframebufferobject.cpp +++ b/src/gui/opengl/qopenglframebufferobject.cpp @@ -1014,66 +1014,25 @@ QOpenGLFramebufferObjectFormat QOpenGLFramebufferObject::format() const return d->format; } -namespace { -/* - Read back the contents of the currently bound framebuffer, used in - QGLWidget::grabFrameBuffer(), QGLPixelbuffer::toImage() and - QGLFramebufferObject::toImage() -*/ - -void convertFromGLImage(QImage &img, int w, int h, bool alpha_format, bool include_alpha) -{ - if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { - // OpenGL gives RGBA; Qt wants ARGB - uint *p = (uint*)img.bits(); - uint *end = p + w*h; - if (alpha_format && include_alpha) { - while (p < end) { - uint a = *p << 24; - *p = (*p >> 8) | a; - p++; - } - } else { - // This is an old legacy fix for PowerPC based Macs, which - // we shouldn't remove - while (p < end) { - *p = 0xff000000 | (*p>>8); - ++p; - } - } - } else { - // OpenGL gives ABGR (i.e. RGBA backwards); Qt wants ARGB - for (int y = 0; y < h; y++) { - uint *q = (uint*)img.scanLine(y); - for (int x=0; x < w; ++x) { - const uint pixel = *q; - if (alpha_format && include_alpha) { - *q = ((pixel << 16) & 0xff0000) | ((pixel >> 16) & 0xff) - | (pixel & 0xff00ff00); - } else { - *q = 0xff000000 | ((pixel << 16) & 0xff0000) - | ((pixel >> 16) & 0xff) | (pixel & 0x00ff00); - } - - q++; - } - } - - } - img = img.mirrored(); -} - -} - Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha) { QImage img(size, (alpha_format && include_alpha) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32); int w = size.width(); int h = size.height(); - glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); - convertFromGLImage(img, w, h, alpha_format, include_alpha); - return img; + +#ifdef QT_OPENGL_ES + GLint fmt = GL_BGRA_EXT; +#else + GLint fmt = GL_BGRA; +#endif + while (glGetError()); + glReadPixels(0, 0, w, h, fmt, GL_UNSIGNED_BYTE, img.bits()); + if (glGetError()) { + glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); + img = img.rgbSwapped(); + } + return img.mirrored(); } /*! -- cgit v1.2.3