From a214bb99775e898fd9233b932f08ff91a57fc053 Mon Sep 17 00:00:00 2001 From: Benjamin Poulain Date: Wed, 4 Aug 2010 11:46:40 +0200 Subject: Implement comp_Source with SSE2 when there is a const alpha On Atom, comp_Source is 280% faster with the SSE2 implementation. Reviewed-by: Andreas Kling --- src/gui/painting/qdrawhelper.cpp | 2 ++ src/gui/painting/qdrawhelper_sse2.cpp | 33 ++++++++++++++++++++++++++ tests/benchmarks/gui/image/blendbench/main.cpp | 32 +++++++++++++++++++++++++ 3 files changed, 67 insertions(+) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 4ce2bee..1ff3d7b 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -7820,8 +7820,10 @@ void qInitDrawhelperAsm() uint const_alpha); extern void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels, int length, uint color, uint const_alpha); extern void QT_FASTCALL comp_func_Plus_sse2(uint *dst, const uint *src, int length, uint const_alpha); + extern void QT_FASTCALL comp_func_Source_sse2(uint *dst, const uint *src, int length, uint const_alpha); functionForModeAsm[0] = comp_func_SourceOver_sse2; + functionForModeAsm[QPainter::CompositionMode_Source] = comp_func_Source_sse2; functionForModeAsm[QPainter::CompositionMode_Plus] = comp_func_Plus_sse2; functionForModeSolidAsm[0] = comp_func_solid_SourceOver_sse2; diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp index e090ae5..7ab9eda 100644 --- a/src/gui/painting/qdrawhelper_sse2.cpp +++ b/src/gui/painting/qdrawhelper_sse2.cpp @@ -229,6 +229,39 @@ void QT_FASTCALL comp_func_Plus_sse2(uint *dst, const uint *src, int length, uin } } +void QT_FASTCALL comp_func_Source_sse2(uint *dst, const uint *src, int length, uint const_alpha) +{ + if (const_alpha == 255) { + ::memcpy(dst, src, length * sizeof(uint)); + } else { + const int ialpha = 255 - const_alpha; + + int x = 0; + + // 1) prologue, align on 16 bytes + const int offsetToAlignOn16Bytes = (4 - ((reinterpret_cast(dst) >> 2) & 0x3)) & 0x3; + const int prologLength = qMin(length, offsetToAlignOn16Bytes); + for (; x < prologLength; ++x) + dst[x] = INTERPOLATE_PIXEL_255(src[x], const_alpha, dst[x], ialpha); + + // 2) interpolate pixels with SSE2 + const __m128i half = _mm_set1_epi16(0x80); + const __m128i colorMask = _mm_set1_epi32(0x00ff00ff); + const __m128i constAlphaVector = _mm_set1_epi16(const_alpha); + const __m128i oneMinusConstAlpha = _mm_set1_epi16(ialpha); + for (; x < length - 3; x += 4) { + const __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]); + __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); + INTERPOLATE_PIXEL_255_SSE2(dstVector, srcVector, dstVector, constAlphaVector, oneMinusConstAlpha, colorMask, half) + _mm_store_si128((__m128i *)&dst[x], dstVector); + } + + // 3) Epilogue + for (; x < length; ++x) + dst[x] = INTERPOLATE_PIXEL_255(src[x], const_alpha, dst[x], ialpha); + } +} + void qt_memfill32_sse2(quint32 *dest, quint32 value, int count) { if (count < 7) { diff --git a/tests/benchmarks/gui/image/blendbench/main.cpp b/tests/benchmarks/gui/image/blendbench/main.cpp index 92d1633..f53654b 100644 --- a/tests/benchmarks/gui/image/blendbench/main.cpp +++ b/tests/benchmarks/gui/image/blendbench/main.cpp @@ -103,6 +103,9 @@ class BlendBench : public QObject private slots: void blendBench_data(); void blendBench(); + + void blendBenchAlpha_data(); + void blendBenchAlpha(); }; void BlendBench::blendBench_data() @@ -147,6 +150,35 @@ void BlendBench::blendBench() } } +void BlendBench::blendBenchAlpha_data() +{ + blendBench_data(); +} + +void BlendBench::blendBenchAlpha() +{ + QFETCH(int, brushType); + QFETCH(int, compositionMode); + + QImage img(512, 512, QImage::Format_ARGB32_Premultiplied); + QImage src(512, 512, QImage::Format_ARGB32_Premultiplied); + paint(&src); + QPainter p(&img); + p.setPen(Qt::NoPen); + + p.setCompositionMode(QPainter::CompositionMode(compositionMode)); + if (brushType == ImageBrush) { + p.setBrush(QBrush(src)); + } else if (brushType == SolidBrush) { + p.setBrush(QColor(127, 127, 127, 127)); + } + p.setOpacity(0.7f); + + QBENCHMARK { + p.drawRect(0, 0, 512, 512); + } +} + QTEST_MAIN(BlendBench) #include "main.moc" -- cgit v0.12 From 26218170746d36b866ae80c8f4418f5592121eb6 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 4 Aug 2010 17:22:58 +0200 Subject: QDeclarativeDebug: use QueuedConnection in the packet protocol Else, we can have deadlock in the javascript debugger, which may start an event loop. If the javascript execution result from some network command, the further network command are not processed more (the ones that exist the javascript debugger event loop) Having a QueuedConnection there means the network events will not be blocked by a rentrency in the event loop Reviewed-by: Lasse Holmstedt --- src/declarative/debugger/qpacketprotocol.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/declarative/debugger/qpacketprotocol.cpp b/src/declarative/debugger/qpacketprotocol.cpp index 878f42f..c2f7709 100644 --- a/src/declarative/debugger/qpacketprotocol.cpp +++ b/src/declarative/debugger/qpacketprotocol.cpp @@ -125,7 +125,7 @@ public: QObject::connect(this, SIGNAL(invalidPacket()), parent, SIGNAL(invalidPacket())); QObject::connect(dev, SIGNAL(readyRead()), - this, SLOT(readyToRead())); + this, SLOT(readyToRead()), Qt::QueuedConnection); QObject::connect(dev, SIGNAL(aboutToClose()), this, SLOT(aboutToClose())); QObject::connect(dev, SIGNAL(bytesWritten(qint64)), -- cgit v0.12 From 08d09a78d3faf8b211e78cb63285c35c5544b5fc Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 4 Aug 2010 19:38:41 +0200 Subject: Fixed crash in concentric circles example The problem is that the qt_arcs... function will return point_count = 0 when the input rectangle is empty which it is in this case. Because we previously passed 13 there, were passing random memory to downwards in the pipeline, which caused problems. Task: http://bugreports.qt.nokia.com/browse/QTBUG-12516 Reviewed-by: mariusso --- src/gui/painting/qpaintengineex.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index e0746fb..881bd6e 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -831,7 +831,7 @@ void QPaintEngineEx::drawEllipse(const QRectF &r) int point_count = 0; x.points[0] = qt_curves_for_arc(r, 0, -360, x.points + 1, &point_count); - QVectorPath vp((qreal *) pts, 13, qpaintengineex_ellipse_types, QVectorPath::EllipseHint); + QVectorPath vp((qreal *) pts, point_count, qpaintengineex_ellipse_types, QVectorPath::EllipseHint); draw(vp); } -- cgit v0.12