From 24cdab32de2abd8669f281dd54c8da1124514915 Mon Sep 17 00:00:00 2001 From: Pierre Rossi Date: Fri, 23 Jul 2010 14:53:58 +0200 Subject: Fix QLineEdit's Highlight color when inactive. This commit also updates QPalette's documentation regarding the current ColorGroup and operator==. Task-number: QTBUG-697 Reviewed-by: ogoffart --- src/gui/kernel/qpalette.cpp | 10 ++++++++++ src/gui/widgets/qlineedit.cpp | 3 ++- tests/auto/qlineedit/tst_qlineedit.cpp | 18 +++++++++++++++++- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qpalette.cpp b/src/gui/kernel/qpalette.cpp index 98e8f66..38ec806 100644 --- a/src/gui/kernel/qpalette.cpp +++ b/src/gui/kernel/qpalette.cpp @@ -868,11 +868,21 @@ void QPalette::detach() Returns true (slowly) if this palette is different from \a p; otherwise returns false (usually quickly). + + \note The current ColorGroup is not taken into account when + comparing palettes + + \sa operator== */ /*! Returns true (usually quickly) if this palette is equal to \a p; otherwise returns false (slowly). + + \note The current ColorGroup is not taken into account when + comparing palettes + + \sa operator!= */ bool QPalette::operator==(const QPalette &p) const { diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp index d7311ef..981e934 100644 --- a/src/gui/widgets/qlineedit.cpp +++ b/src/gui/widgets/qlineedit.cpp @@ -1949,7 +1949,8 @@ void QLineEdit::paintEvent(QPaintEvent *) if (d->control->hasSelectedText() || (d->cursorVisible && !d->control->inputMask().isEmpty() && !d->control->isReadOnly())){ flags |= QLineControl::DrawSelections; // Palette only used for selections/mask and may not be in sync - if(d->control->palette() != pal) + if (d->control->palette() != pal + || d->control->palette().currentColorGroup() != pal.currentColorGroup()) d->control->setPalette(pal); } diff --git a/tests/auto/qlineedit/tst_qlineedit.cpp b/tests/auto/qlineedit/tst_qlineedit.cpp index b34e559..e0747f8 100644 --- a/tests/auto/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/qlineedit/tst_qlineedit.cpp @@ -66,7 +66,6 @@ #include #include - //TESTED_CLASS= //TESTED_FILES= @@ -275,6 +274,7 @@ private slots: void taskQTBUG_7902_contextMenuCrash(); #endif void taskQTBUG_7395_readOnlyShortcut(); + void QTBUG697_paletteCurrentColorGroup(); #ifdef QT3_SUPPORT void validateAndSet_data(); @@ -3714,5 +3714,21 @@ void tst_QLineEdit::taskQTBUG_7395_readOnlyShortcut() QCOMPARE(spy.count(), 1); } +void tst_QLineEdit::QTBUG697_paletteCurrentColorGroup() +{ + testWidget->setText(" "); + QPalette p = testWidget->palette(); + p.setBrush(QPalette::Active, QPalette::Highlight, Qt::green); + p.setBrush(QPalette::Inactive, QPalette::Highlight, Qt::red); + testWidget->setPalette(p); + testWidget->selectAll(); + QImage img(testWidget->rect().size(),QImage::Format_ARGB32 ); + testWidget->render(&img); + QCOMPARE(img.pixel(10, testWidget->height()/2), QColor(Qt::green).rgb()); + QApplication::setActiveWindow(0); + testWidget->render(&img); + QCOMPARE(img.pixel(10, testWidget->height()/2), QColor(Qt::red).rgb()); +} + QTEST_MAIN(tst_QLineEdit) #include "tst_qlineedit.moc" -- cgit v0.12 From 9d2760f619782145e0861300901531a56c12991a Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 23 Jul 2010 16:06:08 +0200 Subject: QScriptEngineAgent: ensure that the top of the backtrace is correct in exceptionThrow Reviewed-by: Jedrzej Nowacki --- src/script/api/qscriptengineagent.cpp | 3 + .../qscriptengineagent/tst_qscriptengineagent.cpp | 83 ++++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/src/script/api/qscriptengineagent.cpp b/src/script/api/qscriptengineagent.cpp index 28905e8..0b5828a 100644 --- a/src/script/api/qscriptengineagent.cpp +++ b/src/script/api/qscriptengineagent.cpp @@ -134,9 +134,12 @@ void QScriptEngineAgentPrivate::returnEvent(const JSC::DebuggerCallFrame& frame, void QScriptEngineAgentPrivate::exceptionThrow(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, bool hasHandler) { JSC::CallFrame *oldFrame = engine->currentFrame; + int oldAgentLineNumber = engine->agentLineNumber; engine->currentFrame = frame.callFrame(); QScriptValue value(engine->scriptValueFromJSCValue(frame.exception())); + engine->agentLineNumber = value.property(QLatin1String("lineNumber")).toInt32(); q_ptr->exceptionThrow(sourceID, value, hasHandler); + engine->agentLineNumber = oldAgentLineNumber; engine->currentFrame = oldFrame; engine->setCurrentException(value); }; diff --git a/tests/auto/qscriptengineagent/tst_qscriptengineagent.cpp b/tests/auto/qscriptengineagent/tst_qscriptengineagent.cpp index a0f10dd..ed00b96 100644 --- a/tests/auto/qscriptengineagent/tst_qscriptengineagent.cpp +++ b/tests/auto/qscriptengineagent/tst_qscriptengineagent.cpp @@ -116,6 +116,8 @@ private slots: void evaluateProgram_SyntaxError(); void evaluateNullProgram(); void QTBUG6108(); + void backtraces_data(); + void backtraces(); private: double m_testProperty; @@ -2379,5 +2381,86 @@ void tst_QScriptEngineAgent::QTBUG6108() QCOMPARE(spy->at(4).scriptId, spy->at(0).scriptId); } +class BacktraceSpy : public QScriptEngineAgent +{ +public: + BacktraceSpy(QScriptEngine *engine, const QStringList &expectedbacktrace, int breakpoint) + : QScriptEngineAgent(engine), expectedbacktrace(expectedbacktrace), breakpoint(breakpoint), ok(false) {} + + QStringList expectedbacktrace; + int breakpoint; + bool ok; + +protected: + + void exceptionThrow(qint64 , const QScriptValue &, bool) + { check(); } + + void positionChange(qint64 , int lineNumber, int ) + { + if (lineNumber == breakpoint) + check(); + } + +private: + void check() + { + QCOMPARE(engine()->currentContext()->backtrace(), expectedbacktrace); + ok = true; + } +}; + + +void tst_QScriptEngineAgent::backtraces_data() +{ + QTest::addColumn("code"); + QTest::addColumn("breakpoint"); + QTest::addColumn("expectedbacktrace"); + + { + QString source( + "function foo() {\n" + " var a = 5\n" + "}\n" + "foo('hello', { })\n" + "var r = 0;"); + + QStringList expected; + expected + << "foo('hello', [object Object]) at filename.js:2" + << "() at filename.js:4"; + QTest::newRow("simple breakpoint") << source << 2 << expected; + } + + { + QString source( + "function foo() {\n" + " error = err\n" //this must throw + "}\n" + "foo('hello', { })\n" + "var r = 0;"); + + QStringList expected; + expected + << "foo('hello', [object Object]) at filename.js:2" + << "() at filename.js:4"; + QTest::newRow("throw because of error") << source << -100 << expected; + } +} + +void tst_QScriptEngineAgent::backtraces() +{ + QFETCH(QString, code); + QFETCH(int, breakpoint); + QFETCH(QStringList, expectedbacktrace); + + QScriptEngine eng; + BacktraceSpy *spy = new BacktraceSpy(&eng, expectedbacktrace, breakpoint); + eng.setAgent(spy); + QLatin1String filename("filename.js"); + eng.evaluate(code, filename); + QVERIFY(spy->ok); +} + QTEST_MAIN(tst_QScriptEngineAgent) #include "tst_qscriptengineagent.moc" -- cgit v0.12 From 1b0bc13c14083d6146517ba1d8a63a6a503733b9 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 23 Jul 2010 19:04:42 +0200 Subject: Stabilize tst_qlineedit.cpp --- tests/auto/qlineedit/tst_qlineedit.cpp | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/tests/auto/qlineedit/tst_qlineedit.cpp b/tests/auto/qlineedit/tst_qlineedit.cpp index e0747f8..8951130 100644 --- a/tests/auto/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/qlineedit/tst_qlineedit.cpp @@ -3716,18 +3716,26 @@ void tst_QLineEdit::taskQTBUG_7395_readOnlyShortcut() void tst_QLineEdit::QTBUG697_paletteCurrentColorGroup() { - testWidget->setText(" "); - QPalette p = testWidget->palette(); + QLineEdit le; + le.setText(" "); + QPalette p = le.palette(); p.setBrush(QPalette::Active, QPalette::Highlight, Qt::green); p.setBrush(QPalette::Inactive, QPalette::Highlight, Qt::red); - testWidget->setPalette(p); - testWidget->selectAll(); - QImage img(testWidget->rect().size(),QImage::Format_ARGB32 ); - testWidget->render(&img); - QCOMPARE(img.pixel(10, testWidget->height()/2), QColor(Qt::green).rgb()); + le.setPalette(p); + + le.show(); + QApplication::setActiveWindow(&le); + QTest::qWaitForWindowShown(&le); + le.setFocus(); + QTRY_VERIFY(le.hasFocus()); + le.selectAll(); + + QImage img(le.size(),QImage::Format_ARGB32 ); + le.render(&img); + QCOMPARE(img.pixel(10, le.height()/2), QColor(Qt::green).rgb()); QApplication::setActiveWindow(0); - testWidget->render(&img); - QCOMPARE(img.pixel(10, testWidget->height()/2), QColor(Qt::red).rgb()); + le.render(&img); + QCOMPARE(img.pixel(10, le.height()/2), QColor(Qt::red).rgb()); } QTEST_MAIN(tst_QLineEdit) -- cgit v0.12 From 5878a161e8a4b332fc056874aee4833352dedaa9 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 26 Jul 2010 10:50:26 +0200 Subject: Skip tst_QLineEdit::QTBUG697_paletteCurrentColorGroup on non-x11 --- tests/auto/qlineedit/tst_qlineedit.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/auto/qlineedit/tst_qlineedit.cpp b/tests/auto/qlineedit/tst_qlineedit.cpp index 8951130..717b32d 100644 --- a/tests/auto/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/qlineedit/tst_qlineedit.cpp @@ -3716,6 +3716,9 @@ void tst_QLineEdit::taskQTBUG_7395_readOnlyShortcut() void tst_QLineEdit::QTBUG697_paletteCurrentColorGroup() { +#ifndef Q_WS_X11 + QSKIP("Only tested on X11", SkipAll); +#endif QLineEdit le; le.setText(" "); QPalette p = le.palette(); -- cgit v0.12 From efa190848270347362a1caab739961d185561627 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 26 Jul 2010 12:07:16 +0200 Subject: Use the appropriate CPUID bitmap for detecting SSE3 etc This information actually comes from ECX after CPUID(0x00000001), not EDX after CPUID(0x80000001) --- src/corelib/tools/qsimd.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp index aa2ee47..ea90b66 100644 --- a/src/corelib/tools/qsimd.cpp +++ b/src/corelib/tools/qsimd.cpp @@ -91,6 +91,7 @@ uint qDetectCPUFeatures() features = MMX|SSE|SSE2; #elif defined(__i386__) || defined(_M_IX86) unsigned int extended_result = 0; + unsigned int feature_result = 0; uint result = 0; /* see p. 118 of amd64 instruction set manual Vol3 */ #if defined(Q_CC_GNU) @@ -112,7 +113,8 @@ uint qDetectCPUFeatures() "1:\n" "pop %%ebx\n" "mov %%edx, %0\n" - : "=r" (result) + "mov %%ecx, %1\n" + : "=r" (result), "=r" (feature_result) : : "%eax", "%ecx", "%edx" ); @@ -164,6 +166,7 @@ uint qDetectCPUFeatures() mov eax, 1 cpuid mov result, edx + mov feature_result, ecx skip: pop edx pop ecx @@ -218,15 +221,15 @@ uint qDetectCPUFeatures() features |= SSE; if (result & (1u << 26)) features |= SSE2; - if (extended_result & (1u)) + if (feature_result & (1u)) features |= SSE3; - if (extended_result & (1u << 9)) + if (feature_result & (1u << 9)) features |= SSSE3; - if (extended_result & (1u << 19)) + if (feature_result & (1u << 19)) features |= SSE4_1; - if (extended_result & (1u << 20)) + if (feature_result & (1u << 20)) features |= SSE4_2; - if (extended_result & (1u << 28)) + if (feature_result & (1u << 28)) features |= AVX; #endif // i386 -- cgit v0.12 From 7500a3de97d828a05315cdac03df32a506f806c4 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 26 Jul 2010 12:26:05 +0200 Subject: CPU feature detection for x86_64 Previously we've only done feature detection for i386 CPUs since we can assume all x86_64 processors have MMX/3DNOW/SSE2. No assumptions can be made about SSE3 and newer features, so now that we start using those, we need to check for their presence with CPUID on 64-bit processors as well. --- src/corelib/tools/qsimd.cpp | 67 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp index ea90b66..5aa7217 100644 --- a/src/corelib/tools/qsimd.cpp +++ b/src/corelib/tools/qsimd.cpp @@ -234,6 +234,73 @@ uint qDetectCPUFeatures() #endif // i386 +#if defined(__x86_64__) || defined(Q_OS_WIN64) + uint feature_result = 0; + +#if defined(Q_CC_GNU) + asm ("push %%rbx\n" + "pushf\n" + "pop %%rax\n" + "mov %%eax, %%ebx\n" + "xor $0x00200000, %%eax\n" + "push %%rax\n" + "popf\n" + "pushf\n" + "pop %%rax\n" + "xor %%edx, %%edx\n" + "xor %%ebx, %%eax\n" + "jz 1f\n" + + "mov $0x00000001, %%eax\n" + "cpuid\n" + "1:\n" + "pop %%rbx\n" + "mov %%ecx, %0\n" + : "=r" (feature_result) + : + : "%eax", "%ecx", "%edx" + ); +#elif defined (Q_OS_WIN64) + _asm { + push rax + push rbx + push rcx + push rdx + pushfd + pop rax + mov ebx, eax + xor eax, 00200000h + push rax + popfd + pushfd + pop rax + mov edx, 0 + xor eax, ebx + jz skip + + mov eax, 1 + cpuid + mov feature_result, ecx + skip: + pop rdx + pop rcx + pop rbx + pop rax + } +#endif + + if (feature_result & (1u)) + features |= SSE3; + if (feature_result & (1u << 9)) + features |= SSSE3; + if (feature_result & (1u << 19)) + features |= SSE4_1; + if (feature_result & (1u << 20)) + features |= SSE4_2; + if (feature_result & (1u << 28)) + features |= AVX; +#endif // x86_64 + #if defined(QT_HAVE_MMX) if (qgetenv("QT_NO_MMX").toInt()) features ^= MMX; -- cgit v0.12 From 38d8826503385f249cfd4d35382a79252de85873 Mon Sep 17 00:00:00 2001 From: Benjamin Poulain Date: Thu, 22 Jul 2010 14:48:19 +0200 Subject: Extend the build system to SSSE3 Extend the build of QtGui to include generic compilation of files specific to SSSE3. Also extend qsimd_p.h for the new #includes. --- src/corelib/tools/qsimd_p.h | 21 +++++++++++++++++++++ src/gui/gui.pro | 20 ++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h index 18394853..5ff0f97 100644 --- a/src/corelib/tools/qsimd_p.h +++ b/src/corelib/tools/qsimd_p.h @@ -72,6 +72,27 @@ QT_BEGIN_HEADER # include #endif +// SSE3 intrinsics +#if defined(QT_HAVE_SSE3) && (defined(__SSE3__) || defined(Q_CC_MSVC)) +#include +#endif + +// SSSE3 intrinsics +#if defined(QT_HAVE_SSSE3) && (defined(__SSSE3__) || defined(Q_CC_MSVC)) +#include +#endif + +// SSE4.1 and SSE4.2 intrinsics +#if (defined(QT_HAVE_SSE4_1) || defined(QT_HAVE_SSE4_2)) && (defined(__SSE4_1__) || defined(Q_CC_MSVC)) +#include +#endif + +// AVX intrinsics +#if defined(QT_HAVE_AVX) && (defined(__AVX__) || defined(Q_CC_MSVC)) +#include +#endif + + #if !defined(QT_BOOTSTRAPPED) && (!defined(Q_CC_MSVC) || (defined(_M_X64) || _M_IX86_FP == 2)) #define QT_ALWAYS_HAVE_SSE2 #endif diff --git a/src/gui/gui.pro b/src/gui/gui.pro index 3aee078..1b43ef2 100644 --- a/src/gui/gui.pro +++ b/src/gui/gui.pro @@ -187,6 +187,25 @@ contains(QMAKE_MAC_XARCH, no) { silent:sse2_compiler.commands = @echo compiling[sse2] ${QMAKE_FILE_IN} && $$sse2_compiler.commands QMAKE_EXTRA_COMPILERS += sse2_compiler } + ssse3 { + ssse3_compiler.commands = $$QMAKE_CXX -c -Winline + + mac { + ssse3_compiler.commands += -Xarch_i386 -mssse3 + ssse3_compiler.commands += -Xarch_x86_64 -mssse3 + } else { + ssse3_compiler.commands += -mssse3 + } + + ssse3_compiler.commands += $(CXXFLAGS) $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT} + ssse3_compiler.dependency_type = TYPE_C + ssse3_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)} + ssse3_compiler.input = SSSE3_SOURCES + ssse3_compiler.variable_out = OBJECTS + ssse3_compiler.name = compiling[ssse3] ${QMAKE_FILE_IN} + silent:ssse3_compiler.commands = @echo compiling[ssse3] ${QMAKE_FILE_IN} && $$ssse3_compiler.commands + QMAKE_EXTRA_COMPILERS += ssse3_compiler + } iwmmxt { iwmmxt_compiler.commands = $$QMAKE_CXX -c -Winline iwmmxt_compiler.commands += -mcpu=iwmmxt @@ -205,6 +224,7 @@ contains(QMAKE_MAC_XARCH, no) { 3dnow:sse: SOURCES += $$SSE3DNOW_SOURCES sse: SOURCES += $$SSE_SOURCES sse2: SOURCES += $$SSE2_SOURCES + ssse3: SOURCES += $$SSSE3_SOURCES iwmmxt: SOURCES += $$IWMMXT_SOURCES } } -- cgit v0.12 From 90642dd2b6b14c39cc6178f1161331895809b342 Mon Sep 17 00:00:00 2001 From: Benjamin Poulain Date: Fri, 23 Jul 2010 16:14:49 +0200 Subject: Use SSSE3 to convert from RGB888 to RGB32 Converting from RGB encoded on 24bits to RGB encoded on 32 bits is quite inefficient. This type of conversion is common for some image format. The patch implement the conversion with SSSE3. This reduce by 3 the number of instructions, pushing the bottleneck to memory bandwidth. On Atom N450, the new benchmark is 40% faster for scanlines of 2000 pixels, 30% faster for scanlines of 32 pixels, and 15% slower for small images (3 and 8px). Reviewed-by: Olivier Goffart --- src/gui/image/image.pri | 1 + src/gui/image/qimage.cpp | 10 +- src/gui/image/qimage_ssse3.cpp | 150 +++++++++++++++++++++ tests/auto/qimage/tst_qimage.cpp | 22 +++ tests/benchmarks/gui/image/image.pro | 1 + .../image/qimageconversion/qimageconversion.pro | 10 ++ .../qimageconversion/tst_qimageconversion.cpp | 108 +++++++++++++++ 7 files changed, 301 insertions(+), 1 deletion(-) create mode 100644 src/gui/image/qimage_ssse3.cpp create mode 100644 tests/benchmarks/gui/image/qimageconversion/qimageconversion.pro create mode 100644 tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp diff --git a/src/gui/image/image.pri b/src/gui/image/image.pri index 3a02d56..b20a04f 100644 --- a/src/gui/image/image.pri +++ b/src/gui/image/image.pri @@ -95,3 +95,4 @@ contains(QT_CONFIG, gif):include($$PWD/qgifhandler.pri) # SIMD SSE2_SOURCES += image/qimage_sse2.cpp +SSSE3_SOURCES += image/qimage_ssse3.cpp diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 713e765..30cf758 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -3354,7 +3354,7 @@ CONVERT_DECL(qargb4444, quint32) // first index source, second dest -static const Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormats] = +static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormats] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 @@ -3761,6 +3761,14 @@ void qInitImageConversions() inplace_converter_map[QImage::Format_ARGB32][QImage::Format_ARGB32_Premultiplied] = convert_ARGB_to_ARGB_PM_inplace_sse2; } #endif +#ifdef QT_HAVE_SSSE3 + if (features & SSSE3) { + extern void convert_RGB888_to_RGB32_ssse3(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags); + converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_ssse3; + converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_ssse3; + converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_ssse3; + } +#endif } /*! diff --git a/src/gui/image/qimage_ssse3.cpp b/src/gui/image/qimage_ssse3.cpp new file mode 100644 index 0000000..1c664f2 --- /dev/null +++ b/src/gui/image/qimage_ssse3.cpp @@ -0,0 +1,150 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include + +#ifdef QT_HAVE_SSSE3 + +#include +QT_BEGIN_NAMESPACE + +// Convert a scanline of RGB888 (src) to RGB32 (dst) +// src must be at least len * 3 bytes +// dst must be at least len * 4 bytes +inline void convert_rgb888_to_rgb32_ssse3(quint32 *dst, const uchar *src, int len) +{ + quint32 *const end = dst + len; + + // Prologue, align dst to 16 bytes. The alignement is done on dst because it has 4 store() + // for each 3 load() of src. + const int offsetToAlignOn16Bytes = (4 - ((reinterpret_cast(dst) >> 2) & 0x3)) & 0x3; + const int prologLength = qMin(len, offsetToAlignOn16Bytes); + + for (int i = 0; i < prologLength; ++i) { + *dst++ = qRgb(src[0], src[1], src[2]); + src += 3; + } + + // Mask the 4 first colors of the RGB888 vector + const __m128i shuffleMask = _mm_set_epi8(0xff, 9, 10, 11, 0xff, 6, 7, 8, 0xff, 3, 4, 5, 0xff, 0, 1, 2); + + // Mask the 4 last colors of a RGB888 vector with an offset of 1 (so the last 3 bytes are RGB) + const __m128i shuffleMaskEnd = _mm_set_epi8(0xff, 13, 14, 15, 0xff, 10, 11, 12, 0xff, 7, 8, 9, 0xff, 4, 5, 6); + + // Mask to have alpha = 0xff + const __m128i alphaMask = _mm_set1_epi32(0xff000000); + + __m128i *inVectorPtr = (__m128i *)src; + __m128i *dstVectorPtr = (__m128i *)dst; + + const int simdRoundCount = (len - prologLength) / 16; // one iteration in the loop converts 16 pixels + for (int i = 0; i < simdRoundCount; ++i) { + /* + RGB888 has 5 pixels per vector, + 1 byte from the next pixel. The idea here is + to load vectors of RGB888 and use palignr to select a vector out of two vectors. + + After 3 loads of RGB888 and 3 stores of RGB32, we have 4 pixels left in the last + vector of RGB888, we can mask it directly to get a last store or RGB32. After that, + the first next byte is a R, and we can loop for the next 16 pixels. + + The conversion itself is done with a byte permutation (pshufb). + */ + __m128i firstSrcVector = _mm_lddqu_si128(inVectorPtr); + __m128i outputVector = _mm_shuffle_epi8(firstSrcVector, shuffleMask); + _mm_store_si128(dstVectorPtr, _mm_or_si128(outputVector, alphaMask)); + ++inVectorPtr; + ++dstVectorPtr; + + // There are 4 unused bytes left in srcVector, we need to load the next 16 bytes + // and load the next input with palignr + __m128i secondSrcVector = _mm_lddqu_si128(inVectorPtr); + __m128i srcVector = _mm_alignr_epi8(secondSrcVector, firstSrcVector, 12); + outputVector = _mm_shuffle_epi8(srcVector, shuffleMask); + _mm_store_si128(dstVectorPtr, _mm_or_si128(outputVector, alphaMask)); + ++inVectorPtr; + ++dstVectorPtr; + firstSrcVector = secondSrcVector; + + // We now have 8 unused bytes left in firstSrcVector + secondSrcVector = _mm_lddqu_si128(inVectorPtr); + srcVector = _mm_alignr_epi8(secondSrcVector, firstSrcVector, 8); + outputVector = _mm_shuffle_epi8(srcVector, shuffleMask); + _mm_store_si128(dstVectorPtr, _mm_or_si128(outputVector, alphaMask)); + ++inVectorPtr; + ++dstVectorPtr; + + // There are now 12 unused bytes in firstSrcVector. + // We can mask them directly, almost there. + outputVector = _mm_shuffle_epi8(secondSrcVector, shuffleMaskEnd); + _mm_store_si128(dstVectorPtr, _mm_or_si128(outputVector, alphaMask)); + ++dstVectorPtr; + } + src = (uchar *)inVectorPtr; + dst = (quint32 *)dstVectorPtr; + + while (dst != end) { + *dst++ = qRgb(src[0], src[1], src[2]); + src += 3; + } +} + +void convert_RGB888_to_RGB32_ssse3(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_RGB888); + Q_ASSERT(dest->format == QImage::Format_RGB32 || dest->format == QImage::Format_ARGB32 || dest->format == QImage::Format_ARGB32_Premultiplied); + Q_ASSERT(src->width == dest->width); + Q_ASSERT(src->height == dest->height); + + const uchar *src_data = (uchar *) src->data; + quint32 *dest_data = (quint32 *) dest->data; + + for (int i = 0; i < src->height; ++i) { + convert_rgb888_to_rgb32_ssse3(dest_data, src_data, src->width); + src_data += src->bytes_per_line; + dest_data = (quint32 *)((uchar*)dest_data + dest->bytes_per_line); + } +} + +QT_END_NAMESPACE + +#endif // QT_HAVE_SSSE3 diff --git a/tests/auto/qimage/tst_qimage.cpp b/tests/auto/qimage/tst_qimage.cpp index 5052114..1330d96 100644 --- a/tests/auto/qimage/tst_qimage.cpp +++ b/tests/auto/qimage/tst_qimage.cpp @@ -83,6 +83,8 @@ private slots: void convertToFormat_data(); void convertToFormat(); + void convertToFormatRgb888ToRGB32(); + void createAlphaMask_data(); void createAlphaMask(); #ifndef QT_NO_IMAGE_HEURISTIC_MASK @@ -799,6 +801,26 @@ void tst_QImage::convertToFormat() QFile::remove(QLatin1String("expected2.xpm")); } +void tst_QImage::convertToFormatRgb888ToRGB32() +{ + // 545 so width % 4 != 0. This ensure there is padding at the end of the scanlines + const int height = 545; + const int width = 545; + QImage source(width, height, QImage::Format_RGB888); + for (int y = 0; y < height; ++y) { + uchar *srcPixels = source.scanLine(y); + for (int x = 0; x < width * 3; ++x) + srcPixels[x] = x; + } + + QImage rgb32Image = source.convertToFormat(QImage::Format_RGB888); + QCOMPARE(rgb32Image.format(), QImage::Format_RGB888); + for (int x = 0; x < width; ++x) { + for (int y = 0; y < height; ++y) + QCOMPARE(rgb32Image.pixel(x, y), source.pixel(x, y)); + } +} + void tst_QImage::createAlphaMask_data() { QTest::addColumn("x"); diff --git a/tests/benchmarks/gui/image/image.pro b/tests/benchmarks/gui/image/image.pro index 3094e72..a8c6732 100644 --- a/tests/benchmarks/gui/image/image.pro +++ b/tests/benchmarks/gui/image/image.pro @@ -1,6 +1,7 @@ TEMPLATE = subdirs SUBDIRS = \ blendbench \ + qimageconversion \ qimagereader \ qpixmap \ qpixmapcache diff --git a/tests/benchmarks/gui/image/qimageconversion/qimageconversion.pro b/tests/benchmarks/gui/image/qimageconversion/qimageconversion.pro new file mode 100644 index 0000000..ec50d98 --- /dev/null +++ b/tests/benchmarks/gui/image/qimageconversion/qimageconversion.pro @@ -0,0 +1,10 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_bench_imageConversion + +SOURCES += tst_qimageconversion.cpp + +!contains(QT_CONFIG, no-gif):DEFINES += QTEST_HAVE_GIF +!contains(QT_CONFIG, no-jpeg):DEFINES += QTEST_HAVE_JPEG +!contains(QT_CONFIG, no-mng):DEFINES += QTEST_HAVE_MNG +!contains(QT_CONFIG, no-tiff):DEFINES += QTEST_HAVE_TIFF diff --git a/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp b/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp new file mode 100644 index 0000000..1c76d46 --- /dev/null +++ b/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +Q_DECLARE_METATYPE(QImage) + +class tst_QImageConversion : public QObject +{ + Q_OBJECT +private slots: + void convertRgb888ToRGB32_data(); + void convertRgb888ToRGB32(); + +private: + QImage generateImageRgb888(int width, int height); +}; + +void tst_QImageConversion::convertRgb888ToRGB32_data() +{ + QTest::addColumn("inputImage"); + // height = 5000 to get interesting timing. + + // 3 pixels wide -> smaller than regular vector of 128bits + QTest::newRow("width: 3px; height: 5000px;") << generateImageRgb888(3, 5000); + + // 8 pixels wide -> potential for 2 vectors + QTest::newRow("width: 8px; height: 5000px;") << generateImageRgb888(3, 5000); + + // 16 pixels, minimum for the SSSE3 implementation + QTest::newRow("width: 16px; height: 5000px;") << generateImageRgb888(16, 5000); + + // 50 pixels, more realistic use case + QTest::newRow("width: 50px; height: 5000px;") << generateImageRgb888(50, 5000); + + // 2000 pixels -> typical values for pictures + QTest::newRow("width: 2000px; height: 5000px;") << generateImageRgb888(2000, 5000); +} + +void tst_QImageConversion::convertRgb888ToRGB32() +{ + QFETCH(QImage, inputImage); + + QBENCHMARK { + volatile QImage output = inputImage.convertToFormat(QImage::Format_RGB32); + // we need the volatile and the following to make sure the compiler does not do + // anything stupid :) + (void)output; + } +} + +/* + Fill a RGB888 image with "random" pixel values. + */ +QImage tst_QImageConversion::generateImageRgb888(int width, int height) +{ + QImage image(width, height, QImage::Format_RGB888); + const int byteWidth = width * 3; + + for (int y = 0; y < image.height(); ++y) { + uchar *scanline = image.scanLine(y); + for (int x = 0; x < byteWidth; ++x) + scanline[x] = x ^ y; + } + return image; +} + +QTEST_MAIN(tst_QImageConversion) +#include "tst_qimageconversion.moc" -- cgit v0.12 From 3a08c5b1682e211bf664c21850187e2b15e89c23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Mon, 26 Jul 2010 15:06:57 +0200 Subject: QGLBuffer::bind()/release() should not be const functions. This is more or less the same as in the QGLFramebufferObject::bind()/release() case. Task-number: QTBUG-12319 Reviewed-by: Kim --- src/opengl/qglbuffer.cpp | 4 ++-- src/opengl/qglbuffer.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/opengl/qglbuffer.cpp b/src/opengl/qglbuffer.cpp index d6e0109..5f0aed4 100644 --- a/src/opengl/qglbuffer.cpp +++ b/src/opengl/qglbuffer.cpp @@ -416,7 +416,7 @@ void QGLBuffer::allocate(const void *data, int count) \sa release(), create() */ -bool QGLBuffer::bind() const +bool QGLBuffer::bind() { #ifndef QT_NO_DEBUG if (!isCreated()) @@ -448,7 +448,7 @@ bool QGLBuffer::bind() const \sa bind() */ -void QGLBuffer::release() const +void QGLBuffer::release() { #ifndef QT_NO_DEBUG if (!isCreated()) diff --git a/src/opengl/qglbuffer.h b/src/opengl/qglbuffer.h index a1b45ff..9867f31 100644 --- a/src/opengl/qglbuffer.h +++ b/src/opengl/qglbuffer.h @@ -101,8 +101,8 @@ public: void destroy(); - bool bind() const; - void release() const; + bool bind(); + void release(); static void release(QGLBuffer::Type type); -- cgit v0.12 From a882a46b1c60e5774ade68eaac60922b19a08835 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 26 Jul 2010 14:03:00 +0200 Subject: Doc: use const& in foreach when applicable. Const reference are slightly faster than doing a copy of the object on each iteration. Lead by example by having this pattern right in our documentation --- doc/src/snippets/code/doc_src_containers.qdoc | 8 ++++---- doc/src/snippets/code/doc_src_qalgorithms.qdoc | 2 +- doc/src/snippets/code/doc_src_qset.qdoc | 2 +- doc/src/snippets/code/doc_src_qt4-tulip.qdoc | 2 +- doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp | 2 +- doc/src/snippets/code/src_gui_kernel_qapplication.cpp | 4 ++-- doc/src/snippets/code/src_network_kernel_qhostinfo.cpp | 2 +- doc/src/snippets/code/src_network_ssl_qsslcertificate.cpp | 2 +- doc/src/snippets/droparea.cpp | 2 +- doc/src/snippets/picture/picture.cpp | 4 ++-- doc/src/snippets/qfontdatabase/main.cpp | 4 ++-- doc/src/snippets/qlistview-dnd/model.cpp | 4 ++-- doc/src/snippets/qstringlist/main.cpp | 2 +- doc/src/snippets/qtreeview-dnd/dragdropmodel.cpp | 2 +- doc/src/snippets/widgets-tutorial/nestedlayouts/main.cpp | 4 ++-- 15 files changed, 23 insertions(+), 23 deletions(-) diff --git a/doc/src/snippets/code/doc_src_containers.qdoc b/doc/src/snippets/code/doc_src_containers.qdoc index 5cf2aab..1f86f60 100644 --- a/doc/src/snippets/code/doc_src_containers.qdoc +++ b/doc/src/snippets/code/doc_src_containers.qdoc @@ -216,7 +216,7 @@ while (i.hasNext()) //! [17] QLinkedList list; ... -foreach (QString str, list) +foreach (const QString &str, list) qDebug() << str; //! [17] @@ -224,7 +224,7 @@ foreach (QString str, list) //! [18] QLinkedList list; ... -foreach (QString str, list) { +foreach (const QString &str, list) { if (str.isEmpty()) break; qDebug() << str; @@ -235,7 +235,7 @@ foreach (QString str, list) { //! [19] QMap map; ... -foreach (QString str, map.keys()) +foreach (const QString &str, map.keys()) qDebug() << str << ":" << map.value(str); //! [19] @@ -243,7 +243,7 @@ foreach (QString str, map.keys()) //! [20] QMultiMap map; ... -foreach (QString str, map.uniqueKeys()) { +foreach (const QString &str, map.uniqueKeys()) { foreach (int i, map.values(str)) qDebug() << str << ":" << i; } diff --git a/doc/src/snippets/code/doc_src_qalgorithms.qdoc b/doc/src/snippets/code/doc_src_qalgorithms.qdoc index 78634a2..f5a73c6 100644 --- a/doc/src/snippets/code/doc_src_qalgorithms.qdoc +++ b/doc/src/snippets/code/doc_src_qalgorithms.qdoc @@ -217,7 +217,7 @@ QStringList list; list << "AlPha" << "beTA" << "gamma" << "DELTA"; QMap map; -foreach (QString str, list) +foreach (const QString &str, list) map.insert(str.toLower(), str); list = map.values(); diff --git a/doc/src/snippets/code/doc_src_qset.qdoc b/doc/src/snippets/code/doc_src_qset.qdoc index ac48edb..c6e1933 100644 --- a/doc/src/snippets/code/doc_src_qset.qdoc +++ b/doc/src/snippets/code/doc_src_qset.qdoc @@ -80,7 +80,7 @@ while (i != set.constEnd()) { //! [6] QSet set; ... -foreach (QString value, set) +foreach (const QString &value, set) qDebug() << value; //! [6] diff --git a/doc/src/snippets/code/doc_src_qt4-tulip.qdoc b/doc/src/snippets/code/doc_src_qt4-tulip.qdoc index 3d88a0d..f29d3ba 100644 --- a/doc/src/snippets/code/doc_src_qt4-tulip.qdoc +++ b/doc/src/snippets/code/doc_src_qt4-tulip.qdoc @@ -47,7 +47,7 @@ foreach (variable, container) //! [1] QList list; ... -foreach (QString str, list) +foreach (const QString &str, list) cout << str.ascii() << endl; //! [1] diff --git a/doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp b/doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp index 2e64505..fb62347 100644 --- a/doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp +++ b/doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp @@ -51,7 +51,7 @@ connect(quitButton, SIGNAL(clicked()), &app, SLOT(quit())); //! [2] -foreach (QString path, app.libraryPaths()) +foreach (const QString &path, app.libraryPaths()) do_something(path); //! [2] diff --git a/doc/src/snippets/code/src_gui_kernel_qapplication.cpp b/doc/src/snippets/code/src_gui_kernel_qapplication.cpp index c93a25c..766b249 100644 --- a/doc/src/snippets/code/src_gui_kernel_qapplication.cpp +++ b/doc/src/snippets/code/src_gui_kernel_qapplication.cpp @@ -158,13 +158,13 @@ appname -session id //! [10] -foreach (QString command, mySession.restartCommand()) +foreach (const QString &command, mySession.restartCommand()) do_something(command); //! [10] //! [11] -foreach (QString command, mySession.discardCommand()) +foreach (const QString &command, mySession.discardCommand()) do_something(command); //! [11] diff --git a/doc/src/snippets/code/src_network_kernel_qhostinfo.cpp b/doc/src/snippets/code/src_network_kernel_qhostinfo.cpp index 3871289..99deb20 100644 --- a/doc/src/snippets/code/src_network_kernel_qhostinfo.cpp +++ b/doc/src/snippets/code/src_network_kernel_qhostinfo.cpp @@ -68,7 +68,7 @@ void MyWidget::lookedUp(const QHostInfo &host) return; } - foreach (QHostAddress address, host.addresses()) + foreach (const QHostAddress &address, host.addresses()) qDebug() << "Found address:" << address.toString(); } //! [3] diff --git a/doc/src/snippets/code/src_network_ssl_qsslcertificate.cpp b/doc/src/snippets/code/src_network_ssl_qsslcertificate.cpp index 5c9421f..937dbb9 100644 --- a/doc/src/snippets/code/src_network_ssl_qsslcertificate.cpp +++ b/doc/src/snippets/code/src_network_ssl_qsslcertificate.cpp @@ -39,7 +39,7 @@ ****************************************************************************/ //! [0] -foreach (QSslCertificate cert, QSslCertificate::fromPath("C:/ssl/certificate.*.pem", QSsl::Pem, +foreach (const QSslCertificate &cert, QSslCertificate::fromPath("C:/ssl/certificate.*.pem", QSsl::Pem, QRegExp::Wildcard)) { qDebug() << cert.issuerInfo(QSslCertificate::Organization); } diff --git a/doc/src/snippets/droparea.cpp b/doc/src/snippets/droparea.cpp index bbcf82d..bb49dd7 100644 --- a/doc/src/snippets/droparea.cpp +++ b/doc/src/snippets/droparea.cpp @@ -130,7 +130,7 @@ QPixmap DropArea::extractPixmap(const QByteArray &data, const QString &format) QList imageFormats = QImageReader::supportedImageFormats(); QPixmap pixmap; - foreach (QByteArray imageFormat, imageFormats) { + foreach (const QByteArray &imageFormat, imageFormats) { if (format.mid(6) == QString(imageFormat)) { pixmap.loadFromData(data, imageFormat); break; diff --git a/doc/src/snippets/picture/picture.cpp b/doc/src/snippets/picture/picture.cpp index 0c5712a..5283978 100644 --- a/doc/src/snippets/picture/picture.cpp +++ b/doc/src/snippets/picture/picture.cpp @@ -76,7 +76,7 @@ int main() // FORMATS //! [2] QStringList list = QPicture::inputFormatList(); - foreach (QString string, list) + foreach (const QString &string, list) myProcessing(string); //! [2] } @@ -85,7 +85,7 @@ int main() // OUTPUT //! [3] QStringList list = QPicture::outputFormatList(); - foreach (QString string, list) + foreach (const QString &string, list) myProcessing(string); //! [3] } diff --git a/doc/src/snippets/qfontdatabase/main.cpp b/doc/src/snippets/qfontdatabase/main.cpp index 7f939de..1b8ff42 100644 --- a/doc/src/snippets/qfontdatabase/main.cpp +++ b/doc/src/snippets/qfontdatabase/main.cpp @@ -50,11 +50,11 @@ int main(int argc, char **argv) fontTree.setColumnCount(2); fontTree.setHeaderLabels(QStringList() << "Font" << "Smooth Sizes"); - foreach (QString family, database.families()) { + foreach (const QString &family, database.families()) { QTreeWidgetItem *familyItem = new QTreeWidgetItem(&fontTree); familyItem->setText(0, family); - foreach (QString style, database.styles(family)) { + foreach (const QString &style, database.styles(family)) { QTreeWidgetItem *styleItem = new QTreeWidgetItem(familyItem); styleItem->setText(0, style); diff --git a/doc/src/snippets/qlistview-dnd/model.cpp b/doc/src/snippets/qlistview-dnd/model.cpp index d310c03..bca71ee 100644 --- a/doc/src/snippets/qlistview-dnd/model.cpp +++ b/doc/src/snippets/qlistview-dnd/model.cpp @@ -109,7 +109,7 @@ bool DragDropListModel::dropMimeData(const QMimeData *data, //! [6] insertRows(beginRow, rows, QModelIndex()); - foreach (QString text, newItems) { + foreach (const QString &text, newItems) { QModelIndex idx = index(beginRow, 0, QModelIndex()); setData(idx, text); beginRow++; @@ -139,7 +139,7 @@ QMimeData *DragDropListModel::mimeData(const QModelIndexList &indexes) const QDataStream stream(&encodedData, QIODevice::WriteOnly); - foreach (QModelIndex index, indexes) { + foreach (const QModelIndex &index, indexes) { if (index.isValid()) { QString text = data(index, Qt::DisplayRole).toString(); stream << text; diff --git a/doc/src/snippets/qstringlist/main.cpp b/doc/src/snippets/qstringlist/main.cpp index 76785f1..9ada319 100644 --- a/doc/src/snippets/qstringlist/main.cpp +++ b/doc/src/snippets/qstringlist/main.cpp @@ -118,7 +118,7 @@ Widget::Widget(QWidget *parent) result.clear(); //! [12] - foreach (QString str, list) { + foreach (const QString &str, list) { if (str.contains("Bill")) result += str; } diff --git a/doc/src/snippets/qtreeview-dnd/dragdropmodel.cpp b/doc/src/snippets/qtreeview-dnd/dragdropmodel.cpp index 2d01240..620a716 100644 --- a/doc/src/snippets/qtreeview-dnd/dragdropmodel.cpp +++ b/doc/src/snippets/qtreeview-dnd/dragdropmodel.cpp @@ -123,7 +123,7 @@ QMimeData *DragDropModel::mimeData(const QModelIndexList &indexes) const QDataStream stream(&encodedData, QIODevice::WriteOnly); - foreach (QModelIndex index, indexes) { + foreach (const QModelIndex &index, indexes) { if (index.isValid()) { QString text = data(index, Qt::DisplayRole).toString(); stream << index.internalId() << index.row() << index.column() << text; diff --git a/doc/src/snippets/widgets-tutorial/nestedlayouts/main.cpp b/doc/src/snippets/widgets-tutorial/nestedlayouts/main.cpp index 6a49be8..35d2fa7 100644 --- a/doc/src/snippets/widgets-tutorial/nestedlayouts/main.cpp +++ b/doc/src/snippets/widgets-tutorial/nestedlayouts/main.cpp @@ -72,9 +72,9 @@ int main(int argc, char *argv[]) << (QStringList() << "David Bradley" << "42") << (QStringList() << "Knut Walters" << "25") << (QStringList() << "Andrea Jones" << "34"); - foreach (QStringList row, rows) { + foreach (const QStringList &row, rows) { QList items; - foreach (QString text, row) + foreach (const QString &text, row) items.append(new QStandardItem(text)); model.appendRow(items); } -- cgit v0.12 From 2ecb7eebdc950eb559b9203d70077301b8b5a3b1 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 26 Jul 2010 15:40:10 +0200 Subject: QDeclarativeEngineDebugServer: Fix crash when trying to update non-properties. QDeclarativePropertyPrivate::setBinding would delete the binding if it cannot set the property. Then the call to binding->update() would crash. So test for (property.isProperty()) before. Also this will display a warning in the application output if the property cannot be changed. Reviewed-by: Lasse Holmstedt --- src/declarative/qml/qdeclarativeenginedebug.cpp | 30 ++++++++++++------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/declarative/qml/qdeclarativeenginedebug.cpp b/src/declarative/qml/qdeclarativeenginedebug.cpp index 008d054..1837366 100644 --- a/src/declarative/qml/qdeclarativeenginedebug.cpp +++ b/src/declarative/qml/qdeclarativeenginedebug.cpp @@ -485,24 +485,22 @@ void QDeclarativeEngineDebugServer::setBinding(int objectId, if (object && context) { + QDeclarativeProperty property(object, propertyName, context); if (isLiteralValue) { - QDeclarativeProperty literalProperty(object, propertyName, context); - literalProperty.write(expression); + property.write(expression); + } else if (hasValidSignal(object, propertyName)) { + QDeclarativeExpression *declarativeExpression = new QDeclarativeExpression(context, object, expression.toString()); + QDeclarativePropertyPrivate::setSignalExpression(property, declarativeExpression); + } else if (property.isProperty()) { + QDeclarativeBinding *binding = new QDeclarativeBinding(expression.toString(), object, context); + binding->setTarget(property); + binding->setNotifyOnValueChanged(true); + QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::setBinding(property, binding); + if (oldBinding) + oldBinding->destroy(); + binding->update(); } else { - if (hasValidSignal(object, propertyName)) { - QDeclarativeProperty property(object, propertyName); - QDeclarativeExpression *declarativeExpression = new QDeclarativeExpression(context, object, expression.toString()); - QDeclarativePropertyPrivate::setSignalExpression(property, declarativeExpression); - } else { - QDeclarativeBinding *binding = new QDeclarativeBinding(expression.toString(), object, context); - QDeclarativeProperty property(object, propertyName, context); - binding->setTarget(property); - binding->setNotifyOnValueChanged(true); - QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::setBinding(property, binding); - if (oldBinding) - oldBinding->destroy(); - binding->update(); - } + qWarning() << "QDeclarativeEngineDebugServer::setBinding: unable to set property" << propertyName << "on object" << object; } } } -- cgit v0.12 From d6203cfeb0e096575c1fc0254dddc07a3d65d24c Mon Sep 17 00:00:00 2001 From: Michael Dominic K Date: Wed, 21 Jul 2010 11:17:33 +0200 Subject: Do check after all if we have partialUpdateSupport. Task-number: QTBUG-12266 Merge-request: 752 Reviewed-by: Trond --- src/opengl/qwindowsurface_gl.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index e9da452..6b82ed3 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -494,10 +494,9 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & } } #endif - if (d_ptr->paintedRegion.boundingRect() != geometry()) { - // Emits warning if not supported. Should never happen unless - // setPartialUpdateSupport(true) has been called. - context()->d_func()->swapRegion(&d_ptr->paintedRegion); + if (d_ptr->paintedRegion.boundingRect() != geometry() && + hasPartialUpdateSupport()) { + context()->d_func()->swapRegion(&d_ptr->paintedRegion); } else context()->swapBuffers(); -- cgit v0.12