summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2024-07-18 00:01:10 +0300
committerAndrey Kleshchev <117672381+akleshchev@users.noreply.github.com>2024-07-18 06:37:11 +0300
commite3a7ad3d35d1bf51544829b698525e7dcac5a8c8 (patch)
tree8784010f1d7aa06c835c8a0a2dfcfe9810757f26 /indra
parent5482d6a92fcc2eb4f8506a521c2386849a2e9172 (diff)
viewer#2027 Cannot apply PBR Materials on larger linksets
Split updates into batches that respect server update limit
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/llgltfmateriallist.cpp60
-rw-r--r--indra/newview/llgltfmateriallist.h25
2 files changed, 73 insertions, 12 deletions
diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp
index 215f3dd3a7..25438eae5e 100644
--- a/indra/newview/llgltfmateriallist.cpp
+++ b/indra/newview/llgltfmateriallist.cpp
@@ -55,6 +55,8 @@ LLGLTFMaterialList::modify_queue_t LLGLTFMaterialList::sModifyQueue;
LLGLTFMaterialList::apply_queue_t LLGLTFMaterialList::sApplyQueue;
LLSD LLGLTFMaterialList::sUpdates;
+const size_t MAX_TASK_UPDATES = 255;
+
#ifdef SHOW_ASSERT
// return true if given data is (probably) valid update message for ModifyMaterialParams capability
static bool is_valid_update(const LLSD& data)
@@ -362,6 +364,17 @@ void LLGLTFMaterialList::queueApply(const LLViewerObject* obj, S32 side, const L
LLGLTFMaterial* material = new LLGLTFMaterial(*material_override);
sApplyQueue.push_back({ obj->getID(), side, asset_id, material });
}
+
+ if (sUpdates.size() >= MAX_TASK_UPDATES)
+ {
+ LLCoros::instance().launch("modifyMaterialCoro",
+ std::bind(&LLGLTFMaterialList::modifyMaterialCoro,
+ gAgent.getRegionCapability("ModifyMaterialParams"),
+ sUpdates,
+ std::shared_ptr<CallbackHolder>(nullptr)));
+
+ sUpdates = LLSD::emptyArray();
+ }
}
void LLGLTFMaterialList::queueUpdate(const LLSD& data)
@@ -374,16 +387,41 @@ void LLGLTFMaterialList::queueUpdate(const LLSD& data)
}
sUpdates[sUpdates.size()] = data;
+
+ if (sUpdates.size() >= MAX_TASK_UPDATES)
+ {
+ LLCoros::instance().launch("modifyMaterialCoro",
+ std::bind(&LLGLTFMaterialList::modifyMaterialCoro,
+ gAgent.getRegionCapability("ModifyMaterialParams"),
+ sUpdates,
+ std::shared_ptr<CallbackHolder>(nullptr)));
+
+ sUpdates = LLSD::emptyArray();
+ }
}
void LLGLTFMaterialList::flushUpdates(void(*done_callback)(bool))
{
+ std::shared_ptr<CallbackHolder> callback_holder;
+ if (done_callback)
+ {
+ callback_holder = std::make_shared<CallbackHolder>(done_callback);
+ }
+ while (!sModifyQueue.empty() || !sApplyQueue.empty())
+ {
+ flushUpdatesOnce(callback_holder);
+ }
+}
+
+void LLGLTFMaterialList::flushUpdatesOnce(std::shared_ptr<CallbackHolder> callback_holder)
+{
LLSD& data = sUpdates;
- auto i = data.size();
+ size_t i = data.size();
- for (ModifyMaterialData& e : sModifyQueue)
+ while (!sModifyQueue.empty() && i < MAX_TASK_UPDATES)
{
+ ModifyMaterialData& e = sModifyQueue.front();
#ifdef SHOW_ASSERT
// validate object has a material id
LLViewerObject* obj = gObjectList.findObject(e.object_id);
@@ -405,11 +443,12 @@ void LLGLTFMaterialList::flushUpdates(void(*done_callback)(bool))
llassert(is_valid_update(data[i]));
++i;
+ sModifyQueue.pop_front();
}
- sModifyQueue.clear();
- for (ApplyMaterialAssetData& e : sApplyQueue)
+ while (!sApplyQueue.empty() && i < MAX_TASK_UPDATES)
{
+ ApplyMaterialAssetData& e = sApplyQueue.front();
data[i]["object_id"] = e.object_id;
data[i]["side"] = e.side;
data[i]["asset_id"] = e.asset_id;
@@ -425,8 +464,8 @@ void LLGLTFMaterialList::flushUpdates(void(*done_callback)(bool))
llassert(is_valid_update(data[i]));
++i;
+ sApplyQueue.pop_front();
}
- sApplyQueue.clear();
#if 0 // debug output of data being sent to capability
std::stringstream str;
@@ -440,7 +479,7 @@ void LLGLTFMaterialList::flushUpdates(void(*done_callback)(bool))
std::bind(&LLGLTFMaterialList::modifyMaterialCoro,
gAgent.getRegionCapability("ModifyMaterialParams"),
sUpdates,
- done_callback));
+ callback_holder));
sUpdates = LLSD::emptyArray();
}
@@ -661,7 +700,7 @@ void LLGLTFMaterialList::flushMaterials()
}
// static
-void LLGLTFMaterialList::modifyMaterialCoro(std::string cap_url, LLSD overrides, void(*done_callback)(bool) )
+void LLGLTFMaterialList::modifyMaterialCoro(std::string cap_url, LLSD overrides, std::shared_ptr<CallbackHolder> callback_holder)
{
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
@@ -691,9 +730,12 @@ void LLGLTFMaterialList::modifyMaterialCoro(std::string cap_url, LLSD overrides,
success = false;
}
- if (done_callback)
+ if (callback_holder)
{
- done_callback(success);
+ // Set to false even if something went through
+ // since at the moment it get used to refresh UI
+ // if update failed
+ callback_holder->mSuccess &= success;
}
}
diff --git a/indra/newview/llgltfmateriallist.h b/indra/newview/llgltfmateriallist.h
index 982538f106..e79da3592a 100644
--- a/indra/newview/llgltfmateriallist.h
+++ b/indra/newview/llgltfmateriallist.h
@@ -58,7 +58,9 @@ public:
// NOTE: do not use to revert to asset when applying a new asset id, use queueApply below
static void queueModify(const LLViewerObject* obj, S32 side, const LLGLTFMaterial* mat);
- // Queue an application of a material asset we want to send to the simulator. Call "flushUpdates" to flush pending updates.
+ // Queue an application of a material asset we want to send to the simulator.
+ // Call "flushUpdates" to flush pending updates immediately.
+ // Will be flushed automatically if queue is full.
// object_id - ID of object to apply material asset to
// side - TextureEntry index to apply material to, or -1 for all sides
// asset_id - ID of material asset to apply, or LLUUID::null to disassociate current material asset
@@ -66,7 +68,9 @@ public:
// NOTE: Implicitly clears most override data if present
static void queueApply(const LLViewerObject* obj, S32 side, const LLUUID& asset_id);
- // Queue an application of a material asset we want to send to the simulator. Call "flushUpdates" to flush pending updates.
+ // Queue an application of a material asset we want to send to the simulator.
+ // Call "flushUpdates" to flush pending updates immediately.
+ // Will be flushed automatically if queue is full.
// object_id - ID of object to apply material asset to
// side - TextureEntry index to apply material to, or -1 for all sides
// asset_id - ID of material asset to apply, or LLUUID::null to disassociate current material asset
@@ -104,7 +108,22 @@ private:
// NOTE: this is NOT for applying overrides from the UI, see queueModifyMaterial above
void queueOverrideUpdate(const LLUUID& id, S32 side, LLGLTFMaterial* override_data);
- static void modifyMaterialCoro(std::string cap_url, LLSD overrides, void(*done_callback)(bool));
+
+ class CallbackHolder
+ {
+ public:
+ CallbackHolder(void(*done_callback)(bool))
+ : mCallback(done_callback)
+ {}
+ ~CallbackHolder()
+ {
+ if (mCallback) mCallback(mSuccess);
+ }
+ std::function<void(bool)> mCallback = nullptr;
+ bool mSuccess = true;
+ };
+ static void flushUpdatesOnce(std::shared_ptr<CallbackHolder> callback_holder);
+ static void modifyMaterialCoro(std::string cap_url, LLSD overrides, std::shared_ptr<CallbackHolder> callback_holder);
protected:
static void onAssetLoadComplete(