forked from qt-creator/qt-creator
QmlDesigner: Enable shader caching in puppet
When shaders are cached in addition to pipeline caching, further speedup of another 20% or so is achieved on resetting puppets in complex 3D projects. Task-number: QTBUG-103802 Change-Id: I55c950b14c7d854ca3b4de40558ecd26889aa134 Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io> Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
@@ -47,6 +47,13 @@
|
|||||||
#include <QQuickGraphicsConfiguration>
|
#include <QQuickGraphicsConfiguration>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
#define USE_PIPELINE_CACHE 1
|
||||||
|
|
||||||
|
#if defined(QUICK3D_MODULE) && QT_VERSION >= QT_VERSION_CHECK(6, 5, 2)
|
||||||
|
#include <QtQuick3DRuntimeRender/private/qssgrendercontextcore_p.h>
|
||||||
|
#include <QtQuick3D/private/qquick3dscenemanager_p.h>
|
||||||
|
#define USE_SHADER_CACHE 1
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
@@ -170,7 +177,7 @@ void Qt5NodeInstanceServer::setupScene(const CreateSceneCommand &command)
|
|||||||
setupInstances(command);
|
setupInstances(command);
|
||||||
resizeCanvasToRootItem();
|
resizeCanvasToRootItem();
|
||||||
|
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 1)
|
#ifdef USE_PIPELINE_CACHE
|
||||||
if (!m_pipelineCacheLocation.isEmpty()) {
|
if (!m_pipelineCacheLocation.isEmpty()) {
|
||||||
QString fileId = command.fileUrl.toLocalFile();
|
QString fileId = command.fileUrl.toLocalFile();
|
||||||
fileId.remove(':');
|
fileId.remove(':');
|
||||||
@@ -181,6 +188,10 @@ void Qt5NodeInstanceServer::setupScene(const CreateSceneCommand &command)
|
|||||||
QFile cacheFile(m_pipelineCacheFile);
|
QFile cacheFile(m_pipelineCacheFile);
|
||||||
if (cacheFile.open(QIODevice::ReadOnly))
|
if (cacheFile.open(QIODevice::ReadOnly))
|
||||||
m_pipelineCacheData = cacheFile.readAll();
|
m_pipelineCacheData = cacheFile.readAll();
|
||||||
|
|
||||||
|
#ifdef USE_SHADER_CACHE
|
||||||
|
m_shaderCacheFile = m_pipelineCacheFile + ".qsbc";
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -213,7 +224,7 @@ bool Qt5NodeInstanceServer::rootIsRenderable3DObject() const
|
|||||||
|
|
||||||
void Qt5NodeInstanceServer::savePipelineCacheData()
|
void Qt5NodeInstanceServer::savePipelineCacheData()
|
||||||
{
|
{
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 1)
|
#ifdef USE_PIPELINE_CACHE
|
||||||
if (!m_viewData.rhi)
|
if (!m_viewData.rhi)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -239,10 +250,24 @@ void Qt5NodeInstanceServer::savePipelineCacheData()
|
|||||||
// Cache file can grow indefinitely, so let's just purge it every so often.
|
// Cache file can grow indefinitely, so let's just purge it every so often.
|
||||||
// The count is stored as the last char in the data.
|
// The count is stored as the last char in the data.
|
||||||
char count = m_pipelineCacheData[m_pipelineCacheData.size() - 1];
|
char count = m_pipelineCacheData[m_pipelineCacheData.size() - 1];
|
||||||
if (count > 25)
|
const char maxCount = 25;
|
||||||
|
if (count > maxCount)
|
||||||
cacheFile.remove();
|
cacheFile.remove();
|
||||||
else if (cacheFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
|
else if (cacheFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
|
||||||
cacheFile.write(m_pipelineCacheData);
|
cacheFile.write(m_pipelineCacheData);
|
||||||
|
|
||||||
|
#ifdef USE_SHADER_CACHE
|
||||||
|
auto wa = QQuick3DSceneManager::getOrSetWindowAttachment(*m_viewData.window);
|
||||||
|
auto context = wa ? wa->rci().get() : nullptr;
|
||||||
|
if (context && context->shaderCache()) {
|
||||||
|
if (count > maxCount) {
|
||||||
|
QFile shaderCacheFile(m_shaderCacheFile);
|
||||||
|
shaderCacheFile.remove();
|
||||||
|
} else {
|
||||||
|
context->shaderCache()->persistentShaderBakingCache().save(m_shaderCacheFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -250,7 +275,7 @@ void Qt5NodeInstanceServer::savePipelineCacheData()
|
|||||||
|
|
||||||
void Qt5NodeInstanceServer::setPipelineCacheConfig([[maybe_unused]] QQuickWindow *w)
|
void Qt5NodeInstanceServer::setPipelineCacheConfig([[maybe_unused]] QQuickWindow *w)
|
||||||
{
|
{
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 1)
|
#ifdef USE_PIPELINE_CACHE
|
||||||
// This dummy file is not actually used for cache as we manage cache save/load ourselves,
|
// 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
|
// but some file needs to be set to enable pipeline caching
|
||||||
const QString cachePath = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
|
const QString cachePath = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
|
||||||
@@ -262,6 +287,23 @@ void Qt5NodeInstanceServer::setPipelineCacheConfig([[maybe_unused]] QQuickWindow
|
|||||||
config.setPipelineCacheSaveFile(dummyCache);
|
config.setPipelineCacheSaveFile(dummyCache);
|
||||||
config.setAutomaticPipelineCache(false);
|
config.setAutomaticPipelineCache(false);
|
||||||
w->setGraphicsConfiguration(config);
|
w->setGraphicsConfiguration(config);
|
||||||
|
|
||||||
|
#ifdef USE_SHADER_CACHE
|
||||||
|
QtQuick3DEditorHelpers::ShaderCache::setAutomaticDiskCache(false);
|
||||||
|
auto wa = QQuick3DSceneManager::getOrSetWindowAttachment(*w);
|
||||||
|
connect(wa, &QQuick3DWindowAttachment::renderContextInterfaceChanged,
|
||||||
|
this, &Qt5NodeInstanceServer::handleRciSet);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void Qt5NodeInstanceServer::handleRciSet()
|
||||||
|
{
|
||||||
|
#ifdef USE_SHADER_CACHE
|
||||||
|
auto wa = qobject_cast<QQuick3DWindowAttachment *>(sender());
|
||||||
|
auto context = wa ? wa->rci().get() : nullptr;
|
||||||
|
if (context && context->shaderCache())
|
||||||
|
context->shaderCache()->persistentShaderBakingCache().load(m_shaderCacheFile);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,7 +323,7 @@ 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)
|
#ifdef USE_PIPELINE_CACHE
|
||||||
if (!m_pipelineCacheData.isEmpty())
|
if (!m_pipelineCacheData.isEmpty())
|
||||||
viewData.rhi->setPipelineCacheData(m_pipelineCacheData.left(m_pipelineCacheData.size() - 1));
|
viewData.rhi->setPipelineCacheData(m_pipelineCacheData.left(m_pipelineCacheData.size() - 1));
|
||||||
#endif
|
#endif
|
||||||
|
@@ -81,10 +81,13 @@ protected:
|
|||||||
virtual QImage grabRenderControl(RenderViewData &viewData);
|
virtual QImage grabRenderControl(RenderViewData &viewData);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void handleRciSet();
|
||||||
|
|
||||||
RenderViewData m_viewData;
|
RenderViewData m_viewData;
|
||||||
QByteArray m_pipelineCacheData;
|
QByteArray m_pipelineCacheData;
|
||||||
QString m_pipelineCacheLocation;
|
QString m_pipelineCacheLocation;
|
||||||
QString m_pipelineCacheFile;
|
QString m_pipelineCacheFile;
|
||||||
|
QString m_shaderCacheFile;
|
||||||
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