summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Rødal <samuel.rodal@nokia.com>2011-11-02 17:02:11 +0100
committerQt by Nokia <qt-info@nokia.com>2011-11-04 14:31:25 +0100
commit171e137d25dccca15b31e6bd01de58776f3d9e94 (patch)
treef94b10cbaa65b18c32b199b315e0b27763bec534
parent780a03191feb2b5f64de97ad623ad9e0c4f5871a (diff)
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>
-rw-r--r--src/gui/image/qimage.cpp12
-rw-r--r--src/gui/painting/qdrawhelper.cpp141
-rw-r--r--src/gui/text/qfontenginedirectwrite.cpp6
3 files changed, 98 insertions, 61 deletions
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index a19b608216..c107fea919 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -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;
}
}
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 88c237b59b..cf899b986d 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -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();
+
+ 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
+}
-uint qt_pow_gamma[256];
-uchar qt_pow_invgamma[2048];
+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)
diff --git a/src/gui/text/qfontenginedirectwrite.cpp b/src/gui/text/qfontenginedirectwrite.cpp
index 5bac1172fa..952e06d151 100644
--- a/src/gui/text/qfontenginedirectwrite.cpp
+++ b/src/gui/text/qfontenginedirectwrite.cpp
@@ -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;
}