5#include <private/qopengltextureuploader_p.h>
7#include <qopenglfunctions.h>
8#include <private/qimagepixmapcleanuphooks_p.h>
9#include <qpa/qplatformpixmap.h>
11#include <qtopengl_tracepoints_p.h>
20 QImagePixmapCleanupHooks::instance()->addPlatformPixmapModificationHook(cleanupTexturesForPixmapData);
21 QImagePixmapCleanupHooks::instance()->addPlatformPixmapDestructionHook(cleanupTexturesForPixmapData);
22 QImagePixmapCleanupHooks::instance()->addImageHook(cleanupTexturesForCacheKey);
27 QImagePixmapCleanupHooks::instance()->removePlatformPixmapModificationHook(cleanupTexturesForPixmapData);
28 QImagePixmapCleanupHooks::instance()->removePlatformPixmapDestructionHook(cleanupTexturesForPixmapData);
29 QImagePixmapCleanupHooks::instance()->removeImageHook(cleanupTexturesForCacheKey);
33 QMutexLocker lock(&m_mutex);
34 return m_resource.value<QOpenGLTextureCache>(context);
41 QOpenGLMultiGroupSharedResource m_resource;
45Q_GLOBAL_STATIC(QOpenGLTextureCacheWrapper, qt_texture_caches)
47QOpenGLTextureCache *QOpenGLTextureCache::cacheForContext(QOpenGLContext *context)
49 return qt_texture_caches()->cacheForContext(context);
52void QOpenGLTextureCacheWrapper::cleanupTexturesForCacheKey(qint64 key)
54 QList<QOpenGLSharedResource *> resources = qt_texture_caches()->m_resource.resources();
55 for (QList<QOpenGLSharedResource *>::iterator it = resources.begin(); it != resources.end(); ++it)
56 static_cast<QOpenGLTextureCache *>(*it)->invalidate(key);
59void QOpenGLTextureCacheWrapper::cleanupTexturesForPixmapData(QPlatformPixmap *pmd)
61 cleanupTexturesForCacheKey(pmd->cacheKey());
64static quint64 cacheSize()
67 const int envCacheSize = qEnvironmentVariableIntValue(
"QT_OPENGL_TEXTURE_CACHE_SIZE", &ok);
74QOpenGLTextureCache::QOpenGLTextureCache(QOpenGLContext *ctx)
75 : QOpenGLSharedResource(ctx->shareGroup())
76 , m_cache(cacheSize())
80QOpenGLTextureCache::~QOpenGLTextureCache()
84QOpenGLTextureCache::BindResult QOpenGLTextureCache::bindTexture(QOpenGLContext *context,
85 const QPixmap &pixmap,
86 QOpenGLTextureUploader::BindOptions options)
90 QMutexLocker locker(&m_mutex);
91 qint64 key = pixmap.cacheKey();
94 if (!pixmap.paintingActive()) {
95 QOpenGLCachedTexture *entry = m_cache.object(key);
96 if (entry && entry->options() == options) {
97 context->functions()->glBindTexture(GL_TEXTURE_2D, entry->id());
98 return { entry->id(), {} };
102 BindResult result = bindTexture(context, key, pixmap.toImage(), options);
104 QImagePixmapCleanupHooks::enableCleanupHooks(pixmap);
109QOpenGLTextureCache::BindResult QOpenGLTextureCache::bindTexture(QOpenGLContext *context,
111 QOpenGLTextureUploader::BindOptions options)
115 QMutexLocker locker(&m_mutex);
116 qint64 key = image.cacheKey();
119 if (!image.paintingActive()) {
120 QOpenGLCachedTexture *entry = m_cache.object(key);
121 if (entry && entry->options() == options) {
122 context->functions()->glBindTexture(GL_TEXTURE_2D, entry->id());
123 return { entry->id(), {} };
128 if (!context->functions()->hasOpenGLFeature(QOpenGLFunctions::NPOTTextures))
129 options |= QOpenGLTextureUploader::PowerOfTwoBindOption;
131 BindResult result = bindTexture(context, key, img, options);
133 QImagePixmapCleanupHooks::enableCleanupHooks(image);
138Q_TRACE_POINT(qtopengl, QOpenGLTextureCache_bindTexture_entry, QOpenGLContext *context, qint64 key,
const unsigned char *image,
int options);
141QOpenGLTextureCache::BindResult QOpenGLTextureCache::bindTexture(QOpenGLContext *context,
144 QOpenGLTextureUploader::BindOptions options)
146 Q_TRACE_SCOPE(QOpenGLTextureCache_bindTexture, context, key, image.bits(), options);
149 QOpenGLFunctions *funcs = context->functions();
150 funcs->glGenTextures(1, &id);
151 funcs->glBindTexture(GL_TEXTURE_2D, id);
153 int cost = QOpenGLTextureUploader::textureImage(GL_TEXTURE_2D, image, options);
155 m_cache.insert(key,
new QOpenGLCachedTexture(id, options, context), cost / 1024);
157 return { id, BindResultFlag::NewTexture };
160void QOpenGLTextureCache::invalidate(qint64 key)
162 QMutexLocker locker(&m_mutex);
166void QOpenGLTextureCache::invalidateResource()
171void QOpenGLTextureCache::freeResource(QOpenGLContext *)
178 funcs->glDeleteTextures(1, &id);
181QOpenGLCachedTexture::QOpenGLCachedTexture(GLuint id, QOpenGLTextureUploader::BindOptions options, QOpenGLContext *context) : m_options(options)
183 m_resource =
new QOpenGLSharedResourceGuard(context, id, freeTexture);
static void cleanupTexturesForPixmapData(QPlatformPixmap *pmd)
~QOpenGLTextureCacheWrapper()
QOpenGLTextureCache * cacheForContext(QOpenGLContext *context)
QOpenGLTextureCacheWrapper()
static void cleanupTexturesForCacheKey(qint64 key)
Combined button and popup list for selecting options.
Q_TRACE_POINT(qtcore, QCoreApplication_postEvent_exit)
static void freeTexture(QOpenGLFunctions *funcs, GLuint id)