From 8dc55367ca3993f465f270ef79c2cb212d821d0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= Date: Mon, 8 Feb 2016 15:02:17 +0100 Subject: QtGui: Avoid rgba64->rgba32 conversion on every pixel in gradient Convert rgba64 color table to a new rgb32 color table only once. Use this cache when required. This patch can 2x speed up gradient painting using 32bit color format. Task-number: QTBUG-50930 Change-Id: I9212e01e397c2e0127cdf3070cc49880a2d8df88 Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/qpaintengine_raster.cpp | 38 ++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 9 deletions(-) (limited to 'src/gui/painting/qpaintengine_raster.cpp') diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 05ccff5de0..fb44a7aeb1 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -4138,7 +4138,8 @@ class QGradientCache { inline CacheInfo(QGradientStops s, int op, QGradient::InterpolationMode mode) : stops(qMove(s)), opacity(op), interpolationMode(mode) {} - QRgba64 buffer[GRADIENT_STOPTABLE_SIZE]; + QRgba64 buffer64[GRADIENT_STOPTABLE_SIZE]; + QRgb buffer32[GRADIENT_STOPTABLE_SIZE]; QGradientStops stops; int opacity; QGradient::InterpolationMode interpolationMode; @@ -4147,7 +4148,9 @@ class QGradientCache typedef QMultiHash QGradientColorTableHash; public: - inline const QRgba64 *getBuffer(const QGradient &gradient, int opacity) { + typedef QPair ColorBufferPair; + + inline ColorBufferPair getBuffer(const QGradient &gradient, int opacity) { quint64 hash_val = 0; const QGradientStops stops = gradient.stops(); @@ -4163,7 +4166,8 @@ public: do { const CacheInfo &cache_info = it.value(); if (cache_info.stops == stops && cache_info.opacity == opacity && cache_info.interpolationMode == gradient.interpolationMode()) - return cache_info.buffer; + return qMakePair(reinterpret_cast(cache_info.buffer32), + reinterpret_cast(cache_info.buffer64)); ++it; } while (it != cache.constEnd() && it.key() == hash_val); // an exact match for these stops and opacity was not found, create new cache @@ -4177,14 +4181,18 @@ protected: inline void generateGradientColorTable(const QGradient& g, QRgba64 *colorTable, int size, int opacity) const; - QRgba64 *addCacheElement(quint64 hash_val, const QGradient &gradient, int opacity) { + ColorBufferPair addCacheElement(quint64 hash_val, const QGradient &gradient, int opacity) { if (cache.size() == maxCacheSize()) { // may remove more than 1, but OK cache.erase(cache.begin() + (qrand() % maxCacheSize())); } CacheInfo cache_entry(gradient.stops(), opacity, gradient.interpolationMode()); - generateGradientColorTable(gradient, cache_entry.buffer, paletteSize(), opacity); - return cache.insert(hash_val, cache_entry).value().buffer; + generateGradientColorTable(gradient, cache_entry.buffer64, paletteSize(), opacity); + for (int i = 0; i < GRADIENT_STOPTABLE_SIZE; ++i) + cache_entry.buffer32[i] = cache_entry.buffer64[i].toArgb32(); + CacheInfo &cache_value = cache.insert(hash_val, cache_entry).value(); + return qMakePair(reinterpret_cast(cache_value.buffer32), + reinterpret_cast(cache_value.buffer64)); } QGradientColorTableHash cache; @@ -4418,7 +4426,11 @@ void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode type = LinearGradient; const QLinearGradient *g = static_cast(brush.gradient()); gradient.alphaColor = !brush.isOpaque() || alpha != 256; - gradient.colorTable = const_cast(qt_gradient_cache()->getBuffer(*g, alpha)); + + QGradientCache::ColorBufferPair colorBuffers = qt_gradient_cache()->getBuffer(*g, alpha); + gradient.colorTable64 = colorBuffers.second; + gradient.colorTable32 = colorBuffers.first; + gradient.spread = g->spread(); QLinearGradientData &linearData = gradient.linear; @@ -4435,7 +4447,11 @@ void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode type = RadialGradient; const QRadialGradient *g = static_cast(brush.gradient()); gradient.alphaColor = !brush.isOpaque() || alpha != 256; - gradient.colorTable = const_cast(qt_gradient_cache()->getBuffer(*g, alpha)); + + QGradientCache::ColorBufferPair colorBuffers = qt_gradient_cache()->getBuffer(*g, alpha); + gradient.colorTable64 = colorBuffers.second; + gradient.colorTable32 = colorBuffers.first; + gradient.spread = g->spread(); QRadialGradientData &radialData = gradient.radial; @@ -4456,7 +4472,11 @@ void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode type = ConicalGradient; const QConicalGradient *g = static_cast(brush.gradient()); gradient.alphaColor = !brush.isOpaque() || alpha != 256; - gradient.colorTable = const_cast(qt_gradient_cache()->getBuffer(*g, alpha)); + + QGradientCache::ColorBufferPair colorBuffers = qt_gradient_cache()->getBuffer(*g, alpha); + gradient.colorTable64 = colorBuffers.second; + gradient.colorTable32 = colorBuffers.first; + gradient.spread = QGradient::RepeatSpread; QConicalGradientData &conicalData = gradient.conical; -- cgit v1.2.3