65 int jsonStart = 0, jsonEnd = 0;
74 if (jsonStart <= 0 || jsonEnd <= 0)
77 const int size = jsonEnd - jsonStart;
80 qWarning(
"Shader metadata section found, but content to small to be valid!");
84 QByteArray jsonData = data.mid(jsonStart, size).trimmed();
85 if (!jsonData.startsWith(QByteArrayLiteral(
"/*{"))) {
86 qWarning(
"Missing /*{ prefix");
89 if (!jsonData.endsWith(QByteArrayLiteral(
"}*/"))) {
90 qWarning(
"Missing }*/ suffix");
93 jsonData = jsonData.mid(2, jsonData.size() - 4);
95 QJsonParseError error;
96 const auto doc = QJsonDocument::fromJson(jsonData, &error);
97 if (error.error != QJsonParseError::NoError) {
98 qWarning() <<
"Shader metadata parse error at offset: " << error.offset;
102 static const auto toUniform = [](
const QJsonObject &uObj) {
104 auto it = uObj.constBegin();
105 const auto end = uObj.constEnd();
107 it = uObj.constFind(QLatin1String(
"type"));
108 uniform.type = (it != end) ? it->toString().toLatin1() : QByteArray();
109 it = uObj.constFind(QLatin1String(
"name"));
110 uniform.name = (it != end) ? it->toString().toLatin1() : QByteArray();
111 it = uObj.constFind(QLatin1String(
"multiview_dependent"));
112 uniform
.multiview = (it != end) ? it->toBool() :
false;
114 it = uObj.constFind(QLatin1String(
"condition"));
115 const QString conditionString = (it != end) ? it->toString() : QString();
116 uniform.condition = Uniform::conditionFromString(conditionString);
118 uniform.conditionName = conditionString.mid(1).toLatin1();
120 uniform.conditionName = conditionString.toLatin1();
125 static const auto toImage = [](
const QJsonObject &uObj,
const Uniform &uniform)
128 auto it = uObj.constBegin();
129 const auto end = uObj.constEnd();
131 it = uObj.constFind(QLatin1String(
"imgtype"));
132 img.imageType = (it != end) ? it->toString().toLatin1() : QByteArray();
133 it = uObj.constFind(QLatin1String(
"qualifiers"));
134 img.qualifiers = (it != end) ? it->toString().toLatin1() : QByteArray();
139 static const auto toInputOutput = [](
const QJsonObject &uObj) {
141 auto it = uObj.constBegin();
142 const auto end = uObj.constEnd();
144 it = uObj.constFind(QLatin1String(
"type"));
145 inOutVar.type = (it != end) ? it->toString().toLatin1() : QByteArray();
146 it = uObj.constFind(QLatin1String(
"name"));
147 inOutVar.name = (it != end) ? it->toString().toLatin1() : QByteArray();
148 it = uObj.constFind(QLatin1String(
"stage"));
149 inOutVar.stage = InputOutput::stageFromString((it != end) ? it->toString() : QString());
150 it = uObj.constFind(QLatin1String(
"flat"));
151 inOutVar
.flat = (it != end) ? it->toBool() :
false;
156 const QJsonObject obj = doc.object();
157 auto it = obj.constBegin();
158 const auto end = obj.constEnd();
161 it = obj.constFind(QLatin1String(
"uniforms"));
162 if (it != obj.constEnd()) {
164 if (it->type() == QJsonValue::Array) {
165 const auto uniformArray = it->toArray();
166 for (
const auto valueRef : uniformArray) {
167 if (!valueRef.isObject())
170 const QJsonObject obj = valueRef.toObject();
171 const auto uniform = toUniform(obj);
172 if (!uniform.type.isEmpty() && !uniform.name.isEmpty()) {
173 if (obj.constFind(QLatin1String(
"imgtype")) != obj.constEnd())
174 result.images.push_back(toImage(obj, uniform));
176 result.uniforms.push_back(uniform);
178 qWarning(
"Invalid uniform, skipping");
181 }
else if (it->type() == QJsonValue::Object) {
182 const auto uniform = toUniform(it->toObject());
183 if (!uniform.type.isEmpty() && !uniform.name.isEmpty()) {
184 if (obj.constFind(QLatin1String(
"imgtype")) != obj.constEnd())
185 result.images.push_back(toImage(obj, uniform));
187 result.uniforms.push_back(uniform);
189 qWarning(
"Invalid uniform, skipping");
195 it = obj.constFind(QLatin1String(
"inputs"));
197 if (it->type() == QJsonValue::Array) {
198 for (
const auto valueRef : it->toArray()) {
199 if (!valueRef.isObject())
201 const auto inOutVar = toInputOutput(valueRef.toObject());
202 if (!inOutVar.type.isEmpty() && !inOutVar.name.isEmpty())
203 result.inputs.push_back(inOutVar);
205 qWarning(
"Invalid input variable, skipping");
207 }
else if (it->type() == QJsonValue::Object) {
208 const QJsonObject obj = it->toObject();
209 const auto inOutVar = toInputOutput(obj);
210 if (!inOutVar.type.isEmpty() && !inOutVar.name.isEmpty()) {
211 result.inputs.push_back(inOutVar);
213 qWarning(
"Invalid input variable, skipping");
219 it = obj.constFind(QLatin1String(
"outputs"));
221 if (it->type() == QJsonValue::Array) {
222 for (
const auto valueRef : it->toArray()) {
223 if (!valueRef.isObject())
225 const auto inOutVar = toInputOutput(valueRef.toObject());
226 if (!inOutVar.type.isEmpty() && !inOutVar.name.isEmpty())
227 result.outputs.push_back(inOutVar);
229 qWarning(
"Invalid output variable, skipping");
231 }
else if (it->type() == QJsonValue::Object) {
232 const QJsonObject inputJObj = it->toObject();
233 const auto inOutVar = toInputOutput(inputJObj);
234 if (!inOutVar.type.isEmpty() && !inOutVar.name.isEmpty()) {
235 result.outputs.push_back(inOutVar);
237 qWarning(
"Invalid output variable, skipping");