blob: cfa6531be8212e1a23335002397069e7273a0f13 [file] [log] [blame]
/****************************************************************************
**
** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB).
** Copyright (C) 2016 Paul Lemire <paul.lemire350@gmail.com>
** 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 <Qt3DCore/private/qabstractaspect_p.h>
#include <Qt3DCore/qbackendnode.h>
#include <Qt3DRender/private/nodemanagers_p.h>
#include <Qt3DRender/private/geometryrenderermanager_p.h>
#include <Qt3DRender/private/stringtoint_p.h>
#include <QJsonObject>
#include <QJsonDocument>
#include <QJsonArray>
#include <submissioncontext_p.h>
#include <renderview_p.h>
#include <rendercommand_p.h>
#include <renderer_p.h>
#include <submissioncontext_p.h>
QT_BEGIN_NAMESPACE
namespace Qt3DRender {
namespace Debug {
namespace {
template<typename Type>
QJsonObject typeToJsonObj(const Type &) noexcept
{
return QJsonObject();
}
template<typename Type>
QJsonValue typeToJsonValue(const Type &t) noexcept
{
Q_UNUSED(t);
return QJsonValue();
}
template<>
QJsonObject typeToJsonObj<QRectF>(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<QRectF>(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<QSize>(const QSize &s) noexcept
{
QJsonObject obj;
obj.insert(QLatin1String("width"), s.width());
obj.insert(QLatin1String("height"), s.height());
return obj;
}
template<>
QJsonValue typeToJsonValue<QSize>(const QSize &s) noexcept
{
QJsonArray value;
value.push_back(s.width());
value.push_back(s.height());
return value;
}
template<>
QJsonObject typeToJsonObj<QVector3D>(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<QVector3D>(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<Qt3DCore::QNodeId>(const Qt3DCore::QNodeId &v) noexcept
{
QJsonObject obj;
obj.insert(QLatin1String("id"), qint64(v.id()));
return obj;
}
template<>
QJsonValue typeToJsonValue<Qt3DCore::QNodeId>(const Qt3DCore::QNodeId &v) noexcept
{
QJsonValue value(qint64(v.id()));
return value;
}
template<>
QJsonObject typeToJsonObj<QVector4D>(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<QVector4D>(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<QMatrix4x4>(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<QMatrix4x4>(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<QVariant>(const QVariant &v) noexcept
{
const int nodeTypeId = qMetaTypeId<Qt3DCore::QNodeId>();
if (v.userType() == nodeTypeId)
return typeToJsonValue(v.value<Qt3DCore::QNodeId>());
switch (v.userType()) {
case QMetaType::QVector3D:
return typeToJsonValue(v.value<QVector3D>());
case QMetaType::QVector4D:
return typeToJsonValue(v.value<QVector4D>());
case QMetaType::QMatrix4x4:
return typeToJsonValue(v.value<QMatrix4x4>());
default:
return QJsonValue::fromVariant(v);
}
}
template<typename Handle, typename Manager>
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<Render::Rhi::ShaderParameterPack::NamedResource> &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<Render::Rhi::BlockToUBO> &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<Render::Rhi::BlockToSSBO> &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<Render::Rhi::RenderView *> &views)
{
RHI_UNIMPLEMENTED;
//* QMutexLocker lock(&m_pendingCommandsMutex);
//* const QVector<Qt3DCore::Debug::AsynchronousCommandReply *> 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