/**************************************************************************** ** ** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB). ** Copyright (C) 2016 Paul Lemire ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt3D module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see http://www.qt.io/terms-conditions. For further ** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 3 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPLv3 included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 3 requirements ** will be met: https://www.gnu.org/licenses/lgpl.html. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 2.0 or later as published by the Free ** Software Foundation and appearing in the file LICENSE.GPL included in ** the packaging of this file. Please review the following information to ** ensure the GNU General Public License version 2.0 requirements will be ** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "commandexecuter_p.h" #include #include #include #include #include #include #include #include #include #include #include #include #include QT_BEGIN_NAMESPACE namespace Qt3DRender { namespace Debug { namespace { template QJsonObject typeToJsonObj(const Type &) noexcept { return QJsonObject(); } template QJsonValue typeToJsonValue(const Type &t) noexcept { Q_UNUSED(t); return QJsonValue(); } template<> QJsonObject typeToJsonObj(const QRectF &rect) noexcept { QJsonObject obj; obj.insert(QLatin1String("x"), rect.x()); obj.insert(QLatin1String("y"), rect.y()); obj.insert(QLatin1String("width"), rect.width()); obj.insert(QLatin1String("height"), rect.height()); return obj; } template<> QJsonValue typeToJsonValue(const QRectF &rect) noexcept { QJsonArray value; value.push_back(rect.x()); value.push_back(rect.y()); value.push_back(rect.width()); value.push_back(rect.height()); return value; } template<> QJsonObject typeToJsonObj(const QSize &s) noexcept { QJsonObject obj; obj.insert(QLatin1String("width"), s.width()); obj.insert(QLatin1String("height"), s.height()); return obj; } template<> QJsonValue typeToJsonValue(const QSize &s) noexcept { QJsonArray value; value.push_back(s.width()); value.push_back(s.height()); return value; } template<> QJsonObject typeToJsonObj(const QVector3D &v) noexcept { QJsonObject obj; obj.insert(QLatin1String("x"), v.x()); obj.insert(QLatin1String("y"), v.y()); obj.insert(QLatin1String("z"), v.z()); return obj; } template<> QJsonValue typeToJsonValue(const QVector3D &v) noexcept { QJsonArray value; value.push_back(v.x()); value.push_back(v.y()); value.push_back(v.z()); return value; } template<> QJsonObject typeToJsonObj(const Qt3DCore::QNodeId &v) noexcept { QJsonObject obj; obj.insert(QLatin1String("id"), qint64(v.id())); return obj; } template<> QJsonValue typeToJsonValue(const Qt3DCore::QNodeId &v) noexcept { QJsonValue value(qint64(v.id())); return value; } template<> QJsonObject typeToJsonObj(const QVector4D &v) noexcept { QJsonObject obj; obj.insert(QLatin1String("x"), v.x()); obj.insert(QLatin1String("y"), v.y()); obj.insert(QLatin1String("z"), v.z()); obj.insert(QLatin1String("w"), v.w()); return obj; } template<> QJsonValue typeToJsonValue(const QVector4D &v) noexcept { QJsonArray value; value.push_back(v.x()); value.push_back(v.y()); value.push_back(v.z()); value.push_back(v.w()); return value; } template<> QJsonObject typeToJsonObj(const QMatrix4x4 &v) noexcept { QJsonObject obj; obj.insert(QLatin1String("row 0"), typeToJsonObj(v.row(0))); obj.insert(QLatin1String("row 1"), typeToJsonObj(v.row(0))); obj.insert(QLatin1String("row 2"), typeToJsonObj(v.row(0))); obj.insert(QLatin1String("row 3"), typeToJsonObj(v.row(0))); return obj; } template<> QJsonValue typeToJsonValue(const QMatrix4x4 &v) noexcept { QJsonArray value; value.push_back(typeToJsonValue(v.row(0))); value.push_back(typeToJsonValue(v.row(1))); value.push_back(typeToJsonValue(v.row(2))); value.push_back(typeToJsonValue(v.row(3))); return value; } template<> QJsonValue typeToJsonValue(const QVariant &v) noexcept { const int nodeTypeId = qMetaTypeId(); if (v.userType() == nodeTypeId) return typeToJsonValue(v.value()); switch (v.userType()) { case QMetaType::QVector3D: return typeToJsonValue(v.value()); case QMetaType::QVector4D: return typeToJsonValue(v.value()); case QMetaType::QMatrix4x4: return typeToJsonValue(v.value()); default: return QJsonValue::fromVariant(v); } } template QJsonObject backendNodeToJSon(Handle handle, Manager *manager) noexcept { Qt3DCore::QBackendNode *node = manager->data(handle); QJsonObject obj; Qt3DCore::QNodeId id; if (node != nullptr) id = node->peerId(); obj.insert(QLatin1String("id"), qint64(id.id())); return obj; } QJsonObject parameterPackToJson(const Render::Rhi::ShaderParameterPack &pack) noexcept { QJsonObject obj; const Render::Rhi::PackUniformHash &uniforms = pack.uniforms(); QJsonArray uniformsArray; for (int i = 0, m = uniforms.keys.size(); i < m; ++i) { QJsonObject uniformObj; uniformObj.insert(QLatin1String("name"), Render::StringToInt::lookupString(uniforms.keys.at(i))); const Render::UniformValue::ValueType type = uniforms.values.at(i).valueType(); uniformObj.insert(QLatin1String("type"), type == Render::UniformValue::ScalarValue ? QLatin1String("value") : QLatin1String("texture")); uniformsArray.push_back(uniformObj); } obj.insert(QLatin1String("uniforms"), uniformsArray); QJsonArray texturesArray; const QVector &textures = pack.textures(); for (const auto &texture : textures) { QJsonObject textureObj; textureObj.insert(QLatin1String("name"), Render::StringToInt::lookupString(texture.glslNameId)); textureObj.insert(QLatin1String("id"), qint64(texture.nodeId.id())); texturesArray.push_back(textureObj); } obj.insert(QLatin1String("textures"), texturesArray); const QVector &ubos = pack.uniformBuffers(); QJsonArray ubosArray; for (const auto &ubo : ubos) { QJsonObject uboObj; uboObj.insert(QLatin1String("index"), ubo.m_blockIndex); uboObj.insert(QLatin1String("bufferId"), qint64(ubo.m_bufferID.id())); ubosArray.push_back(uboObj); } obj.insert(QLatin1String("ubos"), ubosArray); const QVector &ssbos = pack.shaderStorageBuffers(); QJsonArray ssbosArray; for (const auto &ssbo : ssbos) { QJsonObject ssboObj; ssboObj.insert(QLatin1String("index"), ssbo.m_blockIndex); ssboObj.insert(QLatin1String("bufferId"), qint64(ssbo.m_bufferID.id())); ssbosArray.push_back(ssboObj); } obj.insert(QLatin1String("ssbos"), ssbosArray); return obj; } } // anonymous CommandExecuter::CommandExecuter(Render::Rhi::Renderer *renderer) : m_renderer(renderer) { } // Render thread void CommandExecuter::performAsynchronousCommandExecution( const QVector &views) { RHI_UNIMPLEMENTED; //* QMutexLocker lock(&m_pendingCommandsMutex); //* const QVector shellCommands = //std::move(m_pendingCommands); //* lock.unlock(); //* //* for (auto *reply : shellCommands) { //* if (reply->commandName() == QLatin1String("glinfo")) { //* QJsonObject replyObj; //* const GraphicsApiFilterData *contextInfo = //m_renderer->submissionContext()->contextInfo(); //* if (contextInfo != nullptr) { //* replyObj.insert(QLatin1String("api"), //* contextInfo->m_api == QGraphicsApiFilter::OpenGL //* ? QLatin1String("OpenGL") //* : QLatin1String("OpenGLES")); //* const QString versionString = //* QString::number(contextInfo->m_major) //* + QStringLiteral(".") //* + QString::number(contextInfo->m_minor); //* replyObj.insert(QLatin1String("version"), versionString); //* replyObj.insert(QLatin1String("profile"), //* contextInfo->m_profile == QGraphicsApiFilter::CoreProfile //* ? QLatin1String("Core") //* : contextInfo->m_profile == //QGraphicsApiFilter::CompatibilityProfile //* ? QLatin1String("Compatibility") //* : QLatin1String("None")); //* } //* reply->setData(QJsonDocument(replyObj).toJson()); //* } else if (reply->commandName() == QLatin1String("rendercommands")) { //* QJsonObject replyObj; //* //* QJsonArray viewArray; //* for (Render::Rhi::RenderView *v : views) { //* QJsonObject viewObj; //* viewObj.insert(QLatin1String("viewport"), typeToJsonValue(v->viewport())); //* viewObj.insert(QLatin1String("surfaceSize"), //typeToJsonValue(v->surfaceSize())); //* viewObj.insert(QLatin1String("devicePixelRatio"), v->devicePixelRatio()); //* viewObj.insert(QLatin1String("noDraw"), v->noDraw()); //* viewObj.insert(QLatin1String("frustumCulling"), v->frustumCulling()); //* viewObj.insert(QLatin1String("compute"), v->isCompute()); //* viewObj.insert(QLatin1String("clearDepthValue"), v->clearDepthValue()); //* viewObj.insert(QLatin1String("clearStencilValue"), v->clearStencilValue()); //* //* QJsonArray renderCommandsArray; //* for (Render::Rhi::RenderCommand &c : v->commands()) { //* QJsonObject commandObj; //* Render::NodeManagers *nodeManagers = m_renderer->nodeManagers(); //* commandObj.insert(QLatin1String("shader"), //typeToJsonValue(QVariant::fromValue(c.m_shaderId))); //* commandObj.insert(QLatin1String("vao"), double(c.m_vao.handle())); //* commandObj.insert(QLatin1String("instanceCount"), c.m_instanceCount); //* commandObj.insert(QLatin1String("geometry"), //backendNodeToJSon(c.m_geometry, nodeManagers->geometryManager())); //* commandObj.insert(QLatin1String("geometryRenderer"), //backendNodeToJSon(c.m_geometryRenderer, nodeManagers->geometryRendererManager())); //* commandObj.insert(QLatin1String("shaderParameterPack"), //parameterPackToJson(c.m_parameterPack)); //* //* renderCommandsArray.push_back(commandObj); //* } //* viewObj.insert(QLatin1String("commands"), renderCommandsArray); //* viewArray.push_back(viewObj); //* } //* //* replyObj.insert(QLatin1String("renderViews"), viewArray); //* reply->setData(QJsonDocument(replyObj).toJson()); //* } //* reply->setFinished(true); //* } } // Main thread QVariant CommandExecuter::executeCommand(const QStringList &args) { RHI_UNIMPLEMENTED; //* // Note: The replies will be deleted by the AspectCommandDebugger //* if (args.length() > 0 && //* (args.first() == QLatin1String("glinfo") || //* args.first() == QLatin1String("rendercommands"))) { //* auto reply = new Qt3DCore::Debug::AsynchronousCommandReply(args.first()); //* QMutexLocker lock(&m_pendingCommandsMutex); //* m_pendingCommands.push_back(reply); //* return QVariant::fromValue(reply); //* } return QVariant(); } } // Debug } // Qt3DRenderer QT_END_NAMESPACE