summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2022-10-19 00:08:27 +0300
committerAndrey Kleshchev <andreykproductengine@lindenlab.com>2022-10-19 01:01:03 +0300
commit58472180696401155159414c20a307cf97f7df44 (patch)
treee19a13561730db2915bdbd8ef5152e8881848944 /indra
parent0b177c27a07344d81cb52806695b2348b6f33b0a (diff)
SL-18391 Basic GLTF lifetime management
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/llfetchedgltfmaterial.cpp42
-rw-r--r--indra/newview/llfetchedgltfmaterial.h48
-rw-r--r--indra/newview/llgltfmateriallist.cpp82
-rw-r--r--indra/newview/llgltfmateriallist.h13
-rw-r--r--indra/newview/lllocalgltfmaterials.cpp6
-rw-r--r--indra/newview/llmaterialeditor.cpp5
-rw-r--r--indra/newview/llviewerdisplay.cpp14
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();