opengl/qopengltexturecache.cpp

Source codeSwitch to Preprocessed file
LineSource CodeCoverage
1/**************************************************************************** -
2** -
3** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -
4** Contact: http://www.qt-project.org/legal -
5** -
6** This file is part of the QtGui 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 Digia. For licensing terms and -
14** conditions see http://qt.digia.com/licensing. For further information -
15** use the contact form at http://qt.digia.com/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 as published by the Free Software -
20** Foundation and appearing in the file LICENSE.LGPL included in the -
21** packaging of this file. Please review the following information to -
22** ensure the GNU Lesser General Public License version 2.1 requirements -
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -
24** -
25** In addition, as a special exception, Digia gives you certain additional -
26** rights. These rights are described in the Digia Qt LGPL Exception -
27** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -
28** -
29** GNU General Public License Usage -
30** Alternatively, this file may be used under the terms of the GNU -
31** General Public License version 3.0 as published by the Free Software -
32** Foundation and appearing in the file LICENSE.GPL included in the -
33** packaging of this file. Please review the following information to -
34** ensure the GNU General Public License version 3.0 requirements will be -
35** met: http://www.gnu.org/copyleft/gpl.html. -
36** -
37** -
38** $QT_END_LICENSE$ -
39** -
40****************************************************************************/ -
41 -
42#include "qopengltexturecache_p.h" -
43#include <private/qopenglcontext_p.h> -
44#include <private/qimagepixmapcleanuphooks_p.h> -
45#include <qpa/qplatformpixmap.h> -
46 -
47QT_BEGIN_NAMESPACE -
48 -
49class QOpenGLTextureCacheWrapper -
50{ -
51public: -
52 QOpenGLTextureCacheWrapper() -
53 { -
54 QImagePixmapCleanupHooks::instance()->addPlatformPixmapModificationHook(cleanupTexturesForPixmapData);
never executed (the execution status of this line is deduced): QImagePixmapCleanupHooks::instance()->addPlatformPixmapModificationHook(cleanupTexturesForPixmapData);
-
55 QImagePixmapCleanupHooks::instance()->addPlatformPixmapDestructionHook(cleanupTexturesForPixmapData);
never executed (the execution status of this line is deduced): QImagePixmapCleanupHooks::instance()->addPlatformPixmapDestructionHook(cleanupTexturesForPixmapData);
-
56 QImagePixmapCleanupHooks::instance()->addImageHook(cleanupTexturesForCacheKey);
never executed (the execution status of this line is deduced): QImagePixmapCleanupHooks::instance()->addImageHook(cleanupTexturesForCacheKey);
-
57 }
never executed: }
0
58 -
59 ~QOpenGLTextureCacheWrapper() -
60 { -
61 QImagePixmapCleanupHooks::instance()->removePlatformPixmapModificationHook(cleanupTexturesForPixmapData);
never executed (the execution status of this line is deduced): QImagePixmapCleanupHooks::instance()->removePlatformPixmapModificationHook(cleanupTexturesForPixmapData);
-
62 QImagePixmapCleanupHooks::instance()->removePlatformPixmapDestructionHook(cleanupTexturesForPixmapData);
never executed (the execution status of this line is deduced): QImagePixmapCleanupHooks::instance()->removePlatformPixmapDestructionHook(cleanupTexturesForPixmapData);
-
63 QImagePixmapCleanupHooks::instance()->removeImageHook(cleanupTexturesForCacheKey);
never executed (the execution status of this line is deduced): QImagePixmapCleanupHooks::instance()->removeImageHook(cleanupTexturesForCacheKey);
-
64 }
never executed: }
0
65 -
66 QOpenGLTextureCache *cacheForContext(QOpenGLContext *context) { -
67 QMutexLocker lock(&m_mutex);
never executed (the execution status of this line is deduced): QMutexLocker lock(&m_mutex);
-
68 return m_resource.value<QOpenGLTextureCache>(context);
never executed: return m_resource.value<QOpenGLTextureCache>(context);
0
69 } -
70 -
71 static void cleanupTexturesForCacheKey(qint64 key); -
72 static void cleanupTexturesForPixmapData(QPlatformPixmap *pmd); -
73 -
74private: -
75 QOpenGLMultiGroupSharedResource m_resource; -
76 QMutex m_mutex; -
77}; -
78 -
79Q_GLOBAL_STATIC(QOpenGLTextureCacheWrapper, qt_texture_caches)
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
80 -
81QOpenGLTextureCache *QOpenGLTextureCache::cacheForContext(QOpenGLContext *context) -
82{ -
83 return qt_texture_caches()->cacheForContext(context);
never executed: return qt_texture_caches()->cacheForContext(context);
0
84} -
85 -
86void QOpenGLTextureCacheWrapper::cleanupTexturesForCacheKey(qint64 key) -
87{ -
88 QList<QOpenGLSharedResource *> resources = qt_texture_caches()->m_resource.resources();
never executed (the execution status of this line is deduced): QList<QOpenGLSharedResource *> resources = qt_texture_caches()->m_resource.resources();
-
89 for (QList<QOpenGLSharedResource *>::iterator it = resources.begin(); it != resources.end(); ++it)
never evaluated: it != resources.end()
0
90 static_cast<QOpenGLTextureCache *>(*it)->invalidate(key);
never executed: static_cast<QOpenGLTextureCache *>(*it)->invalidate(key);
0
91}
never executed: }
0
92 -
93void QOpenGLTextureCacheWrapper::cleanupTexturesForPixmapData(QPlatformPixmap *pmd) -
94{ -
95 cleanupTexturesForCacheKey(pmd->cacheKey());
never executed (the execution status of this line is deduced): cleanupTexturesForCacheKey(pmd->cacheKey());
-
96}
never executed: }
0
97 -
98QOpenGLTextureCache::QOpenGLTextureCache(QOpenGLContext *ctx) -
99 : QOpenGLSharedResource(ctx->shareGroup()) -
100 , m_cache(64 * 1024) // 64 MB cache -
101{ -
102}
never executed: }
0
103 -
104QOpenGLTextureCache::~QOpenGLTextureCache() -
105{ -
106} -
107 -
108GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, const QPixmap &pixmap) -
109{ -
110 if (pixmap.isNull())
never evaluated: pixmap.isNull()
0
111 return 0;
never executed: return 0;
0
112 QMutexLocker locker(&m_mutex);
never executed (the execution status of this line is deduced): QMutexLocker locker(&m_mutex);
-
113 qint64 key = pixmap.cacheKey();
never executed (the execution status of this line is deduced): qint64 key = pixmap.cacheKey();
-
114 -
115 // A QPainter is active on the image - take the safe route and replace the texture. -
116 if (!pixmap.paintingActive()) {
never evaluated: !pixmap.paintingActive()
0
117 QOpenGLCachedTexture *entry = m_cache.object(key);
never executed (the execution status of this line is deduced): QOpenGLCachedTexture *entry = m_cache.object(key);
-
118 if (entry) {
never evaluated: entry
0
119 glBindTexture(GL_TEXTURE_2D, entry->id());
never executed (the execution status of this line is deduced): glBindTexture(0x0DE1, entry->id());
-
120 return entry->id();
never executed: return entry->id();
0
121 } -
122 }
never executed: }
0
123 -
124 GLuint id = bindTexture(context, key, pixmap.toImage());
never executed (the execution status of this line is deduced): GLuint id = bindTexture(context, key, pixmap.toImage());
-
125 if (id > 0)
never evaluated: id > 0
0
126 QImagePixmapCleanupHooks::enableCleanupHooks(pixmap);
never executed: QImagePixmapCleanupHooks::enableCleanupHooks(pixmap);
0
127 -
128 return id;
never executed: return id;
0
129} -
130 -
131GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, const QImage &image) -
132{ -
133 if (image.isNull())
never evaluated: image.isNull()
0
134 return 0;
never executed: return 0;
0
135 QMutexLocker locker(&m_mutex);
never executed (the execution status of this line is deduced): QMutexLocker locker(&m_mutex);
-
136 qint64 key = image.cacheKey();
never executed (the execution status of this line is deduced): qint64 key = image.cacheKey();
-
137 -
138 // A QPainter is active on the image - take the safe route and replace the texture. -
139 if (!image.paintingActive()) {
never evaluated: !image.paintingActive()
0
140 QOpenGLCachedTexture *entry = m_cache.object(key);
never executed (the execution status of this line is deduced): QOpenGLCachedTexture *entry = m_cache.object(key);
-
141 if (entry) {
never evaluated: entry
0
142 glBindTexture(GL_TEXTURE_2D, entry->id());
never executed (the execution status of this line is deduced): glBindTexture(0x0DE1, entry->id());
-
143 return entry->id();
never executed: return entry->id();
0
144 } -
145 }
never executed: }
0
146 -
147 GLuint id = bindTexture(context, key, image);
never executed (the execution status of this line is deduced): GLuint id = bindTexture(context, key, image);
-
148 if (id > 0)
never evaluated: id > 0
0
149 QImagePixmapCleanupHooks::enableCleanupHooks(image);
never executed: QImagePixmapCleanupHooks::enableCleanupHooks(image);
0
150 -
151 return id;
never executed: return id;
0
152} -
153 -
154static inline void qgl_byteSwapImage(QImage &img) -
155{ -
156 const int width = img.width();
never executed (the execution status of this line is deduced): const int width = img.width();
-
157 const int height = img.height();
never executed (the execution status of this line is deduced): const int height = img.height();
-
158 -
159 if (QSysInfo::ByteOrder == QSysInfo::LittleEndian)
never evaluated: QSysInfo::ByteOrder == QSysInfo::LittleEndian
0
160 { -
161 for (int i = 0; i < height; ++i) {
never evaluated: i < height
0
162 uint *p = (uint *) img.scanLine(i);
never executed (the execution status of this line is deduced): uint *p = (uint *) img.scanLine(i);
-
163 for (int x = 0; x < width; ++x)
never evaluated: x < width
0
164 p[x] = ((p[x] << 16) & 0xff0000) | ((p[x] >> 16) & 0xff) | (p[x] & 0xff00ff00);
never executed: p[x] = ((p[x] << 16) & 0xff0000) | ((p[x] >> 16) & 0xff) | (p[x] & 0xff00ff00);
0
165 }
never executed: }
0
166 } else {
never executed: }
0
167 for (int i = 0; i < height; ++i) {
never evaluated: i < height
0
168 uint *p = (uint *) img.scanLine(i);
never executed (the execution status of this line is deduced): uint *p = (uint *) img.scanLine(i);
-
169 for (int x = 0; x < width; ++x)
never evaluated: x < width
0
170 p[x] = (p[x] << 8) | (p[x] >> 24);
never executed: p[x] = (p[x] << 8) | (p[x] >> 24);
0
171 }
never executed: }
0
172 }
never executed: }
0
173} -
174 -
175GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, qint64 key, const QImage &image) -
176{ -
177 GLuint id;
never executed (the execution status of this line is deduced): GLuint id;
-
178 glGenTextures(1, &id);
never executed (the execution status of this line is deduced): glGenTextures(1, &id);
-
179 glBindTexture(GL_TEXTURE_2D, id);
never executed (the execution status of this line is deduced): glBindTexture(0x0DE1, id);
-
180 -
181 QImage tx = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
never executed (the execution status of this line is deduced): QImage tx = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
-
182 -
183 qgl_byteSwapImage(tx);
never executed (the execution status of this line is deduced): qgl_byteSwapImage(tx);
-
184 -
185 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tx.width(), tx.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, const_cast<const QImage &>(tx).bits());
never executed (the execution status of this line is deduced): glTexImage2D(0x0DE1, 0, 0x1908, tx.width(), tx.height(), 0, 0x1908, 0x1401, const_cast<const QImage &>(tx).bits());
-
186 -
187 int cost = tx.width() * tx.height() * 4 / 1024;
never executed (the execution status of this line is deduced): int cost = tx.width() * tx.height() * 4 / 1024;
-
188 m_cache.insert(key, new QOpenGLCachedTexture(id, context), cost);
never executed (the execution status of this line is deduced): m_cache.insert(key, new QOpenGLCachedTexture(id, context), cost);
-
189 -
190 return id;
never executed: return id;
0
191} -
192 -
193void QOpenGLTextureCache::invalidate(qint64 key) -
194{ -
195 QMutexLocker locker(&m_mutex);
never executed (the execution status of this line is deduced): QMutexLocker locker(&m_mutex);
-
196 m_cache.remove(key);
never executed (the execution status of this line is deduced): m_cache.remove(key);
-
197}
never executed: }
0
198 -
199void QOpenGLTextureCache::invalidateResource() -
200{ -
201 m_cache.clear();
never executed (the execution status of this line is deduced): m_cache.clear();
-
202}
never executed: }
0
203 -
204void QOpenGLTextureCache::freeResource(QOpenGLContext *) -
205{ -
206 Q_ASSERT(false); // the texture cache lives until the context group disappears
never executed (the execution status of this line is deduced): qt_noop();
-
207}
never executed: }
0
208 -
209static void freeTexture(QOpenGLFunctions *, GLuint id) -
210{ -
211 glDeleteTextures(1, &id);
never executed (the execution status of this line is deduced): glDeleteTextures(1, &id);
-
212}
never executed: }
0
213 -
214QOpenGLCachedTexture::QOpenGLCachedTexture(GLuint id, QOpenGLContext *context) -
215{ -
216 m_resource = new QOpenGLSharedResourceGuard(context, id, freeTexture);
never executed (the execution status of this line is deduced): m_resource = new QOpenGLSharedResourceGuard(context, id, freeTexture);
-
217}
never executed: }
0
218 -
219QT_END_NAMESPACE -
220 -
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial