Split PixelLayout to separate source file
Change-Id: I0beafa39d92550ea78e78a07b25ce1253cc6668d Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
This commit is contained in:
parent
2ed048fa8d
commit
8a0f100e97
@ -183,6 +183,7 @@ qt_add_module(Gui
|
||||
painting/qpdf.cpp painting/qpdf_p.h
|
||||
painting/qpdfwriter.cpp painting/qpdfwriter.h
|
||||
painting/qpen.cpp painting/qpen.h
|
||||
painting/qpixellayout.cpp painting/qpixellayout_p.h
|
||||
painting/qplatformbackingstore.cpp painting/qplatformbackingstore.h
|
||||
painting/qpolygon.cpp painting/qpolygon.h
|
||||
painting/qpolygonclipper_p.h
|
||||
|
@ -56,9 +56,9 @@
|
||||
#include <limits.h>
|
||||
#include <qpa/qplatformpixmap.h>
|
||||
#include <private/qcolortransform_p.h>
|
||||
#include <private/qdrawhelper_p.h>
|
||||
#include <private/qmemrotate_p.h>
|
||||
#include <private/qimagescale_p.h>
|
||||
#include <private/qpixellayout_p.h>
|
||||
#include <private/qsimd_p.h>
|
||||
|
||||
#include <qhash.h>
|
||||
|
@ -37,10 +37,11 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <private/qdrawhelper_p.h>
|
||||
#include <private/qguiapplication_p.h>
|
||||
#include <private/qcolortrclut_p.h>
|
||||
#include <private/qdrawhelper_p.h>
|
||||
#include <private/qendian_p.h>
|
||||
#include <private/qpixellayout_p.h>
|
||||
#include <private/qsimd_p.h>
|
||||
#include <private/qimage_p.h>
|
||||
|
||||
|
@ -47,6 +47,7 @@ HEADERS += \
|
||||
painting/qpdf_p.h \
|
||||
painting/qpdfwriter.h \
|
||||
painting/qpen.h \
|
||||
painting/qpixellayout_p.h \
|
||||
painting/qpolygon.h \
|
||||
painting/qpolygonclipper_p.h \
|
||||
painting/qrangecollection.h \
|
||||
@ -100,6 +101,7 @@ SOURCES += \
|
||||
painting/qpdf.cpp \
|
||||
painting/qpdfwriter.cpp \
|
||||
painting/qpen.cpp \
|
||||
painting/qpixellayout.cpp \
|
||||
painting/qpolygon.cpp \
|
||||
painting/qrangecollection.cpp \
|
||||
painting/qrasterizer.cpp \
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -41,6 +41,7 @@
|
||||
#include "qdrawhelper_p.h"
|
||||
#include "qdrawhelper_x86_p.h"
|
||||
#include "qdrawingprimitive_sse2_p.h"
|
||||
#include "qpixellayout_p.h"
|
||||
#include "qrgba64_p.h"
|
||||
|
||||
#if defined(QT_COMPILER_SUPPORTS_AVX2)
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include <private/qdrawhelper_neon_p.h>
|
||||
#include <private/qblendfunctions_p.h>
|
||||
#include <private/qmath_p.h>
|
||||
#include <private/qpixellayout_p.h>
|
||||
|
||||
#ifdef __ARM_NEON__
|
||||
|
||||
|
@ -61,6 +61,7 @@
|
||||
#define QT_FT_BEGIN_HEADER
|
||||
#define QT_FT_END_HEADER
|
||||
#endif
|
||||
#include "private/qpixellayout_p.h"
|
||||
#include "private/qrasterdefs_p.h"
|
||||
#include <private/qsimd_p.h>
|
||||
|
||||
@ -149,8 +150,6 @@ typedef void (*SrcOverTransformFunc)(uchar *destPixels, int dbpl,
|
||||
const QTransform &targetRectTransform,
|
||||
int const_alpha);
|
||||
|
||||
typedef void (*MemRotateFunc)(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl);
|
||||
|
||||
struct DrawHelper {
|
||||
ProcessSpans blendColor;
|
||||
BitmapBlitFunc bitmapBlit;
|
||||
@ -845,31 +844,6 @@ static inline QRgba64 interpolate_4_pixels_rgb64(const QRgba64 t[], const QRgba6
|
||||
}
|
||||
#endif // __SSE2__
|
||||
|
||||
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
|
||||
static Q_ALWAYS_INLINE quint32 RGBA2ARGB(quint32 x) {
|
||||
quint32 rgb = x >> 8;
|
||||
quint32 a = x << 24;
|
||||
return a | rgb;
|
||||
}
|
||||
|
||||
static Q_ALWAYS_INLINE quint32 ARGB2RGBA(quint32 x) {
|
||||
quint32 rgb = x << 8;
|
||||
quint32 a = x >> 24;
|
||||
return a | rgb;
|
||||
}
|
||||
#else
|
||||
static Q_ALWAYS_INLINE quint32 RGBA2ARGB(quint32 x) {
|
||||
// RGBA8888 is ABGR32 on little endian.
|
||||
quint32 ag = x & 0xff00ff00;
|
||||
quint32 rg = x & 0x00ff00ff;
|
||||
return ag | (rg << 16) | (rg >> 16);
|
||||
}
|
||||
|
||||
static Q_ALWAYS_INLINE quint32 ARGB2RGBA(quint32 x) {
|
||||
return RGBA2ARGB(x);
|
||||
}
|
||||
#endif
|
||||
|
||||
static Q_ALWAYS_INLINE uint BYTE_MUL_RGB16(uint x, uint a) {
|
||||
a += 1;
|
||||
uint t = (((x & 0x07e0)*a) >> 8) & 0x07e0;
|
||||
@ -889,14 +863,6 @@ static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_div_257_floor(uint x) { return
|
||||
static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_div_257(uint x) { return qt_div_257_floor(x + 128); }
|
||||
static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_div_65535(uint x) { return (x + (x>>16) + 0x8000U) >> 16; }
|
||||
|
||||
static Q_ALWAYS_INLINE uint qAlphaRgb30(uint c)
|
||||
{
|
||||
uint a = c >> 30;
|
||||
a |= a << 2;
|
||||
a |= a << 4;
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class T> inline void qt_memfill_template(T *dest, T color, qsizetype count)
|
||||
{
|
||||
if (!count)
|
||||
@ -978,214 +944,6 @@ inline QRgb qConvertRgb16To32(uint c)
|
||||
| ((((c) << 8) & 0xf80000) | (((c) << 3) & 0x70000));
|
||||
}
|
||||
|
||||
enum QtPixelOrder {
|
||||
PixelOrderRGB,
|
||||
PixelOrderBGR
|
||||
};
|
||||
|
||||
template<enum QtPixelOrder> inline uint qConvertArgb32ToA2rgb30(QRgb);
|
||||
|
||||
template<enum QtPixelOrder> inline uint qConvertRgb32ToRgb30(QRgb);
|
||||
|
||||
template<enum QtPixelOrder> inline QRgb qConvertA2rgb30ToArgb32(uint c);
|
||||
|
||||
// A combined unpremultiply and premultiply with new simplified alpha.
|
||||
// Needed when alpha loses precision relative to other colors during conversion (ARGB32 -> A2RGB30).
|
||||
template<unsigned int Shift>
|
||||
inline QRgb qRepremultiply(QRgb p)
|
||||
{
|
||||
const uint alpha = qAlpha(p);
|
||||
if (alpha == 255 || alpha == 0)
|
||||
return p;
|
||||
p = qUnpremultiply(p);
|
||||
Q_CONSTEXPR uint mult = 255 / (255 >> Shift);
|
||||
const uint newAlpha = mult * (alpha >> Shift);
|
||||
p = (p & ~0xff000000) | (newAlpha<<24);
|
||||
return qPremultiply(p);
|
||||
}
|
||||
|
||||
template<unsigned int Shift>
|
||||
inline QRgba64 qRepremultiply(QRgba64 p)
|
||||
{
|
||||
const uint alpha = p.alpha();
|
||||
if (alpha == 65535 || alpha == 0)
|
||||
return p;
|
||||
p = p.unpremultiplied();
|
||||
Q_CONSTEXPR uint mult = 65535 / (65535 >> Shift);
|
||||
p.setAlpha(mult * (alpha >> Shift));
|
||||
return p.premultiplied();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline uint qConvertArgb32ToA2rgb30<PixelOrderBGR>(QRgb c)
|
||||
{
|
||||
c = qRepremultiply<6>(c);
|
||||
return (c & 0xc0000000)
|
||||
| (((c << 22) & 0x3fc00000) | ((c << 14) & 0x00300000))
|
||||
| (((c << 4) & 0x000ff000) | ((c >> 4) & 0x00000c00))
|
||||
| (((c >> 14) & 0x000003fc) | ((c >> 22) & 0x00000003));
|
||||
}
|
||||
|
||||
template<>
|
||||
inline uint qConvertArgb32ToA2rgb30<PixelOrderRGB>(QRgb c)
|
||||
{
|
||||
c = qRepremultiply<6>(c);
|
||||
return (c & 0xc0000000)
|
||||
| (((c << 6) & 0x3fc00000) | ((c >> 2) & 0x00300000))
|
||||
| (((c << 4) & 0x000ff000) | ((c >> 4) & 0x00000c00))
|
||||
| (((c << 2) & 0x000003fc) | ((c >> 6) & 0x00000003));
|
||||
}
|
||||
|
||||
template<>
|
||||
inline uint qConvertRgb32ToRgb30<PixelOrderBGR>(QRgb c)
|
||||
{
|
||||
return 0xc0000000
|
||||
| (((c << 22) & 0x3fc00000) | ((c << 14) & 0x00300000))
|
||||
| (((c << 4) & 0x000ff000) | ((c >> 4) & 0x00000c00))
|
||||
| (((c >> 14) & 0x000003fc) | ((c >> 22) & 0x00000003));
|
||||
}
|
||||
|
||||
template<>
|
||||
inline uint qConvertRgb32ToRgb30<PixelOrderRGB>(QRgb c)
|
||||
{
|
||||
return 0xc0000000
|
||||
| (((c << 6) & 0x3fc00000) | ((c >> 2) & 0x00300000))
|
||||
| (((c << 4) & 0x000ff000) | ((c >> 4) & 0x00000c00))
|
||||
| (((c << 2) & 0x000003fc) | ((c >> 6) & 0x00000003));
|
||||
}
|
||||
|
||||
template<>
|
||||
inline QRgb qConvertA2rgb30ToArgb32<PixelOrderBGR>(uint c)
|
||||
{
|
||||
uint a = c >> 30;
|
||||
a |= a << 2;
|
||||
a |= a << 4;
|
||||
return (a << 24)
|
||||
| ((c << 14) & 0x00ff0000)
|
||||
| ((c >> 4) & 0x0000ff00)
|
||||
| ((c >> 22) & 0x000000ff);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline QRgb qConvertA2rgb30ToArgb32<PixelOrderRGB>(uint c)
|
||||
{
|
||||
uint a = c >> 30;
|
||||
a |= a << 2;
|
||||
a |= a << 4;
|
||||
return (a << 24)
|
||||
| ((c >> 6) & 0x00ff0000)
|
||||
| ((c >> 4) & 0x0000ff00)
|
||||
| ((c >> 2) & 0x000000ff);
|
||||
}
|
||||
|
||||
template<enum QtPixelOrder> inline QRgba64 qConvertA2rgb30ToRgb64(uint rgb);
|
||||
|
||||
template<>
|
||||
inline QRgba64 qConvertA2rgb30ToRgb64<PixelOrderBGR>(uint rgb)
|
||||
{
|
||||
quint16 alpha = rgb >> 30;
|
||||
quint16 blue = (rgb >> 20) & 0x3ff;
|
||||
quint16 green = (rgb >> 10) & 0x3ff;
|
||||
quint16 red = rgb & 0x3ff;
|
||||
// Expand the range.
|
||||
alpha |= (alpha << 2);
|
||||
alpha |= (alpha << 4);
|
||||
alpha |= (alpha << 8);
|
||||
red = (red << 6) | (red >> 4);
|
||||
green = (green << 6) | (green >> 4);
|
||||
blue = (blue << 6) | (blue >> 4);
|
||||
return qRgba64(red, green, blue, alpha);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline QRgba64 qConvertA2rgb30ToRgb64<PixelOrderRGB>(uint rgb)
|
||||
{
|
||||
quint16 alpha = rgb >> 30;
|
||||
quint16 red = (rgb >> 20) & 0x3ff;
|
||||
quint16 green = (rgb >> 10) & 0x3ff;
|
||||
quint16 blue = rgb & 0x3ff;
|
||||
// Expand the range.
|
||||
alpha |= (alpha << 2);
|
||||
alpha |= (alpha << 4);
|
||||
alpha |= (alpha << 8);
|
||||
red = (red << 6) | (red >> 4);
|
||||
green = (green << 6) | (green >> 4);
|
||||
blue = (blue << 6) | (blue >> 4);
|
||||
return qRgba64(red, green, blue, alpha);
|
||||
}
|
||||
|
||||
template<enum QtPixelOrder> inline unsigned int qConvertRgb64ToRgb30(QRgba64);
|
||||
|
||||
template<>
|
||||
inline unsigned int qConvertRgb64ToRgb30<PixelOrderBGR>(QRgba64 c)
|
||||
{
|
||||
c = qRepremultiply<14>(c);
|
||||
const uint a = c.alpha() >> 14;
|
||||
const uint r = c.red() >> 6;
|
||||
const uint g = c.green() >> 6;
|
||||
const uint b = c.blue() >> 6;
|
||||
return (a << 30) | (b << 20) | (g << 10) | r;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline unsigned int qConvertRgb64ToRgb30<PixelOrderRGB>(QRgba64 c)
|
||||
{
|
||||
c = qRepremultiply<14>(c);
|
||||
const uint a = c.alpha() >> 14;
|
||||
const uint r = c.red() >> 6;
|
||||
const uint g = c.green() >> 6;
|
||||
const uint b = c.blue() >> 6;
|
||||
return (a << 30) | (r << 20) | (g << 10) | b;
|
||||
}
|
||||
|
||||
inline uint qRgbSwapRgb30(uint c)
|
||||
{
|
||||
const uint ag = c & 0xc00ffc00;
|
||||
const uint rb = c & 0x3ff003ff;
|
||||
return ag | (rb << 20) | (rb >> 20);
|
||||
}
|
||||
|
||||
inline int qRed565(quint16 rgb) {
|
||||
const int r = (rgb & 0xf800);
|
||||
return (r >> 8) | (r >> 13);
|
||||
}
|
||||
|
||||
inline int qGreen565(quint16 rgb) {
|
||||
const int g = (rgb & 0x07e0);
|
||||
return (g >> 3) | (g >> 9);
|
||||
}
|
||||
|
||||
inline int qBlue565(quint16 rgb) {
|
||||
const int b = (rgb & 0x001f);
|
||||
return (b << 3) | (b >> 2);
|
||||
}
|
||||
|
||||
// We manually unalias the variables to make sure the compiler
|
||||
// fully optimizes both aliased and unaliased cases.
|
||||
#define UNALIASED_CONVERSION_LOOP(buffer, src, count, conversion) \
|
||||
if (src == buffer) { \
|
||||
for (int i = 0; i < count; ++i) \
|
||||
buffer[i] = conversion(buffer[i]); \
|
||||
} else { \
|
||||
for (int i = 0; i < count; ++i) \
|
||||
buffer[i] = conversion(src[i]); \
|
||||
}
|
||||
|
||||
|
||||
static Q_ALWAYS_INLINE const uint *qt_convertARGB32ToARGB32PM(uint *buffer, const uint *src, int count)
|
||||
{
|
||||
UNALIASED_CONVERSION_LOOP(buffer, src, count, qPremultiply);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static Q_ALWAYS_INLINE const uint *qt_convertRGBA8888ToARGB32PM(uint *buffer, const uint *src, int count)
|
||||
{
|
||||
UNALIASED_CONVERSION_LOOP(buffer, src, count, [](uint s) { return qPremultiply(RGBA2ARGB(s));});
|
||||
return buffer;
|
||||
}
|
||||
|
||||
template<bool RGBA> void qt_convertRGBA64ToARGB32(uint *dst, const QRgba64 *src, int count);
|
||||
|
||||
const uint qt_bayer_matrix[16][16] = {
|
||||
{ 0x1, 0xc0, 0x30, 0xf0, 0xc, 0xcc, 0x3c, 0xfc,
|
||||
0x3, 0xc3, 0x33, 0xf3, 0xf, 0xcf, 0x3f, 0xff},
|
||||
@ -1265,61 +1023,70 @@ struct IntermediateBuffer
|
||||
quint32 buffer_ag[BufferSize+2];
|
||||
};
|
||||
|
||||
struct QDitherInfo {
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
typedef const uint *(QT_FASTCALL *FetchAndConvertPixelsFunc)(uint *buffer, const uchar *src, int index, int count,
|
||||
const QVector<QRgb> *clut, QDitherInfo *dither);
|
||||
typedef void (QT_FASTCALL *ConvertAndStorePixelsFunc)(uchar *dest, const uint *src, int index, int count,
|
||||
const QVector<QRgb> *clut, QDitherInfo *dither);
|
||||
|
||||
typedef const QRgba64 *(QT_FASTCALL *FetchAndConvertPixelsFunc64)(QRgba64 *buffer, const uchar *src, int index, int count,
|
||||
const QVector<QRgb> *clut, QDitherInfo *dither);
|
||||
typedef void (QT_FASTCALL *ConvertAndStorePixelsFunc64)(uchar *dest, const QRgba64 *src, int index, int count,
|
||||
const QVector<QRgb> *clut, QDitherInfo *dither);
|
||||
|
||||
typedef void (QT_FASTCALL *ConvertFunc)(uint *buffer, int count, const QVector<QRgb> *clut);
|
||||
typedef void (QT_FASTCALL *Convert64Func)(quint64 *buffer, int count, const QVector<QRgb> *clut);
|
||||
typedef const QRgba64 *(QT_FASTCALL *ConvertTo64Func)(QRgba64 *buffer, const uint *src, int count,
|
||||
const QVector<QRgb> *clut, QDitherInfo *dither);
|
||||
typedef void (QT_FASTCALL *RbSwapFunc)(uchar *dst, const uchar *src, int count);
|
||||
|
||||
|
||||
struct QPixelLayout
|
||||
template <QPixelLayout::BPP bpp>
|
||||
inline uint QT_FASTCALL qFetchPixel(const uchar *, int)
|
||||
{
|
||||
// Bits per pixel
|
||||
enum BPP {
|
||||
BPPNone,
|
||||
BPP1MSB,
|
||||
BPP1LSB,
|
||||
BPP8,
|
||||
BPP16,
|
||||
BPP24,
|
||||
BPP32,
|
||||
BPP64,
|
||||
BPPCount
|
||||
Q_UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline uint QT_FASTCALL qFetchPixel<QPixelLayout::BPP1LSB>(const uchar *src, int index)
|
||||
{
|
||||
return (src[index >> 3] >> (index & 7)) & 1;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline uint QT_FASTCALL qFetchPixel<QPixelLayout::BPP1MSB>(const uchar *src, int index)
|
||||
{
|
||||
return (src[index >> 3] >> (~index & 7)) & 1;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline uint QT_FASTCALL qFetchPixel<QPixelLayout::BPP8>(const uchar *src, int index)
|
||||
{
|
||||
return src[index];
|
||||
}
|
||||
|
||||
template <>
|
||||
inline uint QT_FASTCALL qFetchPixel<QPixelLayout::BPP16>(const uchar *src, int index)
|
||||
{
|
||||
return reinterpret_cast<const quint16 *>(src)[index];
|
||||
}
|
||||
|
||||
template <>
|
||||
inline uint QT_FASTCALL qFetchPixel<QPixelLayout::BPP24>(const uchar *src, int index)
|
||||
{
|
||||
return reinterpret_cast<const quint24 *>(src)[index];
|
||||
}
|
||||
|
||||
template <>
|
||||
inline uint QT_FASTCALL qFetchPixel<QPixelLayout::BPP32>(const uchar *src, int index)
|
||||
{
|
||||
return reinterpret_cast<const uint *>(src)[index];
|
||||
}
|
||||
|
||||
template <>
|
||||
inline uint QT_FASTCALL qFetchPixel<QPixelLayout::BPP64>(const uchar *src, int index)
|
||||
{
|
||||
// We have to do the conversion in fetch to fit into a 32bit uint
|
||||
QRgba64 c = reinterpret_cast<const QRgba64 *>(src)[index];
|
||||
return c.toArgb32();
|
||||
}
|
||||
|
||||
typedef uint (QT_FASTCALL *FetchPixelFunc)(const uchar *src, int index);
|
||||
|
||||
constexpr FetchPixelFunc qFetchPixelTable[QPixelLayout::BPPCount] = {
|
||||
nullptr, // BPPNone
|
||||
qFetchPixel<QPixelLayout::BPP1MSB>,
|
||||
qFetchPixel<QPixelLayout::BPP1LSB>,
|
||||
qFetchPixel<QPixelLayout::BPP8>,
|
||||
qFetchPixel<QPixelLayout::BPP16>,
|
||||
qFetchPixel<QPixelLayout::BPP24>,
|
||||
qFetchPixel<QPixelLayout::BPP32>,
|
||||
qFetchPixel<QPixelLayout::BPP64>,
|
||||
};
|
||||
|
||||
bool hasAlphaChannel;
|
||||
bool premultiplied;
|
||||
BPP bpp;
|
||||
RbSwapFunc rbSwap;
|
||||
ConvertFunc convertToARGB32PM;
|
||||
ConvertTo64Func convertToRGBA64PM;
|
||||
FetchAndConvertPixelsFunc fetchToARGB32PM;
|
||||
FetchAndConvertPixelsFunc64 fetchToRGBA64PM;
|
||||
ConvertAndStorePixelsFunc storeFromARGB32PM;
|
||||
ConvertAndStorePixelsFunc storeFromRGB32;
|
||||
};
|
||||
|
||||
extern ConvertAndStorePixelsFunc64 qStoreFromRGBA64PM[QImage::NImageFormats];
|
||||
|
||||
extern QPixelLayout qPixelLayouts[QImage::NImageFormats];
|
||||
|
||||
extern MemRotateFunc qMemRotateFunctions[QPixelLayout::BPPCount][3];
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QDRAWHELPER_P_H
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include <private/qdrawhelper_p.h>
|
||||
#include <private/qdrawingprimitive_sse2_p.h>
|
||||
#include <private/qpaintengine_raster_p.h>
|
||||
#include <private/qpixellayout_p.h>
|
||||
|
||||
#if defined(QT_COMPILER_SUPPORTS_SSE4_1)
|
||||
|
||||
|
@ -37,7 +37,8 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "private/qmemrotate_p.h"
|
||||
#include "qmemrotate_p.h"
|
||||
#include "qpixellayout_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
@ -52,7 +52,7 @@
|
||||
//
|
||||
|
||||
#include <QtGui/private/qtguiglobal_p.h>
|
||||
#include "private/qdrawhelper_p.h"
|
||||
#include <QtGui/private/qdrawhelper_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
@ -62,8 +62,10 @@
|
||||
#include <private/qimage_p.h>
|
||||
#include <private/qstatictext_p.h>
|
||||
#include <private/qcosmeticstroker_p.h>
|
||||
#include "qmemrotate_p.h"
|
||||
#include "qrgba64_p.h"
|
||||
#include <private/qdrawhelper_p.h>
|
||||
#include <private/qmemrotate_p.h>
|
||||
#include <private/qpixellayout_p.h>
|
||||
#include <private/qrgba64_p.h>
|
||||
|
||||
#include "qpaintengine_raster_p.h"
|
||||
// #include "qbezier_p.h"
|
||||
|
1545
src/gui/painting/qpixellayout.cpp
Normal file
1545
src/gui/painting/qpixellayout.cpp
Normal file
File diff suppressed because it is too large
Load Diff
336
src/gui/painting/qpixellayout_p.h
Normal file
336
src/gui/painting/qpixellayout_p.h
Normal file
@ -0,0 +1,336 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtGui module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QPIXELLAYOUT_P_H
|
||||
#define QPIXELLAYOUT_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtCore/qvector.h>
|
||||
#include <QtGui/qimage.h>
|
||||
#include <QtGui/qrgba64.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
enum QtPixelOrder {
|
||||
PixelOrderRGB,
|
||||
PixelOrderBGR
|
||||
};
|
||||
|
||||
template<enum QtPixelOrder> inline uint qConvertArgb32ToA2rgb30(QRgb);
|
||||
|
||||
template<enum QtPixelOrder> inline uint qConvertRgb32ToRgb30(QRgb);
|
||||
|
||||
template<enum QtPixelOrder> inline QRgb qConvertA2rgb30ToArgb32(uint c);
|
||||
|
||||
// A combined unpremultiply and premultiply with new simplified alpha.
|
||||
// Needed when alpha loses precision relative to other colors during conversion (ARGB32 -> A2RGB30).
|
||||
template<unsigned int Shift>
|
||||
inline QRgb qRepremultiply(QRgb p)
|
||||
{
|
||||
const uint alpha = qAlpha(p);
|
||||
if (alpha == 255 || alpha == 0)
|
||||
return p;
|
||||
p = qUnpremultiply(p);
|
||||
Q_CONSTEXPR uint mult = 255 / (255 >> Shift);
|
||||
const uint newAlpha = mult * (alpha >> Shift);
|
||||
p = (p & ~0xff000000) | (newAlpha<<24);
|
||||
return qPremultiply(p);
|
||||
}
|
||||
|
||||
template<unsigned int Shift>
|
||||
inline QRgba64 qRepremultiply(QRgba64 p)
|
||||
{
|
||||
const uint alpha = p.alpha();
|
||||
if (alpha == 65535 || alpha == 0)
|
||||
return p;
|
||||
p = p.unpremultiplied();
|
||||
Q_CONSTEXPR uint mult = 65535 / (65535 >> Shift);
|
||||
p.setAlpha(mult * (alpha >> Shift));
|
||||
return p.premultiplied();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline uint qConvertArgb32ToA2rgb30<PixelOrderBGR>(QRgb c)
|
||||
{
|
||||
c = qRepremultiply<6>(c);
|
||||
return (c & 0xc0000000)
|
||||
| (((c << 22) & 0x3fc00000) | ((c << 14) & 0x00300000))
|
||||
| (((c << 4) & 0x000ff000) | ((c >> 4) & 0x00000c00))
|
||||
| (((c >> 14) & 0x000003fc) | ((c >> 22) & 0x00000003));
|
||||
}
|
||||
|
||||
template<>
|
||||
inline uint qConvertArgb32ToA2rgb30<PixelOrderRGB>(QRgb c)
|
||||
{
|
||||
c = qRepremultiply<6>(c);
|
||||
return (c & 0xc0000000)
|
||||
| (((c << 6) & 0x3fc00000) | ((c >> 2) & 0x00300000))
|
||||
| (((c << 4) & 0x000ff000) | ((c >> 4) & 0x00000c00))
|
||||
| (((c << 2) & 0x000003fc) | ((c >> 6) & 0x00000003));
|
||||
}
|
||||
|
||||
template<>
|
||||
inline uint qConvertRgb32ToRgb30<PixelOrderBGR>(QRgb c)
|
||||
{
|
||||
return 0xc0000000
|
||||
| (((c << 22) & 0x3fc00000) | ((c << 14) & 0x00300000))
|
||||
| (((c << 4) & 0x000ff000) | ((c >> 4) & 0x00000c00))
|
||||
| (((c >> 14) & 0x000003fc) | ((c >> 22) & 0x00000003));
|
||||
}
|
||||
|
||||
template<>
|
||||
inline uint qConvertRgb32ToRgb30<PixelOrderRGB>(QRgb c)
|
||||
{
|
||||
return 0xc0000000
|
||||
| (((c << 6) & 0x3fc00000) | ((c >> 2) & 0x00300000))
|
||||
| (((c << 4) & 0x000ff000) | ((c >> 4) & 0x00000c00))
|
||||
| (((c << 2) & 0x000003fc) | ((c >> 6) & 0x00000003));
|
||||
}
|
||||
|
||||
template<>
|
||||
inline QRgb qConvertA2rgb30ToArgb32<PixelOrderBGR>(uint c)
|
||||
{
|
||||
uint a = c >> 30;
|
||||
a |= a << 2;
|
||||
a |= a << 4;
|
||||
return (a << 24)
|
||||
| ((c << 14) & 0x00ff0000)
|
||||
| ((c >> 4) & 0x0000ff00)
|
||||
| ((c >> 22) & 0x000000ff);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline QRgb qConvertA2rgb30ToArgb32<PixelOrderRGB>(uint c)
|
||||
{
|
||||
uint a = c >> 30;
|
||||
a |= a << 2;
|
||||
a |= a << 4;
|
||||
return (a << 24)
|
||||
| ((c >> 6) & 0x00ff0000)
|
||||
| ((c >> 4) & 0x0000ff00)
|
||||
| ((c >> 2) & 0x000000ff);
|
||||
}
|
||||
|
||||
template<enum QtPixelOrder> inline QRgba64 qConvertA2rgb30ToRgb64(uint rgb);
|
||||
|
||||
template<>
|
||||
inline QRgba64 qConvertA2rgb30ToRgb64<PixelOrderBGR>(uint rgb)
|
||||
{
|
||||
quint16 alpha = rgb >> 30;
|
||||
quint16 blue = (rgb >> 20) & 0x3ff;
|
||||
quint16 green = (rgb >> 10) & 0x3ff;
|
||||
quint16 red = rgb & 0x3ff;
|
||||
// Expand the range.
|
||||
alpha |= (alpha << 2);
|
||||
alpha |= (alpha << 4);
|
||||
alpha |= (alpha << 8);
|
||||
red = (red << 6) | (red >> 4);
|
||||
green = (green << 6) | (green >> 4);
|
||||
blue = (blue << 6) | (blue >> 4);
|
||||
return qRgba64(red, green, blue, alpha);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline QRgba64 qConvertA2rgb30ToRgb64<PixelOrderRGB>(uint rgb)
|
||||
{
|
||||
quint16 alpha = rgb >> 30;
|
||||
quint16 red = (rgb >> 20) & 0x3ff;
|
||||
quint16 green = (rgb >> 10) & 0x3ff;
|
||||
quint16 blue = rgb & 0x3ff;
|
||||
// Expand the range.
|
||||
alpha |= (alpha << 2);
|
||||
alpha |= (alpha << 4);
|
||||
alpha |= (alpha << 8);
|
||||
red = (red << 6) | (red >> 4);
|
||||
green = (green << 6) | (green >> 4);
|
||||
blue = (blue << 6) | (blue >> 4);
|
||||
return qRgba64(red, green, blue, alpha);
|
||||
}
|
||||
|
||||
template<enum QtPixelOrder> inline unsigned int qConvertRgb64ToRgb30(QRgba64);
|
||||
|
||||
template<>
|
||||
inline unsigned int qConvertRgb64ToRgb30<PixelOrderBGR>(QRgba64 c)
|
||||
{
|
||||
c = qRepremultiply<14>(c);
|
||||
const uint a = c.alpha() >> 14;
|
||||
const uint r = c.red() >> 6;
|
||||
const uint g = c.green() >> 6;
|
||||
const uint b = c.blue() >> 6;
|
||||
return (a << 30) | (b << 20) | (g << 10) | r;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline unsigned int qConvertRgb64ToRgb30<PixelOrderRGB>(QRgba64 c)
|
||||
{
|
||||
c = qRepremultiply<14>(c);
|
||||
const uint a = c.alpha() >> 14;
|
||||
const uint r = c.red() >> 6;
|
||||
const uint g = c.green() >> 6;
|
||||
const uint b = c.blue() >> 6;
|
||||
return (a << 30) | (r << 20) | (g << 10) | b;
|
||||
}
|
||||
|
||||
inline uint qRgbSwapRgb30(uint c)
|
||||
{
|
||||
const uint ag = c & 0xc00ffc00;
|
||||
const uint rb = c & 0x3ff003ff;
|
||||
return ag | (rb << 20) | (rb >> 20);
|
||||
}
|
||||
|
||||
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
|
||||
Q_ALWAYS_INLINE quint32 RGBA2ARGB(quint32 x) {
|
||||
quint32 rgb = x >> 8;
|
||||
quint32 a = x << 24;
|
||||
return a | rgb;
|
||||
}
|
||||
|
||||
Q_ALWAYS_INLINE quint32 ARGB2RGBA(quint32 x) {
|
||||
quint32 rgb = x << 8;
|
||||
quint32 a = x >> 24;
|
||||
return a | rgb;
|
||||
}
|
||||
#else
|
||||
Q_ALWAYS_INLINE quint32 RGBA2ARGB(quint32 x) {
|
||||
// RGBA8888 is ABGR32 on little endian.
|
||||
quint32 ag = x & 0xff00ff00;
|
||||
quint32 rg = x & 0x00ff00ff;
|
||||
return ag | (rg << 16) | (rg >> 16);
|
||||
}
|
||||
|
||||
Q_ALWAYS_INLINE quint32 ARGB2RGBA(quint32 x) {
|
||||
return RGBA2ARGB(x);
|
||||
}
|
||||
#endif
|
||||
|
||||
// We manually unalias the variables to make sure the compiler
|
||||
// fully optimizes both aliased and unaliased cases.
|
||||
#define UNALIASED_CONVERSION_LOOP(buffer, src, count, conversion) \
|
||||
if (src == buffer) { \
|
||||
for (int i = 0; i < count; ++i) \
|
||||
buffer[i] = conversion(buffer[i]); \
|
||||
} else { \
|
||||
for (int i = 0; i < count; ++i) \
|
||||
buffer[i] = conversion(src[i]); \
|
||||
}
|
||||
|
||||
|
||||
inline const uint *qt_convertARGB32ToARGB32PM(uint *buffer, const uint *src, int count)
|
||||
{
|
||||
UNALIASED_CONVERSION_LOOP(buffer, src, count, qPremultiply);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
inline const uint *qt_convertRGBA8888ToARGB32PM(uint *buffer, const uint *src, int count)
|
||||
{
|
||||
UNALIASED_CONVERSION_LOOP(buffer, src, count, [](uint s) { return qPremultiply(RGBA2ARGB(s));});
|
||||
return buffer;
|
||||
}
|
||||
|
||||
template<bool RGBA> void qt_convertRGBA64ToARGB32(uint *dst, const QRgba64 *src, int count);
|
||||
|
||||
struct QDitherInfo {
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
typedef const uint *(QT_FASTCALL *FetchAndConvertPixelsFunc)(uint *buffer, const uchar *src, int index, int count,
|
||||
const QVector<QRgb> *clut, QDitherInfo *dither);
|
||||
typedef void (QT_FASTCALL *ConvertAndStorePixelsFunc)(uchar *dest, const uint *src, int index, int count,
|
||||
const QVector<QRgb> *clut, QDitherInfo *dither);
|
||||
|
||||
typedef const QRgba64 *(QT_FASTCALL *FetchAndConvertPixelsFunc64)(QRgba64 *buffer, const uchar *src, int index, int count,
|
||||
const QVector<QRgb> *clut, QDitherInfo *dither);
|
||||
typedef void (QT_FASTCALL *ConvertAndStorePixelsFunc64)(uchar *dest, const QRgba64 *src, int index, int count,
|
||||
const QVector<QRgb> *clut, QDitherInfo *dither);
|
||||
|
||||
typedef void (QT_FASTCALL *ConvertFunc)(uint *buffer, int count, const QVector<QRgb> *clut);
|
||||
typedef void (QT_FASTCALL *Convert64Func)(quint64 *buffer, int count, const QVector<QRgb> *clut);
|
||||
typedef const QRgba64 *(QT_FASTCALL *ConvertTo64Func)(QRgba64 *buffer, const uint *src, int count,
|
||||
const QVector<QRgb> *clut, QDitherInfo *dither);
|
||||
typedef void (QT_FASTCALL *RbSwapFunc)(uchar *dst, const uchar *src, int count);
|
||||
|
||||
typedef void (*MemRotateFunc)(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl);
|
||||
|
||||
struct QPixelLayout
|
||||
{
|
||||
// Bits per pixel
|
||||
enum BPP {
|
||||
BPPNone,
|
||||
BPP1MSB,
|
||||
BPP1LSB,
|
||||
BPP8,
|
||||
BPP16,
|
||||
BPP24,
|
||||
BPP32,
|
||||
BPP64,
|
||||
BPPCount
|
||||
};
|
||||
|
||||
bool hasAlphaChannel;
|
||||
bool premultiplied;
|
||||
BPP bpp;
|
||||
RbSwapFunc rbSwap;
|
||||
ConvertFunc convertToARGB32PM;
|
||||
ConvertTo64Func convertToRGBA64PM;
|
||||
FetchAndConvertPixelsFunc fetchToARGB32PM;
|
||||
FetchAndConvertPixelsFunc64 fetchToRGBA64PM;
|
||||
ConvertAndStorePixelsFunc storeFromARGB32PM;
|
||||
ConvertAndStorePixelsFunc storeFromRGB32;
|
||||
};
|
||||
|
||||
extern ConvertAndStorePixelsFunc64 qStoreFromRGBA64PM[QImage::NImageFormats];
|
||||
|
||||
extern QPixelLayout qPixelLayouts[QImage::NImageFormats];
|
||||
|
||||
extern MemRotateFunc qMemRotateFunctions[QPixelLayout::BPPCount][3];
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QPIXELLAYOUT_P_H
|
Loading…
x
Reference in New Issue
Block a user