summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2010-07-27 11:45:03 +0200
committerQt Continuous Integration System <qt-info@nokia.com>2010-07-27 11:45:03 +0200
commitbd89fe50408452ed343715f3ef28c5d3e106715c (patch)
treeec00855dbed3731877343e1f07e51ac0f753a9f0
parent29a6377c6539840ca901bdcb045a42b7832ac98a (diff)
parent34beae57ff8248e7666a4ce08a06eeff54e05e7a (diff)
downloadqt4-tools-bd89fe50408452ed343715f3ef28c5d3e106715c.tar.gz
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-2 into 4.7-integration
* '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-2: Implement the composition mode "Plus" with SSE2 Clean the CompositionFunction tables of drawhelper
-rw-r--r--src/gui/painting/qdrawhelper.cpp135
-rw-r--r--src/gui/painting/qdrawhelper_iwmmxt.cpp25
-rw-r--r--src/gui/painting/qdrawhelper_mmx.cpp23
-rw-r--r--src/gui/painting/qdrawhelper_mmx3dnow.cpp25
-rw-r--r--src/gui/painting/qdrawhelper_p.h40
-rw-r--r--src/gui/painting/qdrawhelper_sse.cpp25
-rw-r--r--src/gui/painting/qdrawhelper_sse2.cpp66
-rw-r--r--src/gui/painting/qdrawhelper_sse3dnow.cpp25
-rw-r--r--tests/auto/qpainter/tst_qpainter.cpp24
9 files changed, 302 insertions, 86 deletions
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index ca9556b282..4ce2beece8 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -1314,7 +1314,7 @@ static void QT_FASTCALL comp_func_solid_Clear(uint *dest, int length, uint, uint
comp_func_Clear_impl(dest, length, const_alpha);
}
-static void QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, uint const_alpha)
+void QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, uint const_alpha)
{
comp_func_Clear_impl(dest, length, const_alpha);
}
@@ -1338,7 +1338,7 @@ static void QT_FASTCALL comp_func_solid_Source(uint *dest, int length, uint colo
}
}
-static void QT_FASTCALL comp_func_Source(uint *dest, const uint *src, int length, uint const_alpha)
+void QT_FASTCALL comp_func_Source(uint *dest, const uint *src, int length, uint const_alpha)
{
if (const_alpha == 255) {
::memcpy(dest, src, length * sizeof(uint));
@@ -1356,7 +1356,7 @@ static void QT_FASTCALL comp_func_solid_Destination(uint *, int, uint, uint)
{
}
-static void QT_FASTCALL comp_func_Destination(uint *, const uint *, int, uint)
+void QT_FASTCALL comp_func_Destination(uint *, const uint *, int, uint)
{
}
@@ -1381,7 +1381,7 @@ static void QT_FASTCALL comp_func_solid_SourceOver(uint *dest, int length, uint
}
}
-static void QT_FASTCALL comp_func_SourceOver(uint *dest, const uint *src, int length, uint const_alpha)
+void QT_FASTCALL comp_func_SourceOver(uint *dest, const uint *src, int length, uint const_alpha)
{
PRELOAD_INIT2(dest, src)
if (const_alpha == 255) {
@@ -1419,7 +1419,7 @@ static void QT_FASTCALL comp_func_solid_DestinationOver(uint *dest, int length,
}
}
-static void QT_FASTCALL comp_func_DestinationOver(uint *dest, const uint *src, int length, uint const_alpha)
+void QT_FASTCALL comp_func_DestinationOver(uint *dest, const uint *src, int length, uint const_alpha)
{
PRELOAD_INIT2(dest, src)
if (const_alpha == 255) {
@@ -1461,7 +1461,7 @@ static void QT_FASTCALL comp_func_solid_SourceIn(uint *dest, int length, uint co
}
}
-static void QT_FASTCALL comp_func_SourceIn(uint *dest, const uint *src, int length, uint const_alpha)
+void QT_FASTCALL comp_func_SourceIn(uint *dest, const uint *src, int length, uint const_alpha)
{
PRELOAD_INIT2(dest, src)
if (const_alpha == 255) {
@@ -1498,7 +1498,7 @@ static void QT_FASTCALL comp_func_solid_DestinationIn(uint *dest, int length, ui
}
}
-static void QT_FASTCALL comp_func_DestinationIn(uint *dest, const uint *src, int length, uint const_alpha)
+void QT_FASTCALL comp_func_DestinationIn(uint *dest, const uint *src, int length, uint const_alpha)
{
PRELOAD_INIT2(dest, src)
if (const_alpha == 255) {
@@ -1540,7 +1540,7 @@ static void QT_FASTCALL comp_func_solid_SourceOut(uint *dest, int length, uint c
}
}
-static void QT_FASTCALL comp_func_SourceOut(uint *dest, const uint *src, int length, uint const_alpha)
+void QT_FASTCALL comp_func_SourceOut(uint *dest, const uint *src, int length, uint const_alpha)
{
PRELOAD_INIT2(dest, src)
if (const_alpha == 255) {
@@ -1576,7 +1576,7 @@ static void QT_FASTCALL comp_func_solid_DestinationOut(uint *dest, int length, u
}
}
-static void QT_FASTCALL comp_func_DestinationOut(uint *dest, const uint *src, int length, uint const_alpha)
+void QT_FASTCALL comp_func_DestinationOut(uint *dest, const uint *src, int length, uint const_alpha)
{
PRELOAD_INIT2(dest, src)
if (const_alpha == 255) {
@@ -1613,7 +1613,7 @@ static void QT_FASTCALL comp_func_solid_SourceAtop(uint *dest, int length, uint
}
}
-static void QT_FASTCALL comp_func_SourceAtop(uint *dest, const uint *src, int length, uint const_alpha)
+void QT_FASTCALL comp_func_SourceAtop(uint *dest, const uint *src, int length, uint const_alpha)
{
PRELOAD_INIT2(dest, src)
if (const_alpha == 255) {
@@ -1653,7 +1653,7 @@ static void QT_FASTCALL comp_func_solid_DestinationAtop(uint *dest, int length,
}
}
-static void QT_FASTCALL comp_func_DestinationAtop(uint *dest, const uint *src, int length, uint const_alpha)
+void QT_FASTCALL comp_func_DestinationAtop(uint *dest, const uint *src, int length, uint const_alpha)
{
PRELOAD_INIT2(dest, src)
if (const_alpha == 255) {
@@ -1695,7 +1695,7 @@ static void QT_FASTCALL comp_func_solid_XOR(uint *dest, int length, uint color,
}
}
-static void QT_FASTCALL comp_func_XOR(uint *dest, const uint *src, int length, uint const_alpha)
+void QT_FASTCALL comp_func_XOR(uint *dest, const uint *src, int length, uint const_alpha)
{
PRELOAD_INIT2(dest, src)
if (const_alpha == 255) {
@@ -1715,11 +1715,6 @@ static void QT_FASTCALL comp_func_XOR(uint *dest, const uint *src, int length, u
}
}
-static const uint AMASK = 0xff000000;
-static const uint RMASK = 0x00ff0000;
-static const uint GMASK = 0x0000ff00;
-static const uint BMASK = 0x000000ff;
-
struct QFullCoverage {
inline void store(uint *dest, const uint src) const
{
@@ -1794,7 +1789,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Plus_impl(uint *dest, const uin
}
}
-static void QT_FASTCALL comp_func_Plus(uint *dest, const uint *src, int length, uint const_alpha)
+void QT_FASTCALL comp_func_Plus(uint *dest, const uint *src, int length, uint const_alpha)
{
if (const_alpha == 255)
comp_func_Plus_impl(dest, src, length, QFullCoverage());
@@ -1866,7 +1861,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Multiply_impl(uint *dest, const
}
}
-static void QT_FASTCALL comp_func_Multiply(uint *dest, const uint *src, int length, uint const_alpha)
+void QT_FASTCALL comp_func_Multiply(uint *dest, const uint *src, int length, uint const_alpha)
{
if (const_alpha == 255)
comp_func_Multiply_impl(dest, src, length, QFullCoverage());
@@ -1934,7 +1929,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Screen_impl(uint *dest, const u
}
}
-static void QT_FASTCALL comp_func_Screen(uint *dest, const uint *src, int length, uint const_alpha)
+void QT_FASTCALL comp_func_Screen(uint *dest, const uint *src, int length, uint const_alpha)
{
if (const_alpha == 255)
comp_func_Screen_impl(dest, src, length, QFullCoverage());
@@ -2013,7 +2008,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Overlay_impl(uint *dest, const
}
}
-static void QT_FASTCALL comp_func_Overlay(uint *dest, const uint *src, int length, uint const_alpha)
+void QT_FASTCALL comp_func_Overlay(uint *dest, const uint *src, int length, uint const_alpha)
{
if (const_alpha == 255)
comp_func_Overlay_impl(dest, src, length, QFullCoverage());
@@ -2086,7 +2081,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Darken_impl(uint *dest, const u
}
}
-static void QT_FASTCALL comp_func_Darken(uint *dest, const uint *src, int length, uint const_alpha)
+void QT_FASTCALL comp_func_Darken(uint *dest, const uint *src, int length, uint const_alpha)
{
if (const_alpha == 255)
comp_func_Darken_impl(dest, src, length, QFullCoverage());
@@ -2159,7 +2154,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Lighten_impl(uint *dest, const
}
}
-static void QT_FASTCALL comp_func_Lighten(uint *dest, const uint *src, int length, uint const_alpha)
+void QT_FASTCALL comp_func_Lighten(uint *dest, const uint *src, int length, uint const_alpha)
{
if (const_alpha == 255)
comp_func_Lighten_impl(dest, src, length, QFullCoverage());
@@ -2242,7 +2237,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_ColorDodge_impl(uint *dest, con
}
}
-static void QT_FASTCALL comp_func_ColorDodge(uint *dest, const uint *src, int length, uint const_alpha)
+void QT_FASTCALL comp_func_ColorDodge(uint *dest, const uint *src, int length, uint const_alpha)
{
if (const_alpha == 255)
comp_func_ColorDodge_impl(dest, src, length, QFullCoverage());
@@ -2325,7 +2320,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_ColorBurn_impl(uint *dest, cons
}
}
-static void QT_FASTCALL comp_func_ColorBurn(uint *dest, const uint *src, int length, uint const_alpha)
+void QT_FASTCALL comp_func_ColorBurn(uint *dest, const uint *src, int length, uint const_alpha)
{
if (const_alpha == 255)
comp_func_ColorBurn_impl(dest, src, length, QFullCoverage());
@@ -2405,7 +2400,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_HardLight_impl(uint *dest, cons
}
}
-static void QT_FASTCALL comp_func_HardLight(uint *dest, const uint *src, int length, uint const_alpha)
+void QT_FASTCALL comp_func_HardLight(uint *dest, const uint *src, int length, uint const_alpha)
{
if (const_alpha == 255)
comp_func_HardLight_impl(dest, src, length, QFullCoverage());
@@ -2496,7 +2491,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_SoftLight_impl(uint *dest, cons
}
}
-static void QT_FASTCALL comp_func_SoftLight(uint *dest, const uint *src, int length, uint const_alpha)
+void QT_FASTCALL comp_func_SoftLight(uint *dest, const uint *src, int length, uint const_alpha)
{
if (const_alpha == 255)
comp_func_SoftLight_impl(dest, src, length, QFullCoverage());
@@ -2569,7 +2564,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Difference_impl(uint *dest, con
}
}
-static void QT_FASTCALL comp_func_Difference(uint *dest, const uint *src, int length, uint const_alpha)
+void QT_FASTCALL comp_func_Difference(uint *dest, const uint *src, int length, uint const_alpha)
{
if (const_alpha == 255)
comp_func_Difference_impl(dest, src, length, QFullCoverage());
@@ -2636,7 +2631,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Exclusion_impl(uint *dest, cons
}
}
-static void QT_FASTCALL comp_func_Exclusion(uint *dest, const uint *src, int length, uint const_alpha)
+void QT_FASTCALL comp_func_Exclusion(uint *dest, const uint *src, int length, uint const_alpha)
{
if (const_alpha == 255)
comp_func_Exclusion_impl(dest, src, length, QFullCoverage());
@@ -2659,10 +2654,10 @@ static void QT_FASTCALL rasterop_solid_SourceOrDestination(uint *dest,
*dest++ |= color;
}
-static void QT_FASTCALL rasterop_SourceOrDestination(uint *dest,
- const uint *src,
- int length,
- uint const_alpha)
+void QT_FASTCALL rasterop_SourceOrDestination(uint *dest,
+ const uint *src,
+ int length,
+ uint const_alpha)
{
Q_UNUSED(const_alpha);
while (length--)
@@ -2680,10 +2675,10 @@ static void QT_FASTCALL rasterop_solid_SourceAndDestination(uint *dest,
*dest++ &= color;
}
-static void QT_FASTCALL rasterop_SourceAndDestination(uint *dest,
- const uint *src,
- int length,
- uint const_alpha)
+void QT_FASTCALL rasterop_SourceAndDestination(uint *dest,
+ const uint *src,
+ int length,
+ uint const_alpha)
{
Q_UNUSED(const_alpha);
while (length--) {
@@ -2703,10 +2698,10 @@ static void QT_FASTCALL rasterop_solid_SourceXorDestination(uint *dest,
*dest++ ^= color;
}
-static void QT_FASTCALL rasterop_SourceXorDestination(uint *dest,
- const uint *src,
- int length,
- uint const_alpha)
+void QT_FASTCALL rasterop_SourceXorDestination(uint *dest,
+ const uint *src,
+ int length,
+ uint const_alpha)
{
Q_UNUSED(const_alpha);
while (length--) {
@@ -2728,10 +2723,10 @@ static void QT_FASTCALL rasterop_solid_NotSourceAndNotDestination(uint *dest,
}
}
-static void QT_FASTCALL rasterop_NotSourceAndNotDestination(uint *dest,
- const uint *src,
- int length,
- uint const_alpha)
+void QT_FASTCALL rasterop_NotSourceAndNotDestination(uint *dest,
+ const uint *src,
+ int length,
+ uint const_alpha)
{
Q_UNUSED(const_alpha);
while (length--) {
@@ -2753,10 +2748,10 @@ static void QT_FASTCALL rasterop_solid_NotSourceOrNotDestination(uint *dest,
}
}
-static void QT_FASTCALL rasterop_NotSourceOrNotDestination(uint *dest,
- const uint *src,
- int length,
- uint const_alpha)
+void QT_FASTCALL rasterop_NotSourceOrNotDestination(uint *dest,
+ const uint *src,
+ int length,
+ uint const_alpha)
{
Q_UNUSED(const_alpha);
while (length--) {
@@ -2778,10 +2773,10 @@ static void QT_FASTCALL rasterop_solid_NotSourceXorDestination(uint *dest,
}
}
-static void QT_FASTCALL rasterop_NotSourceXorDestination(uint *dest,
- const uint *src,
- int length,
- uint const_alpha)
+void QT_FASTCALL rasterop_NotSourceXorDestination(uint *dest,
+ const uint *src,
+ int length,
+ uint const_alpha)
{
Q_UNUSED(const_alpha);
while (length--) {
@@ -2797,8 +2792,8 @@ static void QT_FASTCALL rasterop_solid_NotSource(uint *dest, int length,
qt_memfill(dest, ~color | 0xff000000, length);
}
-static void QT_FASTCALL rasterop_NotSource(uint *dest, const uint *src,
- int length, uint const_alpha)
+void QT_FASTCALL rasterop_NotSource(uint *dest, const uint *src,
+ int length, uint const_alpha)
{
Q_UNUSED(const_alpha);
while (length--)
@@ -2818,10 +2813,10 @@ static void QT_FASTCALL rasterop_solid_NotSourceAndDestination(uint *dest,
}
}
-static void QT_FASTCALL rasterop_NotSourceAndDestination(uint *dest,
- const uint *src,
- int length,
- uint const_alpha)
+void QT_FASTCALL rasterop_NotSourceAndDestination(uint *dest,
+ const uint *src,
+ int length,
+ uint const_alpha)
{
Q_UNUSED(const_alpha);
while (length--) {
@@ -2842,10 +2837,10 @@ static void QT_FASTCALL rasterop_solid_SourceAndNotDestination(uint *dest,
}
}
-static void QT_FASTCALL rasterop_SourceAndNotDestination(uint *dest,
- const uint *src,
- int length,
- uint const_alpha)
+void QT_FASTCALL rasterop_SourceAndNotDestination(uint *dest,
+ const uint *src,
+ int length,
+ uint const_alpha)
{
Q_UNUSED(const_alpha);
while (length--) {
@@ -7775,6 +7770,7 @@ void qInitDrawhelperAsm()
#ifdef QT_HAVE_MMX
if (features & MMX) {
functionForModeAsm = qt_functionForMode_MMX;
+
functionForModeSolidAsm = qt_functionForModeSolid_MMX;
qDrawHelper[QImage::Format_ARGB32_Premultiplied].blendColor = qt_blend_color_argb_mmx;
#ifdef QT_HAVE_3DNOW
@@ -7823,8 +7819,10 @@ void qInitDrawhelperAsm()
int length,
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);
functionForModeAsm[0] = comp_func_SourceOver_sse2;
+ functionForModeAsm[QPainter::CompositionMode_Plus] = comp_func_Plus_sse2;
functionForModeSolidAsm[0] = comp_func_solid_SourceOver_sse2;
extern void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl,
@@ -7919,17 +7917,8 @@ void qInitDrawhelperAsm()
functionForModeSolid = functionForModeSolidAsm;
}
- if (functionForModeAsm) {
- const int destinationMode = QPainter::CompositionMode_Destination;
- functionForModeAsm[destinationMode] = functionForMode_C[destinationMode];
-
- // use the default qdrawhelper implementation for the
- // extended composition modes
- for (int mode = 12; mode < numCompositionFunctions; ++mode)
- functionForModeAsm[mode] = functionForMode_C[mode];
-
+ if (functionForModeAsm)
functionForMode = functionForModeAsm;
- }
qt_build_pow_tables();
}
diff --git a/src/gui/painting/qdrawhelper_iwmmxt.cpp b/src/gui/painting/qdrawhelper_iwmmxt.cpp
index 80b2c04864..d99045d347 100644
--- a/src/gui/painting/qdrawhelper_iwmmxt.cpp
+++ b/src/gui/painting/qdrawhelper_iwmmxt.cpp
@@ -106,14 +106,35 @@ CompositionFunction qt_functionForMode_IWMMXT[] = {
comp_func_DestinationOver<QIWMMXTIntrinsics>,
comp_func_Clear<QIWMMXTIntrinsics>,
comp_func_Source<QIWMMXTIntrinsics>,
- 0,
+ comp_func_Destination,
comp_func_SourceIn<QIWMMXTIntrinsics>,
comp_func_DestinationIn<QIWMMXTIntrinsics>,
comp_func_SourceOut<QIWMMXTIntrinsics>,
comp_func_DestinationOut<QIWMMXTIntrinsics>,
comp_func_SourceAtop<QIWMMXTIntrinsics>,
comp_func_DestinationAtop<QIWMMXTIntrinsics>,
- comp_func_XOR<QIWMMXTIntrinsics>
+ comp_func_XOR<QIWMMXTIntrinsics>,
+ comp_func_Plus,
+ comp_func_Multiply,
+ comp_func_Screen,
+ comp_func_Overlay,
+ comp_func_Darken,
+ comp_func_Lighten,
+ comp_func_ColorDodge,
+ comp_func_ColorBurn,
+ comp_func_HardLight,
+ comp_func_SoftLight,
+ comp_func_Difference,
+ comp_func_Exclusion,
+ rasterop_SourceOrDestination,
+ rasterop_SourceAndDestination,
+ rasterop_SourceXorDestination,
+ rasterop_NotSourceAndNotDestination,
+ rasterop_NotSourceOrNotDestination,
+ rasterop_NotSourceXorDestination,
+ rasterop_NotSource,
+ rasterop_NotSourceAndDestination,
+ rasterop_SourceAndNotDestination
};
void qt_blend_color_argb_iwmmxt(int count, const QSpan *spans, void *userData)
diff --git a/src/gui/painting/qdrawhelper_mmx.cpp b/src/gui/painting/qdrawhelper_mmx.cpp
index d49c5a12d2..ba92554ef9 100644
--- a/src/gui/painting/qdrawhelper_mmx.cpp
+++ b/src/gui/painting/qdrawhelper_mmx.cpp
@@ -77,7 +77,7 @@ CompositionFunction qt_functionForMode_MMX[numCompositionFunctions] = {
comp_func_DestinationOver<QMMXIntrinsics>,
comp_func_Clear<QMMXIntrinsics>,
comp_func_Source<QMMXIntrinsics>,
- 0,
+ comp_func_Destination,
comp_func_SourceIn<QMMXIntrinsics>,
comp_func_DestinationIn<QMMXIntrinsics>,
comp_func_SourceOut<QMMXIntrinsics>,
@@ -85,6 +85,27 @@ CompositionFunction qt_functionForMode_MMX[numCompositionFunctions] = {
comp_func_SourceAtop<QMMXIntrinsics>,
comp_func_DestinationAtop<QMMXIntrinsics>,
comp_func_XOR<QMMXIntrinsics>,
+ comp_func_Plus,
+ comp_func_Multiply,
+ comp_func_Screen,
+ comp_func_Overlay,
+ comp_func_Darken,
+ comp_func_Lighten,
+ comp_func_ColorDodge,
+ comp_func_ColorBurn,
+ comp_func_HardLight,
+ comp_func_SoftLight,
+ comp_func_Difference,
+ comp_func_Exclusion,
+ rasterop_SourceOrDestination,
+ rasterop_SourceAndDestination,
+ rasterop_SourceXorDestination,
+ rasterop_NotSourceAndNotDestination,
+ rasterop_NotSourceOrNotDestination,
+ rasterop_NotSourceXorDestination,
+ rasterop_NotSource,
+ rasterop_NotSourceAndDestination,
+ rasterop_SourceAndNotDestination
};
void qt_blend_color_argb_mmx(int count, const QSpan *spans, void *userData)
diff --git a/src/gui/painting/qdrawhelper_mmx3dnow.cpp b/src/gui/painting/qdrawhelper_mmx3dnow.cpp
index 8bffaa7a45..b1e81fce4f 100644
--- a/src/gui/painting/qdrawhelper_mmx3dnow.cpp
+++ b/src/gui/painting/qdrawhelper_mmx3dnow.cpp
@@ -85,14 +85,35 @@ CompositionFunction qt_functionForMode_MMX3DNOW[numCompositionFunctions] = {
comp_func_DestinationOver<QMMX3DNOWIntrinsics>,
comp_func_Clear<QMMX3DNOWIntrinsics>,
comp_func_Source<QMMX3DNOWIntrinsics>,
- 0,
+ comp_func_Destination,
comp_func_SourceIn<QMMX3DNOWIntrinsics>,
comp_func_DestinationIn<QMMX3DNOWIntrinsics>,
comp_func_SourceOut<QMMX3DNOWIntrinsics>,
comp_func_DestinationOut<QMMX3DNOWIntrinsics>,
comp_func_SourceAtop<QMMX3DNOWIntrinsics>,
comp_func_DestinationAtop<QMMX3DNOWIntrinsics>,
- comp_func_XOR<QMMX3DNOWIntrinsics>
+ comp_func_XOR<QMMX3DNOWIntrinsics>,
+ comp_func_Plus,
+ comp_func_Multiply,
+ comp_func_Screen,
+ comp_func_Overlay,
+ comp_func_Darken,
+ comp_func_Lighten,
+ comp_func_ColorDodge,
+ comp_func_ColorBurn,
+ comp_func_HardLight,
+ comp_func_SoftLight,
+ comp_func_Difference,
+ comp_func_Exclusion,
+ rasterop_SourceOrDestination,
+ rasterop_SourceAndDestination,
+ rasterop_SourceXorDestination,
+ rasterop_NotSourceAndNotDestination,
+ rasterop_NotSourceOrNotDestination,
+ rasterop_NotSourceXorDestination,
+ rasterop_NotSource,
+ rasterop_NotSourceAndDestination,
+ rasterop_SourceAndNotDestination
};
void qt_blend_color_argb_mmx3dnow(int count, const QSpan *spans, void *userData)
diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h
index 97c78bb0a2..1a87127f38 100644
--- a/src/gui/painting/qdrawhelper_p.h
+++ b/src/gui/painting/qdrawhelper_p.h
@@ -91,6 +91,11 @@ QT_BEGIN_NAMESPACE
# define Q_STATIC_INLINE_FUNCTION static inline
#endif
+static const uint AMASK = 0xff000000;
+static const uint RMASK = 0x00ff0000;
+static const uint GMASK = 0x0000ff00;
+static const uint BMASK = 0x000000ff;
+
/*******************************************************************************
* QSpan
*
@@ -1945,6 +1950,41 @@ const uint qt_bayer_matrix[16][16] = {
((((argb >> 24) * alpha) >> 8) << 24) | (argb & 0x00ffffff)
+// prototypes of all the composition functions
+void QT_FASTCALL comp_func_SourceOver(uint *dest, const uint *src, int length, uint const_alpha);
+void QT_FASTCALL comp_func_DestinationOver(uint *dest, const uint *src, int length, uint const_alpha);
+void QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, uint const_alpha);
+void QT_FASTCALL comp_func_Source(uint *dest, const uint *src, int length, uint const_alpha);
+void QT_FASTCALL comp_func_Destination(uint *, const uint *, int, uint);
+void QT_FASTCALL comp_func_SourceIn(uint *dest, const uint *src, int length, uint const_alpha);
+void QT_FASTCALL comp_func_DestinationIn(uint *dest, const uint *src, int length, uint const_alpha);
+void QT_FASTCALL comp_func_SourceOut(uint *dest, const uint *src, int length, uint const_alpha);
+void QT_FASTCALL comp_func_DestinationOut(uint *dest, const uint *src, int length, uint const_alpha);
+void QT_FASTCALL comp_func_SourceAtop(uint *dest, const uint *src, int length, uint const_alpha);
+void QT_FASTCALL comp_func_DestinationAtop(uint *dest, const uint *src, int length, uint const_alpha);
+void QT_FASTCALL comp_func_XOR(uint *dest, const uint *src, int length, uint const_alpha);
+void QT_FASTCALL comp_func_Plus(uint *dest, const uint *src, int length, uint const_alpha);
+void QT_FASTCALL comp_func_Multiply(uint *dest, const uint *src, int length, uint const_alpha);
+void QT_FASTCALL comp_func_Screen(uint *dest, const uint *src, int length, uint const_alpha);
+void QT_FASTCALL comp_func_Overlay(uint *dest, const uint *src, int length, uint const_alpha);
+void QT_FASTCALL comp_func_Darken(uint *dest, const uint *src, int length, uint const_alpha);
+void QT_FASTCALL comp_func_Lighten(uint *dest, const uint *src, int length, uint const_alpha);
+void QT_FASTCALL comp_func_ColorDodge(uint *dest, const uint *src, int length, uint const_alpha);
+void QT_FASTCALL comp_func_ColorBurn(uint *dest, const uint *src, int length, uint const_alpha);
+void QT_FASTCALL comp_func_HardLight(uint *dest, const uint *src, int length, uint const_alpha);
+void QT_FASTCALL comp_func_SoftLight(uint *dest, const uint *src, int length, uint const_alpha);
+void QT_FASTCALL comp_func_Difference(uint *dest, const uint *src, int length, uint const_alpha);
+void QT_FASTCALL comp_func_Exclusion(uint *dest, const uint *src, int length, uint const_alpha);
+void QT_FASTCALL rasterop_SourceOrDestination(uint *dest, const uint *src, int length, uint const_alpha);
+void QT_FASTCALL rasterop_SourceAndDestination(uint *dest, const uint *src, int length, uint const_alpha);
+void QT_FASTCALL rasterop_SourceXorDestination(uint *dest, const uint *src, int length, uint const_alpha);
+void QT_FASTCALL rasterop_NotSourceAndNotDestination(uint *dest, const uint *src, int length, uint const_alpha);
+void QT_FASTCALL rasterop_NotSourceOrNotDestination(uint *dest, const uint *src, int length, uint const_alpha);
+void QT_FASTCALL rasterop_NotSourceXorDestination(uint *dest, const uint *src, int length, uint const_alpha);
+void QT_FASTCALL rasterop_NotSource(uint *dest, const uint *src, int length, uint const_alpha);
+void QT_FASTCALL rasterop_NotSourceAndDestination(uint *dest, const uint *src, int length, uint const_alpha);
+void QT_FASTCALL rasterop_SourceAndNotDestination(uint *dest, const uint *src, int length, uint const_alpha);
+
QT_END_NAMESPACE
#endif // QDRAWHELPER_P_H
diff --git a/src/gui/painting/qdrawhelper_sse.cpp b/src/gui/painting/qdrawhelper_sse.cpp
index 58a7fdd7db..8b17c29e92 100644
--- a/src/gui/painting/qdrawhelper_sse.cpp
+++ b/src/gui/painting/qdrawhelper_sse.cpp
@@ -77,14 +77,35 @@ CompositionFunction qt_functionForMode_SSE[numCompositionFunctions] = {
comp_func_DestinationOver<QSSEIntrinsics>,
comp_func_Clear<QSSEIntrinsics>,
comp_func_Source<QSSEIntrinsics>,
- 0,
+ comp_func_Destination,
comp_func_SourceIn<QSSEIntrinsics>,
comp_func_DestinationIn<QSSEIntrinsics>,
comp_func_SourceOut<QSSEIntrinsics>,
comp_func_DestinationOut<QSSEIntrinsics>,
comp_func_SourceAtop<QSSEIntrinsics>,
comp_func_DestinationAtop<QSSEIntrinsics>,
- comp_func_XOR<QSSEIntrinsics>
+ comp_func_XOR<QSSEIntrinsics>,
+ comp_func_Plus,
+ comp_func_Multiply,
+ comp_func_Screen,
+ comp_func_Overlay,
+ comp_func_Darken,
+ comp_func_Lighten,
+ comp_func_ColorDodge,
+ comp_func_ColorBurn,
+ comp_func_HardLight,
+ comp_func_SoftLight,
+ comp_func_Difference,
+ comp_func_Exclusion,
+ rasterop_SourceOrDestination,
+ rasterop_SourceAndDestination,
+ rasterop_SourceXorDestination,
+ rasterop_NotSourceAndNotDestination,
+ rasterop_NotSourceOrNotDestination,
+ rasterop_NotSourceXorDestination,
+ rasterop_NotSource,
+ rasterop_NotSourceAndDestination,
+ rasterop_SourceAndNotDestination
};
void qt_blend_color_argb_sse(int count, const QSpan *spans, void *userData)
diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp
index 279f685fc7..b4ef23e886 100644
--- a/src/gui/painting/qdrawhelper_sse2.cpp
+++ b/src/gui/painting/qdrawhelper_sse2.cpp
@@ -164,6 +164,72 @@ void QT_FASTCALL comp_func_SourceOver_sse2(uint *destPixels, const uint *srcPixe
}
}
+inline int comp_func_Plus_one_pixel_const_alpha(uint d, const uint s, const uint const_alpha, const uint one_minus_const_alpha)
+{
+#define MIX(mask) (qMin(((qint64(s)&mask) + (qint64(d)&mask)), qint64(mask)))
+ const int result = (MIX(AMASK) | MIX(RMASK) | MIX(GMASK) | MIX(BMASK));
+#undef MIX
+ return INTERPOLATE_PIXEL_255(result, const_alpha, d, one_minus_const_alpha);
+}
+
+inline int comp_func_Plus_one_pixel(uint d, const uint s)
+{
+#define MIX(mask) (qMin(((qint64(s)&mask) + (qint64(d)&mask)), qint64(mask)))
+ const int result = (MIX(AMASK) | MIX(RMASK) | MIX(GMASK) | MIX(BMASK));
+#undef MIX
+ return result;
+}
+
+void QT_FASTCALL comp_func_Plus_sse2(uint *dst, const uint *src, int length, uint const_alpha)
+{
+ int x = 0;
+ const int offsetToAlignOn16Bytes = (4 - ((reinterpret_cast<quintptr>(dst) >> 2) & 0x3)) & 0x3;
+ const int prologLength = qMin(length, offsetToAlignOn16Bytes);
+
+ if (const_alpha == 255) {
+ // 1) Prologue: align destination on 16 bytes
+ for (; x < prologLength; ++x)
+ dst[x] = comp_func_Plus_one_pixel(dst[x], src[x]);
+
+ // 2) composition with SSE2
+ for (; x < length - 3; x += 4) {
+ const __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]);
+ const __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]);
+
+ const __m128i result = _mm_adds_epu8(srcVector, dstVector);
+ _mm_store_si128((__m128i *)&dst[x], result);
+ }
+
+ // 3) Epilogue:
+ for (; x < length; ++x)
+ dst[x] = comp_func_Plus_one_pixel(dst[x], src[x]);
+ } else {
+ const int one_minus_const_alpha = 255 - const_alpha;
+ const __m128i constAlphaVector = _mm_set1_epi16(const_alpha);
+ const __m128i oneMinusConstAlpha = _mm_set1_epi16(one_minus_const_alpha);
+
+ // 1) Prologue: align destination on 16 bytes
+ for (; x < prologLength; ++x)
+ dst[x] = comp_func_Plus_one_pixel_const_alpha(dst[x], src[x], const_alpha, one_minus_const_alpha);
+
+ const __m128i half = _mm_set1_epi16(0x80);
+ const __m128i colorMask = _mm_set1_epi32(0x00ff00ff);
+ // 2) composition with SSE2
+ for (; x < length - 3; x += 4) {
+ const __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]);
+ const __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]);
+
+ __m128i result = _mm_adds_epu8(srcVector, dstVector);
+ INTERPOLATE_PIXEL_255_SSE2(result, result, dstVector, constAlphaVector, oneMinusConstAlpha, colorMask, half)
+ _mm_store_si128((__m128i *)&dst[x], result);
+ }
+
+ // 3) Epilogue:
+ for (; x < length; ++x)
+ dst[x] = comp_func_Plus_one_pixel_const_alpha(dst[x], src[x], const_alpha, one_minus_const_alpha);
+ }
+}
+
void qt_memfill32_sse2(quint32 *dest, quint32 value, int count)
{
if (count < 7) {
diff --git a/src/gui/painting/qdrawhelper_sse3dnow.cpp b/src/gui/painting/qdrawhelper_sse3dnow.cpp
index c58cf13c5c..9ae0e0792b 100644
--- a/src/gui/painting/qdrawhelper_sse3dnow.cpp
+++ b/src/gui/painting/qdrawhelper_sse3dnow.cpp
@@ -85,14 +85,35 @@ CompositionFunction qt_functionForMode_SSE3DNOW[numCompositionFunctions] = {
comp_func_DestinationOver<QSSE3DNOWIntrinsics>,
comp_func_Clear<QSSE3DNOWIntrinsics>,
comp_func_Source<QSSE3DNOWIntrinsics>,
- 0,
+ comp_func_Destination,
comp_func_SourceIn<QSSE3DNOWIntrinsics>,
comp_func_DestinationIn<QSSE3DNOWIntrinsics>,
comp_func_SourceOut<QSSE3DNOWIntrinsics>,
comp_func_DestinationOut<QSSE3DNOWIntrinsics>,
comp_func_SourceAtop<QSSE3DNOWIntrinsics>,
comp_func_DestinationAtop<QSSE3DNOWIntrinsics>,
- comp_func_XOR<QSSE3DNOWIntrinsics>
+ comp_func_XOR<QSSE3DNOWIntrinsics>,
+ comp_func_Plus,
+ comp_func_Multiply,
+ comp_func_Screen,
+ comp_func_Overlay,
+ comp_func_Darken,
+ comp_func_Lighten,
+ comp_func_ColorDodge,
+ comp_func_ColorBurn,
+ comp_func_HardLight,
+ comp_func_SoftLight,
+ comp_func_Difference,
+ comp_func_Exclusion,
+ rasterop_SourceOrDestination,
+ rasterop_SourceAndDestination,
+ rasterop_SourceXorDestination,
+ rasterop_NotSourceAndNotDestination,
+ rasterop_NotSourceOrNotDestination,
+ rasterop_NotSourceXorDestination,
+ rasterop_NotSource,
+ rasterop_NotSourceAndDestination,
+ rasterop_SourceAndNotDestination
};
void qt_blend_color_argb_sse3dnow(int count, const QSpan *spans, void *userData)
diff --git a/tests/auto/qpainter/tst_qpainter.cpp b/tests/auto/qpainter/tst_qpainter.cpp
index 27ee6e76f1..f358681077 100644
--- a/tests/auto/qpainter/tst_qpainter.cpp
+++ b/tests/auto/qpainter/tst_qpainter.cpp
@@ -4176,14 +4176,18 @@ void tst_QPainter::inactivePainter()
p.setWorldTransform(QTransform().scale(0.5, 0.5), true);
}
-bool testCompositionMode(int src, int dst, int expected, QPainter::CompositionMode op)
+bool testCompositionMode(int src, int dst, int expected, QPainter::CompositionMode op, qreal opacity = 1.0)
{
- QImage actual(1, 1, QImage::Format_ARGB32_Premultiplied);
+ // The test image needs to be large enough to test SIMD code
+ const QSize imageSize(100, 100);
+
+ QImage actual(imageSize, QImage::Format_ARGB32_Premultiplied);
actual.fill(QColor(dst, dst, dst).rgb());
QPainter p(&actual);
p.setCompositionMode(op);
- p.fillRect(0, 0, 1, 1, QColor(src, src, src));
+ p.setOpacity(opacity);
+ p.fillRect(QRect(QPoint(), imageSize), QColor(src, src, src));
p.end();
if (qRed(actual.pixel(0, 0)) != expected) {
@@ -4191,7 +4195,9 @@ bool testCompositionMode(int src, int dst, int expected, QPainter::CompositionMo
src, dst, qRed(actual.pixel(0, 0)), expected);
return false;
} else {
- return true;
+ QImage refImage(imageSize, QImage::Format_ARGB32_Premultiplied);
+ refImage.fill(QColor(expected, expected, expected).rgb());
+ return actual == refImage;
}
}
@@ -4206,6 +4212,16 @@ void tst_QPainter::extendedBlendModes()
QVERIFY(testCompositionMode( 0, 255, 255, QPainter::CompositionMode_Plus));
QVERIFY(testCompositionMode(128, 128, 255, QPainter::CompositionMode_Plus));
+ QVERIFY(testCompositionMode(255, 255, 255, QPainter::CompositionMode_Plus, 0.3));
+ QVERIFY(testCompositionMode( 0, 0, 0, QPainter::CompositionMode_Plus, 0.3));
+ QVERIFY(testCompositionMode(127, 128, 165, QPainter::CompositionMode_Plus, 0.3));
+ QVERIFY(testCompositionMode(127, 0, 37, QPainter::CompositionMode_Plus, 0.3));
+ QVERIFY(testCompositionMode( 0, 127, 127, QPainter::CompositionMode_Plus, 0.3));
+ QVERIFY(testCompositionMode(255, 0, 75, QPainter::CompositionMode_Plus, 0.3));
+ QVERIFY(testCompositionMode( 0, 255, 255, QPainter::CompositionMode_Plus, 0.3));
+ QVERIFY(testCompositionMode(128, 128, 166, QPainter::CompositionMode_Plus, 0.3));
+ QVERIFY(testCompositionMode(186, 200, 255, QPainter::CompositionMode_Plus, 0.3));
+
QVERIFY(testCompositionMode(255, 255, 255, QPainter::CompositionMode_Multiply));
QVERIFY(testCompositionMode( 0, 0, 0, QPainter::CompositionMode_Multiply));
QVERIFY(testCompositionMode(127, 255, 127, QPainter::CompositionMode_Multiply));