diff options
author | Jani Hautakangas <jani.hautakangas@nokia.com> | 2011-02-07 11:38:51 (GMT) |
---|---|---|
committer | Jani Hautakangas <jani.hautakangas@nokia.com> | 2011-02-08 09:57:35 (GMT) |
commit | 7dc4c8dc1dd4fba8072fd688014f74c98aeb3a23 (patch) | |
tree | aeae13443ee35e076adf7cb6e8bcb1ce399786ec /src/opengl | |
parent | fe68a04ed15038a9e22b66c567bcd44ee93e33d1 (diff) | |
download | Qt-7dc4c8dc1dd4fba8072fd688014f74c98aeb3a23.zip Qt-7dc4c8dc1dd4fba8072fd688014f74c98aeb3a23.tar.gz Qt-7dc4c8dc1dd4fba8072fd688014f74c98aeb3a23.tar.bz2 |
Use the 'convertInPlace' versions of QImage in QGLPixmapData load.
Change QGLPixmapData load functions to use 'convertInPlace' versions
of QImage to save memory.
Task-number: QTBUG-17256
Reviewed-by: Samuel Rødal
Diffstat (limited to 'src/opengl')
-rw-r--r-- | src/opengl/qpixmapdata_gl.cpp | 113 | ||||
-rw-r--r-- | src/opengl/qpixmapdata_gl_p.h | 4 |
2 files changed, 83 insertions, 34 deletions
diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index d12704d..249c71e 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -55,6 +55,7 @@ #include <qdesktopwidget.h> #include <qfile.h> #include <qimagereader.h> +#include <qbuffer.h> QT_BEGIN_NAMESPACE @@ -369,40 +370,18 @@ void QGLPixmapData::ensureCreated() const void QGLPixmapData::fromImage(const QImage &image, Qt::ImageConversionFlags flags) { - if (image.size() == QSize(w, h)) - setSerialNumber(++qt_gl_pixmap_serial); - resize(image.width(), image.height()); - - if (pixelType() == BitmapType) { - m_source = image.convertToFormat(QImage::Format_MonoLSB); - - } else { - QImage::Format format = QImage::Format_RGB32; - if (qApp->desktop()->depth() == 16) - format = QImage::Format_RGB16; - - if (image.hasAlphaChannel() - && ((flags & Qt::NoOpaqueDetection) - || const_cast<QImage &>(image).data_ptr()->checkForAlphaPixels())) - format = QImage::Format_ARGB32_Premultiplied;; - - m_source = image.convertToFormat(format); - } - - m_dirty = true; - m_hasFillColor = false; + QImage img = image; + createPixmapForImage(img, flags, false); +} - m_hasAlpha = m_source.hasAlphaChannel(); - w = image.width(); - h = image.height(); - is_null = (w <= 0 || h <= 0); - d = m_source.depth(); +void QGLPixmapData::fromImageReader(QImageReader *imageReader, + Qt::ImageConversionFlags flags) +{ + QImage image = imageReader->read(); + if (image.isNull()) + return; - if (m_texture.id) { - QGLShareContextScope ctx(qt_gl_share_context()); - glDeleteTextures(1, &m_texture.id); - m_texture.id = 0; - } + createPixmapForImage(image, flags, true); } bool QGLPixmapData::fromFile(const QString &filename, const char *format, @@ -435,7 +414,13 @@ bool QGLPixmapData::fromFile(const QString &filename, const char *format, } return false; } - fromImage(QImageReader(&file, format).read(), flags); + + QImage image = QImageReader(filename, format).read(); + if (image.isNull()) + return false; + + createPixmapForImage(image, flags, true); + return !isNull(); } @@ -459,7 +444,67 @@ bool QGLPixmapData::fromData(const uchar *buffer, uint len, const char *format, return true; } } - return QPixmapData::fromData(buffer, len, format, flags); + + QByteArray a = QByteArray::fromRawData(reinterpret_cast<const char *>(buffer), len); + QBuffer b(&a); + b.open(QIODevice::ReadOnly); + QImage image = QImageReader(&b, format).read(); + if (image.isNull()) + return false; + + createPixmapForImage(image, flags, true); + + return !isNull(); +} + +/*! + out-of-place conversion (inPlace == false) will always detach() + */ +void QGLPixmapData::createPixmapForImage(QImage &image, Qt::ImageConversionFlags flags, bool inPlace) +{ + if (image.size() == QSize(w, h)) + setSerialNumber(++qt_gl_pixmap_serial); + + resize(image.width(), image.height()); + + if (pixelType() == BitmapType) { + m_source = image.convertToFormat(QImage::Format_MonoLSB); + + } else { + QImage::Format format = QImage::Format_RGB32; + if (qApp->desktop()->depth() == 16) + format = QImage::Format_RGB16; + + if (image.hasAlphaChannel() + && ((flags & Qt::NoOpaqueDetection) + || const_cast<QImage &>(image).data_ptr()->checkForAlphaPixels())) + format = QImage::Format_ARGB32_Premultiplied;; + + if (inPlace && image.data_ptr()->convertInPlace(format, flags)) { + m_source = image; + } else { + m_source = image.convertToFormat(format); + + // convertToFormat won't detach the image if format stays the same. + if (image.format() == format) + m_source.detach(); + } + } + + m_dirty = true; + m_hasFillColor = false; + + m_hasAlpha = m_source.hasAlphaChannel(); + w = image.width(); + h = image.height(); + is_null = (w <= 0 || h <= 0); + d = m_source.depth(); + + if (m_texture.id) { + QGLShareContextScope ctx(qt_gl_share_context()); + glDeleteTextures(1, &m_texture.id); + m_texture.id = 0; + } } bool QGLPixmapData::scroll(int dx, int dy, const QRect &rect) diff --git a/src/opengl/qpixmapdata_gl_p.h b/src/opengl/qpixmapdata_gl_p.h index 5545d3c..96631e6 100644 --- a/src/opengl/qpixmapdata_gl_p.h +++ b/src/opengl/qpixmapdata_gl_p.h @@ -107,6 +107,8 @@ public: // Re-implemented from QPixmapData: void resize(int width, int height); void fromImage(const QImage &image, Qt::ImageConversionFlags flags); + void fromImageReader(QImageReader *imageReader, + Qt::ImageConversionFlags flags); bool fromFile(const QString &filename, const char *format, Qt::ImageConversionFlags flags); bool fromData(const uchar *buffer, uint len, const char *format, @@ -149,6 +151,8 @@ private: QImage fillImage(const QColor &color) const; + void createPixmapForImage(QImage &image, Qt::ImageConversionFlags flags, bool inPlace); + mutable QGLFramebufferObject *m_renderFbo; mutable QPaintEngine *m_engine; mutable QGLContext *m_ctx; |