1// Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB).
2// Copyright (C) 2016 Paul Lemire <paul.lemire350@gmail.com>
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#include "commandexecuter_p.h"
6
7#include <Qt3DCore/private/qabstractaspect_p.h>
8#include <Qt3DCore/qbackendnode.h>
9#include <Qt3DRender/private/nodemanagers_p.h>
10#include <Qt3DRender/private/geometryrenderermanager_p.h>
11#include <Qt3DRender/private/stringtoint_p.h>
12#include <QJsonObject>
13#include <QJsonDocument>
14#include <QJsonArray>
15#include <submissioncontext_p.h>
16#include <renderview_p.h>
17#include <rendercommand_p.h>
18#include <renderer_p.h>
19#include <submissioncontext_p.h>
20
21QT_BEGIN_NAMESPACE
22
23namespace Qt3DRender {
24
25namespace DebugRhi {
26
27namespace {
28
29#if 0 // unused for now
30
31template<typename Type>
32QJsonObject typeToJsonObj(const Type &) noexcept
33{
34 return QJsonObject();
35}
36
37template<typename Type>
38QJsonValue typeToJsonValue(const Type &t) noexcept
39{
40 Q_UNUSED(t);
41 return QJsonValue();
42}
43
44template<>
45QJsonObject typeToJsonObj<QRectF>(const QRectF &rect) noexcept
46{
47 QJsonObject obj;
48
49 obj.insert(QLatin1String("x"), rect.x());
50 obj.insert(QLatin1String("y"), rect.y());
51 obj.insert(QLatin1String("width"), rect.width());
52 obj.insert(QLatin1String("height"), rect.height());
53
54 return obj;
55}
56
57template<>
58QJsonValue typeToJsonValue<QRectF>(const QRectF &rect) noexcept
59{
60 QJsonArray value;
61
62 value.push_back(rect.x());
63 value.push_back(rect.y());
64 value.push_back(rect.width());
65 value.push_back(rect.height());
66
67 return value;
68}
69
70template<>
71QJsonObject typeToJsonObj<QSize>(const QSize &s) noexcept
72{
73 QJsonObject obj;
74
75 obj.insert(QLatin1String("width"), s.width());
76 obj.insert(QLatin1String("height"), s.height());
77
78 return obj;
79}
80
81template<>
82QJsonValue typeToJsonValue<QSize>(const QSize &s) noexcept
83{
84 QJsonArray value;
85
86 value.push_back(s.width());
87 value.push_back(s.height());
88
89 return value;
90}
91
92template<>
93QJsonObject typeToJsonObj<QVector3D>(const QVector3D &v) noexcept
94{
95 QJsonObject obj;
96
97 obj.insert(QLatin1String("x"), v.x());
98 obj.insert(QLatin1String("y"), v.y());
99 obj.insert(QLatin1String("z"), v.z());
100
101 return obj;
102}
103
104template<>
105QJsonValue typeToJsonValue<QVector3D>(const QVector3D &v) noexcept
106{
107 QJsonArray value;
108
109 value.push_back(v.x());
110 value.push_back(v.y());
111 value.push_back(v.z());
112
113 return value;
114}
115
116template<>
117QJsonObject typeToJsonObj<Qt3DCore::QNodeId>(const Qt3DCore::QNodeId &v) noexcept
118{
119 QJsonObject obj;
120 obj.insert(QLatin1String("id"), qint64(v.id()));
121 return obj;
122}
123
124template<>
125QJsonValue typeToJsonValue<Qt3DCore::QNodeId>(const Qt3DCore::QNodeId &v) noexcept
126{
127 QJsonValue value(qint64(v.id()));
128 return value;
129}
130
131template<>
132QJsonObject typeToJsonObj<QVector4D>(const QVector4D &v) noexcept
133{
134 QJsonObject obj;
135
136 obj.insert(QLatin1String("x"), v.x());
137 obj.insert(QLatin1String("y"), v.y());
138 obj.insert(QLatin1String("z"), v.z());
139 obj.insert(QLatin1String("w"), v.w());
140
141 return obj;
142}
143
144template<>
145QJsonValue typeToJsonValue<QVector4D>(const QVector4D &v) noexcept
146{
147 QJsonArray value;
148
149 value.push_back(v.x());
150 value.push_back(v.y());
151 value.push_back(v.z());
152 value.push_back(v.w());
153
154 return value;
155}
156
157template<>
158QJsonObject typeToJsonObj<QMatrix4x4>(const QMatrix4x4 &v) noexcept
159{
160 QJsonObject obj;
161
162 obj.insert(QLatin1String("row 0"), typeToJsonObj(v.row(0)));
163 obj.insert(QLatin1String("row 1"), typeToJsonObj(v.row(0)));
164 obj.insert(QLatin1String("row 2"), typeToJsonObj(v.row(0)));
165 obj.insert(QLatin1String("row 3"), typeToJsonObj(v.row(0)));
166
167 return obj;
168}
169
170template<>
171QJsonValue typeToJsonValue<QMatrix4x4>(const QMatrix4x4 &v) noexcept
172{
173 QJsonArray value;
174
175 value.push_back(typeToJsonValue(v.row(0)));
176 value.push_back(typeToJsonValue(v.row(1)));
177 value.push_back(typeToJsonValue(v.row(2)));
178 value.push_back(typeToJsonValue(v.row(3)));
179
180 return value;
181}
182
183template<>
184QJsonValue typeToJsonValue<QVariant>(const QVariant &v) noexcept
185{
186 const int nodeTypeId = qMetaTypeId<Qt3DCore::QNodeId>();
187
188 if (v.userType() == nodeTypeId)
189 return typeToJsonValue(v.value<Qt3DCore::QNodeId>());
190
191 switch (v.userType()) {
192 case QMetaType::QVector3D:
193 return typeToJsonValue(v.value<QVector3D>());
194 case QMetaType::QVector4D:
195 return typeToJsonValue(v.value<QVector4D>());
196 case QMetaType::QMatrix4x4:
197 return typeToJsonValue(v.value<QMatrix4x4>());
198 default:
199 return QJsonValue::fromVariant(v);
200 }
201}
202
203template<typename Handle, typename Manager>
204QJsonObject backendNodeToJSon(Handle handle, Manager *manager) noexcept
205{
206 Qt3DCore::QBackendNode *node = manager->data(handle);
207 QJsonObject obj;
208 Qt3DCore::QNodeId id;
209 if (node != nullptr)
210 id = node->peerId();
211 obj.insert(QLatin1String("id"), qint64(id.id()));
212 return obj;
213}
214
215QJsonObject parameterPackToJson(const Render::Rhi::ShaderParameterPack &pack) noexcept
216{
217 QJsonObject obj;
218
219 const Render::Rhi::PackUniformHash &uniforms = pack.uniforms();
220 QJsonArray uniformsArray;
221 for (qsizetype i = 0, m = uniforms.keys.size(); i < m; ++i) {
222 QJsonObject uniformObj;
223 uniformObj.insert(QLatin1String("name"), Render::StringToInt::lookupString(uniforms.keys.at(i)));
224 const Render::UniformValue::ValueType type = uniforms.values.at(i).valueType();
225 uniformObj.insert(QLatin1String("type"),
226 type == Render::UniformValue::ScalarValue
227 ? QLatin1String("value")
228 : QLatin1String("texture"));
229 uniformsArray.push_back(uniformObj);
230 }
231 obj.insert(QLatin1String("uniforms"), uniformsArray);
232
233 QJsonArray texturesArray;
234 const std::vector<Render::Rhi::ShaderParameterPack::NamedResource> &textures = pack.textures();
235 for (const auto & texture : textures) {
236 QJsonObject textureObj;
237 textureObj.insert(QLatin1String("name"), Render::StringToInt::lookupString(texture.glslNameId));
238 textureObj.insert(QLatin1String("id"), qint64(texture.nodeId.id()));
239 texturesArray.push_back(textureObj);
240 }
241 obj.insert(QLatin1String("textures"), texturesArray);
242
243 const std::vector<Render::Rhi::BlockToUBO> &ubos = pack.uniformBuffers();
244 QJsonArray ubosArray;
245 for (const auto &ubo : ubos) {
246 QJsonObject uboObj;
247 uboObj.insert(QLatin1String("index"), ubo.m_blockIndex);
248 uboObj.insert(QLatin1String("bufferId"), qint64(ubo.m_bufferID.id()));
249 ubosArray.push_back(uboObj);
250
251 }
252 obj.insert(QLatin1String("ubos"), ubosArray);
253
254 const std::vector<Render::Rhi::BlockToSSBO> &ssbos = pack.shaderStorageBuffers();
255 QJsonArray ssbosArray;
256 for (const auto &ssbo : ssbos) {
257 QJsonObject ssboObj;
258 ssboObj.insert(QLatin1String("index"), ssbo.m_blockIndex);
259 ssboObj.insert(QLatin1String("bufferId"), qint64(ssbo.m_bufferID.id()));
260 ssbosArray.push_back(ssboObj);
261 }
262 obj.insert(QLatin1String("ssbos"), ssbosArray);
263
264 return obj;
265}
266
267#endif // 0
268
269} // anonymous
270
271CommandExecuter::CommandExecuter(Render::Rhi::Renderer *renderer) : m_renderer(renderer) {
272 Q_UNUSED(m_renderer)
273}
274
275// Render thread
276void CommandExecuter::performAsynchronousCommandExecution(
277 const std::vector<Render::Rhi::RenderView *> &views)
278{
279 Q_UNUSED(views);
280 RHI_UNIMPLEMENTED;
281 //* QMutexLocker lock(&m_pendingCommandsMutex);
282 //* const std::vector<Qt3DCore::Debug::AsynchronousCommandReply *> shellCommands =
283 //std::move(m_pendingCommands);
284 //* lock.unlock();
285 //*
286 //* for (auto *reply : shellCommands) {
287 //* if (reply->commandName() == QLatin1String("glinfo")) {
288 //* QJsonObject replyObj;
289 //* const GraphicsApiFilterData *contextInfo =
290 //m_renderer->submissionContext()->contextInfo();
291 //* if (contextInfo != nullptr) {
292 //* replyObj.insert(QLatin1String("api"),
293 //* contextInfo->m_api == QGraphicsApiFilter::OpenGL
294 //* ? QLatin1String("OpenGL")
295 //* : QLatin1String("OpenGLES"));
296 //* const QString versionString =
297 //* QString::number(contextInfo->m_major)
298 //* + QStringLiteral(".")
299 //* + QString::number(contextInfo->m_minor);
300 //* replyObj.insert(QLatin1String("version"), versionString);
301 //* replyObj.insert(QLatin1String("profile"),
302 //* contextInfo->m_profile == QGraphicsApiFilter::CoreProfile
303 //* ? QLatin1String("Core")
304 //* : contextInfo->m_profile ==
305 //QGraphicsApiFilter::CompatibilityProfile
306 //* ? QLatin1String("Compatibility")
307 //* : QLatin1String("None"));
308 //* }
309 //* reply->setData(QJsonDocument(replyObj).toJson());
310 //* } else if (reply->commandName() == QLatin1String("rendercommands")) {
311 //* QJsonObject replyObj;
312 //*
313 //* QJsonArray viewArray;
314 //* for (Render::Rhi::RenderView *v : views) {
315 //* QJsonObject viewObj;
316 //* viewObj.insert(QLatin1String("viewport"), typeToJsonValue(v->viewport()));
317 //* viewObj.insert(QLatin1String("surfaceSize"),
318 //typeToJsonValue(v->surfaceSize()));
319 //* viewObj.insert(QLatin1String("devicePixelRatio"), v->devicePixelRatio());
320 //* viewObj.insert(QLatin1String("noDraw"), v->noDraw());
321 //* viewObj.insert(QLatin1String("frustumCulling"), v->frustumCulling());
322 //* viewObj.insert(QLatin1String("compute"), v->isCompute());
323 //* viewObj.insert(QLatin1String("clearDepthValue"), v->clearDepthValue());
324 //* viewObj.insert(QLatin1String("clearStencilValue"), v->clearStencilValue());
325 //*
326 //* QJsonArray renderCommandsArray;
327 //* for (Render::Rhi::RenderCommand &c : v->commands()) {
328 //* QJsonObject commandObj;
329 //* Render::NodeManagers *nodeManagers = m_renderer->nodeManagers();
330 //* commandObj.insert(QLatin1String("shader"),
331 //typeToJsonValue(QVariant::fromValue(c.m_shaderId)));
332 //* commandObj.insert(QLatin1String("vao"), double(c.m_vao.handle()));
333 //* commandObj.insert(QLatin1String("instanceCount"), c.m_instanceCount);
334 //* commandObj.insert(QLatin1String("geometry"),
335 //backendNodeToJSon(c.m_geometry, nodeManagers->geometryManager()));
336 //* commandObj.insert(QLatin1String("geometryRenderer"),
337 //backendNodeToJSon(c.m_geometryRenderer, nodeManagers->geometryRendererManager()));
338 //* commandObj.insert(QLatin1String("shaderParameterPack"),
339 //parameterPackToJson(c.m_parameterPack));
340 //*
341 //* renderCommandsArray.push_back(commandObj);
342 //* }
343 //* viewObj.insert(QLatin1String("commands"), renderCommandsArray);
344 //* viewArray.push_back(viewObj);
345 //* }
346 //*
347 //* replyObj.insert(QLatin1String("renderViews"), viewArray);
348 //* reply->setData(QJsonDocument(replyObj).toJson());
349 //* }
350 //* reply->setFinished(true);
351 //* }
352}
353
354// Main thread
355QVariant CommandExecuter::executeCommand(const QStringList &args)
356{
357 Q_UNUSED(args);
358 RHI_UNIMPLEMENTED;
359 //* // Note: The replies will be deleted by the AspectCommandDebugger
360 //* if (args.length() > 0 &&
361 //* (args.first() == QLatin1String("glinfo") ||
362 //* args.first() == QLatin1String("rendercommands"))) {
363 //* auto reply = new Qt3DCore::Debug::AsynchronousCommandReply(args.first());
364 //* QMutexLocker lock(&m_pendingCommandsMutex);
365 //* m_pendingCommands.push_back(reply);
366 //* return QVariant::fromValue(reply);
367 //* }
368 return QVariant();
369}
370
371} // DebugRhi
372
373} // Qt3DRenderer
374
375QT_END_NAMESPACE
376

source code of qt3d/src/plugins/renderers/rhi/renderer/commandexecuter.cpp