63 int jsonStart = 0, jsonEnd = 0;
72 if (jsonStart <= 0 || jsonEnd <= 0)
75 const int size = jsonEnd - jsonStart;
78 qWarning(
"Shader metadata section found, but content to small to be valid!");
82 QByteArray jsonData = data.mid(jsonStart, size).trimmed();
83 if (!jsonData.startsWith(QByteArrayLiteral(
"/*{"))) {
84 qWarning(
"Missing /*{ prefix");
87 if (!jsonData.endsWith(QByteArrayLiteral(
"}*/"))) {
88 qWarning(
"Missing }*/ suffix");
91 jsonData = jsonData.mid(2, jsonData.size() - 4);
93 QJsonParseError error;
94 const auto doc = QJsonDocument::fromJson(jsonData, &error);
95 if (error.error != QJsonParseError::NoError) {
96 qWarning() <<
"Shader metadata parse error at offset: " << error.offset;
100 static const auto toUniform = [](
const QJsonObject &uObj) {
102 auto it = uObj.constBegin();
103 const auto end = uObj.constEnd();
105 it = uObj.constFind(QLatin1String(
"type"));
106 uniform.type = (it != end) ? it->toString().toLatin1() : QByteArray();
107 it = uObj.constFind(QLatin1String(
"name"));
108 uniform.name = (it != end) ? it->toString().toLatin1() : QByteArray();
109 it = uObj.constFind(QLatin1String(
"multiview_dependent"));
110 uniform
.multiview = (it != end) ? it->toBool() :
false;
112 it = uObj.constFind(QLatin1String(
"condition"));
113 const QString conditionString = (it != end) ? it->toString() : QString();
114 uniform.condition = Uniform::conditionFromString(conditionString);
116 uniform.conditionName = conditionString.mid(1).toLatin1();
118 uniform.conditionName = conditionString.toLatin1();
123 static const auto toInputOutput = [](
const QJsonObject &uObj) {
125 auto it = uObj.constBegin();
126 const auto end = uObj.constEnd();
128 it = uObj.constFind(QLatin1String(
"type"));
129 inOutVar.type = (it != end) ? it->toString().toLatin1() : QByteArray();
130 it = uObj.constFind(QLatin1String(
"name"));
131 inOutVar.name = (it != end) ? it->toString().toLatin1() : QByteArray();
132 it = uObj.constFind(QLatin1String(
"stage"));
133 inOutVar.stage = InputOutput::stageFromString((it != end) ? it->toString() : QString());
134 it = uObj.constFind(QLatin1String(
"flat"));
135 inOutVar
.flat = (it != end) ? it->toBool() :
false;
140 const QJsonObject obj = doc.object();
141 auto it = obj.constBegin();
142 const auto end = obj.constEnd();
145 it = obj.constFind(QLatin1String(
"uniforms"));
146 if (it != obj.constEnd()) {
148 if (it->type() == QJsonValue::Array) {
149 const auto uniformArray = it->toArray();
150 for (
const auto valueRef : uniformArray) {
151 if (!valueRef.isObject())
154 const QJsonObject obj = valueRef.toObject();
155 const auto uniform = toUniform(obj);
156 if (!uniform.type.isEmpty() && !uniform.name.isEmpty()) {
157 result.uniforms.push_back(uniform);
159 qWarning(
"Invalid uniform, skipping");
162 }
else if (it->type() == QJsonValue::Object) {
163 const auto uniform = toUniform(it->toObject());
164 if (!uniform.type.isEmpty() && !uniform.name.isEmpty())
165 result.uniforms.push_back(uniform);
167 qWarning(
"Invalid uniform, skipping");
172 it = obj.constFind(QLatin1String(
"inputs"));
174 if (it->type() == QJsonValue::Array) {
175 for (
const auto valueRef : it->toArray()) {
176 if (!valueRef.isObject())
178 const auto inOutVar = toInputOutput(valueRef.toObject());
179 if (!inOutVar.type.isEmpty() && !inOutVar.name.isEmpty())
180 result.inputs.push_back(inOutVar);
182 qWarning(
"Invalid input variable, skipping");
184 }
else if (it->type() == QJsonValue::Object) {
185 const QJsonObject obj = it->toObject();
186 const auto inOutVar = toInputOutput(obj);
187 if (!inOutVar.type.isEmpty() && !inOutVar.name.isEmpty()) {
188 result.inputs.push_back(inOutVar);
190 qWarning(
"Invalid input variable, skipping");
196 it = obj.constFind(QLatin1String(
"outputs"));
198 if (it->type() == QJsonValue::Array) {
199 for (
const auto valueRef : it->toArray()) {
200 if (!valueRef.isObject())
202 const auto inOutVar = toInputOutput(valueRef.toObject());
203 if (!inOutVar.type.isEmpty() && !inOutVar.name.isEmpty())
204 result.outputs.push_back(inOutVar);
206 qWarning(
"Invalid output variable, skipping");
208 }
else if (it->type() == QJsonValue::Object) {
209 const QJsonObject inputJObj = it->toObject();
210 const auto inOutVar = toInputOutput(inputJObj);
211 if (!inOutVar.type.isEmpty() && !inOutVar.name.isEmpty()) {
212 result.outputs.push_back(inOutVar);
214 qWarning(
"Invalid output variable, skipping");