diff --git a/doc/contributions.txt b/doc/contributions.txt
index ef035c7035..fa61ab7177 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -835,6 +835,7 @@ Khyota Wulluf
Kimar Coba
Kithrak Kirkorian
Kitty Barnett
+ BUG-228665
VWR-19699
STORM-288
STORM-799
diff --git a/indra/llinventory/llinventorysettings.cpp b/indra/llinventory/llinventorysettings.cpp
index a2ed9e1596..4d4c002a03 100644
--- a/indra/llinventory/llinventorysettings.cpp
+++ b/indra/llinventory/llinventorysettings.cpp
@@ -33,10 +33,6 @@
#include "llsingleton.h"
#include "llinvtranslationbrdg.h"
-//=========================================================================
-namespace {
- LLTranslationBridge::ptr_t sTranslator;
-}
//=========================================================================
struct SettingsEntry : public LLDictionaryEntry
@@ -49,14 +45,14 @@ struct SettingsEntry : public LLDictionaryEntry
mLabel(name),
mIconName(iconName)
{
- std::string transdname = sTranslator->getString(mLabel);
+ std::string transdname = LLSettingsType::getInstance()->mTranslator->getString(mLabel);
if (!transdname.empty())
{
mLabel = transdname;
}
// Name of newly created setting is not translated
- transdname = sTranslator->getString(mDefaultNewName);
+ transdname = LLSettingsType::getInstance()->mTranslator->getString(mDefaultNewName);
if (!transdname.empty())
{
mDefaultNewName = transdname;
@@ -92,6 +88,16 @@ void LLSettingsDictionary::initSingleton()
//=========================================================================
+LLSettingsType::LLSettingsType(LLTranslationBridge::ptr_t &trans)
+{
+ mTranslator = trans;
+}
+
+LLSettingsType::~LLSettingsType()
+{
+ mTranslator.reset();
+}
+
LLSettingsType::type_e LLSettingsType::fromInventoryFlags(U32 flags)
{
return (LLSettingsType::type_e)(flags & LLInventoryItemFlags::II_FLAGS_SUBTYPE_MASK);
@@ -112,13 +118,3 @@ std::string LLSettingsType::getDefaultName(LLSettingsType::type_e type)
return getDefaultName(ST_INVALID);
return entry->mDefaultNewName;
}
-
-void LLSettingsType::initClass(LLTranslationBridge::ptr_t &trans)
-{
- sTranslator = trans;
-}
-
-void LLSettingsType::cleanupClass()
-{
- sTranslator.reset();
-}
diff --git a/indra/llinventory/llinventorysettings.h b/indra/llinventory/llinventorysettings.h
index 906540689c..6b6685d088 100644
--- a/indra/llinventory/llinventorysettings.h
+++ b/indra/llinventory/llinventorysettings.h
@@ -30,9 +30,15 @@
#include "llinventorytype.h"
#include "llinvtranslationbrdg.h"
+#include "llsingleton.h"
-class LLSettingsType
+class LLSettingsType : public LLParamSingleton
{
+ LLSINGLETON(LLSettingsType, LLTranslationBridge::ptr_t &trans);
+ ~LLSettingsType();
+
+ friend struct SettingsEntry;
+
public:
enum type_e
{
@@ -48,8 +54,9 @@ public:
static LLInventoryType::EIconName getIconName(type_e type);
static std::string getDefaultName(type_e type);
- static void initClass(LLTranslationBridge::ptr_t &trans);
- static void cleanupClass();
+protected:
+
+ LLTranslationBridge::ptr_t mTranslator;
};
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index a14bc744bb..f8c4e9b7f5 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -2707,9 +2707,10 @@ LLGLSPipelineBlendSkyBox::LLGLSPipelineBlendSkyBox(bool depth_test, bool depth_w
}
#if LL_WINDOWS
-// Expose desired use of high-performance graphics processor to Optimus driver
+// Expose desired use of high-performance graphics processor to Optimus driver and to AMD driver
extern "C"
-{
- _declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
+{
+ __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
+ __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
}
#endif
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index b31fb2d6ef..8fb81acbd9 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -1359,7 +1359,7 @@ bool LLVertexBuffer::createGLBuffer(U32 size)
return true;
}
- bool sucsess = true;
+ bool success = true;
mEmpty = true;
@@ -1381,9 +1381,9 @@ bool LLVertexBuffer::createGLBuffer(U32 size)
if (!mMappedData)
{
- sucsess = false;
+ success = false;
}
- return sucsess;
+ return success;
}
bool LLVertexBuffer::createGLIndices(U32 size)
@@ -1398,7 +1398,7 @@ bool LLVertexBuffer::createGLIndices(U32 size)
return true;
}
- bool sucsess = true;
+ bool success = true;
mEmpty = true;
@@ -1423,9 +1423,9 @@ bool LLVertexBuffer::createGLIndices(U32 size)
if (!mMappedIndexData)
{
- sucsess = false;
+ success = false;
}
- return sucsess;
+ return success;
}
void LLVertexBuffer::destroyGLBuffer()
@@ -1472,7 +1472,7 @@ bool LLVertexBuffer::updateNumVerts(S32 nverts)
{
llassert(nverts >= 0);
- bool sucsess = true;
+ bool success = true;
if (nverts > 65536)
{
@@ -1484,34 +1484,34 @@ bool LLVertexBuffer::updateNumVerts(S32 nverts)
if (needed_size > mSize || needed_size <= mSize/2)
{
- sucsess &= createGLBuffer(needed_size);
+ success &= createGLBuffer(needed_size);
}
sVertexCount -= mNumVerts;
mNumVerts = nverts;
sVertexCount += mNumVerts;
- return sucsess;
+ return success;
}
bool LLVertexBuffer::updateNumIndices(S32 nindices)
{
llassert(nindices >= 0);
- bool sucsess = true;
+ bool success = true;
U32 needed_size = sizeof(U16) * nindices;
if (needed_size > mIndicesSize || needed_size <= mIndicesSize/2)
{
- sucsess &= createGLIndices(needed_size);
+ success &= createGLIndices(needed_size);
}
sIndexCount -= mNumIndices;
mNumIndices = nindices;
sIndexCount += mNumIndices;
- return sucsess;
+ return success;
}
bool LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
@@ -1524,10 +1524,10 @@ bool LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
LL_ERRS() << "Bad vertex buffer allocation: " << nverts << " : " << nindices << LL_ENDL;
}
- bool sucsess = true;
+ bool success = true;
- sucsess &= updateNumVerts(nverts);
- sucsess &= updateNumIndices(nindices);
+ success &= updateNumVerts(nverts);
+ success &= updateNumIndices(nindices);
if (create && (nverts || nindices))
{
@@ -1543,7 +1543,7 @@ bool LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
}
}
- return sucsess;
+ return success;
}
static LLTrace::BlockTimerStatHandle FTM_SETUP_VERTEX_ARRAY("Setup VAO");
diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index 52c596c7f5..4812de1109 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -346,12 +346,9 @@ static LLTrace::BlockTimerStatHandle FTM_FILTER("Filter Folder View");
void LLFolderView::filter( LLFolderViewFilter& filter )
{
LL_RECORD_BLOCK_TIME(FTM_FILTER);
- // Replace frequently called gSavedSettings
- //filter.resetTime(llclamp(LLUI::getInstance()->mSettingGroups["config"]->getS32(mParentPanel.get()->getVisible() ? "FilterItemsMaxTimePerFrameVisible" : "FilterItemsMaxTimePerFrameUnvisible"), 1, 100));
- static LLCachedControl sFilterItemsMaxTimePerFrameVisible(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameVisible");
- static LLCachedControl sFilterItemsMaxTimePerFrameUnvisible(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameUnvisible");
- filter.resetTime(llclamp((mParentPanel.get()->getVisible() ? sFilterItemsMaxTimePerFrameVisible() : sFilterItemsMaxTimePerFrameUnvisible()), 1, 100));
- //
+ static LLCachedControl filter_visible(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameVisible", 10);
+ static LLCachedControl filter_hidden(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameUnvisible", 1);
+ filter.resetTime(llclamp(mParentPanel.get()->getVisible() ? filter_visible() : filter_hidden(), 1, 100));
// Note: we filter the model, not the view
getViewModelItem()->filter(filter);
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 1193093bee..ac47494655 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -129,6 +129,7 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
: LLView(p),
mLabelWidth(0),
mLabelWidthDirty(false),
+ mSuffixNeedsRefresh(false),
mLabelPaddingRight(DEFAULT_LABEL_PADDING_RIGHT),
mParentFolder( NULL ),
mIsSelected( FALSE ),
@@ -200,11 +201,25 @@ LLFolderViewItem::~LLFolderViewItem()
BOOL LLFolderViewItem::postBuild()
{
- refresh();
+ LLFolderViewModelItem& vmi = *getViewModelItem();
+ // getDisplayName() is expensive (due to internal getLabelSuffix() and name building)
+ // it also sets search strings so it requires a filter reset
+ mLabel = vmi.getDisplayName();
+ setToolTip(vmi.getName());
+
+ // Dirty the filter flag of the model from the view (CHUI-849)
+ vmi.dirtyFilter();
+
+ // Don't do full refresh on constructor if it is possible to avoid
+ // it significantly slows down bulk view creation.
+ // Todo: Ideally we need to move getDisplayName() out of constructor as well.
+ // Like: make a logic that will let filter update search string,
+ // while LLFolderViewItem::arrange() updates visual part
+ mSuffixNeedsRefresh = true;
+ mLabelWidthDirty = true;
return TRUE;
}
-
LLFolderView* LLFolderViewItem::getRoot()
{
return mRoot;
@@ -299,24 +314,51 @@ BOOL LLFolderViewItem::isPotentiallyVisible(S32 filter_generation)
void LLFolderViewItem::refresh()
{
- LLFolderViewModelItem& vmi = *getViewModelItem();
+ LLFolderViewModelItem& vmi = *getViewModelItem();
- mLabel = vmi.getDisplayName();
+ mLabel = vmi.getDisplayName();
+ setToolTip(vmi.getName());
+ // icons are slightly expensive to get, can be optimized
+ // see LLInventoryIcon::getIcon()
+ mIcon = vmi.getIcon();
+ mIconOpen = vmi.getIconOpen();
+ mIconOverlay = vmi.getIconOverlay();
- setToolTip(vmi.getName());
- mIcon = vmi.getIcon();
- mIconOpen = vmi.getIconOpen();
- mIconOverlay = vmi.getIconOverlay();
+ if (mRoot->useLabelSuffix())
+ {
+ // Very Expensive!
+ // Can do a number of expensive checks, like checking active motions, wearables or friend list
+ mLabelStyle = vmi.getLabelStyle();
+ mLabelSuffix = vmi.getLabelSuffix();
+ }
+
+ // Dirty the filter flag of the model from the view (CHUI-849)
+ vmi.dirtyFilter();
+
+ mLabelWidthDirty = true;
+ mSuffixNeedsRefresh = false;
+}
+
+void LLFolderViewItem::refreshSuffix()
+{
+ LLFolderViewModelItem const* vmi = getViewModelItem();
+
+ // icons are slightly expensive to get, can be optimized
+ // see LLInventoryIcon::getIcon()
+ mIcon = vmi->getIcon();
+ mIconOpen = vmi->getIconOpen();
+ mIconOverlay = vmi->getIconOverlay();
if (mRoot->useLabelSuffix())
{
- mLabelStyle = vmi.getLabelStyle();
- mLabelSuffix = vmi.getLabelSuffix();
+ // Very Expensive!
+ // Can do a number of expensive checks, like checking active motions, wearables or friend list
+ mLabelStyle = vmi->getLabelStyle();
+ mLabelSuffix = vmi->getLabelSuffix();
}
- mLabelWidthDirty = true;
- // Dirty the filter flag of the model from the view (CHUI-849)
- vmi.dirtyFilter();
+ mLabelWidthDirty = true;
+ mSuffixNeedsRefresh = false;
}
// Utility function for LLFolderView
@@ -385,6 +427,12 @@ S32 LLFolderViewItem::arrange( S32* width, S32* height )
if (mLabelWidthDirty)
{
+ if (mSuffixNeedsRefresh)
+ {
+ // Expensive. But despite refreshing label,
+ // it is purely visual, so it is fine to do at our laisure
+ refreshSuffix();
+ }
mLabelWidth = getLabelXPos() + getLabelFontForStyle(mLabelStyle)->getWidth(mLabel) + getLabelFontForStyle(mLabelStyle)->getWidth(mLabelSuffix) + mLabelPaddingRight;
mLabelWidthDirty = false;
}
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index 51d07769fc..7baf88a629 100644
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -99,6 +99,7 @@ protected:
LLPointer mViewModelItem;
LLFontGL::StyleFlags mLabelStyle;
std::string mLabelSuffix;
+ bool mSuffixNeedsRefresh; //suffix and icons
LLUIImagePtr mIcon,
mIconOpen,
mIconOverlay;
@@ -276,8 +277,13 @@ public:
virtual BOOL passedFilter(S32 filter_generation = -1);
virtual BOOL isPotentiallyVisible(S32 filter_generation = -1);
- // refresh information from the object being viewed.
- virtual void refresh();
+ // refresh information from the object being viewed.
+ // refreshes label, suffixes and sets icons. Expensive!
+ // Causes filter update
+ virtual void refresh();
+ // refreshes suffixes and sets icons. Expensive!
+ // Does not need filter update
+ virtual void refreshSuffix();
// LLView functionality
virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
diff --git a/indra/llui/llfolderviewmodel.cpp b/indra/llui/llfolderviewmodel.cpp
index 0f82f08892..ea106b5fae 100644
--- a/indra/llui/llfolderviewmodel.cpp
+++ b/indra/llui/llfolderviewmodel.cpp
@@ -48,11 +48,8 @@ std::string LLFolderViewModelCommon::getStatusText()
void LLFolderViewModelCommon::filter()
{
- // Replace frequently called gSavedSettings
- //getFilter().resetTime(llclamp(LLUI::getInstance()->mSettingGroups["config"]->getS32("FilterItemsMaxTimePerFrameVisible"), 1, 100));
- static LLCachedControl sFilterItemsMaxTimePerFrameVisible(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameVisible");
- getFilter().resetTime(llclamp(sFilterItemsMaxTimePerFrameVisible(), 1, 100));
- //
+ static LLCachedControl filter_visible(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameVisible", 10);
+ getFilter().resetTime(llclamp(filter_visible(), 1, 100));
mFolderView->getViewModelItem()->filter(getFilter());
}
diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h
index cbd0cd8d46..082eb91368 100644
--- a/indra/llui/llfolderviewmodel.h
+++ b/indra/llui/llfolderviewmodel.h
@@ -295,26 +295,7 @@ public:
typedef std::list child_list_t;
virtual void addChild(LLFolderViewModelItem* child)
- {
- // Avoid duplicates: bail out if that child is already present in the list
- // Note: this happens when models are created before views
-
- // Ugh, linear search! Replace this by simply looking if the parent matches
-
- // child_list_t::const_iterator iter;
- // for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
- // {
- // if (child == *iter)
- // {
- // return;
- // }
- // }
-
- if( child->getParent() == this )
- return;
-
- //
-
+ {
mChildren.push_back(child);
child->setParent(this);
dirtyFilter();
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index 5e945a7497..1b158bbead 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -520,13 +520,17 @@ std::string LLUrlEntrySLURL::getLocation(const std::string &url) const
}
//
-// LLUrlEntrySeconlifeURL Describes *secondlife.com/ *lindenlab.com/ and *tilia-inc.com/ urls to substitute icon 'hand.png' before link
+// LLUrlEntrySeconlifeURL Describes *secondlife.com/ *lindenlab.com/ *secondlifegrid.net/ and *tilia-inc.com/ urls to substitute icon 'hand.png' before link
//
LLUrlEntrySecondlifeURL::LLUrlEntrySecondlifeURL()
{
mPattern = boost::regex("((http://([-\\w\\.]*\\.)?(secondlife|lindenlab|tilia-inc)\\.com)"
"|"
- "(https://([-\\w\\.]*\\.)?(secondlife|lindenlab|tilia-inc)\\.com(:\\d{1,5})?))"
+ "(http://([-\\w\\.]*\\.)?secondlifegrid\\.net)"
+ "|"
+ "(https://([-\\w\\.]*\\.)?(secondlife|lindenlab|tilia-inc)\\.com(:\\d{1,5})?)"
+ "|"
+ "(https://([-\\w\\.]*\\.)?secondlifegrid\\.net(:\\d{1,5})?))"
"\\/\\S*",
boost::regex::perl|boost::regex::icase);
@@ -564,12 +568,14 @@ std::string LLUrlEntrySecondlifeURL::getTooltip(const std::string &url) const
}
//
-// LLUrlEntrySimpleSecondlifeURL Describes *secondlife.com *lindenlab.com and *tilia-inc.com urls to substitute icon 'hand.png' before link
+// LLUrlEntrySimpleSecondlifeURL Describes *secondlife.com *lindenlab.com *secondlifegrid.net and *tilia-inc.com urls to substitute icon 'hand.png' before link
//
LLUrlEntrySimpleSecondlifeURL::LLUrlEntrySimpleSecondlifeURL()
{
- mPattern = boost::regex("https?://([-\\w\\.]*\\.)?(secondlife|lindenlab|tilia-inc)\\.com(?!\\S)",
- boost::regex::perl|boost::regex::icase);
+ mPattern = boost::regex("https?://([-\\w\\.]*\\.)?(secondlife|lindenlab|tilia-inc)\\.com(?!\\S)"
+ "|"
+ "https?://([-\\w\\.]*\\.)?secondlifegrid\\.net(?!\\S)",
+ boost::regex::perl|boost::regex::icase);
mIcon = "Hand";
mMenuName = "menu_url_http.xml";
diff --git a/indra/newview/fsexportperms.cpp b/indra/newview/fsexportperms.cpp
index d0d25fa3b7..607f849e1c 100644
--- a/indra/newview/fsexportperms.cpp
+++ b/indra/newview/fsexportperms.cpp
@@ -105,8 +105,7 @@ bool FSExportPermsCheck::canExportNode(LLSelectNode* node, bool dae)
{
if (dae)
{
- LLSD mesh_header = gMeshRepo.getMeshHeader(sculpt_params->getSculptTexture());
- exportable = mesh_header["creator"].asUUID() == gAgentID;
+ exportable = gMeshRepo.getCreatorFromHeader(sculpt_params->getSculptTexture()) == gAgentID;
}
else
{
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 3f409ad562..4bd8e33ffd 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -867,7 +867,7 @@ bool LLAppViewer::init()
LLWearableType::initParamSingleton(new LLUITranslationBridge());
LLTranslationBridge::ptr_t trans = std::make_shared();
- LLSettingsType::initClass(trans);
+ LLSettingsType::initParamSingleton(trans);
// initialize SSE options
LLVector4a::initClass();
diff --git a/indra/newview/llcommandlineparser.cpp b/indra/newview/llcommandlineparser.cpp
index fe14bc081f..06d959ba3c 100644
--- a/indra/newview/llcommandlineparser.cpp
+++ b/indra/newview/llcommandlineparser.cpp
@@ -402,23 +402,30 @@ bool LLCommandLineParser::parseCommandLineString(const std::string& str)
}
}
- // Split the string content into tokens
- const char* escape_chars = "\\";
- const char* separator_chars = "\r\n ";
- const char* quote_chars = "\"'";
- boost::escaped_list_separator sep(escape_chars, separator_chars, quote_chars);
- boost::tokenizer< boost::escaped_list_separator > tok(cmd_line_string, sep);
std::vector tokens;
- // std::copy(tok.begin(), tok.end(), std::back_inserter(tokens));
- for(boost::tokenizer< boost::escaped_list_separator >::iterator i = tok.begin();
- i != tok.end();
- ++i)
+ try
{
- if(0 != i->size())
+ // Split the string content into tokens
+ const char* escape_chars = "\\";
+ const char* separator_chars = "\r\n ";
+ const char* quote_chars = "\"'";
+ boost::escaped_list_separator sep(escape_chars, separator_chars, quote_chars);
+ boost::tokenizer< boost::escaped_list_separator > tok(cmd_line_string, sep);
+ // std::copy(tok.begin(), tok.end(), std::back_inserter(tokens));
+ for (boost::tokenizer< boost::escaped_list_separator >::iterator i = tok.begin();
+ i != tok.end();
+ ++i)
{
- tokens.push_back(*i);
+ if (0 != i->size())
+ {
+ tokens.push_back(*i);
+ }
}
}
+ catch (...)
+ {
+ CRASH_ON_UNHANDLED_EXCEPTION(STRINGIZE("Unexpected crash while parsing: " << str));
+ }
po::command_line_parser clp(tokens);
return parseAndStoreResults(clp);
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 80166f1a10..d176c9647c 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -94,6 +94,23 @@ LLConversationItem::~LLConversationItem()
}
}
+//virtual
+void LLConversationItem::addChild(LLFolderViewModelItem* child)
+{
+ // Avoid duplicates: bail out if that child is already present in the list
+ // Note: this happens when models are created and 'parented' before views
+ // This is performance unfriendly, but conversation can addToFolder multiple times
+ child_list_t::const_iterator iter;
+ for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
+ {
+ if (child == *iter)
+ {
+ return;
+ }
+ }
+ LLFolderViewModelItemCommon::addChild(child);
+}
+
void LLConversationItem::postEvent(const std::string& event_type, LLConversationItemSession* session, LLConversationItemParticipant* participant)
{
LLUUID session_id = (session ? session->getUUID() : LLUUID());
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index fbdffc4997..68bc6d65f4 100644
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -99,6 +99,7 @@ public:
virtual void buildContextMenu(LLMenuGL& menu, U32 flags) { }
virtual BOOL isUpToDate() const { return TRUE; }
virtual bool hasChildren() const { return FALSE; }
+ virtual void addChild(LLFolderViewModelItem* child);
virtual bool potentiallyVisible() { return true; }
virtual bool filter( LLFolderViewFilter& filter) { return false; }
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 805646a2aa..0cf9ea6dfd 100644
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -432,7 +432,7 @@ void LLConversationViewSession::refresh()
// Refresh the session view from its model data
LLConversationItem* vmi = dynamic_cast(getViewModelItem());
vmi->resetRefresh();
-
+
if (mSessionTitle)
{
mSessionTitle->setText(vmi->getDisplayName());
@@ -547,7 +547,9 @@ BOOL LLConversationViewParticipant::postBuild()
}
updateChildren();
- return LLFolderViewItem::postBuild();
+ LLFolderViewItem::postBuild();
+ refresh();
+ return TRUE;
}
void LLConversationViewParticipant::draw()
@@ -621,7 +623,7 @@ void LLConversationViewParticipant::refresh()
// *TODO: We should also do something with vmi->isModerator() to echo that state in the UI somewhat
mSpeakingIndicator->setIsModeratorMuted(participant_model->isModeratorMuted());
-
+
// Do the regular upstream refresh
LLFolderViewItem::refresh();
}
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index efbf29ab0e..f28b9e1c98 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -733,17 +733,59 @@ void LLInventoryModel::createNewCategoryCoro(std::string url, LLSD postData, inv
LLUUID categoryId = result["folder_id"].asUUID();
- // Add the category to the internal representation
- LLPointer cat = new LLViewerInventoryCategory(categoryId,
- result["parent_id"].asUUID(), (LLFolderType::EType)result["type"].asInteger(),
- result["name"].asString(), gAgent.getID());
+ LLViewerInventoryCategory* folderp = gInventory.getCategory(categoryId);
+ if (!folderp)
+ {
+ // Add the category to the internal representation
+ LLPointer cat = new LLViewerInventoryCategory(categoryId,
+ result["parent_id"].asUUID(), (LLFolderType::EType)result["type"].asInteger(),
+ result["name"].asString(), gAgent.getID());
- cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL - 1); // accountForUpdate() will icrease version by 1
- cat->setDescendentCount(0);
- LLInventoryModel::LLCategoryUpdate update(cat->getParentUUID(), 1);
-
- accountForUpdate(update);
- updateCategory(cat);
+ LLInventoryModel::LLCategoryUpdate update(cat->getParentUUID(), 1);
+ accountForUpdate(update);
+
+ cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL - 1); // accountForUpdate() will icrease version by 1
+ cat->setDescendentCount(0);
+ updateCategory(cat);
+ }
+ else
+ {
+ // bulk processing was faster than coroutine (coro request->processBulkUpdateInventory->coro response)
+ // category already exists, but needs an update
+ if (folderp->getVersion() != LLViewerInventoryCategory::VERSION_INITIAL
+ || folderp->getDescendentCount() != LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN)
+ {
+ LL_WARNS() << "Inventory desync on folder creation. Newly created folder already has descendants or got a version.\n"
+ << "Name: " << folderp->getName()
+ << " Id: " << folderp->getUUID()
+ << " Version: " << folderp->getVersion()
+ << " Descendants: " << folderp->getDescendentCount()
+ << LL_ENDL;
+ }
+ // Recreate category with correct values
+ // Creating it anew just simplifies figuring out needed change-masks
+ // and making all needed updates, see updateCategory
+ LLPointer cat = new LLViewerInventoryCategory(categoryId,
+ result["parent_id"].asUUID(), (LLFolderType::EType)result["type"].asInteger(),
+ result["name"].asString(), gAgent.getID());
+
+ if (folderp->getParentUUID() != cat->getParentUUID())
+ {
+ LL_WARNS() << "Inventory desync on folder creation. Newly created folder has wrong parent.\n"
+ << "Name: " << folderp->getName()
+ << " Id: " << folderp->getUUID()
+ << " Expected parent: " << cat->getParentUUID()
+ << " Actual parent: " << folderp->getParentUUID()
+ << LL_ENDL;
+ LLInventoryModel::LLCategoryUpdate update(cat->getParentUUID(), 1);
+ accountForUpdate(update);
+ }
+ // else: Do not update parent, parent is already aware of the change. See processBulkUpdateInventory
+
+ cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL - 1); // accountForUpdate() will icrease version by 1
+ cat->setDescendentCount(0);
+ updateCategory(cat);
+ }
if (callback)
{
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 80a95c1419..c5db14c6dd 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -153,7 +153,7 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
mCompletionObserver(NULL),
mScroller(NULL),
mSortOrderSetting(p.sort_order_setting),
- mInventory(p.inventory),
+ mInventory(p.inventory), //inventory("", &gInventory)
mAcceptsDragAndDrop(p.accepts_drag_and_drop),
mAllowMultiSelect(p.allow_multi_select),
mAllowDrag(p.allow_drag),
@@ -566,7 +566,18 @@ void LLInventoryPanel::itemChanged(const LLUUID& item_id, U32 mask, const LLInve
view_item->destroyView();
removeItemID(idp);
}
- view_item = buildNewViews(item_id);
+
+ LLInventoryObject const* objectp = mInventory->getObject(item_id);
+ if (objectp)
+ {
+ // providing NULL directly avoids unnessesary getItemByID calls
+ view_item = buildNewViews(item_id, objectp, NULL);
+ }
+ else
+ {
+ view_item = NULL;
+ }
+
viewmodel_item =
static_cast(view_item ? view_item->getViewModelItem() : NULL);
view_folder = dynamic_cast(view_item);
@@ -609,7 +620,13 @@ void LLInventoryPanel::itemChanged(const LLUUID& item_id, U32 mask, const LLInve
if (model_item && !view_item)
{
// Add the UI element for this item.
- buildNewViews(item_id);
+ LLInventoryObject const* objectp = mInventory->getObject(item_id);
+ if (objectp)
+ {
+ // providing NULL directly avoids unnessesary getItemByID calls
+ buildNewViews(item_id, objectp, NULL);
+ }
+
// Select any newly created object that has the auto rename at top of folder root set.
if(mFolderRoot.get()->getRoot()->needsAutoRename())
{
@@ -924,7 +941,7 @@ LLFolderViewItem * LLInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge
LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
{
- LLInventoryObject const* objectp = gInventory.getObject(id);
+ LLInventoryObject const* objectp = mInventory->getObject(id);
return buildNewViews(id, objectp);
}
@@ -934,11 +951,43 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id, LLInventoryO
{
return NULL;
}
- LLFolderViewItem* folder_view_item = getItemByID(id);
+ if (!typedViewsFilter(id, objectp))
+ {
+ // if certain types are not allowed permanently, no reason to create views
+ return NULL;
+ }
const LLUUID &parent_id = objectp->getParentUUID();
- LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)getItemByID(parent_id);
-
+ LLFolderViewItem* folder_view_item = getItemByID(id);
+ LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)getItemByID(parent_id);
+
+ return buildViewsTree(id, parent_id, objectp, folder_view_item, parent_folder);
+}
+
+LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id, LLInventoryObject const* objectp, LLFolderViewItem *folder_view_item)
+{
+ if (!objectp)
+ {
+ return NULL;
+ }
+ if (!typedViewsFilter(id, objectp))
+ {
+ // if certain types are not allowed permanently, no reason to create views
+ return NULL;
+ }
+
+ const LLUUID &parent_id = objectp->getParentUUID();
+ LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)getItemByID(parent_id);
+
+ return buildViewsTree(id, parent_id, objectp, folder_view_item, parent_folder);
+}
+
+LLFolderViewItem* LLInventoryPanel::buildViewsTree(const LLUUID& id,
+ const LLUUID& parent_id,
+ LLInventoryObject const* objectp,
+ LLFolderViewItem *folder_view_item,
+ LLFolderViewFolder *parent_folder)
+{
// Force the creation of an extra root level folder item if required by the inventory panel (default is "false")
bool allow_drop = true;
bool create_root = false;
@@ -959,7 +1008,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id, LLInventoryO
{
if (objectp->getType() <= LLAssetType::AT_NONE)
{
- LL_WARNS() << "LLInventoryPanel::buildNewViews called with invalid objectp->mType : "
+ LL_WARNS() << "LLInventoryPanel::buildViewsTree called with invalid objectp->mType : "
<< ((S32)objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID()
<< LL_ENDL;
return NULL;
@@ -968,7 +1017,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id, LLInventoryO
if (objectp->getType() >= LLAssetType::AT_COUNT)
{
// Example: Happens when we add assets of new, not yet supported type to library
- LL_DEBUGS() << "LLInventoryPanel::buildNewViews called with unknown objectp->mType : "
+ LL_DEBUGS() << "LLInventoryPanel::buildViewsTree called with unknown objectp->mType : "
<< ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID()
<< LL_ENDL;
@@ -1045,26 +1094,58 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id, LLInventoryO
LLViewerInventoryCategory::cat_array_t* categories;
LLViewerInventoryItem::item_array_t* items;
mInventory->lockDirectDescendentArrays(id, categories, items);
-
+
+ LLFolderViewFolder *parentp = dynamic_cast(folder_view_item);
+
if(categories)
- {
+ {
+ bool has_folders = parentp->getFoldersCount() > 0;
for (LLViewerInventoryCategory::cat_array_t::const_iterator cat_iter = categories->begin();
cat_iter != categories->end();
++cat_iter)
{
const LLViewerInventoryCategory* cat = (*cat_iter);
- buildNewViews(cat->getUUID());
+ if (typedViewsFilter(cat->getUUID(), cat))
+ {
+ if (has_folders)
+ {
+ // This can be optimized: we don't need to call getItemByID()
+ // each time, especially since content is growing, we can just
+ // iter over copy of mItemMap in some way
+ LLFolderViewItem* view_itemp = getItemByID(cat->getUUID());
+ buildViewsTree(cat->getUUID(), id, cat, view_itemp, parentp);
+ }
+ else
+ {
+ buildViewsTree(cat->getUUID(), id, cat, NULL, parentp);
+ }
+ }
}
}
if(items)
- {
+ {
+ bool has_items = parentp->getItemsCount() > 0;
for (LLViewerInventoryItem::item_array_t::const_iterator item_iter = items->begin();
item_iter != items->end();
++item_iter)
{
const LLViewerInventoryItem* item = (*item_iter);
- buildNewViews(item->getUUID());
+ if (typedViewsFilter(item->getUUID(), item))
+ {
+ if (has_items)
+ {
+ // This can be optimized: we don't need to call getItemByID()
+ // each time, especially since content is growing, we can just
+ // iter over copy of mItemMap in some way
+ LLFolderViewItem* view_itemp = getItemByID(item->getUUID());
+ buildViewsTree(item->getUUID(), id, item, view_itemp, parentp);
+ }
+ else
+ {
+ buildViewsTree(item->getUUID(), id, item, NULL, parentp);
+ }
+ }
}
}
mInventory->unlockDirectDescendentArrays(id);
@@ -1966,41 +2047,7 @@ LLInventoryRecentItemsPanel::LLInventoryRecentItemsPanel( const Params& params)
/************************************************************************/
/* Asset Pre-Filtered Inventory Panel related class */
-/* Exchanges filter's flexibility for speed of generation and */
-/* improved performance */
/************************************************************************/
-class LLAssetFilteredInventoryPanel : public LLInventoryPanel
-{
-public:
- struct Params
- : public LLInitParam::Block
- {
- Mandatory filter_asset_type;
-
- Params() : filter_asset_type("filter_asset_type") {}
- };
-
- void initFromParams(const Params& p);
-protected:
- LLAssetFilteredInventoryPanel(const Params& p) : LLInventoryPanel(p) {}
- friend class LLUICtrlFactory;
-public:
- ~LLAssetFilteredInventoryPanel() {}
-
- /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg) override;
-
-protected:
- /*virtual*/ LLFolderViewItem* buildNewViews(const LLUUID& id) override;
- /*virtual*/ void itemChanged(const LLUUID& item_id, U32 mask, const LLInventoryObject* model_item) override;
-
-private:
- LLAssetType::EType mAssetType;
-};
-
void LLAssetFilteredInventoryPanel::initFromParams(const Params& p)
{
@@ -2034,21 +2081,20 @@ BOOL LLAssetFilteredInventoryPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, B
return result;
}
-LLFolderViewItem* LLAssetFilteredInventoryPanel::buildNewViews(const LLUUID& id)
+/*virtual*/
+bool LLAssetFilteredInventoryPanel::typedViewsFilter(const LLUUID& id, LLInventoryObject const* objectp)
{
- LLInventoryObject const* objectp = gInventory.getObject(id);
-
if (!objectp)
{
- return NULL;
+ return false;
}
if (objectp->getType() != mAssetType && objectp->getType() != LLAssetType::AT_CATEGORY)
{
- return NULL;
+ return false;
}
- return LLInventoryPanel::buildNewViews(id, objectp);
+ return true;
}
void LLAssetFilteredInventoryPanel::itemChanged(const LLUUID& id, U32 mask, const LLInventoryObject* model_item)
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 29a45c0bd1..625de2f4ed 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -335,8 +335,15 @@ protected:
static LLUIColor sLibraryColor;
static LLUIColor sLinkColor;
- virtual LLFolderViewItem* buildNewViews(const LLUUID& id);
- LLFolderViewItem* buildNewViews(const LLUUID& id, LLInventoryObject const* objectp);
+ LLFolderViewItem* buildNewViews(const LLUUID& id);
+ LLFolderViewItem* buildNewViews(const LLUUID& id,
+ LLInventoryObject const* objectp);
+ LLFolderViewItem* buildNewViews(const LLUUID& id,
+ LLInventoryObject const* objectp,
+ LLFolderViewItem *target_view);
+ // if certain types are not allowed, no reason to create views
+ virtual bool typedViewsFilter(const LLUUID& id, LLInventoryObject const* objectp) { return true; }
+
virtual void itemChanged(const LLUUID& item_id, U32 mask, const LLInventoryObject* model_item);
BOOL getIsHiddenFolderType(LLFolderType::EType folder_type) const;
@@ -344,8 +351,75 @@ protected:
virtual LLFolderViewFolder* createFolderViewFolder(LLInvFVBridge * bridge, bool allow_drop);
virtual LLFolderViewItem* createFolderViewItem(LLInvFVBridge * bridge);
private:
+ // buildViewsTree does not include some checks and is meant
+ // for recursive use, use buildNewViews() for first call
+ LLFolderViewItem* buildViewsTree(const LLUUID& id,
+ const LLUUID& parent_id,
+ LLInventoryObject const* objectp,
+ LLFolderViewItem *target_view,
+ LLFolderViewFolder *parent_folder_view);
+
bool mBuildDefaultHierarchy; // default inventory hierarchy should be created in postBuild()
bool mViewsInitialized; // Views have been generated
};
+
+class LLInventoryFavoriteItemsPanel : public LLInventoryPanel
+{
+public:
+ struct Params : public LLInitParam::Block
+ {};
+
+ void initFromParams(const Params& p);
+ bool isSelectionRemovable() { return false; }
+ void setSelectCallback(const boost::function& items, BOOL user_action)>& cb);
+
+protected:
+ LLInventoryFavoriteItemsPanel(const Params& params);
+ ~LLInventoryFavoriteItemsPanel() { mFolderChangedSignal.disconnect(); }
+ void updateFavoritesRootFolder();
+
+ boost::signals2::connection mFolderChangedSignal;
+ boost::function& items, BOOL user_action)> mSelectionCallback;
+ friend class LLUICtrlFactory;
+};
+
+/************************************************************************/
+/* Asset Pre-Filtered Inventory Panel related class */
+/* Exchanges filter's flexibility for speed of generation and */
+/* improved performance */
+/************************************************************************/
+
+class LLAssetFilteredInventoryPanel : public LLInventoryPanel
+{
+public:
+ struct Params
+ : public LLInitParam::Block
+ {
+ Mandatory filter_asset_type;
+
+ Params() : filter_asset_type("filter_asset_type") {}
+ };
+
+ void initFromParams(const Params& p);
+protected:
+ LLAssetFilteredInventoryPanel(const Params& p) : LLInventoryPanel(p) {}
+ friend class LLUICtrlFactory;
+public:
+ ~LLAssetFilteredInventoryPanel() {}
+
+ /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg) override;
+
+protected:
+ /*virtual*/ bool typedViewsFilter(const LLUUID& id, LLInventoryObject const* objectp) override;
+ /*virtual*/ void itemChanged(const LLUUID& item_id, U32 mask, const LLInventoryObject* model_item) override;
+
+private:
+ LLAssetType::EType mAssetType;
+};
+
#endif // LL_LLINVENTORYPANEL_H
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 4642dd8afe..7a8502b4a4 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -147,6 +147,16 @@ void append_to_last_message(std::list& messages, const std::string& line)
messages.back()[LL_IM_TEXT] = im_text;
}
+std::string remove_utf8_bom(const char* buf)
+{
+ std::string res(buf);
+ if (res[0] == (char)0xEF && res[1] == (char)0xBB && res[2] == (char)0xBF)
+ {
+ res.erase(0, 3);
+ }
+ return res;
+}
+
class LLLogChatTimeScanner: public LLSingleton
{
LLSINGLETON(LLLogChatTimeScanner);
@@ -504,18 +514,7 @@ void LLLogChat::loadChatHistory(const std::string& file_name, std::list& m
continue;
}
- std::string line(buffer);
-
- // FIRE-28990: Unable to open chat transcript if file is UTF-8-BOM encoded
- // Technically it doesn't make sense to do it each iteration and ideally we
- // would do it once before the loop starts, but seeking backwards to the start of
- // the file causes the viewer's process being locked up for several seconds
- // during login, we just do it here to skip seeking backwards.
- if (line.length() > 3 && line[0] == char(239) && line[1] == char(187) && line[2] == char(191))
- {
- line = line.substr(3);
- }
- //
+ std::string line(remove_utf8_bom(buffer));
//updated 1.23 plain text log format requires a space added before subsequent lines in a multilined message
if (' ' == line[0])
@@ -919,19 +918,11 @@ bool LLLogChat::isTranscriptFileFound(std::string fullname)
if (bytes_to_read > 0 && NULL != fgets(buffer, bytes_to_read, filep))
{
- // FIRE-28990: Unable to open chat transcript if file is UTF-8-BOM encoded
- std::string bufferstr(buffer);
- if (bufferstr.length() > 3 && bufferstr[0] == char(239) && bufferstr[1] == char(187) && bufferstr[2] == char(191))
- {
- bufferstr = bufferstr.substr(3);
- }
- //
-
//matching a timestamp
boost::match_results matches;
// Seconds in timestamp
- //if (boost::regex_match(std::string(buffer), matches, TIMESTAMP))
- if (boost::regex_match(bufferstr, matches, TIMESTAMP) || boost::regex_match(bufferstr, matches, TIMESTAMP_AND_SEC))
+ //if (boost::regex_match(remove_utf8_bom(buffer), matches, TIMESTAMP))
+ if (boost::regex_match(remove_utf8_bom(buffer), matches, TIMESTAMP) || boost::regex_match(remove_utf8_bom(buffer), matches, TIMESTAMP_AND_SEC))
//
{
result = true;
@@ -1295,19 +1286,7 @@ void LLLoadHistoryThread::loadHistory(const std::string& file_name, std::list FIRE-28990: Unable to open chat transcript if file is UTF-8-BOM encoded
- // Technically it doesn't make sense to do it each iteration and ideally we
- // would do it once before the loop starts, but since this code was duplicated
- // from further above and in the other case seeking backwards to the start of
- // the file causes the viewer's process being locked up for several seconds
- // during login, we just do it here the same way we do above.
- if (line.length() > 3 && line[0] == char(239) && line[1] == char(187) && line[2] == char(191))
- {
- line = line.substr(3);
- }
- //
+ std::string line(remove_utf8_bom(buffer));
//updated 1.23 plaint text log format requires a space added before subsequent lines in a multilined message
if (' ' == line[0])
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index f4b58dfe3a..5982422f03 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -100,7 +100,7 @@
// locking actions. In particular, the following operations
// on LLMeshRepository are very averse to any stalls:
// * loadMesh
-// * getMeshHeader (For structural details, see:
+// * search in mMeshHeader (For structural details, see:
// http://wiki.secondlife.com/wiki/Mesh/Mesh_Asset_Format)
// * notifyLoadedMeshes
// * getSkinInfo
@@ -3277,7 +3277,6 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
header_bytes = (S32)gMeshRepo.mThread->mMeshHeaderSize[mesh_id];
header = iter->second;
}
- gMeshRepo.mThread->mHeaderMutex->unlock();
if (header_bytes > 0
&& !header.has("404")
@@ -3298,7 +3297,10 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
lod_bytes = llmax(lod_bytes, header["skin"]["offset"].asInteger() + header["skin"]["size"].asInteger());
lod_bytes = llmax(lod_bytes, header["physics_convex"]["offset"].asInteger() + header["physics_convex"]["size"].asInteger());
- S32 header_bytes = (S32) gMeshRepo.mThread->mMeshHeaderSize[mesh_id];
+ // Do not unlock mutex untill we are done with LLSD.
+ // LLSD is smart and can work like smart pointer, is not thread safe.
+ gMeshRepo.mThread->mHeaderMutex->unlock();
+
S32 bytes = lod_bytes + header_bytes;
@@ -3334,6 +3336,8 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
{
LL_WARNS(LOG_MESH) << "Trying to cache nonexistent mesh, mesh id: " << mesh_id << LL_ENDL;
+ gMeshRepo.mThread->mHeaderMutex->unlock();
+
// headerReceived() parsed header, but header's data is invalid so none of the LODs will be available
LLMutexLock lock(gMeshRepo.mThread->mMutex);
for (int i(0); i < 4; ++i)
@@ -4269,44 +4273,74 @@ void LLMeshRepository::buildHull(const LLVolumeParams& params, S32 detail)
bool LLMeshRepository::hasPhysicsShape(const LLUUID& mesh_id)
{
- LLSD mesh = mThread->getMeshHeader(mesh_id);
- if (mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0))
- {
- return true;
- }
+ if (mesh_id.isNull())
+ {
+ return false;
+ }
- LLModel::Decomposition* decomp = getDecomposition(mesh_id);
- if (decomp && !decomp->mHull.empty())
- {
- return true;
- }
+ if (mThread->hasPhysicsShapeInHeader(mesh_id))
+ {
+ return true;
+ }
- return false;
+ LLModel::Decomposition* decomp = getDecomposition(mesh_id);
+ if (decomp && !decomp->mHull.empty())
+ {
+ return true;
+ }
+
+ return false;
}
-LLSD& LLMeshRepository::getMeshHeader(const LLUUID& mesh_id)
+bool LLMeshRepoThread::hasPhysicsShapeInHeader(const LLUUID& mesh_id)
{
- LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH);
+ LLMutexLock lock(mHeaderMutex);
+ if (mMeshHeaderSize[mesh_id] > 0)
+ {
+ mesh_header_map::iterator iter = mMeshHeader.find(mesh_id);
+ if (iter != mMeshHeader.end())
+ {
+ LLSD &mesh = iter->second;
+ if (mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0))
+ {
+ return true;
+ }
+ }
+ }
- return mThread->getMeshHeader(mesh_id);
+ return false;
}
-LLSD& LLMeshRepoThread::getMeshHeader(const LLUUID& mesh_id)
+// DAE export
+LLUUID LLMeshRepository::getCreatorFromHeader(const LLUUID& mesh_id)
{
- static LLSD dummy_ret;
- if (mesh_id.notNull())
+ if (mesh_id.isNull())
+ {
+ return LLUUID();
+ }
+
+ return mThread->getCreatorFromHeader(mesh_id);
+}
+
+LLUUID LLMeshRepoThread::getCreatorFromHeader(const LLUUID& mesh_id)
+{
+ LLMutexLock lock(mHeaderMutex);
+ if (mMeshHeaderSize[mesh_id] > 0)
{
- LLMutexLock lock(mHeaderMutex);
mesh_header_map::iterator iter = mMeshHeader.find(mesh_id);
- if (iter != mMeshHeader.end() && mMeshHeaderSize[mesh_id] > 0)
+ if (iter != mMeshHeader.end())
{
- return iter->second;
+ LLSD& mesh = iter->second;
+ if (mesh.has("creator") && mesh["creator"].isUUID())
+ {
+ return mesh["creator"].asUUID();
+ }
}
}
- return dummy_ret;
+ return LLUUID();
}
-
+//
void LLMeshRepository::uploadModel(std::vector& data, LLVector3& scale, bool upload_textures,
bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position,
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 5a0fa15bd5..8de7f4ce2b 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -349,7 +349,7 @@ public:
bool skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
bool decompositionReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
bool physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
- LLSD& getMeshHeader(const LLUUID& mesh_id);
+ bool hasPhysicsShapeInHeader(const LLUUID& mesh_id);
void notifyLoadedMeshes();
S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
@@ -390,6 +390,9 @@ public:
void constructUrl(LLUUID mesh_id, std::string * url, int * legacy_version);
// [UDP Assets]
+ // DAE export
+ LLUUID getCreatorFromHeader(const LLUUID& mesh_id);
+
private:
// Issue a GET request to a URL with 'Range' header using
// the correct policy class and other attributes. If an invalid
@@ -610,9 +613,6 @@ public:
bool meshUploadEnabled();
bool meshRezEnabled();
-
-
- LLSD& getMeshHeader(const LLUUID& mesh_id);
void uploadModel(std::vector& data, LLVector3& scale, bool upload_textures,
bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position,
@@ -631,6 +631,9 @@ public:
typedef std::map > mesh_load_map;
mesh_load_map mLoadingMeshes[4];
+ // DAE export
+ LLUUID getCreatorFromHeader(const LLUUID& mesh_id);
+
// Faster lookup
//typedef std::map skin_map;
typedef boost::unordered_map skin_map;
diff --git a/indra/newview/llpanellandmarkinfo.cpp b/indra/newview/llpanellandmarkinfo.cpp
index 06bb886ae8..9b55fe9ce2 100644
--- a/indra/newview/llpanellandmarkinfo.cpp
+++ b/indra/newview/llpanellandmarkinfo.cpp
@@ -39,6 +39,7 @@
#include "llagent.h"
#include "llagentui.h"
#include "lllandmarkactions.h"
+#include "llparcel.h"
#include "llslurl.h"
#include "llviewerinventory.h"
#include "llviewerparcelmgr.h"
@@ -101,6 +102,9 @@ void LLPanelLandmarkInfo::resetLocation()
mLandmarkTitle->setText(LLStringUtil::null);
mLandmarkTitleEditor->setText(LLStringUtil::null);
mNotesEditor->setText(LLStringUtil::null);
+
+ mParcelOwner->setVisible(FALSE);
+ getChild("parcel_owner_label")->setVisible(FALSE);
}
// virtual
@@ -126,7 +130,8 @@ void LLPanelLandmarkInfo::setInfoType(EInfoType type)
mNotesEditor->setEnabled(TRUE);
LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();
- std::string name = parcel_mgr->getAgentParcelName();
+ LLParcel* parcel = parcel_mgr->getAgentParcel();
+ std::string name = parcel->getName();
LLVector3 agent_pos = gAgent.getPositionAgent();
std::string desc;
@@ -159,6 +164,27 @@ void LLPanelLandmarkInfo::setInfoType(EInfoType type)
mLandmarkTitleEditor->setText(name);
}
+ mParcelOwner->setVisible(TRUE);
+ getChild("parcel_owner_label")->setVisible(TRUE);
+ LLUUID owner_id = parcel->getOwnerID();
+ if (owner_id.notNull())
+ {
+ if (parcel->getIsGroupOwned())
+ {
+ std::string owner_name = LLSLURL("group", parcel->getGroupID(), "inspect").getSLURLString();
+ mParcelOwner->setText(owner_name);
+ }
+ else
+ {
+ std::string owner_name = LLSLURL("agent", owner_id, "inspect").getSLURLString();
+ mParcelOwner->setText(owner_name);
+ }
+ }
+ else
+ {
+ mParcelOwner->setText(getString("public"));
+ }
+
// Moved landmark creation here from LLPanelLandmarkInfo::processParcelInfo()
// because we use only agent's current coordinates instead of waiting for
// remote parcel request to complete.
@@ -210,6 +236,17 @@ void LLPanelLandmarkInfo::processParcelInfo(const LLParcelData& parcel_data)
mMaturityRatingText->setText(LLViewerRegion::accessToString(SIM_ACCESS_PG));
}
+ if (parcel_data.owner_id.notNull())
+ {
+ // not suported and ivisible due to missing isGroupOwned flag
+ }
+ else
+ {
+ mParcelOwner->setVisible(TRUE);
+ mParcelOwner->setText(getString("public"));
+ getChild("parcel_owner_label")->setVisible(FALSE);
+ }
+
LLSD info;
info["update_verbs"] = true;
info["global_x"] = parcel_data.global_x;
@@ -264,7 +301,8 @@ void LLPanelLandmarkInfo::displayItemInfo(const LLInventoryItem* pItem)
}
else
{
- mOwner->setText(getString("public"));
+ std::string public_str = getString("public");
+ mOwner->setText(public_str);
}
//////////////////
@@ -357,7 +395,7 @@ void LLPanelLandmarkInfo::createLandmark(const LLUUID& folder_id)
// If no parcel exists use the region name instead.
if (name.empty())
{
- name = mRegionName->getText();
+ name = mRegionTitle;
}
}
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index 32b3658105..b914b705b8 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -686,7 +686,6 @@ void LLPanelLogin::getFields(LLPointer& credential,
if (LLPanelLogin::sInstance->mPasswordModified)
{
- authenticator = LLSD::emptyMap();
// password is plaintext
authenticator["type"] = CRED_AUTHENTICATOR_TYPE_CLEAR;
authenticator["secret"] = password;
@@ -697,6 +696,15 @@ void LLPanelLogin::getFields(LLPointer& credential,
if (credential.notNull())
{
authenticator = credential->getAuthenticator();
+ if (authenticator.emptyMap())
+ {
+ // Likely caused by user trying to log in to non-system grid
+ // with unsupported name format, just retry
+ LL_WARNS() << "Authenticator failed to load for: " << username << LL_ENDL;
+ // password is plaintext
+ authenticator["type"] = CRED_AUTHENTICATOR_TYPE_CLEAR;
+ authenticator["secret"] = password;
+ }
}
}
}
diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp
index d0e331c5e4..452d92a1a3 100644
--- a/indra/newview/llpanelplaceinfo.cpp
+++ b/indra/newview/llpanelplaceinfo.cpp
@@ -43,6 +43,7 @@
#include "llagent.h"
#include "llexpandabletextbox.h"
#include "llpanelpick.h"
+#include "llslurl.h"
#include "lltexturectrl.h"
#include "llviewerregion.h"
#include "llhttpconstants.h"
@@ -80,6 +81,7 @@ BOOL LLPanelPlaceInfo::postBuild()
mSnapshotCtrl = getChild("logo");
mRegionName = getChild("region_title");
mParcelName = getChild("parcel_title");
+ mParcelOwner = getChild("parcel_owner"); // Custom place profile layout
mDescEditor = getChild("description");
// FIRE-2717: Display traffic and area in landmark
mInfoText = findChild("information");
@@ -112,11 +114,13 @@ void LLPanelPlaceInfo::resetLocation()
mParcelID.setNull();
mRequestedID.setNull();
mPosRegion.clearVec();
+ mRegionTitle.clear();
std::string loading = LLTrans::getString("LoadingData");
mMaturityRatingText->setValue(loading);
- mRegionName->setText(loading);
+ mRegionName->setTextArg("[REGIONAMEPOS]", loading);
mParcelName->setText(loading);
+ mParcelOwner->setText(loading);
mDescEditor->setText(loading);
// FIRE-2717: Display traffic and area in landmark
if (mInfoText)
@@ -205,8 +209,9 @@ void LLPanelPlaceInfo::setErrorStatus(S32 status, const std::string& reason)
std::string not_available = getString("not_available");
mMaturityRatingText->setValue(not_available);
- mRegionName->setText(not_available);
+ mRegionName->setTextArg("[REGIONAMEPOS]", not_available);
mParcelName->setText(not_available);
+ mParcelOwner->setText(not_available);
// FIRE-2717: Display traffic and area in landmark
if (mInfoText)
{
@@ -217,6 +222,7 @@ void LLPanelPlaceInfo::setErrorStatus(S32 status, const std::string& reason)
//mMaturityRatingIcon->setValue(LLUUID::null);
mMaturityRatingIcon->setValue(LLSD("Unknown_Icon"));
// Fix loading icon
+ mRegionTitle.clear();
// Enable "Back" button that was disabled when parcel request was sent.
getChild("back_btn")->setEnabled(TRUE);
@@ -230,12 +236,34 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)
mSnapshotCtrl->setImageAssetID(parcel_data.snapshot_id);
}
- if(!parcel_data.sim_name.empty())
- {
- mRegionName->setText(parcel_data.sim_name);
+ S32 region_x;
+ S32 region_y;
+ S32 region_z;
+
+ // If the region position is zero, grab position from the global
+ if (mPosRegion.isExactlyZero())
+ {
+ region_x = ll_round(parcel_data.global_x) % REGION_WIDTH_UNITS;
+ region_y = ll_round(parcel_data.global_y) % REGION_WIDTH_UNITS;
+ region_z = ll_round(parcel_data.global_z);
+ }
+ else
+ {
+ region_x = ll_round(mPosRegion.mV[VX]);
+ region_y = ll_round(mPosRegion.mV[VY]);
+ region_z = ll_round(mPosRegion.mV[VZ]);
+ }
+
+ if (!parcel_data.sim_name.empty())
+ {
+ mRegionTitle = parcel_data.sim_name;
+ std::string name_and_pos = llformat("%s (%d, %d, %d)",
+ mRegionTitle.c_str(), region_x, region_y, region_z);
+ mRegionName->setTextArg("[REGIONAMEPOS]", name_and_pos);
}
else
{
+ mRegionTitle.clear();
mRegionName->setText(LLStringUtil::null);
}
@@ -248,30 +276,11 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)
mDescEditor->setText(getString("not_available"));
}
- S32 region_x;
- S32 region_y;
- S32 region_z;
-
- // If the region position is zero, grab position from the global
- if(mPosRegion.isExactlyZero())
- {
- region_x = ll_round(parcel_data.global_x) % REGION_WIDTH_UNITS;
- region_y = ll_round(parcel_data.global_y) % REGION_WIDTH_UNITS;
- region_z = ll_round(parcel_data.global_z);
- }
- else
- {
- region_x = ll_round(mPosRegion.mV[VX]);
- region_y = ll_round(mPosRegion.mV[VY]);
- region_z = ll_round(mPosRegion.mV[VZ]);
- }
-
if (!parcel_data.name.empty())
{
mParcelTitle = parcel_data.name;
- mParcelName->setText(llformat("%s (%d, %d, %d)",
- mParcelTitle.c_str(), region_x, region_y, region_z));
+ mParcelName->setText(mParcelTitle);
}
else
{
@@ -330,12 +339,10 @@ void LLPanelPlaceInfo::reshape(S32 width, S32 height, BOOL called_from_parent)
void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global, LLPanelPickEdit* pick_panel)
{
- std::string region_name = mRegionName->getText();
-
LLPickData data;
data.pos_global = pos_global;
- data.name = mParcelTitle.empty() ? region_name : mParcelTitle;
- data.sim_name = region_name;
+ data.name = mParcelTitle.empty() ? mRegionTitle : mParcelTitle;
+ data.sim_name = mRegionTitle;
data.desc = mDescEditor->getText();
data.snapshot_id = mSnapshotCtrl->getImageAssetID();
data.parcel_id = mParcelID;
diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h
index 0780975073..10b6c8a1bc 100644
--- a/indra/newview/llpanelplaceinfo.h
+++ b/indra/newview/llpanelplaceinfo.h
@@ -122,6 +122,7 @@ protected:
LLUUID mRequestedID;
LLVector3 mPosRegion;
std::string mParcelTitle; // used for pick title without coordinates
+ std::string mRegionTitle;
std::string mCurrentTitle;
S32 mScrollingPanelMinHeight;
S32 mScrollingPanelWidth;
@@ -133,6 +134,7 @@ protected:
LLTextureCtrl* mSnapshotCtrl;
LLTextBox* mRegionName;
LLTextBox* mParcelName;
+ LLTextBox* mParcelOwner;
LLExpandableTextBox* mDescEditor;
LLIconCtrl* mMaturityRatingIcon;
LLTextBox* mMaturityRatingText;
diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp
index edf85774f7..91d51d6594 100644
--- a/indra/newview/llpanelplaceprofile.cpp
+++ b/indra/newview/llpanelplaceprofile.cpp
@@ -107,8 +107,6 @@ BOOL LLPanelPlaceProfile::postBuild()
mForSalePanel->getChild("icon_for_sale")->
setMouseDownCallback(boost::bind(&LLPanelPlaceProfile::onForSaleBannerClick, this));
- mParcelOwner = getChild("owner_value");
-
mParcelRatingIcon = getChild("rating_icon");
mParcelRatingText = getChild("rating_value");
mVoiceIcon = getChild("voice_icon");
@@ -189,7 +187,6 @@ void LLPanelPlaceProfile::resetLocation()
const std::string unknown("Unknown_Icon");
std::string loading = LLTrans::getString("LoadingData");
- mParcelOwner->setValue(loading);
// Fix loading icon; don't use translated string!
//mParcelRatingIcon->setValue(loading);
@@ -266,14 +263,14 @@ void LLPanelPlaceProfile::setInfoType(EInfoType type)
const S32 SEARCH_DESC_HEIGHT = 150;
// Remember original geometry (once).
- static const S32 sOrigDescVPad = getChildView("parcel_title")->getRect().mBottom - mDescEditor->getRect().mTop;
+ static const S32 sOrigDescVPad = getChildView("owner_label")->getRect().mBottom - mDescEditor->getRect().mTop;
static const S32 sOrigDescHeight = mDescEditor->getRect().getHeight();
static const S32 sOrigMRIconVPad = mDescEditor->getRect().mBottom - mMaturityRatingIcon->getRect().mTop;
static const S32 sOrigMRTextVPad = mDescEditor->getRect().mBottom - mMaturityRatingText->getRect().mTop;
// Resize the description.
const S32 desc_height = is_info_type_agent ? sOrigDescHeight : SEARCH_DESC_HEIGHT;
- const S32 desc_top = getChildView("parcel_title")->getRect().mBottom - sOrigDescVPad;
+ const S32 desc_top = getChildView("owner_label")->getRect().mBottom - sOrigDescVPad;
LLRect desc_rect = mDescEditor->getRect();
desc_rect.setOriginAndSize(desc_rect.mLeft, desc_top - desc_height, desc_rect.getWidth(), desc_height);
mDescEditor->reshape(desc_rect.getWidth(), desc_rect.getHeight());
@@ -419,6 +416,7 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
parcel_data.global_x = pos_global.mdV[VX];
parcel_data.global_y = pos_global.mdV[VY];
parcel_data.global_z = pos_global.mdV[VZ];
+ parcel_data.owner_id = parcel->getOwnerID();
std::string on = getString("on");
std::string off = getString("off");
diff --git a/indra/newview/llpanelplaceprofile.h b/indra/newview/llpanelplaceprofile.h
index 3d2654fc12..16478bc179 100644
--- a/indra/newview/llpanelplaceprofile.h
+++ b/indra/newview/llpanelplaceprofile.h
@@ -76,8 +76,6 @@ private:
LLPanel* mForSalePanel;
LLPanel* mYouAreHerePanel;
- LLTextBox* mParcelOwner;
-
LLIconCtrl* mParcelRatingIcon;
LLTextBox* mParcelRatingText;
LLIconCtrl* mVoiceIcon;
diff --git a/indra/newview/llplacesinventorypanel.cpp b/indra/newview/llplacesinventorypanel.cpp
index b601f53403..dcafa5dd6a 100644
--- a/indra/newview/llplacesinventorypanel.cpp
+++ b/indra/newview/llplacesinventorypanel.cpp
@@ -44,9 +44,8 @@ static LLDefaultChildRegistry::Register r("places_invent
static LLPlacesInventoryBridgeBuilder PLACES_INVENTORY_BUILDER; // const makes GCC >= 4.6 very angry about not user defined default ctor.
LLPlacesInventoryPanel::LLPlacesInventoryPanel(const Params& p) :
- LLInventoryPanel(p),
+ LLAssetFilteredInventoryPanel(p),
mSavedFolderState(NULL)
-
{
mInvFVBridgeBuilder = &PLACES_INVENTORY_BUILDER;
mSavedFolderState = new LLSaveFolderState();
diff --git a/indra/newview/llplacesinventorypanel.h b/indra/newview/llplacesinventorypanel.h
index 27d9b83bd1..5629438415 100644
--- a/indra/newview/llplacesinventorypanel.h
+++ b/indra/newview/llplacesinventorypanel.h
@@ -32,14 +32,16 @@
class LLLandmarksPanel;
class LLFolderView;
-class LLPlacesInventoryPanel : public LLInventoryPanel
+class LLPlacesInventoryPanel : public LLAssetFilteredInventoryPanel
{
public:
struct Params
- : public LLInitParam::Block
+ : public LLInitParam::Block
{
Params()
- {}
+ {
+ filter_asset_type = "landmark";
+ }
};
LLPlacesInventoryPanel(const Params& p);
diff --git a/indra/newview/llsecapi.cpp b/indra/newview/llsecapi.cpp
index c2814d1d67..580e6aa5af 100644
--- a/indra/newview/llsecapi.cpp
+++ b/indra/newview/llsecapi.cpp
@@ -135,7 +135,7 @@ LLSD LLCredential::getLoginParams()
else if (mIdentifier["type"].asString() == "account")
{
result["username"] = mIdentifier["account_name"];
- result["passwd"] = mAuthenticator["secret"];
+ result["passwd"] = mAuthenticator["secret"].asString();
username = result["username"].asString();
}
}
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 03932dfdd6..bb72460603 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -6200,25 +6200,18 @@ static F32 calc_light_dist(LLVOVolume* light, const LLVector3& cam_pos, F32 max_
{
return max_dist;
}
- F32 radius = light->getLightRadius();
bool selected = light->isSelected();
- LLVector3 dpos = light->getRenderPosition() - cam_pos;
- F32 dist2 = dpos.lengthSquared();
- if (!selected && dist2 > (max_dist + radius)*(max_dist + radius))
- {
- return max_dist;
- }
- F32 dist = (F32) sqrt(dist2);
- dist *= 1.f / inten;
- dist -= radius;
if (selected)
{
- dist -= 10000.f; // selected lights get highest priority
+ return 0.f; // selected lights get highest priority
}
+ F32 radius = light->getLightRadius();
+ F32 dist = dist_vec(light->getRenderPosition(), cam_pos);
+ dist = llmax(dist - radius, 0.f);
if (light->mDrawable.notNull() && light->mDrawable->isState(LLDrawable::ACTIVE))
{
// moving lights get a little higher priority (too much causes artifacts)
- dist -= light->getLightRadius()*0.25f;
+ dist = llmax(dist - light->getLightRadius()*0.25f, 0.f);
}
return dist;
}
@@ -6237,12 +6230,17 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
// mNearbyLight (and all light_set_t's) are sorted such that
// begin() == the closest light and rbegin() == the farthest light
const S32 MAX_LOCAL_LIGHTS = 6;
-// LLVector3 cam_pos = gAgent.getCameraPositionAgent();
- LLVector3 cam_pos = LLViewerJoystick::getInstance()->getOverrideCamera() ?
- camera.getOrigin() :
- gAgent.getPositionAgent();
+ LLVector3 cam_pos = camera.getOrigin();
- F32 max_dist = LIGHT_MAX_RADIUS * 4.f; // ignore enitrely lights > 4 * max light rad
+ F32 max_dist;
+ if (LLPipeline::sRenderDeferred)
+ {
+ max_dist = RenderFarClip;
+ }
+ else
+ {
+ max_dist = llmin(RenderFarClip, LIGHT_MAX_RADIUS * 4.f);
+ }
// UPDATE THE EXISTING NEARBY LIGHTS
light_set_t cur_nearby_lights;
@@ -6277,8 +6275,38 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
continue;
}
- F32 dist = calc_light_dist(volight, cam_pos, max_dist);
- cur_nearby_lights.insert(Light(drawable, dist, light->fade));
+ F32 dist = calc_light_dist(volight, cam_pos, max_dist);
+ F32 fade = light->fade;
+ // actual fade gets decreased/increased by setupHWLights
+ // light->fade value is 'time'.
+ // >=0 and light will become visible as value increases
+ // <0 and light will fade out
+ if (dist < max_dist)
+ {
+ if (fade < 0)
+ {
+ // mark light to fade in
+ // if fade was -LIGHT_FADE_TIME - it was fully invisible
+ // if fade -0 - it was fully visible
+ // visibility goes up from 0 to LIGHT_FADE_TIME.
+ fade += LIGHT_FADE_TIME;
+ }
+ }
+ else
+ {
+ // mark light to fade out
+ // visibility goes down from -0 to -LIGHT_FADE_TIME.
+ if (fade >= LIGHT_FADE_TIME)
+ {
+ fade = -0.0001f; // was fully visible
+ }
+ else if (fade >= 0)
+ {
+ // 0.75 visible light should stay 0.75 visible, but should reverse direction
+ fade -= LIGHT_FADE_TIME;
+ }
+ }
+ cur_nearby_lights.insert(Light(drawable, dist, fade));
}
mNearbyLights = cur_nearby_lights;
@@ -6297,17 +6325,23 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
{
continue; // no lighting from HUD objects
}
+ if (!sRenderAttachedLights && light && light->isAttachment())
+ {
+ continue;
+ }
+ LLVOAvatar *av = light->getAvatar();
+ if (av && (av->isTooComplex() || av->isInMuteList()))
+ {
+ // avatars that are already in the list will be removed by removeMutedAVsLights
+ continue;
+ }
F32 dist = calc_light_dist(light, cam_pos, max_dist);
if (dist >= max_dist)
{
continue;
}
- if (!sRenderAttachedLights && light && light->isAttachment())
- {
- continue;
- }
new_nearby_lights.insert(Light(drawable, dist, 0.f));
- if (new_nearby_lights.size() > (U32)MAX_LOCAL_LIGHTS)
+ if (!LLPipeline::sRenderDeferred && new_nearby_lights.size() > (U32)MAX_LOCAL_LIGHTS)
{
new_nearby_lights.erase(--new_nearby_lights.end());
const Light& last = *new_nearby_lights.rbegin();
@@ -6320,7 +6354,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
iter != new_nearby_lights.end(); iter++)
{
const Light* light = &(*iter);
- if (mNearbyLights.size() < (U32)MAX_LOCAL_LIGHTS)
+ if (LLPipeline::sRenderDeferred || mNearbyLights.size() < (U32)MAX_LOCAL_LIGHTS)
{
mNearbyLights.insert(*light);
((LLDrawable*) light->drawable)->setState(LLDrawable::NEARBY_LIGHT);
@@ -6333,10 +6367,22 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
Light* farthest_light = (const_cast(&(*(mNearbyLights.rbegin()))));
if (light->dist < farthest_light->dist)
{
- if (farthest_light->fade >= 0.f)
- {
- farthest_light->fade = -(gFrameIntervalSeconds.value());
- }
+ // mark light to fade out
+ // visibility goes down from -0 to -LIGHT_FADE_TIME.
+ //
+ // This is a mess, but for now it needs to be in sync
+ // with fade code above. Ex: code above detects distance < max,
+ // sets fade time to positive, this code then detects closer
+ // lights and sets fade time negative, fully compensating
+ // for the code above
+ if (farthest_light->fade >= LIGHT_FADE_TIME)
+ {
+ farthest_light->fade = -0.0001f; // was fully visible
+ }
+ else if (farthest_light->fade >= 0)
+ {
+ farthest_light->fade -= LIGHT_FADE_TIME;
+ }
}
else
{
@@ -6456,12 +6502,6 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
}
}
- const LLViewerObject *vobj = drawable->getVObj();
- if(vobj && vobj->getAvatar() && vobj->getAvatar()->isInMuteList())
- {
- continue;
- }
-
if (drawable->isState(LLDrawable::ACTIVE))
{
mLightMovingMask |= (1<setSpecular(specular);
}
else // omnidirectional (point) light
+
{
light_state->setSpotExponent(0.f);
light_state->setSpotCutoff(180.f);
@@ -8913,47 +8954,51 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget* screen_target)
mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
- for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter)
- {
- LLDrawable* drawablep = *iter;
-
- LLVOVolume* volume = drawablep->getVOVolume();
- if (!volume)
- {
- continue;
- }
-
- if (volume->isAttachment())
- {
- if (!sRenderAttachedLights)
- {
- continue;
- }
- }
-
- const LLViewerObject *vobj = drawablep->getVObj();
- if (vobj)
+ // mNearbyLights already includes distance calculation and excludes muted avatars.
+ // It is calculated from mLights
+ // mNearbyLights also provides fade value to gracefully fade-out out of range lights
+ for (light_set_t::iterator iter = mNearbyLights.begin(); iter != mNearbyLights.end(); ++iter)
+ {
+ LLDrawable* drawablep = iter->drawable;
+ LLVOVolume* volume = drawablep->getVOVolume();
+ if (!volume)
{
- LLVOAvatar *av = vobj->getAvatar();
- if (av && (av->isTooComplex() || av->isInMuteList()))
+ continue;
+ }
+
+ if (volume->isAttachment())
+ {
+ if (!sRenderAttachedLights)
{
continue;
}
}
- const LLVector3 position = drawablep->getPositionAgent();
- if (dist_vec(position, LLViewerCamera::getInstance()->getOrigin()) > RenderFarClip + volume->getLightRadius())
- {
- continue;
- }
-
LLVector4a center;
- center.load3(position.mV);
+ center.load3(drawablep->getPositionAgent().mV);
const F32* c = center.getF32ptr();
F32 s = volume->getLightRadius()*1.5f;
//send light color to shader in linear space
LLColor3 col = volume->getLightLinearColor();
+
+ // fade also works as flicker prevention during reparenting
+ // because reparenting causes distance to jump temporary
+ F32 fade = iter->fade;
+ if (fade < LIGHT_FADE_TIME)
+ {
+ // fade in/out light
+ if (fade >= 0.f)
+ {
+ fade = fade / LIGHT_FADE_TIME;
+ }
+ else
+ {
+ fade = 1.f + fade / LIGHT_FADE_TIME;
+ }
+ fade = llclamp(fade, 0.f, 1.f);
+ col *= fade;
+ }
if (col.magVecSquared() < 0.001f)
{
diff --git a/indra/newview/skins/ansastorm/xui/en/panel_landmark_info.xml b/indra/newview/skins/ansastorm/xui/en/panel_landmark_info.xml
deleted file mode 100644
index 979c64c60b..0000000000
--- a/indra/newview/skins/ansastorm/xui/en/panel_landmark_info.xml
+++ /dev/null
@@ -1,373 +0,0 @@
-
-
-
-
-
-
-
-
-
- Place information not available without server update.
-
-
- Information about this location is unavailable at this time, please try again later.
-
-
- Information about this location is unavailable due to access restrictions. Please check your permissions with the parcel owner.
-
-
- [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local]
-
-
- Traffic: [TRAFFIC] Area: [AREA] m²
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml
index 7477d93055..d72594c41f 100644
--- a/indra/newview/skins/default/xui/de/notifications.xml
+++ b/indra/newview/skins/default/xui/de/notifications.xml
@@ -4220,7 +4220,7 @@ Sie ist voll oder startet in Kürze neu.
Skript konnte nicht hinzugefügt werden.
- Asset-Server hat nicht rechtzeitig reagiert. Objekt wurde zum Sim zurückübertragen.
+ Asset-Server hat nicht rechtzeitig reagiert. Objekt wurde zur Region zurückübertragen.
In dieser Region sind keine Physikformen aktiviert.
diff --git a/indra/newview/skins/default/xui/de/panel_landmark_info.xml b/indra/newview/skins/default/xui/de/panel_landmark_info.xml
index 016088ccf5..2ca2d3044e 100644
--- a/indra/newview/skins/default/xui/de/panel_landmark_info.xml
+++ b/indra/newview/skins/default/xui/de/panel_landmark_info.xml
@@ -31,9 +31,13 @@
-
-
+
+ Region: [REGIONAMEPOS]
+
+
+
+
diff --git a/indra/newview/skins/default/xui/de/panel_place_profile.xml b/indra/newview/skins/default/xui/de/panel_place_profile.xml
index 15661e05c0..cb67a2dea8 100644
--- a/indra/newview/skins/default/xui/de/panel_place_profile.xml
+++ b/indra/newview/skins/default/xui/de/panel_place_profile.xml
@@ -51,11 +51,13 @@
-
+
+ Region: [REGIONAMEPOS]
+
-
+
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 6d1d4a2cdd..bc18ebefa4 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -11434,7 +11434,7 @@ Unable to add script!
name="AssetServerTimeoutObjReturn"
type="notify">
fail
-Asset server didn't respond in a timely fashion. Object returned to sim.
+Asset server didn't respond in a timely fashion. Object returned to the region.
-
+
+ value="SampleParcel, Name Long"
+ right="-1" />
+
+
+ Region: [REGIONAMEPOS]
+
@@ -157,17 +170,26 @@
name="maturity_value"
top_pad="-13"
value="unknown"
- width="60" />
+ width="50" />
+
@@ -361,7 +382,7 @@
height="23"
layout="topleft"
left_pad="0"
- top_pad="-18"
+ top_pad="-20"
name="folder_combo"
right="-1" />
diff --git a/indra/newview/skins/default/xui/en/panel_place_profile.xml b/indra/newview/skins/default/xui/en/panel_place_profile.xml
index ad077c173c..3f4d9a3508 100644
--- a/indra/newview/skins/default/xui/en/panel_place_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_place_profile.xml
@@ -286,7 +286,7 @@
height="14"
layout="topleft"
left="10"
- name="region_title"
+ name="parcel_title"
text_color="white"
top_pad="5"
use_ellipses="true"
@@ -298,11 +298,12 @@
height="14"
layout="topleft"
left="10"
- name="parcel_title"
+ name="region_title"
top_pad="4"
use_ellipses="true"
- value="unknown"
- width="320" />
+ width="320">
+ Region: [REGIONAMEPOS]
+
-
-
-
-
-
-
-
-
- Place information not available without server update.
-
-
- Information about this location is unavailable at this time, please try again later.
-
-
- Information about this location is unavailable due to access restrictions. Please check your permissions with the parcel owner.
-
-
- [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local]
-
-
- Traffic: [TRAFFIC] Area: [AREA] m²
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/indra/newview/skins/starlight/xui/en/panel_landmark_info.xml b/indra/newview/skins/starlight/xui/en/panel_landmark_info.xml
index 8a17631908..75ed8c9af2 100644
--- a/indra/newview/skins/starlight/xui/en/panel_landmark_info.xml
+++ b/indra/newview/skins/starlight/xui/en/panel_landmark_info.xml
@@ -129,7 +129,7 @@
+
+ value="SampleParcel, Name Long" />
+ Region: [REGIONAMEPOS]
+
+
+
+ value="TempOwner"
+ width="215" />
+
+
+ This landmark:
+
-
@@ -226,11 +226,11 @@
name="place_scroll"
opaque="true"
top_pad="10"
- width="310">
+ width="320">
+ value="Unknown" />
-
+ width="285"
+ name="region_title"
+ text_color="White"
+ use_ellipses="true">
+ Region: [REGIONAMEPOS]
+
-
+
+ width="305">
-
+
+ value="SampleParcel, Name Long" />
+ Region: [REGIONAMEPOS]
+
+
+
+ value="TempOwner"
+ width="215" />
+
+
+ This landmark:
+
-
@@ -226,11 +226,11 @@
name="place_scroll"
opaque="true"
top_pad="10"
- width="310">
+ width="320">
+ value="Unknown" />
-
+ width="285"
+ name="region_title"
+ text_color="White"
+ use_ellipses="true">
+ Region: [REGIONAMEPOS]
+
-
+
+ width="305">
-
-
-
-
-
-
-
-
-
- Place information not available without server update.
-
-
- Information about this location is unavailable at this time, please try again later.
-
-
- Information about this location is unavailable due to access restrictions. Please check your permissions with the parcel owner.
-
-
- [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local]
-
-
- Traffic: [TRAFFIC] Area: [AREA] m²
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-