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) 2015 The Qt Company Ltd.-
4** Contact: http://www.qt.io/licensing/-
5**-
6** This file is part of the QtOpenGL 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 "qglgradientcache_p.h"-
35#include <private/qdrawhelper_p.h>-
36#include <private/qgl_p.h>-
37#include <QtCore/qmutex.h>-
38-
39QT_BEGIN_NAMESPACE-
40-
41class QGL2GradientCacheWrapper-
42{-
43public:-
44 QGL2GradientCache *cacheForContext(const QGLContext *context) {-
45 QMutexLocker lock(&m_mutex);-
46 return m_resource.value<QGL2GradientCache>(context->contextHandle());
never executed: return m_resource.value<QGL2GradientCache>(context->contextHandle());
0
47 }-
48-
49private:-
50 QOpenGLMultiGroupSharedResource m_resource;-
51 QMutex m_mutex;-
52};-
53-
54Q_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
55-
56QGL2GradientCache::QGL2GradientCache(QOpenGLContext *ctx)-
57 : QOpenGLSharedResource(ctx->shareGroup())-
58{-
59}
never executed: end of block
0
60-
61QGL2GradientCache::~QGL2GradientCache()-
62{-
63 cache.clear();-
64}
never executed: end of block
0
65-
66QGL2GradientCache *QGL2GradientCache::cacheForContext(const QGLContext *context)-
67{-
68 return qt_gradient_caches()->cacheForContext(context);
never executed: return qt_gradient_caches()->cacheForContext(context);
0
69}-
70-
71void QGL2GradientCache::invalidateResource()-
72{-
73 QMutexLocker lock(&m_mutex);-
74 cache.clear();-
75}
never executed: end of block
0
76-
77void QGL2GradientCache::freeResource(QOpenGLContext *)-
78{-
79 cleanCache();-
80}
never executed: end of block
0
81-
82void QGL2GradientCache::cleanCache()-
83{-
84 QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();-
85 QMutexLocker lock(&m_mutex);-
86 QGLGradientColorTableHash::const_iterator it = cache.constBegin();-
87 for (; it != cache.constEnd(); ++it) {
it != cache.constEnd()Description
TRUEnever evaluated
FALSEnever evaluated
0
88 const CacheInfo &cache_info = it.value();-
89 funcs->glDeleteTextures(1, &cache_info.texId);-
90 }
never executed: end of block
0
91 cache.clear();-
92}
never executed: end of block
0
93-
94GLuint QGL2GradientCache::getBuffer(const QGradient &gradient, qreal opacity)-
95{-
96 QMutexLocker lock(&m_mutex);-
97 quint64 hash_val = 0;-
98-
99 QGradientStops stops = gradient.stops();-
100 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
101 hash_val += stops[i].second.rgba();
never executed: hash_val += stops[i].second.rgba();
0
102-
103 QGLGradientColorTableHash::const_iterator it = cache.constFind(hash_val);-
104-
105 if (it == cache.constEnd())
it == cache.constEnd()Description
TRUEnever evaluated
FALSEnever evaluated
0
106 return addCacheElement(hash_val, gradient, opacity);
never executed: return addCacheElement(hash_val, gradient, opacity);
0
107 else {-
108 do {-
109 const CacheInfo &cache_info = it.value();-
110 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
111 && cache_info.interpolationMode == gradient.interpolationMode())
cache_info.int...polationMode()Description
TRUEnever evaluated
FALSEnever evaluated
0
112 {-
113 return cache_info.texId;
never executed: return cache_info.texId;
0
114 }-
115 ++it;-
116 } 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
117 // an exact match for these stops and opacity was not found, create new cache-
118 return addCacheElement(hash_val, gradient, opacity);
never executed: return addCacheElement(hash_val, gradient, opacity);
0
119 }-
120}-
121-
122-
123GLuint QGL2GradientCache::addCacheElement(quint64 hash_val, const QGradient &gradient, qreal opacity)-
124{-
125 QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();-
126 if (cache.size() == maxCacheSize()) {
cache.size() == maxCacheSize()Description
TRUEnever evaluated
FALSEnever evaluated
0
127 int elem_to_remove = qrand() % maxCacheSize();-
128 quint64 key = cache.keys()[elem_to_remove];-
129-
130 // need to call glDeleteTextures on each removed cache entry:-
131 QGLGradientColorTableHash::const_iterator it = cache.constFind(key);-
132 do {-
133 funcs->glDeleteTextures(1, &it.value().texId);-
134 } 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
135 cache.remove(key); // may remove more than 1, but OK-
136 }
never executed: end of block
0
137-
138 CacheInfo cache_entry(gradient.stops(), opacity, gradient.interpolationMode());-
139 uint buffer[1024];-
140 generateGradientColorTable(gradient, buffer, paletteSize(), opacity);-
141 funcs->glGenTextures(1, &cache_entry.texId);-
142 funcs->glBindTexture(GL_TEXTURE_2D, cache_entry.texId);-
143 funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, paletteSize(), 1,-
144 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);-
145 return cache.insert(hash_val, cache_entry).value().texId;
never executed: return cache.insert(hash_val, cache_entry).value().texId;
0
146}-
147-
148-
149// GL's expects pixels in RGBA (when using GL_RGBA), bin-endian (ABGR on x86).-
150// Qt always stores in ARGB reguardless of the byte-order the mancine uses.-
151static inline uint qtToGlColor(uint c)-
152{-
153 uint o;-
154#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN-
155 o = (c & 0xff00ff00) // alpha & green already in the right place-
156 | ((c >> 16) & 0x000000ff) // red-
157 | ((c << 16) & 0x00ff0000); // blue-
158#else //Q_BIG_ENDIAN-
159 o = (c << 8)-
160 | ((c >> 24) & 0x000000ff);-
161#endif // Q_BYTE_ORDER-
162 return o;
never executed: return o;
0
163}-
164-
165//TODO: Let GL generate the texture using an FBO-
166void QGL2GradientCache::generateGradientColorTable(const QGradient& gradient, uint *colorTable, int size, qreal opacity) const-
167{-
168 int pos = 0;-
169 QGradientStops s = gradient.stops();-
170 QVector<uint> colors(s.size());-
171-
172 for (int i = 0; i < s.size(); ++i)
i < s.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
173 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
174-
175 bool colorInterpolation = (gradient.interpolationMode() == QGradient::ColorInterpolation);-
176-
177 uint alpha = qRound(opacity * 256);-
178 uint current_color = ARGB_COMBINE_ALPHA(colors[0], alpha);-
179 qreal incr = 1.0 / qreal(size);-
180 qreal fpos = 1.5 * incr;-
181 colorTable[pos++] = qtToGlColor(qPremultiply(current_color));-
182-
183 while (fpos <= s.first().first) {
fpos <= s.first().firstDescription
TRUEnever evaluated
FALSEnever evaluated
0
184 colorTable[pos] = colorTable[pos - 1];-
185 pos++;-
186 fpos += incr;-
187 }
never executed: end of block
0
188-
189 if (colorInterpolation)
colorInterpolationDescription
TRUEnever evaluated
FALSEnever evaluated
0
190 current_color = qPremultiply(current_color);
never executed: current_color = qPremultiply(current_color);
0
191-
192 for (int i = 0; i < s.size() - 1; ++i) {
i < s.size() - 1Description
TRUEnever evaluated
FALSEnever evaluated
0
193 qreal delta = 1/(s[i+1].first - s[i].first);-
194 uint next_color = ARGB_COMBINE_ALPHA(colors[i+1], alpha);-
195 if (colorInterpolation)
colorInterpolationDescription
TRUEnever evaluated
FALSEnever evaluated
0
196 next_color = qPremultiply(next_color);
never executed: next_color = qPremultiply(next_color);
0
197-
198 while (fpos < s[i+1].first && pos < size) {
fpos < s[i+1].firstDescription
TRUEnever evaluated
FALSEnever evaluated
pos < sizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
199 int dist = int(256 * ((fpos - s[i].first) * delta));-
200 int idist = 256 - dist;-
201 if (colorInterpolation)
colorInterpolationDescription
TRUEnever evaluated
FALSEnever evaluated
0
202 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
203 else-
204 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
205 ++pos;-
206 fpos += incr;-
207 }
never executed: end of block
0
208 current_color = next_color;-
209 }
never executed: end of block
0
210-
211 Q_ASSERT(s.size() > 0);-
212-
213 uint last_color = qtToGlColor(qPremultiply(ARGB_COMBINE_ALPHA(colors[s.size() - 1], alpha)));-
214 for (;pos < size; ++pos)
pos < sizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
215 colorTable[pos] = last_color;
never executed: colorTable[pos] = last_color;
0
216-
217 // Make sure the last color stop is represented at the end of the table-
218 colorTable[size-1] = last_color;-
219}
never executed: end of block
0
220-
221QT_END_NAMESPACE-
Source codeSwitch to Preprocessed file

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