From c69469ff12eeed23584b5c3b15978a7e75d01df1 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 13 Sep 2010 14:05:54 +0200 Subject: Linux: Fix mispositioned, misclipped glyphs in large fonts (QStaticText) While drawText() will use the path fallback for large fonts, and never hit this problem, QStaticText will draw the large fonts into the glyph cache. This broke when the freetype (or any other font engine) falls back to the generic implementation of alphaMapForGlyph() which uses path drawing. The problem was that alphaMapForGlyph() is not supposed to contain the bearing of the glyph, only the actual pixels. Since QFontEngine did not honor this contract, we would sample the wrong area in the glyph cache to get the glyph image. Task-number: QTBUG-12540 Reviewed-by: Gunnar --- src/gui/text/qfontengine.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 1e8461f..a3f4d8a 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -631,10 +631,10 @@ QImage QFontEngine::alphaMapForGlyph(glyph_t glyph) if (glyph_width <= 0 || glyph_height <= 0) return QImage(); QFixedPoint pt; - pt.x = 0; + pt.x = -glyph_x; pt.y = -glyph_y; // the baseline QPainterPath path; - QImage im(glyph_width + qAbs(glyph_x) + 4, glyph_height, QImage::Format_ARGB32_Premultiplied); + QImage im(glyph_width + 4, glyph_height, QImage::Format_ARGB32_Premultiplied); im.fill(Qt::transparent); QPainter p(&im); p.setRenderHint(QPainter::Antialiasing); -- cgit v0.12 From 548155fec3a8b575215625d4fd767e63c20f6b84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Mon, 13 Sep 2010 14:23:04 +0200 Subject: Assertion calledEmitUpdated fails in QGraphicsScene. Problem was that the 'updateAll' boolean was reset to 'false' when it really should have been unchanged. This happened when rendering the scene from outside the view's paint event (i.e. from QGraphicsView/Scene::render). We only want to reset 'updateAll' when triggering drawItems() from QGraphicsView::paintEvent, i.e. when the 'view' pointer != 0. Broke after commit: dda8a57c. Auto test included. Task-number: QT-3674 --- src/gui/graphicsview/qgraphicsscene.cpp | 2 +- tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 539685a..36a24db 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -5270,7 +5270,6 @@ void QGraphicsScene::drawItems(QPainter *painter, if (!d->unpolishedItems.isEmpty()) d->_q_polishItems(); - d->updateAll = false; QTransform viewTransform = painter->worldTransform(); Q_UNUSED(options); @@ -5279,6 +5278,7 @@ void QGraphicsScene::drawItems(QPainter *painter, QRegion *expose = 0; const quint32 oldRectAdjust = d->rectAdjust; if (view) { + d->updateAll = false; expose = &view->d_func()->exposedRegion; if (view->d_func()->optimizationFlags & QGraphicsView::DontAdjustForAntialiasing) d->rectAdjust = 1; diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp index c145623..b8e729e 100644 --- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp @@ -287,6 +287,7 @@ private slots: void taskQTBUG_5904_crashWithDeviceCoordinateCache(); void taskQT657_paintIntoCacheWithTransparentParts(); void taskQTBUG_7863_paintIntoCacheWithTransparentParts(); + void taskQT_3674_doNotCrash(); }; void tst_QGraphicsScene::initTestCase() @@ -4565,6 +4566,25 @@ void tst_QGraphicsScene::taskQTBUG_7863_paintIntoCacheWithTransparentParts() } } +void tst_QGraphicsScene::taskQT_3674_doNotCrash() +{ + QGraphicsScene scene; + + QGraphicsView view(&scene); + view.resize(200, 200); + + QPixmap pixmap(view.size()); + QPainter painter(&pixmap); + view.render(&painter); + painter.end(); + + scene.addItem(new QGraphicsWidget); + scene.setBackgroundBrush(Qt::green); + + QApplication::processEvents(); + QApplication::processEvents(); +} + void tst_QGraphicsScene::zeroScale() { //should not crash -- cgit v0.12 From 5d9fb4b86ffd604e65ade61a252037dca224af53 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 13 Sep 2010 15:50:40 +0200 Subject: tests: fix compilation with suncc Patch derived from the tasks Task-number: QTBUG-12997 Task-number: QTBUG-12984 Task-number: QTBUG-12985 Task-number: QTBUG-12990 Task-number: QTBUG-12999 --- tests/auto/moc/tst_moc.cpp | 8 ++++---- tests/auto/q3table/tst_q3table.cpp | 8 ++++---- tests/auto/qcompleter/tst_qcompleter.cpp | 4 ++-- tests/auto/qobject/tst_qobject.cpp | 8 ++++---- .../qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp | 4 ++-- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/auto/moc/tst_moc.cpp b/tests/auto/moc/tst_moc.cpp index f9c3ccb..bb23f49 100644 --- a/tests/auto/moc/tst_moc.cpp +++ b/tests/auto/moc/tst_moc.cpp @@ -1077,10 +1077,10 @@ void tst_Moc::qprivateslots() class PrivatePropertyTest : public QObject { Q_OBJECT - Q_PROPERTY(int foo READ foo WRITE setFoo); - Q_PRIVATE_PROPERTY(d, int bar READ bar WRITE setBar); - Q_PRIVATE_PROPERTY(PrivatePropertyTest::d, int plop READ plop WRITE setPlop); - Q_PRIVATE_PROPERTY(PrivatePropertyTest::d_func(), int baz READ baz WRITE setBaz); + Q_PROPERTY(int foo READ foo WRITE setFoo) + Q_PRIVATE_PROPERTY(d, int bar READ bar WRITE setBar) + Q_PRIVATE_PROPERTY(PrivatePropertyTest::d, int plop READ plop WRITE setPlop) + Q_PRIVATE_PROPERTY(PrivatePropertyTest::d_func(), int baz READ baz WRITE setBaz) class MyDPointer { public: MyDPointer() : mBar(0), mPlop(0) {} diff --git a/tests/auto/q3table/tst_q3table.cpp b/tests/auto/q3table/tst_q3table.cpp index 90bf806..93de251 100644 --- a/tests/auto/q3table/tst_q3table.cpp +++ b/tests/auto/q3table/tst_q3table.cpp @@ -502,7 +502,7 @@ void tst_Q3Table::pageUpDownNavigation() void tst_Q3Table::simpleKeyboardNavigation() { QApplication::setActiveWindow(testWidget); - QTRY_COMPARE(QApplication::activeWindow(), testWidget); + QTRY_COMPARE(QApplication::activeWindow(), static_cast(testWidget)); QWidget *w; // Test for task #24726 @@ -1208,7 +1208,7 @@ void tst_Q3Table::editCheck() table.show(); QApplication::setActiveWindow(&table); QTest::qWaitForWindowShown(&table); - QTRY_COMPARE(QApplication::activeWindow(), &table); + QTRY_COMPARE(QApplication::activeWindow(), static_cast(&table)); table.setCurrentCell(0, 0); #ifdef WAITS QTest::qWait(50); @@ -1345,7 +1345,7 @@ void tst_Q3Table::valueChanged() testWidget->show(); QApplication::setActiveWindow(testWidget); QTest::qWaitForWindowShown(testWidget); - QTRY_COMPARE(QApplication::activeWindow(), testWidget); + QTRY_COMPARE(QApplication::activeWindow(), static_cast(testWidget)); #ifdef WAITS QTest::qWait(50); #endif @@ -1395,7 +1395,7 @@ void tst_Q3Table::dateTimeEdit() testWidget->show(); QApplication::setActiveWindow(testWidget); QTest::qWaitForWindowShown(testWidget); - QTRY_COMPARE(QApplication::activeWindow(), testWidget); + QTRY_COMPARE(QApplication::activeWindow(), static_cast(testWidget)); #ifdef WAITS QTest::qWait(50); #endif diff --git a/tests/auto/qcompleter/tst_qcompleter.cpp b/tests/auto/qcompleter/tst_qcompleter.cpp index a62720b..1590528 100644 --- a/tests/auto/qcompleter/tst_qcompleter.cpp +++ b/tests/auto/qcompleter/tst_qcompleter.cpp @@ -1324,7 +1324,7 @@ void tst_QCompleter::task253125_lineEditCompletion() #endif QTest::qWait(10); QApplication::setActiveWindow(&edit); - QTRY_COMPARE(QApplication::activeWindow(), &edit); + QTRY_COMPARE(QApplication::activeWindow(), static_cast(&edit)); QTest::keyClick(&edit, 'i'); QCOMPARE(edit.completer()->currentCompletion(), QString("iota")); @@ -1362,7 +1362,7 @@ void tst_QCompleter::task247560_keyboardNavigation() QTest::qWait(10); QApplication::setActiveWindow(&edit); - QTRY_COMPARE(QApplication::activeWindow(), &edit); + QTRY_COMPARE(QApplication::activeWindow(), static_cast(&edit)); QTest::keyClick(&edit, 'r'); QTest::keyClick(edit.completer()->popup(), Qt::Key_Down); diff --git a/tests/auto/qobject/tst_qobject.cpp b/tests/auto/qobject/tst_qobject.cpp index 08b7c19..5f6262e 100644 --- a/tests/auto/qobject/tst_qobject.cpp +++ b/tests/auto/qobject/tst_qobject.cpp @@ -3243,16 +3243,16 @@ void tst_QObject::overloads() QCOMPARE(obj2.s_num, 101); emit obj1.sig(&obj2, &obj3); //this signal is connected QCOMPARE(obj1.s_num, 11); - QCOMPARE(obj1.o1_obj, &obj2); + QCOMPARE(obj1.o1_obj, (QObject *)&obj2); QCOMPARE(obj1.o2_obj, &obj3); QCOMPARE(obj1.o3_obj, (QObject *)0); //default arg of the signal - QCOMPARE(obj1.o4_obj, qApp); //default arg of the slot + QCOMPARE(obj1.o4_obj, (QObject *)qApp); //default arg of the slot QCOMPARE(obj2.s_num, 111); - QCOMPARE(obj2.o1_obj, &obj2); + QCOMPARE(obj2.o1_obj, (QObject *)&obj2); QCOMPARE(obj2.o2_obj, &obj3); QCOMPARE(obj2.o3_obj, (QObject *)0); //default arg of the signal - QCOMPARE(obj2.o4_obj, qApp); //default arg of the slot + QCOMPARE(obj2.o4_obj, (QObject *)qApp); //default arg of the slot } class ManySignals : public QObject diff --git a/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp b/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp index e154528..e16be8b 100644 --- a/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp +++ b/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp @@ -381,7 +381,7 @@ void tst_QSequentialAnimationGroup::setCurrentTimeWithUncontrolledAnimation() QCOMPARE(a1_s_o2->currentLoopTime(), 250); QCOMPARE(notTimeDriven->currentLoopTime(), 0); QCOMPARE(loopsForever->currentLoopTime(), 0); - QCOMPARE(group.currentAnimation(), notTimeDriven); + QCOMPARE(group.currentAnimation(), static_cast(notTimeDriven)); // Current time = 505 group.setCurrentTime(505); @@ -391,7 +391,7 @@ void tst_QSequentialAnimationGroup::setCurrentTimeWithUncontrolledAnimation() QCOMPARE(a1_s_o2->currentLoopTime(), 250); QCOMPARE(notTimeDriven->currentLoopTime(), 5); QCOMPARE(loopsForever->currentLoopTime(), 0); - QCOMPARE(group.currentAnimation(), notTimeDriven); + QCOMPARE(group.currentAnimation(), static_cast(notTimeDriven)); QCOMPARE(sequence->state(), QAnimationGroup::Stopped); QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped); QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped); -- cgit v0.12 From 52f82846e651d240f6e610f91bc63b3ee74b3d44 Mon Sep 17 00:00:00 2001 From: Benjamin Poulain Date: Fri, 10 Sep 2010 21:51:13 +0200 Subject: Remove the memory safety for the first scanline of the SSSE3 blending MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Memory is allocated on 16 bytes boundaries. We can do the aligned load without risking a invalid memory access. This simplify the code. Reviewed-by: Samuel Rødal --- src/gui/painting/qdrawhelper_ssse3.cpp | 75 ++-------------------------------- 1 file changed, 3 insertions(+), 72 deletions(-) diff --git a/src/gui/painting/qdrawhelper_ssse3.cpp b/src/gui/painting/qdrawhelper_ssse3.cpp index 4cb4089..fb5602e 100644 --- a/src/gui/painting/qdrawhelper_ssse3.cpp +++ b/src/gui/painting/qdrawhelper_ssse3.cpp @@ -79,69 +79,6 @@ inline static void blend_pixel(quint32 &dst, const quint32 src) } -#define BLEND_SOURCE_OVER_ARGB32_FIRST_ROW_SSSE3(dst, src, length, nullVector, half, one, colorMask, alphaMask) { \ - int x = 0; \ -\ - /* First, get dst aligned. */ \ - const int offsetToAlignOn16Bytes = (4 - ((reinterpret_cast(dst) >> 2) & 0x3)) & 0x3;\ - const int prologLength = qMin(length, offsetToAlignOn16Bytes);\ -\ - for (; x < prologLength; ++x) {\ - blend_pixel(dst[x], src[x]); \ - } \ -\ - const int minusOffsetToAlignSrcOn16Bytes = (reinterpret_cast(&(src[x])) >> 2) & 0x3;\ -\ - if (!minusOffsetToAlignSrcOn16Bytes) {\ - /* src is aligned, usual algorithm but with aligned operations.\ - See the SSE2 version for more documentation on the algorithm itself. */\ - const __m128i alphaShuffleMask = _mm_set_epi8(0xff,15,0xff,15,0xff,11,0xff,11,0xff,7,0xff,7,0xff,3,0xff,3);\ - for (; x < length-3; x += 4) { \ - const __m128i srcVector = _mm_load_si128((__m128i *)&src[x]); \ - const __m128i srcVectorAlpha = _mm_and_si128(srcVector, alphaMask); \ - if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, alphaMask)) == 0xffff) { \ - _mm_store_si128((__m128i *)&dst[x], srcVector); \ - } else if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, nullVector)) != 0xffff) { \ - __m128i alphaChannel = _mm_shuffle_epi8(srcVector, alphaShuffleMask); \ - alphaChannel = _mm_sub_epi16(one, alphaChannel); \ - const __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); \ - __m128i destMultipliedByOneMinusAlpha; \ - BYTE_MUL_SSE2(destMultipliedByOneMinusAlpha, dstVector, alphaChannel, colorMask, half); \ - const __m128i result = _mm_add_epi8(srcVector, destMultipliedByOneMinusAlpha); \ - _mm_store_si128((__m128i *)&dst[x], result); \ - } \ - } /* end for() */\ - } else if ((length - x) >= 8) {\ - /* We are at the first line, so "x - minusOffsetToAlignSrcOn16Bytes" could go before src, and\ - generate an invalid access. */\ -\ - /* We use two vectors to extract the src: prevLoaded for the first pixels, lastLoaded for the current pixels. */\ - __m128i srcVectorPrevLoaded;\ - if (minusOffsetToAlignSrcOn16Bytes > prologLength) {\ - /* We go forward 4 pixels to avoid reading before src. */\ - for (; x < prologLength + 4; ++x)\ - blend_pixel(dst[x], src[x]); \ - }\ - srcVectorPrevLoaded = _mm_load_si128((__m128i *)&src[x - minusOffsetToAlignSrcOn16Bytes]);\ - const int palignrOffset = minusOffsetToAlignSrcOn16Bytes << 2;\ -\ - const __m128i alphaShuffleMask = _mm_set_epi8(0xff,15,0xff,15,0xff,11,0xff,11,0xff,7,0xff,7,0xff,3,0xff,3);\ - switch (palignrOffset) {\ - case 4:\ - BLENDING_LOOP(4, length)\ - break;\ - case 8:\ - BLENDING_LOOP(8, length)\ - break;\ - case 12:\ - BLENDING_LOOP(12, length)\ - break;\ - }\ - }\ - for (; x < length; ++x) \ - blend_pixel(dst[x], src[x]); \ -} - // Basically blend src over dst with the const alpha defined as constAlphaVector. // nullVector, half, one, colorMask are constant accross the whole image/texture, and should be defined as: //const __m128i nullVector = _mm_set1_epi32(0); @@ -153,7 +90,7 @@ inline static void blend_pixel(quint32 &dst, const quint32 src) // The computation being done is: // result = s + d * (1-alpha) // with shortcuts if fully opaque or fully transparent. -#define BLEND_SOURCE_OVER_ARGB32_MAIN_SSSE3(dst, src, length, nullVector, half, one, colorMask, alphaMask) { \ +#define BLEND_SOURCE_OVER_ARGB32_SSSE3(dst, src, length, nullVector, half, one, colorMask, alphaMask) { \ int x = 0; \ \ /* First, get dst aligned. */ \ @@ -218,14 +155,8 @@ void qt_blend_argb32_on_argb32_ssse3(uchar *destPixels, int dbpl, const __m128i one = _mm_set1_epi16(0xff); const __m128i colorMask = _mm_set1_epi32(0x00ff00ff); - // We have to unrol the first row in order to deal with the load on unaligned data - // prior to the src pointer. - BLEND_SOURCE_OVER_ARGB32_FIRST_ROW_SSSE3(dst, src, w, nullVector, half, one, colorMask, alphaMask); - dst = (quint32 *)(((uchar *) dst) + dbpl); - src = (const quint32 *)(((const uchar *) src) + sbpl); - - for (int y = 1; y < h; ++y) { - BLEND_SOURCE_OVER_ARGB32_MAIN_SSSE3(dst, src, w, nullVector, half, one, colorMask, alphaMask); + for (int y = 0; y < h; ++y) { + BLEND_SOURCE_OVER_ARGB32_SSSE3(dst, src, w, nullVector, half, one, colorMask, alphaMask); dst = (quint32 *)(((uchar *) dst) + dbpl); src = (const quint32 *)(((const uchar *) src) + sbpl); } -- cgit v0.12 From faba2072ae1cf3661caceae2ef4f87cee485cf29 Mon Sep 17 00:00:00 2001 From: Benjamin Poulain Date: Mon, 13 Sep 2010 15:29:25 +0200 Subject: Use the stream operation for the SSE2 implementation of memfill32 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Writing the data of memfill() to a cacheline is unecessary because the data is not reused directly. We can use the stream operations to avoid the cache completely. When testing memfill32 separately, the function is twice as fast on Core2 and Atom. Reviewed-by: Samuel Rødal --- src/gui/painting/qdrawhelper_sse2.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp index ba2ba32..ac73958 100644 --- a/src/gui/painting/qdrawhelper_sse2.cpp +++ b/src/gui/painting/qdrawhelper_sse2.cpp @@ -266,10 +266,10 @@ void qt_memfill32_sse2(quint32 *dest, quint32 value, int count) int n = (count128 + 3) / 4; switch (count128 & 0x3) { - case 0: do { _mm_store_si128(dst128++, value128); - case 3: _mm_store_si128(dst128++, value128); - case 2: _mm_store_si128(dst128++, value128); - case 1: _mm_store_si128(dst128++, value128); + case 0: do { _mm_stream_si128(dst128++, value128); + case 3: _mm_stream_si128(dst128++, value128); + case 2: _mm_stream_si128(dst128++, value128); + case 1: _mm_stream_si128(dst128++, value128); } while (--n > 0); } -- cgit v0.12