summaryrefslogtreecommitdiff
path: root/indra/newview/llavatarrendernotifier.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llavatarrendernotifier.cpp')
-rw-r--r--indra/newview/llavatarrendernotifier.cpp259
1 files changed, 176 insertions, 83 deletions
diff --git a/indra/newview/llavatarrendernotifier.cpp b/indra/newview/llavatarrendernotifier.cpp
index f7a1ef1621..94584a623b 100644
--- a/indra/newview/llavatarrendernotifier.cpp
+++ b/indra/newview/llavatarrendernotifier.cpp
@@ -38,6 +38,7 @@
#include "llnotifications.h"
#include "llnotificationsutil.h"
#include "llnotificationtemplate.h"
+#include "llslurl.h"
#include "lltimer.h"
#include "llvoavatarself.h"
#include "llviewercontrol.h"
@@ -54,7 +55,7 @@ static const U32 OVER_LIMIT_UPDATE_DELAY = 70;
static const U32 WARN_HUD_OBJECTS_LIMIT = 1000;
static const U32 WARN_HUD_TEXTURES_LIMIT = 200;
static const U32 WARN_HUD_OVERSIZED_TEXTURES_LIMIT = 6;
-static const U32 WARN_HUD_TEXTURE_MEMORY_LIMIT = 10000000; // in pixels
+static const U32 WARN_HUD_TEXTURE_MEMORY_LIMIT = 32000000; // in bytes
LLAvatarRenderNotifier::LLAvatarRenderNotifier() :
@@ -271,7 +272,17 @@ void LLAvatarRenderNotifier::updateNotificationAgent(U32 agentComplexity)
// LLHUDRenderNotifier
-LLHUDRenderNotifier::LLHUDRenderNotifier()
+static const char* e_hud_messages[] =
+{
+ "hud_render_textures_warning",
+ "hud_render_cramped_warning",
+ "hud_render_heavy_textures_warning",
+ "hud_render_cost_warning",
+ "hud_render_memory_warning",
+};
+
+LLHUDRenderNotifier::LLHUDRenderNotifier() :
+mReportedHUDWarning(WARN_NONE)
{
}
@@ -279,118 +290,200 @@ LLHUDRenderNotifier::~LLHUDRenderNotifier()
{
}
-void LLHUDRenderNotifier::updateNotificationHUD(LLHUDComplexity new_complexity)
+void LLHUDRenderNotifier::updateNotificationHUD(hud_complexity_list_t complexity)
{
- if (!isAgentAvatarValid())
+ if (!isAgentAvatarValid() || !gAgentWearables.areWearablesLoaded())
{
// data not ready.
return;
}
- static const char* hud_memory = "hud_render_memory_warning";
- static const char* hud_cost = "hud_render_cost_warning";
- static const char* hud_heavy = "hud_render_heavy_textures_warning";
- static const char* hud_cramped = "hud_render_cramped_warning";
- static const char* hud_textures = "hud_render_textures_warning";
+ // TODO:
+ // Find a way to show message with list of issues, but without making it too large
+ // and intrusive.
- static LLCachedControl<U32> max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0U); // ties max HUD cost to avatar cost
- static LLCachedControl<U32> max_objects_count(gSavedSettings, "RenderHUDObjectsWarning", WARN_HUD_OBJECTS_LIMIT);
- static LLCachedControl<U32> max_textures_count(gSavedSettings, "RenderHUDTexturesWarning", WARN_HUD_TEXTURES_LIMIT);
- static LLCachedControl<U32> max_oversized_count(gSavedSettings, "RenderHUDOversizedTexturesWarning", WARN_HUD_OVERSIZED_TEXTURES_LIMIT);
- static LLCachedControl<U32> max_texture_memory(gSavedSettings, "RenderHUDTexturesVirtualMemoryWarning", WARN_HUD_TEXTURE_MEMORY_LIMIT);
+ LLHUDComplexity new_total_complexity;
+ LLHUDComplexity report_complexity;
- if (mHUDPopUpDelayTimer.hasExpired())
+ hud_complexity_list_t::iterator iter = complexity.begin();
+ hud_complexity_list_t::iterator end = complexity.end();
+ EWarnLevel warning_level = WARN_NONE;
+ for (; iter != end; ++iter)
{
- // Show warning with highest importance (5m delay between warnings by default)
- // TODO:
- // Consider showing message with list of issues.
- // For now shows one after another if update arrives and timer expired, so
- // consider showing only one most important or consider triggering not
- // only in case of update
- if (mReportedHUDComplexity.texturesSizeTotal < new_complexity.texturesSizeTotal
- && new_complexity.texturesSizeTotal > max_texture_memory)
+ LLHUDComplexity object_complexity = *iter;
+ EWarnLevel object_level = getWarningType(object_complexity, report_complexity);
+ if (object_level >= 0)
{
- displayHUDNotification(hud_memory);
- LL_DEBUGS("HUDdetail") << "HUD memory usage over limit,"
- << " was " << mReportedHUDComplexity.texturesSizeTotal
- << " is " << new_complexity.texturesSizeTotal << LL_ENDL;
- mReportedHUDComplexity.texturesSizeTotal = new_complexity.texturesSizeTotal;
+ warning_level = object_level;
+ report_complexity = object_complexity;
}
- else if ((mReportedHUDComplexity.objectsCost < new_complexity.objectsCost
- || mReportedHUDComplexity.texturesCost < new_complexity.texturesCost)
- && max_render_cost > 0
- && new_complexity.objectsCost + new_complexity.texturesCost > max_render_cost)
- {
- LL_DEBUGS("HUDdetail") << "HUD complexity over limit,"
- << " HUD textures cost: " << new_complexity.texturesCost
- << " HUD objects cost: " << new_complexity.objectsCost << LL_ENDL;
- displayHUDNotification(hud_cost);
- mReportedHUDComplexity.objectsCost = new_complexity.objectsCost;
- mReportedHUDComplexity.texturesCost = new_complexity.texturesCost;
- }
- else if (mReportedHUDComplexity.largeTexturesCount < new_complexity.largeTexturesCount
- && new_complexity.largeTexturesCount > max_oversized_count)
- {
- LL_DEBUGS("HUDdetail") << "HUD contains to many large textures: "
- << new_complexity.largeTexturesCount << LL_ENDL;
- displayHUDNotification(hud_heavy);
- mReportedHUDComplexity.largeTexturesCount = new_complexity.largeTexturesCount;
- }
- else if (mReportedHUDComplexity.texturesCount < new_complexity.texturesCount
- && new_complexity.texturesCount > max_textures_count)
- {
- LL_DEBUGS("HUDdetail") << "HUD contains too many textures: "
- << new_complexity.texturesCount << LL_ENDL;
- displayHUDNotification(hud_cramped);
- mReportedHUDComplexity.texturesCount = new_complexity.texturesCount;
- }
- else if (mReportedHUDComplexity.objectsCount < new_complexity.objectsCount
- && new_complexity.objectsCount > max_objects_count)
+ new_total_complexity.objectsCost += object_complexity.objectsCost;
+ new_total_complexity.objectsCount += object_complexity.objectsCount;
+ new_total_complexity.texturesCost += object_complexity.texturesCost;
+ new_total_complexity.texturesCount += object_complexity.texturesCount;
+ new_total_complexity.largeTexturesCount += object_complexity.largeTexturesCount;
+ new_total_complexity.texturesMemoryTotal += object_complexity.texturesMemoryTotal;
+ }
+
+ if (mHUDPopUpDelayTimer.hasExpired() || isNotificationVisible())
+ {
+ if (warning_level >= 0)
{
- LL_DEBUGS("HUDdetail") << "HUD contains too many objects: "
- << new_complexity.objectsCount << LL_ENDL;
- displayHUDNotification(hud_textures);
- mReportedHUDComplexity.objectsCount = new_complexity.objectsCount;
+ // Display info about most complex HUD object
+ // make sure it shown only once unless object's complexity or object itself changed
+ if (mReportedHUDComplexity.objectId != report_complexity.objectId
+ || mReportedHUDWarning != warning_level)
+ {
+ displayHUDNotification(warning_level, report_complexity.objectId, report_complexity.objectName, report_complexity.jointName);
+ mReportedHUDComplexity = report_complexity;
+ mReportedHUDWarning = warning_level;
+ }
}
else
{
- // all warnings displayed, just store everything so that we will
- // be able to reduce values and show warnings again later
- mReportedHUDComplexity = new_complexity;
+ // Check if total complexity is above threshold and above previous warning
+ // Show warning with highest importance (5m delay between warnings by default)
+ if (!mReportedHUDComplexity.objectId.isNull())
+ {
+ mReportedHUDComplexity.reset();
+ mReportedHUDWarning = WARN_NONE;
+ }
+
+ warning_level = getWarningType(new_total_complexity, mReportedHUDComplexity);
+ if (warning_level >= 0 && mReportedHUDWarning != warning_level)
+ {
+ displayHUDNotification(warning_level);
+ }
+ mReportedHUDComplexity = new_total_complexity;
+ mReportedHUDWarning = warning_level;
}
}
+ else if (warning_level >= 0)
+ {
+ LL_DEBUGS("HUDdetail") << "HUD individual warning postponed" << LL_ENDL;
+ }
+
+ if (mLatestHUDComplexity.objectsCost != new_total_complexity.objectsCost
+ || mLatestHUDComplexity.objectsCount != new_total_complexity.objectsCount
+ || mLatestHUDComplexity.texturesCost != new_total_complexity.texturesCost
+ || mLatestHUDComplexity.texturesCount != new_total_complexity.texturesCount
+ || mLatestHUDComplexity.largeTexturesCount != new_total_complexity.largeTexturesCount
+ || mLatestHUDComplexity.texturesMemoryTotal != new_total_complexity.texturesMemoryTotal)
+ {
+ LL_INFOS("HUDdetail") << "HUD textures count: " << new_total_complexity.texturesCount
+ << " HUD textures cost: " << new_total_complexity.texturesCost
+ << " Large textures: " << new_total_complexity.largeTexturesCount
+ << " HUD objects cost: " << new_total_complexity.objectsCost
+ << " HUD objects count: " << new_total_complexity.objectsCount << LL_ENDL;
+
+ mLatestHUDComplexity = new_total_complexity;
+ }
+}
+
+bool LLHUDRenderNotifier::isNotificationVisible()
+{
+ return mHUDNotificationPtr != NULL && mHUDNotificationPtr->isActive();
+}
+
+// private static
+LLHUDRenderNotifier::EWarnLevel LLHUDRenderNotifier::getWarningType(LLHUDComplexity object_complexity, LLHUDComplexity cmp_complexity)
+{
+ static LLCachedControl<U32> max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0U); // ties max HUD cost to avatar cost
+ static LLCachedControl<U32> max_objects_count(gSavedSettings, "RenderHUDObjectsWarning", WARN_HUD_OBJECTS_LIMIT);
+ static LLCachedControl<U32> max_textures_count(gSavedSettings, "RenderHUDTexturesWarning", WARN_HUD_TEXTURES_LIMIT);
+ static LLCachedControl<U32> max_oversized_count(gSavedSettings, "RenderHUDOversizedTexturesWarning", WARN_HUD_OVERSIZED_TEXTURES_LIMIT);
+ static LLCachedControl<U32> max_texture_memory(gSavedSettings, "RenderHUDTexturesMemoryWarning", WARN_HUD_TEXTURE_MEMORY_LIMIT);
+
+ if (cmp_complexity.texturesMemoryTotal < object_complexity.texturesMemoryTotal
+ && object_complexity.texturesMemoryTotal > (F64Bytes)max_texture_memory)
+ {
+ // Note: Memory might not be accurate since texture is still loading or discard level changes
+
+ LL_DEBUGS("HUDdetail") << "HUD " << object_complexity.objectName << " memory usage over limit, "
+ << " was " << cmp_complexity.texturesMemoryTotal
+ << " is " << object_complexity.texturesMemoryTotal << LL_ENDL;
+
+ return WARN_MEMORY;
+ }
+ else if ((cmp_complexity.objectsCost < object_complexity.objectsCost
+ || cmp_complexity.texturesCost < object_complexity.texturesCost)
+ && max_render_cost > 0
+ && object_complexity.objectsCost + object_complexity.texturesCost > max_render_cost)
+ {
+ LL_DEBUGS("HUDdetail") << "HUD " << object_complexity.objectName << " complexity over limit,"
+ << " HUD textures cost: " << object_complexity.texturesCost
+ << " HUD objects cost: " << object_complexity.objectsCost << LL_ENDL;
- if (mLatestHUDComplexity.objectsCost != new_complexity.objectsCost
- || mLatestHUDComplexity.objectsCount != new_complexity.objectsCount
- || mLatestHUDComplexity.texturesCost != new_complexity.texturesCost
- || mLatestHUDComplexity.texturesCount != new_complexity.texturesCount
- || mLatestHUDComplexity.largeTexturesCount != new_complexity.largeTexturesCount
- || mLatestHUDComplexity.texturesSizeTotal != new_complexity.texturesSizeTotal)
+ return WARN_COST;
+ }
+ else if (cmp_complexity.largeTexturesCount < object_complexity.largeTexturesCount
+ && object_complexity.largeTexturesCount > max_oversized_count)
{
- LL_INFOS("HUDdetail") << "HUD textures count: " << new_complexity.texturesCount
- << " HUD textures cost: " << new_complexity.texturesCost
- << " Large textures: " << new_complexity.largeTexturesCount
- << " HUD objects cost: " << new_complexity.objectsCost
- << " HUD objects count: " << new_complexity.objectsCount << LL_ENDL;
+ LL_DEBUGS("HUDdetail") << "HUD " << object_complexity.objectName << " contains to many large textures: "
+ << object_complexity.largeTexturesCount << LL_ENDL;
- mLatestHUDComplexity = new_complexity;
+ return WARN_HEAVY;
}
-
+ else if (cmp_complexity.texturesCount < object_complexity.texturesCount
+ && object_complexity.texturesCount > max_textures_count)
+ {
+ LL_DEBUGS("HUDdetail") << "HUD " << object_complexity.objectName << " contains too many textures: "
+ << object_complexity.texturesCount << LL_ENDL;
+
+ return WARN_CRAMPED;
+ }
+ else if (cmp_complexity.objectsCount < object_complexity.objectsCount
+ && object_complexity.objectsCount > max_objects_count)
+ {
+ LL_DEBUGS("HUDdetail") << "HUD " << object_complexity.objectName << " contains too many objects: "
+ << object_complexity.objectsCount << LL_ENDL;
+
+ return WARN_TEXTURES;
+ }
+ return WARN_NONE;
}
-void LLHUDRenderNotifier::displayHUDNotification(const char* message)
+void LLHUDRenderNotifier::displayHUDNotification(EWarnLevel warn_type, LLUUID obj_id, std::string obj_name, std::string joint_name)
{
static LLCachedControl<U32> pop_up_delay(gSavedSettings, "ComplexityChangesPopUpDelay", 300);
static LLCachedControl<U32> expire_delay(gSavedSettings, "ShowMyComplexityChanges", 20);
LLDate expire_date(LLDate::now().secondsSinceEpoch() + expire_delay);
- LLSD args;
- args["HUD_REASON"] = LLTrans::getString(message);
+ // Since we need working "ignoretext" there is no other way but to
+ // use single notification while constructing it from multiple pieces
+ LLSD reason_args;
+ if (obj_id.isNull())
+ {
+ reason_args["HUD_DETAILS"] = LLTrans::getString("hud_description_total");
+ }
+ else
+ {
+ if (obj_name.empty())
+ {
+ LL_WARNS("HUDdetail") << "Object name not assigned" << LL_ENDL;
+ }
+ if (joint_name.empty())
+ {
+ std::string verb = "select?name=" + LLURI::escape(obj_name);
+ reason_args["HUD_DETAILS"] = LLSLURL("inventory", obj_id, verb.c_str()).getSLURLString();
+ }
+ else
+ {
+ LLSD object_args;
+ std::string verb = "select?name=" + LLURI::escape(obj_name);
+ object_args["OBJ_NAME"] = LLSLURL("inventory", obj_id, verb.c_str()).getSLURLString();
+ object_args["JNT_NAME"] = LLTrans::getString(joint_name);
+ reason_args["HUD_DETAILS"] = LLTrans::getString("hud_name_with_joint", object_args);
+ }
+ }
+
+ LLSD msg_args;
+ msg_args["HUD_REASON"] = LLTrans::getString(e_hud_messages[warn_type], reason_args);
- LLNotifications::instance().add(LLNotification::Params()
+ mHUDNotificationPtr = LLNotifications::instance().add(LLNotification::Params()
.name("HUDComplexityWarning")
.expiry(expire_date)
- .substitutions(args));
+ .substitutions(msg_args));
mHUDPopUpDelayTimer.resetWithExpiry(pop_up_delay);
}