qglgradientcache.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/opengl/gl2paintengineex/qglgradientcache.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2016 The Qt Company Ltd.-
4** Contact: https://www.qt.io/licensing/-
5**-
6** This file is part of the QtOpenGL module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL$-
9** Commercial License Usage-
10** Licensees holding valid commercial Qt licenses may use this file in-
11** accordance with the commercial license agreement provided with the-
12** Software or, alternatively, in accordance with the terms contained in-
13** a written agreement between you and The Qt Company. For licensing terms-
14** and conditions see https://www.qt.io/terms-conditions. For further-
15** information use the contact form at https://www.qt.io/contact-us.-
16**-
17** GNU Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 3 as published by the Free Software-
20** Foundation and appearing in the file LICENSE.LGPL3 included in the-
21** packaging of this file. Please review the following information to-
22** ensure the GNU Lesser General Public License version 3 requirements-
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
24**-
25** GNU General Public License Usage-
26** Alternatively, this file may be used under the terms of the GNU-
27** General Public License version 2.0 or (at your option) the GNU General-
28** Public license version 3 or any later version approved by the KDE Free-
29** Qt Foundation. The licenses are as published by the Free Software-
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
31** included in the packaging of this file. Please review the following-
32** information to ensure the GNU General Public License requirements will-
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
34** https://www.gnu.org/licenses/gpl-3.0.html.-
35**-
36** $QT_END_LICENSE$-
37**-
38****************************************************************************/-
39-
40#include "qglgradientcache_p.h"-
41#include <private/qdrawhelper_p.h>-
42#include <private/qgl_p.h>-
43#include <QtCore/qmutex.h>-
44-
45QT_BEGIN_NAMESPACE-
46-
47class QGL2GradientCacheWrapper-
48{-
49public:-
50 QGL2GradientCache *cacheForContext(const QGLContext *context) {-
51 QMutexLocker lock(&m_mutex);-
52 return m_resource.value<QGL2GradientCache>(context->contextHandle());
never executed: return m_resource.value<QGL2GradientCache>(context->contextHandle());
0
53 }-
54-
55private:-
56 QOpenGLMultiGroupSharedResource m_resource;-
57 QMutex m_mutex;-
58};-
59-
60Q_GLOBAL_STATIC(QGL2GradientCacheWrapper, qt_gradient_caches)
never executed: end of block
never executed: guard.store(QtGlobalStatic::Destroyed);
never executed: return &holder.value;
guard.load() =...c::InitializedDescription
TRUEnever evaluated
FALSEnever evaluated
0
61-
62QGL2GradientCache::QGL2GradientCache(QOpenGLContext *ctx)-
63 : QOpenGLSharedResource(ctx->shareGroup())-
64{-
65}
never executed: end of block
0
66-
67QGL2GradientCache::~QGL2GradientCache()-
68{-
69 cache.clear();-
70}
never executed: end of block
0
71-
72QGL2GradientCache *QGL2GradientCache::cacheForContext(const QGLContext *context)-
73{-
74 return qt_gradient_caches()->cacheForContext(context);
never executed: return qt_gradient_caches()->cacheForContext(context);
0
75}-
76-
77void QGL2GradientCache::invalidateResource()-
78{-
79 QMutexLocker lock(&m_mutex);-
80 cache.clear();-
81}
never executed: end of block
0
82-
83void QGL2GradientCache::freeResource(QOpenGLContext *)-
84{-
85 cleanCache();-
86}
never executed: end of block
0
87-
88void QGL2GradientCache::cleanCache()-
89{-
90 QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();-
91 QMutexLocker lock(&m_mutex);-
92 QGLGradientColorTableHash::const_iterator it = cache.constBegin();-
93 for (; it != cache.constEnd(); ++it) {
it != cache.constEnd()Description
TRUEnever evaluated
FALSEnever evaluated
0
94 const CacheInfo &cache_info = it.value();-
95 funcs->glDeleteTextures(1, &cache_info.texId);-
96 }
never executed: end of block
0
97 cache.clear();-
98}
never executed: end of block
0
99-
100GLuint QGL2GradientCache::getBuffer(const QGradient &gradient, qreal opacity)-
101{-
102 QMutexLocker lock(&m_mutex);-
103 quint64 hash_val = 0;-
104-
105 const QGradientStops stops = gradient.stops();-
106 for (int i = 0; i < stops.size() && i <= 2; i++)
i < stops.size()Description
TRUEnever evaluated
FALSEnever evaluated
i <= 2Description
TRUEnever evaluated
FALSEnever evaluated
0
107 hash_val += stops[i].second.rgba();
never executed: hash_val += stops[i].second.rgba();
0
108-
109 QGLGradientColorTableHash::const_iterator it = cache.constFind(hash_val);-
110-
111 if (it == cache.constEnd())
it == cache.constEnd()Description
TRUEnever evaluated
FALSEnever evaluated
0
112 return addCacheElement(hash_val, gradient, opacity);
never executed: return addCacheElement(hash_val, gradient, opacity);
0
113 else {-
114 do {-
115 const CacheInfo &cache_info = it.value();-
116 if (cache_info.stops == stops && cache_info.opacity == opacity
cache_info.stops == stopsDescription
TRUEnever evaluated
FALSEnever evaluated
cache_info.opacity == opacityDescription
TRUEnever evaluated
FALSEnever evaluated
0
117 && cache_info.interpolationMode == gradient.interpolationMode())
cache_info.int...polationMode()Description
TRUEnever evaluated
FALSEnever evaluated
0
118 {-
119 return cache_info.texId;
never executed: return cache_info.texId;
0
120 }-
121 ++it;-
122 } while (it != cache.constEnd() && it.key() == hash_val);
never executed: end of block
it != cache.constEnd()Description
TRUEnever evaluated
FALSEnever evaluated
it.key() == hash_valDescription
TRUEnever evaluated
FALSEnever evaluated
0
123 // an exact match for these stops and opacity was not found, create new cache-
124 return addCacheElement(hash_val, gradient, opacity);
never executed: return addCacheElement(hash_val, gradient, opacity);
0
125 }-
126}-
127-
128-
129GLuint QGL2GradientCache::addCacheElement(quint64 hash_val, const QGradient &gradient, qreal opacity)-
130{-
131 QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();-
132 if (cache.size() == maxCacheSize()) {
cache.size() == maxCacheSize()Description
TRUEnever evaluated
FALSEnever evaluated
0
133 int elem_to_remove = qrand() % maxCacheSize();-
134 quint64 key = cache.keys()[elem_to_remove];-
135-
136 // need to call glDeleteTextures on each removed cache entry:-
137 QGLGradientColorTableHash::const_iterator it = cache.constFind(key);-
138 do {-
139 funcs->glDeleteTextures(1, &it.value().texId);-
140 } while (++it != cache.constEnd() && it.key() == key);
never executed: end of block
++it != cache.constEnd()Description
TRUEnever evaluated
FALSEnever evaluated
it.key() == keyDescription
TRUEnever evaluated
FALSEnever evaluated
0
141 cache.remove(key); // may remove more than 1, but OK-
142 }
never executed: end of block
0
143-
144 CacheInfo cache_entry(gradient.stops(), opacity, gradient.interpolationMode());-
145 uint buffer[1024];-
146 generateGradientColorTable(gradient, buffer, paletteSize(), opacity);-
147 funcs->glGenTextures(1, &cache_entry.texId);-
148 funcs->glBindTexture(GL_TEXTURE_2D, cache_entry.texId);-
149 funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, paletteSize(), 1,-
150 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);-
151 return cache.insert(hash_val, cache_entry).value().texId;
never executed: return cache.insert(hash_val, cache_entry).value().texId;
0
152}-
153-
154-
155// GL's expects pixels in RGBA (when using GL_RGBA), bin-endian (ABGR on x86).-
156// Qt always stores in ARGB reguardless of the byte-order the mancine uses.-
157static inline uint qtToGlColor(uint c)-
158{-
159 uint o;-
160#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN-
161 o = (c & 0xff00ff00) // alpha & green already in the right place-
162 | ((c >> 16) & 0x000000ff) // red-
163 | ((c << 16) & 0x00ff0000); // blue-
164#else //Q_BIG_ENDIAN-
165 o = (c << 8)-
166 | ((c >> 24) & 0x000000ff);-
167#endif // Q_BYTE_ORDER-
168 return o;
never executed: return o;
0
169}-
170-
171//TODO: Let GL generate the texture using an FBO-
172void QGL2GradientCache::generateGradientColorTable(const QGradient& gradient, uint *colorTable, int size, qreal opacity) const-
173{-
174 int pos = 0;-
175 const QGradientStops s = gradient.stops();-
176 bool colorInterpolation = (gradient.interpolationMode() == QGradient::ColorInterpolation);-
177-
178 uint alpha = qRound(opacity * 256);-
179 // Qt LIES! It returns ARGB (on little-endian AND on big-endian)-
180 uint current_color = ARGB_COMBINE_ALPHA(s[0].second.rgba(), alpha);-
181 qreal incr = 1.0 / qreal(size);-
182 qreal fpos = 1.5 * incr;-
183 colorTable[pos++] = qtToGlColor(qPremultiply(current_color));-
184-
185 while (fpos <= s.first().first) {
fpos <= s.first().firstDescription
TRUEnever evaluated
FALSEnever evaluated
0
186 colorTable[pos] = colorTable[pos - 1];-
187 pos++;-
188 fpos += incr;-
189 }
never executed: end of block
0
190-
191 if (colorInterpolation)
colorInterpolationDescription
TRUEnever evaluated
FALSEnever evaluated
0
192 current_color = qPremultiply(current_color);
never executed: current_color = qPremultiply(current_color);
0
193-
194 const int sLast = s.size() - 1;-
195 for (int i = 0; i < sLast; ++i) {
i < sLastDescription
TRUEnever evaluated
FALSEnever evaluated
0
196 qreal delta = 1/(s[i+1].first - s[i].first);-
197 uint next_color = ARGB_COMBINE_ALPHA(s[i + 1].second.rgba(), alpha);-
198 if (colorInterpolation)
colorInterpolationDescription
TRUEnever evaluated
FALSEnever evaluated
0
199 next_color = qPremultiply(next_color);
never executed: next_color = qPremultiply(next_color);
0
200-
201 while (fpos < s[i+1].first && pos < size) {
fpos < s[i+1].firstDescription
TRUEnever evaluated
FALSEnever evaluated
pos < sizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
202 int dist = int(256 * ((fpos - s[i].first) * delta));-
203 int idist = 256 - dist;-
204 if (colorInterpolation)
colorInterpolationDescription
TRUEnever evaluated
FALSEnever evaluated
0
205 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
206 else-
207 colorTable[pos] = qtToGlColor(qPremultiply(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist)));
never executed: colorTable[pos] = qtToGlColor(qPremultiply(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist)));
0
208 ++pos;-
209 fpos += incr;-
210 }
never executed: end of block
0
211 current_color = next_color;-
212 }
never executed: end of block
0
213-
214 Q_ASSERT(s.size() > 0);-
215-
216 uint last_color = qtToGlColor(qPremultiply(ARGB_COMBINE_ALPHA(s[sLast].second.rgba(), alpha)));-
217 for (;pos < size; ++pos)
pos < sizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
218 colorTable[pos] = last_color;
never executed: colorTable[pos] = last_color;
0
219-
220 // Make sure the last color stop is represented at the end of the table-
221 colorTable[size-1] = last_color;-
222}
never executed: end of block
0
223-
224QT_END_NAMESPACE-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9