summaryrefslogtreecommitdiffstats
path: root/src/opengl
diff options
context:
space:
mode:
authorJani Hautakangas <jani.hautakangas@nokia.com>2011-02-07 13:38:51 +0200
committerJani Hautakangas <jani.hautakangas@nokia.com>2011-02-08 11:57:35 +0200
commit7dc4c8dc1dd4fba8072fd688014f74c98aeb3a23 (patch)
treeaeae13443ee35e076adf7cb6e8bcb1ce399786ec /src/opengl
parentfe68a04ed15038a9e22b66c567bcd44ee93e33d1 (diff)
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.cpp113
-rw-r--r--src/opengl/qpixmapdata_gl_p.h4
2 files changed, 83 insertions, 34 deletions
diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp
index d12704dd29..249c71ec40 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 5545d3c5a7..96631e6000 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;