Add a qt_memfill24 implementation

This function gets called from qt_rectfill_quint24, which is used by the
RGB666, ARGB6666_Premultiplied, ARGB8555_Premultiplied, and RGB888
formats.

Together-with: Thiago Macieira <thiago.macieira@intel.com>
Change-Id: Iba4b5c183776497d8ee1fffd1564585fdee835c2
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
bb10
Allan Sandfeld Jensen 2018-11-14 14:17:38 +01:00 committed by Thiago Macieira
parent db0616097f
commit 33177b0456
2 changed files with 59 additions and 19 deletions

View File

@ -55,6 +55,7 @@
#endif
#include <private/qguiapplication_p.h>
#include <private/qrgba64_p.h>
#include <qendian.h>
#include <qloggingcategory.h>
#include <qmath.h>
@ -6267,6 +6268,42 @@ void qt_memfill64(quint64 *dest, quint64 color, qsizetype count)
}
#endif
void qt_memfill24(quint24 *dest, quint24 color, qsizetype count)
{
const quint32 v = color;
quint24 *end = dest + count;
// prolog: align dest to 32bit
while ((quintptr(dest) & 0x3) && dest < end) {
*dest++ = v;
}
if (dest >= end)
return;
const uint val1 = qFromBigEndian((v << 8) | (v >> 16));
const uint val2 = qFromBigEndian((v << 16) | (v >> 8));
const uint val3 = qFromBigEndian((v << 24) | (v >> 0));
for ( ; dest <= (end - 4); dest += 4) {
quint32 *dst = reinterpret_cast<quint32 *>(dest);
dst[0] = val1;
dst[1] = val2;
dst[2] = val3;
}
// less than 4px left
switch (end - dest) {
case 3:
*dest++ = v;
Q_FALLTHROUGH();
case 2:
*dest++ = v;
Q_FALLTHROUGH();
case 1:
*dest++ = v;
}
}
void qt_memfill16(quint16 *dest, quint16 value, qsizetype count)
{
const int align = quintptr(dest) & 0x3;

View File

@ -165,6 +165,22 @@ extern SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::N
extern DrawHelper qDrawHelper[QImage::NImageFormats];
struct quint24 {
quint24() = default;
quint24(uint value)
{
data[0] = uchar(value >> 16);
data[1] = uchar(value >> 8);
data[2] = uchar(value);
}
operator uint() const
{
return data[2] | (data[1] << 8) | (data[0] << 16);
}
uchar data[3];
};
void qBlendGradient(int count, const QSpan *spans, void *userData);
void qBlendTexture(int count, const QSpan *spans, void *userData);
#ifdef __SSE2__
@ -174,6 +190,7 @@ extern void (*qt_memfill32)(quint32 *dest, quint32 value, qsizetype count);
extern void qt_memfill64(quint64 *dest, quint64 value, qsizetype count);
extern void qt_memfill32(quint32 *dest, quint32 value, qsizetype count);
#endif
extern void qt_memfill24(quint24 *dest, quint24 value, qsizetype count);
extern void qt_memfill16(quint16 *dest, quint16 value, qsizetype count);
typedef void (QT_FASTCALL *CompositionFunction)(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha);
@ -872,25 +889,6 @@ static Q_ALWAYS_INLINE uint qAlphaRgb30(uint c)
return a;
}
struct quint24 {
quint24() = default;
quint24(uint value);
operator uint() const;
uchar data[3];
};
inline quint24::quint24(uint value)
{
data[0] = uchar(value >> 16);
data[1] = uchar(value >> 8);
data[2] = uchar(value);
}
inline quint24::operator uint() const
{
return data[2] | (data[1] << 8) | (data[0] << 16);
}
template <class T> inline void qt_memfill_template(T *dest, T color, qsizetype count)
{
if (!count)
@ -926,6 +924,11 @@ template<> inline void qt_memfill(quint32 *dest, quint32 color, qsizetype count)
qt_memfill32(dest, color, count);
}
template<> inline void qt_memfill(quint24 *dest, quint24 color, qsizetype count)
{
qt_memfill24(dest, color, count);
}
template<> inline void qt_memfill(quint16 *dest, quint16 color, qsizetype count)
{
qt_memfill16(dest, color, count);