From 992809f9ba91c50bc759508127b493172236c149 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Thu, 23 Sep 2010 12:36:42 +0200 Subject: Fixes gray_raster incorrectly reporting out of memory error. The bug caused a useless realloction everytime a path was rasterized with gray_raster. Task-number: QTBUG-13871 Reviewed-by: Samuel --- src/gui/painting/qgrayraster.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/painting/qgrayraster.c b/src/gui/painting/qgrayraster.c index 94039fb..19cef49 100644 --- a/src/gui/painting/qgrayraster.c +++ b/src/gui/painting/qgrayraster.c @@ -324,6 +324,7 @@ { void* buffer; long buffer_size; + long buffer_allocated_size; int band_size; void* memory; PWorker worker; @@ -1767,7 +1768,7 @@ // If raster object and raster buffer are allocated, but // raster size isn't of the minimum size, indicate out of // memory. - if (raster && raster->buffer && raster->buffer_size < MINIMUM_POOL_SIZE ) + if (raster->buffer_allocated_size < MINIMUM_POOL_SIZE ) return ErrRaster_OutOfMemory; /* return immediately if the outline is empty */ @@ -1906,6 +1907,7 @@ rast->buffer_size = 0; rast->worker = NULL; } + rast->buffer_allocated_size = pool_size; } } -- cgit v0.12 From d31dcaf0c17d56f74d4faeaae3b5ce54ed847ee6 Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Fri, 24 Sep 2010 12:47:06 +0200 Subject: Named anonymous struct in the OpenGL paint engine. Task-number: QTBUG-13926 Reviewed-by: Gunnar --- src/opengl/qpaintengine_opengl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp index 58778ea..2f17aa6 100644 --- a/src/opengl/qpaintengine_opengl.cpp +++ b/src/opengl/qpaintengine_opengl.cpp @@ -506,12 +506,12 @@ struct QDrawQueueItem ////////// GL program cache: start -typedef struct { +struct GLProgram { int brush; // brush index or mask index int mode; // composition mode index bool mask; GLuint program; -} GLProgram; +}; typedef QMultiHash QGLProgramHash; -- cgit v0.12 From 4e781b65c60c6bdf0917fe9983a4f1e699643e55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Fri, 24 Sep 2010 13:16:01 +0200 Subject: Don't pretend to support single buffered EGL surfaces. Task-number: QTBUG-12865 Reviewed-by: Samuel --- src/opengl/qgl.cpp | 3 +++ src/opengl/qgl_egl.cpp | 1 + 2 files changed, 4 insertions(+) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 0d1a66e..b678790 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -509,6 +509,9 @@ QGLFormat::~QGLFormat() exchange the screen contents with the buffer. The result is flicker-free drawing and often better performance. + Note that single buffered contexts are currently not supported + with EGL. + \sa doubleBuffer(), QGLContext::swapBuffers(), QGLWidget::swapBuffers() */ diff --git a/src/opengl/qgl_egl.cpp b/src/opengl/qgl_egl.cpp index ebd1169..c79c4cd 100644 --- a/src/opengl/qgl_egl.cpp +++ b/src/opengl/qgl_egl.cpp @@ -143,6 +143,7 @@ void qt_glformat_from_eglconfig(QGLFormat& format, const EGLConfig config) format.setRgba(true); // EGL doesn't support colour index rendering format.setStereo(false); // EGL doesn't support stereo buffers format.setAccumBufferSize(0); // EGL doesn't support accululation buffers + format.setDoubleBuffer(true); // We don't support single buffered EGL contexts // Clear the EGL error state because some of the above may // have errored out because the attribute is not applicable -- cgit v0.12 From d5e6aa0a70004338a644387ba3d682a73fa169a9 Mon Sep 17 00:00:00 2001 From: aavit Date: Fri, 24 Sep 2010 16:49:19 +0200 Subject: Optimization of pixel conversion when storing jpeg Reviewed-by: Kim --- src/gui/image/qjpeghandler.cpp | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/gui/image/qjpeghandler.cpp b/src/gui/image/qjpeghandler.cpp index b9eda05..d47cc82 100644 --- a/src/gui/image/qjpeghandler.cpp +++ b/src/gui/image/qjpeghandler.cpp @@ -648,22 +648,28 @@ static bool write_jpeg_image(const QImage &image, QIODevice *device, int sourceQ break; case QImage::Format_RGB32: case QImage::Format_ARGB32: - case QImage::Format_ARGB32_Premultiplied: { - const QRgb* rgb = (const QRgb*)image.constScanLine(cinfo.next_scanline); - for (int i=0; i Date: Mon, 27 Sep 2010 07:10:54 +0200 Subject: fix documentation of drawText(int, int, int, int, ... --- src/gui/painting/qpainter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 12be93e..376d68b 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -6185,7 +6185,7 @@ void QPainter::drawText(const QRectF &r, int flags, const QString &str, QRectF * By default, QPainter draws text anti-aliased. - \note The y-position is used as the baseline of the font. + \note The y-position is used as the top of the font. \sa Qt::AlignmentFlag, Qt::TextFlag */ -- cgit v0.12 From ce2a273bab9b9094a1f0f3f60309797e11e59404 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Mon, 27 Sep 2010 11:39:05 +0200 Subject: Doc update for the support of MSVC 2010 64-bit MS has released a hotfix for the support of MSVC 2010 64-bit. It fixes the optimizer that could generate code that crashes. Reviewed-by: Trust-Me Task-number: QTBUG-11445 --- doc/src/platforms/compiler-notes.qdoc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/src/platforms/compiler-notes.qdoc b/doc/src/platforms/compiler-notes.qdoc index 3870e8f..bcf7cb4 100644 --- a/doc/src/platforms/compiler-notes.qdoc +++ b/doc/src/platforms/compiler-notes.qdoc @@ -267,8 +267,9 @@ for more information. There currently is a problem when compiling Qt with Visual Studio 2010 for 64-bit. - Its optimizer causes trouble and crashes for the release builds and it is not supported - in that configuration. See task http://bugreports.qt.nokia.com/browse/QTBUG-11445. + Its optimizer causes trouble and generates code that crashes for the release builds. + To avoid the crashes, You need to apply the hotfix in the following article + http://support.microsoft.com/kb/2280741. \section1 IBM xlC (AIX) -- cgit v0.12 From c9a5ab5fd506663c5a7cd587d1b963c067d334bf Mon Sep 17 00:00:00 2001 From: aavit Date: Fri, 24 Sep 2010 17:51:14 +0200 Subject: Avoid creating copy of an image in memory when storing as png Task-number: QT-3871 Reviewed-by: Kim --- src/gui/image/qpnghandler.cpp | 92 ++++++++++++++-------------- tests/auto/qimagereader/tst_qimagereader.cpp | 43 +++++++++++++ 2 files changed, 88 insertions(+), 47 deletions(-) diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp index dc54313..935aba0 100644 --- a/src/gui/image/qpnghandler.cpp +++ b/src/gui/image/qpnghandler.cpp @@ -678,41 +678,19 @@ bool QPNGImageWriter::writeImage(const QImage& image, int off_x, int off_y) return writeImage(image, -1, QString(), off_x, off_y); } -bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image_in, int quality_in, const QString &description, +bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image, int quality_in, const QString &description, int off_x_in, int off_y_in) { #ifdef QT_NO_IMAGE_TEXT Q_UNUSED(description); #endif - QImage image; - switch (image_in.format()) { - case QImage::Format_ARGB32_Premultiplied: - case QImage::Format_ARGB4444_Premultiplied: - case QImage::Format_ARGB8555_Premultiplied: - case QImage::Format_ARGB8565_Premultiplied: - case QImage::Format_ARGB6666_Premultiplied: - image = image_in.convertToFormat(QImage::Format_ARGB32); - break; - case QImage::Format_RGB16: - case QImage::Format_RGB444: - case QImage::Format_RGB555: - case QImage::Format_RGB666: - case QImage::Format_RGB888: - image = image_in.convertToFormat(QImage::Format_RGB32); - break; - default: - image = image_in; - break; - } - QPoint offset = image.offset(); int off_x = off_x_in + offset.x(); int off_y = off_y_in + offset.y(); png_structp png_ptr; png_infop info_ptr; - png_bytep* row_pointers; png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,0,0,0); if (!png_ptr) { @@ -743,13 +721,18 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image_in, png_set_write_fn(png_ptr, (void*)this, qpiw_write_fn, qpiw_flush_fn); + + int color_type = 0; + if (image.colorCount()) + color_type = PNG_COLOR_TYPE_PALETTE; + else if (image.hasAlphaChannel()) + color_type = PNG_COLOR_TYPE_RGB_ALPHA; + else + color_type = PNG_COLOR_TYPE_RGB; + png_set_IHDR(png_ptr, info_ptr, image.width(), image.height(), - image.depth() == 1 ? 1 : 8 /* per channel */, - image.depth() == 32 - ? image.format() == QImage::Format_RGB32 - ? PNG_COLOR_TYPE_RGB - : PNG_COLOR_TYPE_RGB_ALPHA - : PNG_COLOR_TYPE_PALETTE, 0, 0, 0); // also sets #channels + image.depth() == 1 ? 1 : 8, // per channel + color_type, 0, 0, 0); // sets #channels if (gamma != 0.0) { png_set_gAMA(png_ptr, info_ptr, 1.0/gamma); @@ -794,8 +777,9 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image_in, png_set_swap_alpha(png_ptr); } - // Qt==ARGB==Big(ARGB)==Little(BGRA) - if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) { + // Qt==ARGB==Big(ARGB)==Little(BGRA). But RGB888 is RGB regardless + if (QSysInfo::ByteOrder == QSysInfo::LittleEndian + && image.format() != QImage::Format_RGB888) { png_set_bgr(png_ptr); } @@ -820,7 +804,7 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image_in, if (image.depth() != 1) png_set_packing(png_ptr); - if (image.format() == QImage::Format_RGB32) + if (color_type == PNG_COLOR_TYPE_RGB && image.format() != QImage::Format_RGB888) png_set_filler(png_ptr, 0, QSysInfo::ByteOrder == QSysInfo::BigEndian ? PNG_FILLER_BEFORE : PNG_FILLER_AFTER); @@ -841,22 +825,36 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image_in, png_write_chunk(png_ptr, (png_byte*)"gIFg", data, 4); } - png_uint_32 width; - png_uint_32 height; - int bit_depth; - int color_type; - png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, - 0, 0, 0); - - const uchar *data = (static_cast(&image))->bits(); - int bpl = image.bytesPerLine(); - row_pointers = new png_bytep[height]; - uint y; - for (y=0; y("format"); + + QTest::newRow("Format_Mono") << QImage::Format_Mono; + QTest::newRow("Format_MonoLSB") << QImage::Format_MonoLSB; + QTest::newRow("Format_Indexed8") << QImage::Format_Indexed8; + QTest::newRow("Format_RGB32") << QImage::Format_RGB32; + QTest::newRow("Format_ARGB32") << QImage::Format_ARGB32; + QTest::newRow("Format_ARGB32_Premultiplied") << QImage::Format_ARGB32_Premultiplied; + QTest::newRow("Format_RGB16") << QImage::Format_RGB16; + QTest::newRow("Format_ARGB8565_Premultiplied") << QImage::Format_ARGB8565_Premultiplied; + QTest::newRow("Format_RGB666") << QImage::Format_RGB666; + QTest::newRow("Format_ARGB6666_Premultiplied") << QImage::Format_ARGB6666_Premultiplied; + QTest::newRow("Format_RGB555") << QImage::Format_RGB555; + QTest::newRow("Format_ARGB8555_Premultiplied") << QImage::Format_ARGB8555_Premultiplied; + QTest::newRow("Format_RGB888") << QImage::Format_RGB888; + QTest::newRow("Format_RGB444") << QImage::Format_RGB444; + QTest::newRow("Format_ARGB4444_Premultiplied") << QImage::Format_ARGB4444_Premultiplied; +} + +void tst_QImageReader::saveFormat() +{ + QFETCH(QImage::Format, format); + + QImage orig(":/images/kollada.png"); + + QImage converted = orig.convertToFormat(format); + QBuffer buf; + buf.open(QIODevice::WriteOnly); + QVERIFY(converted.save(&buf, "png")); + buf.close(); + QImage stored = QImage::fromData(buf.buffer(), "png"); + + stored = stored.convertToFormat(QImage::Format_ARGB32); + converted = converted.convertToFormat(QImage::Format_ARGB32); + QCOMPARE(stored, converted); +} + + QTEST_MAIN(tst_QImageReader) #include "tst_qimagereader.moc" -- cgit v0.12 From 5ff714badf06f492c3f6f8282b64181cc93faadb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Mon, 27 Sep 2010 12:14:56 +0200 Subject: Don't disable texture_from_pixmap on GLX/X11 by default. We made a mistake of trying to make use of the texture_from_pixmap extension by default when binding textures in Qt. The extension have several limitation and using it produces crashes with certain drivers/graphic card combos, but we can't change this now since it will break existing apps using well behaved drivers. We'll fix this for 4.8 with either a QGL::BindOption or configure flag. Revert "Don't try to use the texture_from_pixmap extension in GL on desktop/X11." This reverts commit 07c5429d5aacab932cd912e66287d66fb952e7c4. --- src/opengl/qgl.cpp | 33 ++++++++++++++++++++++++++------- src/opengl/qgl_p.h | 3 +++ 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index b678790..9e74e04 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -1692,6 +1692,9 @@ void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format) workaround_brokenFBOReadBack = false; workaroundsCached = false; + workaround_brokenTextureFromPixmap = false; + workaround_brokenTextureFromPixmap_init = false; + for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i) vertexAttributeArraysEnabledState[i] = false; } @@ -2577,18 +2580,34 @@ QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target, } } -#if defined(Q_WS_X11) && !defined(QT_NO_EGL) - // Only try to use texture_from_pixmap under X11/EGL +#if defined(Q_WS_X11) + // Try to use texture_from_pixmap const QX11Info *xinfo = qt_x11Info(paintDevice); if (pd->classId() == QPixmapData::X11Class && pd->pixelType() == QPixmapData::PixmapType && xinfo && xinfo->screen() == pixmap.x11Info().screen() && target == GL_TEXTURE_2D) { - texture = bindTextureFromNativePixmap(const_cast(&pixmap), key, options); - if (texture) { - texture->options |= QGLContext::MemoryManagedBindOption; - texture->boundPixmap = pd; - boundPixmaps.insert(pd, QPixmap(pixmap)); + if (!workaround_brokenTextureFromPixmap_init) { + workaround_brokenTextureFromPixmap_init = true; + + const QByteArray versionString(reinterpret_cast(glGetString(GL_VERSION))); + const int pos = versionString.indexOf("NVIDIA "); + + if (pos >= 0) { + const QByteArray nvidiaVersionString = versionString.mid(pos + strlen("NVIDIA ")); + + if (nvidiaVersionString.startsWith("195") || nvidiaVersionString.startsWith("256")) + workaround_brokenTextureFromPixmap = true; + } + } + + if (!workaround_brokenTextureFromPixmap) { + texture = bindTextureFromNativePixmap(const_cast(&pixmap), key, options); + if (texture) { + texture->options |= QGLContext::MemoryManagedBindOption; + texture->boundPixmap = pd; + boundPixmaps.insert(pd, QPixmap(pixmap)); + } } } #endif diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 6323ce2..623eeaf 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -401,6 +401,9 @@ public: uint workaround_brokenFBOReadBack : 1; uint workaroundsCached : 1; + uint workaround_brokenTextureFromPixmap : 1; + uint workaround_brokenTextureFromPixmap_init : 1; + QPaintDevice *paintDevice; QColor transpColor; QGLContext *q_ptr; -- cgit v0.12 From d60dc7cba21794866c9382f83080fab1a129eb08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Mon, 27 Sep 2010 13:02:47 +0200 Subject: Fixed performance regression in curve stroking. Change c46688b8a88da made us use m_curve_threshold for both QBezier::shifted and QBezier::toPolygon, and adjusted the threshold dynamically based on the painter scale. Since the threshold in shifted was already relative to the pen width, it is independent from the painter scale. Instead, we need to set a separate threshold for dashing. Also, in several places we were calling setCurveThresholdForTransform with the painter matrix even though we were transforming the points into device coordinate space before stroking. Task-number: QTBUG-13894 Reviewed-by: Gunnar Sletta --- src/gui/painting/qpaintengineex.cpp | 2 +- src/gui/painting/qstroker.cpp | 9 +++++---- src/gui/painting/qstroker_p.h | 3 ++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index 1e857e4..c1e3d66 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -517,7 +517,7 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) QPainterPath painterPath = state()->matrix.map(path.convertToPainterPath()); d->activeStroker->strokePath(painterPath, d->strokeHandler, QTransform()); } else { - d->activeStroker->setCurveThresholdFromTransform(state()->matrix); + d->activeStroker->setCurveThresholdFromTransform(QTransform()); d->activeStroker->begin(d->strokeHandler); if (types) { while (points < lastPoint) { diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp index 9cff339..9decf41 100644 --- a/src/gui/painting/qstroker.cpp +++ b/src/gui/painting/qstroker.cpp @@ -190,6 +190,7 @@ static inline qreal adapted_angle_on_x(const QLineF &line) QStrokerOps::QStrokerOps() : m_elements(0) , m_curveThreshold(qt_real_to_fixed(0.25)) + , m_dashThreshold(qt_real_to_fixed(0.25)) , m_customData(0) , m_moveTo(0) , m_lineTo(0) @@ -243,7 +244,7 @@ void QStrokerOps::strokePath(const QPainterPath &path, void *customData, const Q if (path.isEmpty()) return; - setCurveThresholdFromTransform(matrix); + setCurveThresholdFromTransform(QTransform()); begin(customData); int count = path.elementCount(); if (matrix.isIdentity()) { @@ -315,7 +316,7 @@ void QStrokerOps::strokePolygon(const QPointF *points, int pointCount, bool impl if (!pointCount) return; - setCurveThresholdFromTransform(matrix); + setCurveThresholdFromTransform(QTransform()); begin(data); if (matrix.isIdentity()) { moveTo(qt_real_to_fixed(points[0].x()), qt_real_to_fixed(points[0].y())); @@ -356,7 +357,7 @@ void QStrokerOps::strokeEllipse(const QRectF &rect, void *data, const QTransform } } - setCurveThresholdFromTransform(matrix); + setCurveThresholdFromTransform(QTransform()); begin(data); moveTo(qt_real_to_fixed(start.x()), qt_real_to_fixed(start.y())); for (int i=0; i<12; i+=3) { @@ -1142,7 +1143,7 @@ void QDashStroker::processCurrentSubpath() QPainterPath dashPath; - QSubpathFlatIterator it(&m_elements, m_curveThreshold); + QSubpathFlatIterator it(&m_elements, m_dashThreshold); qfixed2d prev = it.next(); bool clipping = !m_clip_rect.isEmpty(); diff --git a/src/gui/painting/qstroker_p.h b/src/gui/painting/qstroker_p.h index d646135..5607a8e 100644 --- a/src/gui/painting/qstroker_p.h +++ b/src/gui/painting/qstroker_p.h @@ -168,7 +168,7 @@ public: { qreal scale; qt_scaleForTransform(transform, &scale); - setCurveThreshold(scale == 0 ? qreal(0.5) : (qreal(0.5) / scale)); + m_dashThreshold = scale == 0 ? qreal(0.5) : (qreal(0.5) / scale); } void setCurveThreshold(qfixed threshold) { m_curveThreshold = threshold; } @@ -184,6 +184,7 @@ protected: QRectF m_clip_rect; qfixed m_curveThreshold; + qfixed m_dashThreshold; void *m_customData; qStrokerMoveToHook m_moveTo; -- cgit v0.12