qopenglgradientcache.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/gui/opengl/qopenglgradientcache.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2015 The Qt Company Ltd.-
4** Contact: http://www.qt.io/licensing/-
5**-
6** This file is part of the QtGui module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL21$-
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 http://www.qt.io/terms-conditions. For further-
15** information use the contact form at http://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 2.1 or version 3 as published by the Free-
20** Software Foundation and appearing in the file LICENSE.LGPLv21 and-
21** LICENSE.LGPLv3 included in the packaging of this file. Please review the-
22** following information to ensure the GNU Lesser General Public License-
23** requirements will be met: https://www.gnu.org/licenses/lgpl.html and-
24** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.-
25**-
26** As a special exception, The Qt Company gives you certain additional-
27** rights. These rights are described in The Qt Company LGPL Exception-
28** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.-
29**-
30** $QT_END_LICENSE$-
31**-
32****************************************************************************/-
33-
34#include "qopenglgradientcache_p.h"-
35#include <private/qdrawhelper_p.h>-
36#include <private/qopenglcontext_p.h>-
37#include <private/qrgba64_p.h>-
38#include <QtCore/qmutex.h>-
39#include "qopenglfunctions.h"-
40#include "qopenglextensions_p.h"-
41-
42#ifndef GL_RGBA16-
43#define GL_RGBA16 0x805B-
44#endif-
45-
46QT_BEGIN_NAMESPACE-
47-
48class QOpenGL2GradientCacheWrapper-
49{-
50public:-
51 QOpenGL2GradientCache *cacheForContext(QOpenGLContext *context) {-
52 QMutexLocker lock(&m_mutex);-
53 return m_resource.value<QOpenGL2GradientCache>(context);
never executed: return m_resource.value<QOpenGL2GradientCache>(context);
0
54 }-
55-
56private:-
57 QOpenGLMultiGroupSharedResource m_resource;-
58 QMutex m_mutex;-
59};-
60-
61Q_GLOBAL_STATIC(QOpenGL2GradientCacheWrapper, 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
62-
63QOpenGL2GradientCache::QOpenGL2GradientCache(QOpenGLContext *ctx)-
64 : QOpenGLSharedResource(ctx->shareGroup())-
65{-
66}
never executed: end of block
0
67-
68QOpenGL2GradientCache::~QOpenGL2GradientCache()-
69{-
70 cache.clear();-
71}
never executed: end of block
0
72-
73QOpenGL2GradientCache *QOpenGL2GradientCache::cacheForContext(QOpenGLContext *context)-
74{-
75 return qt_gradient_caches()->cacheForContext(context);
never executed: return qt_gradient_caches()->cacheForContext(context);
0
76}-
77-
78void QOpenGL2GradientCache::invalidateResource()-
79{-
80 QMutexLocker lock(&m_mutex);-
81 cache.clear();-
82}
never executed: end of block
0
83-
84void QOpenGL2GradientCache::freeResource(QOpenGLContext *)-
85{-
86 cleanCache();-
87}
never executed: end of block
0
88-
89void QOpenGL2GradientCache::cleanCache()-
90{-
91 QMutexLocker lock(&m_mutex);-
92 QOpenGLGradientColorTableHash::const_iterator it = cache.constBegin();-
93 QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();-
94 for (; it != cache.constEnd(); ++it) {
it != cache.constEnd()Description
TRUEnever evaluated
FALSEnever evaluated
0
95 const CacheInfo &cache_info = it.value();-
96 funcs->glDeleteTextures(1, &cache_info.texId);-
97 }
never executed: end of block
0
98 cache.clear();-
99}
never executed: end of block
0
100-
101GLuint QOpenGL2GradientCache::getBuffer(const QGradient &gradient, qreal opacity)-
102{-
103 quint64 hash_val = 0;-
104-
105 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 const QMutexLocker lock(&m_mutex);-
110 QOpenGLGradientColorTableHash::const_iterator it = cache.constFind(hash_val);-
111-
112 if (it == cache.constEnd())
it == cache.constEnd()Description
TRUEnever evaluated
FALSEnever evaluated
0
113 return addCacheElement(hash_val, gradient, opacity);
never executed: return addCacheElement(hash_val, gradient, opacity);
0
114 else {-
115 do {-
116 const CacheInfo &cache_info = it.value();-
117 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
118 && cache_info.interpolationMode == gradient.interpolationMode())
cache_info.int...polationMode()Description
TRUEnever evaluated
FALSEnever evaluated
0
119 {-
120 return cache_info.texId;
never executed: return cache_info.texId;
0
121 }-
122 ++it;-
123 } 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
124 // an exact match for these stops and opacity was not found, create new cache-
125 return addCacheElement(hash_val, gradient, opacity);
never executed: return addCacheElement(hash_val, gradient, opacity);
0
126 }-
127}-
128-
129-
130GLuint QOpenGL2GradientCache::addCacheElement(quint64 hash_val, const QGradient &gradient, qreal opacity)-
131{-
132 QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();-
133 if (cache.size() == maxCacheSize()) {
cache.size() == maxCacheSize()Description
TRUEnever evaluated
FALSEnever evaluated
0
134 int elem_to_remove = qrand() % maxCacheSize();-
135 quint64 key = cache.keys()[elem_to_remove];-
136-
137 // need to call glDeleteTextures on each removed cache entry:-
138 QOpenGLGradientColorTableHash::const_iterator it = cache.constFind(key);-
139 do {-
140 funcs->glDeleteTextures(1, &it.value().texId);-
141 } 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
142 cache.remove(key); // may remove more than 1, but OK-
143 }
never executed: end of block
0
144-
145 CacheInfo cache_entry(gradient.stops(), opacity, gradient.interpolationMode());-
146 funcs->glGenTextures(1, &cache_entry.texId);-
147 funcs->glBindTexture(GL_TEXTURE_2D, cache_entry.texId);-
148 if (static_cast<QOpenGLExtensions *>(funcs)->hasOpenGLExtension(QOpenGLExtensions::Sized16Formats)) {
static_cast<QO...ized16Formats)Description
TRUEnever evaluated
FALSEnever evaluated
0
149 QRgba64 buffer[1024];-
150 generateGradientColorTable(gradient, buffer, paletteSize(), opacity);-
151 funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, paletteSize(), 1,-
152 0, GL_RGBA, GL_UNSIGNED_SHORT, buffer);-
153 } else {
never executed: end of block
0
154 uint buffer[1024];-
155 generateGradientColorTable(gradient, buffer, paletteSize(), opacity);-
156 funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, paletteSize(), 1,-
157 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);-
158 }
never executed: end of block
0
159 return cache.insert(hash_val, cache_entry).value().texId;
never executed: return cache.insert(hash_val, cache_entry).value().texId;
0
160}-
161-
162-
163//TODO: Let GL generate the texture using an FBO-
164void QOpenGL2GradientCache::generateGradientColorTable(const QGradient& gradient, QRgba64 *colorTable, int size, qreal opacity) const-
165{-
166 int pos = 0;-
167 QGradientStops s = gradient.stops();-
168 QVector<QRgba64> colors(s.size());-
169-
170 for (int i = 0; i < s.size(); ++i)
i < s.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
171 colors[i] = s[i].second.rgba64();
never executed: colors[i] = s[i].second.rgba64();
0
172-
173 bool colorInterpolation = (gradient.interpolationMode() == QGradient::ColorInterpolation);-
174-
175 uint alpha = qRound(opacity * 256);-
176 QRgba64 current_color = combineAlpha256(colors[0], alpha);-
177 qreal incr = 1.0 / qreal(size);-
178 qreal fpos = 1.5 * incr;-
179 colorTable[pos++] = qPremultiply(current_color);-
180-
181 while (fpos <= s.first().first) {
fpos <= s.first().firstDescription
TRUEnever evaluated
FALSEnever evaluated
0
182 colorTable[pos] = colorTable[pos - 1];-
183 pos++;-
184 fpos += incr;-
185 }
never executed: end of block
0
186-
187 if (colorInterpolation)
colorInterpolationDescription
TRUEnever evaluated
FALSEnever evaluated
0
188 current_color = qPremultiply(current_color);
never executed: current_color = qPremultiply(current_color);
0
189-
190 for (int i = 0; i < s.size() - 1; ++i) {
i < s.size() - 1Description
TRUEnever evaluated
FALSEnever evaluated
0
191 qreal delta = 1/(s[i+1].first - s[i].first);-
192 QRgba64 next_color = combineAlpha256(colors[i+1], alpha);-
193 if (colorInterpolation)
colorInterpolationDescription
TRUEnever evaluated
FALSEnever evaluated
0
194 next_color = qPremultiply(next_color);
never executed: next_color = qPremultiply(next_color);
0
195-
196 while (fpos < s[i+1].first && pos < size) {
fpos < s[i+1].firstDescription
TRUEnever evaluated
FALSEnever evaluated
pos < sizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
197 int dist = int(256 * ((fpos - s[i].first) * delta));-
198 int idist = 256 - dist;-
199 if (colorInterpolation)
colorInterpolationDescription
TRUEnever evaluated
FALSEnever evaluated
0
200 colorTable[pos] = interpolate256(current_color, idist, next_color, dist);
never executed: colorTable[pos] = interpolate256(current_color, idist, next_color, dist);
0
201 else-
202 colorTable[pos] = qPremultiply(interpolate256(current_color, idist, next_color, dist));
never executed: colorTable[pos] = qPremultiply(interpolate256(current_color, idist, next_color, dist));
0
203 ++pos;-
204 fpos += incr;-
205 }
never executed: end of block
0
206 current_color = next_color;-
207 }
never executed: end of block
0
208-
209 Q_ASSERT(s.size() > 0);-
210-
211 QRgba64 last_color = qPremultiply(combineAlpha256(colors[s.size() - 1], alpha));-
212 for (;pos < size; ++pos)
pos < sizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
213 colorTable[pos] = last_color;
never executed: colorTable[pos] = last_color;
0
214-
215 // Make sure the last color stop is represented at the end of the table-
216 colorTable[size-1] = last_color;-
217}
never executed: end of block
0
218-
219void QOpenGL2GradientCache::generateGradientColorTable(const QGradient& gradient, uint *colorTable, int size, qreal opacity) const-
220{-
221 int pos = 0;-
222 QGradientStops s = gradient.stops();-
223 QVector<uint> colors(s.size());-
224-
225 for (int i = 0; i < s.size(); ++i)
i < s.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
226 colors[i] = s[i].second.rgba(); // Qt LIES! It returns ARGB (on little-endian AND on big-endian)
never executed: colors[i] = s[i].second.rgba();
0
227-
228 bool colorInterpolation = (gradient.interpolationMode() == QGradient::ColorInterpolation);-
229-
230 uint alpha = qRound(opacity * 256);-
231 uint current_color = ARGB_COMBINE_ALPHA(colors[0], alpha);-
232 qreal incr = 1.0 / qreal(size);-
233 qreal fpos = 1.5 * incr;-
234 colorTable[pos++] = ARGB2RGBA(qPremultiply(current_color));-
235-
236 while (fpos <= s.first().first) {
fpos <= s.first().firstDescription
TRUEnever evaluated
FALSEnever evaluated
0
237 colorTable[pos] = colorTable[pos - 1];-
238 pos++;-
239 fpos += incr;-
240 }
never executed: end of block
0
241-
242 if (colorInterpolation)
colorInterpolationDescription
TRUEnever evaluated
FALSEnever evaluated
0
243 current_color = qPremultiply(current_color);
never executed: current_color = qPremultiply(current_color);
0
244-
245 for (int i = 0; i < s.size() - 1; ++i) {
i < s.size() - 1Description
TRUEnever evaluated
FALSEnever evaluated
0
246 qreal delta = 1/(s[i+1].first - s[i].first);-
247 uint next_color = ARGB_COMBINE_ALPHA(colors[i+1], alpha);-
248 if (colorInterpolation)
colorInterpolationDescription
TRUEnever evaluated
FALSEnever evaluated
0
249 next_color = qPremultiply(next_color);
never executed: next_color = qPremultiply(next_color);
0
250-
251 while (fpos < s[i+1].first && pos < size) {
fpos < s[i+1].firstDescription
TRUEnever evaluated
FALSEnever evaluated
pos < sizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
252 int dist = int(256 * ((fpos - s[i].first) * delta));-
253 int idist = 256 - dist;-
254 if (colorInterpolation)
colorInterpolationDescription
TRUEnever evaluated
FALSEnever evaluated
0
255 colorTable[pos] = ARGB2RGBA(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
never executed: colorTable[pos] = ARGB2RGBA(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
0
256 else-
257 colorTable[pos] = ARGB2RGBA(qPremultiply(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist)));
never executed: colorTable[pos] = ARGB2RGBA(qPremultiply(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist)));
0
258 ++pos;-
259 fpos += incr;-
260 }
never executed: end of block
0
261 current_color = next_color;-
262 }
never executed: end of block
0
263-
264 Q_ASSERT(s.size() > 0);-
265-
266 uint last_color = ARGB2RGBA(qPremultiply(ARGB_COMBINE_ALPHA(colors[s.size() - 1], alpha)));-
267 for (;pos < size; ++pos)
pos < sizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
268 colorTable[pos] = last_color;
never executed: colorTable[pos] = last_color;
0
269-
270 // Make sure the last color stop is represented at the end of the table-
271 colorTable[size-1] = last_color;-
272}
never executed: end of block
0
273-
274QT_END_NAMESPACE-
Source codeSwitch to Preprocessed file

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