summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJere Tuliniemi <jere.tuliniemi@qt.io>2020-01-10 11:41:53 +0200
committerJere Tuliniemi <jere.tuliniemi@qt.io>2020-01-16 11:52:10 +0200
commit29eab4197f6cd2d6725c71bc612356c43f872993 (patch)
tree1e86ba2a26e0844b90ea2313bdd0b2bb32447851
parentc9439aa3b34085563e0e50657d71a01c13b50d7b (diff)
Load referenced material assets upon use
When using delayed loading, assets used by materials inside the material container are not loaded upon startup anymore. Instead the assets are loaded when entering the slide in which the material is referenced. This also fixes referenced materials that refer to an animatable material in another slide. Task-number: QT3DS-3100 Change-Id: If55c73e8f91389f3c47ae16357ebe6a473f43585 Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io> Reviewed-by: Janne Kangas <janne.kangas@qt.io> Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io> Reviewed-by: Antti Määttä <antti.maatta@qt.io>
-rw-r--r--src/runtime/Qt3DSSlideSystem.cpp7
-rw-r--r--src/runtime/Qt3DSSlideSystem.h1
-rw-r--r--src/uipparser/Qt3DSUIPParserImpl.cpp117
-rw-r--r--src/uipparser/Qt3DSUIPParserImpl.h7
4 files changed, 117 insertions, 15 deletions
diff --git a/src/runtime/Qt3DSSlideSystem.cpp b/src/runtime/Qt3DSSlideSystem.cpp
index 32d5ea3..7e7d77f 100644
--- a/src/runtime/Qt3DSSlideSystem.cpp
+++ b/src/runtime/Qt3DSSlideSystem.cpp
@@ -223,6 +223,13 @@ struct SSlideSystem : public ISlideSystem
m_CurrentSlide->m_sourcePaths.push_back(QString::fromUtf8(path));
}
+ void AddSourcePath(SSlideKey key, const char8_t *path) override
+ {
+ auto slide = FindSlide(key);
+ if (slide)
+ slide->m_sourcePaths.push_back(QString::fromUtf8(path));
+ }
+
void AddSubPresentation(const char8_t *subpresentationId) override
{
if (m_CurrentSlide)
diff --git a/src/runtime/Qt3DSSlideSystem.h b/src/runtime/Qt3DSSlideSystem.h
index ddde8ac..2d8e84b 100644
--- a/src/runtime/Qt3DSSlideSystem.h
+++ b/src/runtime/Qt3DSSlideSystem.h
@@ -135,6 +135,7 @@ namespace runtime {
virtual SSlideAnimAction *AddSlideAnimAction(bool inAnimation, QT3DSI32 inIndex,
bool inActive) = 0;
virtual void AddSourcePath(const char8_t *path) = 0;
+ virtual void AddSourcePath(SSlideKey key, const char8_t *path) = 0;
virtual void AddSubPresentation(const char8_t *subpresentationId) = 0;
virtual QVector<QString> GetSourcePaths(SSlideKey inKey) = 0;
virtual QVector<QString> GetSubPresentations(SSlideKey inKey) = 0;
diff --git a/src/uipparser/Qt3DSUIPParserImpl.cpp b/src/uipparser/Qt3DSUIPParserImpl.cpp
index 80187bf..d0868ee 100644
--- a/src/uipparser/Qt3DSUIPParserImpl.cpp
+++ b/src/uipparser/Qt3DSUIPParserImpl.cpp
@@ -1021,7 +1021,7 @@ EElementType GetElementType(const char *inType)
*/
BOOL CUIPParserImpl::LoadSceneGraph(IPresentation &inPresentation, IDOMReader &inReader,
qt3ds::runtime::element::SElement *inNewStyleParent,
- bool initInRenderThread)
+ bool initInRenderThread, bool isInsideLayer)
{
IDOMReader::Scope __childScope(inReader);
IScriptBridge *theScriptBridgeQml = inPresentation.GetScriptBridgeQml();
@@ -1046,6 +1046,7 @@ BOOL CUIPParserImpl::LoadSceneGraph(IPresentation &inPresentation, IDOMReader &i
UINT32 theLoopTime = 0;
bool isComponent = false;
bool isBehavior = false;
+ bool isChildInsideLayer = isInsideLayer;
// Create SElement
if (AreEqual(theType, "Scene") || AreEqual(theType, "Component")) {
@@ -1055,7 +1056,14 @@ BOOL CUIPParserImpl::LoadSceneGraph(IPresentation &inPresentation, IDOMReader &i
Q3DStudio_ASSERT(theLoopTime != 0); // Something is wrong here
isComponent = true;
} else {
- if (AreEqual(theType, "Behavior") && !IsTrivial(theClass)) {
+ if (AreEqual(theType, "Layer")) {
+ isChildInsideLayer = true;
+ } else if ((AreEqual(theType, "Material") || AreEqual(theType, "CustomMaterial")
+ || AreEqual(theType, "Image")) && !isInsideLayer) {
+ // Identify objects outside a Layer object with types of Material, CustomMaterial
+ // or Image to be inside the material container
+ m_materialContainerIds.append(QString::fromUtf8(theId));
+ } else if (AreEqual(theType, "Behavior") && !IsTrivial(theClass)) {
// Find the sourcepath and load the script
++theClass; // remove the '#'
TIdSourcePathMap::iterator theSourcePathIter = m_IdScriptMap.find(theClass);
@@ -1156,7 +1164,8 @@ BOOL CUIPParserImpl::LoadSceneGraph(IPresentation &inPresentation, IDOMReader &i
theFileString.c_str(), initInRenderThread);
}
}
- LoadSceneGraph(inPresentation, inReader, &theNewElem, initInRenderThread);
+ LoadSceneGraph(inPresentation, inReader, &theNewElem, initInRenderThread,
+ isChildInsideLayer);
}
return true;
@@ -1627,6 +1636,32 @@ BOOL CUIPParserImpl::LoadStateGraph(IPresentation &inPresentation, qt3dsdm::IDOM
}
}
+ // Add source paths of the source materials of the ReferencedMaterials
+ // to the slide source paths
+ for (const auto &slideRefMats : qAsConst(m_referencedMaterialsBySlide)) {
+ const auto &slideKey = slideRefMats.first;
+ const auto &refMats = slideRefMats.second;
+
+ QVector<QString> sourcePathRefs;
+ for (const auto &refMat : refMats) {
+ // CustomMaterials contains their own source paths
+ sourcePathRefs.append(refMat);
+ // Materials have their source paths inside Image objects
+ if (m_imagesByMaterial.contains(refMat))
+ sourcePathRefs.append(m_imagesByMaterial[refMat]);
+ }
+
+ for (const auto &sourcePathRef : qAsConst(sourcePathRefs)) {
+ if (m_sourcePathsById.contains(sourcePathRef)) {
+ const auto &sourcePaths = m_sourcePathsById[sourcePathRef];
+ for (const auto &sourcePath : sourcePaths) {
+ inPresentation.GetSlideSystem().AddSourcePath(slideKey,
+ sourcePath.toUtf8().constData());
+ }
+ }
+ }
+ }
+
return theStatus;
}
@@ -1643,6 +1678,7 @@ BOOL CUIPParserImpl::LoadState(IPresentation &inPresentation, SElement *inCompon
BOOL theResult = true;
ISlideSystem &theBuilder = inPresentation.GetSlideSystem();
+ m_currentSlideReferencedMaterials.clear();
eastl::string theSlideName = GetSlideName(inReader);
@@ -1673,6 +1709,16 @@ BOOL CUIPParserImpl::LoadState(IPresentation &inPresentation, SElement *inCompon
if (theMaxTime != 0)
theBuilder.SetSlideMaxTime((QT3DSU32)theMaxTime);
+ if (!m_currentSlideReferencedMaterials.empty()) {
+ qt3ds::runtime::SSlideKey key;
+ key.m_Component = inComponent;
+ key.m_Index = inSlideIndex;
+ QPair<qt3ds::runtime::SSlideKey, QVector<QString>> pair;
+ pair.first = key;
+ pair.second = m_currentSlideReferencedMaterials;
+ m_referencedMaterialsBySlide.append(pair);
+ }
+
return theResult;
}
@@ -2155,6 +2201,9 @@ BOOL CUIPParserImpl::LoadSlideElementAttrs(IPresentation &inPresentation, bool m
inReader.Att("ref", theRef);
if (theRef && *theRef && theRef[0] == '#')
++theRef;
+
+ bool isInsideMaterialContainer = m_materialContainerIds.contains(theRef);
+
bool isSet = AreEqual(inReader.GetNarrowElementName(), "Set");
const char8_t *sourcepath;
if (inReader.UnregisteredAtt("sourcepath", sourcepath)) {
@@ -2165,21 +2214,53 @@ BOOL CUIPParserImpl::LoadSlideElementAttrs(IPresentation &inPresentation, bool m
ibl = true;
}
if (!IsTrivial(sourcepath) && sourcepath[0] != '#') {
- AddSourcePath(sourcepath, ibl);
- theBuilder.AddSourcePath(sourcepath);
- if (!masterSlide)
+ m_sourcePathsById[QLatin1Char('#') + QString::fromUtf8(theRef)].append(
+ QString::fromUtf8(sourcepath));
+ // Don't add material container assets to the Master Slide source path list
+ if (!isInsideMaterialContainer) {
+ AddSourcePath(sourcepath, ibl);
+ theBuilder.AddSourcePath(sourcepath);
+ }
+ // Add the material container assets to the list of source paths used by slides
+ // other than the Master Slide, so that the assets are not loaded at startup
+ if (!masterSlide || isInsideMaterialContainer)
m_slideSourcePaths.push_back(QString::fromLatin1(sourcepath));
if (AreEqual(inElementData.m_Type.c_str(), "Layer"))
theBuilder.AddSubPresentation(sourcepath);
-
}
}
+
const char8_t *subpres;
if (inReader.UnregisteredAtt("subpresentation", subpres)) {
if (!IsTrivial(subpres))
theBuilder.AddSubPresentation(subpres);
}
+ const char8_t *referencedmaterial;
+ if (inReader.UnregisteredAtt("referencedmaterial", referencedmaterial)) {
+ if (!IsTrivial(referencedmaterial))
+ m_currentSlideReferencedMaterials.append(referencedmaterial);
+ }
+
+ if (strcmp(inElementData.m_Type, "Material") == 0) {
+ eastl::vector<eastl::string> propertyList;
+ m_MetaData.GetInstanceProperties(inElementData.m_Type, inElementData.m_Class,
+ propertyList, false);
+ for (int i = 0; i < propertyList.size(); ++i) {
+ ERuntimeDataModelDataType type = m_MetaData.GetPropertyType(inElementData.m_Type,
+ m_MetaData.Register(propertyList[i].c_str()),
+ inElementData.m_Class);
+ if (type == ERuntimeDataModelDataTypeLong4) {
+ const char8_t *attValue = "";
+ bool hasAtt = inReader.UnregisteredAtt(propertyList[i].c_str(), attValue);
+ if (hasAtt) {
+ m_imagesByMaterial[QLatin1Char('#') + inElementData.m_Id.c_str()]
+ .append(QString::fromUtf8(attValue));
+ }
+ }
+ }
+ }
+
const bool dyn = IsDynamicObject(inElementData.m_Type);
Option<qt3dsdm::SMetaDataCustomMaterial> mat;
Option<qt3dsdm::SMetaDataEffect> eff;
@@ -2226,9 +2307,13 @@ BOOL CUIPParserImpl::LoadSlideElementAttrs(IPresentation &inPresentation, bool m
// Handle dynamic object texture source paths
if (hasAtt && !IsTrivial(theAttValue) && IsDynamicObject(inElementData.m_Type)
&& theIter->second.m_AdditionalType == ERuntimeAdditionalMetaDataTypeTexture) {
- AddSourcePath(theAttValue, false);
- theBuilder.AddSourcePath(theAttValue);
- if (!masterSlide)
+ m_sourcePathsById[QLatin1Char('#') + QString::fromUtf8(theRef)].append(
+ QString::fromUtf8(theAttValue));
+ if (!isInsideMaterialContainer) {
+ AddSourcePath(theAttValue, false);
+ theBuilder.AddSourcePath(theAttValue);
+ }
+ if (!masterSlide || isInsideMaterialContainer)
m_slideSourcePaths.push_back(QString::fromLatin1(theAttValue));
}
if (isSet == false && theIter->second.m_SlideForceFlag == false) {
@@ -2251,10 +2336,14 @@ BOOL CUIPParserImpl::LoadSlideElementAttrs(IPresentation &inPresentation, bool m
if (prop.m_DataType == qt3ds::render::NVRenderShaderDataTypes::NVRenderTexture2DPtr) {
const char8_t *theAttValue = "";
bool hasAtt = inReader.UnregisteredAtt(prop.m_Name, theAttValue);
- if (hasAtt && !IsTrivial(theAttValue) ) {
- AddSourcePath(theAttValue, false);
- theBuilder.AddSourcePath(theAttValue);
- if (!masterSlide)
+ if (hasAtt && !IsTrivial(theAttValue)) {
+ m_sourcePathsById[QLatin1Char('#') + QString::fromUtf8(theRef)].append(
+ QString::fromUtf8(theAttValue));
+ if (!isInsideMaterialContainer) {
+ AddSourcePath(theAttValue, false);
+ theBuilder.AddSourcePath(theAttValue);
+ }
+ if (!masterSlide || isInsideMaterialContainer)
m_slideSourcePaths.push_back(QString::fromLatin1(theAttValue));
}
}
diff --git a/src/uipparser/Qt3DSUIPParserImpl.h b/src/uipparser/Qt3DSUIPParserImpl.h
index f89227b..85f8c18 100644
--- a/src/uipparser/Qt3DSUIPParserImpl.h
+++ b/src/uipparser/Qt3DSUIPParserImpl.h
@@ -430,6 +430,11 @@ protected:
TStringVector m_SourcePathList;
TStringSet m_iblSources;
QVector<QString> m_slideSourcePaths;
+ QVector<QString> m_materialContainerIds;
+ QHash<QString, QVector<QString>> m_imagesByMaterial;
+ QHash<QString, QVector<QString>> m_sourcePathsById;
+ QVector<QString> m_currentSlideReferencedMaterials;
+ QVector<QPair<qt3ds::runtime::SSlideKey, QVector<QString>>> m_referencedMaterialsBySlide;
struct SElementRefCache
{
@@ -554,7 +559,7 @@ protected: // Operation
bool initInRenderThread);
BOOL LoadSceneGraph(IPresentation &inPresentation, qt3dsdm::IDOMReader &inReader,
qt3ds::runtime::element::SElement *inNewStyleParent,
- bool initInRenderThread);
+ bool initInRenderThread, bool isInsideLayer = false);
BOOL LoadLogic(IPresentation &inPresentation, qt3dsdm::IDOMReader &inReader);
BOOL LoadStateGraph(IPresentation &inPresentation, qt3dsdm::IDOMReader &inReader);