Remove runtime detection of SSE2

If the compiler supports SSE2, we'll use our SSE2-optimised code
unconditionally. Runtime detection is left for SSSE3 code.

The SSE2 codebase is big and thus a timebomb if an inline function
gets leaked out and run without runtime check. In reality, it's
extremely unlikely people running CPUs without SSE2 support are
running Qt 5 at this moment (they're either too old or too new,
e.g. Intel Quark).

The SSSE3 codebase is a lot more manageable.

Task-number: QTBUG-30440
Change-Id: I3e586e4434e820365d5316b650ee3061d0acf767
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
This commit is contained in:
Thiago Macieira 2013-12-08 19:16:57 -08:00 committed by The Qt Project
parent 5ca6039b77
commit d006e69da6
6 changed files with 67 additions and 80 deletions

View File

@ -79,5 +79,7 @@ contains(QT_CONFIG, gif):include($$PWD/qgifhandler.pri)
# SIMD # SIMD
NEON_SOURCES += image/qimage_neon.cpp NEON_SOURCES += image/qimage_neon.cpp
SSE2_SOURCES += image/qimage_sse2.cpp contains(QT_CPU_FEATURES.$$QT_ARCH, sse2) {
SSSE3_SOURCES += image/qimage_ssse3.cpp SOURCES += image/qimage_sse2.cpp
SSSE3_SOURCES += image/qimage_ssse3.cpp
}

View File

@ -162,6 +162,9 @@ static void convert_ARGB_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt:
} }
} }
extern bool convert_ARGB_to_ARGB_PM_inplace_sse2(QImageData *data, Qt::ImageConversionFlags);
#ifndef __SSE2__
static bool convert_ARGB_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags) static bool convert_ARGB_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags)
{ {
Q_ASSERT(data->format == QImage::Format_ARGB32); Q_ASSERT(data->format == QImage::Format_ARGB32);
@ -180,6 +183,7 @@ static bool convert_ARGB_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversio
data->format = QImage::Format_ARGB32_Premultiplied; data->format = QImage::Format_ARGB32_Premultiplied;
return true; return true;
} }
#endif
static void convert_ARGB_to_RGBx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) static void convert_ARGB_to_RGBx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
{ {
@ -1986,7 +1990,11 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0, 0,
0, 0,
0, 0,
#ifdef __SSE2__
convert_ARGB_to_ARGB_PM_inplace_sse2,
#else
convert_ARGB_to_ARGB_PM_inplace, convert_ARGB_to_ARGB_PM_inplace,
#endif
0, 0,
0, 0,
0, 0,
@ -2115,21 +2123,14 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
void qInitImageConversions() void qInitImageConversions()
{ {
#if defined(QT_COMPILER_SUPPORTS_SSE2) #if defined(__SSE2__) && defined(QT_COMPILER_SUPPORTS_SSSE3)
if (qCpuHasFeature(SSE2)) { if (qCpuHasFeature(SSSE3)) {
extern bool convert_ARGB_to_ARGB_PM_inplace_sse2(QImageData *data, Qt::ImageConversionFlags); extern void convert_RGB888_to_RGB32_ssse3(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
qimage_inplace_converter_map[QImage::Format_ARGB32][QImage::Format_ARGB32_Premultiplied] = convert_ARGB_to_ARGB_PM_inplace_sse2; qimage_converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_ssse3;
#ifdef QT_COMPILER_SUPPORTS_SSSE3 qimage_converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_ssse3;
if (qCpuHasFeature(SSSE3)) { qimage_converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_ssse3;
extern void convert_RGB888_to_RGB32_ssse3(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
qimage_converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_ssse3;
qimage_converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_ssse3;
qimage_converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_ssse3;
}
#endif
return;
} }
#endif // SSE2 #endif
#ifdef QT_COMPILER_SUPPORTS_NEON #ifdef QT_COMPILER_SUPPORTS_NEON
if (qCpuHasFeature(NEON)) { if (qCpuHasFeature(NEON)) {

View File

@ -87,8 +87,10 @@ SOURCES += \
painting/qpaintbuffer.cpp \ painting/qpaintbuffer.cpp \
painting/qpathsimplifier.cpp painting/qpathsimplifier.cpp
SSE2_SOURCES += painting/qdrawhelper_sse2.cpp contains(QT_CPU_FEATURES.$$QT_ARCH, sse2) {
SSSE3_SOURCES += painting/qdrawhelper_ssse3.cpp SOURCES += painting/qdrawhelper_sse2.cpp
SSSE3_SOURCES += painting/qdrawhelper_ssse3.cpp
}
IWMMXT_SOURCES += painting/qdrawhelper_iwmmxt.cpp IWMMXT_SOURCES += painting/qdrawhelper_iwmmxt.cpp
!ios { !ios {

View File

@ -6201,62 +6201,51 @@ void qInitDrawhelperAsm()
CompositionFunctionSolid *functionForModeSolidAsm = 0; CompositionFunctionSolid *functionForModeSolidAsm = 0;
const uint features = qCpuFeatures(); const uint features = qCpuFeatures();
if (false) { Q_UNUSED(features);
Q_UNUSED(features); #ifdef __SSE2__
#ifdef QT_COMPILER_SUPPORTS_SSE2
} else if (features & SSE2) {
qt_memfill32 = qt_memfill32_sse2; qt_memfill32 = qt_memfill32_sse2;
qt_memfill16 = qt_memfill16_sse2; qt_memfill16 = qt_memfill16_sse2;
qDrawHelper[QImage::Format_RGB32].bitmapBlit = qt_bitmapblit32_sse2; qDrawHelper[QImage::Format_RGB32].bitmapBlit = qt_bitmapblit32_sse2;
qDrawHelper[QImage::Format_ARGB32].bitmapBlit = qt_bitmapblit32_sse2; qDrawHelper[QImage::Format_ARGB32].bitmapBlit = qt_bitmapblit32_sse2;
qDrawHelper[QImage::Format_ARGB32_Premultiplied].bitmapBlit = qt_bitmapblit32_sse2; qDrawHelper[QImage::Format_ARGB32_Premultiplied].bitmapBlit = qt_bitmapblit32_sse2;
qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_sse2; qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_sse2;
qDrawHelper[QImage::Format_RGBX8888].bitmapBlit = qt_bitmapblit32_sse2; qDrawHelper[QImage::Format_RGBX8888].bitmapBlit = qt_bitmapblit32_sse2;
qDrawHelper[QImage::Format_RGBA8888].bitmapBlit = qt_bitmapblit32_sse2; qDrawHelper[QImage::Format_RGBA8888].bitmapBlit = qt_bitmapblit32_sse2;
qDrawHelper[QImage::Format_RGBA8888_Premultiplied].bitmapBlit = qt_bitmapblit32_sse2; qDrawHelper[QImage::Format_RGBA8888_Premultiplied].bitmapBlit = qt_bitmapblit32_sse2;
extern void qt_scale_image_argb32_on_argb32_sse2(uchar *destPixels, int dbpl, extern void qt_scale_image_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl, const uchar *srcPixels, int sbpl,
const QRectF &targetRect, const QRectF &targetRect,
const QRectF &sourceRect, const QRectF &sourceRect,
const QRect &clip, const QRect &clip,
int const_alpha); int const_alpha);
qScaleFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2; qScaleFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
qScaleFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2; qScaleFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN qScaleFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
qScaleFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2; qScaleFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
qScaleFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
#endif
#endif
}
#ifdef QT_COMPILER_SUPPORTS_SSE2 extern void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl,
if (features & SSE2) { const uchar *srcPixels, int sbpl,
extern void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl, int w, int h,
const uchar *srcPixels, int sbpl, int const_alpha);
int w, int h, extern void qt_blend_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
int const_alpha); const uchar *srcPixels, int sbpl,
extern void qt_blend_argb32_on_argb32_sse2(uchar *destPixels, int dbpl, int w, int h,
const uchar *srcPixels, int sbpl, int const_alpha);
int w, int h,
int const_alpha);
qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2; qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2;
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2; qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2;
qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2; qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2; qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_sse2;
qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_sse2; qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_sse2;
qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_sse2; qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_sse2; qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
#endif
extern const uint * QT_FASTCALL qt_fetch_radial_gradient_sse2(uint *buffer, const Operator *op, const QSpanData *data, extern const uint * QT_FASTCALL qt_fetch_radial_gradient_sse2(uint *buffer, const Operator *op, const QSpanData *data,
int y, int x, int length); int y, int x, int length);
qt_fetch_radial_gradient = qt_fetch_radial_gradient_sse2; qt_fetch_radial_gradient = qt_fetch_radial_gradient_sse2;
}
#ifdef QT_COMPILER_SUPPORTS_SSSE3 #ifdef QT_COMPILER_SUPPORTS_SSSE3
if (features & SSSE3) { if (features & SSSE3) {
@ -6267,22 +6256,15 @@ void qInitDrawhelperAsm()
qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3; qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3; qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3; qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3; qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
#endif
} }
#endif // SSSE3 #endif // SSSE3
functionForModeAsm = qt_functionForMode_SSE2;
functionForModeSolidAsm = qt_functionForModeSolid_SSE2;
#endif // SSE2 #endif // SSE2
#ifdef QT_COMPILER_SUPPORTS_SSE2
if (features & SSE2) {
functionForModeAsm = qt_functionForMode_SSE2;
functionForModeSolidAsm = qt_functionForModeSolid_SSE2;
}
#endif
#ifdef QT_COMPILER_SUPPORTS_IWMMXT #ifdef QT_COMPILER_SUPPORTS_IWMMXT
if (features & IWMMXT) { if (features & IWMMXT) {
functionForModeAsm = qt_functionForMode_IWMMXT; functionForModeAsm = qt_functionForMode_IWMMXT;

View File

@ -57,7 +57,7 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
#ifdef QT_COMPILER_SUPPORTS_SSE2 #ifdef __SSE2__
void qt_memfill32_sse2(quint32 *dest, quint32 value, int count); void qt_memfill32_sse2(quint32 *dest, quint32 value, int count);
void qt_memfill16_sse2(quint16 *dest, quint16 value, int count); void qt_memfill16_sse2(quint16 *dest, quint16 value, int count);
void qt_bitmapblit32_sse2(QRasterBuffer *rasterBuffer, int x, int y, void qt_bitmapblit32_sse2(QRasterBuffer *rasterBuffer, int x, int y,
@ -77,7 +77,7 @@ void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl,
extern CompositionFunction qt_functionForMode_SSE2[]; extern CompositionFunction qt_functionForMode_SSE2[];
extern CompositionFunctionSolid qt_functionForModeSolid_SSE2[]; extern CompositionFunctionSolid qt_functionForModeSolid_SSE2[];
#endif // QT_COMPILER_SUPPORTS_SSE2 #endif // __SSE2__
#ifdef QT_COMPILER_SUPPORTS_IWMMXT #ifdef QT_COMPILER_SUPPORTS_IWMMXT
void qt_blend_color_argb_iwmmxt(int count, const QSpan *spans, void *userData); void qt_blend_color_argb_iwmmxt(int count, const QSpan *spans, void *userData);

View File

@ -44,7 +44,7 @@
#include <private/qsimd_p.h> #include <private/qsimd_p.h>
#ifdef QT_COMPILER_SUPPORTS_SSE2 #ifdef __SSE2__
// //
// W A R N I N G // W A R N I N G
@ -242,6 +242,6 @@ QT_BEGIN_NAMESPACE
QT_END_NAMESPACE QT_END_NAMESPACE
#endif // QT_COMPILER_SUPPORTS_SSE2 #endif // __SSE2__
#endif // QDRAWINGPRIMITIVE_SSE2_P_H #endif // QDRAWINGPRIMITIVE_SSE2_P_H