1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QOPENGLPROGRAMBINARYCACHE_P_H
5#define QOPENGLPROGRAMBINARYCACHE_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtGui/qtguiglobal.h>
19#include <QtCore/qcache.h>
20#include <QtCore/qmutex.h>
21#include <QtCore/QLoggingCategory>
22#include <QtGui/private/qopenglcontext_p.h>
23#include <rhi/qshader.h>
24
25QT_BEGIN_NAMESPACE
26
27// These classes are also used by the OpenGL backend of QRhi. They must
28// therefore stay independent from QOpenGLShader(Program). Must rely only on
29// QOpenGLContext/Functions.
30
31Q_DECLARE_EXPORTED_LOGGING_CATEGORY(lcOpenGLProgramDiskCache, Q_GUI_EXPORT)
32
33class Q_GUI_EXPORT QOpenGLProgramBinaryCache
34{
35public:
36 struct Q_GUI_EXPORT ShaderDesc {
37 ShaderDesc() { }
38 ShaderDesc(QShader::Stage stage, const QByteArray &source = QByteArray())
39 : stage(stage), source(source)
40 { }
41 QShader::Stage stage;
42 QByteArray source;
43 };
44 struct Q_GUI_EXPORT ProgramDesc {
45 QList<ShaderDesc> shaders;
46 QByteArray cacheKey() const;
47 };
48
49 QOpenGLProgramBinaryCache();
50
51 bool load(const QByteArray &cacheKey, uint programId);
52 void save(const QByteArray &cacheKey, uint programId);
53
54private:
55 QString cacheFileName(const QByteArray &cacheKey) const;
56 bool verifyHeader(const QByteArray &buf) const;
57 bool setProgramBinary(uint programId, uint blobFormat, const void *p, uint blobSize);
58
59 QString m_globalCacheDir;
60 QString m_localCacheDir;
61 QString m_currentCacheDir;
62 bool m_cacheWritable;
63 struct MemCacheEntry {
64 MemCacheEntry(const void *p, int size, uint format)
65 : blob(reinterpret_cast<const char *>(p), size),
66 format(format)
67 { }
68 QByteArray blob;
69 uint format;
70 };
71 QCache<QByteArray, MemCacheEntry> m_memCache;
72#if QT_CONFIG(opengles2)
73 void (QOPENGLF_APIENTRYP programBinaryOES)(GLuint program, GLenum binaryFormat, const GLvoid *binary, GLsizei length);
74 void (QOPENGLF_APIENTRYP getProgramBinaryOES)(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary);
75 void initializeProgramBinaryOES(QOpenGLContext *context);
76 bool m_programBinaryOESInitialized = false;
77#endif
78 QMutex m_mutex;
79};
80
81// While unlikely, one application can in theory use contexts with different versions
82// or profiles. Therefore any version- or extension-specific checks must be done on a
83// per-context basis, not just once per process. QOpenGLSharedResource enables this,
84// although it's once-per-sharing-context-group, not per-context. Still, this should
85// be good enough in practice.
86class Q_GUI_EXPORT QOpenGLProgramBinarySupportCheck : public QOpenGLSharedResource
87{
88public:
89 QOpenGLProgramBinarySupportCheck(QOpenGLContext *context);
90 void invalidateResource() override { }
91 void freeResource(QOpenGLContext *) override { }
92
93 bool isSupported() const { return m_supported; }
94
95private:
96 bool m_supported;
97};
98
99class QOpenGLProgramBinarySupportCheckWrapper
100{
101public:
102 QOpenGLProgramBinarySupportCheck *get(QOpenGLContext *context)
103 {
104 return m_resource.value<QOpenGLProgramBinarySupportCheck>(context);
105 }
106
107private:
108 QOpenGLMultiGroupSharedResource m_resource;
109};
110
111QT_END_NAMESPACE
112
113#endif
114

source code of qtbase/src/gui/opengl/qopenglprogrambinarycache_p.h