Improve QtGui start-up time and memory use.
The gamma lookup tables can be allocated and computed on demand, as they're not always needed, depending on the platform and the use case. Change-Id: I2d4c2860746366a0e46edb53bd4ecd2778de2464 Reviewed-by: Olivier Goffart <ogoffart@kde.org>bb10
parent
780a03191f
commit
171e137d25
|
|
@ -3340,9 +3340,13 @@ void qInitImageConversions()
|
|||
#endif
|
||||
}
|
||||
|
||||
extern const uchar *qt_pow_rgb_gamma();
|
||||
|
||||
void qGamma_correct_back_to_linear_cs(QImage *image)
|
||||
{
|
||||
extern uchar qt_pow_rgb_gamma[256];
|
||||
const uchar *gamma = qt_pow_rgb_gamma();
|
||||
if (!gamma)
|
||||
return;
|
||||
|
||||
// gamma correct the pixels back to linear color space...
|
||||
int h = image->height();
|
||||
|
|
@ -3352,9 +3356,9 @@ void qGamma_correct_back_to_linear_cs(QImage *image)
|
|||
uint *pixels = (uint *) image->scanLine(y);
|
||||
for (int x=0; x<w; ++x) {
|
||||
uint p = pixels[x];
|
||||
uint r = qt_pow_rgb_gamma[qRed(p)];
|
||||
uint g = qt_pow_rgb_gamma[qGreen(p)];
|
||||
uint b = qt_pow_rgb_gamma[qBlue(p)];
|
||||
uint r = gamma[qRed(p)];
|
||||
uint g = gamma[qGreen(p)];
|
||||
uint b = gamma[qBlue(p)];
|
||||
pixels[x] = (r << 16) | (g << 8) | b | 0xff000000;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6519,11 +6519,52 @@ inline static void qt_bitmapblit_quint16(QRasterBuffer *rasterBuffer,
|
|||
}
|
||||
|
||||
|
||||
uchar qt_pow_rgb_gamma[256];
|
||||
uchar qt_pow_rgb_invgamma[256];
|
||||
struct QDrawHelperGammaTables
|
||||
{
|
||||
QDrawHelperGammaTables();
|
||||
|
||||
uint qt_pow_gamma[256];
|
||||
uchar qt_pow_invgamma[2048];
|
||||
uchar qt_pow_rgb_gamma[256];
|
||||
uchar qt_pow_rgb_invgamma[256];
|
||||
|
||||
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
|
||||
uint qt_pow_gamma[256];
|
||||
uchar qt_pow_invgamma[2048];
|
||||
#endif
|
||||
};
|
||||
|
||||
QDrawHelperGammaTables::QDrawHelperGammaTables()
|
||||
{
|
||||
qreal smoothing = qreal(1.7);
|
||||
|
||||
for (int i=0; i<256; ++i) {
|
||||
qt_pow_rgb_gamma[i] = uchar(qRound(qPow(i / qreal(255.0), smoothing) * 255));
|
||||
qt_pow_rgb_invgamma[i] = uchar(qRound(qPow(i / qreal(255.), 1 / smoothing) * 255));
|
||||
}
|
||||
|
||||
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
|
||||
const qreal gray_gamma = 2.31;
|
||||
for (int i=0; i<256; ++i)
|
||||
qt_pow_gamma[i] = uint(qRound(qPow(i / qreal(255.), gray_gamma) * 2047));
|
||||
for (int i=0; i<2048; ++i)
|
||||
qt_pow_invgamma[i] = uchar(qRound(qPow(i / qreal(2047.0), 1 / gray_gamma) * 255));
|
||||
#endif
|
||||
}
|
||||
|
||||
Q_GLOBAL_STATIC(QDrawHelperGammaTables, qt_gamma_tables);
|
||||
|
||||
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
|
||||
const uint *qt_pow_gamma()
|
||||
{
|
||||
QDrawHelperGammaTables *tables = qt_gamma_tables();
|
||||
return tables ? tables->qt_pow_gamma : 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
const uchar *qt_pow_rgb_gamma()
|
||||
{
|
||||
QDrawHelperGammaTables *tables = qt_gamma_tables();
|
||||
return tables ? tables->qt_pow_rgb_gamma : 0;
|
||||
}
|
||||
|
||||
static void qt_alphamapblit_quint16(QRasterBuffer *rasterBuffer,
|
||||
int x, int y, quint32 color,
|
||||
|
|
@ -6554,26 +6595,7 @@ static void qt_alphamapblit_quint16(QRasterBuffer *rasterBuffer,
|
|||
}
|
||||
}
|
||||
|
||||
void qt_build_pow_tables() {
|
||||
qreal smoothing = qreal(1.7);
|
||||
|
||||
|
||||
|
||||
for (int i=0; i<256; ++i) {
|
||||
qt_pow_rgb_gamma[i] = uchar(qRound(qPow(i / qreal(255.0), smoothing) * 255));
|
||||
qt_pow_rgb_invgamma[i] = uchar(qRound(qPow(i / qreal(255.), 1 / smoothing) * 255));
|
||||
}
|
||||
|
||||
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
|
||||
const qreal gray_gamma = 2.31;
|
||||
for (int i=0; i<256; ++i)
|
||||
qt_pow_gamma[i] = uint(qRound(qPow(i / qreal(255.), gray_gamma) * 2047));
|
||||
for (int i=0; i<2048; ++i)
|
||||
qt_pow_invgamma[i] = uchar(qRound(qPow(i / qreal(2047.0), 1 / gray_gamma) * 255));
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void rgbBlendPixel(quint32 *dst, int coverage, int sr, int sg, int sb)
|
||||
static inline void rgbBlendPixel(quint32 *dst, int coverage, int sr, int sg, int sb, const uchar *gamma, const uchar *invgamma)
|
||||
{
|
||||
// Do a gray alphablend...
|
||||
int da = qAlpha(*dst);
|
||||
|
|
@ -6585,9 +6607,9 @@ static inline void rgbBlendPixel(quint32 *dst, int coverage, int sr, int sg, int
|
|||
) {
|
||||
|
||||
int a = qGray(coverage);
|
||||
sr = qt_div_255(qt_pow_rgb_invgamma[sr] * a);
|
||||
sg = qt_div_255(qt_pow_rgb_invgamma[sg] * a);
|
||||
sb = qt_div_255(qt_pow_rgb_invgamma[sb] * a);
|
||||
sr = qt_div_255(invgamma[sr] * a);
|
||||
sg = qt_div_255(invgamma[sg] * a);
|
||||
sb = qt_div_255(invgamma[sb] * a);
|
||||
|
||||
int ia = 255 - a;
|
||||
dr = qt_div_255(dr * ia);
|
||||
|
|
@ -6605,32 +6627,32 @@ static inline void rgbBlendPixel(quint32 *dst, int coverage, int sr, int sg, int
|
|||
int mg = qGreen(coverage);
|
||||
int mb = qBlue(coverage);
|
||||
|
||||
dr = qt_pow_rgb_gamma[dr];
|
||||
dg = qt_pow_rgb_gamma[dg];
|
||||
db = qt_pow_rgb_gamma[db];
|
||||
dr = gamma[dr];
|
||||
dg = gamma[dg];
|
||||
db = gamma[db];
|
||||
|
||||
int nr = qt_div_255((sr - dr) * mr) + dr;
|
||||
int ng = qt_div_255((sg - dg) * mg) + dg;
|
||||
int nb = qt_div_255((sb - db) * mb) + db;
|
||||
|
||||
nr = qt_pow_rgb_invgamma[nr];
|
||||
ng = qt_pow_rgb_invgamma[ng];
|
||||
nb = qt_pow_rgb_invgamma[nb];
|
||||
nr = invgamma[nr];
|
||||
ng = invgamma[ng];
|
||||
nb = invgamma[nb];
|
||||
|
||||
*dst = qRgb(nr, ng, nb);
|
||||
}
|
||||
|
||||
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
|
||||
static inline void grayBlendPixel(quint32 *dst, int coverage, int sr, int sg, int sb)
|
||||
static inline void grayBlendPixel(quint32 *dst, int coverage, int sr, int sg, int sb, const uint *gamma, const uchar *invgamma)
|
||||
{
|
||||
// Do a gammacorrected gray alphablend...
|
||||
int dr = qRed(*dst);
|
||||
int dg = qGreen(*dst);
|
||||
int db = qBlue(*dst);
|
||||
|
||||
dr = qt_pow_gamma[dr];
|
||||
dg = qt_pow_gamma[dg];
|
||||
db = qt_pow_gamma[db];
|
||||
dr = gamma[dr];
|
||||
dg = gamma[dg];
|
||||
db = gamma[db];
|
||||
|
||||
int alpha = coverage;
|
||||
int ialpha = 255 - alpha;
|
||||
|
|
@ -6638,9 +6660,9 @@ static inline void grayBlendPixel(quint32 *dst, int coverage, int sr, int sg, in
|
|||
int ng = (sg * alpha + ialpha * dg) / 255;
|
||||
int nb = (sb * alpha + ialpha * db) / 255;
|
||||
|
||||
nr = qt_pow_invgamma[nr];
|
||||
ng = qt_pow_invgamma[ng];
|
||||
nb = qt_pow_invgamma[nb];
|
||||
nr = invgamma[nr];
|
||||
ng = invgamma[ng];
|
||||
nb = invgamma[nb];
|
||||
|
||||
*dst = qRgb(nr, ng, nb);
|
||||
}
|
||||
|
|
@ -6656,13 +6678,17 @@ static void qt_alphamapblit_quint32(QRasterBuffer *rasterBuffer,
|
|||
const int destStride = rasterBuffer->bytesPerLine() / sizeof(quint32);
|
||||
|
||||
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
|
||||
int sr = qRed(color);
|
||||
int sg = qGreen(color);
|
||||
int sb = qBlue(color);
|
||||
QDrawHelperGammaTables *tables = qt_gamma_tables();
|
||||
if (!tables)
|
||||
return;
|
||||
|
||||
const uint *gamma = tables->qt_pow_gamma;
|
||||
const uchar *invgamma = tables->qt_pow_invgamma;
|
||||
|
||||
int sr = gamma[qRed(color)];
|
||||
int sg = gamma[qGreen(color)];
|
||||
int sb = gamma[qBlue(color)];
|
||||
|
||||
sr = qt_pow_gamma[sr];
|
||||
sg = qt_pow_gamma[sg];
|
||||
sb = qt_pow_gamma[sb];
|
||||
bool opaque_src = (qAlpha(color) == 255);
|
||||
#endif
|
||||
|
||||
|
|
@ -6680,7 +6706,7 @@ static void qt_alphamapblit_quint32(QRasterBuffer *rasterBuffer,
|
|||
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
|
||||
if (QSysInfo::WindowsVersion >= QSysInfo::WV_XP && opaque_src
|
||||
&& qAlpha(dest[i]) == 255) {
|
||||
grayBlendPixel(dest+i, coverage, sr, sg, sb);
|
||||
grayBlendPixel(dest+i, coverage, sr, sg, sb, gamma, invgamma);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
|
|
@ -6721,7 +6747,7 @@ static void qt_alphamapblit_quint32(QRasterBuffer *rasterBuffer,
|
|||
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
|
||||
if (QSysInfo::WindowsVersion >= QSysInfo::WV_XP && opaque_src
|
||||
&& qAlpha(dest[xp]) == 255) {
|
||||
grayBlendPixel(dest+xp, coverage, sr, sg, sb);
|
||||
grayBlendPixel(dest+xp, coverage, sr, sg, sb, gamma, invgamma);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
|
|
@ -6749,9 +6775,16 @@ static void qt_alphargbblit_quint32(QRasterBuffer *rasterBuffer,
|
|||
int sb = qBlue(color);
|
||||
int sa = qAlpha(color);
|
||||
|
||||
sr = qt_pow_rgb_gamma[sr];
|
||||
sg = qt_pow_rgb_gamma[sg];
|
||||
sb = qt_pow_rgb_gamma[sb];
|
||||
QDrawHelperGammaTables *tables = qt_gamma_tables();
|
||||
if (!tables)
|
||||
return;
|
||||
|
||||
const uchar *gamma = tables->qt_pow_rgb_gamma;
|
||||
const uchar *invgamma = tables->qt_pow_rgb_invgamma;
|
||||
|
||||
sr = gamma[sr];
|
||||
sg = gamma[sg];
|
||||
sb = gamma[sb];
|
||||
|
||||
if (sa == 0)
|
||||
return;
|
||||
|
|
@ -6765,7 +6798,7 @@ static void qt_alphargbblit_quint32(QRasterBuffer *rasterBuffer,
|
|||
if (coverage == 0xffffffff) {
|
||||
dst[i] = c;
|
||||
} else if (coverage != 0xff000000) {
|
||||
rgbBlendPixel(dst+i, coverage, sr, sg, sb);
|
||||
rgbBlendPixel(dst+i, coverage, sr, sg, sb, gamma, invgamma);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6795,7 +6828,7 @@ static void qt_alphargbblit_quint32(QRasterBuffer *rasterBuffer,
|
|||
if (coverage == 0xffffffff) {
|
||||
dst[xp] = c;
|
||||
} else if (coverage != 0xff000000) {
|
||||
rgbBlendPixel(dst+xp, coverage, sr, sg, sb);
|
||||
rgbBlendPixel(dst+xp, coverage, sr, sg, sb, gamma, invgamma);
|
||||
}
|
||||
}
|
||||
} // for (i -> line.count)
|
||||
|
|
@ -7257,8 +7290,6 @@ void qInitDrawhelperAsm()
|
|||
}
|
||||
if (functionForModeAsm)
|
||||
functionForMode = functionForModeAsm;
|
||||
|
||||
qt_build_pow_tables();
|
||||
}
|
||||
|
||||
static void qt_memfill32_setup(quint32 *dest, quint32 value, int count)
|
||||
|
|
|
|||
|
|
@ -508,7 +508,7 @@ qreal QFontEngineDirectWrite::maxCharWidth() const
|
|||
return 0;
|
||||
}
|
||||
|
||||
extern uint qt_pow_gamma[256];
|
||||
extern const uint *qt_pow_gamma();
|
||||
|
||||
QImage QFontEngineDirectWrite::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition,
|
||||
const QTransform &xform)
|
||||
|
|
@ -521,11 +521,13 @@ QImage QFontEngineDirectWrite::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPo
|
|||
colors[i] = qRgba(0, 0, 0, i);
|
||||
indexed.setColorTable(colors);
|
||||
|
||||
uint *gamma = qt_pow_gamma();
|
||||
for (int y=0; y<im.height(); ++y) {
|
||||
uint *src = (uint*) im.scanLine(y);
|
||||
uchar *dst = indexed.scanLine(y);
|
||||
for (int x=0; x<im.width(); ++x) {
|
||||
*dst = 255 - (qt_pow_gamma[qGray(0xffffffff - *src)] * 255. / 2047.);
|
||||
uint gray = qGray(0xffffffff - *src);
|
||||
*dst = 255 - (gamma ? gamma[gray] * 255. / 2047. : gray);
|
||||
++dst;
|
||||
++src;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue