summaryrefslogtreecommitdiff
path: root/indra/newview/llgltfmateriallist.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llgltfmateriallist.cpp')
-rw-r--r--indra/newview/llgltfmateriallist.cpp164
1 files changed, 102 insertions, 62 deletions
diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp
index 8e184c719d..c18988ef15 100644
--- a/indra/newview/llgltfmateriallist.cpp
+++ b/indra/newview/llgltfmateriallist.cpp
@@ -271,92 +271,132 @@ void LLGLTFMaterialList::flushModifyMaterialQueue(void(*done_callback)(bool))
sModifyQueue.clear();
}
-LLGLTFMaterial* LLGLTFMaterialList::getMaterial(const LLUUID& id)
+class AssetLoadUserData
{
- LL_PROFILE_ZONE_SCOPED;
- uuid_mat_map_t::iterator iter = mList.find(id);
- if (iter == mList.end())
+public:
+ AssetLoadUserData() {}
+ tinygltf::Model mModelIn;
+ LLPointer<LLFetchedGLTFMaterial> mMaterial;
+};
+
+void LLGLTFMaterialList::onAssetLoadComplete(const LLUUID& id, LLAssetType::EType asset_type, void* user_data, S32 status, LLExtStat ext_status)
+{
+ LL_PROFILE_ZONE_NAMED("gltf asset callback");
+ AssetLoadUserData* asset_data = (AssetLoadUserData*)user_data;
+
+ if (status != LL_ERR_NOERR)
+ {
+ LL_WARNS() << "Error getting material asset data: " << LLAssetStorage::getErrorString(status) << " (" << status << ")" << LL_ENDL;
+ asset_data->mMaterial->mFetching = false;
+ delete asset_data;
+ }
+ else
{
- LL_PROFILE_ZONE_NAMED("gltf fetch")
- LLFetchedGLTFMaterial* mat = new LLFetchedGLTFMaterial();
- mList[id] = mat;
- if (!mat->mFetching)
- {
- // if we do multiple getAssetData calls,
- // some will get distched, messing ref counter
- // Todo: get rid of mat->ref()
- mat->mFetching = true;
- mat->ref();
+ LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop");
+ LL::WorkQueue::ptr_t general_queue = LL::WorkQueue::getInstance("General");
- gAssetStorage->getAssetData(id, LLAssetType::AT_MATERIAL,
- [=](const LLUUID& id, LLAssetType::EType asset_type, void* user_data, S32 status, LLExtStat ext_status)
+ typedef std::pair<U32, tinygltf::Model> return_data_t;
+
+ main_queue->postTo(
+ general_queue,
+ [id, asset_type, asset_data]() // Work done on general queue
+ {
+ std::vector<char> buffer;
{
- LL_PROFILE_ZONE_NAMED("gltf asset callback");
- if (status)
+ LL_PROFILE_ZONE_NAMED("gltf read asset");
+ LLFileSystem file(id, asset_type, LLFileSystem::READ);
+ auto size = file.getSize();
+ if (!size)
{
- LL_WARNS() << "Error getting material asset data: " << LLAssetStorage::getErrorString(status) << " (" << status << ")" << LL_ENDL;
+ return false;
}
- std::vector<char> buffer;
+ buffer.resize(size);
+ file.read((U8*)&buffer[0], buffer.size());
+ }
- {
- LL_PROFILE_ZONE_NAMED("gltf read asset");
- LLFileSystem file(id, asset_type, LLFileSystem::READ);
- auto size = file.getSize();
- if (!size)
- {
- LL_DEBUGS() << "Zero size material." << LL_ENDL;
- mat->mFetching = false;
- mat->unref();
- return;
- }
+ {
+ LL_PROFILE_ZONE_NAMED("gltf deserialize asset");
+ LLSD asset;
+ // read file into buffer
+ std::istrstream str(&buffer[0], buffer.size());
- buffer.resize(size);
- file.read((U8*)&buffer[0], buffer.size());
- }
-
+ if (LLSDSerialize::deserialize(asset, str, buffer.size()))
{
- LL_PROFILE_ZONE_NAMED("gltf deserialize asset");
-
- LLSD asset;
-
- // read file into buffer
- std::istrstream str(&buffer[0], buffer.size());
-
- if (LLSDSerialize::deserialize(asset, str, buffer.size()))
+ if (asset.has("version") && asset["version"] == "1.0")
{
- if (asset.has("version") && asset["version"] == "1.0")
+ if (asset.has("type") && asset["type"].asString() == "GLTF 2.0")
{
- if (asset.has("type") && asset["type"].asString() == "GLTF 2.0")
+ if (asset.has("data") && asset["data"].isString())
{
- if (asset.has("data") && asset["data"].isString())
- {
- std::string data = asset["data"];
+ std::string data = asset["data"];
+
+ std::string warn_msg, error_msg;
- std::string warn_msg, error_msg;
+ LL_PROFILE_ZONE_SCOPED;
+ tinygltf::TinyGLTF gltf;
- if (!mat->fromJSON(data, warn_msg, error_msg))
- {
- LL_WARNS() << "Failed to decode material asset: " << LL_ENDL;
- LL_WARNS() << warn_msg << LL_ENDL;
- LL_WARNS() << error_msg << LL_ENDL;
- }
+ if (!gltf.LoadASCIIFromString(&asset_data->mModelIn, &error_msg, &warn_msg, data.c_str(), data.length(), ""))
+ {
+ LL_WARNS() << "Failed to decode material asset: "
+ << LL_NEWLINE
+ << warn_msg
+ << LL_NEWLINE
+ << error_msg
+ << LL_ENDL;
+ return false;
}
+ return true;
}
}
}
- else
- {
- LL_WARNS() << "Failed to deserialize material LLSD" << LL_ENDL;
- }
}
+ else
+ {
+ LL_WARNS() << "Failed to deserialize material LLSD" << LL_ENDL;
+ }
+ }
+
+ return false;
+ },
+ [id, asset_data](bool result) // Callback to main thread
+ mutable {
+
+ if (result)
+ {
+ asset_data->mMaterial->setFromModel(asset_data->mModelIn, 0/*only one index*/);
+ }
+ else
+ {
+ LL_DEBUGS() << "Failed to get material " << id << LL_ENDL;
+ }
+ asset_data->mMaterial->mFetching = false;
+ delete asset_data;
+ });
+ }
+}
+
+LLGLTFMaterial* LLGLTFMaterialList::getMaterial(const LLUUID& id)
+{
+ LL_PROFILE_ZONE_SCOPED;
+ uuid_mat_map_t::iterator iter = mList.find(id);
+ if (iter == mList.end())
+ {
+ LL_PROFILE_ZONE_NAMED("gltf fetch")
+ LLFetchedGLTFMaterial* mat = new LLFetchedGLTFMaterial();
+ mList[id] = mat;
+
+ if (!mat->mFetching)
+ {
+ mat->mFetching = true;
+
+ AssetLoadUserData *user_data = new AssetLoadUserData();
+ user_data->mMaterial = mat;
- mat->mFetching = false;
- mat->unref();
- }, nullptr);
+ gAssetStorage->getAssetData(id, LLAssetType::AT_MATERIAL, onAssetLoadComplete, (void*)user_data);
}
return mat;