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² - - - - - - - - - -