41 #include <QOpenGLContext>
42 #include <QOpenGLExtraFunctions>
44 #include <QStandardPaths>
47 #include <QCoreApplication>
48 #include <QCryptographicHash>
52 #include <private/qcore_unix_p.h>
59 #ifndef GL_CONTEXT_LOST
60 #define GL_CONTEXT_LOST 0x0507
63 #ifndef GL_PROGRAM_BINARY_LENGTH
64 #define GL_PROGRAM_BINARY_LENGTH 0x8741
67 #ifndef GL_NUM_PROGRAM_BINARY_FORMATS
68 #define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE
86 GLEnvInfo::GLEnvInfo()
91 const char *vendor =
reinterpret_cast<const char *
>(
f->glGetString(GL_VENDOR));
92 const char *renderer =
reinterpret_cast<const char *
>(
f->glGetString(GL_RENDERER));
93 const char *
version =
reinterpret_cast<const char *
>(
f->glGetString(GL_VERSION));
102 QByteArray QOpenGLProgramBinaryCache::ProgramDesc::cacheKey()
const
105 for (
const QOpenGLProgramBinaryCache::ShaderDesc &
shader :
shaders)
106 keyBuilder.addData(
shader.source);
108 return keyBuilder.result().toHex();
111 static inline bool qt_ensureWritableDir(
const QString &
name)
117 QOpenGLProgramBinaryCache::QOpenGLProgramBinaryCache()
118 : m_cacheWritable(
false)
122 m_globalCacheDir = sharedCachePath + subPath;
125 if (!sharedCachePath.
isEmpty()) {
126 m_currentCacheDir = m_globalCacheDir;
127 m_cacheWritable = qt_ensureWritableDir(m_currentCacheDir);
129 if (!m_cacheWritable) {
130 m_currentCacheDir = m_localCacheDir;
131 m_cacheWritable = qt_ensureWritableDir(m_currentCacheDir);
134 qCDebug(lcOpenGLProgramDiskCache,
"Cache location '%s' writable = %d", qPrintable(m_currentCacheDir), m_cacheWritable);
137 QString QOpenGLProgramBinaryCache::cacheFileName(
const QByteArray &cacheKey)
const
142 #define BASE_HEADER_SIZE (int(4 * sizeof(quint32)))
143 #define FULL_HEADER_SIZE(stringsSize) (BASE_HEADER_SIZE + 12 + stringsSize + 8)
144 #define PADDING_SIZE(fullHeaderSize) (((fullHeaderSize + 3) & ~3) - fullHeaderSize)
162 bool QOpenGLProgramBinaryCache::verifyHeader(
const QByteArray &
buf)
const
165 qCDebug(lcOpenGLProgramDiskCache,
"Cached size too small");
168 const uchar *
p =
reinterpret_cast<const uchar *
>(
buf.constData());
170 qCDebug(lcOpenGLProgramDiskCache,
"Magic does not match");
174 qCDebug(lcOpenGLProgramDiskCache,
"Version does not match");
178 qCDebug(lcOpenGLProgramDiskCache,
"Qt version does not match");
182 qCDebug(lcOpenGLProgramDiskCache,
"Architecture does not match");
188 bool QOpenGLProgramBinaryCache::setProgramBinary(
uint programId,
uint blobFormat,
const void *
p,
uint blobSize)
197 #if QT_CONFIG(opengles2)
198 if (
context->isOpenGLES() &&
context->format().majorVersion() < 3) {
199 initializeProgramBinaryOES(
context);
200 programBinaryOES(programId, blobFormat,
p, blobSize);
206 if (err != GL_NO_ERROR) {
207 qCDebug(lcOpenGLProgramDiskCache,
"Program binary failed to load for program %u, size %d, "
208 "format 0x%x, err = 0x%x",
209 programId, blobSize, blobFormat, err);
212 GLint linkStatus = 0;
214 if (linkStatus != GL_TRUE) {
215 qCDebug(lcOpenGLProgramDiskCache,
"Program binary failed to load for program %u, size %d, "
216 "format 0x%x, linkStatus = 0x%x, err = 0x%x",
217 programId, blobSize, blobFormat, linkStatus, err);
221 qCDebug(lcOpenGLProgramDiskCache,
"Program binary set for program %u, size %d, format 0x%x, err = 0x%x",
222 programId, blobSize, blobFormat, err);
238 munmap(ptr, mapSize);
245 if (offs == (off_t) -1) {
249 mapSize =
static_cast<size_t>(offs);
250 ptr = mmap(
nullptr, mapSize, PROT_READ, MAP_SHARED,
fd, 0);
285 if (
const MemCacheEntry *
e = m_memCache.object(cacheKey))
286 return setProgramBinary(programId,
e->format,
e->blob.constData(),
e->blob.size());
289 const QString fn = cacheFileName(cacheKey);
306 if (!verifyHeader(
buf)) {
320 p =
reinterpret_cast<const uchar *
>(
buf.constData());
326 if (vendor !=
info.glvendor) {
329 qCDebug(lcOpenGLProgramDiskCache) <<
"GL_VENDOR does not match" << vendor <<
info.glvendor;
334 if (renderer !=
info.glrenderer) {
335 qCDebug(lcOpenGLProgramDiskCache) <<
"GL_RENDERER does not match" << renderer <<
info.glrenderer;
341 qCDebug(lcOpenGLProgramDiskCache) <<
"GL_VERSION does not match" <<
version <<
info.glversion;
351 return setProgramBinary(programId, blobFormat,
p, blobSize)
352 && m_memCache.insert(cacheKey,
new MemCacheEntry(
p, blobSize, blobFormat));
370 #if QT_CONFIG(temporaryfile)
387 void QOpenGLProgramBinaryCache::save(
const QByteArray &cacheKey,
uint programId)
389 if (!m_cacheWritable)
411 const int totalSize = headerSize + paddingSize + blobSize;
413 qCDebug(lcOpenGLProgramDiskCache,
"Program binary is %d bytes, err = 0x%x, total %d", blobSize, funcs->
glGetError(), totalSize);
425 writeStr(&
p,
info.glvendor);
426 writeStr(&
p,
info.glrenderer);
427 writeStr(&
p,
info.glversion);
431 writeUInt(&
p, blobFormat);
432 writeUInt(&
p, blobSize);
434 for (
int i = 0;
i < paddingSize; ++
i)
438 #if QT_CONFIG(opengles2)
439 if (
context->isOpenGLES() &&
context->format().majorVersion() < 3) {
441 initializeProgramBinaryOES(
context);
442 getProgramBinaryOES(programId, blobSize, &outSize, &blobFormat,
p);
446 if (blobSize != outSize) {
447 qCDebug(lcOpenGLProgramDiskCache,
"glGetProgramBinary returned size %d instead of %d", outSize, blobSize);
451 writeUInt(&blobFormatPtr, blobFormat);
455 if (!
ok && m_currentCacheDir == m_globalCacheDir) {
456 m_currentCacheDir = m_localCacheDir;
457 m_cacheWritable = qt_ensureWritableDir(m_currentCacheDir);
458 qCDebug(lcOpenGLProgramDiskCache,
"Cache location changed to '%s' writable = %d",
459 qPrintable(m_currentCacheDir), m_cacheWritable);
460 if (m_cacheWritable) {
466 qCDebug(lcOpenGLProgramDiskCache,
"Failed to write %s to shader cache", qPrintable(
filename));
469 #if QT_CONFIG(opengles2)
472 if (m_programBinaryOESInitialized)
474 m_programBinaryOESInitialized =
true;
487 qCDebug(lcOpenGLProgramDiskCache,
"Shader cache disabled via app attribute");
490 if (qEnvironmentVariableIntValue(
"QT_DISABLE_SHADER_DISK_CACHE")) {
491 qCDebug(lcOpenGLProgramDiskCache,
"Shader cache disabled via env var");
502 const bool hasExt = ctx->
hasExtension(
"GL_OES_get_program_binary");
503 qCDebug(lcOpenGLProgramDiskCache,
"GL_OES_get_program_binary support = %d", hasExt);
508 const bool hasExt = ctx->
hasExtension(
"GL_ARB_get_program_binary");
509 qCDebug(lcOpenGLProgramDiskCache,
"GL_ARB_get_program_binary support = %d", hasExt);
516 qCDebug(lcOpenGLProgramDiskCache,
"Supported binary format count = %d", fmtCount);
517 m_supported = fmtCount > 0;
520 qCDebug(lcOpenGLProgramDiskCache,
"Shader cache supported = %d", m_supported);
small capitals from c petite p scientific i
[1]
DeferredFileRemove(const QString &fn)
The QByteArray class provides an array of bytes.
qsizetype size() const noexcept
static QByteArray fromRawData(const char *data, qsizetype size)
static bool testAttribute(Qt::ApplicationAttribute attribute)
The QCryptographicHash class provides a way to generate cryptographic hashes.
bool mkpath(const QString &dirPath) const
The QFile class provides an interface for reading from and writing to files.
static QByteArray encodeName(const QString &fileName)
The QFileInfo class provides system-independent file information.
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal.
The QMutexLocker class is a convenience class that simplifies locking and unlocking mutexes.
The QOpenGLContext class represents a native OpenGL context, enabling OpenGL rendering on a QSurface.
QSurfaceFormat format() const
bool hasExtension(const QByteArray &extension) const
static QOpenGLContext * currentContext()
QOpenGLFunctions * functions() const
The QOpenGLFunctions class provides cross-platform access to the OpenGL ES 2.0 API.
void glGetProgramiv(GLuint program, GLenum pname, GLint *params)
void glGetIntegerv(GLenum pname, GLint *params)
QOpenGLProgramBinarySupportCheck(QOpenGLContext *context)
The QSaveFile class provides an interface for safely writing to files.
static QString writableLocation(StandardLocation type)
The QString class provides a Unicode character string.
const QChar * constData() const
static QString fromUtf8(QByteArrayView utf8)
static QString buildAbi()
QMap< QString, QString > map
[6]
backing_store_ptr info
[4]
@ AA_DisableShaderDiskCache
constexpr Initialization Uninitialized
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
EGLOutputLayerEXT EGLint EGLAttrib value
QT_BEGIN_INCLUDE_NAMESPACE typedef unsigned char uchar
Q_CORE_EXPORT Q_DECL_COLD_FUNCTION void qErrnoWarning(int code, const char *msg,...)
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
#define QOPENGLF_APIENTRYP
GLenum GLuint GLenum GLsizei length
GLsizei GLsizei GLenum void * binary
typedef GLint(GL_APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONINDEXEXTPROC)(GLuint program
GLsizei const GLfloat * v
[13]
typedef GLsizei(GL_APIENTRYP PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC)(GLuint target)
typedef GLenum(GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSKHRPROC)(void)
GLenum GLuint GLenum GLsizei const GLchar * buf
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLsizei GLsizei GLenum * binaryFormat
typedef GLuint(GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGKHRPROC)(GLuint count
GLsizei GLsizei GLuint * shaders
#define GL_NUM_PROGRAM_BINARY_FORMATS
const quint32 BINSHADER_VERSION
const quint32 BINSHADER_QTVERSION
#define GL_PROGRAM_BINARY_LENGTH
#define PADDING_SIZE(fullHeaderSize)
const quint32 BINSHADER_MAGIC
#define FULL_HEADER_SIZE(stringsSize)
void writeFile(QCborStreamWriter &writer, const QString &fileName)
[6]
QHttpRequestHeader header("GET", QUrl::toPercentEncoding("/index.html"))
[1]
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.