diff options
author | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2022-10-19 00:08:27 +0300 |
---|---|---|
committer | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2022-10-19 01:01:03 +0300 |
commit | 58472180696401155159414c20a307cf97f7df44 (patch) | |
tree | e19a13561730db2915bdbd8ef5152e8881848944 /indra/newview | |
parent | 0b177c27a07344d81cb52806695b2348b6f33b0a (diff) |
SL-18391 Basic GLTF lifetime management
Diffstat (limited to 'indra/newview')
-rw-r--r-- | indra/newview/CMakeLists.txt | 2 | ||||
-rw-r--r-- | indra/newview/llfetchedgltfmaterial.cpp | 42 | ||||
-rw-r--r-- | indra/newview/llfetchedgltfmaterial.h | 48 | ||||
-rw-r--r-- | indra/newview/llgltfmateriallist.cpp | 82 | ||||
-rw-r--r-- | indra/newview/llgltfmateriallist.h | 13 | ||||
-rw-r--r-- | indra/newview/lllocalgltfmaterials.cpp | 6 | ||||
-rw-r--r-- | indra/newview/llmaterialeditor.cpp | 5 | ||||
-rw-r--r-- | indra/newview/llviewerdisplay.cpp | 14 |
8 files changed, 189 insertions, 23 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 1882f75de9..374db7fdf8 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -208,6 +208,7 @@ set(viewer_SOURCE_FILES llfasttimerview.cpp llfavoritesbar.cpp llfeaturemanager.cpp + llfetchedgltfmaterial.cpp llfilepicker.cpp llfilteredwearablelist.cpp llfirstuse.cpp @@ -853,6 +854,7 @@ set(viewer_HEADER_FILES llfasttimerview.h llfavoritesbar.h llfeaturemanager.h + llfetchedgltfmaterial.h llfilepicker.h llfilteredwearablelist.h llfirstuse.h diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp new file mode 100644 index 0000000000..a06dd276cd --- /dev/null +++ b/indra/newview/llfetchedgltfmaterial.cpp @@ -0,0 +1,42 @@ +/** + * @file llfetchedgltfmaterial.cpp + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfetchedgltfmaterial.h" + +LLFetchedGLTFMaterial::LLFetchedGLTFMaterial() + : LLGLTFMaterial() + , mExpectedFlusTime(0.f) + , mActive(true) + , mFetching(false) +{ + +} + +LLFetchedGLTFMaterial::~LLFetchedGLTFMaterial() +{ + +} diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h new file mode 100644 index 0000000000..115e85a5e2 --- /dev/null +++ b/indra/newview/llfetchedgltfmaterial.h @@ -0,0 +1,48 @@ +/** + * @file llfetchedgltfmaterial.h + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + + +#pragma once + +#include "llgltfmaterial.h" +#include "llpointer.h" + +class LLFetchedGLTFMaterial : public LLGLTFMaterial +{ + friend class LLGLTFMaterialList; // for lifetime management +public: + LLFetchedGLTFMaterial(); + virtual ~LLFetchedGLTFMaterial(); + +protected: + //Lifetime management + F64 mExpectedFlusTime; // since epoch in seconds + bool mActive; + bool mFetching; +}; + +extern LLGLTFMaterialList gGLTFMaterialList; + + diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index a433644e0e..84cf746198 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -29,9 +29,11 @@ #include "llassetstorage.h" #include "lldispatcher.h" +#include "llfetchedgltfmaterial.h" #include "llfilesystem.h" #include "llsdserialize.h" #include "lltinygltfhelper.h" +#include "llviewercontrol.h" #include "llviewergenericmessage.h" #include "tinygltf/tiny_gltf.h" @@ -73,19 +75,25 @@ LLGLTFMaterialList gGLTFMaterialList; LLGLTFMaterial* LLGLTFMaterialList::getMaterial(const LLUUID& id) { - List::iterator iter = mList.find(id); + uuid_mat_map_t::iterator iter = mList.find(id); if (iter == mList.end()) { - LLGLTFMaterial* mat = new LLGLTFMaterial(); + LLFetchedGLTFMaterial* mat = new LLFetchedGLTFMaterial(); mList[id] = mat; - mat->ref(); - - gAssetStorage->getAssetData(id, LLAssetType::AT_MATERIAL, - [=](const LLUUID& id, LLAssetType::EType asset_type, void* user_data, S32 status, LLExtStat ext_status) + 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(); + + gAssetStorage->getAssetData(id, LLAssetType::AT_MATERIAL, + [=](const LLUUID& id, LLAssetType::EType asset_type, void* user_data, S32 status, LLExtStat ext_status) { if (status) - { + { LL_WARNS() << "Error getting material asset data: " << LLAssetStorage::getErrorString(status) << " (" << status << ")" << LL_ENDL; } @@ -94,6 +102,7 @@ LLGLTFMaterial* LLGLTFMaterialList::getMaterial(const LLUUID& id) if (!size) { LL_DEBUGS() << "Zero size material." << LL_ENDL; + mat->mFetching = false; mat->unref(); return; } @@ -134,8 +143,10 @@ LLGLTFMaterial* LLGLTFMaterialList::getMaterial(const LLUUID& id) LL_WARNS() << "Failed to deserialize material LLSD" << LL_ENDL; } + mat->mFetching = false; mat->unref(); }, nullptr); + } return mat; } @@ -143,7 +154,7 @@ LLGLTFMaterial* LLGLTFMaterialList::getMaterial(const LLUUID& id) return iter->second; } -void LLGLTFMaterialList::addMaterial(const LLUUID& id, LLGLTFMaterial* material) +void LLGLTFMaterialList::addMaterial(const LLUUID& id, LLFetchedGLTFMaterial* material) { mList[id] = material; } @@ -153,6 +164,61 @@ void LLGLTFMaterialList::removeMaterial(const LLUUID& id) mList.erase(id); } +void LLGLTFMaterialList::flushMaterials() +{ + // Similar variant to what textures use + static const S32 MIN_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMinCount"); // default: 32 + //update MIN_UPDATE_COUNT or 5% of materials, whichever is greater + U32 update_count = llmax((U32)MIN_UPDATE_COUNT, (U32)mList.size() / 20); + update_count = llmin(update_count, (U32)mList.size()); + + const F64 MAX_INACTIVE_TIME = 30.f; + F64 cur_time = LLTimer::getTotalSeconds(); + + uuid_mat_map_t::iterator iter = mList.upper_bound(mLastUpdateKey); + while (update_count-- > 0) + { + if (iter == mList.end()) + { + iter = mList.begin(); + } + + LLPointer<LLFetchedGLTFMaterial> material = iter->second; + if (material->getNumRefs() == 2) // this one plus one from the list + { + + if (!material->mActive + && cur_time > material->mExpectedFlusTime) + { + iter = mList.erase(iter); + } + else + { + if (material->mActive) + { + material->mExpectedFlusTime = cur_time + MAX_INACTIVE_TIME; + material->mActive = false; + } + ++iter; + } + } + else + { + material->mActive = true; + ++iter; + } + } + + if (iter != mList.end()) + { + mLastUpdateKey = iter->first; + } + else + { + mLastUpdateKey.setNull(); + } +} + // static void LLGLTFMaterialList::registerCallbacks() { diff --git a/indra/newview/llgltfmateriallist.h b/indra/newview/llgltfmateriallist.h index 4aed4b009d..4b905e32c9 100644 --- a/indra/newview/llgltfmateriallist.h +++ b/indra/newview/llgltfmateriallist.h @@ -26,26 +26,33 @@ #pragma once +#include "llfetchedgltfmaterial.h" #include "llgltfmaterial.h" #include "llpointer.h" #include <unordered_map> +class LLFetchedGLTFMaterial; + class LLGLTFMaterialList { public: LLGLTFMaterialList() {} - typedef std::unordered_map<LLUUID, LLPointer<LLGLTFMaterial > > List; - List mList; LLGLTFMaterial* getMaterial(const LLUUID& id); - void addMaterial(const LLUUID& id, LLGLTFMaterial* material); + void addMaterial(const LLUUID& id, LLFetchedGLTFMaterial* material); void removeMaterial(const LLUUID& id); + void flushMaterials(); + static void registerCallbacks(); +private: + typedef std::unordered_map<LLUUID, LLPointer<LLFetchedGLTFMaterial > > uuid_mat_map_t; + uuid_mat_map_t mList; + LLUUID mLastUpdateKey; }; extern LLGLTFMaterialList gGLTFMaterialList; diff --git a/indra/newview/lllocalgltfmaterials.cpp b/indra/newview/lllocalgltfmaterials.cpp index fe2b7ac816..f292844313 100644 --- a/indra/newview/lllocalgltfmaterials.cpp +++ b/indra/newview/lllocalgltfmaterials.cpp @@ -152,16 +152,16 @@ bool LLLocalGLTFMaterial::updateSelf() if (mLastModified.asString() != new_last_modified.asString()) { - LLPointer<LLGLTFMaterial> raw_material; + LLPointer<LLFetchedGLTFMaterial> raw_material; if (mWorldID.notNull()) { // update existing material // will create a new one if material doesn't exist yet - raw_material = gGLTFMaterialList.getMaterial(mWorldID); + raw_material = (LLFetchedGLTFMaterial*)gGLTFMaterialList.getMaterial(mWorldID); } else { - raw_material = new LLGLTFMaterial(); + raw_material = new LLFetchedGLTFMaterial(); } if (loadMaterial(raw_material, mMaterialIndex)) { diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 319f98b816..c5cdb81d67 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1422,7 +1422,8 @@ void LLMaterialEditor::loadFromGLTFMaterial(LLUUID &asset_id) return; } LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor"); - me->setTitle(LLTrans::getString("New Material")); + me->mMaterialName = LLTrans::getString("New Material"); + me->setTitle(me->mMaterialName); me->setHasUnsavedChanges(true); me->setFromGLTFMaterial(gGLTFMaterialList.getMaterial(asset_id)); me->openFloater(); @@ -1943,7 +1944,7 @@ void LLMaterialEditor::applyToSelection() LL_WARNS() << "not connected to materials capable region, missing ModifyMaterialParams cap" << LL_ENDL; // Fallback local preview. Will be removed once override systems is finished and new cap is deployed everywhere. - LLPointer<LLGLTFMaterial> mat = new LLGLTFMaterial(); + LLPointer<LLFetchedGLTFMaterial> mat = new LLFetchedGLTFMaterial(); getGLTFMaterial(mat); static const LLUUID placeholder("984e183e-7811-4b05-a502-d79c6f978a98"); gGLTFMaterialList.addMaterial(placeholder, mat); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 46e25b18b7..ed3631be99 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -31,6 +31,7 @@ #include "llgl.h" #include "llrender.h" #include "llglheaders.h" +#include "llgltfmateriallist.h" #include "llagent.h" #include "llagentcamera.h" #include "llviewercontrol.h" @@ -254,7 +255,7 @@ static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE("Update Images"); static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_CLASS("Class"); static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_BUMP("Image Update Bump"); static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_LIST("List"); -static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_DELETE("Delete"); +static LLTrace::BlockTimerStatHandle FTM_MATERIALS_FLUSH("GLTF Materials Cleanup"); static LLTrace::BlockTimerStatHandle FTM_RESIZE_WINDOW("Resize Window"); static LLTrace::BlockTimerStatHandle FTM_HUD_UPDATE("HUD Update"); static LLTrace::BlockTimerStatHandle FTM_DISPLAY_UPDATE_GEOM("Update Geom"); @@ -807,12 +808,11 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) gTextureList.updateImages(max_image_decode_time); } - /*{ - LL_RECORD_BLOCK_TIME(FTM_IMAGE_UPDATE_DELETE); - //remove dead textures from GL - LLImageGL::deleteDeadTextures(); - stop_glerror(); - }*/ + { + LL_RECORD_BLOCK_TIME(FTM_MATERIALS_FLUSH); + //remove dead gltf materials + gGLTFMaterialList.flushMaterials(); + } } LLGLState::checkStates(); |