summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCosmic Linden <cosmic@lindenlab.com>2023-01-24 17:48:18 -0800
committerCosmic Linden <cosmic@lindenlab.com>2023-01-25 12:34:35 -0800
commit2aaa15fef15243e6b38f46426d8ebb355ccfb807 (patch)
tree718f00f4f3c5eb412199ab1b4c530e3308a647c2
parenta851aa83e705fa4a1c78919cfcac6709cfb1a875 (diff)
SL-19012: Fix new material IDs sometimes not applying when set via LSL
-rw-r--r--indra/newview/llfetchedgltfmaterial.cpp32
-rw-r--r--indra/newview/llfetchedgltfmaterial.h10
-rw-r--r--indra/newview/llgltfmateriallist.cpp10
-rw-r--r--indra/newview/llgltfmateriallist.h2
-rw-r--r--indra/newview/llviewerobject.cpp36
-rw-r--r--indra/newview/llviewerobject.h1
6 files changed, 76 insertions, 15 deletions
diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp
index b095b74519..047f1a4965 100644
--- a/indra/newview/llfetchedgltfmaterial.cpp
+++ b/indra/newview/llfetchedgltfmaterial.cpp
@@ -115,3 +115,35 @@ void LLFetchedGLTFMaterial::bind()
}
}
+
+void LLFetchedGLTFMaterial::materialBegin()
+{
+ llassert(!mFetching);
+ mFetching = true;
+}
+
+void LLFetchedGLTFMaterial::onMaterialComplete(std::function<void()> material_complete)
+{
+ if (!material_complete) { return; }
+
+ if (!mFetching)
+ {
+ material_complete();
+ return;
+ }
+
+ materialCompleteCallbacks.push_back(material_complete);
+}
+
+void LLFetchedGLTFMaterial::materialComplete()
+{
+ llassert(mFetching);
+ mFetching = false;
+
+ for (std::function<void()> material_complete : materialCompleteCallbacks)
+ {
+ material_complete();
+ }
+ materialCompleteCallbacks.clear();
+ materialCompleteCallbacks.shrink_to_fit();
+}
diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h
index 4f6c56012e..f784f19c4f 100644
--- a/indra/newview/llfetchedgltfmaterial.h
+++ b/indra/newview/llfetchedgltfmaterial.h
@@ -39,6 +39,9 @@ public:
LLFetchedGLTFMaterial();
virtual ~LLFetchedGLTFMaterial();
+ // If this material is loaded, fire the given function
+ void onMaterialComplete(std::function<void()> material_complete);
+
// bind this material for rendering
void bind();
@@ -49,9 +52,14 @@ public:
LLPointer<LLViewerFetchedTexture> mEmissiveTexture;
protected:
- //Lifetime management
+ // Lifetime management
+
+ void materialBegin();
+ void materialComplete();
+
F64 mExpectedFlusTime; // since epoch in seconds
bool mActive;
bool mFetching;
+ std::vector<std::function<void()>> materialCompleteCallbacks;
};
diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp
index 4cf1562042..bc094ac838 100644
--- a/indra/newview/llgltfmateriallist.cpp
+++ b/indra/newview/llgltfmateriallist.cpp
@@ -525,7 +525,7 @@ void LLGLTFMaterialList::onAssetLoadComplete(const LLUUID& id, LLAssetType::ETyp
if (status != LL_ERR_NOERR)
{
LL_WARNS("GLTF") << "Error getting material asset data: " << LLAssetStorage::getErrorString(status) << " (" << status << ")" << LL_ENDL;
- asset_data->mMaterial->mFetching = false;
+ asset_data->mMaterial->materialComplete();
delete asset_data;
}
else
@@ -611,13 +611,15 @@ void LLGLTFMaterialList::onAssetLoadComplete(const LLUUID& id, LLAssetType::ETyp
{
LL_DEBUGS("GLTF") << "Failed to get material " << id << LL_ENDL;
}
- asset_data->mMaterial->mFetching = false;
+
+ asset_data->mMaterial->materialComplete();
+
delete asset_data;
});
}
}
-LLGLTFMaterial* LLGLTFMaterialList::getMaterial(const LLUUID& id)
+LLFetchedGLTFMaterial* LLGLTFMaterialList::getMaterial(const LLUUID& id)
{
LL_PROFILE_ZONE_SCOPED;
uuid_mat_map_t::iterator iter = mList.find(id);
@@ -629,7 +631,7 @@ LLGLTFMaterial* LLGLTFMaterialList::getMaterial(const LLUUID& id)
if (!mat->mFetching)
{
- mat->mFetching = true;
+ mat->materialBegin();
AssetLoadUserData *user_data = new AssetLoadUserData();
user_data->mMaterial = mat;
diff --git a/indra/newview/llgltfmateriallist.h b/indra/newview/llgltfmateriallist.h
index 5ce0e324f5..85e60aa17f 100644
--- a/indra/newview/llgltfmateriallist.h
+++ b/indra/newview/llgltfmateriallist.h
@@ -45,7 +45,7 @@ public:
LLGLTFMaterialList() {}
- LLGLTFMaterial* getMaterial(const LLUUID& id);
+ LLFetchedGLTFMaterial* getMaterial(const LLUUID& id);
void addMaterial(const LLUUID& id, LLFetchedGLTFMaterial* material);
void removeMaterial(const LLUUID& id);
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index f416080f9e..5a365c79ea 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -7160,6 +7160,14 @@ const LLUUID& LLViewerObject::getRenderMaterialID(U8 te) const
return LLUUID::null;
}
+void LLViewerObject::rebuildMaterial()
+{
+ llassert(!isDead());
+
+ faceMappingChanged();
+ gPipeline.markTextured(mDrawable);
+}
+
void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool update_server)
{
// implementation is delicate
@@ -7188,17 +7196,16 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat
}
+ LLFetchedGLTFMaterial* new_material = nullptr;
+ if (id.notNull())
+ {
+ new_material = gGLTFMaterialList.getMaterial(id);
+ }
+
// update local state
for (S32 te = start_idx; te < end_idx; ++te)
{
-
- LLGLTFMaterial* new_material = nullptr;
LLTextureEntry* tep = getTE(te);
-
- if (id.notNull())
- {
- new_material = gGLTFMaterialList.getMaterial(id);
- }
bool material_changed = !param_block || id != param_block->getMaterial(te);
@@ -7225,8 +7232,19 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat
}
// signal to render pipe that render batches must be rebuilt for this object
- faceMappingChanged();
- gPipeline.markTextured(mDrawable);
+ if (!new_material)
+ {
+ rebuildMaterial();
+ }
+ else
+ {
+ LLPointer<LLViewerObject> this_ptr = this;
+ new_material->onMaterialComplete([this_ptr]() mutable {
+ if (this_ptr->isDead()) { return; }
+
+ this_ptr->rebuildMaterial();
+ });
+ }
if (update_server)
{
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index fae29c3bc2..93b17361ab 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -226,6 +226,7 @@ public:
private:
void resetRotTime();
void setRenderMaterialIDs(const LLRenderMaterialParams* material_params, bool local_origin);
+ void rebuildMaterial();
public:
void resetRot();
void applyAngularVelocity(F32 dt);