summaryrefslogtreecommitdiffstats
path: root/src/opengl/qpixmapdata_gl.cpp
diff options
context:
space:
mode:
authorSamuel Rødal <sroedal@trolltech.com>2009-06-12 12:01:25 (GMT)
committerSamuel Rødal <sroedal@trolltech.com>2009-06-12 12:41:52 (GMT)
commit8a2993a6c53e1a5641bd1c500ad4bd54e799299b (patch)
treed9b4fb4e6525ac7fb166c99350e780cac86dd678 /src/opengl/qpixmapdata_gl.cpp
parent0265a36425cfcb01d7c35fbb4a7c5907893972a1 (diff)
downloadQt-8a2993a6c53e1a5641bd1c500ad4bd54e799299b.zip
Qt-8a2993a6c53e1a5641bd1c500ad4bd54e799299b.tar.gz
Qt-8a2993a6c53e1a5641bd1c500ad4bd54e799299b.tar.bz2
Made QPixmap autotest pass with -graphicssystem opengl
The window surface has been modified to track widget deletion to make sure it doesn't try to access the widget's context data after deletion. QGLPixmapData now also uses GL_RGB instead of GL_RGBA when appropriate, and hasAlphaChannel() has been modified in view of this. A number of other issues have been fixed in QGLPixmapData, and the autotest has been modified to use a more lenient pixmap compare function due to off-by-one pixel errors here and there. Reviewed-by: Trond
Diffstat (limited to 'src/opengl/qpixmapdata_gl.cpp')
-rw-r--r--src/opengl/qpixmapdata_gl.cpp67
1 files changed, 53 insertions, 14 deletions
diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp
index 98c406b..4c53c46 100644
--- a/src/opengl/qpixmapdata_gl.cpp
+++ b/src/opengl/qpixmapdata_gl.cpp
@@ -104,6 +104,7 @@ QGLPixmapData::QGLPixmapData(PixelType type)
, m_ctx(0)
, m_dirty(false)
, m_hasFillColor(false)
+ , m_hasAlpha(false)
{
setSerialNumber(++qt_gl_pixmap_serial);
}
@@ -136,6 +137,11 @@ void QGLPixmapData::resize(int width, int height)
if (width == m_width && height == m_height)
return;
+ if (width <= 0 || height <= 0) {
+ width = 0;
+ height = 0;
+ }
+
m_width = width;
m_height = height;
@@ -166,7 +172,8 @@ void QGLPixmapData::ensureCreated() const
if (!m_textureId) {
glGenTextures(1, &m_textureId);
glBindTexture(target, m_textureId);
- glTexImage2D(target, 0, GL_RGBA, m_width, m_height, 0,
+ GLenum format = m_hasAlpha ? GL_RGBA : GL_RGB;
+ glTexImage2D(target, 0, format, m_width, m_height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, 0);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
@@ -195,10 +202,20 @@ void QGLPixmapData::fromImage(const QImage &image,
if (image.size() == QSize(m_width, m_height))
setSerialNumber(++qt_gl_pixmap_serial);
resize(image.width(), image.height());
- m_source = 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);
+ }
+
m_dirty = true;
m_hasFillColor = false;
+ m_hasAlpha = image.hasAlphaChannel();
+
if (m_textureId) {
QGLShareContextScope ctx(qt_gl_share_widget()->context());
glDeleteTextures(1, &m_textureId);
@@ -230,24 +247,46 @@ void QGLPixmapData::fill(const QColor &color)
if (!isValid())
return;
+ if (!m_textureId)
+ m_hasAlpha = color.alpha() != 255;
+
if (useFramebufferObjects()) {
m_source = QImage();
m_hasFillColor = true;
m_fillColor = color;
- } else if (!m_source.isNull()) {
- m_source.fill(PREMUL(color.rgba()));
} else {
- // ## TODO: improve performance here
- QImage img(m_width, m_height, QImage::Format_ARGB32_Premultiplied);
- img.fill(PREMUL(color.rgba()));
-
- fromImage(img, 0);
+ QImage image = fillImage(color);
+ fromImage(image, 0);
}
}
bool QGLPixmapData::hasAlphaChannel() const
{
- return true;
+ return pixelType() == BitmapType || m_hasAlpha;
+}
+
+QImage QGLPixmapData::fillImage(const QColor &color) const
+{
+ QImage img;
+ if (pixelType() == BitmapType) {
+ img = QImage(m_width, m_height, QImage::Format_MonoLSB);
+ img.setNumColors(2);
+ img.setColor(0, QColor(Qt::color0).rgba());
+ img.setColor(1, QColor(Qt::color1).rgba());
+
+ int gray = qGray(color.rgba());
+ if (qAbs(255 - gray) < gray)
+ img.fill(0);
+ else
+ img.fill(1);
+ } else {
+ img = QImage(m_width, m_height,
+ m_hasAlpha
+ ? QImage::Format_ARGB32_Premultiplied
+ : QImage::Format_RGB32);
+ img.fill(PREMUL(color.rgba()));
+ }
+ return img;
}
QImage QGLPixmapData::toImage() const
@@ -260,10 +299,7 @@ QImage QGLPixmapData::toImage() const
} else if (!m_source.isNull()) {
return m_source;
} else if (m_dirty || m_hasFillColor) {
- QImage img(m_width, m_height, QImage::Format_ARGB32_Premultiplied);
- if (m_hasFillColor)
- img.fill(PREMUL(m_fillColor.rgba()));
- return img;
+ return fillImage(m_fillColor);
} else {
ensureCreated();
}
@@ -453,6 +489,9 @@ extern int qt_defaultDpiY();
int QGLPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
{
+ if (m_width == 0)
+ return 0;
+
switch (metric) {
case QPaintDevice::PdmWidth:
return m_width;