gl2paintengineex/qglgradientcache.cpp

Switch to Source codePreprocessed file
LineSource CodeCoverage
1 -
2 -
3 -
4class QGL2GradientCacheWrapper -
5{ -
6public: -
7 QGL2GradientCache *cacheForContext(const QGLContext *context) { -
8 QMutexLocker lock(&m_mutex); -
9 return m_resource.value<QGL2GradientCache>(context->contextHandle());
never executed: return m_resource.value<QGL2GradientCache>(context->contextHandle());
0
10 } -
11 -
12private: -
13 QOpenGLMultiGroupSharedResource m_resource; -
14 QMutex m_mutex; -
15}; -
16 -
17static QGL2GradientCacheWrapper *qt_gradient_caches() { static QGlobalStatic<QGL2GradientCacheWrapper > thisGlobalStatic = { { (0) }, false }; if (!thisGlobalStatic.pointer.load() && !thisGlobalStatic.destroyed) { QGL2GradientCacheWrapper *x = new QGL2GradientCacheWrapper; if (!thisGlobalStatic.pointer.testAndSetOrdered(0, x)) delete x; else static QGlobalStaticDeleter<QGL2GradientCacheWrapper > cleanup(thisGlobalStatic); } return thisGlobalStatic.pointer.load(); }
never executed: delete x;
never executed: return thisGlobalStatic.pointer.load();
never evaluated: !thisGlobalStatic.pointer.testAndSetOrdered(0, x)
never evaluated: !thisGlobalStatic.pointer.load()
never evaluated: !thisGlobalStatic.destroyed
0
18 -
19QGL2GradientCache::QGL2GradientCache(QOpenGLContext *ctx) -
20 : QOpenGLSharedResource(ctx->shareGroup()) -
21{ -
22}
never executed: }
0
23 -
24QGL2GradientCache::~QGL2GradientCache() -
25{ -
26 cache.clear(); -
27}
never executed: }
0
28 -
29QGL2GradientCache *QGL2GradientCache::cacheForContext(const QGLContext *context) -
30{ -
31 return qt_gradient_caches()->cacheForContext(context);
never executed: return qt_gradient_caches()->cacheForContext(context);
0
32} -
33 -
34void QGL2GradientCache::invalidateResource() -
35{ -
36 QMutexLocker lock(&m_mutex); -
37 cache.clear(); -
38}
never executed: }
0
39 -
40void QGL2GradientCache::freeResource(QOpenGLContext *) -
41{ -
42 cleanCache(); -
43}
never executed: }
0
44 -
45void QGL2GradientCache::cleanCache() -
46{ -
47 QMutexLocker lock(&m_mutex); -
48 QGLGradientColorTableHash::const_iterator it = cache.constBegin(); -
49 for (; it != cache.constEnd(); ++it) {
never evaluated: it != cache.constEnd()
0
50 const CacheInfo &cache_info = it.value(); -
51 glDeleteTextures(1, &cache_info.texId); -
52 }
never executed: }
0
53 cache.clear(); -
54}
never executed: }
0
55 -
56GLuint QGL2GradientCache::getBuffer(const QGradient &gradient, qreal opacity) -
57{ -
58 QMutexLocker lock(&m_mutex); -
59 quint64 hash_val = 0; -
60 -
61 QGradientStops stops = gradient.stops(); -
62 for (int i = 0; i < stops.size() && i <= 2; i++)
never evaluated: i < stops.size()
never evaluated: i <= 2
0
63 hash_val += stops[i].second.rgba();
never executed: hash_val += stops[i].second.rgba();
0
64 -
65 QGLGradientColorTableHash::const_iterator it = cache.constFind(hash_val); -
66 -
67 if (it == cache.constEnd())
never evaluated: it == cache.constEnd()
0
68 return addCacheElement(hash_val, gradient, opacity);
never executed: return addCacheElement(hash_val, gradient, opacity);
0
69 else { -
70 do { -
71 const CacheInfo &cache_info = it.value(); -
72 if (cache_info.stops == stops && cache_info.opacity == opacity
never evaluated: cache_info.stops == stops
never evaluated: cache_info.opacity == opacity
0
73 && cache_info.interpolationMode == gradient.interpolationMode())
never evaluated: cache_info.interpolationMode == gradient.interpolationMode()
0
74 { -
75 return cache_info.texId;
never executed: return cache_info.texId;
0
76 } -
77 ++it; -
78 } while (it != cache.constEnd() && it.key() == hash_val);
never executed: }
never evaluated: it != cache.constEnd()
never evaluated: it.key() == hash_val
0
79 -
80 return addCacheElement(hash_val, gradient, opacity);
never executed: return addCacheElement(hash_val, gradient, opacity);
0
81 } -
82} -
83 -
84 -
85GLuint QGL2GradientCache::addCacheElement(quint64 hash_val, const QGradient &gradient, qreal opacity) -
86{ -
87 if (cache.size() == maxCacheSize()) {
never evaluated: cache.size() == maxCacheSize()
0
88 int elem_to_remove = qrand() % maxCacheSize(); -
89 quint64 key = cache.keys()[elem_to_remove]; -
90 -
91 -
92 QGLGradientColorTableHash::const_iterator it = cache.constFind(key); -
93 do { -
94 glDeleteTextures(1, &it.value().texId); -
95 } while (++it != cache.constEnd() && it.key() == key);
never executed: }
never evaluated: ++it != cache.constEnd()
never evaluated: it.key() == key
0
96 cache.remove(key); -
97 }
never executed: }
0
98 -
99 CacheInfo cache_entry(gradient.stops(), opacity, gradient.interpolationMode()); -
100 uint buffer[1024]; -
101 generateGradientColorTable(gradient, buffer, paletteSize(), opacity); -
102 glGenTextures(1, &cache_entry.texId); -
103 glBindTexture(0x0DE1, cache_entry.texId); -
104 glTexImage2D(0x0DE1, 0, 0x1908, paletteSize(), 1, -
105 0, 0x1908, 0x1401, buffer); -
106 return cache.insert(hash_val, cache_entry).value().texId;
never executed: return cache.insert(hash_val, cache_entry).value().texId;
0
107} -
108 -
109 -
110 -
111 -
112static inline uint qtToGlColor(uint c) -
113{ -
114 uint o; -
115 -
116 o = (c & 0xff00ff00) -
117 | ((c >> 16) & 0x000000ff) -
118 | ((c << 16) & 0x00ff0000); -
119 -
120 -
121 -
122 -
123 return o;
never executed: return o;
0
124} -
125 -
126 -
127void QGL2GradientCache::generateGradientColorTable(const QGradient& gradient, uint *colorTable, int size, qreal opacity) const -
128{ -
129 int pos = 0; -
130 QGradientStops s = gradient.stops(); -
131 QVector<uint> colors(s.size()); -
132 -
133 for (int i = 0; i < s.size(); ++i)
never evaluated: i < s.size()
0
134 colors[i] = s[i].second.rgba();
never executed: colors[i] = s[i].second.rgba();
0
135 -
136 bool colorInterpolation = (gradient.interpolationMode() == QGradient::ColorInterpolation); -
137 -
138 uint alpha = qRound(opacity * 256); -
139 uint current_color = ((((colors[0] >> 24) * alpha) >> 8) << 24) | (colors[0] & 0x00ffffff); -
140 qreal incr = 1.0 / qreal(size); -
141 qreal fpos = 1.5 * incr; -
142 colorTable[pos++] = qtToGlColor(PREMUL(current_color)); -
143 -
144 while (fpos <= s.first().first) {
never evaluated: fpos <= s.first().first
0
145 colorTable[pos] = colorTable[pos - 1]; -
146 pos++; -
147 fpos += incr; -
148 }
never executed: }
0
149 -
150 if (colorInterpolation)
never evaluated: colorInterpolation
0
151 current_color = PREMUL(current_color);
never executed: current_color = PREMUL(current_color);
0
152 -
153 for (int i = 0; i < s.size() - 1; ++i) {
never evaluated: i < s.size() - 1
0
154 qreal delta = 1/(s[i+1].first - s[i].first); -
155 uint next_color = ((((colors[i+1] >> 24) * alpha) >> 8) << 24) | (colors[i+1] & 0x00ffffff); -
156 if (colorInterpolation)
never evaluated: colorInterpolation
0
157 next_color = PREMUL(next_color);
never executed: next_color = PREMUL(next_color);
0
158 -
159 while (fpos < s[i+1].first && pos < size) {
never evaluated: fpos < s[i+1].first
never evaluated: pos < size
0
160 int dist = int(256 * ((fpos - s[i].first) * delta)); -
161 int idist = 256 - dist; -
162 if (colorInterpolation)
never evaluated: colorInterpolation
0
163 colorTable[pos] = qtToGlColor(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
never executed: colorTable[pos] = qtToGlColor(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
0
164 else -
165 colorTable[pos] = qtToGlColor(PREMUL(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist)));
never executed: colorTable[pos] = qtToGlColor(PREMUL(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist)));
0
166 ++pos; -
167 fpos += incr; -
168 }
never executed: }
0
169 current_color = next_color; -
170 }
never executed: }
0
171 -
172 qt_noop(); -
173 -
174 uint last_color = qtToGlColor(PREMUL(((((colors[s.size() - 1] >> 24) * alpha) >> 8) << 24) | (colors[s.size() - 1] & 0x00ffffff))); -
175 for (;pos < size; ++pos)
never evaluated: pos < size
0
176 colorTable[pos] = last_color;
never executed: colorTable[pos] = last_color;
0
177 -
178 -
179 colorTable[size-1] = last_color; -
180}
never executed: }
0
181 -
182 -
183 -
Switch to Source codePreprocessed file

Generated by Squish Coco Non-Commercial