diff options
Diffstat (limited to 'indra')
58 files changed, 940 insertions, 203 deletions
| diff --git a/indra/llappearance/llwearable.cpp b/indra/llappearance/llwearable.cpp index f30c147b91..4acb0ef3d4 100644 --- a/indra/llappearance/llwearable.cpp +++ b/indra/llappearance/llwearable.cpp @@ -645,9 +645,10 @@ void LLWearable::addVisualParam(LLVisualParam *param)  void LLWearable::setVisualParamWeight(S32 param_index, F32 value)  { -    if( is_in_map(mVisualParamIndexMap, param_index ) ) +    visual_param_index_map_t::iterator found = mVisualParamIndexMap.find(param_index); +    if(found != mVisualParamIndexMap.end())      { -        LLVisualParam *wearable_param = mVisualParamIndexMap[param_index]; +        LLVisualParam *wearable_param = found->second;          wearable_param->setWeight(value);      }      else @@ -658,10 +659,10 @@ void LLWearable::setVisualParamWeight(S32 param_index, F32 value)  F32 LLWearable::getVisualParamWeight(S32 param_index) const  { -    if( is_in_map(mVisualParamIndexMap, param_index ) ) +    visual_param_index_map_t::const_iterator found = mVisualParamIndexMap.find(param_index); +    if(found != mVisualParamIndexMap.end())      { -        const LLVisualParam *wearable_param = mVisualParamIndexMap.find(param_index)->second; -        return wearable_param->getWeight(); +        return found->second->getWeight();      }      else      { @@ -726,7 +727,7 @@ void LLWearable::writeToAvatar(LLAvatarAppearance* avatarp)      if (!avatarp) return;      // Pull params -    for( LLVisualParam* param = avatarp->getFirstVisualParam(); param; param = avatarp->getNextVisualParam() ) +    for( const LLVisualParam* param = avatarp->getFirstVisualParam(); param; param = avatarp->getNextVisualParam() )      {          // cross-wearable parameters are not authoritative, as they are driven by a different wearable. So don't copy the values to the          // avatar object if cross wearable. Cross wearable params get their values from the avatar, they shouldn't write the other way. diff --git a/indra/llcommon/workqueue.cpp b/indra/llcommon/workqueue.cpp index 6066e74fb5..c8ece616b2 100644 --- a/indra/llcommon/workqueue.cpp +++ b/indra/llcommon/workqueue.cpp @@ -17,6 +17,7 @@  // std headers  // external library headers  // other Linden headers +#include "llapp.h"  #include "llcoros.h"  #include LLCOROS_MUTEX_HEADER  #include "llerror.h" @@ -102,19 +103,95 @@ std::string LL::WorkQueueBase::makeName(const std::string& name)      return STRINGIZE("WorkQueue" << num);  } +namespace +{ +#if LL_WINDOWS + +    static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific + +    U32 exception_filter(U32 code, struct _EXCEPTION_POINTERS* exception_infop) +    { +        if (LLApp::instance()->reportCrashToBugsplat((void*)exception_infop)) +        { +            // Handled +            return EXCEPTION_CONTINUE_SEARCH; +        } +        else if (code == STATUS_MSC_EXCEPTION) +        { +            // C++ exception, go on +            return EXCEPTION_CONTINUE_SEARCH; +        } +        else +        { +            // handle it, convert to std::exception +            return EXCEPTION_EXECUTE_HANDLER; +        } + +        return EXCEPTION_CONTINUE_SEARCH; +    } + +    void cpphandle(const LL::WorkQueueBase::Work& work) +    { +        // SE and C++ can not coexists, thus two handlers +        try +        { +            work(); +        } +        catch (const LLContinueError&) +        { +            // Any uncaught exception derived from LLContinueError will be caught +            // here and logged. This coroutine will terminate but the rest of the +            // viewer will carry on. +            LOG_UNHANDLED_EXCEPTION(STRINGIZE("LLContinue in work queue")); +        } +    } + +    void sehandle(const LL::WorkQueueBase::Work& work) +    { +        __try +        { +            // handle stop and continue exceptions first +            cpphandle(work); +        } +        __except (exception_filter(GetExceptionCode(), GetExceptionInformation())) +        { +            // convert to C++ styled exception +            char integer_string[512]; +            sprintf(integer_string, "SEH, code: %lu\n", GetExceptionCode()); +            throw std::exception(integer_string); +        } +    } +#endif // LL_WINDOWS +} // anonymous namespace +  void LL::WorkQueueBase::callWork(const Work& work)  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + +#ifdef LL_WINDOWS +    // can not use __try directly, toplevel requires unwinding, thus use of a wrapper +    sehandle(work); +#else // LL_WINDOWS      try      {          work();      } -    catch (...) +    catch (LLContinueError&)      { -        // No matter what goes wrong with any individual work item, the worker -        // thread must go on! Log our own instance name with the exception.          LOG_UNHANDLED_EXCEPTION(getKey());      } +    catch (...) +    { +        // Stash any other kind of uncaught exception to be rethrown by main thread. +        LL_WARNS("LLCoros") << "Capturing and rethrowing uncaught exception in WorkQueueBase " +            << getKey() << LL_ENDL; + +        LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop"); +        main_queue->post( +            // Bind the current exception, rethrow it in main loop. +            [exc = std::current_exception()]() { std::rethrow_exception(exc); }); +    } +#endif // else LL_WINDOWS  }  void LL::WorkQueueBase::error(const std::string& msg) diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 44b6e7923b..76e5e3aae9 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -5586,14 +5586,22 @@ struct MikktData      {          U32 count = face->mNumIndices; -        p.resize(count); -        n.resize(count); -        tc.resize(count); -        t.resize(count); +        try +        { +            p.resize(count); +            n.resize(count); +            tc.resize(count); +            t.resize(count); -        if (face->mWeights) +            if (face->mWeights) +            { +                w.resize(count); +            } +        } +        catch (std::bad_alloc&)          { -            w.resize(count); +            LLError::LLUserWarningMsg::showOutOfMemory(); +            LL_ERRS("LLCoros") << "Bad memory allocation in MikktData, elements count: " << count << LL_ENDL;          } @@ -5665,7 +5673,16 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)          // and is executed on a background thread          MikktData data(this);          mikk::Mikktspace ctx(data); -        ctx.genTangSpace(); +        try +        { +            ctx.genTangSpace(); +        } +        catch (std::bad_alloc&) +        { +            LLError::LLUserWarningMsg::showOutOfMemory(); +            LL_ERRS("LLCoros") << "Bad memory allocation in MikktData::genTangSpace" << LL_ENDL; +        } +          //re-weld          meshopt_Stream mos[] = @@ -5678,7 +5695,15 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)          };          std::vector<U32> remap; -        remap.resize(data.p.size()); +        try +        { +            remap.resize(data.p.size()); +        } +        catch (std::bad_alloc&) +        { +            LLError::LLUserWarningMsg::showOutOfMemory(); +            LL_ERRS("LLCoros") << "Failed to allocate memory for remap: " << (S32)data.p.size() << LL_ENDL; +        }          U32 stream_count = data.w.empty() ? 4 : 5; diff --git a/indra/llmessage/llassetstorage.cpp b/indra/llmessage/llassetstorage.cpp index 2de59c1b6a..10fd56a68e 100644 --- a/indra/llmessage/llassetstorage.cpp +++ b/indra/llmessage/llassetstorage.cpp @@ -585,7 +585,8 @@ void LLAssetStorage::getAssetData(const LLUUID uuid,  // static  void LLAssetStorage::removeAndCallbackPendingDownloads(const LLUUID& file_id, LLAssetType::EType file_type,                                                         const LLUUID& callback_id, LLAssetType::EType callback_type, -                                                       S32 result_code, LLExtStat ext_status) +                                                       S32 result_code, LLExtStat ext_status, +                                                       S32 bytes_fetched)  {      // find and callback ALL pending requests for this UUID      // SJB: We process the callbacks in reverse order, I do not know if this is important, @@ -598,6 +599,10 @@ void LLAssetStorage::removeAndCallbackPendingDownloads(const LLUUID& file_id, LL          LLAssetRequest* tmp = *curiter;          if ((tmp->getUUID() == file_id) && (tmp->getType()== file_type))          { +            if (bytes_fetched > 0) +            { +                tmp->mBytesFetched = bytes_fetched; +            }              requests.push_front(tmp);              iter = gAssetStorage->mPendingDownloads.erase(curiter);          } @@ -664,6 +669,7 @@ void LLAssetStorage::downloadCompleteCallback(          callback_type = req->getType();      } +    S32 bytes_fetched = 0;      if (LL_ERR_NOERR == result)      {          // we might have gotten a zero-size file @@ -677,21 +683,11 @@ void LLAssetStorage::downloadCompleteCallback(          }          else          { -#if 1 -            for (request_list_t::iterator iter = gAssetStorage->mPendingDownloads.begin(); -                 iter != gAssetStorage->mPendingDownloads.end(); ++iter  ) -            { -                LLAssetRequest* dlreq = *iter; -                if ((dlreq->getUUID() == file_id) && (dlreq->getType()== file_type)) -                { -                    dlreq->mBytesFetched = vfile.getSize(); -                } -            } -#endif +            bytes_fetched = vfile.getSize();          }      } -    removeAndCallbackPendingDownloads(file_id, file_type, callback_id, callback_type, result, ext_status); +    removeAndCallbackPendingDownloads(file_id, file_type, callback_id, callback_type, result, ext_status, bytes_fetched);  }  void LLAssetStorage::getEstateAsset( diff --git a/indra/llmessage/llassetstorage.h b/indra/llmessage/llassetstorage.h index 88fa572092..6d6526757d 100644 --- a/indra/llmessage/llassetstorage.h +++ b/indra/llmessage/llassetstorage.h @@ -324,7 +324,8 @@ public:      static void removeAndCallbackPendingDownloads(const LLUUID& file_id, LLAssetType::EType file_type,                                                    const LLUUID& callback_id, LLAssetType::EType callback_type, -                                                  S32 result_code, LLExtStat ext_status); +                                                  S32 result_code, LLExtStat ext_status, +                                                  S32 bytes_fetched);      // download process callbacks      static void downloadCompleteCallback( diff --git a/indra/llrender/llcubemaparray.cpp b/indra/llrender/llcubemaparray.cpp index d0a97dc2c6..998b57217d 100644 --- a/indra/llrender/llcubemaparray.cpp +++ b/indra/llrender/llcubemaparray.cpp @@ -105,6 +105,36 @@ LLCubeMapArray::LLCubeMapArray()  } +LLCubeMapArray::LLCubeMapArray(LLCubeMapArray& lhs, U32 width, U32 count) : mTextureStage(0) +{ +    mWidth = width; +    mCount = count; + +    // Allocate a new cubemap array with the same criteria as the incoming cubemap array +    allocate(mWidth, lhs.mImage->getComponents(), count, lhs.mImage->getUseMipMaps(), lhs.mHDR); + +    // Copy each cubemap from the incoming array to the new array +    U32 min_count = std::min(count, lhs.mCount); +    for (U32 i = 0; i < min_count * 6; ++i) +    { +        U32 src_resolution = lhs.mWidth; +        U32 dst_resolution = mWidth; +        { +            GLint components = GL_RGB; +            if (mImage->getComponents() == 4) +                components = GL_RGBA; +            GLint format = GL_RGB; + +            // Handle different resolutions by scaling the image +            LLPointer<LLImageRaw> src_image = new LLImageRaw(lhs.mWidth, lhs.mWidth, lhs.mImage->getComponents()); +            glGetTexImage(GL_TEXTURE_CUBE_MAP_ARRAY, 0, components, GL_UNSIGNED_BYTE, src_image->getData()); + +            LLPointer<LLImageRaw> scaled_image = src_image->scaled(mWidth, mWidth); +            glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 0, 0, i, mWidth, mWidth, 1, components, GL_UNSIGNED_BYTE, scaled_image->getData()); +        } +    } +} +  LLCubeMapArray::~LLCubeMapArray()  {  } @@ -115,6 +145,8 @@ void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count, bool us      mWidth = resolution;      mCount = count; +    mHDR = hdr; +      LLImageGL::generateTextures(1, &texname);      mImage = new LLImageGL(resolution, resolution, components, use_mips); diff --git a/indra/llrender/llcubemaparray.h b/indra/llrender/llcubemaparray.h index bfc72a321d..6b4288cb23 100644 --- a/indra/llrender/llcubemaparray.h +++ b/indra/llrender/llcubemaparray.h @@ -36,6 +36,7 @@ class LLCubeMapArray : public LLRefCount  {  public:      LLCubeMapArray(); +    LLCubeMapArray(LLCubeMapArray& lhs, U32 width, U32 count);      static GLenum sTargets[6]; @@ -73,4 +74,5 @@ protected:      U32 mWidth = 0;      U32 mCount = 0;      S32 mTextureStage; +    bool mHDR;  }; diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index 1bce31edb1..d2534b3939 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -837,7 +837,7 @@ void LLButton::draw()      // Highlight if needed      if( ll::ui::SearchableControl::getHighlighted() ) -        label_color = ll::ui::SearchableControl::getHighlightColor(); +        label_color = ll::ui::SearchableControl::getHighlightFontColor();      // overlay with keyboard focus border      if (hasFocus()) diff --git a/indra/llui/llcommandmanager.cpp b/indra/llui/llcommandmanager.cpp index 03717da80b..b10ec51f18 100644 --- a/indra/llui/llcommandmanager.cpp +++ b/indra/llui/llcommandmanager.cpp @@ -170,12 +170,14 @@ bool LLCommandManager::load()      if (!parser.readXUI(commands_file, commandsParams))      { +        LLError::LLUserWarningMsg::showMissingFiles();          LL_ERRS() << "Unable to load xml file: " << commands_file << LL_ENDL;          return false;      }      if (!commandsParams.validateBlock())      { +        LLError::LLUserWarningMsg::showMissingFiles();          LL_ERRS() << "Invalid commands file: " << commands_file << LL_ENDL;          return false;      } diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 69ffa9a94f..c11b42a348 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -508,7 +508,7 @@ void LLMenuItemGL::draw( void )      // Highlight if needed      if( ll::ui::SearchableControl::getHighlighted() ) -        color = ll::ui::SearchableControl::getHighlightColor(); +        color = ll::ui::SearchableControl::getHighlightFontColor();      // Draw the text on top.      if (mBriefItem) diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 7405413a3d..a05feab1d9 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -614,6 +614,13 @@ void LLNotification::cancel()  LLSD LLNotification::getResponseTemplate(EResponseTemplateType type)  {      LLSD response = LLSD::emptyMap(); + +    if (!mForm) +    { +        LL_WARNS("Notifications") << "Null form when getting response template for notification " << getName() << LL_ENDL; +        return response; +    } +      for (S32 element_idx = 0;          element_idx < mForm->getNumElements();          ++element_idx) @@ -1249,9 +1256,26 @@ LLNotifications::LLNotifications()      LLInstanceTracker<LLNotificationChannel, std::string>::instanceCount();  } + +LLNotifications::~LLNotifications() +{ +    // Clear explicitly, something in ~LLNotifications() crashes so narrowing down suspects +    pHistoryChannel = nullptr; +    pExpirationChannel = nullptr; +    mGlobalStrings.clear(); +    mTemplates.clear(); +    mVisibilityRules.clear(); +    mUniqueNotifications.clear(); +    mListener = nullptr; +} +  void LLNotifications::clear()  { -   mDefaultChannels.clear(); +    mDefaultChannels.clear(); +    // At this point mTemplates still gets used by lingering notifications +    // to do responses (ex: group notice will call forceResponse()), but +    // since network should be down and everything save, it's questionable +    // whether it should stay that way  }  // The expiration channel gets all notifications that are cancelled @@ -1464,6 +1488,13 @@ bool LLNotifications::templateExists(std::string_view name)  void LLNotifications::forceResponse(const LLNotification::Params& params, S32 option)  {      LLNotificationPtr temp_notify(new LLNotification(params)); + +    if (!temp_notify->getForm()) +    { +        LL_WARNS("Notifications") << "Cannot force response for notification with null form: " << (std::string)params.name << LL_ENDL; +        return; +    } +      LLSD response = temp_notify->getResponseTemplate();      LLSD selected_item = temp_notify->getForm()->getElement(option); diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 46286457cf..138f1969d5 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -887,7 +887,7 @@ class LLNotifications :  {      LLSINGLETON(LLNotifications);      LOG_CLASS(LLNotifications); -    virtual ~LLNotifications() {} +    virtual ~LLNotifications();  public: diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 943aff1ca1..245339b107 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -3394,7 +3394,7 @@ bool LLScrollListCtrl::highlightMatchingItems(const std::string& filter_str)      bool res = false; -    setHighlightedColor(LLUIColorTable::instance().getColor("SearchableControlHighlightColor", LLColor4::red4)); +    setHighlightedColor(LLUIColorTable::instance().getColor("SearchableControlHighlightBgColor", LLColor4::red4));      std::string filter_str_lc(filter_str);      LLStringUtil::toLower(filter_str_lc); diff --git a/indra/llui/llsearchablecontrol.h b/indra/llui/llsearchablecontrol.h index 7f1421dd19..bae85fe9a5 100644 --- a/indra/llui/llsearchablecontrol.h +++ b/indra/llui/llsearchablecontrol.h @@ -43,9 +43,15 @@ namespace ll              virtual ~SearchableControl()              { } -            const LLColor4& getHighlightColor( ) const +            const LLColor4& getHighlightBgColor( ) const              { -                static LLUIColor highlight_color = LLUIColorTable::instance().getColor("SearchableControlHighlightColor", LLColor4::red4); +                static LLUIColor highlight_color = LLUIColorTable::instance().getColor("SearchableControlHighlightBgColor", LLColor4::red4); +                return highlight_color.get(); +            } + +            const LLColor4& getHighlightFontColor() const +            { +                static LLUIColor highlight_color = LLUIColorTable::instance().getColor("SearchableControlHighlightFontColor", LLColor4::red4);                  return highlight_color.get();              } diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index fae22fd248..41e7094163 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1378,7 +1378,7 @@ void LLTextBase::draw()      // Draw highlighted if needed      if( ll::ui::SearchableControl::getHighlighted() )      { -        const LLColor4& bg_color = ll::ui::SearchableControl::getHighlightColor(); +        const LLColor4& bg_color = ll::ui::SearchableControl::getHighlightBgColor();          LLRect bg_rect = mVisibleTextRect;          if( mScroller )              bg_rect.intersectWith( text_rect ); diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 6c59ed0fd9..fe4cce29ab 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -209,8 +209,15 @@ public:      }      virtual bool execute( LLTextBase* editor, S32* delta )      { -        mWString = editor->getWText().substr(getPosition(), mLen); -        *delta = remove(editor, getPosition(), mLen ); +        try +        { +            mWString = editor->getWText().substr(getPosition(), mLen); +            *delta = remove(editor, getPosition(), mLen); +        } +        catch (std::out_of_range&) +        { +            return false; +        }          return (*delta != 0);      }      virtual S32 undo( LLTextBase* editor ) diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 6c3be3eef8..dadbc83f45 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -279,6 +279,10 @@ void callResetKeys()  bool callUnicodeCallback(wchar_t character, unsigned int mask)  { +    if (!gWindowImplementation) +    { +        return false; +    }      NativeKeyEventData eventData;      memset(&eventData, 0, sizeof(NativeKeyEventData)); @@ -300,7 +304,7 @@ bool callUnicodeCallback(wchar_t character, unsigned int mask)  void callFocus()  { -    if (gWindowImplementation) +    if (gWindowImplementation && gWindowImplementation->getCallbacks())      {          gWindowImplementation->getCallbacks()->handleFocus(gWindowImplementation);      } @@ -308,7 +312,7 @@ void callFocus()  void callFocusLost()  { -    if (gWindowImplementation) +    if (gWindowImplementation && gWindowImplementation->getCallbacks())      {          gWindowImplementation->getCallbacks()->handleFocusLost(gWindowImplementation);      } @@ -316,6 +320,10 @@ void callFocusLost()  void callRightMouseDown(float *pos, MASK mask)  { +    if (!gWindowImplementation) +    { +        return; +    }      if (gWindowImplementation->allowsLanguageInput())      {          gWindowImplementation->interruptLanguageTextInput(); @@ -329,6 +337,10 @@ void callRightMouseDown(float *pos, MASK mask)  void callRightMouseUp(float *pos, MASK mask)  { +    if (!gWindowImplementation) +    { +        return; +    }      if (gWindowImplementation->allowsLanguageInput())      {          gWindowImplementation->interruptLanguageTextInput(); @@ -342,6 +354,10 @@ void callRightMouseUp(float *pos, MASK mask)  void callLeftMouseDown(float *pos, MASK mask)  { +    if (!gWindowImplementation) +    { +        return; +    }      if (gWindowImplementation->allowsLanguageInput())      {          gWindowImplementation->interruptLanguageTextInput(); @@ -355,6 +371,10 @@ void callLeftMouseDown(float *pos, MASK mask)  void callLeftMouseUp(float *pos, MASK mask)  { +    if (!gWindowImplementation) +    { +        return; +    }      if (gWindowImplementation->allowsLanguageInput())      {          gWindowImplementation->interruptLanguageTextInput(); @@ -369,6 +389,10 @@ void callLeftMouseUp(float *pos, MASK mask)  void callDoubleClick(float *pos, MASK mask)  { +    if (!gWindowImplementation) +    { +        return; +    }      if (gWindowImplementation->allowsLanguageInput())      {          gWindowImplementation->interruptLanguageTextInput(); @@ -382,7 +406,7 @@ void callDoubleClick(float *pos, MASK mask)  void callResize(unsigned int width, unsigned int height)  { -    if (gWindowImplementation != NULL) +    if (gWindowImplementation && gWindowImplementation->getCallbacks())      {          gWindowImplementation->getCallbacks()->handleResize(gWindowImplementation, width, height);      } @@ -390,6 +414,10 @@ void callResize(unsigned int width, unsigned int height)  void callMouseMoved(float *pos, MASK mask)  { +    if (!gWindowImplementation) +    { +        return; +    }      LLCoordGL       outCoords;      outCoords.mX = ll_round(pos[0]);      outCoords.mY = ll_round(pos[1]); @@ -403,6 +431,10 @@ void callMouseMoved(float *pos, MASK mask)  void callMouseDragged(float *pos, MASK mask)  { +    if (!gWindowImplementation) +    { +        return; +    }      LLCoordGL       outCoords;      outCoords.mX = ll_round(pos[0]);      outCoords.mY = ll_round(pos[1]); @@ -424,6 +456,10 @@ void callScrollMoved(float deltaX, float deltaY)  void callMouseExit()  { +    if (!gWindowImplementation) +    { +        return; +    }      gWindowImplementation->getCallbacks()->handleMouseLeave(gWindowImplementation);  } @@ -475,11 +511,19 @@ void callWindowDidChangeScreen()  void callDeltaUpdate(float *delta, MASK mask)  { +    if (!gWindowImplementation) +    { +        return; +    }      gWindowImplementation->updateMouseDeltas(delta);  }  void callOtherMouseDown(float *pos, MASK mask, int button)  { +    if (!gWindowImplementation) +    { +        return; +    }      LLCoordGL       outCoords;      outCoords.mX = ll_round(pos[0]);      outCoords.mY = ll_round(pos[1]); @@ -500,6 +544,10 @@ void callOtherMouseDown(float *pos, MASK mask, int button)  void callOtherMouseUp(float *pos, MASK mask, int button)  { +    if (!gWindowImplementation) +    { +        return; +    }      LLCoordGL outCoords;      outCoords.mX = ll_round(pos[0]);      outCoords.mY = ll_round(pos[1]); @@ -524,27 +572,43 @@ void callModifier(MASK mask)  void callHandleDragEntered(std::string url)  { +    if (!gWindowImplementation) +    { +        return; +    }      gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_START_TRACKING);  }  void callHandleDragExited(std::string url)  { +    if (!gWindowImplementation) +    { +        return; +    }      gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_STOP_TRACKING);  }  void callHandleDragUpdated(std::string url)  { +    if (!gWindowImplementation) +    { +        return; +    }      gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_TRACK);  }  void callHandleDragDropped(std::string url)  { +    if (!gWindowImplementation) +    { +        return; +    }      gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_DROPPED);  }  void callQuitHandler()  { -    if (gWindowImplementation) +    if (gWindowImplementation && gWindowImplementation->getCallbacks())      {          if(gWindowImplementation->getCallbacks()->handleCloseRequest(gWindowImplementation))          { @@ -555,7 +619,7 @@ void callQuitHandler()  void getPreeditSelectionRange(int *position, int *length)  { -    if (gWindowImplementation->getPreeditor()) +    if (gWindowImplementation && gWindowImplementation->getPreeditor())      {          gWindowImplementation->getPreeditor()->getSelectionRange(position, length);      } @@ -563,7 +627,7 @@ void getPreeditSelectionRange(int *position, int *length)  void getPreeditMarkedRange(int *position, int *length)  { -    if (gWindowImplementation->getPreeditor()) +    if (gWindowImplementation && gWindowImplementation->getPreeditor())      {          gWindowImplementation->getPreeditor()->getPreeditRange(position, length);      } @@ -571,7 +635,7 @@ void getPreeditMarkedRange(int *position, int *length)  void setPreeditMarkedRange(int position, int length)  { -    if (gWindowImplementation->getPreeditor()) +    if (gWindowImplementation && gWindowImplementation->getPreeditor())      {          gWindowImplementation->getPreeditor()->markAsPreedit(position, length);      } @@ -580,7 +644,7 @@ void setPreeditMarkedRange(int position, int length)  bool handleUnicodeCharacter(wchar_t c)  {      bool success = false; -    if (gWindowImplementation->getPreeditor()) +    if (gWindowImplementation && gWindowImplementation->getPreeditor())      {          success = gWindowImplementation->getPreeditor()->handleUnicodeCharHere(c);      } @@ -590,7 +654,7 @@ bool handleUnicodeCharacter(wchar_t c)  void resetPreedit()  { -    if (gWindowImplementation->getPreeditor()) +    if (gWindowImplementation && gWindowImplementation->getPreeditor())      {          gWindowImplementation->getPreeditor()->resetPreedit();      } @@ -600,7 +664,7 @@ void resetPreedit()  // This largely mirrors the old implementation, only sans the carbon parameters.  void setMarkedText(unsigned short *unitext, unsigned int *selectedRange, unsigned int *replacementRange, long text_len, attributedStringInfo segments)  { -    if (gWindowImplementation->getPreeditor()) +    if (gWindowImplementation && gWindowImplementation->getPreeditor())      {          LLPreeditor *preeditor = gWindowImplementation->getPreeditor();          preeditor->resetPreedit(); @@ -623,7 +687,7 @@ void setMarkedText(unsigned short *unitext, unsigned int *selectedRange, unsigne  void getPreeditLocation(float *location, unsigned int length)  { -    if (gWindowImplementation->getPreeditor()) +    if (gWindowImplementation && gWindowImplementation->getPreeditor())      {          LLPreeditor *preeditor = gWindowImplementation->getPreeditor();          LLCoordGL coord; diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 3210b76649..ed29911a43 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -291,6 +291,7 @@ set(viewer_SOURCE_FILES      llfloatersettingscolor.cpp      llfloatersettingsdebug.cpp      llfloatersidepanelcontainer.cpp +    llfloaterslapptest.cpp      llfloatersnapshot.cpp      llfloatersounddevices.cpp      llfloaterspellchecksettings.cpp @@ -962,6 +963,7 @@ set(viewer_HEADER_FILES      llfloatersettingscolor.h      llfloatersettingsdebug.h      llfloatersidepanelcontainer.h +    llfloaterslapptest.h      llfloatersnapshot.h      llfloatersounddevices.h      llfloaterspellchecksettings.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 86d36b3f29..a2a6744722 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -3676,6 +3676,17 @@          <key>Value</key>          <integer>5000</integer>      </map> +    <key>InventoryExposeFolderID</key> +    <map> +        <key>Comment</key> +        <string>Allows copying folder id from context menu</string> +        <key>Persist</key> +        <integer>0</integer> +        <key>Type</key> +        <string>Boolean</string> +        <key>Value</key> +        <integer>0</integer> +    </map>      <key>MarketplaceListingsSortOrder</key>      <map>        <key>Comment</key> @@ -7803,7 +7814,7 @@        <key>Type</key>        <string>U32</string>        <key>Value</key> -      <integer>2</integer> +      <integer>1</integer>    </map>    <key>RenderMinFreeMainMemoryThreshold</key>    <map> @@ -9076,6 +9087,17 @@      <key>Value</key>      <integer>1</integer>    </map> +    <key>RenderReflectionProbeDynamicAllocation</key> +    <map> +        <key>Comment</key> +        <string>Enable dynamic allocation of reflection probes. -1 means no dynamic allocation. Sets a buffer to allocate when a dynamic allocation occurs otherwise.</string> +        <key>Persist</key> +        <integer>1</integer> +        <key>Type</key> +        <string>S32</string> +        <key>Value</key> +        <integer>-1</integer> +    </map>      <key>RenderReflectionProbeCount</key>      <map>          <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl index 205d4bff6d..5089b9e31e 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl @@ -154,6 +154,7 @@ void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, ou      if (classic_mode < 1)      {          amblit = srgb_to_linear(amblit); +        amblit = vec3(dot(amblit, vec3(0.2126, 0.7152, 0.0722)));          sunlit = srgb_to_linear(sunlit);      } diff --git a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl index 1b7b0c1937..349f3b9a67 100644 --- a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl +++ b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl @@ -264,11 +264,11 @@ void main()      // Calculate some distance fade in the water to better assist with refraction blending and reducing the refraction texture's "disconnect".  #ifdef SHORELINE_FADE -    fade = max(0,min(1, (pos.z - refPos.z) / 10)) +    fade = max(0,min(1, (pos.z - refPos.z) / 10));  #else -    fade = 1 * water_mask; +    fade = 1;  #endif - +    fade *= water_mask;      distort2 = mix(distort, distort2, min(1, fade * 10));      depth = texture(depthMap, distort2).r; diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index 883963d558..c0009d24ee 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -172,7 +172,7 @@ RenderTonemapType			1   1  RenderTonemapMix			1   0.7  RenderDisableVintageMode           1   0  RenderMaxTextureResolution         1   1024 -RenderReflectionProbeCount  1   16 +RenderReflectionProbeCount  1   32  //  // Medium Graphics Settings (standard) @@ -214,7 +214,7 @@ RenderExposure				1   1  RenderTonemapType			1   1  RenderTonemapMix			1   0.7  RenderMaxTextureResolution  1   2048 -RenderReflectionProbeCount  1   32 +RenderReflectionProbeCount  1   64  //  // Medium High Graphics Settings @@ -245,7 +245,7 @@ RenderFSAASamples			1	1  RenderReflectionsEnabled    1   1  RenderReflectionProbeDetail	1	1  RenderScreenSpaceReflections 1  0 -RenderReflectionProbeLevel  1   2 +RenderReflectionProbeLevel  1   1  RenderMirrors				1	0  RenderHeroProbeResolution	1	512  RenderHeroProbeDistance		1	6 @@ -287,7 +287,7 @@ RenderFSAASamples			1	2  RenderReflectionsEnabled    1   1  RenderReflectionProbeDetail	1	1  RenderScreenSpaceReflections 1  0 -RenderReflectionProbeLevel  1   3 +RenderReflectionProbeLevel  1   2  RenderMirrors				1	0  RenderHeroProbeResolution	1	512  RenderHeroProbeDistance		1	8 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index 103d24a26d..5940d1ec12 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -172,7 +172,7 @@ RenderTonemapType			1   1  RenderTonemapMix			1   0.7  RenderDisableVintageMode           1   0  RenderMaxTextureResolution         1   1024 -RenderReflectionProbeCount  1   16 +RenderReflectionProbeCount  1   32  //  // Medium Graphics Settings (standard) @@ -214,7 +214,7 @@ RenderExposure				1   1  RenderTonemapType			1   1  RenderTonemapMix			1   0.7  RenderMaxTextureResolution  1   2048 -RenderReflectionProbeCount  1   32 +RenderReflectionProbeCount  1   64  //  // Medium High Graphics Settings diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 3f7aaf9557..dfe4a0c197 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -445,8 +445,8 @@ void idle_afk_check()  {      // check idle timers      F32 current_idle = gAwayTriggerTimer.getElapsedTimeF32(); -    F32 afk_timeout  = (F32)gSavedSettings.getS32("AFKTimeout"); -    if (afk_timeout && (current_idle > afk_timeout) && ! gAgent.getAFK()) +    static LLCachedControl<S32> afk_timeout(gSavedSettings, "AFKTimeout", 300); +    if (afk_timeout() && (current_idle > (F32)afk_timeout()) && !gAgent.getAFK())      {          LL_INFOS("IdleAway") << "Idle more than " << afk_timeout << " seconds: automatically changing to Away status" << LL_ENDL;          gAgent.setAFK(); @@ -5217,15 +5217,28 @@ void LLAppViewer::sendLogoutRequest()          gLogoutInProgress = true;          if (!mSecondInstance)          { -            mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LOGOUT_MARKER_FILE_NAME); - -            mLogoutMarkerFile.open(mLogoutMarkerFileName, LL_APR_WB); -            if (mLogoutMarkerFile.getFileHandle()) +            mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LOGOUT_MARKER_FILE_NAME); +            try              { -                LL_INFOS("MarkerFile") << "Created logout marker file '"<< mLogoutMarkerFileName << "' " << LL_ENDL; -                recordMarkerVersion(mLogoutMarkerFile); +                if (!mLogoutMarkerFile.getFileHandle()) +                { +                    mLogoutMarkerFile.open(mLogoutMarkerFileName, LL_APR_WB); +                    if (mLogoutMarkerFile.getFileHandle()) +                    { +                        LL_INFOS("MarkerFile") << "Created logout marker file '" << mLogoutMarkerFileName << "' " << LL_ENDL; +                        recordMarkerVersion(mLogoutMarkerFile); +                    } +                    else +                    { +                        LL_WARNS("MarkerFile") << "Cannot create logout marker file " << mLogoutMarkerFileName << LL_ENDL; +                    } +                } +                else +                { +                    LL_WARNS("MarkerFile") << "Atempted to reopen file '" << mLogoutMarkerFileName << "' " << LL_ENDL; +                }              } -            else +            catch (...)              {                  LL_WARNS("MarkerFile") << "Cannot create logout marker file " << mLogoutMarkerFileName << LL_ENDL;              } @@ -5377,7 +5390,8 @@ void LLAppViewer::idleNetwork()      gObjectList.mNumNewObjects = 0;      S32 total_decoded = 0; -    if (!gSavedSettings.getBOOL("SpeedTest")) +    static LLCachedControl<bool> speed_test(gSavedSettings, "SpeedTest", false); +    if (!speed_test())      {          LL_PROFILE_ZONE_NAMED_CATEGORY_NETWORK("idle network"); //LL_RECORD_BLOCK_TIME(FTM_IDLE_NETWORK); // decode @@ -5436,7 +5450,9 @@ void LLAppViewer::idleNetwork()              }              // Handle per-frame message system processing. -            lmc.processAcks(gSavedSettings.getF32("AckCollectTime")); + +            static LLCachedControl<F32> ack_collection_time(gSavedSettings, "AckCollectTime", 0.1f); +            lmc.processAcks(ack_collection_time());          }      }      add(LLStatViewer::NUM_NEW_OBJECTS, gObjectList.mNumNewObjects); diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index b4a2479520..aaf2a7ea3e 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -155,10 +155,10 @@ namespace              sBugSplatSender->setAttribute(WCSTR(L"OS"), WCSTR(LLOSInfo::instance().getOSStringSimple())); // In case we ever stop using email for this              sBugSplatSender->setAttribute(WCSTR(L"AppState"), WCSTR(LLStartUp::getStartupStateString())); -            sBugSplatSender->setAttribute(WCSTR(L"GL Vendor"), WCSTR(gGLManager.mGLVendor)); -            sBugSplatSender->setAttribute(WCSTR(L"GL Version"), WCSTR(gGLManager.mGLVersionString)); -            sBugSplatSender->setAttribute(WCSTR(L"GPU Version"), WCSTR(gGLManager.mDriverVersionVendorString)); -            sBugSplatSender->setAttribute(WCSTR(L"GL Renderer"), WCSTR(gGLManager.mGLRenderer)); +            sBugSplatSender->setAttribute(WCSTR(L"GLVendor"), WCSTR(gGLManager.mGLVendor)); +            sBugSplatSender->setAttribute(WCSTR(L"GLVersion"), WCSTR(gGLManager.mGLVersionString)); +            sBugSplatSender->setAttribute(WCSTR(L"GPUVersion"), WCSTR(gGLManager.mDriverVersionVendorString)); +            sBugSplatSender->setAttribute(WCSTR(L"GLRenderer"), WCSTR(gGLManager.mGLRenderer));              sBugSplatSender->setAttribute(WCSTR(L"VRAM"), WCSTR(STRINGIZE(gGLManager.mVRAM)));              sBugSplatSender->setAttribute(WCSTR(L"RAM"), WCSTR(STRINGIZE(gSysMemory.getPhysicalMemoryKB().value()))); diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp index 6efd503574..26ef190fbb 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -108,8 +108,9 @@ void LLDrawPoolTree::beginShadowPass(S32 pass)  {      LL_PROFILE_ZONE_SCOPED; -    glPolygonOffset(gSavedSettings.getF32("RenderDeferredTreeShadowOffset"), -                    gSavedSettings.getF32("RenderDeferredTreeShadowBias")); +    static LLCachedControl<F32> shadow_offset(gSavedSettings, "RenderDeferredTreeShadowOffset"); +    static LLCachedControl<F32> shadow_bias(gSavedSettings, "RenderDeferredTreeShadowBias"); +    glPolygonOffset(shadow_offset(), shadow_bias());      LLEnvironment& environment = LLEnvironment::instance(); diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 811aacb2ed..373a556f86 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -2218,7 +2218,7 @@ bool LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)      {          LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("calcPixelArea - rigged");          //override with joint volume face joint bounding boxes -        LLVOAvatar* avatar = mVObjp->getAvatar(); +        LLVOAvatar* avatar = mVObjp.notNull() ? mVObjp->getAvatar() : nullptr;          bool hasRiggedExtents = false;          if (avatar && avatar->mDrawable) diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp index c2821d56d6..558fc92018 100644 --- a/indra/newview/llfetchedgltfmaterial.cpp +++ b/indra/newview/llfetchedgltfmaterial.cpp @@ -199,6 +199,7 @@ bool LLFetchedGLTFMaterial::replaceLocalTexture(const LLUUID& tracking_id, const      {          mTrackingIdToLocalTexture.erase(tracking_id);      } +    updateLocalTexDataDigest();      return res;  } diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index e55bf50724..e4b14d8df6 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -1939,7 +1939,7 @@ bool LLFloaterIMContainer::removeConversationListItem(const LLUUID& uuid, bool c      mConversationEventQueue.erase(uuid);      // Don't let the focus fall IW, select and refocus on the first conversation in the list -    if (change_focus) +    if (change_focus && isInVisibleChain())      {          setFocus(true);          if (new_selection) @@ -1959,6 +1959,10 @@ bool LLFloaterIMContainer::removeConversationListItem(const LLUUID& uuid, bool c              }          }      } +    else +    { +        LL_INFOS() << "Conversation widgets: " << (S32)mConversationsWidgets.size() << LL_ENDL; +    }      return is_widget_selected;  } diff --git a/indra/newview/llfloaterslapptest.cpp b/indra/newview/llfloaterslapptest.cpp new file mode 100644 index 0000000000..0075379529 --- /dev/null +++ b/indra/newview/llfloaterslapptest.cpp @@ -0,0 +1,51 @@ +/** + * @file llfloaterslapptest.cpp + * + * $LicenseInfo:firstyear=2025&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2025, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterslapptest.h" +#include "lluictrlfactory.h" + +#include "lllineeditor.h" +#include "lltextbox.h" + +LLFloaterSLappTest::LLFloaterSLappTest(const LLSD& key) +    :   LLFloater("floater_test_slapp") +{ +} + +LLFloaterSLappTest::~LLFloaterSLappTest() +{} + +bool LLFloaterSLappTest::postBuild() +{ +    getChild<LLLineEditor>("remove_folder_id")->setKeystrokeCallback([this](LLLineEditor* editor, void*) +        { +            std::string slapp(getString("remove_folder_slapp")); +            getChild<LLTextBox>("remove_folder_txt")->setValue(slapp + editor->getValue().asString()); +        }, NULL); + +    return true; +} diff --git a/indra/newview/llfloaterslapptest.h b/indra/newview/llfloaterslapptest.h new file mode 100644 index 0000000000..ec727cb629 --- /dev/null +++ b/indra/newview/llfloaterslapptest.h @@ -0,0 +1,42 @@ +/** + * @file llfloaterslapptest.h + * + * $LicenseInfo:firstyear=2025&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2025, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLFLOATERSLAPPTEST_H +#define LL_LLFLOATERSLAPPTEST_H + +#include "llfloater.h" + +class LLFloaterSLappTest: +    public LLFloater +{ +    friend class LLFloaterReg; +    virtual bool postBuild() override; + +private: +    LLFloaterSLappTest(const LLSD& key); +    ~LLFloaterSLappTest(); +}; + +#endif diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 479b7c19ac..ce91f9a1f3 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -3599,6 +3599,13 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)          const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);          move_folder_to_marketplacelistings(cat, marketplacelistings_id, ("move_to_marketplace_listings" != action), (("copy_or_move_to_marketplace_listings" == action)));      } +    else if ("copy_folder_uuid" == action) +    { +        LLInventoryCategory* cat = gInventory.getCategory(mUUID); +        if (!cat) return; +        gViewerWindow->getWindow()->copyTextToClipboard(utf8str_to_wstring(mUUID.asString())); +        return; +    }  }  void LLFolderBridge::gatherMessage(std::string& message, S32 depth, LLError::ELevel log_level) @@ -4466,6 +4473,14 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t&   items      {          disabled_items.push_back(std::string("Delete System Folder"));      } +    else +    { +        static LLCachedControl<bool> show_copy_id(gSavedSettings, "InventoryExposeFolderID", false); +        if (show_copy_id()) +        { +            items.push_back(std::string("Copy UUID")); +        } +    }      if (isAgentInventory() && !isMarketplaceListingsFolder())      { diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index 72a7fe8814..75c77e9301 100644 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -298,8 +298,9 @@ void LLLocalBitmap::addGLTFMaterial(LLGLTFMaterial* mat)          return;      } -    mat_list_t::iterator end = mGLTFMaterialWithLocalTextures.end(); -    for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != end;) +    mat->addLocalTextureTracking(getTrackingID(), getWorldID()); + +    for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != mGLTFMaterialWithLocalTextures.end();)      {          if (it->get() == mat)          { @@ -309,15 +310,12 @@ void LLLocalBitmap::addGLTFMaterial(LLGLTFMaterial* mat)          if ((*it)->getNumRefs() == 1)          {              it = mGLTFMaterialWithLocalTextures.erase(it); -            end = mGLTFMaterialWithLocalTextures.end();          }          else          {              it++;          }      } - -    mat->addLocalTextureTracking(getTrackingID(), getWorldID());      mGLTFMaterialWithLocalTextures.push_back(mat);  } @@ -648,16 +646,16 @@ void LLLocalBitmap::updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableTyp  void LLLocalBitmap::updateGLTFMaterials(LLUUID old_id, LLUUID new_id)  {      // Might be a better idea to hold this in LLGLTFMaterialList -    mat_list_t::iterator end = mGLTFMaterialWithLocalTextures.end(); -    for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != end;) +    for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != mGLTFMaterialWithLocalTextures.end();)      {          if ((*it)->getNumRefs() == 1)          {              // render and override materials are often recreated,              // clean up any remains              it = mGLTFMaterialWithLocalTextures.erase(it); -            end = mGLTFMaterialWithLocalTextures.end();          } +        // Render material consists of base and override materials, make sure replaceLocalTexture +        // gets called for base and override before applyOverride          else if ((*it)->replaceLocalTexture(mTrackingID, old_id, new_id))          {              it++; @@ -667,43 +665,47 @@ void LLLocalBitmap::updateGLTFMaterials(LLUUID old_id, LLUUID new_id)              // Matching id not found, no longer in use              // material would clean itself, remove from the list              it = mGLTFMaterialWithLocalTextures.erase(it); -            end = mGLTFMaterialWithLocalTextures.end();          }      } -    // Render material consists of base and override materials, make sure replaceLocalTexture -    // gets called for base and override before applyOverride -    end = mGLTFMaterialWithLocalTextures.end(); -    for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != end;) +    // Updating render materials calls updateTextureTracking which can modify +    // mGLTFMaterialWithLocalTextures, so precollect all entries that need to be updated +    std::set<LLTextureEntry*> update_entries; +    for (LLGLTFMaterial* mat : mGLTFMaterialWithLocalTextures)      { -        LLFetchedGLTFMaterial* fetched_mat = dynamic_cast<LLFetchedGLTFMaterial*>((*it).get()); +        // mGLTFMaterialWithLocalTextures includes overrides that are not 'fetched' +        // and don't have texture entries (they don't need to since render material does). +        LLFetchedGLTFMaterial* fetched_mat = dynamic_cast<LLFetchedGLTFMaterial*>(mat);          if (fetched_mat)          {              for (LLTextureEntry* entry : fetched_mat->mTextureEntires)              { -                // Normally a change in applied material id is supposed to -                // drop overrides thus reset material, but local materials -                // currently reuse their existing asset id, and purpose is -                // to preview how material will work in-world, overrides -                // included, so do an override to render update instead. -                LLGLTFMaterial* override_mat = entry->getGLTFMaterialOverride(); -                if (override_mat) -                { -                    // do not create a new material, reuse existing pointer -                    LLFetchedGLTFMaterial* render_mat = dynamic_cast<LLFetchedGLTFMaterial*>(entry->getGLTFRenderMaterial()); -                    if (render_mat) -                    { -                            *render_mat = *fetched_mat; -                        render_mat->applyOverride(*override_mat); -                    } -                    else -                    { -                        LL_WARNS_ONCE() << "Failed to apply local material override, render material not found" << LL_ENDL; -                    } -                } +                update_entries.insert(entry); +            } +        } +    } + + +    for (LLTextureEntry* entry : update_entries) +    { +        // Normally a change in applied material id is supposed to +        // drop overrides thus reset material, but local materials +        // currently reuse their existing asset id, and purpose is +        // to preview how material will work in-world, overrides +        // included, so do an override to render update instead. +        LLGLTFMaterial* override_mat = entry->getGLTFMaterialOverride(); +        LLGLTFMaterial* mat = entry->getGLTFMaterial(); +        if (override_mat && mat) +        { +            // do not create a new material, reuse existing pointer +            // so that mTextureEntires remains untouched +            LLGLTFMaterial* render_mat = entry->getGLTFRenderMaterial(); +            if (render_mat) +            { +                *render_mat = *mat; +                render_mat->applyOverride(*override_mat); // can update mGLTFMaterialWithLocalTextures              }          } -        ++it;      }  } diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h index 06770334e4..6c9d65e3b6 100644 --- a/indra/newview/lllocalbitmaps.h +++ b/indra/newview/lllocalbitmaps.h @@ -107,7 +107,7 @@ class LLLocalBitmap          // Store a list of accosiated materials          // Might be a better idea to hold this in LLGLTFMaterialList -        typedef std::vector<LLPointer<LLGLTFMaterial> > mat_list_t; +        typedef std::list<LLPointer<LLGLTFMaterial> > mat_list_t;          mat_list_t mGLTFMaterialWithLocalTextures;  }; diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index e1fa84b4d8..a8c6f69425 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -4573,6 +4573,8 @@ void LLMeshRepository::notifyLoadedMeshes()                  std::partial_sort(mPendingRequests.begin(), mPendingRequests.begin() + push_count,                                    mPendingRequests.end(), PendingRequestBase::CompareScoreGreater());              } +            LLMutexTrylock lock3(mThread->mHeaderMutex); +            LLMutexTrylock lock4(mThread->mPendingMutex);              while (!mPendingRequests.empty() && push_count > 0)              {                  std::unique_ptr<PendingRequestBase>& req_p = mPendingRequests.front(); diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index f491cccaf8..b7d9df6ea6 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -3075,8 +3075,7 @@ void LLPanelFace::onCommitHideWater()      }      else      { -        // reset texture to default plywood -        LLSelectMgr::getInstance()->selectionSetImage(DEFAULT_OBJECT_TEXTURE); +        LLSelectMgr::getInstance()->clearWaterExclusion();      }  } diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp index f3adb52d5e..910509928d 100644 --- a/indra/newview/llreflectionmap.cpp +++ b/indra/newview/llreflectionmap.cpp @@ -52,6 +52,9 @@ LLReflectionMap::~LLReflectionMap()  void LLReflectionMap::update(U32 resolution, U32 face, bool force_dynamic, F32 near_clip, bool useClipPlane, LLPlane clipPlane)  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; +    if (!mCubeArray.notNull()) +        return; +      mLastUpdateTime = gFrameTimeSeconds;      llassert(mCubeArray.notNull());      llassert(mCubeIndex != -1); diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 48b73531ea..f2abc7b8b7 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -144,13 +144,14 @@ static void touch_default_probe(LLReflectionMap* probe)  LLReflectionMapManager::LLReflectionMapManager()  { +    mDynamicProbeCount = LL_MAX_REFLECTION_PROBE_COUNT;      initCubeFree();  }  void LLReflectionMapManager::initCubeFree()  {      // start at 1 because index 0 is reserved for mDefaultProbe -    for (int i = 1; i < LL_MAX_REFLECTION_PROBE_COUNT; ++i) +    for (U32 i = 1; i < mDynamicProbeCount; ++i)      {          mCubeFree.push_back(i);      } @@ -221,12 +222,53 @@ void LLReflectionMapManager::update()          resume();      } -    static LLCachedControl<U32> probe_count(gSavedSettings, "RenderReflectionProbeCount", 256U); -    bool countReset = mReflectionProbeCount != probe_count; +    static LLCachedControl<S32> sDetail(gSavedSettings, "RenderReflectionProbeDetail", -1); +    static LLCachedControl<S32> sLevel(gSavedSettings, "RenderReflectionProbeLevel", 3); +    static LLCachedControl<U32> sReflectionProbeCount(gSavedSettings, "RenderReflectionProbeCount", 256U); +    static LLCachedControl<S32> sProbeDynamicAllocation(gSavedSettings, "RenderReflectionProbeDynamicAllocation", -1); +    mResetFade = llmin((F32)(mResetFade + gFrameIntervalSeconds * 2.f), 1.f); -    if (countReset)      { -        mResetFade = -0.5f; +        U32 probe_count_temp = mDynamicProbeCount; +        if (sProbeDynamicAllocation > -1) +        { +            if (sLevel == 0) +            { +                mDynamicProbeCount = 1; +            } +            else if (sLevel == 1) +            { +                mDynamicProbeCount = (U32)mProbes.size(); +            } +            else if (sLevel == 2) +            { +                mDynamicProbeCount = llmax((U32)mProbes.size(), 128); +            } +            else +            { +                mDynamicProbeCount = 256; +            } + +            if (sProbeDynamicAllocation > 1) +            { +                // Round mDynamicProbeCount to the nearest increment of 16 +                mDynamicProbeCount = ((mDynamicProbeCount + sProbeDynamicAllocation / 2) / sProbeDynamicAllocation) * 16; +                mDynamicProbeCount = llclamp(mDynamicProbeCount, 1, sReflectionProbeCount); +            } +            else +            { +                mDynamicProbeCount = llclamp(mDynamicProbeCount + sProbeDynamicAllocation, 1, sReflectionProbeCount); +            } +        } +        else +        { +            mDynamicProbeCount = sReflectionProbeCount; +        } + +        mDynamicProbeCount = llmin(mDynamicProbeCount, LL_MAX_REFLECTION_PROBE_COUNT); + +        if (mDynamicProbeCount != probe_count_temp) +            mResetFade = 1.f;      }      initReflectionMaps(); @@ -286,9 +328,6 @@ void LLReflectionMapManager::update()      bool did_update = false; -    static LLCachedControl<S32> sDetail(gSavedSettings, "RenderReflectionProbeDetail", -1); -    static LLCachedControl<S32> sLevel(gSavedSettings, "RenderReflectionProbeLevel", 3); -      bool realtime = sDetail >= (S32)LLReflectionMapManager::DetailLevel::REALTIME;      LLReflectionMap* closestDynamic = nullptr; @@ -323,6 +362,7 @@ void LLReflectionMapManager::update()              probe->mCubeArray = nullptr;              probe->mCubeIndex = -1;              probe->mComplete = false; +            probe->mFadeIn = 0;          }      } @@ -343,12 +383,7 @@ void LLReflectionMapManager::update()          }      } -    if (countReset) -    { -        mResetFade = -0.5f; -    } - -    mResetFade = llmin((F32)(mResetFade + gFrameIntervalSeconds), 1.f); +    mResetFade = llmin((F32)(mResetFade + gFrameIntervalSeconds * 2.f), 1.f);      for (unsigned int i = 0; i < mProbes.size(); ++i)      { @@ -520,6 +555,16 @@ LLReflectionMap* LLReflectionMapManager::addProbe(LLSpatialGroup* group)      return probe;  } +U32 LLReflectionMapManager::probeCount() +{ +    return mDynamicProbeCount; +} + +U32 LLReflectionMapManager::probeMemory() +{ +    return (mDynamicProbeCount * 6 * (mProbeResolution * mProbeResolution) * 4) / 1024 / 1024 + (mDynamicProbeCount * 6 * (LL_IRRADIANCE_MAP_RESOLUTION * LL_IRRADIANCE_MAP_RESOLUTION) * 4) / 1024 / 1024; +} +  struct CompareProbeDepth  {      bool operator()(const LLReflectionMap* lhs, const LLReflectionMap* rhs) @@ -1058,7 +1103,11 @@ void LLReflectionMapManager::updateUniforms()      bool is_ambiance_pass = gCubeSnapshot && !isRadiancePass();      F32 ambscale = is_ambiance_pass ? 0.f : 1.f; +    ambscale *= mResetFade; +    ambscale = llmax(0, ambscale);      F32 radscale = is_ambiance_pass ? 0.5f : 1.f; +    radscale *= mResetFade; +    radscale = llmax(0, radscale);      for (auto* refmap : mReflectionMaps)      { @@ -1129,8 +1178,8 @@ void LLReflectionMapManager::updateUniforms()          }          mProbeData.refParams[count].set( -            llmax(minimum_ambiance, refmap->getAmbiance())*ambscale * llmax(mResetFade, 0.f), // ambiance scale -            radscale * llmax(mResetFade, 0.f), // radiance scale +            llmax(minimum_ambiance, refmap->getAmbiance())*ambscale, // ambiance scale +            radscale, // radiance scale              refmap->mFadeIn, // fade in weight              oa.getF32ptr()[2] - refmap->mRadius); // z near @@ -1365,12 +1414,9 @@ void LLReflectionMapManager::renderDebug()  void LLReflectionMapManager::initReflectionMaps()  { -    static LLCachedControl<U32> probe_count(gSavedSettings, "RenderReflectionProbeCount", 256U); -    U32 count = probe_count(); -      static LLCachedControl<U32> ref_probe_res(gSavedSettings, "RenderReflectionProbeResolution", 128U);      U32 probe_resolution = nhpo2(llclamp(ref_probe_res(), (U32)64, (U32)512)); -    if (mTexture.isNull() || mReflectionProbeCount != count || mProbeResolution != probe_resolution || mReset) +    if (mTexture.isNull() || mReflectionProbeCount != mDynamicProbeCount || mProbeResolution != probe_resolution || mReset)      {          if(mProbeResolution != probe_resolution)          { @@ -1379,9 +1425,8 @@ void LLReflectionMapManager::initReflectionMaps()          }          gEXRImage = nullptr; -          mReset = false; -        mReflectionProbeCount = count; +        mReflectionProbeCount = mDynamicProbeCount;          mProbeResolution = probe_resolution;          mMaxProbeLOD = log2f((F32)mProbeResolution) - 1.f; // number of mips - 1 @@ -1389,15 +1434,25 @@ void LLReflectionMapManager::initReflectionMaps()              mTexture->getWidth() != mProbeResolution ||              mReflectionProbeCount + 2 != mTexture->getCount())          { -            mTexture = new LLCubeMapArray(); +            if (mTexture) +            { +                mTexture = new LLCubeMapArray(*mTexture, mProbeResolution, mReflectionProbeCount + 2); -            static LLCachedControl<bool> render_hdr(gSavedSettings, "RenderHDREnabled", true); +                mIrradianceMaps = new LLCubeMapArray(*mIrradianceMaps, LL_IRRADIANCE_MAP_RESOLUTION, mReflectionProbeCount); +            } +            else +            { +                mTexture = new LLCubeMapArray(); -            // store mReflectionProbeCount+2 cube maps, final two cube maps are used for render target and radiance map generation source) -            mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2, true, render_hdr); +                static LLCachedControl<bool> render_hdr(gSavedSettings, "RenderHDREnabled", true); -            mIrradianceMaps = new LLCubeMapArray(); -            mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount, false, render_hdr); +                // store mReflectionProbeCount+2 cube maps, final two cube maps are used for render target and radiance map generation +                // source) +                mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2, true, render_hdr); + +                mIrradianceMaps = new LLCubeMapArray(); +                mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount, false, render_hdr); +            }          }          // reset probe state @@ -1417,6 +1472,7 @@ void LLReflectionMapManager::initReflectionMaps()              probe->mCubeArray = nullptr;              probe->mCubeIndex = -1;              probe->mNeighbors.clear(); +            probe->mFadeIn = 0;          }          mCubeFree.clear(); diff --git a/indra/newview/llreflectionmapmanager.h b/indra/newview/llreflectionmapmanager.h index 9f88776ac2..0719c28134 100644 --- a/indra/newview/llreflectionmapmanager.h +++ b/indra/newview/llreflectionmapmanager.h @@ -38,7 +38,7 @@ class LLViewerObject;  #define LL_MAX_REFLECTION_PROBE_COUNT 256  // reflection probe resolution -#define LL_IRRADIANCE_MAP_RESOLUTION 64 +#define LL_IRRADIANCE_MAP_RESOLUTION 16  // reflection probe mininum scale  #define LL_REFLECTION_PROBE_MINIMUM_SCALE 1.f; @@ -159,6 +159,9 @@ public:      // with false when done.      void forceDefaultProbeAndUpdateUniforms(bool force = true); +    U32 probeCount(); +    U32 probeMemory(); +  private:      friend class LLPipeline;      friend class LLHeroProbeManager; @@ -166,6 +169,9 @@ private:      // initialize mCubeFree array to default values      void initCubeFree(); +    // Just does a bulk clear of all of the cubemaps. +    void clearCubeMaps(); +      // delete the probe with the given index in mProbes      void deleteProbe(U32 i); @@ -240,6 +246,8 @@ private:      // number of reflection probes to use for rendering      U32 mReflectionProbeCount; +    U32 mDynamicProbeCount; +      // resolution of reflection probes      U32 mProbeResolution = 128; @@ -253,6 +261,7 @@ private:      bool mReset = false;      float mResetFade = 1.f; +    float mGlobalFadeTarget = 1.f;      // if true, only update the default probe      bool mPaused = false; diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index b2f30dd966..3d17446186 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -1995,7 +1995,7 @@ bool LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id)                      asset_id = BLANK_MATERIAL_ASSET_ID;                  }              } - +            objectp->clearTEWaterExclusion(te);              // Blank out most override data on the object and send to server              objectp->setRenderMaterialID(te, asset_id); @@ -2477,6 +2477,7 @@ void LLSelectMgr::selectionSetMedia(U8 media_type, const LLSD &media_data)                      }                      else {                          // Add/update media +                        object->clearTEWaterExclusion(te);                          object->setTEMediaFlags(te, mMediaFlags);                          LLVOVolume *vo = dynamic_cast<LLVOVolume*>(object);                          llassert(NULL != vo); @@ -7751,6 +7752,14 @@ void LLSelectMgr::setAgentHUDZoom(F32 target_zoom, F32 current_zoom)      gAgentCamera.mHUDCurZoom = current_zoom;  } +void LLSelectMgr::clearWaterExclusion() +{ +    // reset texture to default plywood +    LLSelectMgr::getInstance()->selectionSetImage(DEFAULT_OBJECT_TEXTURE); +    // reset texture repeats, that might be altered by invisiprim script from wiki +    LLSelectMgr::getInstance()->selectionTexScaleAutofit(2.f); +} +  /////////////////////////////////////////////////////////////////////////////  // Object selection iterator helpers  ///////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index e4613bb3e7..792a37297f 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -838,6 +838,7 @@ public:      void getAgentHUDZoom(F32 &target_zoom, F32 ¤t_zoom) const;      void updatePointAt(); +    void clearWaterExclusion();      // Internal list maintenance functions. TODO: Make these private!      void remove(std::vector<LLViewerObject*>& objects); diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index 78d930c05c..8560a01c4b 100644 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -559,10 +559,12 @@ void LLGLTexMemBar::draw()      gGL.color4f(0.f, 0.f, 0.f, 0.25f);      gl_rect_2d(-10, getRect().getHeight() + line_height*2 + 1, getRect().getWidth()+2, getRect().getHeight()+2); -    text = llformat("Est. Free: %d MB Sys Free: %d MB FBO: %d MB Bias: %.2f Cache: %.1f/%.1f MB", +    text = llformat("Est. Free: %d MB Sys Free: %d MB FBO: %d MB Probe#: %d Probe Mem: %d MB Bias: %.2f Cache: %.1f/%.1f MB",                      (S32)LLViewerTexture::sFreeVRAMMegabytes,                      LLMemory::getAvailableMemKB()/1024,                      LLRenderTarget::sBytesAllocated/(1024*1024), +                    gPipeline.mReflectionMapManager.probeCount(), +                    gPipeline.mReflectionMapManager.probeMemory(),                      discard_bias,                      cache_usage,                      cache_max_usage); diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp index 5ab9f76e47..255cfc998a 100644 --- a/indra/newview/llviewerassetstorage.cpp +++ b/indra/newview/llviewerassetstorage.cpp @@ -402,10 +402,10 @@ void LLViewerAssetStorage::queueRequestHttp(          manager->enqueueCoprocedure(              VIEWER_ASSET_STORAGE_CORO_POOL,              "LLViewerAssetStorage::assetRequestCoro", -            [this, req, uuid, atype, callback, user_data] +            [this, uuid, atype, callback, user_data]              (LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t&, const LLUUID&)              { -                assetRequestCoro(req, uuid, atype, callback, user_data); +                assetRequestCoro(uuid, atype, callback, user_data);              });      }  } @@ -440,7 +440,6 @@ struct LLScopedIncrement  };  void LLViewerAssetStorage::assetRequestCoro( -    LLViewerAssetRequest *req,      const LLUUID uuid,      LLAssetType::EType atype,      LLGetAssetCallback callback, @@ -464,7 +463,7 @@ void LLViewerAssetStorage::assetRequestCoro(          LL_WARNS_ONCE("ViewerAsset") << "Asset request fails: no region set" << LL_ENDL;          result_code = LL_ERR_ASSET_REQUEST_FAILED;          ext_status = LLExtStat::NONE; -        removeAndCallbackPendingDownloads(uuid, atype, uuid, atype, result_code, ext_status); +        removeAndCallbackPendingDownloads(uuid, atype, uuid, atype, result_code, ext_status, 0);          return;      }      else if (!gAgent.getRegion()->capabilitiesReceived()) @@ -495,7 +494,7 @@ void LLViewerAssetStorage::assetRequestCoro(          LL_WARNS_ONCE("ViewerAsset") << "asset request fails: caps received but no viewer asset cap found" << LL_ENDL;          result_code = LL_ERR_ASSET_REQUEST_FAILED;          ext_status = LLExtStat::NONE; -        removeAndCallbackPendingDownloads(uuid, atype, uuid, atype, result_code, ext_status); +        removeAndCallbackPendingDownloads(uuid, atype, uuid, atype, result_code, ext_status, 0);          return;      }      std::string url = getAssetURL(mViewerAssetUrl, uuid,atype); @@ -517,6 +516,7 @@ void LLViewerAssetStorage::assetRequestCoro(      mCountCompleted++; +    S32 bytes_fetched = 0;      LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];      LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);      if (!status) @@ -554,7 +554,7 @@ void LLViewerAssetStorage::assetRequestCoro(              LLUUID temp_id;              temp_id.generate();              LLFileSystem vf(temp_id, atype, LLFileSystem::WRITE); -            req->mBytesFetched = size; +            bytes_fetched = size;              if (!vf.write(raw.data(),size))              {                  // TODO asset-http: handle error @@ -583,7 +583,7 @@ void LLViewerAssetStorage::assetRequestCoro(      }      // Clean up pending downloads and trigger callbacks -    removeAndCallbackPendingDownloads(uuid, atype, uuid, atype, result_code, ext_status); +    removeAndCallbackPendingDownloads(uuid, atype, uuid, atype, result_code, ext_status, bytes_fetched);  }  std::string LLViewerAssetStorage::getAssetURL(const std::string& cap_url, const LLUUID& uuid, LLAssetType::EType atype) diff --git a/indra/newview/llviewerassetstorage.h b/indra/newview/llviewerassetstorage.h index fdb8af7457..42dd9d1dd8 100644 --- a/indra/newview/llviewerassetstorage.h +++ b/indra/newview/llviewerassetstorage.h @@ -82,8 +82,7 @@ protected:      void capsRecvForRegion(const LLUUID& region_id, std::string pumpname); -    void assetRequestCoro(LLViewerAssetRequest *req, -                          const LLUUID uuid, +    void assetRequestCoro(const LLUUID uuid,                            LLAssetType::EType atype,                            LLGetAssetCallback callback,                            void *user_data); diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index ef68609182..95c2a77ba8 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -137,6 +137,7 @@  #include "llfloatersettingscolor.h"  #include "llfloatersettingsdebug.h"  #include "llfloatersidepanelcontainer.h" +#include "llfloaterslapptest.h"  #include "llfloatersnapshot.h"  #include "llfloatersounddevices.h"  #include "llfloaterspellchecksettings.h" @@ -278,7 +279,8 @@ public:                  "upload_model",                  "upload_script",                  "upload_sound", -                "bulk_upload" +                "bulk_upload", +                "slapp_test"              };              return std::find(blacklist_untrusted.begin(), blacklist_untrusted.end(), fl_name) == blacklist_untrusted.end();          } @@ -499,6 +501,7 @@ void LLViewerFloaterReg::registerFloaters()      LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>);      LLFloaterReg::add("profile", "floater_profile.xml",(LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterProfile>);      LLFloaterReg::add("guidebook", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHowTo>); +    LLFloaterReg::add("slapp_test", "floater_test_slapp.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSLappTest>);      LLFloaterReg::add("big_preview", "floater_big_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBigPreview>); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 1caa5c61ae..8d90187e91 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -4826,6 +4826,18 @@ void LLViewerObject::setPositionParent(const LLVector3 &pos_parent, bool damped)      else      {          setPositionRegion(pos_parent, damped); + +        // #1964 mark reflection probe in the linkset to update position after moving via script +        for (LLViewerObject* child : mChildList) +        { +            if (child && child->isReflectionProbe()) +            { +                if (LLDrawable* drawablep = child->mDrawable) +                { +                    gPipeline.markMoved(drawablep); +                } +            } +        }      }  } @@ -7676,6 +7688,31 @@ void LLViewerObject::setGLTFAsset(const LLUUID& id)      updateVolume(volume_params);  } +void LLViewerObject::clearTEWaterExclusion(const U8 te) +{ +    if (permModify()) +    { +        LLViewerTexture* image = getTEImage(te); +        if (image && (IMG_ALPHA_GRAD == image->getID())) +        { +            // reset texture to default plywood +            setTEImage(te, LLViewerTextureManager::getFetchedTexture(DEFAULT_OBJECT_TEXTURE, FTT_DEFAULT, true, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); + +            // reset texture repeats, that might be altered by invisiprim script from wiki +            U32 s_axis, t_axis; +            if (!LLPrimitive::getTESTAxes(te, &s_axis, &t_axis)) +            { +                return; +            } +            F32 DEFAULT_REPEATS = 2.f; +            F32 new_s = getScale().mV[s_axis] * DEFAULT_REPEATS; +            F32 new_t = getScale().mV[t_axis] * DEFAULT_REPEATS; + +            setTEScale(te, new_s, new_t); +            sendTEUpdate(); +        } +    } +}  class ObjectPhysicsProperties : public LLHTTPNode  { diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 63458e60ea..2b52ea2076 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -405,6 +405,8 @@ public:      LLViewerTexture     *getTENormalMap(const U8 te) const;      LLViewerTexture     *getTESpecularMap(const U8 te) const; +    void clearTEWaterExclusion(const U8 te); +      bool                        isImageAlphaBlended(const U8 te) const;      void fitFaceTexture(const U8 face); diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp index 2e9b5de72b..da03d3b015 100755 --- a/indra/newview/llviewerparceloverlay.cpp +++ b/indra/newview/llviewerparceloverlay.cpp @@ -581,7 +581,7 @@ void LLViewerParcelOverlay::addPropertyLine(F32 start_x, F32 start_y, F32 dx, F3      outside_y += dy * (dy - LINE_WIDTH);      // Middle part, full width -    const S32 GRID_STEP = S32( PARCEL_GRID_STEP_METERS ); +    const S32 GRID_STEP = (S32)PARCEL_GRID_STEP_METERS;      for (S32 i = 1; i < GRID_STEP; i++)      {          inside_z = land.resolveHeightRegion( inside_x, inside_y ); @@ -666,7 +666,9 @@ void LLViewerParcelOverlay::renderPropertyLines()          return;      LLSurface& land = mRegion->getLand(); -    F32 water_z = land.getWaterHeight() + 0.01f; + +    bool render_water = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_WATER); +    F32 water_z = render_water ? land.getWaterHeight() + 0.01f : 0;      LLGLSUIDefault gls_ui; // called from pipeline      gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index a0723db479..4a9dd1c1b6 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -504,8 +504,11 @@ void LLViewerTexture::updateClass()      // NOTE: our metrics miss about half the vram we use, so this biases high but turns out to typically be within 5% of the real number      F32 used = (F32)ll_round(texture_bytes_alloc + vertex_bytes_alloc); -    F32 budget = max_vram_budget == 0 ? (F32)gGLManager.mVRAM : (F32)max_vram_budget; -    budget /= tex_vram_divisor; +    // For debugging purposes, it's useful to be able to set the VRAM budget manually. +    // But when manual control is not enabled, use the VRAM divisor. +    // While we're at it, assume we have 1024 to play with at minimum when the divisor is in use.  Works more elegantly with the logic below this. +    // -Geenz 2025-03-21 +    F32 budget = max_vram_budget == 0 ? llmax(1024, (F32)gGLManager.mVRAM / tex_vram_divisor) : (F32)max_vram_budget;      // Try to leave at least half a GB for everyone else and for bias,      // but keep at least 768MB for ourselves @@ -519,7 +522,6 @@ void LLViewerTexture::updateClass()      bool is_sys_low = isSystemMemoryLow();      bool is_low = is_sys_low || over_pct > 0.f; -    F32 discard_bias = sDesiredDiscardBias;      static bool was_low = false;      static bool was_sys_low = false; @@ -571,6 +573,7 @@ void LLViewerTexture::updateClass()      // set to max discard bias if the window has been backgrounded for a while      static F32 last_desired_discard_bias = 1.f; +    static F32 last_texture_update_count_bias = 1.f;      static bool was_backgrounded = false;      static LLFrameTimer backgrounded_timer;      static LLCachedControl<F32> minimized_discard_time(gSavedSettings, "TextureDiscardMinimizedTime", 1.f); @@ -606,12 +609,21 @@ void LLViewerTexture::updateClass()      }      sDesiredDiscardBias = llclamp(sDesiredDiscardBias, 1.f, 4.f); -    if (discard_bias != sDesiredDiscardBias) +    if (last_texture_update_count_bias < sDesiredDiscardBias)      { -        // bias changed, reset texture update counter to +        // bias increased, reset texture update counter to          // let updates happen at an increased rate. +        last_texture_update_count_bias = sDesiredDiscardBias;          sBiasTexturesUpdated = 0;      } +    else if (last_texture_update_count_bias > sDesiredDiscardBias + 0.1f) +    { +        // bias decreased, 0.1f is there to filter out small fluctuations +        // and not reset sBiasTexturesUpdated too often. +        // Bias jumps to 1.5 at low memory, so getting stuck at 1.1 is not +        // a problem. +        last_texture_update_count_bias = sDesiredDiscardBias; +    }      LLViewerTexture::sFreezeImageUpdates = false;  } diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 9f23d39506..0d02dc034e 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -899,6 +899,9 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag  {      llassert(!gCubeSnapshot); +    constexpr F32 BIAS_TRS_OUT_OF_SCREEN = 1.5f; +    constexpr F32 BIAS_TRS_ON_SCREEN = 1.f; +      if (imagep->getBoostLevel() < LLViewerFetchedTexture::BOOST_HIGH)  // don't bother checking face list for boosted textures      {          static LLCachedControl<F32> texture_scale_min(gSavedSettings, "TextureScaleMinAreaFactor", 0.0095f); @@ -940,7 +943,7 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag                      F32 vsize = face->getPixelArea(); -                    on_screen = face->mInFrustum; +                    on_screen |= face->mInFrustum;                      // Scale desired texture resolution higher or lower depending on texture scale                      // @@ -958,7 +961,8 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag                      vsize /= min_scale;                      // apply bias to offscreen faces all the time, but only to onscreen faces when bias is large -                    if (!face->mInFrustum || LLViewerTexture::sDesiredDiscardBias > 2.f) +                    // use mImportanceToCamera to make bias switch a bit more gradual +                    if (!face->mInFrustum || LLViewerTexture::sDesiredDiscardBias > 1.9f + face->mImportanceToCamera / 2.f)                      {                          vsize /= bias;                      } @@ -971,14 +975,28 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag                      }                      max_vsize = llmax(max_vsize, vsize); + +                    // addTextureStats limits size to sMaxVirtualSize +                    if (max_vsize >= LLViewerFetchedTexture::sMaxVirtualSize +                        && (on_screen || LLViewerTexture::sDesiredDiscardBias <= BIAS_TRS_ON_SCREEN)) +                    { +                        break; +                    }                  }              } + +            if (max_vsize >= LLViewerFetchedTexture::sMaxVirtualSize +                && (on_screen || LLViewerTexture::sDesiredDiscardBias <= BIAS_TRS_ON_SCREEN)) +            { +                break; +            }          }          if (face_count > 1024)          { // this texture is used in so many places we should just boost it and not bother checking its vsize              // this is especially important because the above is not time sliced and can hit multiple ms for a single texture              imagep->setBoostLevel(LLViewerFetchedTexture::BOOST_HIGH); +            // Do we ever remove it? This also sets texture nodelete!          }          if (imagep->getType() == LLViewerTexture::LOD_TEXTURE && imagep->getBoostLevel() == LLViewerTexture::BOOST_NONE) @@ -986,8 +1004,8 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag            // this is an alternative to decaying mMaxVirtualSize over time            // that keeps textures from continously downrezzing and uprezzing in the background -        if (LLViewerTexture::sDesiredDiscardBias > 1.5f || -                (!on_screen && LLViewerTexture::sDesiredDiscardBias > 1.f)) +            if (LLViewerTexture::sDesiredDiscardBias > BIAS_TRS_OUT_OF_SCREEN || +                (!on_screen && LLViewerTexture::sDesiredDiscardBias > BIAS_TRS_ON_SCREEN))              {                  imagep->mMaxVirtualSize = 0.f;              } diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index a133febb85..d2685bcc48 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -489,7 +489,8 @@ public:          clearText(); -        if (gSavedSettings.getBOOL("DebugShowTime")) +        static LLCachedControl<bool> debug_show_time(gSavedSettings, "DebugShowTime", false); +        if (debug_show_time())          {              F32 time = gFrameTimeSeconds;              S32 hours = (S32)(time / (60*60)); @@ -498,7 +499,8 @@ public:              addText(xpos, ypos, llformat("Time: %d:%02d:%02d", hours,mins,secs)); ypos += y_inc;          } -        if (gSavedSettings.getBOOL("DebugShowMemory")) +        static LLCachedControl<bool> debug_show_memory(gSavedSettings, "DebugShowMemory", false); +        if (debug_show_memory())          {              addText(xpos, ypos,                      STRINGIZE("Memory: " << (LLMemory::getCurrentRSS() / 1024) << " (KB)")); @@ -591,7 +593,8 @@ public:              ypos += y_inc;          }*/ -        if (gSavedSettings.getBOOL("DebugShowRenderInfo")) +        static LLCachedControl<bool> debug_show_render_info(gSavedSettings, "DebugShowRenderInfo", false); +        if (debug_show_render_info())          {              LLTrace::Recording& last_frame_recording = LLTrace::get_frame_recording().getLastRecording(); @@ -730,7 +733,8 @@ public:              gPipeline.mNumVisibleNodes = LLPipeline::sVisibleLightCount = 0;          } -        if (gSavedSettings.getBOOL("DebugShowAvatarRenderInfo")) +        static LLCachedControl<bool> debug_show_avatar_render_info(gSavedSettings, "DebugShowAvatarRenderInfo", false); +        if (debug_show_avatar_render_info())          {              std::map<std::string, LLVOAvatar*> sorted_avs;              { @@ -763,7 +767,8 @@ public:                  av_iter++;              }          } -        if (gSavedSettings.getBOOL("DebugShowRenderMatrices")) +        static LLCachedControl<bool> debug_show_render_matrices(gSavedSettings, "DebugShowRenderMatrices", false); +        if (debug_show_render_matrices())          {              char camera_lines[8][32];              memset(camera_lines, ' ', sizeof(camera_lines)); @@ -789,7 +794,8 @@ public:              ypos += y_inc;          }          // disable use of glReadPixels which messes up nVidia nSight graphics debugging -        if (gSavedSettings.getBOOL("DebugShowColor") && !LLRender::sNsightDebugSupport) +        static LLCachedControl<bool> debug_show_color(gSavedSettings, "DebugShowColor", false); +        if (debug_show_color() && !LLRender::sNsightDebugSupport)          {              U8 color[4];              LLCoordGL coord = gViewerWindow->getCurrentMouse(); @@ -881,7 +887,8 @@ public:              }          } -        if (gSavedSettings.getBOOL("DebugShowTextureInfo")) +        static LLCachedControl<bool> debug_show_texture_info(gSavedSettings, "DebugShowTextureInfo", false); +        if (debug_show_texture_info())          {              LLViewerObject* objectp = NULL ; @@ -1450,10 +1457,13 @@ void LLViewerWindow::handleMouseLeave(LLWindow *window)  bool LLViewerWindow::handleCloseRequest(LLWindow *window)  { -    // User has indicated they want to close, but we may need to ask -    // about modified documents. -    LLAppViewer::instance()->userQuit(); -    // Don't quit immediately +    if (!LLApp::isExiting() && !LLApp::isStopped()) +    { +        // User has indicated they want to close, but we may need to ask +        // about modified documents. +        LLAppViewer::instance()->userQuit(); +        // Don't quit immediately +    }      return false;  } @@ -1597,7 +1607,8 @@ bool LLViewerWindow::handleActivate(LLWindow *window, bool activated)          mActive = false;          // if the user has chosen to go Away automatically after some time, then go Away when minimizing -        if (gSavedSettings.getS32("AFKTimeout")) +        static LLCachedControl<S32> afk_time(gSavedSettings, "AFKTimeout", 300); +        if (afk_time())          {              gAgent.setAFK();          } diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp index 93c217a7ba..08fcec86ac 100644 --- a/indra/newview/llvoicewebrtc.cpp +++ b/indra/newview/llvoicewebrtc.cpp @@ -3024,7 +3024,7 @@ void LLVoiceWebRTCConnection::OnDataReceivedImpl(const std::string &data, bool b          {              root["ug"] = user_gain;          } -        if (root.size() > 0) +        if (root.size() > 0 && mWebRTCDataInterface)          {              std::string json_data = boost::json::serialize(root);              mWebRTCDataInterface->sendData(json_data, false); @@ -3067,7 +3067,10 @@ void LLVoiceWebRTCConnection::OnDataChannelReady(llwebrtc::LLWebRTCDataInterface  void LLVoiceWebRTCConnection::sendJoin()  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE; - +    if (!mWebRTCDataInterface) +    { +        return; +    }      boost::json::object root;      boost::json::object join_obj; diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index e17321e698..f0af4acf20 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -759,7 +759,10 @@       name="SelectedOutfitTextColor"       reference="EmphasisColor" />      <color -     name="SearchableControlHighlightColor" +     name="SearchableControlHighlightFontColor" +     value="1 0 0 1" /> +    <color +     name="SearchableControlHighlightBgColor"       value="0.5 0.1 0.1 1" />      <color       name="SilhouetteChildColor" diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml index 34ed3fa80d..6877ce6411 100644 --- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml @@ -858,22 +858,50 @@        value="3"/>    </combo_box> -  <slider -    control_name="RenderReflectionProbeCount" -    decimal_digits="0" -    follows="left|top" -    height="16" -    increment="1" -    initial_value="256" -    label="Max. Reflection Probes:" -    label_width="145" -    layout="topleft" -    left="420" -    min_val="1" -    max_val="256" -    name="MaxProbes" -    top_delta="24" -    width="260" /> +    <text +      type="string" +      length="1" +      follows="left|top" +      height="16" +      layout="topleft" +      left="420" +      name="ReflectionProbeCount" +      text_readonly_color="LabelDisabledColor" +      top_delta="22" +      width="128"> +        Max Reflection Probes: +    </text> + +    <combo_box +     control_name="RenderReflectionProbeCount" +     height="18" +     layout="topleft" +     label="Max. Reflection Probes:" +     left_delta="130" +     top_delta="0" +     name="ProbeCount" +     width="150"> +        <combo_box.item +          label="None" +          name="1" +          value="1"/> +        <combo_box.item +          label="Low" +          name="32" +          value="32"/> +        <combo_box.item +          label="Medium" +          name="64" +          value="64"/> +        <combo_box.item +          label="High" +          name="128" +          value="128"/> +        <combo_box.item +          label="Ultra" +          name="256" +          value="256"/> +    </combo_box>    <slider      control_name="RenderExposure" diff --git a/indra/newview/skins/default/xui/en/floater_test_slapp.xml b/indra/newview/skins/default/xui/en/floater_test_slapp.xml new file mode 100644 index 0000000000..dd2720816a --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_test_slapp.xml @@ -0,0 +1,123 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater + legacy_header_height="18" + height="300" + layout="topleft" + name="slapp_test" + title="SLAPP TEST" + width="500"> +   <floater.string +    name="remove_folder_slapp"> +    secondlife://app/remove_folder/?folder_id= +   </floater.string> +   <text +    type="string" +    length="1" +    top="20" +    follows="left|top|right" +    height="16" +    name="trusted_txt" +    font="SansSerifMedium" +    text_color="white" +    layout="topleft" +    left="16"> +        Trusted source +   </text> +   <text +    type="string" +    length="1" +    top_pad="8" +    follows="left|top|right" +    height="16" +    layout="topleft" +    left="16"> +    /wear_folder +   </text> +   <text +    type="string" +    length="1" +    top_pad="5" +    follows="left|top|right" +    height="16" +    width="450" +    layout="topleft" +    left="16"> +        secondlife://app/wear_folder/?folder_name=Daisy +   </text> +   <text +    type="string" +    length="1" +    top_pad="8  " +    follows="left|top|right" +    height="16" +    layout="topleft" +    left="16"> +    /add_folder +   </text> +   <text +    type="string" +    length="1" +    top_pad="5" +    follows="left|top|right" +    height="16" +    width="450" +    layout="topleft" +    left="16"> +        secondlife://app/add_folder/?folder_name=Cardboard%20Boxbot +   </text> +   <text +    type="string" +    length="1" +    top_pad="5" +    follows="left|top|right" +    height="16" +    width="450" +    layout="topleft"> +        secondlife://app/add_folder/?folder_id=59219db2-c260-87d3-213d-bb3bc298a3d8 +   </text> +   <text +    type="string" +    length="1" +    top_pad="8  " +    follows="left|top|right" +    height="16" +    layout="topleft" +    left="16"> +    /remove_folder +   </text> +   <text +    type="string" +    length="1" +    top_pad="5" +    follows="left|top|right" +    height="16" +    layout="topleft" +    left="16"> +    Folder ID: +   </text> +   <line_editor +    border_style="line" +    border_thickness="1" +    follows="left|top" +    font="SansSerif" +    height="18" +    layout="topleft" +    left="75" +    max_length_bytes="50" +    prevalidate_callback="ascii" +    name="remove_folder_id" +    top_delta="-2" +    width="270" /> +   <text +    type="string" +    length="1" +    top_pad="5" +    follows="left|top|right" +    height="16" +    width="450" +    name="remove_folder_txt" +    layout="topleft" +    left="16"> +        secondlife://app/remove_folder/?folder_id= +   </text> +</floater> diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index d8aac71dd5..e57e3b0750 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -371,6 +371,14 @@           parameter="copy_uuid" />      </menu_item_call>      <menu_item_call +     label="Copy UUID" +     layout="topleft" +     name="Copy UUID"> +        <menu_item_call.on_click +         function="Inventory.DoToSelected" +         parameter="copy_folder_uuid" /> +    </menu_item_call> +    <menu_item_call       label="Show in Main Panel"       layout="topleft"       name="Show in Main Panel"> diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 6fb92f7b99..343f0c0059 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -3889,6 +3889,13 @@ function="World.EnvPreset"                   function="Floater.Show"                   parameter="font_test" />              </menu_item_call> +            <menu_item_call +             label="Show SLapps Test" +             name="Show SLapps Test"> +                <menu_item_call.on_click +                 function="Floater.Show" +                 parameter="slapp_test" /> +            </menu_item_call>              <menu_item_check               label="Show XUI Names"               name="Show XUI Names"> diff --git a/indra/newview/skins/default/xui/en/panel_login_first.xml b/indra/newview/skins/default/xui/en/panel_login_first.xml index c906e2f96c..d6ac71db94 100644 --- a/indra/newview/skins/default/xui/en/panel_login_first.xml +++ b/indra/newview/skins/default/xui/en/panel_login_first.xml @@ -179,7 +179,6 @@              control_name="RememberPassword"              follows="left|top"              font="SansSerifLarge" -            text_color="EmphasisColor"              height="24"              left="262"              bottom_delta="0" | 
