forked from qt-creator/qt-creator
QmlDesigner: Cache graphics pipeline in puppet
Caching the graphics pipeline to disk improves puppet reset speed somewhat when there are complicated 3d scenes. Task-number: QTBUG-103802 Change-Id: I49b4f1031ab79bb5f660578e3d82806675f468dc Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
committed by
Tim Jenssen
parent
d87e420b39
commit
5d8bbe6f5d
@@ -179,6 +179,7 @@ void Qt5InformationNodeInstanceServer::createAuxiliaryQuickView(const QUrl &url,
|
|||||||
#else
|
#else
|
||||||
viewData.renderControl = new QQuickRenderControl;
|
viewData.renderControl = new QQuickRenderControl;
|
||||||
viewData.window = new QQuickWindow(viewData.renderControl);
|
viewData.window = new QQuickWindow(viewData.renderControl);
|
||||||
|
setPipelineCacheConfig(viewData.window);
|
||||||
viewData.renderControl->initialize();
|
viewData.renderControl->initialize();
|
||||||
#endif
|
#endif
|
||||||
QQmlComponent component(engine());
|
QQmlComponent component(engine());
|
||||||
@@ -1130,6 +1131,16 @@ void Qt5InformationNodeInstanceServer::doRender3DEditView()
|
|||||||
m_render3DEditViewTimer.start(17); // 16.67ms = ~60fps, rounds up to 17
|
m_render3DEditViewTimer.start(17); // 16.67ms = ~60fps, rounds up to 17
|
||||||
--m_need3DEditViewRender;
|
--m_need3DEditViewRender;
|
||||||
}
|
}
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 1)
|
||||||
|
else {
|
||||||
|
static bool pipelineSaved = false;
|
||||||
|
if (!pipelineSaved) {
|
||||||
|
// Store pipeline cache for quicker initialization in future
|
||||||
|
savePipelineCacheData();
|
||||||
|
pipelineSaved = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef FPS_COUNTER
|
#ifdef FPS_COUNTER
|
||||||
// Force constant rendering for accurate fps count
|
// Force constant rendering for accurate fps count
|
||||||
|
@@ -41,6 +41,14 @@
|
|||||||
#include <QtQuick/private/qquickitem_p.h>
|
#include <QtQuick/private/qquickitem_p.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 1)
|
||||||
|
#include <QDir>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QQuickGraphicsConfiguration>
|
||||||
|
#include <QStandardPaths>
|
||||||
|
#include <QTimer>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
Qt5NodeInstanceServer::Qt5NodeInstanceServer(NodeInstanceClientInterface *nodeInstanceClient)
|
Qt5NodeInstanceServer::Qt5NodeInstanceServer(NodeInstanceClientInterface *nodeInstanceClient)
|
||||||
@@ -90,6 +98,7 @@ void Qt5NodeInstanceServer::initializeView()
|
|||||||
#else
|
#else
|
||||||
m_viewData.renderControl = new QQuickRenderControl;
|
m_viewData.renderControl = new QQuickRenderControl;
|
||||||
m_viewData.window = new QQuickWindow(m_viewData.renderControl);
|
m_viewData.window = new QQuickWindow(m_viewData.renderControl);
|
||||||
|
setPipelineCacheConfig(m_viewData.window);
|
||||||
m_viewData.renderControl->initialize();
|
m_viewData.renderControl->initialize();
|
||||||
m_qmlEngine = new QQmlEngine;
|
m_qmlEngine = new QQmlEngine;
|
||||||
#endif
|
#endif
|
||||||
@@ -160,6 +169,20 @@ void Qt5NodeInstanceServer::setupScene(const CreateSceneCommand &command)
|
|||||||
|
|
||||||
setupInstances(command);
|
setupInstances(command);
|
||||||
resizeCanvasToRootItem();
|
resizeCanvasToRootItem();
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 1)
|
||||||
|
if (!m_pipelineCacheLocation.isEmpty()) {
|
||||||
|
QString fileId = command.fileUrl.toLocalFile();
|
||||||
|
fileId.remove(':');
|
||||||
|
fileId.remove('/');
|
||||||
|
fileId.remove('.');
|
||||||
|
m_pipelineCacheFile = QStringLiteral("%1/%2").arg(m_pipelineCacheLocation, fileId);
|
||||||
|
|
||||||
|
QFile cacheFile(m_pipelineCacheFile);
|
||||||
|
if (cacheFile.open(QIODevice::ReadOnly))
|
||||||
|
m_pipelineCacheData = cacheFile.readAll();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QQuickItem*> subItems(QQuickItem *parentItem)
|
QList<QQuickItem*> subItems(QQuickItem *parentItem)
|
||||||
@@ -185,7 +208,45 @@ const QList<QQuickItem*> Qt5NodeInstanceServer::allItems() const
|
|||||||
bool Qt5NodeInstanceServer::rootIsRenderable3DObject() const
|
bool Qt5NodeInstanceServer::rootIsRenderable3DObject() const
|
||||||
{
|
{
|
||||||
return rootNodeInstance().isSubclassOf("QQuick3DNode")
|
return rootNodeInstance().isSubclassOf("QQuick3DNode")
|
||||||
|| rootNodeInstance().isSubclassOf("QQuick3DMaterial");
|
|| rootNodeInstance().isSubclassOf("QQuick3DMaterial");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Qt5NodeInstanceServer::savePipelineCacheData()
|
||||||
|
{
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 1)
|
||||||
|
if (!m_viewData.rhi)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const QByteArray pipelineData = m_viewData.rhi->pipelineCacheData();
|
||||||
|
|
||||||
|
if (pipelineData.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_pipelineCacheData = pipelineData;
|
||||||
|
|
||||||
|
QTimer::singleShot(0, this, [this]() {
|
||||||
|
QFile file(m_pipelineCacheFile);
|
||||||
|
if (file.open(QIODevice::WriteOnly | QIODevice::Truncate))
|
||||||
|
file.write(m_pipelineCacheData);
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void Qt5NodeInstanceServer::setPipelineCacheConfig(QQuickWindow *w)
|
||||||
|
{
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 1)
|
||||||
|
// This dummy file is not actually used for cache as we manage cache save/load ourselves,
|
||||||
|
// but some file needs to be set to enable pipeline caching
|
||||||
|
const QString cachePath = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
|
||||||
|
m_pipelineCacheLocation = QStringLiteral("%1/%2").arg(cachePath, "pipecache");
|
||||||
|
QDir(m_pipelineCacheLocation).mkpath(".");
|
||||||
|
const QString dummyCache = m_pipelineCacheLocation + "/dummycache";
|
||||||
|
|
||||||
|
QQuickGraphicsConfiguration config = w->graphicsConfiguration();
|
||||||
|
config.setPipelineCacheSaveFile(dummyCache);
|
||||||
|
config.setAutomaticPipelineCache(false);
|
||||||
|
w->setGraphicsConfiguration(config);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Qt5NodeInstanceServer::initRhi([[maybe_unused]] RenderViewData &viewData)
|
bool Qt5NodeInstanceServer::initRhi([[maybe_unused]] RenderViewData &viewData)
|
||||||
@@ -204,6 +265,10 @@ bool Qt5NodeInstanceServer::initRhi([[maybe_unused]] RenderViewData &viewData)
|
|||||||
qWarning() << __FUNCTION__ << "Rhi is null";
|
qWarning() << __FUNCTION__ << "Rhi is null";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 1)
|
||||||
|
if (!m_pipelineCacheData.isEmpty())
|
||||||
|
viewData.rhi->setPipelineCacheData(m_pipelineCacheData);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cleanRhiResources = [&viewData]() {
|
auto cleanRhiResources = [&viewData]() {
|
||||||
|
@@ -59,6 +59,8 @@ protected:
|
|||||||
void setupScene(const CreateSceneCommand &command) override;
|
void setupScene(const CreateSceneCommand &command) override;
|
||||||
const QList<QQuickItem*> allItems() const;
|
const QList<QQuickItem*> allItems() const;
|
||||||
bool rootIsRenderable3DObject() const;
|
bool rootIsRenderable3DObject() const;
|
||||||
|
void savePipelineCacheData();
|
||||||
|
void setPipelineCacheConfig(QQuickWindow *w);
|
||||||
|
|
||||||
struct RenderViewData {
|
struct RenderViewData {
|
||||||
QPointer<QQuickWindow> window = nullptr;
|
QPointer<QQuickWindow> window = nullptr;
|
||||||
@@ -80,6 +82,9 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
RenderViewData m_viewData;
|
RenderViewData m_viewData;
|
||||||
|
QByteArray m_pipelineCacheData;
|
||||||
|
QString m_pipelineCacheLocation;
|
||||||
|
QString m_pipelineCacheFile;
|
||||||
std::unique_ptr<QQuickDesignerSupport> m_designerSupport;
|
std::unique_ptr<QQuickDesignerSupport> m_designerSupport;
|
||||||
QQmlEngine *m_qmlEngine = nullptr;
|
QQmlEngine *m_qmlEngine = nullptr;
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user