Add support for more composition modes in rgb64 rendering
Change-Id: I3bacecbabdf2d7b2de1acd86ab9383e69924a390 Reviewed-by: Gunnar Sletta <gunnar@sletta.org>bb10
parent
29380121ef
commit
5c7d2d1d67
|
|
@ -3029,6 +3029,23 @@ void QT_FASTCALL comp_func_solid_SourceIn(uint *dest, int length, uint color, ui
|
|||
}
|
||||
}
|
||||
|
||||
void QT_FASTCALL comp_func_solid_SourceIn_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
|
||||
{
|
||||
if (const_alpha == 255) {
|
||||
for (int i = 0; i < length; ++i) {
|
||||
dest[i] = multiplyAlpha65535(color, dest[i].alpha());
|
||||
}
|
||||
} else {
|
||||
uint ca = const_alpha * 257;
|
||||
uint cia = 65535 - ca;
|
||||
color = multiplyAlpha65535(color, ca);
|
||||
for (int i = 0; i < length; ++i) {
|
||||
QRgba64 d = dest[i];
|
||||
dest[i] = interpolate65535(color, d.alpha(), d, cia);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QT_FASTCALL comp_func_SourceIn(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
|
||||
{
|
||||
PRELOAD_INIT2(dest, src)
|
||||
|
|
@ -3048,6 +3065,23 @@ void QT_FASTCALL comp_func_SourceIn(uint *Q_DECL_RESTRICT dest, const uint *Q_DE
|
|||
}
|
||||
}
|
||||
|
||||
void QT_FASTCALL comp_func_SourceIn_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
|
||||
{
|
||||
if (const_alpha == 255) {
|
||||
for (int i = 0; i < length; ++i) {
|
||||
dest[i] = multiplyAlpha65535(src[i], dest[i].alpha());
|
||||
}
|
||||
} else {
|
||||
uint ca = const_alpha * 257;
|
||||
uint cia = 65535 - ca;
|
||||
for (int i = 0; i < length; ++i) {
|
||||
QRgba64 d = dest[i];
|
||||
QRgba64 s = multiplyAlpha65535(src[i], ca);
|
||||
dest[i] = interpolate65535(s, d.alpha(), d, cia);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
result = d * sa
|
||||
dest = d * sa * ca + d * cia
|
||||
|
|
@ -3066,6 +3100,17 @@ void QT_FASTCALL comp_func_solid_DestinationIn(uint *dest, int length, uint colo
|
|||
}
|
||||
}
|
||||
|
||||
void QT_FASTCALL comp_func_solid_DestinationIn_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
|
||||
{
|
||||
uint a = color.alpha();
|
||||
uint ca64k = const_alpha * 257;
|
||||
if (const_alpha != 255)
|
||||
a = qt_div_65535(a * ca64k) + 65535 - ca64k;
|
||||
for (int i = 0; i < length; ++i) {
|
||||
dest[i] = multiplyAlpha65535(dest[i], a);
|
||||
}
|
||||
}
|
||||
|
||||
void QT_FASTCALL comp_func_DestinationIn(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
|
||||
{
|
||||
PRELOAD_INIT2(dest, src)
|
||||
|
|
@ -3084,6 +3129,22 @@ void QT_FASTCALL comp_func_DestinationIn(uint *Q_DECL_RESTRICT dest, const uint
|
|||
}
|
||||
}
|
||||
|
||||
void QT_FASTCALL comp_func_DestinationIn_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
|
||||
{
|
||||
if (const_alpha == 255) {
|
||||
for (int i = 0; i < length; ++i) {
|
||||
dest[i] = multiplyAlpha65535(dest[i], src[i].alpha());
|
||||
}
|
||||
} else {
|
||||
uint ca = const_alpha * 257;
|
||||
uint cia = 65535 - ca;
|
||||
for (int i = 0; i < length; ++i) {
|
||||
uint a = qt_div_65535(src[i].alpha() * ca) + cia;
|
||||
dest[i] = multiplyAlpha65535(dest[i], a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
result = s * dia
|
||||
dest = s * dia * ca + d * cia
|
||||
|
|
@ -3108,6 +3169,23 @@ void QT_FASTCALL comp_func_solid_SourceOut(uint *dest, int length, uint color, u
|
|||
}
|
||||
}
|
||||
|
||||
void QT_FASTCALL comp_func_solid_SourceOut_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
|
||||
{
|
||||
if (const_alpha == 255) {
|
||||
for (int i = 0; i < length; ++i) {
|
||||
dest[i] = multiplyAlpha65535(color, 65535 - dest[i].alpha());
|
||||
}
|
||||
} else {
|
||||
uint ca = const_alpha * 257;
|
||||
uint cia = 65535 - ca;
|
||||
color = multiplyAlpha65535(color, ca);
|
||||
for (int i = 0; i < length; ++i) {
|
||||
QRgba64 d = dest[i];
|
||||
dest[i] = interpolate65535(color, 65535 - d.alpha(), d, cia);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QT_FASTCALL comp_func_SourceOut(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
|
||||
{
|
||||
PRELOAD_INIT2(dest, src)
|
||||
|
|
@ -3127,6 +3205,23 @@ void QT_FASTCALL comp_func_SourceOut(uint *Q_DECL_RESTRICT dest, const uint *Q_D
|
|||
}
|
||||
}
|
||||
|
||||
void QT_FASTCALL comp_func_SourceOut_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
|
||||
{
|
||||
if (const_alpha == 255) {
|
||||
for (int i = 0; i < length; ++i) {
|
||||
dest[i] = multiplyAlpha65535(src[i], 65535 - dest[i].alpha());
|
||||
}
|
||||
} else {
|
||||
uint ca = const_alpha * 257;
|
||||
uint cia = 65535 - ca;
|
||||
for (int i = 0; i < length; ++i) {
|
||||
QRgba64 d = dest[i];
|
||||
QRgba64 s = multiplyAlpha65535(src[i], ca);
|
||||
dest[i] = interpolate65535(s, 65535 - d.alpha(), d, cia);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
result = d * sia
|
||||
dest = d * sia * ca + d * cia
|
||||
|
|
@ -3144,6 +3239,17 @@ void QT_FASTCALL comp_func_solid_DestinationOut(uint *dest, int length, uint col
|
|||
}
|
||||
}
|
||||
|
||||
void QT_FASTCALL comp_func_solid_DestinationOut_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
|
||||
{
|
||||
uint a = 65535 - color.alpha();
|
||||
uint ca64k = const_alpha * 257;
|
||||
if (const_alpha != 255)
|
||||
a = qt_div_65535(a * ca64k) + 65535 - ca64k;
|
||||
for (int i = 0; i < length; ++i) {
|
||||
dest[i] = multiplyAlpha65535(dest[i], a);
|
||||
}
|
||||
}
|
||||
|
||||
void QT_FASTCALL comp_func_DestinationOut(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
|
||||
{
|
||||
PRELOAD_INIT2(dest, src)
|
||||
|
|
@ -3162,6 +3268,22 @@ void QT_FASTCALL comp_func_DestinationOut(uint *Q_DECL_RESTRICT dest, const uint
|
|||
}
|
||||
}
|
||||
|
||||
void QT_FASTCALL comp_func_DestinationOut_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
|
||||
{
|
||||
if (const_alpha == 255) {
|
||||
for (int i = 0; i < length; ++i) {
|
||||
dest[i] = multiplyAlpha65535(dest[i], 65535 - src[i].alpha());
|
||||
}
|
||||
} else {
|
||||
uint ca = const_alpha * 257;
|
||||
uint cia = 65535 - ca;
|
||||
for (int i = 0; i < length; ++i) {
|
||||
uint a = qt_div_65535((65535 - src[i].alpha()) * ca) + cia;
|
||||
dest[i] = multiplyAlpha65535(dest[i], a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
result = s*da + d*sia
|
||||
dest = s*da*ca + d*sia*ca + d *cia
|
||||
|
|
@ -3181,6 +3303,16 @@ void QT_FASTCALL comp_func_solid_SourceAtop(uint *dest, int length, uint color,
|
|||
}
|
||||
}
|
||||
|
||||
void QT_FASTCALL comp_func_solid_SourceAtop_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
|
||||
{
|
||||
if (const_alpha != 255)
|
||||
color = multiplyAlpha255(color, const_alpha);
|
||||
uint sia = 65535 - color.alpha();
|
||||
for (int i = 0; i < length; ++i) {
|
||||
dest[i] = interpolate65535(color, dest[i].alpha(), dest[i], sia);
|
||||
}
|
||||
}
|
||||
|
||||
void QT_FASTCALL comp_func_SourceAtop(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
|
||||
{
|
||||
PRELOAD_INIT2(dest, src)
|
||||
|
|
@ -3201,6 +3333,23 @@ void QT_FASTCALL comp_func_SourceAtop(uint *Q_DECL_RESTRICT dest, const uint *Q_
|
|||
}
|
||||
}
|
||||
|
||||
void QT_FASTCALL comp_func_SourceAtop_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
|
||||
{
|
||||
if (const_alpha == 255) {
|
||||
for (int i = 0; i < length; ++i) {
|
||||
QRgba64 s = src[i];
|
||||
QRgba64 d = dest[i];
|
||||
dest[i] = interpolate65535(s, d.alpha(), d, 65535 - s.alpha());
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < length; ++i) {
|
||||
QRgba64 s = multiplyAlpha255(src[i], const_alpha);
|
||||
QRgba64 d = dest[i];
|
||||
dest[i] = interpolate65535(s, d.alpha(), d, 65535 - s.alpha());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
result = d*sa + s*dia
|
||||
dest = d*sa*ca + s*dia*ca + d *cia
|
||||
|
|
@ -3221,6 +3370,19 @@ void QT_FASTCALL comp_func_solid_DestinationAtop(uint *dest, int length, uint co
|
|||
}
|
||||
}
|
||||
|
||||
void QT_FASTCALL comp_func_solid_DestinationAtop_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
|
||||
{
|
||||
uint a = color.alpha();
|
||||
if (const_alpha != 255) {
|
||||
color = multiplyAlpha255(color, const_alpha);
|
||||
a = color.alpha() + 65535 - (const_alpha * 257);
|
||||
}
|
||||
for (int i = 0; i < length; ++i) {
|
||||
QRgba64 d = dest[i];
|
||||
dest[i] = interpolate65535(d, a, color, 65535 - d.alpha());
|
||||
}
|
||||
}
|
||||
|
||||
void QT_FASTCALL comp_func_DestinationAtop(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
|
||||
{
|
||||
PRELOAD_INIT2(dest, src)
|
||||
|
|
@ -3243,6 +3405,26 @@ void QT_FASTCALL comp_func_DestinationAtop(uint *Q_DECL_RESTRICT dest, const uin
|
|||
}
|
||||
}
|
||||
|
||||
void QT_FASTCALL comp_func_DestinationAtop_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
|
||||
{
|
||||
if (const_alpha == 255) {
|
||||
for (int i = 0; i < length; ++i) {
|
||||
QRgba64 s = src[i];
|
||||
QRgba64 d = dest[i];
|
||||
dest[i] = interpolate65535(d, s.alpha(), s, 65535 - d.alpha());
|
||||
}
|
||||
} else {
|
||||
int ca = const_alpha * 257;
|
||||
int cia = 65535 - ca;
|
||||
for (int i = 0; i < length; ++i) {
|
||||
QRgba64 s = multiplyAlpha65535(src[i], ca);
|
||||
QRgba64 d = dest[i];
|
||||
uint a = s.alpha() + cia;
|
||||
dest[i] = interpolate65535(d, a, s, 65535 - d.alpha());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
result = d*sia + s*dia
|
||||
dest = d*sia*ca + s*dia*ca + d *cia
|
||||
|
|
@ -3263,6 +3445,17 @@ void QT_FASTCALL comp_func_solid_XOR(uint *dest, int length, uint color, uint co
|
|||
}
|
||||
}
|
||||
|
||||
void QT_FASTCALL comp_func_solid_XOR_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
|
||||
{
|
||||
if (const_alpha != 255)
|
||||
color = multiplyAlpha255(color, const_alpha);
|
||||
uint sia = 65535 - color.alpha();
|
||||
for (int i = 0; i < length; ++i) {
|
||||
QRgba64 d = dest[i];
|
||||
dest[i] = interpolate65535(color, 65535 - d.alpha(), d, sia);
|
||||
}
|
||||
}
|
||||
|
||||
void QT_FASTCALL comp_func_XOR(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
|
||||
{
|
||||
PRELOAD_INIT2(dest, src)
|
||||
|
|
@ -3283,6 +3476,23 @@ void QT_FASTCALL comp_func_XOR(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RE
|
|||
}
|
||||
}
|
||||
|
||||
void QT_FASTCALL comp_func_XOR_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
|
||||
{
|
||||
if (const_alpha == 255) {
|
||||
for (int i = 0; i < length; ++i) {
|
||||
QRgba64 d = dest[i];
|
||||
QRgba64 s = src[i];
|
||||
dest[i] = interpolate65535(s, 65535 - d.alpha(), d, 65535 - s.alpha());
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < length; ++i) {
|
||||
QRgba64 d = dest[i];
|
||||
QRgba64 s = multiplyAlpha255(src[i], const_alpha);
|
||||
dest[i] = interpolate65535(s, 65535 - d.alpha(), d, 65535 - s.alpha());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct QFullCoverage {
|
||||
inline void store(uint *dest, const uint src) const
|
||||
{
|
||||
|
|
@ -3330,6 +3540,17 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Plus_impl(uint *dest, int
|
|||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Plus_impl_rgb64(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
|
||||
{
|
||||
QRgba64 s = color;
|
||||
for (int i = 0; i < length; ++i) {
|
||||
QRgba64 d = dest[i];
|
||||
d = comp_func_Plus_one_pixel(d, s);
|
||||
coverage.store(&dest[i], d);
|
||||
}
|
||||
}
|
||||
|
||||
void QT_FASTCALL comp_func_solid_Plus(uint *dest, int length, uint color, uint const_alpha)
|
||||
{
|
||||
if (const_alpha == 255)
|
||||
|
|
@ -3338,6 +3559,20 @@ void QT_FASTCALL comp_func_solid_Plus(uint *dest, int length, uint color, uint c
|
|||
comp_func_solid_Plus_impl(dest, length, color, QPartialCoverage(const_alpha));
|
||||
}
|
||||
|
||||
void QT_FASTCALL comp_func_solid_Plus_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
|
||||
{
|
||||
if (const_alpha == 255) {
|
||||
for (int i = 0; i < length; ++i) {
|
||||
dest[i] = addWithSaturation(dest[i], color);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < length; ++i) {
|
||||
QRgba64 d = addWithSaturation(dest[i], color);
|
||||
dest[i] = interpolate255(d, const_alpha, dest[i], 255 - const_alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Plus_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
|
||||
{
|
||||
|
|
@ -3361,6 +3596,20 @@ void QT_FASTCALL comp_func_Plus(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_R
|
|||
comp_func_Plus_impl(dest, src, length, QPartialCoverage(const_alpha));
|
||||
}
|
||||
|
||||
void QT_FASTCALL comp_func_Plus_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
|
||||
{
|
||||
if (const_alpha == 255) {
|
||||
for (int i = 0; i < length; ++i) {
|
||||
dest[i] = addWithSaturation(dest[i], src[i]);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < length; ++i) {
|
||||
QRgba64 d = addWithSaturation(dest[i], src[i]);
|
||||
dest[i] = interpolate255(d, const_alpha, dest[i], 255 - const_alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Dca' = Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa)
|
||||
*/
|
||||
|
|
@ -4552,8 +4801,15 @@ static CompositionFunctionSolid64 functionForModeSolid64_C[] = {
|
|||
comp_func_solid_Clear_rgb64,
|
||||
comp_func_solid_Source_rgb64,
|
||||
comp_func_solid_Destination_rgb64,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
comp_func_solid_SourceIn_rgb64,
|
||||
comp_func_solid_DestinationIn_rgb64,
|
||||
comp_func_solid_SourceOut_rgb64,
|
||||
comp_func_solid_DestinationOut_rgb64,
|
||||
comp_func_solid_SourceAtop_rgb64,
|
||||
comp_func_solid_DestinationAtop_rgb64,
|
||||
comp_func_solid_XOR_rgb64,
|
||||
comp_func_solid_Plus_rgb64,
|
||||
0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
|
|
@ -4609,8 +4865,15 @@ static CompositionFunction64 functionForMode64_C[] = {
|
|||
comp_func_Clear_rgb64,
|
||||
comp_func_Source_rgb64,
|
||||
comp_func_Destination_rgb64,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
comp_func_SourceIn_rgb64,
|
||||
comp_func_DestinationIn_rgb64,
|
||||
comp_func_SourceOut_rgb64,
|
||||
comp_func_DestinationOut_rgb64,
|
||||
comp_func_SourceAtop_rgb64,
|
||||
comp_func_DestinationAtop_rgb64,
|
||||
comp_func_XOR_rgb64,
|
||||
comp_func_Plus_rgb64,
|
||||
0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
|
|
|
|||
|
|
@ -78,6 +78,26 @@ inline QRgba64 interpolate255(QRgba64 x, uint alpha1, QRgba64 y, uint alpha2)
|
|||
return QRgba64::fromRgba64(multiplyAlpha255(x, alpha1) + multiplyAlpha255(y, alpha2));
|
||||
}
|
||||
|
||||
inline QRgba64 interpolate65535(QRgba64 x, uint alpha1, QRgba64 y, uint alpha2)
|
||||
{
|
||||
return QRgba64::fromRgba64(multiplyAlpha65535(x, alpha1) + multiplyAlpha65535(y, alpha2));
|
||||
}
|
||||
|
||||
inline QRgba64 addWithSaturation(QRgba64 a, QRgba64 b)
|
||||
{
|
||||
#if defined(__SSE2__) && defined(Q_PROCESSOR_X86_64)
|
||||
__m128i va = _mm_cvtsi64_si128((quint64)a);
|
||||
__m128i vb = _mm_cvtsi64_si128((quint64)b);
|
||||
va = _mm_adds_epu16(va, vb);
|
||||
return QRgba64::fromRgba64(_mm_cvtsi128_si64(va));
|
||||
#else
|
||||
return QRgba64::fromRgba64(qMin(a.red() + b.red(), 65535),
|
||||
qMin(a.green() + b.green(), 65535),
|
||||
qMin(a.blue() + b.blue(), 65535),
|
||||
qMin(a.alpha() + b.alpha(), 65535));
|
||||
#endif
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QRGBA64_P_H
|
||||
|
|
|
|||
Loading…
Reference in New Issue