From 7a5cc73816df5cf65e8a9aaafd750acdac9ca5a3 Mon Sep 17 00:00:00 2001 From: Dmytro Poplavskiy Date: Mon, 8 Mar 2010 17:24:21 +1000 Subject: Delayed initialization of gstreamer video widget. This saves time/memory when the video widget control is not used, and allows using of audio only QMediaPlayer in non gui applications. Reviewed-by: Justin McPherson --- .../gstreamer/qgstreamervideowidget.cpp | 52 +++++++++++++--------- .../gstreamer/qgstreamervideowidget.h | 1 + 2 files changed, 33 insertions(+), 20 deletions(-) diff --git a/src/plugins/mediaservices/gstreamer/qgstreamervideowidget.cpp b/src/plugins/mediaservices/gstreamer/qgstreamervideowidget.cpp index 47fb451..8307aa5 100644 --- a/src/plugins/mediaservices/gstreamer/qgstreamervideowidget.cpp +++ b/src/plugins/mediaservices/gstreamer/qgstreamervideowidget.cpp @@ -99,9 +99,26 @@ protected: QGstreamerVideoWidgetControl::QGstreamerVideoWidgetControl(QObject *parent) : QVideoWidgetControl(parent) , m_videoSink(0) - , m_widget(new QGstreamerVideoWidget) + , m_widget(0) , m_fullScreen(false) +{ +} + +QGstreamerVideoWidgetControl::~QGstreamerVideoWidgetControl() +{ + if (m_videoSink) + gst_object_unref(GST_OBJECT(m_videoSink)); + + delete m_widget; +} + +void QGstreamerVideoWidgetControl::createVideoWidget() { + if (m_widget) + return; + + m_widget = new QGstreamerVideoWidget; + m_widget->installEventFilter(this); m_windowId = m_widget->winId(); @@ -125,22 +142,15 @@ QGstreamerVideoWidgetControl::QGstreamerVideoWidgetControl(QObject *parent) gst_object_sink (GST_OBJECT (m_videoSink)); } -QGstreamerVideoWidgetControl::~QGstreamerVideoWidgetControl() -{ - if (m_videoSink) - gst_object_unref(GST_OBJECT(m_videoSink)); - - delete m_widget; -} - GstElement *QGstreamerVideoWidgetControl::videoSink() { + createVideoWidget(); return m_videoSink; } bool QGstreamerVideoWidgetControl::eventFilter(QObject *object, QEvent *e) { - if (object == m_widget) { + if (m_widget && object == m_widget) { if (e->type() == QEvent::ParentChange || e->type() == QEvent::Show) { WId newWId = m_widget->winId(); if (newWId != m_windowId) { @@ -205,7 +215,8 @@ void QGstreamerVideoWidgetControl::updateNativeVideoSize() gst_caps_unref(caps); } } else { - m_widget->setNativeSize(QSize()); + if (m_widget) + m_widget->setNativeSize(QSize()); } } @@ -218,6 +229,7 @@ void QGstreamerVideoWidgetControl::windowExposed() QWidget *QGstreamerVideoWidgetControl::videoWidget() { + createVideoWidget(); return m_widget; } @@ -252,7 +264,7 @@ int QGstreamerVideoWidgetControl::brightness() const { int brightness = 0; - if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "brightness")) + if (m_videoSink && g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "brightness")) g_object_get(G_OBJECT(m_videoSink), "brightness", &brightness, NULL); return brightness / 10; @@ -260,7 +272,7 @@ int QGstreamerVideoWidgetControl::brightness() const void QGstreamerVideoWidgetControl::setBrightness(int brightness) { - if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "brightness")) { + if (m_videoSink && g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "brightness")) { g_object_set(G_OBJECT(m_videoSink), "brightness", brightness * 10, NULL); emit brightnessChanged(brightness); @@ -271,15 +283,15 @@ int QGstreamerVideoWidgetControl::contrast() const { int contrast = 0; - if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "contrast")) - g_object_get(G_OBJECT(m_videoSink), "contrast", &contrast, NULL); + if (m_videoSink && g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "contrast")) + g_object_get(G_OBJECT(m_videoSink), "contrast", &contrast, NULL); return contrast / 10; } void QGstreamerVideoWidgetControl::setContrast(int contrast) { - if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "contrast")) { + if (m_videoSink && g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "contrast")) { g_object_set(G_OBJECT(m_videoSink), "contrast", contrast * 10, NULL); emit contrastChanged(contrast); @@ -290,7 +302,7 @@ int QGstreamerVideoWidgetControl::hue() const { int hue = 0; - if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "hue")) + if (m_videoSink && g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "hue")) g_object_get(G_OBJECT(m_videoSink), "hue", &hue, NULL); return hue / 10; @@ -298,7 +310,7 @@ int QGstreamerVideoWidgetControl::hue() const void QGstreamerVideoWidgetControl::setHue(int hue) { - if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "hue")) { + if (m_videoSink && g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "hue")) { g_object_set(G_OBJECT(m_videoSink), "hue", hue * 10, NULL); emit hueChanged(hue); @@ -309,7 +321,7 @@ int QGstreamerVideoWidgetControl::saturation() const { int saturation = 0; - if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "saturation")) + if (m_videoSink && g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "saturation")) g_object_get(G_OBJECT(m_videoSink), "saturation", &saturation, NULL); return saturation / 10; @@ -317,7 +329,7 @@ int QGstreamerVideoWidgetControl::saturation() const void QGstreamerVideoWidgetControl::setSaturation(int saturation) { - if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "saturation")) { + if (m_videoSink && g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "saturation")) { g_object_set(G_OBJECT(m_videoSink), "saturation", saturation * 10, NULL); emit saturationChanged(saturation); diff --git a/src/plugins/mediaservices/gstreamer/qgstreamervideowidget.h b/src/plugins/mediaservices/gstreamer/qgstreamervideowidget.h index 7b966b7..6a4c0f3 100644 --- a/src/plugins/mediaservices/gstreamer/qgstreamervideowidget.h +++ b/src/plugins/mediaservices/gstreamer/qgstreamervideowidget.h @@ -93,6 +93,7 @@ public slots: void updateNativeVideoSize(); private: + void createVideoWidget(); void windowExposed(); GstElement *m_videoSink; -- cgit v0.12 From 960ff0590e99b28bc72d3aa104794bfa13eda2e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Wed, 10 Mar 2010 12:58:33 +0100 Subject: Compile with Qt3Support in a ScratchBox environment. Reviewed-by: Tom Cooksey --- src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 2b5f2f4..5f0d920 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -64,6 +64,7 @@ // #define QT_OPENGL_CACHE_AS_VBOS +#include "qglgradientcache_p.h" #include "qpaintengineex_opengl2_p.h" #include //for memcpy @@ -80,7 +81,6 @@ #include #include -#include "qglgradientcache_p.h" #include "qglengineshadermanager_p.h" #include "qgl2pexvertexarray_p.h" #include "qtriangulatingstroker_p.h" -- cgit v0.12 From 9bba92715d96939e4d36c6ea42e8b466756bf891 Mon Sep 17 00:00:00 2001 From: Alexader Karaivanov Date: Wed, 10 Mar 2010 12:42:39 +0100 Subject: Fixes Q3ListViewItem grandchildren not sorted if item has one child Q3ListViewItem::sortChildItems() used to exits early if there is only 1 child item and leaves grandchildren unsorted. Merge-request: 2260 Reviewed-by: Olivier Goffart --- src/qt3support/itemviews/q3listview.cpp | 9 ++- tests/auto/q3listview/tst_q3listview.cpp | 126 ++++++++++++++++++++++++++++++- 2 files changed, 133 insertions(+), 2 deletions(-) diff --git a/src/qt3support/itemviews/q3listview.cpp b/src/qt3support/itemviews/q3listview.cpp index 12dad84..4900827 100644 --- a/src/qt3support/itemviews/q3listview.cpp +++ b/src/qt3support/itemviews/q3listview.cpp @@ -1324,8 +1324,15 @@ void Q3ListViewItem::sortChildItems(int column, bool ascending) const int nColumns = (listView() ? listView()->columns() : 0); // and don't sort if we already have the right sorting order - if (column > nColumns || childItem == 0 || childItem->siblingItem == 0) + if (column > nColumns || childItem == 0) return; + + // If there is just one child, just sort its children + if (childItem->siblingItem == 0) { + if (childItem->isOpen()) + childItem->sortChildItems(column, ascending); + return; + } // make an array for qHeapSort() Q3ListViewPrivate::SortableItem * siblings diff --git a/tests/auto/q3listview/tst_q3listview.cpp b/tests/auto/q3listview/tst_q3listview.cpp index 4de6f95..56fa25f 100644 --- a/tests/auto/q3listview/tst_q3listview.cpp +++ b/tests/auto/q3listview/tst_q3listview.cpp @@ -39,6 +39,7 @@ ** ****************************************************************************/ +#include #include @@ -87,6 +88,8 @@ public slots: private slots: void getSetCheck(); void sortchild(); + void sortchild2(); // item -> item -> 3 items + void sortchild3(); // item -> 3 items void takeItem_data(); void takeItem(); void selections_mouseClick_data(); @@ -262,7 +265,7 @@ void tst_Q3ListView::sortchild() QVERIFY( item == item1 ); listview->setSorting( 0, FALSE ); - + item = listview->firstChild(); QVERIFY( item == item1 ); item = item->itemBelow(); @@ -291,6 +294,127 @@ void tst_Q3ListView::sortchild() delete listview; } +void tst_Q3ListView::sortchild2() +{ + Q3ListView* listview = new Q3ListView( 0 ); + + listview->addColumn( "" ); + + Q3ListViewItem* item1 = new Q3ListViewItem( listview, "zzz" ); + Q3ListViewItem* item2 = new Q3ListViewItem( listview, "hhh" ); + Q3ListViewItem* item3 = new Q3ListViewItem( listview, "bbb" ); + Q3ListViewItem* item4 = new Q3ListViewItem( listview, "jjj" ); + Q3ListViewItem* item5 = new Q3ListViewItem( listview, "ddd" ); + Q3ListViewItem* item6 = new Q3ListViewItem( listview, "lll" ); + + Q3ListViewItem* item31 = new Q3ListViewItem( item3, "bbb-level2" ); + + Q3ListViewItem* item31b = new Q3ListViewItem( item31, "234" ); + Q3ListViewItem* item31c = new Q3ListViewItem( item31, "345" ); + Q3ListViewItem* item31a = new Q3ListViewItem( item31, "123" ); + + listview->setOpen( item3, TRUE ); + listview->setOpen( item31, TRUE ); + + listview->setSorting( 0, TRUE ); + listview->show(); + + Q3ListViewItem *item = listview->firstChild(); + QVERIFY( item == item3 ); + item = item->itemBelow(); + QVERIFY( item == item31 ); + item = item->itemBelow(); + QVERIFY( item == item31a ); + item = item->itemBelow(); + QVERIFY( item == item31b ); + item = item->itemBelow(); + QVERIFY( item == item31c ); + item = item->itemBelow(); + QVERIFY( item == item5 ); + item = item->itemBelow(); + QVERIFY( item == item2 ); + item = item->itemBelow(); + QVERIFY( item == item4 ); + item = item->itemBelow(); + QVERIFY( item == item6 ); + item = item->itemBelow(); + QVERIFY( item == item1 ); + + listview->setSorting( 0, FALSE ); + + item = listview->firstChild(); + QVERIFY( item == item1 ); + item = item->itemBelow(); + QVERIFY( item == item6 ); + item = item->itemBelow(); + QVERIFY( item == item4 ); + item = item->itemBelow(); + QVERIFY( item == item2 ); + item = item->itemBelow(); + QVERIFY( item == item5 ); + item = item->itemBelow(); + QVERIFY( item == item3 ); + item = item->itemBelow(); + QVERIFY( item == item31 ); + item = item->itemBelow(); + QVERIFY( item == item31c ); + item = item->itemBelow(); + QVERIFY( item == item31b ); + item = item->itemBelow(); + QVERIFY( item == item31a ); + + item = listview->firstChild(); + item->moveItem( item->itemBelow() ); + + listview->setSorting( 0, FALSE ); + QVERIFY( item == listview->firstChild() ); + + delete listview; +} + +void tst_Q3ListView::sortchild3() +{ + Q3ListView* listview = new Q3ListView( 0 ); + + listview->addColumn( "" ); + + Q3ListViewItem* item3 = new Q3ListViewItem( listview, "bbb" ); + + + Q3ListViewItem* item31b = new Q3ListViewItem( item3, "234" ); + Q3ListViewItem* item31c = new Q3ListViewItem( item3, "345" ); + Q3ListViewItem* item31a = new Q3ListViewItem( item3, "123" ); + + listview->setOpen( item3, TRUE ); + + listview->setSorting( 0, TRUE ); + listview->show(); + + Q3ListViewItem *item = listview->firstChild(); + QVERIFY( item == item3 ); + item = item->itemBelow(); + QVERIFY( item == item31a ); + item = item->itemBelow(); + QVERIFY( item == item31b ); + item = item->itemBelow(); + QVERIFY( item == item31c ); + item = item->itemBelow(); + + listview->setSorting( 0, FALSE ); + + item = listview->firstChild(); + QVERIFY( item == item3 ); + item = item->itemBelow(); + QVERIFY( item == item31c ); + item = item->itemBelow(); + QVERIFY( item == item31b ); + item = item->itemBelow(); + QVERIFY( item == item31a ); + + delete listview; +} + + void tst_Q3ListView::takeItem_data() { QTest::addColumn("selectionMode"); -- cgit v0.12 From 01a045084ad45da37e6b79938354c82419c0a83e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Wed, 10 Mar 2010 13:34:51 +0100 Subject: Added configure check to diasable building QtDeclarative when Qt is not building the QtScript module --- configure | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/configure b/configure index 71056b6..60bcc67 100755 --- a/configure +++ b/configure @@ -5962,19 +5962,6 @@ if [ "$CFG_NETWORKMANAGER" = "auto" ]; then fi fi -if [ -f "$relpath/src/declarative/declarative.pro" ]; then - if [ "$CFG_DECLARATIVE" = "auto" ]; then - CFG_DECLARATIVE=yes - fi -else - if [ "$CFG_DECLARATIVE" = "auto" ] || [ "$CFG_DECLARATIVE" = "no" ]; then - CFG_DECLARATIVE=no - else - echo "Error: Unable to locate the qt-declarative package. Refer to the documentation on how to build the package." - exit 1 - fi -fi - if [ "$CFG_JAVASCRIPTCORE_JIT" = "yes" ] || [ "$CFG_JAVASCRIPTCORE_JIT" = "auto" ]; then if [ "$CFG_ARCH" = "arm" ] || [ "$CFG_ARCH" = "armv6" ]; then "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/javascriptcore-jit "javascriptcore-jit" $L_FLAGS $I_FLAGS $l_FLAGS @@ -6629,12 +6616,6 @@ else QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_SVG" fi -if [ "$CFG_DECLARATIVE" = "yes" ]; then - QT_CONFIG="$QT_CONFIG declarative" -else - QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_DECLARATIVE" -fi - if [ "$CFG_WEBKIT" = "auto" ]; then CFG_WEBKIT="$canBuildWebKit" fi @@ -6674,6 +6655,27 @@ else QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_SCRIPTTOOLS" fi + +if [ "$CFG_DECLARATIVE" = "yes" ]; then + if [ "$CFG_SCRIPT" = "no" ]; then + echo "Error: QtDeclarative was requested, but it can't be built due to QtScript being disabled." + exit 1 + fi +fi +if [ "$CFG_DECLARATIVE" = "auto" ]; then + if [ "$CFG_SCRIPT" = "no" ]; then + CFG_DECLARATIVE=no + else + CFG_DECLARATIVE=yes + fi +fi + +if [ "$CFG_DECLARATIVE" = "yes" ]; then + QT_CONFIG="$QT_CONFIG declarative" +else + QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_DECLARATIVE" +fi + if [ "$CFG_EXCEPTIONS" = "no" ]; then case "$COMPILER" in g++*) -- cgit v0.12 From ef9e7168a8ed3e8149204cf6c604a38db35245c0 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 10 Mar 2010 14:44:37 +0100 Subject: Cocoa: Fix misaligned text between format changes This reverts part of commit e008504b5ec34975e34adf3b1a2b7170d0e4dd38. The original commit aimed to round up all fractional numbers for the font to "improve appearance". Rounding up the last advance of a set of advances in a glyph layout, however, breaks text layout completely, since the layout of text will be different depending on how many text lines is used to represent it (since the last glyph in each line will have a higher advance than the others.) This was e.g. visible in Qt Creator when turning on whitespace visualization, as all spaces then created a format change, thus a new text line in the text layout, and hence an increase of X pixels in the positioning of the text after the space, where 0.0 < X < 1.0. I see no negative results of removing the rounding, but if there are any problems, it has to be fixed in the usage of the advances not in the advances themselves. Task-number: QTCREATORBUG-381, QTBUG-8791 Reviewed-by: mae --- src/gui/text/qfontengine_mac.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm index 48bc635..8588214 100644 --- a/src/gui/text/qfontengine_mac.mm +++ b/src/gui/text/qfontengine_mac.mm @@ -308,7 +308,7 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay CTFontGetAdvancesForGlyphs(runFont, kCTFontHorizontalOrientation, tmpGlyphs + glyphCount - 1, &lastGlyphAdvance, 1); outGlyphs[rtl ? 0 : (glyphCount - 1)] = tmpGlyphs[glyphCount - 1] | fontIndex; - outAdvances_x[rtl ? 0 : (glyphCount - 1)] = QFixed::fromReal(lastGlyphAdvance.width).ceil(); + outAdvances_x[rtl ? 0 : (glyphCount - 1)] = QFixed::fromReal(lastGlyphAdvance.width); } outGlyphs += glyphCount; outAttributes += glyphCount; -- cgit v0.12 From c94db224c6abb8ed9e214bb96a14b69eb1c557ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Wed, 10 Mar 2010 15:22:21 +0100 Subject: Compile fix when Qt3Support is enabled for devices using EGL. Reviewed-by: Samuel --- src/opengl/gl2paintengineex/qglgradientcache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opengl/gl2paintengineex/qglgradientcache.cpp b/src/opengl/gl2paintengineex/qglgradientcache.cpp index 192e01c..a1495dd 100644 --- a/src/opengl/gl2paintengineex/qglgradientcache.cpp +++ b/src/opengl/gl2paintengineex/qglgradientcache.cpp @@ -39,10 +39,10 @@ ** ****************************************************************************/ +#include "qglgradientcache_p.h" #include #include -#include "qglgradientcache_p.h" QT_BEGIN_NAMESPACE -- cgit v0.12 From 7ddf13c8fba2aadf00c0d6c822c6b4acbd3bd54f Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Wed, 10 Mar 2010 13:34:52 +0100 Subject: Make calls to QGLFormat::set*BufferSize also update flags Reviewed-By: Trond --- src/opengl/qgl.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 73cd6a8..7839191 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -766,6 +766,7 @@ void QGLFormat::setSamples(int numSamples) return; } d->numSamples = numSamples; + setSampleBuffers(numSamples > 0); } /*! @@ -904,6 +905,7 @@ void QGLFormat::setDepthBufferSize(int size) return; } d->depthSize = size; + setDepth(size > 0); } /*! @@ -1017,7 +1019,7 @@ void QGLFormat::setAlphaBufferSize(int size) return; } d->alphaSize = size; - setOption(QGL::AlphaChannel); + setAlpha(size > 0); } /*! @@ -1044,6 +1046,7 @@ void QGLFormat::setAccumBufferSize(int size) return; } d->accumSize = size; + setAccum(size > 0); } /*! @@ -1069,6 +1072,7 @@ void QGLFormat::setStencilBufferSize(int size) return; } d->stencilSize = size; + setStencil(size > 0); } /*! -- cgit v0.12 From 9bf426a2af27ad5bfdb35706c3ed48e77f654f4d Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Wed, 10 Mar 2010 14:50:59 +0100 Subject: Update QGLFormat from EGLConfig properly Previously, some members of QGLFormat (like alphaBufferSize) would be left to the initial -1 value. Reviewed-By: TrustMe --- src/opengl/qgl_egl.cpp | 70 ++++++++++++++++++--------------------- src/opengl/qgl_egl_p.h | 2 +- src/opengl/qgl_qws.cpp | 2 +- src/opengl/qgl_wince.cpp | 2 +- src/opengl/qgl_x11egl.cpp | 5 ++- src/opengl/qglpixelbuffer_egl.cpp | 2 +- 6 files changed, 38 insertions(+), 45 deletions(-) diff --git a/src/opengl/qgl_egl.cpp b/src/opengl/qgl_egl.cpp index 3d146b7..c08d6fd 100644 --- a/src/opengl/qgl_egl.cpp +++ b/src/opengl/qgl_egl.cpp @@ -111,46 +111,40 @@ void qt_eglproperties_set_glformat(QEglProperties& eglProperties, const QGLForma eglProperties.setValue(EGL_SAMPLE_BUFFERS, sampleCount ? 1 : 0); } - // Updates "format" with the parameters of the selected configuration. -void qt_egl_update_format(const QEglContext& context, QGLFormat& format) +void qt_glformat_from_eglconfig(QGLFormat& format, const EGLConfig config) { - EGLint value = 0; - - if (context.configAttrib(EGL_RED_SIZE, &value)) - format.setRedBufferSize(value); - if (context.configAttrib(EGL_GREEN_SIZE, &value)) - format.setGreenBufferSize(value); - if (context.configAttrib(EGL_BLUE_SIZE, &value)) - format.setBlueBufferSize(value); - if (context.configAttrib(EGL_ALPHA_SIZE, &value)) { - format.setAlpha(value != 0); - if (format.alpha()) - format.setAlphaBufferSize(value); - } - - if (context.configAttrib(EGL_DEPTH_SIZE, &value)) { - format.setDepth(value != 0); - if (format.depth()) - format.setDepthBufferSize(value); - } - - if (context.configAttrib(EGL_LEVEL, &value)) - format.setPlane(value); - - if (context.configAttrib(EGL_SAMPLE_BUFFERS, &value)) { - format.setSampleBuffers(value != 0); - if (format.sampleBuffers()) { - context.configAttrib(EGL_SAMPLES, &value); - format.setSamples(value); - } - } - - if (context.configAttrib(EGL_STENCIL_SIZE, &value)) { - format.setStencil(value != 0); - if (format.stencil()) - format.setStencilBufferSize(value); - } + EGLint redSize = 0; + EGLint greenSize = 0; + EGLint blueSize = 0; + EGLint alphaSize = 0; + EGLint depthSize = 0; + EGLint stencilSize = 0; + EGLint sampleCount = 0; + EGLint level = 0; + + EGLDisplay display = QEgl::display(); + eglGetConfigAttrib(display, config, EGL_RED_SIZE, &redSize); + eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &greenSize); + eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &blueSize); + eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &alphaSize); + eglGetConfigAttrib(display, config, EGL_DEPTH_SIZE, &depthSize); + eglGetConfigAttrib(display, config, EGL_STENCIL_SIZE, &stencilSize); + eglGetConfigAttrib(display, config, EGL_SAMPLES, &sampleCount); + eglGetConfigAttrib(display, config, EGL_LEVEL, &level); + + format.setRedBufferSize(redSize); + format.setGreenBufferSize(greenSize); + format.setBlueBufferSize(blueSize); + format.setAlphaBufferSize(alphaSize); + format.setDepthBufferSize(depthSize); + format.setStencilBufferSize(stencilSize); + format.setSamples(sampleCount); + format.setPlane(level + 1); // EGL calls level 0 "normal" whereas Qt calls 1 "normal" + format.setDirectRendering(true); // All EGL contexts are direct-rendered + 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 // Clear the EGL error state because some of the above may // have errored out because the attribute is not applicable diff --git a/src/opengl/qgl_egl_p.h b/src/opengl/qgl_egl_p.h index 6b65227..43793cd 100644 --- a/src/opengl/qgl_egl_p.h +++ b/src/opengl/qgl_egl_p.h @@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE class QGLFormat; void qt_eglproperties_set_glformat(QEglProperties& props, const QGLFormat& format); -void qt_egl_update_format(const QEglContext& context, QGLFormat& format); +void qt_glformat_from_eglconfig(QGLFormat& format, const EGLConfig config); QT_END_NAMESPACE diff --git a/src/opengl/qgl_qws.cpp b/src/opengl/qgl_qws.cpp index f72f051..96b2454 100644 --- a/src/opengl/qgl_qws.cpp +++ b/src/opengl/qgl_qws.cpp @@ -200,7 +200,7 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) } // Inform the higher layers about the actual format properties. - qt_egl_update_format(*(d->eglContext), d->glFormat); + qt_glformat_from_eglconfig(d->glFormat, d->eglContext->config()); // Create a new context for the configuration. if (!d->eglContext->createContext diff --git a/src/opengl/qgl_wince.cpp b/src/opengl/qgl_wince.cpp index 3bf7f3a..fefcca2 100644 --- a/src/opengl/qgl_wince.cpp +++ b/src/opengl/qgl_wince.cpp @@ -163,7 +163,7 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) } // Inform the higher layers about the actual format properties. - qt_egl_update_format(*(d->eglContext), d->glFormat); + qt_glformat_from_eglconfig(d->glFormat, d->eglContext->config()); // Create a new context for the configuration. if (!d->eglContext->createContext diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp index a7c92cf..fe87c65 100644 --- a/src/opengl/qgl_x11egl.cpp +++ b/src/opengl/qgl_x11egl.cpp @@ -216,9 +216,8 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) const_cast(shareContext)->d_func()->sharing = true; } - // Inform the higher layers about the actual format properties. - qt_egl_update_format(*(d->eglContext), d->glFormat); - + // Inform the higher layers about the actual format properties + qt_glformat_from_eglconfig(d->glFormat, d->eglContext->config()); // Do don't create the EGLSurface for everything. // QWidget - yes, create the EGLSurface and store it in QGLContextPrivate::eglSurface diff --git a/src/opengl/qglpixelbuffer_egl.cpp b/src/opengl/qglpixelbuffer_egl.cpp index ee0714f..db9e754 100644 --- a/src/opengl/qglpixelbuffer_egl.cpp +++ b/src/opengl/qglpixelbuffer_egl.cpp @@ -113,7 +113,7 @@ bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidge } // Retrieve the actual format properties. - qt_egl_update_format(*ctx, format); + qt_glformat_from_eglconfig(format, ctx->config()); // Create the attributes needed for the pbuffer. QEglProperties attribs; -- cgit v0.12 From 1ceb2ec18056c41c040e3087f79860b7eb7b9d3f Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Wed, 10 Mar 2010 15:25:38 +0100 Subject: Update tst_QGL::getSetCheck to check for new (correct) behaviour Reviewed-By: Trond --- tests/auto/qgl/tst_qgl.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tests/auto/qgl/tst_qgl.cpp b/tests/auto/qgl/tst_qgl.cpp index d89e463..15c0b66 100644 --- a/tests/auto/qgl/tst_qgl.cpp +++ b/tests/auto/qgl/tst_qgl.cpp @@ -227,12 +227,12 @@ void tst_QGL::getSetCheck() QCOMPARE(false, obj1.alpha()); QVERIFY(!obj1.testOption(QGL::AlphaChannel)); QVERIFY(obj1.testOption(QGL::NoAlphaChannel)); - obj1.setAlphaBufferSize(0); + obj1.setAlphaBufferSize(1); QCOMPARE(true, obj1.alpha()); // setAlphaBufferSize() enables alpha. - QCOMPARE(0, obj1.alphaBufferSize()); + QCOMPARE(1, obj1.alphaBufferSize()); QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setAlphaBufferSize: Cannot set negative alpha buffer size -2147483648"); obj1.setAlphaBufferSize(TEST_INT_MIN); - QCOMPARE(0, obj1.alphaBufferSize()); // Makes no sense with a negative buffer size + QCOMPARE(1, obj1.alphaBufferSize()); // Makes no sense with a negative buffer size obj1.setAlphaBufferSize(3); QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setAlphaBufferSize: Cannot set negative alpha buffer size -1"); obj1.setAlphaBufferSize(-1); @@ -243,11 +243,11 @@ void tst_QGL::getSetCheck() // int QGLFormat::stencilBufferSize() // void QGLFormat::setStencilBufferSize(int) QCOMPARE(-1, obj1.stencilBufferSize()); - obj1.setStencilBufferSize(0); - QCOMPARE(0, obj1.stencilBufferSize()); + obj1.setStencilBufferSize(1); + QCOMPARE(1, obj1.stencilBufferSize()); QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setStencilBufferSize: Cannot set negative stencil buffer size -2147483648"); obj1.setStencilBufferSize(TEST_INT_MIN); - QCOMPARE(0, obj1.stencilBufferSize()); // Makes no sense with a negative buffer size + QCOMPARE(1, obj1.stencilBufferSize()); // Makes no sense with a negative buffer size obj1.setStencilBufferSize(3); QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setStencilBufferSize: Cannot set negative stencil buffer size -1"); obj1.setStencilBufferSize(-1); @@ -352,6 +352,7 @@ void tst_QGL::getSetCheck() // bool QGLFormat::accum() // void QGLFormat::setAccum(bool) + obj1.setAccumBufferSize(0); QCOMPARE(false, obj1.accum()); QVERIFY(!obj1.testOption(QGL::AccumBuffer)); QVERIFY(obj1.testOption(QGL::NoAccumBuffer)); -- cgit v0.12 From 477a3f2720710130dad88a1e8391f7eaf24ffb38 Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Wed, 10 Mar 2010 14:17:50 +0100 Subject: Fixed assert failure when drawing dashes with raster engine. Reviewed-by: Samuel --- src/gui/painting/qpaintengine_raster.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index bfcf7db..03d0825 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -1725,9 +1725,10 @@ void QRasterPaintEngine::stroke(const QVectorPath &path, const QPen &pen) if (patternLength > 0) { int n = qFloor(dashOffset / patternLength); dashOffset -= n * patternLength; - while (dashOffset > pattern.at(dashIndex)) { + while (dashOffset >= pattern.at(dashIndex)) { dashOffset -= pattern.at(dashIndex); - dashIndex = (dashIndex + 1) % pattern.size(); + if (++dashIndex >= pattern.size()) + dashIndex = 0; inDash = !inDash; } } @@ -1738,7 +1739,6 @@ void QRasterPaintEngine::stroke(const QVectorPath &path, const QPen &pen) const QLineF *lines = reinterpret_cast(path.points()); for (int i = 0; i < lineCount; ++i) { - dashOffset = s->lastPen.dashOffset(); if (lines[i].p1() == lines[i].p2()) { if (s->lastPen.capStyle() != Qt::FlatCap) { QPointF p = lines[i].p1(); @@ -3626,13 +3626,14 @@ void QRasterPaintEnginePrivate::rasterizeLine_dashed(QLineF line, } else { *dashOffset = 0; *inDash = !(*inDash); - *dashIndex = (*dashIndex + 1) % pattern.size(); + if (++*dashIndex >= pattern.size()) + *dashIndex = 0; length -= dash; l.setLength(dash); line.setP1(l.p2()); } - if (rasterize && dash != 0) + if (rasterize && dash > 0) rasterizer->rasterizeLine(l.p1(), l.p2(), width / dash, squareCap); } } -- cgit v0.12 From ee6c26115959f46621f5a45f3fbe4a49989fd095 Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Wed, 10 Mar 2010 12:51:46 +0100 Subject: Added clipping to the dashed stroke processor in the GL2 engine. Without clipping, the stroker could consume a huge amount of memory when scaling up cosmetic, dashed strokes. I also made QDashStroker clip more aggressively. Task-number: QTBUG-7832 Reviewed-by: Samuel --- src/gui/painting/qstroker.cpp | 116 +++++++++++++++++---- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 10 +- .../gl2paintengineex/qtriangulatingstroker.cpp | 5 +- .../gl2paintengineex/qtriangulatingstroker_p.h | 4 +- 4 files changed, 105 insertions(+), 30 deletions(-) diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp index 16e3c38..9740fce 100644 --- a/src/gui/painting/qstroker.cpp +++ b/src/gui/painting/qstroker.cpp @@ -1043,6 +1043,47 @@ QVector QDashStroker::patternForStyle(Qt::PenStyle style) return pattern; } +static inline bool lineRectIntersectsRect(qfixed2d p1, qfixed2d p2, const qfixed2d &tl, const qfixed2d &br) +{ + return ((p1.x > tl.x || p2.x > tl.x) && (p1.x < br.x || p2.x < br.x) + && (p1.y > tl.y || p2.y > tl.y) && (p1.y < br.y || p2.y < br.y)); +} + +// If the line intersects the rectangle, this function will return true. +static bool lineIntersectsRect(qfixed2d p1, qfixed2d p2, const qfixed2d &tl, const qfixed2d &br) +{ + if (!lineRectIntersectsRect(p1, p2, tl, br)) + return false; + if (p1.x == p2.x || p1.y == p2.y) + return true; + + if (p1.y > p2.y) + qSwap(p1, p2); // make p1 above p2 + qfixed2d u; + qfixed2d v; + qfixed2d w = {p2.x - p1.x, p2.y - p1.y}; + if (p1.x < p2.x) { + // backslash + u.x = tl.x - p1.x; u.y = br.y - p1.y; + v.x = br.x - p1.x; v.y = tl.y - p1.y; + } else { + // slash + u.x = tl.x - p1.x; u.y = tl.y - p1.y; + v.x = br.x - p1.x; v.y = br.y - p1.y; + } +#if defined(QFIXED_IS_26_6) || defined(QFIXED_IS_16_16) + qint64 val1 = qint64(u.x) * qint64(w.y) - qint64(u.y) * qint64(w.x); + qint64 val2 = qint64(v.x) * qint64(w.y) - qint64(v.y) * qint64(w.x); + return (val1 < 0 && val2 > 0) || (val1 > 0 && val2 < 0); +#elif defined(QFIXED_IS_32_32) + // Cannot do proper test because it may overflow. + return true; +#else + qreal val1 = u.x * w.y - u.y * w.x; + qreal val2 = v.x * w.y - v.y * w.x; + return (val1 < 0 && val2 > 0) || (val1 > 0 && val2 < 0); +#endif +} void QDashStroker::processCurrentSubpath() { @@ -1067,9 +1108,11 @@ void QDashStroker::processCurrentSubpath() if (qFuzzyIsNull(sumLength)) return; + qreal invSumLength = qreal(1) / sumLength; + Q_ASSERT(dashCount > 0); - dashCount = (dashCount / 2) * 2; // Round down to even number + dashCount = dashCount & -2; // Round down to even number int idash = 0; // Index to current dash qreal pos = 0; // The position on the curve, 0 <= pos <= path.length @@ -1077,11 +1120,12 @@ void QDashStroker::processCurrentSubpath() qreal doffset = m_dashOffset * m_stroke_width; // make sure doffset is in range [0..sumLength) - doffset -= qFloor(doffset / sumLength) * sumLength; + doffset -= qFloor(doffset * invSumLength) * sumLength; while (doffset >= dashes[idash]) { doffset -= dashes[idash]; - idash = (idash + 1) % dashCount; + if (++idash >= dashCount) + idash = 0; } qreal estart = 0; // The elements starting position @@ -1119,12 +1163,41 @@ void QDashStroker::processCurrentSubpath() estop = estart + elen; bool done = pos >= estop; + + if (clipping) { + // Check if the entire line can be clipped away. + if (!lineIntersectsRect(prev, e, clip_tl, clip_br)) { + // Cut away full dash sequences. + elen -= qFloor(elen * invSumLength) * sumLength; + // Update dash offset. + while (!done) { + qreal dpos = pos + dashes[idash] - doffset - estart; + + Q_ASSERT(dpos >= 0); + + if (dpos > elen) { // dash extends this line + doffset = dashes[idash] - (dpos - elen); // subtract the part already used + pos = estop; // move pos to next path element + done = true; + } else { // Dash is on this line + pos = dpos + estart; + done = pos >= estop; + if (++idash >= dashCount) + idash = 0; + doffset = 0; // full segment so no offset on next. + } + } + hasMoveTo = false; + move_to_pos = e; + } + } + // Dash away... while (!done) { QPointF p2; - int idash_incr = 0; bool has_offset = doffset > 0; + bool evenDash = (idash & 1) == 0; qreal dpos = pos + dashes[idash] - doffset - estart; Q_ASSERT(dpos >= 0); @@ -1138,39 +1211,36 @@ void QDashStroker::processCurrentSubpath() p2 = cline.pointAt(dpos/elen); pos = dpos + estart; done = pos >= estop; - idash_incr = 1; + if (++idash >= dashCount) + idash = 0; doffset = 0; // full segment so no offset on next. } - if (idash % 2 == 0) { + if (evenDash) { line_to_pos.x = qt_real_to_fixed(p2.x()); line_to_pos.y = qt_real_to_fixed(p2.y()); - // If we have an offset, we're continuing a dash - // from a previous element and should only - // continue the current dash, without starting a - // new subpath. - if (!has_offset || !hasMoveTo) { - emitMoveTo(move_to_pos.x, move_to_pos.y); - hasMoveTo = true; - } - if (!clipping - // if move_to is inside... - || (move_to_pos.x > clip_tl.x && move_to_pos.x < clip_br.x - && move_to_pos.y > clip_tl.y && move_to_pos.y < clip_br.y) - // Or if line_to is inside... - || (line_to_pos.x > clip_tl.x && line_to_pos.x < clip_br.x - && line_to_pos.y > clip_tl.y && line_to_pos.y < clip_br.y)) + || lineRectIntersectsRect(move_to_pos, line_to_pos, clip_tl, clip_br)) { + // If we have an offset, we're continuing a dash + // from a previous element and should only + // continue the current dash, without starting a + // new subpath. + if (!has_offset || !hasMoveTo) { + emitMoveTo(move_to_pos.x, move_to_pos.y); + hasMoveTo = true; + } + emitLineTo(line_to_pos.x, line_to_pos.y); + } else { + hasMoveTo = false; } + move_to_pos = line_to_pos; } else { move_to_pos.x = qt_real_to_fixed(p2.x()); move_to_pos.y = qt_real_to_fixed(p2.y()); } - - idash = (idash + idash_incr) % dashCount; } // Shuffle to the next cycle... diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 5f0d920..d68a268 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1155,16 +1155,20 @@ void QGL2PaintEngineExPrivate::stroke(const QVectorPath &path, const QPen &pen) // prepareForDraw() down below. updateMatrix(); + QRectF clip = q->state()->matrix.inverted().mapRect(q->state()->clipEnabled + ? q->state()->rectangleClip + : QRectF(0, 0, width, height)); + if (penStyle == Qt::SolidLine) { - stroker.process(path, pen); + stroker.process(path, pen, clip); } else { // Some sort of dash - dasher.process(path, pen); + dasher.process(path, pen, clip); QVectorPath dashStroke(dasher.points(), dasher.elementCount(), dasher.elementTypes()); - stroker.process(dashStroke, pen); + stroker.process(dashStroke, pen, clip); } if (opaque) { diff --git a/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp b/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp index 5229d3f..d952988 100644 --- a/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp +++ b/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp @@ -73,7 +73,7 @@ void QTriangulatingStroker::endCapOrJoinClosed(const qreal *start, const qreal * } -void QTriangulatingStroker::process(const QVectorPath &path, const QPen &pen) +void QTriangulatingStroker::process(const QVectorPath &path, const QPen &pen, const QRectF &) { const qreal *pts = path.points(); const QPainterPath::ElementType *types = path.elements(); @@ -480,7 +480,7 @@ QDashedStrokeProcessor::QDashedStrokeProcessor() m_dash_stroker.setCubicToHook(qdashprocessor_cubicTo); } -void QDashedStrokeProcessor::process(const QVectorPath &path, const QPen &pen) +void QDashedStrokeProcessor::process(const QVectorPath &path, const QPen &pen, const QRectF &clip) { const qreal *pts = path.points(); @@ -497,6 +497,7 @@ void QDashedStrokeProcessor::process(const QVectorPath &path, const QPen &pen) m_dash_stroker.setDashPattern(pen.dashPattern()); m_dash_stroker.setStrokeWidth(pen.isCosmetic() ? width * m_inv_scale : width); m_dash_stroker.setMiterLimit(pen.miterLimit()); + m_dash_stroker.setClipRect(clip); qreal curvyness = sqrt(width) * m_inv_scale / 8; if (count < 2) diff --git a/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h b/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h index 06b8a44..956d7cc 100644 --- a/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h +++ b/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h @@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE class QTriangulatingStroker { public: - void process(const QVectorPath &path, const QPen &pen); + void process(const QVectorPath &path, const QPen &pen, const QRectF &clip); inline int vertexCount() const { return m_vertices.size(); } inline const float *vertices() const { return m_vertices.data(); } @@ -96,7 +96,7 @@ class QDashedStrokeProcessor public: QDashedStrokeProcessor(); - void process(const QVectorPath &path, const QPen &pen); + void process(const QVectorPath &path, const QPen &pen, const QRectF &clip); inline void addElement(QPainterPath::ElementType type, qreal x, qreal y) { m_points.add(x); -- cgit v0.12 From 9b016ce33e4d63725239945a2fcf19a8d6af14cf Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Wed, 10 Mar 2010 15:55:23 +0100 Subject: Re-enable tst_QGL::glWidgetRenderPixmap on X11/EGL QGLWidget::renderPixmap now works under X11/EGL. Tested on both Fremantle and Harmattan. Reviewed-By: TrustMe --- tests/auto/qgl/tst_qgl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/qgl/tst_qgl.cpp b/tests/auto/qgl/tst_qgl.cpp index 15c0b66..8ee494f 100644 --- a/tests/auto/qgl/tst_qgl.cpp +++ b/tests/auto/qgl/tst_qgl.cpp @@ -1402,8 +1402,8 @@ void tst_QGL::glWidgetRenderPixmap() QImage reference(fb.size(), QImage::Format_RGB32); reference.fill(0xffff0000); -#ifdef QGL_EGL - QSKIP("renderPixmap() not yet supported under EGL", SkipAll); +#if defined(QGL_EGL) && !defined(Q_WS_X11) + QSKIP("renderPixmap() not yet supported under EGL on your platform", SkipAll); #endif QFUZZY_COMPARE_IMAGES(fb, reference); -- cgit v0.12 From 1436c4f2e41100b45eed58edc5fc290fa94c976b Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Wed, 10 Mar 2010 17:11:47 +0100 Subject: Fixed "inconsistent dll linkage" warning on Windows. qt_memrotate90() was declared twice, once with and once without Q_GUI_EXPORT. Reviewed-by: Trond --- src/gui/painting/qmemrotate_p.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/painting/qmemrotate_p.h b/src/gui/painting/qmemrotate_p.h index 8df0520..2911860 100644 --- a/src/gui/painting/qmemrotate_p.h +++ b/src/gui/painting/qmemrotate_p.h @@ -82,8 +82,9 @@ QT_BEGIN_NAMESPACE void Q_GUI_QWS_EXPORT qt_memrotate270(const srctype*, int, int, int, desttype*, int) void Q_GUI_EXPORT qt_memrotate90(const quint32*, int, int, int, quint32*, int); +void Q_GUI_QWS_EXPORT qt_memrotate180(const quint32*, int, int, int, quint32*, int); +void Q_GUI_QWS_EXPORT qt_memrotate270(const quint32*, int, int, int, quint32*, int); -QT_DECL_MEMROTATE(quint32, quint32); QT_DECL_MEMROTATE(quint32, quint16); QT_DECL_MEMROTATE(quint16, quint32); QT_DECL_MEMROTATE(quint16, quint16); -- cgit v0.12 From 7baaea978200c82fdf65e3934cfa373edeca6524 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Wed, 10 Mar 2010 16:53:06 +0100 Subject: Slow QTreeView::layout() with many (> 10000) children When updating the QTreeViewItem::total field in layout(), we used to call QTreeViewPrivate::viewIndex() to get the parent item, which is O(n). We have now introduced 'parentItem' in QTreeViewItem wich makes this O(1), with a small penality when inserting and removing elements in QTreeViewPrivate::viewItems. The QTreeViewPrivate::checkViewItems() is left inside the code for further debugging. Reviewed-by: Olivier Task-number: QTBUG-8885 --- src/gui/itemviews/qtreeview.cpp | 57 +++++++++++++++++++++++++++++++---------- src/gui/itemviews/qtreeview_p.h | 9 ++++++- 2 files changed, 51 insertions(+), 15 deletions(-) diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index 78184a9..2d9f9c6 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -2480,6 +2480,7 @@ void QTreeView::rowsInserted(const QModelIndex &parent, int start, int end) for (int i = 0; i < delta; ++i) { QTreeViewItem &item = insertedItems[i]; item.index = d->model->index(i + start, 0, parent); + item.parentItem = parentItem; item.level = childLevel; item.hasChildren = d->hasVisibleChildren(item.index); item.hasMoreSiblings = !((i == delta - 1) && (parentRowCount == end +1)); @@ -2518,7 +2519,7 @@ void QTreeView::rowsInserted(const QModelIndex &parent, int start, int end) } } - d->viewItems.insert(insertPos, delta, insertedItems.at(0)); + d->insertViewItems(insertPos, delta, insertedItems.at(0)); if (delta > 1) { qCopy(insertedItems.begin() + 1, insertedItems.end(), d->viewItems.begin() + insertPos + 1); @@ -2952,6 +2953,37 @@ void QTreeViewPrivate::expand(int item, bool emitSignal) } } +void QTreeViewPrivate::insertViewItems(int pos, int count, const QTreeViewItem &viewItem) +{ + viewItems.insert(pos, count, viewItem); + for (int i = pos + count; i < viewItems.count(); i++) + if (viewItems[i].parentItem >= pos) + viewItems[i].parentItem += count; +} + +void QTreeViewPrivate::removeViewItems(int pos, int count) +{ + viewItems.remove(pos, count); + for (int i = pos; i < viewItems.count(); i++) + if (viewItems[i].parentItem >= pos) + viewItems[i].parentItem -= count; +} + +#if 0 +bool QTreeViewPrivate::checkViewItems() const +{ + for (int i = 0; i < viewItems.count(); ++i) { + const QTreeViewItem &vi = viewItems.at(i); + if (vi.parentItem == -1) { + Q_ASSERT(!vi.index.parent().isValid() || vi.index.parent() == root); + } else { + Q_ASSERT(vi.index.parent() == viewItems.at(vi.parentItem).index); + } + } + return true; +} +#endif + void QTreeViewPrivate::collapse(int item, bool emitSignal) { Q_Q(QTreeView); @@ -2980,14 +3012,11 @@ void QTreeViewPrivate::collapse(int item, bool emitSignal) expandedIndexes.erase(it); viewItems[item].expanded = false; int index = item; - QModelIndex parent = modelIndex; - while (parent.isValid() && parent != root) { - Q_ASSERT(index > -1); + while (index > -1) { viewItems[index].total -= total; - parent = parent.parent(); - index = viewIndex(parent); + index = viewItems[index].parentItem; } - viewItems.remove(item + 1, total); // collapse + removeViewItems(item + 1, total); // collapse q->setState(oldState); if (emitSignal) { @@ -3152,7 +3181,7 @@ void QTreeViewPrivate::layout(int i) } viewItems.resize(count); } else if (viewItems[i].total != (uint)count) { - viewItems.insert(i + 1, count, QTreeViewItem()); // expand + insertViewItems(i + 1, count, QTreeViewItem()); // expand } else { expanding = false; } @@ -3174,6 +3203,7 @@ void QTreeViewPrivate::layout(int i) item->hasMoreSiblings = true; item = &viewItems[last]; item->index = current; + item->parentItem = i; item->level = level; item->height = 0; item->spanning = q->isFirstColumnSpanned(current.row(), parent); @@ -3195,16 +3225,14 @@ void QTreeViewPrivate::layout(int i) // remove hidden items if (hidden > 0) - viewItems.remove(last + 1, hidden); // collapse + removeViewItems(last + 1, hidden); // collapse if (!expanding) return; // nothing changed - while (parent != root) { - Q_ASSERT(i > -1); + while (i > -1) { viewItems[i].total += count - hidden; - parent = parent.parent(); - i = viewIndex(parent); + i = viewItems[i].parentItem; } } @@ -3757,7 +3785,7 @@ void QTreeViewPrivate::rowsRemoved(const QModelIndex &parent, item += count; } else if (modelIndex.row() <= end) { // removed - viewItems.remove(item, count); + removeViewItems(item, count); removedCount += count; lastChildItem -= count; } else { @@ -3765,6 +3793,7 @@ void QTreeViewPrivate::rowsRemoved(const QModelIndex &parent, // moved; update the model index viewItems[item].index = model->index( modelIndex.row() - delta, modelIndex.column(), parent); +// viewItems[item].parentItem = parentItem; } item += count; } diff --git a/src/gui/itemviews/qtreeview_p.h b/src/gui/itemviews/qtreeview_p.h index 589a224..7893e04 100644 --- a/src/gui/itemviews/qtreeview_p.h +++ b/src/gui/itemviews/qtreeview_p.h @@ -62,9 +62,10 @@ QT_BEGIN_NAMESPACE struct QTreeViewItem { - QTreeViewItem() : expanded(false), spanning(false), hasChildren(false), + QTreeViewItem() : parentItem(-1), expanded(false), spanning(false), hasChildren(false), hasMoreSiblings(false), total(0), level(0), height(0) {} QModelIndex index; // we remove items whenever the indexes are invalidated + int parentItem; // parent item index in viewItems uint expanded : 1; uint spanning : 1; uint hasChildren : 1; // if the item has visible children (even if collapsed) @@ -136,6 +137,12 @@ public: int viewIndex(const QModelIndex &index) const; QModelIndex modelIndex(int i, int column = 0) const; + void insertViewItems(int pos, int count, const QTreeViewItem &viewItem); + void removeViewItems(int pos, int count); +#if 0 + bool checkViewItems() const; +#endif + int firstVisibleItem(int *offset = 0) const; int columnAt(int x) const; bool hasVisibleChildren( const QModelIndex& parent) const; -- cgit v0.12 From fb27eba721b41cb1b8557ffff663f9747a3922db Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Thu, 11 Mar 2010 10:18:59 +0100 Subject: Fixed rounded SVG rectangles when 'rx' or 'ry' is 0. Task-number: QTBUG-8264 Reviewed-by: Trond --- src/svg/qsvghandler.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp index 926b04d..bc4ca76 100644 --- a/src/svg/qsvghandler.cpp +++ b/src/svg/qsvghandler.cpp @@ -2962,9 +2962,9 @@ static QSvgNode *createRectNode(QSvgNode *parent, if (nry > bounds.height()/2) nry = bounds.height()/2; - if (nrx && !nry) + if (!rx.isEmpty() && ry.isEmpty()) nry = nrx; - else if (nry && !nrx) + else if (!ry.isEmpty() && rx.isEmpty()) nrx = nry; //we draw rounded rect from 0...99 -- cgit v0.12 From e788b32e7f059b0f85ca5104279c8f2bcbfff526 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Thu, 11 Mar 2010 10:33:02 +0100 Subject: Cleaning commit 7baaea978200c82fdf65e3934cfa373edeca6524 Reviewed-by: Trust me --- src/gui/itemviews/qtreeview.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index 2d9f9c6..b7a39b1 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -3793,7 +3793,6 @@ void QTreeViewPrivate::rowsRemoved(const QModelIndex &parent, // moved; update the model index viewItems[item].index = model->index( modelIndex.row() - delta, modelIndex.column(), parent); -// viewItems[item].parentItem = parentItem; } item += count; } -- cgit v0.12 From 8404d073d0a8f02d77888496986cba7c0b1b1739 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 11 Mar 2010 11:08:02 +0100 Subject: QTreeView: Optimize by avoiding calling detach QVector::operator[] calls detach. and we should avoid calling it in a loop. QVector::at() cannot be used here because we need a non const reference. Reviewed-by: Gabriel --- src/gui/itemviews/qtreeview.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index b7a39b1..0a7ffb7 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -2956,17 +2956,19 @@ void QTreeViewPrivate::expand(int item, bool emitSignal) void QTreeViewPrivate::insertViewItems(int pos, int count, const QTreeViewItem &viewItem) { viewItems.insert(pos, count, viewItem); + QTreeViewItem *items = viewItems.data(); for (int i = pos + count; i < viewItems.count(); i++) - if (viewItems[i].parentItem >= pos) - viewItems[i].parentItem += count; + if (items[i].parentItem >= pos) + items[i].parentItem += count; } void QTreeViewPrivate::removeViewItems(int pos, int count) { viewItems.remove(pos, count); + QTreeViewItem *items = viewItems.data(); for (int i = pos; i < viewItems.count(); i++) - if (viewItems[i].parentItem >= pos) - viewItems[i].parentItem -= count; + if (items[i].parentItem >= pos) + items[i].parentItem -= count; } #if 0 -- cgit v0.12 From 6e25e8b7857de7f688c673ba700384f85b4113d4 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Thu, 11 Mar 2010 11:39:37 +0100 Subject: make it possible to use sse2 with mingw All the windows callback functions need an attribute to force the alignment of the arg pointer. Reviewed-by: Benjamin Poulain --- src/3rdparty/phonon/waveout/mediaobject.cpp | 2 +- src/3rdparty/phonon/waveout/mediaobject.h | 2 +- src/activeqt/control/qaxserverbase.cpp | 6 +++--- src/corelib/global/qglobal.h | 10 ++++++++++ src/corelib/io/qprocess_win.cpp | 2 +- src/corelib/kernel/qeventdispatcher_win.cpp | 8 ++++---- src/corelib/kernel/qeventdispatcher_win_p.h | 6 +++--- src/gui/dialogs/qfiledialog_win_p.h | 2 +- src/gui/kernel/qapplication_win.cpp | 5 ++--- src/gui/kernel/qdesktopwidget_win.cpp | 4 ++-- src/gui/kernel/qkeymapper_win.cpp | 2 +- src/gui/kernel/qwidget_win.cpp | 4 ++-- src/gui/kernel/qwidget_wince.cpp | 4 ++-- src/multimedia/audio/qaudioinput_win32_p.cpp | 2 +- src/multimedia/audio/qaudiooutput_win32_p.cpp | 2 +- src/multimedia/audio/qaudiooutput_win32_p.h | 2 +- src/qt3support/other/q3process_win.cpp | 2 +- 17 files changed, 37 insertions(+), 28 deletions(-) diff --git a/src/3rdparty/phonon/waveout/mediaobject.cpp b/src/3rdparty/phonon/waveout/mediaobject.cpp index 08af4ee..fdd81a7 100644 --- a/src/3rdparty/phonon/waveout/mediaobject.cpp +++ b/src/3rdparty/phonon/waveout/mediaobject.cpp @@ -70,7 +70,7 @@ namespace Phonon } - void CALLBACK MediaObject::WaveOutCallBack(HWAVEOUT m_hWaveOut, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2) + void QT_WIN_CALLBACK MediaObject::WaveOutCallBack(HWAVEOUT m_hWaveOut, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2) { Q_UNUSED(m_hWaveOut); Q_UNUSED(dwInstance); diff --git a/src/3rdparty/phonon/waveout/mediaobject.h b/src/3rdparty/phonon/waveout/mediaobject.h index dd6b24b..bb1410a 100644 --- a/src/3rdparty/phonon/waveout/mediaobject.h +++ b/src/3rdparty/phonon/waveout/mediaobject.h @@ -112,7 +112,7 @@ namespace Phonon void deleteValidWaveOutDevice(); void playBuffer(WAVEHDR *waveHeader); - static void CALLBACK WaveOutCallBack(HWAVEOUT hWaveOut, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2); + static void QT_WIN_CALLBACK WaveOutCallBack(HWAVEOUT hWaveOut, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2); struct { WAVEHDR *waveHeader; diff --git a/src/activeqt/control/qaxserverbase.cpp b/src/activeqt/control/qaxserverbase.cpp index ce71490..ca16b39 100644 --- a/src/activeqt/control/qaxserverbase.cpp +++ b/src/activeqt/control/qaxserverbase.cpp @@ -160,7 +160,7 @@ public: void createMenu(QMenuBar *menuBar); void removeMenu(); - static LRESULT CALLBACK ActiveXProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + static LRESULT QT_WIN_CALLBACK ActiveXProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); // Object registration with OLE void registerActiveObject(IUnknown *object); @@ -764,7 +764,7 @@ private: }; // callback for DLL server to hook into non-Qt eventloop -LRESULT CALLBACK axs_FilterProc(int nCode, WPARAM wParam, LPARAM lParam) +LRESULT QT_WIN_CALLBACK axs_FilterProc(int nCode, WPARAM wParam, LPARAM lParam) { if (qApp && !invokeCount) qApp->sendPostedEvents(); @@ -1350,7 +1350,7 @@ class HackWidget : public QWidget The semantics of \a wParam and \a lParam depend on the value of \a uMsg. */ -LRESULT CALLBACK QAxServerBase::ActiveXProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +LRESULT QT_WIN_CALLBACK QAxServerBase::ActiveXProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg == WM_CREATE) { CREATESTRUCT *cs = (CREATESTRUCT*)lParam; diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 4d48b60..6437fb7 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1064,6 +1064,16 @@ redefine to built-in booleans to make autotests work properly */ # define QT_FASTCALL #endif +//defines the type for the WNDPROC on windows +//the alignment needs to be forced for sse2 to not crash with mingw +#if defined(Q_WS_WIN) +# if defined(Q_CC_MINGW) +# define QT_WIN_CALLBACK CALLBACK __attribute__ ((force_align_arg_pointer)) +# else +# define QT_WIN_CALLBACK CALLBACK +# endif +#endif + typedef int QNoImplicitBoolCast; #if defined(QT_ARCH_ARM) || defined(QT_ARCH_ARMV6) || defined(QT_ARCH_AVR32) || (defined(QT_ARCH_MIPS) && (defined(Q_WS_QWS) || defined(Q_OS_WINCE))) || defined(QT_ARCH_SH) || defined(QT_ARCH_SH4A) diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index f3fc28e..cb25a58 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -525,7 +525,7 @@ qint64 QProcessPrivate::readFromStderr(char *data, qint64 maxlen) } -static BOOL CALLBACK qt_terminateApp(HWND hwnd, LPARAM procId) +static BOOL QT_WIN_CALLBACK qt_terminateApp(HWND hwnd, LPARAM procId) { DWORD currentProcId = 0; GetWindowThreadProcessId(hwnd, ¤tProcId); diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index 4755540..2633a7c 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -308,7 +308,7 @@ typedef MMRESULT(WINAPI *ptimeKillEvent)(UINT); static ptimeSetEvent qtimeSetEvent = 0; static ptimeKillEvent qtimeKillEvent = 0; -LRESULT CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp); +LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp); static void resolveTimerAPI() { @@ -420,7 +420,7 @@ Q_CORE_EXPORT bool winGetMessage(MSG* msg, HWND hWnd, UINT wMsgFilterMin, } // This function is called by a workerthread -void WINAPI CALLBACK qt_fast_timer_proc(uint timerId, uint /*reserved*/, DWORD_PTR user, DWORD_PTR /*reserved*/, DWORD_PTR /*reserved*/) +void WINAPI QT_WIN_CALLBACK qt_fast_timer_proc(uint timerId, uint /*reserved*/, DWORD_PTR user, DWORD_PTR /*reserved*/, DWORD_PTR /*reserved*/) { if (!timerId) // sanity check return; @@ -429,7 +429,7 @@ void WINAPI CALLBACK qt_fast_timer_proc(uint timerId, uint /*reserved*/, DWORD_P QCoreApplication::postEvent(t->dispatcher, new QTimerEvent(t->timerId)); } -LRESULT CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp) +LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp) { if (message == WM_NCCREATE) return true; @@ -506,7 +506,7 @@ LRESULT CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp) return DefWindowProc(hwnd, message, wp, lp); } -LRESULT CALLBACK qt_GetMessageHook(int code, WPARAM wp, LPARAM lp) +LRESULT QT_WIN_CALLBACK qt_GetMessageHook(int code, WPARAM wp, LPARAM lp) { if (wp == PM_REMOVE) { QEventDispatcherWin32 *q = qobject_cast(QAbstractEventDispatcher::instance()); diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h index ed94c49..788cc44 100644 --- a/src/corelib/kernel/qeventdispatcher_win_p.h +++ b/src/corelib/kernel/qeventdispatcher_win_p.h @@ -62,7 +62,7 @@ class QWinEventNotifier; class QEventDispatcherWin32Private; // forward declaration -LRESULT CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp); +LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp); class Q_CORE_EXPORT QEventDispatcherWin32 : public QAbstractEventDispatcher { @@ -101,8 +101,8 @@ public: bool event(QEvent *e); private: - friend LRESULT CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp); - friend LRESULT CALLBACK qt_GetMessageHook(int, WPARAM, LPARAM); + friend LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp); + friend LRESULT QT_WIN_CALLBACK qt_GetMessageHook(int, WPARAM, LPARAM); }; QT_END_NAMESPACE diff --git a/src/gui/dialogs/qfiledialog_win_p.h b/src/gui/dialogs/qfiledialog_win_p.h index 44b7e43..7079925 100644 --- a/src/gui/dialogs/qfiledialog_win_p.h +++ b/src/gui/dialogs/qfiledialog_win_p.h @@ -82,7 +82,7 @@ typedef int GETPROPERTYSTOREFLAGS; #define GPS_BESTEFFORT 0x00000040 #define GPS_MASK_VALID 0x0000007F -typedef int (CALLBACK* BFFCALLBACK)(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData); +typedef int (QT_WIN_CALLBACK* BFFCALLBACK)(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData); // message from browser #define BFFM_INITIALIZED 1 #define BFFM_SELCHANGED 2 diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index 9872514..ae9b34c 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -441,7 +441,7 @@ extern QCursor *qt_grab_cursor(); #define __export #endif -extern "C" LRESULT CALLBACK QtWndProc(HWND, UINT, WPARAM, LPARAM); +extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND, UINT, WPARAM, LPARAM); class QETWidget : public QWidget // event translator widget { @@ -1400,8 +1400,7 @@ static bool qt_is_translatable_mouse_event(UINT message) ; } -extern "C" -LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { bool result = true; QEvent::Type evt_type = QEvent::None; diff --git a/src/gui/kernel/qdesktopwidget_win.cpp b/src/gui/kernel/qdesktopwidget_win.cpp index 1fea8d6..07dbc24 100644 --- a/src/gui/kernel/qdesktopwidget_win.cpp +++ b/src/gui/kernel/qdesktopwidget_win.cpp @@ -76,7 +76,7 @@ public: }; typedef BOOL (WINAPI *InfoFunc)(HMONITOR, MONITORINFO*); - typedef BOOL (CALLBACK *EnumProc)(HMONITOR, HDC, LPRECT, LPARAM); + typedef BOOL (QT_WIN_CALLBACK *EnumProc)(HMONITOR, HDC, LPRECT, LPARAM); typedef BOOL (WINAPI *EnumFunc)(HDC, LPCRECT, EnumProc, LPARAM); static EnumFunc enumDisplayMonitors; @@ -107,7 +107,7 @@ static inline void qt_get_sip_info(QRect &rect) #endif -BOOL CALLBACK enumCallback(HMONITOR hMonitor, HDC, LPRECT, LPARAM) +BOOL QT_WIN_CALLBACK enumCallback(HMONITOR hMonitor, HDC, LPRECT, LPARAM) { QDesktopWidgetPrivate::screenCount++; QDesktopWidgetPrivate::rects->resize(QDesktopWidgetPrivate::screenCount); diff --git a/src/gui/kernel/qkeymapper_win.cpp b/src/gui/kernel/qkeymapper_win.cpp index e555c5c..f84b902 100644 --- a/src/gui/kernel/qkeymapper_win.cpp +++ b/src/gui/kernel/qkeymapper_win.cpp @@ -56,7 +56,7 @@ QT_BEGIN_NAMESPACE //#define DEBUG_KEYMAPPER // Implemented elsewhere -extern "C" LRESULT CALLBACK QtWndProc(HWND, UINT, WPARAM, LPARAM); +extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND, UINT, WPARAM, LPARAM); extern Q_CORE_EXPORT QLocale qt_localeFromLCID(LCID id); #ifndef LANG_PASHTO diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp index 2dcbfc3..7d647b7 100644 --- a/src/gui/kernel/qwidget_win.cpp +++ b/src/gui/kernel/qwidget_win.cpp @@ -243,7 +243,7 @@ static QCursor *mouseGrbCur = 0; static QWidget *keyboardGrb = 0; static HHOOK journalRec = 0; -extern "C" LRESULT CALLBACK QtWndProc(HWND, UINT, WPARAM, LPARAM); +extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND, UINT, WPARAM, LPARAM); #define XCOORD_MAX 16383 #define WRECT_MAX 16383 @@ -825,7 +825,7 @@ QCursor *qt_grab_cursor() // The procedure does nothing, but is required for mousegrabbing to work #ifndef Q_WS_WINCE -LRESULT CALLBACK qJournalRecordProc(int nCode, WPARAM wParam, LPARAM lParam) +LRESULT QT_WIN_CALLBACK qJournalRecordProc(int nCode, WPARAM wParam, LPARAM lParam) { return CallNextHookEx(journalRec, nCode, wParam, lParam); } diff --git a/src/gui/kernel/qwidget_wince.cpp b/src/gui/kernel/qwidget_wince.cpp index fa94703..509847b 100644 --- a/src/gui/kernel/qwidget_wince.cpp +++ b/src/gui/kernel/qwidget_wince.cpp @@ -46,7 +46,7 @@ QT_BEGIN_NAMESPACE const QString qt_reg_winclass(QWidget *w); // defined in qapplication_win.cpp -extern "C" LRESULT CALLBACK QtWndProc(HWND, UINT, WPARAM, LPARAM); +extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND, UINT, WPARAM, LPARAM); //#define TABLET_DEBUG #define PACKETDATA (PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE \ @@ -586,7 +586,7 @@ void QWidgetPrivate::setWindowOpacity_sys(qreal level) { } // The procedure does nothing, but is required for mousegrabbing to work -LRESULT CALLBACK qJournalRecordProc(int nCode, WPARAM wParam, LPARAM lParam) { +LRESULT QT_WIN_CALLBACK qJournalRecordProc(int nCode, WPARAM wParam, LPARAM lParam) { Q_UNUSED(nCode); Q_UNUSED(wParam); Q_UNUSED(lParam); diff --git a/src/multimedia/audio/qaudioinput_win32_p.cpp b/src/multimedia/audio/qaudioinput_win32_p.cpp index 594f6ca..180cbda 100644 --- a/src/multimedia/audio/qaudioinput_win32_p.cpp +++ b/src/multimedia/audio/qaudioinput_win32_p.cpp @@ -88,7 +88,7 @@ QAudioInputPrivate::~QAudioInputPrivate() DeleteCriticalSection(&waveInCriticalSection); } -void CALLBACK QAudioInputPrivate::waveInProc( HWAVEIN hWaveIn, UINT uMsg, +void QT_WIN_CALLBACK QAudioInputPrivate::waveInProc( HWAVEIN hWaveIn, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 ) { Q_UNUSED(dwParam1) diff --git a/src/multimedia/audio/qaudiooutput_win32_p.cpp b/src/multimedia/audio/qaudiooutput_win32_p.cpp index 6200160..c7f5752 100644 --- a/src/multimedia/audio/qaudiooutput_win32_p.cpp +++ b/src/multimedia/audio/qaudiooutput_win32_p.cpp @@ -88,7 +88,7 @@ QAudioOutputPrivate::~QAudioOutputPrivate() DeleteCriticalSection(&waveOutCriticalSection); } -void CALLBACK QAudioOutputPrivate::waveOutProc( HWAVEOUT hWaveOut, UINT uMsg, +void QT_WIN_CALLBACK QAudioOutputPrivate::waveOutProc( HWAVEOUT hWaveOut, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 ) { Q_UNUSED(dwParam1) diff --git a/src/multimedia/audio/qaudiooutput_win32_p.h b/src/multimedia/audio/qaudiooutput_win32_p.h index 6e0899f..bb176a0 100644 --- a/src/multimedia/audio/qaudiooutput_win32_p.h +++ b/src/multimedia/audio/qaudiooutput_win32_p.h @@ -116,7 +116,7 @@ private: qint64 totalTimeValue; bool pullMode; int intervalTime; - static void CALLBACK waveOutProc( HWAVEOUT hWaveOut, UINT uMsg, + static void QT_WIN_CALLBACK waveOutProc( HWAVEOUT hWaveOut, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 ); WAVEHDR* allocateBlocks(int size, int count); diff --git a/src/qt3support/other/q3process_win.cpp b/src/qt3support/other/q3process_win.cpp index da39bdc..9b69520 100644 --- a/src/qt3support/other/q3process_win.cpp +++ b/src/qt3support/other/q3process_win.cpp @@ -384,7 +384,7 @@ bool Q3Process::start( QStringList *env ) return true; } -static BOOL CALLBACK qt_terminateApp( HWND hwnd, LPARAM procId ) +static BOOL QT_WIN_CALLBACK qt_terminateApp( HWND hwnd, LPARAM procId ) { DWORD procId_win; GetWindowThreadProcessId( hwnd, &procId_win ); -- cgit v0.12 From f18e95849be93b86ff014147086fa538993abc21 Mon Sep 17 00:00:00 2001 From: Daisuke Kameda Date: Thu, 11 Mar 2010 13:39:15 +0100 Subject: Fixed problem displaying half width character as full width There is the problem that Qt displays half width character (e.g. alphabet) as full width. This is reported in #QTBUG-1726. This occurs in the following fonts. - Monospace font - Selif font - IPA font (Ver.0301) - NSimSun In Cario and fontconfig, the FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH is specified as flag of FT_Load_Glyph function to solve this problem. According to the document of freetype, this flag exists to support buggy CJK fonts. So this flag is specified as default flag of QFontEngineFT. Merge-request: 2319 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qfontengine_ft.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 6b40aad..a9def8e 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -619,7 +619,7 @@ QFontEngineFT::QFontEngineFT(const QFontDef &fd) transform = false; antialias = true; freetype = 0; - default_load_flags = 0; + default_load_flags = FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH; default_hint_style = HintNone; subpixelType = Subpixel_None; lcdFilterType = 0; -- cgit v0.12 From 5f5c9ba6810071bc7bb369afd2aac99064177ce7 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Thu, 11 Mar 2010 12:23:32 +0100 Subject: Fix 1-bit to 8-bit conversion for bitmap fonts on QWS QImage doesn't know that we are abusing Format_Indexed8 as an alpha map. The proper solution is to add new image formats. This is just a quick fix. Task-number: QTBUG-5936 Reviewed-by: Jeremy --- src/gui/text/qfontengine_qpf.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/gui/text/qfontengine_qpf.cpp b/src/gui/text/qfontengine_qpf.cpp index 136737d..a0593cc 100644 --- a/src/gui/text/qfontengine_qpf.cpp +++ b/src/gui/text/qfontengine_qpf.cpp @@ -920,8 +920,18 @@ void QFontEngineQPF::loadGlyph(glyph_t glyph) if (!renderingFontEngine) return; - - QImage img = renderingFontEngine->alphaMapForGlyph(glyph).convertToFormat(QImage::Format_Indexed8); + QImage img = renderingFontEngine->alphaMapForGlyph(glyph); + if (img.format() != QImage::Format_Indexed8) { + bool mono = img.depth() == 1; + img = img.convertToFormat(QImage::Format_Indexed8); + if (mono) { + //### we know that 1 is opaque and 0 is transparent + uchar *byte = img.bits(); + int count = img.byteCount(); + while (count--) + *byte++ *= 0xff; + } + } glyph_metrics_t metrics = renderingFontEngine->boundingBox(glyph); renderingFontEngine->removeGlyphFromCache(glyph); -- cgit v0.12 From c5cb91a714f3fa38aeab41c6e793a5a3d071dcef Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Thu, 11 Mar 2010 13:53:43 +0100 Subject: Add support for QFont::NoAntialias on QWS Task-number: QTBUG-5936 Reviewed-by: Eskil --- src/gui/text/qfontdatabase_qws.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/gui/text/qfontdatabase_qws.cpp b/src/gui/text/qfontdatabase_qws.cpp index 62d7793..a3d8d65 100644 --- a/src/gui/text/qfontdatabase_qws.cpp +++ b/src/gui/text/qfontdatabase_qws.cpp @@ -632,8 +632,9 @@ QFontEngine *loadSingleEngine(int script, const QFontPrivate *fp, #ifndef QT_NO_FREETYPE QScopedPointer fte(new QFontEngineFT(def)); - if (fte->init(faceId, style->antialiased, - style->antialiased ? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono)) { + bool antialias = style->antialiased && !(request.styleStrategy & QFont::NoAntialias); + if (fte->init(faceId, antialias, + antialias ? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono)) { #ifdef QT_NO_QWS_QPF2 return fte.take(); #else @@ -793,7 +794,7 @@ QFontDatabase::findFont(int script, const QFontPrivate *fp, " family: %s [%s], script: %d\n" " weight: %d, style: %d\n" " stretch: %d\n" - " pixelSize: %d\n" + " pixelSize: %g\n" " pitch: %c", family_name.isEmpty() ? "-- first in script --" : family_name.toLatin1().constData(), foundry_name.isEmpty() ? "-- any --" : foundry_name.toLatin1().constData(), -- cgit v0.12 From 82fa80a6b28ea5a4d3e245f531fea22a689c7ad3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Thu, 11 Mar 2010 15:52:37 +0100 Subject: Made QGLTextureCache::instance() threadsafe. Reviewed-by: Tom Cooksey --- src/opengl/qgl.cpp | 27 +++++++-------------------- src/opengl/qgl_p.h | 1 - 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 7839191..c6ecef6 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -1688,14 +1688,12 @@ typedef void (*_qt_image_cleanup_hook_64)(qint64); extern Q_GUI_EXPORT _qt_pixmap_cleanup_hook_64 qt_pixmap_cleanup_hook_64; extern Q_GUI_EXPORT _qt_image_cleanup_hook_64 qt_image_cleanup_hook_64; -static QGLTextureCache *qt_gl_texture_cache = 0; + +Q_GLOBAL_STATIC(QGLTextureCache, qt_gl_texture_cache) QGLTextureCache::QGLTextureCache() : m_cache(64*1024) // cache ~64 MB worth of textures - this is not accurate though { - Q_ASSERT(qt_gl_texture_cache == 0); - qt_gl_texture_cache = this; - QImagePixmapCleanupHooks::instance()->addPixmapDataModificationHook(cleanupTexturesForPixampData); QImagePixmapCleanupHooks::instance()->addPixmapDataDestructionHook(cleanupBeforePixmapDestruction); QImagePixmapCleanupHooks::instance()->addImageHook(cleanupTexturesForCacheKey); @@ -1703,8 +1701,7 @@ QGLTextureCache::QGLTextureCache() QGLTextureCache::~QGLTextureCache() { - qt_gl_texture_cache = 0; - + Q_ASSERT(size() == 0); QImagePixmapCleanupHooks::instance()->removePixmapDataModificationHook(cleanupTexturesForPixampData); QImagePixmapCleanupHooks::instance()->removePixmapDataDestructionHook(cleanupBeforePixmapDestruction); QImagePixmapCleanupHooks::instance()->removeImageHook(cleanupTexturesForCacheKey); @@ -1754,22 +1751,14 @@ void QGLTextureCache::removeContextTextures(QGLContext* ctx) } } -QGLTextureCache* QGLTextureCache::instance() -{ - if (!qt_gl_texture_cache) - qt_gl_texture_cache = new QGLTextureCache; - - return qt_gl_texture_cache; -} - /* a hook that removes textures from the cache when a pixmap/image is deref'ed */ void QGLTextureCache::cleanupTexturesForCacheKey(qint64 cacheKey) { - instance()->remove(cacheKey); - Q_ASSERT(instance()->getTexture(cacheKey) == 0); + qt_gl_texture_cache()->remove(cacheKey); + Q_ASSERT(qt_gl_texture_cache()->getTexture(cacheKey) == 0); } @@ -1791,10 +1780,9 @@ void QGLTextureCache::cleanupBeforePixmapDestruction(QPixmapData* pmd) #endif } -void QGLTextureCache::deleteIfEmpty() +QGLTextureCache *QGLTextureCache::instance() { - if (instance()->size() == 0) - delete instance(); + return qt_gl_texture_cache(); } // DDS format structure @@ -1960,7 +1948,6 @@ QGLContext::~QGLContext() { // remove any textures cached in this context QGLTextureCache::instance()->removeContextTextures(this); - QGLTextureCache::deleteIfEmpty(); // ### thread safety d_ptr->group->cleanupResources(this); diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index ed34f79..5e524a7 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -532,7 +532,6 @@ public: bool remove(QGLContext *ctx, GLuint textureId); void removeContextTextures(QGLContext *ctx); static QGLTextureCache *instance(); - static void deleteIfEmpty(); static void cleanupTexturesForCacheKey(qint64 cacheKey); static void cleanupTexturesForPixampData(QPixmapData* pixmap); static void cleanupBeforePixmapDestruction(QPixmapData* pixmap); -- cgit v0.12 From fc0e0198c5e7ef75d1650bca39a5f06ebddfb932 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Thu, 11 Mar 2010 15:44:08 +0100 Subject: Delete the QGLContext in ~QX11GLPixmapData This also includes changes which allow QGLContext to not own it's own QEglContext. With X11GL, the QEglContext gets reused by multiple QGLContexts so it is important QGLContext doesn't delete it. Reviewed-By: TrustMe --- src/gui/egl/qegl.cpp | 2 +- src/opengl/qgl.cpp | 1 + src/opengl/qgl_egl.cpp | 5 +++-- src/opengl/qgl_p.h | 1 + src/opengl/qgl_qws.cpp | 1 + src/opengl/qgl_wince.cpp | 1 + src/opengl/qgl_x11egl.cpp | 1 + src/opengl/qpixmapdata_x11gl_egl.cpp | 3 +++ 8 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/gui/egl/qegl.cpp b/src/gui/egl/qegl.cpp index 6e0331f..b870523 100644 --- a/src/gui/egl/qegl.cpp +++ b/src/gui/egl/qegl.cpp @@ -60,7 +60,7 @@ static QEglContext * volatile currentVGContext = 0; QEglContext::QEglContext() : apiType(QEgl::OpenGL) , ctx(EGL_NO_CONTEXT) - , cfg(0) + , cfg(QEGL_NO_CONFIG) , currentSurface(EGL_NO_SURFACE) , current(false) , ownsContext(true) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index c6ecef6..58ac642 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -1583,6 +1583,7 @@ void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format) vi = 0; #endif #if defined(QT_OPENGL_ES) + ownsEglContext = false; eglContext = 0; eglSurface = EGL_NO_SURFACE; #endif diff --git a/src/opengl/qgl_egl.cpp b/src/opengl/qgl_egl.cpp index c08d6fd..aa8d2bc 100644 --- a/src/opengl/qgl_egl.cpp +++ b/src/opengl/qgl_egl.cpp @@ -164,10 +164,11 @@ void QGLContext::reset() return; d->cleanup(); doneCurrent(); - if (d->eglContext) { + if (d->eglContext && d->ownsEglContext) { d->destroyEglSurfaceForDevice(); delete d->eglContext; } + d->ownsEglContext = false; d->eglContext = 0; d->eglSurface = EGL_NO_SURFACE; d->crWin = false; @@ -215,7 +216,7 @@ void QGLContextPrivate::destroyEglSurfaceForDevice() #ifdef Q_WS_X11 // Make sure we don't call eglDestroySurface on a surface which // was created for a different winId: - if (paintDevice->devType() == QInternal::Widget) { + if (paintDevice && paintDevice->devType() == QInternal::Widget) { QGLWidget* w = static_cast(paintDevice); if (w->d_func()->eglSurfaceWindowId == w->winId()) diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 5e524a7..f66031a 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -347,6 +347,7 @@ public: HDC hbitmap_hdc; #endif #if defined(QT_OPENGL_ES) + bool ownsEglContext; QEglContext *eglContext; EGLSurface eglSurface; void destroyEglSurfaceForDevice(); diff --git a/src/opengl/qgl_qws.cpp b/src/opengl/qgl_qws.cpp index 96b2454..38c3774 100644 --- a/src/opengl/qgl_qws.cpp +++ b/src/opengl/qgl_qws.cpp @@ -182,6 +182,7 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) // Get the display and initialize it. d->eglContext = new QEglContext(); + d->ownsEglContext = true; d->eglContext->setApi(QEgl::OpenGL); // Construct the configuration we need for this surface. diff --git a/src/opengl/qgl_wince.cpp b/src/opengl/qgl_wince.cpp index fefcca2..47a19b5 100644 --- a/src/opengl/qgl_wince.cpp +++ b/src/opengl/qgl_wince.cpp @@ -145,6 +145,7 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) // Get the display and initialize it. d->eglContext = new QEglContext(); + d->ownsEglContext = true; d->eglContext->setApi(QEgl::OpenGL); // Construct the configuration we need for this surface. diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp index fe87c65..0954e69 100644 --- a/src/opengl/qgl_x11egl.cpp +++ b/src/opengl/qgl_x11egl.cpp @@ -182,6 +182,7 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) // Only create the eglContext if we don't already have one: if (d->eglContext == 0) { d->eglContext = new QEglContext(); + d->ownsEglContext = true; d->eglContext->setApi(QEgl::OpenGL); // If the device is a widget with WA_TranslucentBackground set, make sure the glFormat diff --git a/src/opengl/qpixmapdata_x11gl_egl.cpp b/src/opengl/qpixmapdata_x11gl_egl.cpp index d7fae16..a01eec4 100644 --- a/src/opengl/qpixmapdata_x11gl_egl.cpp +++ b/src/opengl/qpixmapdata_x11gl_egl.cpp @@ -181,6 +181,8 @@ QX11GLPixmapData::QX11GLPixmapData() QX11GLPixmapData::~QX11GLPixmapData() { + if (ctx) + delete ctx; } #if !defined(QT_OPENGL_ES_1) @@ -245,6 +247,7 @@ void QX11GLPixmapData::beginPaint() if ((EGLSurface)gl_surface == EGL_NO_SURFACE) { QPixmap tmpPixmap(this); EGLConfig cfg = ctx->d_func()->eglContext->config(); + Q_ASSERT(cfg != QEGL_NO_CONFIG); EGLSurface surface = QEgl::createSurface(&tmpPixmap, cfg); if (surface == EGL_NO_SURFACE) { -- cgit v0.12 From 5ccbd1a3fc856d6ccdcbf71657a8cd89f9af9173 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Thu, 11 Mar 2010 16:43:03 +0100 Subject: Remove debug output from qt_eglproperties_set_glformat Reviewed-By: TrustMe --- src/opengl/qgl_egl.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/opengl/qgl_egl.cpp b/src/opengl/qgl_egl.cpp index aa8d2bc..822c9f6 100644 --- a/src/opengl/qgl_egl.cpp +++ b/src/opengl/qgl_egl.cpp @@ -63,10 +63,8 @@ void qt_eglproperties_set_glformat(QEglProperties& eglProperties, const QGLForma // QGLFormat uses a magic value of -1 to indicate "don't care", even when a buffer of that // type has been requested. So we must check QGLFormat's booleans too if size is -1: - if (glFormat.alpha() && alphaSize <= 0) { - qDebug("QGLFormat::alpha() returned true"); + if (glFormat.alpha() && alphaSize <= 0) alphaSize = 1; - } if (glFormat.depth() && depthSize <= 0) depthSize = 1; if (glFormat.stencil() && stencilSize <= 0) -- cgit v0.12 From dfa979eea762ec94fb3f7b8eb6562756272b6c18 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 11 Mar 2010 14:12:08 +0100 Subject: QTreeView: speedup more QTreeViewPrivate::layout(-1) Specially when called from expandAll Reviewed-by: Gabriel --- src/gui/itemviews/qtreeview.cpp | 38 +++++++++++++++++++++++--------------- src/gui/itemviews/qtreeview_p.h | 5 ++++- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index 0a7ffb7..18ee5d3 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -2662,17 +2662,8 @@ void QTreeView::expandAll() { Q_D(QTreeView); d->viewItems.clear(); - d->expandedIndexes.clear(); d->interruptDelayedItemsLayout(); - d->layout(-1); - for (int i = 0; i < d->viewItems.count(); ++i) { - if (d->viewItems[i].expanded) - continue; - d->viewItems[i].expanded = true; - d->layout(i); - QModelIndex idx = d->viewItems.at(i).index; - d->expandedIndexes.insert(idx); - } + d->layout(-1, true); updateGeometries(); d->viewport->update(); } @@ -3155,7 +3146,14 @@ void QTreeViewPrivate::_q_columnsRemoved(const QModelIndex &parent, int start, i QAbstractItemViewPrivate::_q_columnsRemoved(parent, start, end); } -void QTreeViewPrivate::layout(int i) +/** \internal + creates and initialize the viewItem structure of the children of the element \i + + set \a recursiveExpanding if the function has to expand all the children (called from expandAll) + \a afterIsUninitialized is when we recurse from layout(-1), it means all the items after 'i' are + not yet initialized and need not to be moved + */ +void QTreeViewPrivate::layout(int i, bool recursiveExpanding, bool afterIsUninitialized) { Q_Q(QTreeView); QModelIndex current; @@ -3182,8 +3180,12 @@ void QTreeViewPrivate::layout(int i) defaultItemHeight = q->indexRowSizeHint(index); } viewItems.resize(count); + afterIsUninitialized = true; } else if (viewItems[i].total != (uint)count) { + if (!afterIsUninitialized) insertViewItems(i + 1, count, QTreeViewItem()); // expand + else if (count > 0) + viewItems.resize(viewItems.count() + count); } else { expanding = false; } @@ -3212,9 +3214,11 @@ void QTreeViewPrivate::layout(int i) item->expanded = false; item->total = 0; item->hasMoreSiblings = false; - if (isIndexExpanded(current)) { + if (recursiveExpanding || isIndexExpanded(current)) { + if (recursiveExpanding) + expandedIndexes.insert(current); item->expanded = true; - layout(last); + layout(last, recursiveExpanding, afterIsUninitialized); item = &viewItems[last]; children += item->total; item->hasChildren = item->total > 0; @@ -3226,8 +3230,12 @@ void QTreeViewPrivate::layout(int i) } // remove hidden items - if (hidden > 0) - removeViewItems(last + 1, hidden); // collapse + if (hidden > 0) { + if (!afterIsUninitialized) + removeViewItems(last + 1, hidden); + else + viewItems.resize(viewItems.size() - hidden); + } if (!expanding) return; // nothing changed diff --git a/src/gui/itemviews/qtreeview_p.h b/src/gui/itemviews/qtreeview_p.h index 7893e04..48997b7 100644 --- a/src/gui/itemviews/qtreeview_p.h +++ b/src/gui/itemviews/qtreeview_p.h @@ -55,6 +55,7 @@ #include "private/qabstractitemview_p.h" #include +#include #ifndef QT_NO_TREEVIEW @@ -75,6 +76,8 @@ struct QTreeViewItem int height : 16; // row height }; +Q_DECLARE_TYPEINFO(QTreeViewItem, Q_MOVABLE_TYPE); + class QTreeViewPrivate : public QAbstractItemViewPrivate { Q_DECLARE_PUBLIC(QTreeView) @@ -124,7 +127,7 @@ public: void _q_sortIndicatorChanged(int column, Qt::SortOrder order); void _q_modelDestroyed(); - void layout(int item); + void layout(int item, bool recusiveExpanding = false, bool afterIsUninitialized = false); int pageUp(int item) const; int pageDown(int item) const; -- cgit v0.12 From 4ae11be00b7aa2257d15140373f24ab1c28c0af7 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 11 Mar 2010 14:46:56 +0100 Subject: Optimize QSortFilterProxyModel - use QHash instead of QMap - use QVector::reserve when the size is known Reviewed-by: Gabriel --- src/gui/itemviews/qsortfilterproxymodel.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/gui/itemviews/qsortfilterproxymodel.cpp index c63a07b..5c7d24b7 100644 --- a/src/gui/itemviews/qsortfilterproxymodel.cpp +++ b/src/gui/itemviews/qsortfilterproxymodel.cpp @@ -122,10 +122,10 @@ public: QVector proxy_rows; QVector proxy_columns; QVector mapped_children; - QMap::const_iterator map_iter; + QHash::const_iterator map_iter; }; - mutable QMap source_index_mapping; + mutable QHash source_index_mapping; int source_sort_column; int proxy_sort_column; @@ -142,7 +142,7 @@ public: QModelIndexPairList saved_persistent_indexes; - QMap::const_iterator create_mapping( + QHash::const_iterator create_mapping( const QModelIndex &source_parent) const; QModelIndex proxy_to_source(const QModelIndex &proxyIndex) const; QModelIndex source_to_proxy(const QModelIndex &sourceIndex) const; @@ -150,14 +150,14 @@ public: void remove_from_mapping(const QModelIndex &source_parent); - inline QMap::const_iterator index_to_iterator( + inline QHash::const_iterator index_to_iterator( const QModelIndex &proxy_index) const { Q_ASSERT(proxy_index.isValid()); Q_ASSERT(proxy_index.model() == q_func()); const void *p = proxy_index.internalPointer(); Q_ASSERT(p); - QMap::const_iterator it = + QHash::const_iterator it = static_cast(p)->map_iter; Q_ASSERT(it != source_index_mapping.constEnd()); Q_ASSERT(it.value()); @@ -165,7 +165,7 @@ public: } inline QModelIndex create_index(int row, int column, - QMap::const_iterator it) const + QHash::const_iterator it) const { return q_func()->createIndex(row, column, *it); } @@ -246,7 +246,7 @@ public: virtual void _q_sourceModelDestroyed(); }; -typedef QMap IndexMap; +typedef QHash IndexMap; void QSortFilterProxyModelPrivate::_q_sourceModelDestroyed() { @@ -292,11 +292,13 @@ IndexMap::const_iterator QSortFilterProxyModelPrivate::create_mapping( Mapping *m = new Mapping; int source_rows = model->rowCount(source_parent); + m->source_rows.reserve(source_rows); for (int i = 0; i < source_rows; ++i) { if (q->filterAcceptsRow(i, source_parent)) m->source_rows.append(i); } int source_cols = model->columnCount(source_parent); + m->source_columns.reserve(source_cols); for (int i = 0; i < source_cols; ++i) { if (q->filterAcceptsColumn(i, source_parent)) m->source_columns.append(i); -- cgit v0.12 From f98d645e7b260fa5098360a5cc4fbb381a30004a Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 11 Mar 2010 13:50:23 +0100 Subject: QTreeView: Optimise QTreeViewPrivate::viewIndex ... by first looking around the last find item. This was already done, but only for the 4 closest item. Now start searching from the last index and continue. Reviewed-by: Gabriel Task-number: QTBUG-8886 --- src/gui/itemviews/qtreeview.cpp | 62 ++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 35 deletions(-) diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index 18ee5d3..4135ba0 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -2407,9 +2407,9 @@ void QTreeView::reexpand() /*! \internal + This function assume that left is a (grand-)child of the parent of left. */ -static bool treeViewItemLessThan(const QTreeViewItem &left, - const QTreeViewItem &right) +static bool treeViewItemLessThanInInsert(const QTreeViewItem &left, const QTreeViewItem &right) { if (left.level != right.level) { Q_ASSERT(left.level > right.level); @@ -2496,7 +2496,7 @@ void QTreeView::rowsInserted(const QModelIndex &parent, int start, int end) QVector::iterator it; it = qLowerBound(d->viewItems.begin() + firstChildItem, d->viewItems.begin() + lastChildItem + 1, - insertedItems.at(0), treeViewItemLessThan); + insertedItems.at(0), treeViewItemLessThanInInsert); insertPos = it - d->viewItems.begin(); // update stale model indexes of siblings @@ -3397,46 +3397,39 @@ int QTreeViewPrivate::viewIndex(const QModelIndex &_index) const const int totalCount = viewItems.count(); const QModelIndex index = _index.sibling(_index.row(), 0); + const int row = index.row(); + const quint64 internalId = index.internalId(); - - // A quick check near the last item to see if we are just incrementing - const int start = lastViewedItem > 2 ? lastViewedItem - 2 : 0; - const int end = lastViewedItem < totalCount - 2 ? lastViewedItem + 2 : totalCount; - int row = index.row(); - for (int i = start; i < end; ++i) { - const QModelIndex &idx = viewItems.at(i).index; - if (idx.row() == row) { - if (idx.internalId() == index.internalId()) { - lastViewedItem = i; - return i; - } + // We start nearest to the lastViewedItem + int localCount = qMin(lastViewedItem - 1, totalCount - lastViewedItem); + for (int i = 0; i < localCount; ++i) { + const QModelIndex &idx1 = viewItems.at(lastViewedItem + i).index; + if (idx1.row() == row && idx1.internalId() == internalId) { + lastViewedItem = lastViewedItem + i; + return lastViewedItem; + } + const QModelIndex &idx2 = viewItems.at(lastViewedItem - i - 1).index; + if (idx2.row() == row && idx2.internalId() == internalId) { + lastViewedItem = lastViewedItem - i - 1; + return lastViewedItem; } } - // NOTE: this function is slow if the item is outside the visible area - // search in visible items first and below - int t = firstVisibleItem(); - t = t > 100 ? t - 100 : 0; // start 100 items above the visible area - - for (int i = t; i < totalCount; ++i) { - const QModelIndex &idx = viewItems.at(i).index; - if (idx.row() == row) { - if (idx.internalId() == index.internalId()) { - lastViewedItem = i; - return i; - } + for (int j = qMax(0, lastViewedItem + localCount); j < totalCount; ++j) { + const QModelIndex &idx = viewItems.at(j).index; + if (idx.row() == row && idx.internalId() == internalId) { + lastViewedItem = j; + return j; } } - // search from top to first visible - for (int j = 0; j < t; ++j) { + for (int j = qMin(totalCount, lastViewedItem - localCount) - 1; j >= 0; --j) { const QModelIndex &idx = viewItems.at(j).index; - if (idx.row() == row) { - if (idx.internalId() == index.internalId()) { - lastViewedItem = j; - return j; - } + if (idx.row() == row && idx.internalId() == internalId) { + lastViewedItem = j; + return j; } } + // nothing found return -1; } @@ -3761,7 +3754,6 @@ bool QTreeViewPrivate::hasVisibleChildren(const QModelIndex& parent) const void QTreeViewPrivate::rowsRemoved(const QModelIndex &parent, int start, int end, bool after) { - Q_Q(QTreeView); // if we are going to do a complete relayout anyway, there is no need to update if (delayedPendingLayout) { _q_rowsRemoved(parent, start, end); -- cgit v0.12 From a3e2e9efd4ed4baed3b5ca71cf518b3d3fda4716 Mon Sep 17 00:00:00 2001 From: Dmytro Poplavskiy Date: Fri, 12 Mar 2010 15:03:58 +1000 Subject: QPainterVideoSurface: assume yuv 420p and YV12 lines are 4 byte aligned. Reviewed-by: Andrew den Exter --- src/multimedia/base/qpaintervideosurface.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/multimedia/base/qpaintervideosurface.cpp b/src/multimedia/base/qpaintervideosurface.cpp index fc3d493..ed93fad 100644 --- a/src/multimedia/base/qpaintervideosurface.cpp +++ b/src/multimedia/base/qpaintervideosurface.cpp @@ -434,6 +434,9 @@ void QVideoSurfaceGLPainter::initRgbTextureInfo( void QVideoSurfaceGLPainter::initYuv420PTextureInfo(const QSize &size) { + int w = (size.width() + 3) & ~3; + int w2 = (size.width()/2 + 3) & ~3; + m_yuv = true; m_textureInternalFormat = GL_LUMINANCE; m_textureFormat = GL_LUMINANCE; @@ -444,14 +447,17 @@ void QVideoSurfaceGLPainter::initYuv420PTextureInfo(const QSize &size) m_textureOffsets[0] = 0; m_textureWidths[1] = size.width() / 2; m_textureHeights[1] = size.height() / 2; - m_textureOffsets[1] = size.width() * size.height(); + m_textureOffsets[1] = w * size.height(); m_textureWidths[2] = size.width() / 2; m_textureHeights[2] = size.height() / 2; - m_textureOffsets[2] = size.width() * size.height() * 5 / 4; + m_textureOffsets[2] = w * size.height() + w2 * (size.height() / 2); } void QVideoSurfaceGLPainter::initYv12TextureInfo(const QSize &size) { + int w = (size.width() + 3) & ~3; + int w2 = (size.width()/2 + 3) & ~3; + m_yuv = true; m_textureInternalFormat = GL_LUMINANCE; m_textureFormat = GL_LUMINANCE; @@ -462,10 +468,10 @@ void QVideoSurfaceGLPainter::initYv12TextureInfo(const QSize &size) m_textureOffsets[0] = 0; m_textureWidths[1] = size.width() / 2; m_textureHeights[1] = size.height() / 2; - m_textureOffsets[1] = size.width() * size.height() * 5 / 4; + m_textureOffsets[1] = w * size.height() + w2 * (size.height() / 2); m_textureWidths[2] = size.width() / 2; m_textureHeights[2] = size.height() / 2; - m_textureOffsets[2] = size.width() * size.height(); + m_textureOffsets[2] = w * size.height(); } #ifndef QT_OPENGL_ES -- cgit v0.12 From 6e8c0095d0410a30ffa06bb0b0cb71f979becfb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Fri, 12 Mar 2010 12:49:38 +0100 Subject: Made QGLExtensions::glExtensions() thread-safe. Reviewed-by: Gunnar --- src/opengl/qgl.cpp | 37 ++++++++++++++++++------------------- src/opengl/qgl_p.h | 2 -- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 58ac642..e0030ad 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -5060,6 +5060,20 @@ QGLExtensions::Extensions QGLExtensions::currentContextExtensions() return glExtensions; } + +class QGLDefaultExtensions +{ +public: + QGLDefaultExtensions() { + QGLTemporaryContext tempContext; + extensions = QGLExtensions::currentContextExtensions(); + } + + QGLExtensions::Extensions extensions; +}; + +Q_GLOBAL_STATIC(QGLDefaultExtensions, qtDefaultExtensions) + /* Returns the GL extensions for the current QGLContext. If there is no current QGLContext, a default context will be created and the extensions @@ -5067,34 +5081,19 @@ QGLExtensions::Extensions QGLExtensions::currentContextExtensions() */ QGLExtensions::Extensions QGLExtensions::glExtensions() { - QGLTemporaryContext *tmpContext = 0; - static bool cachedDefault = false; - static Extensions defaultExtensions = 0; + Extensions extensionFlags = 0; QGLContext *currentCtx = const_cast(QGLContext::currentContext()); if (currentCtx && currentCtx->d_func()->extension_flags_cached) return currentCtx->d_func()->extension_flags; if (!currentCtx) { - if (cachedDefault) { - return defaultExtensions; - } else { - tmpContext = new QGLTemporaryContext; - cachedDefault = true; - } - } - - Extensions extensionFlags = currentContextExtensions(); - if (currentCtx) { + extensionFlags = qtDefaultExtensions()->extensions; + } else { + extensionFlags = currentContextExtensions(); currentCtx->d_func()->extension_flags_cached = true; currentCtx->d_func()->extension_flags = extensionFlags; - } else { - defaultExtensions = extensionFlags; } - - if (tmpContext) - delete tmpContext; - return extensionFlags; } diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index f66031a..45f8f30 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -278,8 +278,6 @@ public: Q_DECLARE_FLAGS(Extensions, Extension) static Extensions glExtensions(); - -private: static Extensions currentContextExtensions(); }; -- cgit v0.12 From 4f1b0d758e42872d2852e0eedd2417a858d603e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Fri, 12 Mar 2010 12:52:37 +0100 Subject: Removed a Valgrind warning. Reviewed-by: Gunnar --- src/gui/painting/qcups.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/painting/qcups.cpp b/src/gui/painting/qcups.cpp index ac41692..1ea1670 100644 --- a/src/gui/painting/qcups.cpp +++ b/src/gui/painting/qcups.cpp @@ -343,7 +343,8 @@ bool QCUPSSupport::printerHasPPD(const char *printerName) if (!isAvailable()) return false; const char *ppdFile = _cupsGetPPD(printerName); - unlink(ppdFile); + if (ppdFile) + unlink(ppdFile); return (ppdFile != 0); } -- cgit v0.12 From df77be2a58a36c756592465616beaaeed06d134b Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Mon, 15 Mar 2010 08:11:13 +1000 Subject: Fix compilation of OpenVG paint engine with OpenVG 1.0 Task-number: QTBUG-9006 --- src/openvg/qpaintengine_vg.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index 2c850c9..4902cbd 100644 --- a/src/openvg/qpaintengine_vg.cpp +++ b/src/openvg/qpaintengine_vg.cpp @@ -3307,6 +3307,7 @@ void QVGPaintEngine::drawStaticTextItem(QStaticTextItem *textItem) bool QVGPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, const QFont &font, QFontEngine *fontEngine, const QPointF &p) { +#if !defined(QVG_NO_DRAW_GLYPHS) Q_D(QVGPaintEngine); // Find the glyph cache for this font. @@ -3361,6 +3362,14 @@ void QVGPaintEngine::drawStaticTextItem(QStaticTextItem *textItem) NULL, NULL, VG_FILL_PATH, VG_TRUE); return true; +#else + Q_UNUSED(numGlyphs); + Q_UNUSED(glyphs); + Q_UNUSED(font); + Q_UNUSED(fontEngine); + Q_UNUSED(p); + return false; +#endif } void QVGPaintEngine::setState(QPainterState *s) -- cgit v0.12 From 2181d48844e923058b136c810a8b9457651e5bbc Mon Sep 17 00:00:00 2001 From: Justin McPherson Date: Mon, 15 Mar 2010 10:20:55 +1000 Subject: Install plugins to correct path. Task-number: QTBUG-9001 Reviewed-by: Kurt Korbatits --- src/plugins/mediaservices/directshow/directshow.pro | 2 +- src/plugins/mediaservices/gstreamer/gstreamer.pro | 2 +- src/plugins/mediaservices/qt7/qt7.pro | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/mediaservices/directshow/directshow.pro b/src/plugins/mediaservices/directshow/directshow.pro index a3080d3..ea133f9 100644 --- a/src/plugins/mediaservices/directshow/directshow.pro +++ b/src/plugins/mediaservices/directshow/directshow.pro @@ -9,6 +9,6 @@ SOURCES += dsserviceplugin.cpp include(mediaplayer/mediaplayer.pri) QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/mediaservices -target.path = $$[QT_INSTALL_PLUGINS]/plugins/mediaservices +target.path = $$[QT_INSTALL_PLUGINS]/mediaservices INSTALLS += target diff --git a/src/plugins/mediaservices/gstreamer/gstreamer.pro b/src/plugins/mediaservices/gstreamer/gstreamer.pro index 22e3c16..d1bfe44 100644 --- a/src/plugins/mediaservices/gstreamer/gstreamer.pro +++ b/src/plugins/mediaservices/gstreamer/gstreamer.pro @@ -46,5 +46,5 @@ SOURCES += \ include(mediaplayer/mediaplayer.pri) QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/mediaservices -target.path = $$[QT_INSTALL_PLUGINS]/plugins/mediaservices +target.path = $$[QT_INSTALL_PLUGINS]/mediaservices INSTALLS += target diff --git a/src/plugins/mediaservices/qt7/qt7.pro b/src/plugins/mediaservices/qt7/qt7.pro index 13d14d7..6624d13 100644 --- a/src/plugins/mediaservices/qt7/qt7.pro +++ b/src/plugins/mediaservices/qt7/qt7.pro @@ -40,6 +40,6 @@ OBJECTIVE_SOURCES += \ include(mediaplayer/mediaplayer.pri) QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/mediaservices -target.path = $$[QT_INSTALL_PLUGINS]/plugins/mediaservices +target.path = $$[QT_INSTALL_PLUGINS]/mediaservices INSTALLS += target -- cgit v0.12