Add support for more composition modes in rgb64 rendering

Change-Id: I3bacecbabdf2d7b2de1acd86ab9383e69924a390
Reviewed-by: Gunnar Sletta <gunnar@sletta.org>
bb10
Allan Sandfeld Jensen 2015-04-10 15:34:23 +02:00
parent 29380121ef
commit 5c7d2d1d67
2 changed files with 287 additions and 4 deletions

View File

@ -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

View File

@ -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