From 4d5b57825a2ec5eb15ab8a40bb173306e2279914 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Mon, 9 Nov 2015 01:47:07 +0400 Subject: QFontEngineFT: Optimize format convertion code with template magic Avoids in-loop check for every pixel by costs of slightly bigger code. Change-Id: I8321d0945ac6b677786431670b2316c60e4db492 Reviewed-by: Friedemann Kleint Reviewed-by: Lars Knoll --- src/gui/text/qfontengine_ft.cpp | 54 +++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 16 deletions(-) (limited to 'src/gui/text/qfontengine_ft.cpp') diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 242dd84096..8dfabd48ad 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -534,55 +534,77 @@ QFontEngineFT::Glyph::~Glyph() delete [] data; } -static inline uint filterPixel(uchar red, uchar green, uchar blue, bool legacyFilter) +struct LcdFilterDummy { - if (legacyFilter) { + static inline void filterPixel(uchar &, uchar &, uchar &) + {} +}; + +struct LcdFilterLegacy +{ + static inline void filterPixel(uchar &red, uchar &green, uchar &blue) + { uint r = red, g = green, b = blue; // intra-pixel filter used by the legacy filter (adopted from _ft_lcd_filter_legacy) red = (r * uint(65538 * 9/13) + g * uint(65538 * 1/6) + b * uint(65538 * 1/13)) / 65536; green = (r * uint(65538 * 3/13) + g * uint(65538 * 4/6) + b * uint(65538 * 3/13)) / 65536; blue = (r * uint(65538 * 1/13) + g * uint(65538 * 1/6) + b * uint(65538 * 9/13)) / 65536; } +}; - // alpha = green - return (green << 24) + (red << 16) + (green << 8) + blue; -} - -static void convertRGBToARGB(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr, bool legacyFilter) +template +static void convertRGBToARGB_helper(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr) { - int h = height; const int offs = bgr ? -1 : 1; const int w = width * 3; - while (h--) { + while (height--) { uint *dd = dst; for (int x = 0; x < w; x += 3) { uchar red = src[x + 1 - offs]; uchar green = src[x + 1]; uchar blue = src[x + 1 + offs]; - *dd = filterPixel(red, green, blue, legacyFilter); - ++dd; + LcdFilter::filterPixel(red, green, blue); + // alpha = green + *dd++ = (green << 24) | (red << 16) | (green << 8) | blue; } dst += width; src += src_pitch; } } -static void convertRGBToARGB_V(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr, bool legacyFilter) +static inline void convertRGBToARGB(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr, bool legacyFilter) +{ + if (!legacyFilter) + convertRGBToARGB_helper(src, dst, width, height, src_pitch, bgr); + else + convertRGBToARGB_helper(src, dst, width, height, src_pitch, bgr); +} + +template +static void convertRGBToARGB_V_helper(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr) { - int h = height; const int offs = bgr ? -src_pitch : src_pitch; - while (h--) { + while (height--) { for (int x = 0; x < width; x++) { uchar red = src[x + src_pitch - offs]; uchar green = src[x + src_pitch]; uchar blue = src[x + src_pitch + offs]; - dst[x] = filterPixel(red, green, blue, legacyFilter); + LcdFilter::filterPixel(red, green, blue); + // alpha = green + *dst++ = (green << 24) | (red << 16) | (green << 8) | blue; } - dst += width; src += 3*src_pitch; } } +static inline void convertRGBToARGB_V(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr, bool legacyFilter) +{ + if (!legacyFilter) + convertRGBToARGB_V_helper(src, dst, width, height, src_pitch, bgr); + else + convertRGBToARGB_V_helper(src, dst, width, height, src_pitch, bgr); +} + static inline void convertGRAYToARGB(const uchar *src, uint *dst, int width, int height, int src_pitch) { while (height--) { -- cgit v1.2.3