Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qssgrendershaderlibrarymanager.cpp
Go to the documentation of this file.
1// Copyright (C) 2008-2012 NVIDIA Corporation.
2// Copyright (C) 2019 The Qt Company Ltd.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
4
6
8#include <QtQuick3DRuntimeRender/private/qssgrenderloadedtexture_p.h>
9
10#include <QXmlStreamReader>
11#include <QFileInfo>
12#include <QCryptographicHash>
13
14#include <QtQuick3DRuntimeRender/private/qssgruntimerenderlogging_p.h>
15
17
22static QByteArray includeSearch() { return QByteArrayLiteral("#include \""); };
23static QByteArray copyrightHeaderStart() { return QByteArrayLiteral("/****************************************************************************"); }
24static QByteArray copyrightHeaderEnd() { return QByteArrayLiteral("****************************************************************************/"); }
25
27
29
31{
32 switch (type) {
34 return 'V';
36 return 'F';
37 default:
38 break;
39 }
40 return '?';
41}
42
44 const QByteArray &inSource, const QSSGCustomShaderMetaData &meta)
45{
46 QWriteLocker locker(&m_lock);
47
48 const QByteArray perStageKey = stageKey(type) + inShaderPathKey;
49 {
50 auto it = m_expandedFiles.find(perStageKey);
51 if (it != m_expandedFiles.end())
52 it.value() = inSource;
53 else
54 m_expandedFiles.insert(perStageKey, inSource);
55 }
56
57 {
58 auto it = m_metadata.find(perStageKey);
59 if (it != m_metadata.end())
60 it.value() = meta;
61 else
62 m_metadata.insert(perStageKey, meta);
63 }
64}
65
66void QSSGShaderLibraryManager::resolveIncludeFiles(QByteArray &theReadBuffer, const QByteArray &inMaterialInfoString)
67{
68 // Now do search and replace for the headers
69 for (int thePos = theReadBuffer.indexOf(includeSearch()); thePos != -1;
70 thePos = theReadBuffer.indexOf(includeSearch(), thePos + 1)) {
71 int theEndQuote = theReadBuffer.indexOf('\"', thePos + includeSearch().size() + 1);
72 // Indicates an unterminated include file.
73 if (theEndQuote == -1) {
74 qCCritical(INVALID_OPERATION, "Unterminated include in file: %s", inMaterialInfoString.constData());
75 theReadBuffer.clear();
76 break;
77 }
78 const int theActualBegin = thePos + includeSearch().size();
79 const auto &theInclude = theReadBuffer.mid(theActualBegin, theEndQuote - theActualBegin);
80 // If we haven't included the file yet this round
81 auto contents = getIncludeContents(theInclude);
82 // Strip copywrite headers from include if present
83 if (contents.startsWith(copyrightHeaderStart())) {
84 int clipPos = contents.indexOf(copyrightHeaderEnd()) ;
85 if (clipPos >= 0)
86 contents.remove(0, clipPos + copyrightHeaderEnd().size());
87 }
88 // Write insert comment for begin source
89 contents.prepend(QByteArrayLiteral("\n// begin \"") + theInclude + QByteArrayLiteral("\"\n"));
90 // Write insert comment for end source
91 contents.append(QByteArrayLiteral("\n// end \"" ) + theInclude + QByteArrayLiteral("\"\n"));
92
93 theReadBuffer = theReadBuffer.replace(thePos, (theEndQuote + 1) - thePos, contents);
94 }
95}
96
98{
99 QWriteLocker locker(&m_lock);
100
101 auto theInsert = m_expandedFiles.constFind(inShaderPathKey);
102 const bool found = (theInsert != m_expandedFiles.cend());
103
104 QByteArray theReadBuffer;
105 if (!found) {
106 const QString defaultDir = getShaderCodeLibraryDirectory();
107 const auto ver = QByteArrayLiteral("rhi");
108
109 QString fullPath;
110 QSharedPointer<QIODevice> theStream;
111 QTextStream stream(&fullPath);
112 stream << defaultDir << QLatin1Char('/') << ver << QLatin1Char('/') << QString::fromLocal8Bit(inShaderPathKey);
113 theStream = QSSGInputUtil::getStreamForFile(fullPath, true);
114 if (theStream.isNull()) {
115 fullPath.clear();
116 QTextStream stream(&fullPath);
117 stream << defaultDir << QLatin1Char('/') << QString::fromLocal8Bit(inShaderPathKey);
118 theStream = QSSGInputUtil::getStreamForFile(fullPath, false);
119 }
120 if (!theStream.isNull()) {
121 char readBuf[1024];
122 qint64 amountRead = 0;
123 do {
124 amountRead = theStream->read(readBuf, 1024);
125 if (amountRead)
126 theReadBuffer.append(readBuf, int(amountRead));
127 } while (amountRead);
128 } else {
129 qCCritical(INVALID_OPERATION, "Failed to find include file %s", qPrintable(QString::fromLocal8Bit(inShaderPathKey)));
130 Q_ASSERT(false);
131 }
132 theInsert = m_expandedFiles.insert(inShaderPathKey, theReadBuffer);
133 } else {
134 theReadBuffer = theInsert.value();
135 }
136
137 locker.unlock();
138 resolveIncludeFiles(theReadBuffer, inShaderPathKey);
139
140 return theReadBuffer;
141}
142
144{
145 QReadLocker locker(&m_lock);
146
147 const QByteArray perStageKey = stageKey(type) + inShaderPathKey;
148 auto it = m_expandedFiles.constFind(perStageKey);
149 if (it != m_expandedFiles.cend())
150 return it.value();
151
152 qWarning("No shader source stored for key %s", perStageKey.constData());
153 return QByteArray();
154}
155
157{
158 QReadLocker locker(&m_lock);
159
160 const QByteArray perStageKey = stageKey(type) + inShaderPathKey;
161 auto it = m_metadata.constFind(perStageKey);
162 if (it != m_metadata.cend())
163 return it.value();
164
165 qWarning("No shader metadata stored for key %s", perStageKey.constData());
166 return {};
167}
168
170{
172 QFile file(collectionFilePath);
173 if (file.exists()) {
175 if (qsbc.map(QQsbIODeviceCollection::Read))
176 m_preGeneratedShaderEntries = qsbc.availableEntries();
177 qsbc.unmap();
178 }
179}
180
186
188{
190#define COMPARE_PROP(x) \
191 if (props.x.getValue(key1) < props.x.getValue(key2)) return true;
192
193 COMPARE_PROP(m_hasLighting)
194 COMPARE_PROP(m_hasIbl)
195 COMPARE_PROP(m_specularEnabled)
196 COMPARE_PROP(m_fresnelEnabled)
197 COMPARE_PROP(m_fresnelScaleBiasEnabled)
198 COMPARE_PROP(m_clearcoatFresnelScaleBiasEnabled)
199 COMPARE_PROP(m_baseColorSingleChannelEnabled)
200 COMPARE_PROP(m_specularSingleChannelEnabled)
201 COMPARE_PROP(m_emissiveSingleChannelEnabled)
202 COMPARE_PROP(m_invertOpacityMapValue)
203 COMPARE_PROP(m_vertexColorsEnabled)
204 COMPARE_PROP(m_vertexColorsMaskEnabled)
205 COMPARE_PROP(m_vertexColorRedMask)
206 COMPARE_PROP(m_vertexColorGreenMask)
207 COMPARE_PROP(m_vertexColorBlueMask)
208 COMPARE_PROP(m_vertexColorAlphaMask)
209 COMPARE_PROP(m_specularModel)
210 COMPARE_PROP(m_vertexAttributes)
211 COMPARE_PROP(m_alphaMode)
212
214 COMPARE_PROP(m_imageMaps[i])
215 }
217 COMPARE_PROP(m_textureChannels[i])
218 }
219 COMPARE_PROP(m_lightCount)
221 int lp1 = calcLightPoint(key1, i);
222 int lp2 = calcLightPoint(key2, i);
223 if (lp1 < lp2)
224 return true;
225 }
226#undef COMPARE_PROP
227 return false;
228}
229
\inmodule QtCore
Definition qbytearray.h:57
\inmodule QtCore
Definition qfile.h:93
bool exists() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qfile.cpp:351
const_iterator constFind(const Key &key) const noexcept
Definition qhash.h:1299
iterator find(const Key &key)
Returns an iterator pointing to the item with the key in the hash.
Definition qhash.h:1291
iterator end() noexcept
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the last ...
Definition qhash.h:1216
const_iterator cend() const noexcept
Definition qhash.h:1218
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition qhash.h:1303
\inmodule QtCore
static QByteArray shaderCollectionFile()
static QByteArray resourceFolder()
QSSGCustomShaderMetaData getShaderMetaData(const QByteArray &inShaderPathKey, QSSGShaderCache::ShaderType type)
void setShaderSource(const QByteArray &inShaderPathKey, QSSGShaderCache::ShaderType type, const QByteArray &inSource, const QSSGCustomShaderMetaData &meta)
QByteArray getShaderSource(const QByteArray &inShaderPathKey, QSSGShaderCache::ShaderType type)
static bool compare(const QSSGShaderDefaultMaterialKey &key1, const QSSGShaderDefaultMaterialKey &key2)
QHash< QByteArray, QSSGCustomShaderMetaData > m_metadata
QByteArray getIncludeContents(const QByteArray &inShaderPathKey)
void resolveIncludeFiles(QByteArray &theReadBuffer, const QByteArray &inMaterialInfoString)
QQsbCollection::EntryMap m_preGeneratedShaderEntries
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5871
static QString fromLocal8Bit(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5949
\inmodule QtCore
\inmodule QtCore
QSet< QString >::iterator it
Combined button and popup list for selecting options.
#define QByteArrayLiteral(str)
Definition qbytearray.h:52
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
EGLStreamKHR stream
#define qWarning
Definition qlogging.h:166
#define qCCritical(category,...)
GLuint64 key
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum type
GLenum GLuint GLsizei const GLenum * props
GLuint64EXT GLuint GLuint GLenum GLenum GLuint GLuint GLenum GLuint GLuint key1
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
static QByteArray copyrightHeaderStart()
#define COMPARE_PROP(x)
static int calcLightPoint(const QSSGShaderDefaultMaterialKey &key, int i)
static QByteArray includeSearch()
static QByteArray copyrightHeaderEnd()
static char stageKey(QSSGShaderCache::ShaderType type)
#define qPrintable(string)
Definition qstring.h:1531
#define QStringLiteral(str)
long long qint64
Definition qtypes.h:60
QFile file
[0]
\inmodule QtCore \reentrant
Definition qchar.h:18
static QSharedPointer< QIODevice > getStreamForFile(const QString &inPath, bool inQuiet=false, QString *outPath=nullptr)
QSSGShaderKeyBoolean m_lightSpotFlags[LightCount]
QSSGShaderKeyBoolean m_lightAreaFlags[LightCount]
QSSGShaderKeyBoolean m_lightFlags[LightCount]
QSSGShaderKeyBoolean m_lightShadowFlags[LightCount]
bool getValue(QSSGDataView< quint32 > inDataStore) const