diff options
-rw-r--r-- | src/gui/image/qimage_p.h | 2 | ||||
-rw-r--r-- | src/gui/image/qpixmap_x11.cpp | 33 | ||||
-rw-r--r-- | src/opengl/qgl.cpp | 28 | ||||
-rw-r--r-- | src/opengl/qgl_x11egl.cpp | 12 | ||||
-rw-r--r-- | src/opengl/qpixmapdata_gl.cpp | 21 | ||||
-rw-r--r-- | src/opengl/qwindowsurface_gl.cpp | 6 |
6 files changed, 83 insertions, 19 deletions
diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h index 4f44109..bea1e8d 100644 --- a/src/gui/image/qimage_p.h +++ b/src/gui/image/qimage_p.h @@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE -struct QImageData { // internal image data +struct Q_GUI_EXPORT QImageData { // internal image data QImageData(); ~QImageData(); static QImageData *create(const QSize &size, QImage::Format format, int numColors = 0); diff --git a/src/gui/image/qpixmap_x11.cpp b/src/gui/image/qpixmap_x11.cpp index f77d200..6cde898 100644 --- a/src/gui/image/qpixmap_x11.cpp +++ b/src/gui/image/qpixmap_x11.cpp @@ -67,6 +67,7 @@ #include <private/qt_x11_p.h> #include "qx11info_x11.h" #include <private/qdrawhelper_p.h> +#include <private/qimage_p.h> #include <stdlib.h> @@ -369,6 +370,30 @@ void QX11PixmapData::resize(int width, int height) #endif // QT_NO_XRENDER } +struct QX11AlphaDetector +{ + bool hasAlpha() const { + if (checked) + return has; + // Will implicitly also check format and return quickly for opaque types... + checked = true; + has = const_cast<QImage *>(image)->data_ptr()->checkForAlphaPixels(); + return has; + } + + bool hasXRenderAndAlpha() const { + if (!X11->use_xrender) + return false; + return hasAlpha(); + } + + QX11AlphaDetector(const QImage *i) : image(i), checked(false), has(false) { } + + const QImage *image; + mutable bool checked; + mutable bool has; +}; + void QX11PixmapData::fromImage(const QImage &img, Qt::ImageConversionFlags flags) { @@ -402,7 +427,9 @@ void QX11PixmapData::fromImage(const QImage &img, return; } - int dd = X11->use_xrender && img.hasAlphaChannel() ? 32 : xinfo.depth(); + QX11AlphaDetector alphaCheck(&img); + int dd = alphaCheck.hasXRenderAndAlpha() ? 32 : xinfo.depth(); + if (qt_x11_preferred_pixmap_depth) dd = qt_x11_preferred_pixmap_depth; @@ -454,7 +481,7 @@ void QX11PixmapData::fromImage(const QImage &img, uchar *newbits= 0; #ifndef QT_NO_XRENDER - if (X11->use_xrender && image.hasAlphaChannel()) { + if (alphaCheck.hasXRenderAndAlpha()) { const QImage &cimage = image; d = 32; @@ -1091,7 +1118,7 @@ void QX11PixmapData::fromImage(const QImage &img, } #endif - if (image.hasAlphaChannel()) { + if (alphaCheck.hasAlpha()) { QBitmap m = QBitmap::fromImage(image.createAlphaMask(flags)); setMask(m); } diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 0402268..2327d7a 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -59,6 +59,8 @@ # include <private/qt_mac_p.h> #endif +#include <qdatetime.h> + #include <stdlib.h> // malloc #include "qpixmap.h" @@ -2077,6 +2079,8 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G #ifdef QGL_BIND_TEXTURE_DEBUG printf("QGLContextPrivate::bindTexture(), imageSize=(%d,%d), internalFormat =0x%x, options=%x\n", image.width(), image.height(), internalFormat, int(options)); + QTime time; + time.start(); #endif // Scale the pixmap if needed. GL textures needs to have the @@ -2092,7 +2096,8 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G { img = img.scaled(tx_w, tx_h); #ifdef QGL_BIND_TEXTURE_DEBUG - printf(" - upscaled to %dx%d\n", tx_w, tx_h); + printf(" - upscaled to %dx%d (%d ms)\n", tx_w, tx_h, time.elapsed()); + #endif } @@ -2112,7 +2117,7 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G && options & QGLContext::MipmapBindOption) { #ifdef QGL_BIND_TEXTURE_DEBUG - printf(" - generating mipmaps\n"); + printf(" - generating mipmaps (%d ms)\n", time.elapsed()); #endif #if !defined(QT_OPENGL_ES_2) glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST); @@ -2148,7 +2153,7 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G if (premul) { img = img.convertToFormat(target_format = QImage::Format_ARGB32_Premultiplied); #ifdef QGL_BIND_TEXTURE_DEBUG - printf(" - converting ARGB32 -> ARGB32_Premultiplied \n"); + printf(" - converting ARGB32 -> ARGB32_Premultiplied (%d ms) \n", time.elapsed()); #endif } break; @@ -2156,7 +2161,7 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G if (!premul) { img = img.convertToFormat(target_format = QImage::Format_ARGB32); #ifdef QGL_BIND_TEXTURE_DEBUG - printf(" - converting ARGB32_Premultiplied -> ARGB32\n"); + printf(" - converting ARGB32_Premultiplied -> ARGB32 (%d ms)\n", time.elapsed()); #endif } break; @@ -2173,19 +2178,19 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G ? QImage::Format_ARGB32_Premultiplied : QImage::Format_ARGB32); #ifdef QGL_BIND_TEXTURE_DEBUG - printf(" - converting to 32-bit alpha format\n"); + printf(" - converting to 32-bit alpha format (%d ms)\n", time.elapsed()); #endif } else { img = img.convertToFormat(QImage::Format_RGB32); #ifdef QGL_BIND_TEXTURE_DEBUG - printf(" - converting to 32-bit\n"); + printf(" - converting to 32-bit (%d ms)\n", time.elapsed()); #endif } } if (options & QGLContext::InvertedYBindOption) { #ifdef QGL_BIND_TEXTURE_DEBUG - printf(" - flipping bits over y\n"); + printf(" - flipping bits over y (%d ms)\n", time.elapsed()); #endif int ipl = img.bytesPerLine() / 4; int h = img.height(); @@ -2199,7 +2204,7 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G if (externalFormat == GL_RGBA) { #ifdef QGL_BIND_TEXTURE_DEBUG - printf(" - doing byte swapping\n"); + printf(" - doing byte swapping (%d ms)\n", time.elapsed()); #endif // The only case where we end up with a depth different from // 32 in the switch above is for the RGB16 case, where we set @@ -2242,6 +2247,13 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G } #endif +#ifdef QGL_BIND_TEXTURE_DEBUG + static int totalUploadTime = 0; + totalUploadTime += time.elapsed(); + printf(" - upload done in (%d ms) time=%d\n", time.elapsed(), totalUploadTime); +#endif + + // this assumes the size of a texture is always smaller than the max cache size int cost = img.width()*img.height()*4/1024; QGLTexture *texture = new QGLTexture(q, tx_id, target, options); diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp index d802bdd..971a660 100644 --- a/src/opengl/qgl_x11egl.cpp +++ b/src/opengl/qgl_x11egl.cpp @@ -86,9 +86,19 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) qt_egl_add_platform_config(configProps, device()); configProps.setRenderableType(QEgl::OpenGL); + QEgl::PixelFormatMatch matchType = QEgl::BestPixelFormat; + if (device()->depth() == 16) { + configProps.setValue(EGL_RED_SIZE, 5); + configProps.setValue(EGL_GREEN_SIZE, 6); + configProps.setValue(EGL_BLUE_SIZE, 5); + configProps.setValue(EGL_ALPHA_SIZE, 0); + matchType = QEgl::ExactPixelFormat; + } + configProps.setRenderableType(QEgl::OpenGL); + // Search for a matching configuration, reducing the complexity // each time until we get something that matches. - if (!d->eglContext->chooseConfig(configProps, QEgl::BestPixelFormat)) { + if (!d->eglContext->chooseConfig(configProps, matchType)) { delete d->eglContext; d->eglContext = 0; return false; diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index 1ee3bbf..ae4bed0 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -48,9 +48,12 @@ #include <private/qgl_p.h> #include <private/qdrawhelper_p.h> +#include <private/qimage_p.h> #include <private/qpaintengineex_opengl2_p.h> +#include <qdesktopwidget.h> + QT_BEGIN_NAMESPACE extern QGLWidget* qt_gl_share_widget(); @@ -315,7 +318,7 @@ void QGLPixmapData::ensureCreated() const } void QGLPixmapData::fromImage(const QImage &image, - Qt::ImageConversionFlags) + Qt::ImageConversionFlags flags) { if (image.size() == QSize(w, h)) setSerialNumber(++qt_gl_pixmap_serial); @@ -323,20 +326,26 @@ void QGLPixmapData::fromImage(const QImage &image, if (pixelType() == BitmapType) { m_source = image.convertToFormat(QImage::Format_MonoLSB); + } else { - m_source = image.hasAlphaChannel() - ? image.convertToFormat(QImage::Format_ARGB32_Premultiplied) - : image.convertToFormat(QImage::Format_RGB32); + QImage::Format format = QImage::Format_RGB32; + if (qApp->desktop()->depth() == 16) + format = QImage::Format_RGB16; + + if (image.hasAlphaChannel() && const_cast<QImage &>(image).data_ptr()->checkForAlphaPixels()) + format = QImage::Format_ARGB32_Premultiplied;; + + m_source = image.convertToFormat(format); } m_dirty = true; m_hasFillColor = false; - m_hasAlpha = image.hasAlphaChannel(); + m_hasAlpha = m_source.hasAlphaChannel(); w = image.width(); h = image.height(); is_null = (w <= 0 || h <= 0); - d = pixelType() == QPixmapData::PixmapType ? 32 : 1; + d = m_source.depth(); if (m_texture.id) { QGLShareContextScope ctx(qt_gl_share_widget()->context()); diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index 3a348bc..7f8577a 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -306,8 +306,13 @@ QGLWindowSurface::QGLWindowSurface(QWidget *window) d_ptr->pb = 0; d_ptr->fbo = 0; d_ptr->ctx = 0; +#if defined (QT_OPENGL_ES_2) + d_ptr->tried_fbo = true; + d_ptr->tried_pb = true; +#else d_ptr->tried_fbo = false; d_ptr->tried_pb = false; +#endif d_ptr->destructive_swap_buffers = qgetenv("QT_GL_SWAPBUFFER_PRESERVE").isNull(); d_ptr->glDevice.d = d_ptr; d_ptr->q_ptr = this; @@ -438,6 +443,7 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & QRect rect = br.translated(-offset - wOffset); const GLenum target = GL_TEXTURE_2D; + Q_UNUSED(target); if (context()) { context()->makeCurrent(); |