diff options
Diffstat (limited to 'indra/newview/llgltfmateriallist.cpp')
-rw-r--r-- | indra/newview/llgltfmateriallist.cpp | 164 |
1 files changed, 102 insertions, 62 deletions
diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index e08a9c2533..36b87b1a3d 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -290,92 +290,132 @@ void LLGLTFMaterialList::flushUpdates(void(*done_callback)(bool)) done_callback)); } -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; - - { - 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; - } + buffer.resize(size); + file.read((U8*)&buffer[0], buffer.size()); + } + { + LL_PROFILE_ZONE_NAMED("gltf deserialize asset"); + LLSD asset; - buffer.resize(size); - file.read((U8*)&buffer[0], buffer.size()); - } + // read file into buffer + std::istrstream str(&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; |