6#include <private/qopengltextureuploader_p.h>
8#include <qopenglfunctions.h>
9#include <private/qimagepixmapcleanuphooks_p.h>
10#include <qpa/qplatformpixmap.h>
12#include <qtopengl_tracepoints_p.h>
21 QImagePixmapCleanupHooks::instance()->addPlatformPixmapModificationHook(cleanupTexturesForPixmapData);
22 QImagePixmapCleanupHooks::instance()->addPlatformPixmapDestructionHook(cleanupTexturesForPixmapData);
23 QImagePixmapCleanupHooks::instance()->addImageHook(cleanupTexturesForCacheKey);
28 QImagePixmapCleanupHooks::instance()->removePlatformPixmapModificationHook(cleanupTexturesForPixmapData);
29 QImagePixmapCleanupHooks::instance()->removePlatformPixmapDestructionHook(cleanupTexturesForPixmapData);
30 QImagePixmapCleanupHooks::instance()->removeImageHook(cleanupTexturesForCacheKey);
34 QMutexLocker lock(&m_mutex);
35 return m_resource.value<QOpenGLTextureCache>(context);
42 QOpenGLMultiGroupSharedResource m_resource;
46Q_GLOBAL_STATIC(QOpenGLTextureCacheWrapper, qt_texture_caches)
48QOpenGLTextureCache *QOpenGLTextureCache::cacheForContext(QOpenGLContext *context)
50 return qt_texture_caches()->cacheForContext(context);
53void QOpenGLTextureCacheWrapper::cleanupTexturesForCacheKey(qint64 key)
55 QList<QOpenGLSharedResource *> resources = qt_texture_caches()->m_resource.resources();
56 for (QList<QOpenGLSharedResource *>::iterator it = resources.begin(); it != resources.end(); ++it)
57 static_cast<QOpenGLTextureCache *>(*it)->invalidate(key);
60void QOpenGLTextureCacheWrapper::cleanupTexturesForPixmapData(QPlatformPixmap *pmd)
62 cleanupTexturesForCacheKey(pmd->cacheKey());
65static quint64 cacheSize()
68 const int envCacheSize = qEnvironmentVariableIntValue(
"QT_OPENGL_TEXTURE_CACHE_SIZE", &ok);
75QOpenGLTextureCache::QOpenGLTextureCache(QOpenGLContext *ctx)
76 : QOpenGLSharedResource(ctx->shareGroup())
77 , m_cache(cacheSize())
81QOpenGLTextureCache::~QOpenGLTextureCache()
85QOpenGLTextureCache::BindResult QOpenGLTextureCache::bindTexture(QOpenGLContext *context,
86 const QPixmap &pixmap,
87 QOpenGLTextureUploader::BindOptions options)
91 QMutexLocker locker(&m_mutex);
92 qint64 key = pixmap.cacheKey();
95 if (!pixmap.paintingActive()) {
96 QOpenGLCachedTexture *entry = m_cache.object(key);
97 if (entry && entry->options() == options) {
98 context->functions()->glBindTexture(GL_TEXTURE_2D, entry->id());
99 return { entry->id(), {} };
103 BindResult result = bindTexture(context, key, pixmap.toImage(), options);
105 QImagePixmapCleanupHooks::enableCleanupHooks(pixmap);
110QOpenGLTextureCache::BindResult QOpenGLTextureCache::bindTexture(QOpenGLContext *context,
112 QOpenGLTextureUploader::BindOptions options)
116 QMutexLocker locker(&m_mutex);
117 qint64 key = image.cacheKey();
120 if (!image.paintingActive()) {
121 QOpenGLCachedTexture *entry = m_cache.object(key);
122 if (entry && entry->options() == options) {
123 context->functions()->glBindTexture(GL_TEXTURE_2D, entry->id());
124 return { entry->id(), {} };
129 if (!context->functions()->hasOpenGLFeature(QOpenGLFunctions::NPOTTextures))
130 options |= QOpenGLTextureUploader::PowerOfTwoBindOption;
132 BindResult result = bindTexture(context, key, img, options);
134 QImagePixmapCleanupHooks::enableCleanupHooks(image);
139Q_TRACE_POINT(qtopengl, QOpenGLTextureCache_bindTexture_entry, QOpenGLContext *context, qint64 key,
const unsigned char *image,
int options);
142QOpenGLTextureCache::BindResult QOpenGLTextureCache::bindTexture(QOpenGLContext *context,
145 QOpenGLTextureUploader::BindOptions options)
147 Q_TRACE_SCOPE(QOpenGLTextureCache_bindTexture, context, key, image.bits(), options);
150 QOpenGLFunctions *funcs = context->functions();
151 funcs->glGenTextures(1, &id);
152 funcs->glBindTexture(GL_TEXTURE_2D, id);
154 int cost = QOpenGLTextureUploader::textureImage(GL_TEXTURE_2D, image, options);
156 m_cache.insert(key,
new QOpenGLCachedTexture(id, options, context), cost / 1024);
158 return { id, BindResultFlag::NewTexture };
161void QOpenGLTextureCache::invalidate(qint64 key)
163 QMutexLocker locker(&m_mutex);
167void QOpenGLTextureCache::invalidateResource()
172void QOpenGLTextureCache::freeResource(QOpenGLContext *)
179 funcs->glDeleteTextures(1, &id);
182QOpenGLCachedTexture::QOpenGLCachedTexture(GLuint id, QOpenGLTextureUploader::BindOptions options, QOpenGLContext *context) : m_options(options)
184 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)