diff options
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llcharacter/llcharacter.cpp | 23 | ||||
| -rw-r--r-- | indra/llcharacter/llcharacter.h | 2 | ||||
| -rw-r--r-- | indra/llcharacter/llkeyframemotion.cpp | 25 | ||||
| -rw-r--r-- | indra/newview/llappviewer.cpp | 39 | ||||
| -rw-r--r-- | indra/newview/llappviewer.h | 7 | ||||
| -rw-r--r-- | indra/newview/llavatarrenderinfoaccountant.cpp | 15 | ||||
| -rw-r--r-- | indra/newview/llcontrolavatar.cpp | 12 | ||||
| -rw-r--r-- | indra/newview/llfloater360capture.cpp | 7 | ||||
| -rw-r--r-- | indra/newview/llfloaterbvhpreview.cpp | 14 | ||||
| -rw-r--r-- | indra/newview/llfloaterperformance.cpp | 10 | ||||
| -rw-r--r-- | indra/newview/llfloatersnapshot.cpp | 9 | ||||
| -rw-r--r-- | indra/newview/llmeshrepository.cpp | 48 | ||||
| -rw-r--r-- | indra/newview/llscenemonitor.cpp | 7 | ||||
| -rw-r--r-- | indra/newview/llviewerassetupload.cpp | 7 | ||||
| -rw-r--r-- | indra/newview/llviewermenu.cpp | 5 | ||||
| -rw-r--r-- | indra/newview/llviewerobject.cpp | 7 | ||||
| -rw-r--r-- | indra/newview/llviewerwindow.cpp | 16 | ||||
| -rw-r--r-- | indra/newview/llvoavatar.cpp | 217 | ||||
| -rw-r--r-- | indra/newview/llworld.cpp | 53 | ||||
| -rw-r--r-- | indra/newview/llworld.h | 2 | ||||
| -rw-r--r-- | indra/newview/pipeline.cpp | 14 | 
21 files changed, 287 insertions, 252 deletions
| diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp index 264b9a0be1..ecbcdb3bf5 100644 --- a/indra/llcharacter/llcharacter.cpp +++ b/indra/llcharacter/llcharacter.cpp @@ -38,7 +38,7 @@  LLStringTable LLCharacter::sVisualParamNames(1024); -std::vector< LLCharacter* > LLCharacter::sInstances; +std::list< LLCharacter* > LLCharacter::sInstances;  bool LLCharacter::sAllowInstancesChange = true ;  //----------------------------------------------------------------------------- @@ -53,7 +53,6 @@ LLCharacter::LLCharacter()      mSkeletonSerialNum( 0 )  {      llassert_always(sAllowInstancesChange) ; -    sInstances.push_back(this);      mMotionController.setCharacter( this );      mPauseRequest = new LLPauseRequestHandle(); @@ -66,28 +65,12 @@ LLCharacter::LLCharacter()  //-----------------------------------------------------------------------------  LLCharacter::~LLCharacter()  { -    for (LLVisualParam *param = getFirstVisualParam(); -        param; -        param = getNextVisualParam()) +    for (const auto& it : mVisualParamIndexMap)      { -        delete param; +        delete it.second;      } -    size_t i ; -    size_t size = sInstances.size() ; -    for(i = 0 ; i < size ; i++) -    { -        if(sInstances[i] == this) -        { -            break ; -        } -    } - -    llassert_always(i < size) ; -      llassert_always(sAllowInstancesChange) ; -    sInstances[i] = sInstances[size - 1] ; -    sInstances.pop_back() ;  } diff --git a/indra/llcharacter/llcharacter.h b/indra/llcharacter/llcharacter.h index b390960a75..6da28f0692 100644 --- a/indra/llcharacter/llcharacter.h +++ b/indra/llcharacter/llcharacter.h @@ -255,7 +255,7 @@ public:      U32             getSkeletonSerialNum() const        { return mSkeletonSerialNum; }      void            setSkeletonSerialNum( U32 num ) { mSkeletonSerialNum = num; } -    static std::vector< LLCharacter* > sInstances; +    static std::list< LLCharacter* > sInstances;      static bool sAllowInstancesChange ; //debug use      virtual void    setHoverOffset(const LLVector3& hover_offset, bool send_update=true) { mHoverOffset = hover_offset; } diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp index 12212efb66..6790f1ad56 100644 --- a/indra/llcharacter/llkeyframemotion.cpp +++ b/indra/llcharacter/llkeyframemotion.cpp @@ -2227,7 +2227,12 @@ bool LLKeyframeMotion::dumpToFile(const std::string& name)          }          S32 file_size = getFileSize(); -        U8* buffer = new U8[file_size]; +        U8* buffer = new(std::nothrow) U8[file_size]; +        if (!buffer) +        { +            LLError::LLUserWarningMsg::showOutOfMemory(); +            LL_ERRS() << "Bad memory allocation for buffer, file: " << name << " " << file_size << LL_ENDL; +        }          LL_DEBUGS("BVH") << "Dumping " << outfilename << LL_ENDL;          LLDataPackerBinaryBuffer dp(buffer, file_size); @@ -2407,13 +2412,10 @@ void LLKeyframeMotion::onLoadComplete(const LLUUID& asset_uuid,  {      LLUUID* id = (LLUUID*)user_data; -    std::vector<LLCharacter* >::iterator char_iter = LLCharacter::sInstances.begin(); - -    while(char_iter != LLCharacter::sInstances.end() && -            (*char_iter)->getID() != *id) -    { -        ++char_iter; -    } +    auto char_iter = std::find_if(LLCharacter::sInstances.begin(), LLCharacter::sInstances.end(), [&](LLCharacter* c) +        { +            return c->getID() == *id; +        });      delete id; @@ -2438,7 +2440,12 @@ void LLKeyframeMotion::onLoadComplete(const LLUUID& asset_uuid,              LLFileSystem file(asset_uuid, type, LLFileSystem::READ);              S32 size = file.getSize(); -            U8* buffer = new U8[size]; +            U8* buffer = new(std::nothrow) U8[size]; +            if (!buffer) +            { +                LLError::LLUserWarningMsg::showOutOfMemory(); +                LL_ERRS() << "Bad memory allocation for buffer of size: " << size << LL_ENDL; +            }              file.read((U8*)buffer, size);   /*Flawfinder: ignore*/              LL_DEBUGS("Animation") << "Loading keyframe data for: " << motionp->getName() << ":" << motionp->getID() << " (" << size << " bytes)" << LL_ENDL; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index b380b09129..f2023565fc 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -646,6 +646,7 @@ LLAppViewer::LLAppViewer()      mSavedFinalSnapshot(false),      mSavePerAccountSettings(false),     // don't save settings on logout unless login succeeded.      mQuitRequested(false), +    mClosingFloaters(false),      mLogoutRequestSent(false),      mLastAgentControlFlags(0),      mLastAgentForceUpdate(0), @@ -2248,7 +2249,9 @@ void errorCallback(LLError::ELevel level, const std::string &error_string)      if (level == LLError::LEVEL_ERROR)      {  #ifndef LL_RELEASE_FOR_DOWNLOAD -        OSMessageBox(error_string, LLTrans::getString("MBFatalError"), OSMB_OK); +        std::string message = error_string + +            "\n\n\nThis is a developer-only notification!\nThis notification won't be present in Release for download build"; +        OSMessageBox(message, LLTrans::getString("MBFatalError"), OSMB_OK);  #endif          gDebugInfo["FatalMessage"] = error_string; @@ -4028,6 +4031,7 @@ void LLAppViewer::requestQuit()      {          // application is quitting          gFloaterView->closeAllChildren(true); +        mClosingFloaters = true;      }      // Send preferences once, when exiting @@ -4091,6 +4095,7 @@ void LLAppViewer::abortQuit()  {      LL_INFOS() << "abortQuit()" << LL_ENDL;      mQuitRequested = false; +    mClosingFloaters = false;  }  void LLAppViewer::migrateCacheDirectory() @@ -5040,10 +5045,19 @@ void LLAppViewer::idleShutdown()      }      // Wait for all floaters to get resolved -    if (gFloaterView -        && !gFloaterView->allChildrenClosed()) +    if (gFloaterView)      { -        return; +        if (!mClosingFloaters) +        { +            // application is quitting +            gFloaterView->closeAllChildren(true); +            mClosingFloaters = true; +            return; +        } +        if (!gFloaterView->allChildrenClosed()) +        { +            return; +        }      }      // ProductEngine: Try moving this code to where we shut down sTextureCache in cleanup() @@ -5204,6 +5218,23 @@ void LLAppViewer::postToMainCoro(const LL::WorkQueue::Work& work)      gMainloopWork.post(work);  } +void LLAppViewer::outOfMemorySoftQuit() +{ +    if (!mQuitRequested) +    { +        // Todo: +        // Find a way to free at least some memory to make it safer +        // Pause decoding and mesh repositorie +        getTextureCache()->pause(); +        getTextureFetch()->pause(); +        LLLFSThread::sLocal->pause(); +        gLogoutTimer.reset(); +        mQuitRequested = true; + +        LLError::LLUserWarningMsg::showOutOfMemory(); +    } +} +  void LLAppViewer::idleNameCache()  {      // Neither old nor new name cache can function before agent has a region diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 417ab0fa00..cf5f1ab1e3 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -230,6 +230,12 @@ public:      // post given work to the "mainloop" work queue for handling on the main thread      void postToMainCoro(const LL::WorkQueue::Work& work); +    // Attempt a 'soft' quit with disconnect and saving of settings/cache. +    // Intended to be thread safe. +    // Good chance of viewer crashing either way, but better than alternatives. +    // Note: mQuitRequested can be aborted by user. +    void outOfMemorySoftQuit(); +  protected:      virtual bool initWindow(); // Initialize the viewer's window.      virtual void initLoggingAndGetLastDuration(); // Initialize log files, logging system @@ -317,6 +323,7 @@ private:      boost::optional<U32> mForceGraphicsLevel;      bool mQuitRequested;                // User wants to quit, may have modified documents open. +    bool mClosingFloaters;      bool mLogoutRequestSent;            // Disconnect message sent to simulator, no longer safe to send messages to the sim.      U32 mLastAgentControlFlags;      F32 mLastAgentForceUpdate; diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp index 3fd2b7fe5d..44f35981b0 100644 --- a/indra/newview/llavatarrenderinfoaccountant.cpp +++ b/indra/newview/llavatarrenderinfoaccountant.cpp @@ -226,14 +226,12 @@ void LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro(std::string url, U      // Build the render info to POST to the region      LLSD agents = LLSD::emptyMap(); -    std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); -    while( iter != LLCharacter::sInstances.end() ) +    for (LLCharacter* character : LLCharacter::sInstances)      { -        LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*iter); -        if (avatar && -            avatar->getRezzedStatus() >= 2 &&                   // Mostly rezzed (maybe without baked textures downloaded) -            !avatar->isDead() &&                                // Not dead yet +        LLVOAvatar* avatar = (LLVOAvatar*)character; +        if (!avatar->isDead() &&                                // Not dead yet              !avatar->isControlAvatar() &&                       // Not part of an animated object +            avatar->getRezzedStatus() >= 2 &&                   // Mostly rezzed (maybe without baked textures downloaded)              avatar->getObjectHost() == regionp->getHost())      // Ensure it's on the same region          {              LLSD info = LLSD::emptyMap(); @@ -243,15 +241,14 @@ void LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro(std::string url, U                  // the weight/complexity is unsigned, but LLSD only stores signed integers,                  // so if it's over that (which would be ridiculously high), just store the maximum signed int value                  info[KEY_WEIGHT] = (S32)(avatar_complexity < S32_MAX ? avatar_complexity : S32_MAX); -                info[KEY_TOO_COMPLEX]  = LLSD::Boolean(avatar->isTooComplex()); +                info[KEY_TOO_COMPLEX] = LLSD::Boolean(avatar->isTooComplex());                  agents[avatar->getID().asString()] = info;                  LL_DEBUGS("AvatarRenderInfo") << "Sending avatar render info for " << avatar->getID() -                                              << ": " << info << LL_ENDL; +                    << ": " << info << LL_ENDL;                  num_avs++;              }          } -        iter++;      }      // Reset this regions timer, moving to longer intervals if there are lots of avatars around diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp index 2a52b7dde9..9201241856 100644 --- a/indra/newview/llcontrolavatar.cpp +++ b/indra/newview/llcontrolavatar.cpp @@ -699,14 +699,14 @@ bool LLControlAvatar::isImpostor()      return LLVOAvatar::isImpostor();  } -//static +// static  void LLControlAvatar::onRegionChanged()  { -    std::vector<LLCharacter*>::iterator it = LLCharacter::sInstances.begin(); -    for ( ; it != LLCharacter::sInstances.end(); ++it) +    for (LLCharacter* character : LLCharacter::sInstances)      { -        LLControlAvatar* cav = dynamic_cast<LLControlAvatar*>(*it); -        if (!cav) continue; -        cav->mRegionChanged = true; +        if (LLControlAvatar* cav = dynamic_cast<LLControlAvatar*>(character)) +        { +            cav->mRegionChanged = true; +        }      }  } diff --git a/indra/newview/llfloater360capture.cpp b/indra/newview/llfloater360capture.cpp index 01a0525d56..ff30c83f51 100644 --- a/indra/newview/llfloater360capture.cpp +++ b/indra/newview/llfloater360capture.cpp @@ -793,12 +793,9 @@ void LLFloater360Capture::freezeWorld(bool enable)          LLEnvironment::instance().pauseCloudScroll();          // freeze all avatars -        LLCharacter* avatarp; -        for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); -                iter != LLCharacter::sInstances.end(); ++iter) +        for (LLCharacter* character : LLCharacter::sInstances)          { -            avatarp = *iter; -            mAvatarPauseHandles.push_back(avatarp->requestPause()); +            mAvatarPauseHandles.push_back(character->requestPause());          }          // freeze everything else diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp index 2cb930922a..3d81d01e16 100644 --- a/indra/newview/llfloaterbvhpreview.cpp +++ b/indra/newview/llfloaterbvhpreview.cpp @@ -285,7 +285,12 @@ bool LLFloaterBvhPreview::postBuild()          // create data buffer for keyframe initialization          S32 buffer_size = loaderp->getOutputSize(); -        U8* buffer = new U8[buffer_size]; +        U8* buffer = new(std::nothrow) U8[buffer_size]; +        if (!buffer) +        { +            LLError::LLUserWarningMsg::showOutOfMemory(); +            LL_ERRS() << "Bad memory allocation for buffer, size: " << buffer_size << LL_ENDL; +        }          LLDataPackerBinaryBuffer dp(buffer, buffer_size); @@ -992,7 +997,12 @@ void LLFloaterBvhPreview::onBtnOK(void* userdata)          LLKeyframeMotion* motionp = (LLKeyframeMotion*)floaterp->mAnimPreview->getDummyAvatar()->findMotion(floaterp->mMotionID);          S32 file_size = motionp->getFileSize(); -        U8* buffer = new U8[file_size]; +        U8* buffer = new(std::nothrow) U8[file_size]; +        if (!buffer) +        { +            LLError::LLUserWarningMsg::showOutOfMemory(); +            LL_ERRS() << "Bad memory allocation for buffer, size: " << file_size << LL_ENDL; +        }          LLDataPackerBinaryBuffer dp(buffer, file_size);          if (motionp->serialize(dp)) diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp index d5782accef..315508f22b 100644 --- a/indra/newview/llfloaterperformance.cpp +++ b/indra/newview/llfloaterperformance.cpp @@ -435,15 +435,12 @@ void LLFloaterPerformance::populateNearbyList()      mNearbyList->updateColumns(true);      static LLCachedControl<U32> max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0); -    std::vector<LLCharacter*> valid_nearby_avs; +    std::vector<LLVOAvatar*> valid_nearby_avs;      mNearbyMaxGPUTime = LLWorld::getInstance()->getNearbyAvatarsAndMaxGPUTime(valid_nearby_avs); -    std::vector<LLCharacter*>::iterator char_iter = valid_nearby_avs.begin(); - -    while (char_iter != valid_nearby_avs.end()) +    for (LLVOAvatar* avatar : valid_nearby_avs)      { -        LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*char_iter); -        if (avatar && (LLVOAvatar::AOA_INVISIBLE != avatar->getOverallAppearance())) +        if (LLVOAvatar::AOA_INVISIBLE != avatar->getOverallAppearance())          {              F32 render_av_gpu_ms = avatar->getGPURenderTime(); @@ -508,7 +505,6 @@ void LLFloaterPerformance::populateNearbyList()                  }              }          } -        char_iter++;      }      mNearbyList->sortByColumnIndex(1, false);      mNearbyList->setScrollPos(prev_pos); diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index ddc567c029..ddd55d0c17 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -210,13 +210,10 @@ void LLFloaterSnapshotBase::ImplBase::updateLayout(LLFloaterSnapshotBase* floate              previewp->setEnabled(true);          } -        //RN: freeze all avatars -        LLCharacter* avatarp; -        for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); -            iter != LLCharacter::sInstances.end(); ++iter) +        // RN: freeze all avatars +        for (LLCharacter* character : LLCharacter::sInstances)          { -            avatarp = *iter; -            floaterp->impl->mAvatarPauseHandles.push_back(avatarp->requestPause()); +            floaterp->impl->mAvatarPauseHandles.push_back(character->requestPause());          }          // freeze everything else diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 1c64ed6822..4c5cc37766 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1361,7 +1361,17 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry)                  if (!buffer)                  {                      LL_WARNS(LOG_MESH) << "Failed to allocate memory for skin info, size: " << size << LL_ENDL; -                    return false; + +                    // Not sure what size is reasonable for skin info, +                    // but if 20MB allocation failed, we definetely have issues +                    const S32 MAX_SIZE = 30 * 1024 * 1024; //30MB +                    if (size < MAX_SIZE) +                    { +                        LLAppViewer::instance()->outOfMemorySoftQuit(); +                    } // else ignore failures for anomalously large data +                    LLMutexLock locker(mMutex); +                    mSkinUnavailableQ.emplace_back(mesh_id); +                    return true;                  }                  LLMeshRepository::sCacheBytesRead += size;                  ++LLMeshRepository::sCacheReads; @@ -1474,7 +1484,15 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)                  if (!buffer)                  {                      LL_WARNS(LOG_MESH) << "Failed to allocate memory for mesh decomposition, size: " << size << LL_ENDL; -                    return false; + +                    // Not sure what size is reasonable for decomposition +                    // but if 20MB allocation failed, we definetely have issues +                    const S32 MAX_SIZE = 30 * 1024 * 1024; //30MB +                    if (size < MAX_SIZE) +                    { +                        LLAppViewer::instance()->outOfMemorySoftQuit(); +                    } // else ignore failures for anomalously large decompositiions +                    return true;                  }                  LLMeshRepository::sCacheBytesRead += size;                  ++LLMeshRepository::sCacheReads; @@ -1575,8 +1593,16 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)                  U8* buffer = new(std::nothrow) U8[size];                  if (!buffer)                  { -                    LL_WARNS(LOG_MESH) << "Failed to allocate memory for physics shape, size: " << size << LL_ENDL; -                    return false; +                    LL_WARNS(LOG_MESH) << "Failed to allocate memory for mesh decomposition, size: " << size << LL_ENDL; + +                    // Not sure what size is reasonable for physcis +                    // but if 20MB allocation failed, we definetely have issues +                    const S32 MAX_SIZE = 30 * 1024 * 1024; //30MB +                    if (size < MAX_SIZE) +                    { +                        LLAppViewer::instance()->outOfMemorySoftQuit(); +                    } // else ignore failures for anomalously large data +                    return true;                  }                  file.read(buffer, size); @@ -1767,9 +1793,17 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod,                  if (!buffer)                  {                      LL_WARNS(LOG_MESH) << "Can't allocate memory for mesh " << mesh_id << " LOD " << lod << ", size: " << size << LL_ENDL; -                    // todo: for now it will result in indefinite constant retries, should result in timeout -                    // or in retry-count and disabling mesh. (but usually viewer is beyond saving at this point) -                    return false; + +                    // Not sure what size is reasonable for a mesh, +                    // but if 20MB allocation failed, we definetely have issues +                    const S32 MAX_SIZE = 30 * 1024 * 1024; //30MB +                    if (size < MAX_SIZE) +                    { +                        LLAppViewer::instance()->outOfMemorySoftQuit(); +                    } // else ignore failures for anomalously large data +                    LLMutexLock lock(mMutex); +                    mUnavailableQ.push_back(LODRequest(mesh_params, lod)); +                    return true;                  }                  LLMeshRepository::sCacheBytesRead += size;                  ++LLMeshRepository::sCacheReads; diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp index cdccaf44e9..7498c2d524 100644 --- a/indra/newview/llscenemonitor.cpp +++ b/indra/newview/llscenemonitor.cpp @@ -225,11 +225,10 @@ void LLSceneMonitor::freezeScene()          return;      } -    //freeze all avatars -    for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); -        iter != LLCharacter::sInstances.end(); ++iter) +    // freeze all avatars +    for (LLCharacter* character : LLCharacter::sInstances)      { -        freezeAvatar((LLCharacter*)(*iter)); +        freezeAvatar((LLCharacter*)character);      }      // freeze everything else diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp index 50128d826a..b74b48b9f6 100644 --- a/indra/newview/llviewerassetupload.cpp +++ b/indra/newview/llviewerassetupload.cpp @@ -479,7 +479,12 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile()          else          {              S32 size = LLAPRFile::size(getFileName()); -            U8* buffer = new U8[size]; +            U8* buffer = new(std::nothrow) U8[size]; +            if (!buffer) +            { +                LLError::LLUserWarningMsg::showOutOfMemory(); +                LL_ERRS() << "Bad memory allocation for buffer, size: " << size << LL_ENDL; +            }              S32 size_read = infile.read(buffer,size);              if (size_read != size)              { diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index cd0b3dbd0c..0c8dd6dff9 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -1892,10 +1892,9 @@ class LLAdvancedForceParamsToDefault : public view_listener_t  static void set_all_animation_time_factors(F32  time_factor)  {      LLMotionController::setCurrentTimeFactor(time_factor); -    for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); -        iter != LLCharacter::sInstances.end(); ++iter) +    for (LLCharacter* character : LLCharacter::sInstances)      { -        (*iter)->setAnimTimeFactor(time_factor); +        character->setAnimTimeFactor(time_factor);      }  } diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 094d866bc1..fd85d75d98 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -1521,7 +1521,12 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,                  S32 size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_ExtraParams);                  if (size > 0)                  { -                    U8 *buffer = new U8[size]; +                    U8 *buffer = new(std::nothrow) U8[size]; +                    if (!buffer) +                    { +                        LLError::LLUserWarningMsg::showOutOfMemory(); +                        LL_ERRS() << "Bad memory allocation for buffer, size: " << size << LL_ENDL; +                    }                      mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ExtraParams, buffer, size, block_num);                      LLDataPackerBinaryBuffer dp(buffer, size); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 9dc12c4856..f6de8377f3 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -741,18 +741,16 @@ public:          if (gSavedSettings.getBOOL("DebugShowAvatarRenderInfo"))          {              std::map<std::string, LLVOAvatar*> sorted_avs; - -            std::vector<LLCharacter*>::iterator sort_iter = LLCharacter::sInstances.begin(); -            while (sort_iter != LLCharacter::sInstances.end())              { -                LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*sort_iter); -                if (avatar && -                    !avatar->isDead())                      // Not dead yet +                for (LLCharacter* character : LLCharacter::sInstances)                  { -                    // Stuff into a sorted map so the display is ordered -                    sorted_avs[avatar->getFullname()] = avatar; +                    LLVOAvatar* avatar = (LLVOAvatar*)character; +                    if (!avatar->isDead()) // Not dead yet +                    { +                        // Stuff into a sorted map so the display is ordered +                        sorted_avs[avatar->getFullname()] = avatar; +                    }                  } -                sort_iter++;              }              std::string trunc_name; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index fcd2f74108..6e6ad485cf 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -768,6 +768,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,      }      mVisuallyMuteSetting = LLVOAvatar::VisualMuteSettings(LLRenderMuteList::getInstance()->getSavedVisualMuteSetting(getID())); + +    sInstances.push_back(this);  }  std::string LLVOAvatar::avString() const @@ -815,6 +817,8 @@ void LLVOAvatar::debugAvatarRezTime(std::string notification_name, std::string c  //------------------------------------------------------------------------  LLVOAvatar::~LLVOAvatar()  { +    sInstances.remove(this); +      if (!mFullyLoaded)      {          debugAvatarRezTime("AvatarRezLeftCloudNotification","left after ruth seconds as cloud"); @@ -957,26 +961,16 @@ void LLVOAvatar::deleteLayerSetCaches(bool clearAll)  // static  bool LLVOAvatar::areAllNearbyInstancesBaked(S32& grey_avatars)  { -    bool res = true;      grey_avatars = 0; -    for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); -         iter != LLCharacter::sInstances.end(); ++iter) +    for (LLCharacter* character : LLCharacter::sInstances)      { -        LLVOAvatar* inst = (LLVOAvatar*) *iter; -        if( inst->isDead() ) +        LLVOAvatar* inst = (LLVOAvatar*)character; +        if (!inst->isDead() && inst->mHasGrey && !inst->isFullyBaked())          { -            continue; -        } -        else if( !inst->isFullyBaked() ) -        { -            res = false; -            if (inst->mHasGrey) -            { -                ++grey_avatars; -            } +            ++grey_avatars;          }      } -    return res; +    return !grey_avatars;  }  // static @@ -987,11 +981,10 @@ void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts, F32& avg_cloud_t      avg_cloud_time = 0;      cloud_avatars = 0;      S32 count_avg = 0; -    for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); -         iter != LLCharacter::sInstances.end(); ++iter) + +    for (LLCharacter* character : LLCharacter::sInstances)      { -        LLVOAvatar* inst = (LLVOAvatar*) *iter; -        if (inst) +        if (LLVOAvatar* inst = (LLVOAvatar*)character)          {              S32 rez_status = inst->getRezzedStatus();              counts[rez_status]++; @@ -1008,6 +1001,7 @@ void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts, F32& avg_cloud_t              }          }      } +      if (count_avg > 0)      {          avg_cloud_time /= count_avg; @@ -1017,11 +1011,19 @@ void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts, F32& avg_cloud_t  // static  std::string LLVOAvatar::rezStatusToString(S32 rez_status)  { -    if (rez_status==0) return "cloud"; -    if (rez_status==1) return "gray"; -    if (rez_status==2) return "downloading baked"; -    if (rez_status==3) return "loading attachments"; -    if (rez_status==4) return "full"; +    switch (rez_status) +    { +    case 0: +        return "cloud"; +    case 1: +        return "gray"; +    case 2: +        return "downloading baked"; +    case 3: +        return "loading attachments"; +    case 4: +        return "full"; +    }      return "unknown";  } @@ -1030,10 +1032,9 @@ void LLVOAvatar::dumpBakedStatus()  {      LLVector3d camera_pos_global = gAgentCamera.getCameraPositionGlobal(); -    for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); -         iter != LLCharacter::sInstances.end(); ++iter) +    for (LLCharacter* character : LLCharacter::sInstances)      { -        LLVOAvatar* inst = (LLVOAvatar*) *iter; +        LLVOAvatar* inst = (LLVOAvatar*)character;          LL_INFOS() << "Avatar ";          LLNameValue* firstname = inst->getNVPair("FirstName"); @@ -1128,10 +1129,9 @@ void LLVOAvatar::destroyGL()  //static  void LLVOAvatar::resetImpostors()  { -    for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); -         iter != LLCharacter::sInstances.end(); ++iter) +    for (LLCharacter* character : LLCharacter::sInstances)      { -        LLVOAvatar* avatar = (LLVOAvatar*) *iter; +        LLVOAvatar* avatar = (LLVOAvatar*)character;          avatar->mImpostor.release();          avatar->mNeedsImpostorUpdate = true;          avatar->mLastImpostorUpdateReason = 1; @@ -1143,11 +1143,9 @@ void LLVOAvatar::deleteCachedImages(bool clearAll)  {      if (LLViewerTexLayerSet::sHasCaches)      { -        for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); -             iter != LLCharacter::sInstances.end(); ++iter) +        for (LLCharacter* character : LLCharacter::sInstances)          { -            LLVOAvatar* inst = (LLVOAvatar*) *iter; -            inst->deleteLayerSetCaches(clearAll); +            ((LLVOAvatar*)character)->deleteLayerSetCaches(clearAll);          }          LLViewerTexLayerSet::sHasCaches = false;      } @@ -1202,7 +1200,7 @@ void LLVOAvatar::initInstance()      //-------------------------------------------------------------------------      if (LLCharacter::sInstances.size() == 1)      { -        registerMotion( ANIM_AGENT_DO_NOT_DISTURB,                  LLNullMotion::create ); +        registerMotion( ANIM_AGENT_DO_NOT_DISTURB,          LLNullMotion::create );          registerMotion( ANIM_AGENT_CROUCH,                  LLKeyframeStandMotion::create );          registerMotion( ANIM_AGENT_CROUCHWALK,              LLKeyframeWalkMotion::create );          registerMotion( ANIM_AGENT_EXPRESS_AFRAID,          LLEmote::create ); @@ -3628,29 +3626,28 @@ void LLVOAvatar::clearNameTag()      mTimeVisible.reset();  } -//static +// static  void LLVOAvatar::invalidateNameTag(const LLUUID& agent_id)  { -    LLViewerObject* obj = gObjectList.findObject(agent_id); -    if (!obj) return; - -    LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(obj); -    if (!avatar) return; - -    avatar->clearNameTag(); +    if (LLViewerObject* obj = gObjectList.findObject(agent_id)) +    { +        if (LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(obj)) +        { +            avatar->clearNameTag(); +        } +    }  } -//static +// static  void LLVOAvatar::invalidateNameTags()  { -    std::vector<LLCharacter*>::iterator it = LLCharacter::sInstances.begin(); -    for ( ; it != LLCharacter::sInstances.end(); ++it) +    for (LLCharacter* character : LLCharacter::sInstances)      { -        LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*it); -        if (!avatar) continue; -        if (avatar->isDead()) continue; - -        avatar->clearNameTag(); +        LLVOAvatar* avatar = (LLVOAvatar*)character; +        if (!avatar->isDead()) +        { +            avatar->clearNameTag(); +        }      }  } @@ -8261,15 +8258,13 @@ void LLVOAvatar::logPendingPhases()  //static  void LLVOAvatar::logPendingPhasesAllAvatars()  { -    for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); -         iter != LLCharacter::sInstances.end(); ++iter) +    for (LLCharacter* character : LLCharacter::sInstances)      { -        LLVOAvatar* inst = (LLVOAvatar*) *iter; -        if( inst->isDead() ) +        LLVOAvatar* avatar = (LLVOAvatar*)character; +        if (!avatar->isDead())          { -            continue; +            avatar->logPendingPhases();          } -        inst->logPendingPhases();      }  } @@ -10443,15 +10438,16 @@ void LLVOAvatar::setVisibilityRank(U32 rank)  S32 LLVOAvatar::getUnbakedPixelAreaRank()  {      S32 rank = 1; -    for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); -         iter != LLCharacter::sInstances.end(); ++iter) + +    for (LLCharacter* character : LLCharacter::sInstances)      { -        LLVOAvatar* inst = (LLVOAvatar*) *iter; -        if (inst == this) +        if (character == this)          {              return rank;          } -        else if (!inst->isDead() && !inst->isFullyBaked()) + +        LLVOAvatar* avatar = (LLVOAvatar*)character; +        if (!avatar->isDead() && !avatar->isFullyBaked())          {              rank++;          } @@ -10461,49 +10457,37 @@ S32 LLVOAvatar::getUnbakedPixelAreaRank()      return 0;  } -struct CompareScreenAreaGreater -{ -    bool operator()(const LLCharacter* const& lhs, const LLCharacter* const& rhs) -    { -        return lhs->getPixelArea() > rhs->getPixelArea(); -    } -}; -  // static  void LLVOAvatar::cullAvatarsByPixelArea()  { -    std::sort(LLCharacter::sInstances.begin(), LLCharacter::sInstances.end(), CompareScreenAreaGreater()); +    LLCharacter::sInstances.sort([](LLCharacter* lhs, LLCharacter* rhs) +        { +            return lhs->getPixelArea() > rhs->getPixelArea(); +        });      // Update the avatars that have changed status -    U32 rank = 2; //1 is reserved for self. -    for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); -         iter != LLCharacter::sInstances.end(); ++iter)      { -        LLVOAvatar* inst = (LLVOAvatar*) *iter; -        bool culled; -        if (inst->isSelf() || inst->isFullyBaked()) -        { -            culled = false; -        } -        else +        U32 rank = 2; //1 is reserved for self. +        for (LLCharacter* character : LLCharacter::sInstances)          { -            culled = true; -        } +            LLVOAvatar* inst = (LLVOAvatar*)character; +            bool culled = !inst->isSelf() && !inst->isFullyBaked(); -        if (inst->mCulled != culled) -        { -            inst->mCulled = culled; -            LL_DEBUGS() << "avatar " << inst->getID() << (culled ? " start culled" : " start not culled" ) << LL_ENDL; -            inst->updateMeshTextures(); -        } +            if (inst->mCulled != culled) +            { +                inst->mCulled = culled; +                LL_DEBUGS() << "avatar " << inst->getID() << (culled ? " start culled" : " start not culled" ) << LL_ENDL; +                inst->updateMeshTextures(); +            } -        if (inst->isSelf()) -        { -            inst->setVisibilityRank(1); -        } -        else if (inst->mDrawable.notNull() && inst->mDrawable->isVisible()) -        { -            inst->setVisibilityRank(rank++); +            if (inst->isSelf()) +            { +                inst->setVisibilityRank(1); +            } +            else if (inst->mDrawable.notNull() && inst->mDrawable->isVisible()) +            { +                inst->setVisibilityRank(rank++); +            }          }      } @@ -10762,11 +10746,9 @@ void LLVOAvatar::updateImpostors()  {      LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; -    std::vector<LLCharacter*> instances_copy = LLCharacter::sInstances; -    for (std::vector<LLCharacter*>::iterator iter = instances_copy.begin(); -        iter != instances_copy.end(); ++iter) +    for (LLCharacter* character : LLCharacter::sInstances)      { -        LLVOAvatar* avatar = (LLVOAvatar*) *iter; +        LLVOAvatar* avatar = (LLVOAvatar*)character;          if (!avatar->isDead()              && avatar->isVisible()              && avatar->isImpostor() @@ -10923,21 +10905,17 @@ void LLVOAvatar::updateNearbyAvatarCount()          S32 avs_nearby = 0;          static LLCachedControl<F32> render_far_clip(gSavedSettings, "RenderFarClip", 64);          F32 radius = render_far_clip * render_far_clip; -        std::vector<LLCharacter *>::iterator char_iter = LLCharacter::sInstances.begin(); -        while (char_iter != LLCharacter::sInstances.end()) +        for (LLCharacter* character : LLCharacter::sInstances)          { -            LLVOAvatar *avatar = dynamic_cast<LLVOAvatar *>(*char_iter); -            if (avatar && !avatar->isDead() && !avatar->isControlAvatar()) +            LLVOAvatar* avatar = (LLVOAvatar*)character; +            if (!avatar->isDead() && !avatar->isControlAvatar())              { -                if ((dist_vec_squared(avatar->getPositionGlobal(), gAgent.getPositionGlobal()) > radius) && -                    (dist_vec_squared(avatar->getPositionGlobal(), gAgentCamera.getCameraPositionGlobal()) > radius)) +                if ((dist_vec_squared(avatar->getPositionGlobal(), gAgent.getPositionGlobal()) <= radius) || +                    (dist_vec_squared(avatar->getPositionGlobal(), gAgentCamera.getCameraPositionGlobal()) <= radius))                  { -                    char_iter++; -                    continue; +                    avs_nearby++;                  } -                avs_nearby++;              } -            char_iter++;          }          sAvatarsNearby = avs_nearby;          agent_update_timer.reset(); @@ -11710,10 +11688,9 @@ F32 LLVOAvatar::getTotalGPURenderTime()      F32 ret = 0.f; -    for (LLCharacter* iter : LLCharacter::sInstances) +    for (LLCharacter* character : LLCharacter::sInstances)      { -        LLVOAvatar* inst = (LLVOAvatar*) iter; -        ret += inst->getGPURenderTime(); +        ret += ((LLVOAvatar*)character)->getGPURenderTime();      }      return ret; @@ -11725,10 +11702,9 @@ F32 LLVOAvatar::getMaxGPURenderTime()      F32 ret = 0.f; -    for (LLCharacter* iter : LLCharacter::sInstances) +    for (LLCharacter* character : LLCharacter::sInstances)      { -        LLVOAvatar* inst = (LLVOAvatar*)iter; -        ret = llmax(inst->getGPURenderTime(), ret); +        ret = llmax(((LLVOAvatar*)character)->getGPURenderTime(), ret);      }      return ret; @@ -11742,12 +11718,12 @@ F32 LLVOAvatar::getAverageGPURenderTime()      S32 count = 0; -    for (LLCharacter* iter : LLCharacter::sInstances) +    for (LLCharacter* character : LLCharacter::sInstances)      { -        LLVOAvatar* inst = (LLVOAvatar*)iter; -        if (!inst->isTooSlow()) +        LLVOAvatar* avatar = (LLVOAvatar*)character; +        if (!avatar->isTooSlow())          { -            ret += inst->getGPURenderTime(); +            ret += avatar->getGPURenderTime();              ++count;          }      } @@ -11759,6 +11735,7 @@ F32 LLVOAvatar::getAverageGPURenderTime()      return ret;  } +  bool LLVOAvatar::isBuddy() const  {      return LLAvatarTracker::instance().isBuddy(getID()); diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 9508d33eb3..40bfa8ec83 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -1320,35 +1320,32 @@ void LLWorld::getAvatars(uuid_vec_t* avatar_ids, std::vector<LLVector3d>* positi      }      // get the list of avatars from the character list first, so distances are correct      // when agent is above 1020m and other avatars are nearby -    for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); -        iter != LLCharacter::sInstances.end(); ++iter) +    for (LLCharacter* character : LLCharacter::sInstances)      { -        LLVOAvatar* pVOAvatar = (LLVOAvatar*) *iter; - -        if (!pVOAvatar->isDead() && !pVOAvatar->mIsDummy && !pVOAvatar->isOrphaned()) +        LLVOAvatar* avatar = (LLVOAvatar*)character; +        if (!avatar->isDead() && !avatar->mIsDummy && !avatar->isOrphaned())          { -            LLVector3d pos_global = pVOAvatar->getPositionGlobal(); -            LLUUID uuid = pVOAvatar->getID(); +            LLVector3d pos_global = avatar->getPositionGlobal(); +            LLUUID uuid = avatar->getID();              if (!uuid.isNull()                  && dist_vec_squared(pos_global, relative_to) <= radius_squared)              { -                if(positions != NULL) +                if (positions != NULL)                  {                      positions->push_back(pos_global);                  } -                if(avatar_ids !=NULL) +                if (avatar_ids != NULL)                  {                      avatar_ids->push_back(uuid);                  }              }          }      } +      // region avatars added for situations where radius is greater than RenderFarClip -    for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); -        iter != LLWorld::getInstance()->getRegionList().end(); ++iter) +    for (const LLViewerRegion* regionp : LLWorld::getInstance()->getRegionList())      { -        LLViewerRegion* regionp = *iter;          const LLVector3d& origin_global = regionp->getOriginGlobal();          auto count = regionp->mMapAvatars.size();          for (size_t i = 0; i < count; i++) @@ -1371,33 +1368,31 @@ void LLWorld::getAvatars(uuid_vec_t* avatar_ids, std::vector<LLVector3d>* positi      }  } -F32 LLWorld::getNearbyAvatarsAndMaxGPUTime(std::vector<LLCharacter*> &valid_nearby_avs) +F32 LLWorld::getNearbyAvatarsAndMaxGPUTime(std::vector<LLVOAvatar*> &valid_nearby_avs)  {      static LLCachedControl<F32> render_far_clip(gSavedSettings, "RenderFarClip", 64); +      F32 nearby_max_complexity = 0;      F32 radius = render_far_clip * render_far_clip; -    std::vector<LLCharacter*>::iterator char_iter = LLCharacter::sInstances.begin(); -    while (char_iter != LLCharacter::sInstances.end()) + +    for (LLCharacter* character : LLCharacter::sInstances)      { -        LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*char_iter); -        if (avatar && !avatar->isDead() && !avatar->isControlAvatar()) +        LLVOAvatar* avatar = (LLVOAvatar*)character; +        if (!avatar->isDead() && !avatar->isControlAvatar())          { -            if ((dist_vec_squared(avatar->getPositionGlobal(), gAgent.getPositionGlobal()) > radius) && -                (dist_vec_squared(avatar->getPositionGlobal(), gAgentCamera.getCameraPositionGlobal()) > radius)) +            if ((dist_vec_squared(avatar->getPositionGlobal(), gAgent.getPositionGlobal()) <= radius) || +                (dist_vec_squared(avatar->getPositionGlobal(), gAgentCamera.getCameraPositionGlobal()) <= radius))              { -                char_iter++; -                continue; -            } - -            if (!avatar->isTooSlow()) -            { -                gPipeline.profileAvatar(avatar); +                if (!avatar->isTooSlow()) +                { +                    gPipeline.profileAvatar(avatar); +                } +                nearby_max_complexity = llmax(nearby_max_complexity, avatar->getGPURenderTime()); +                valid_nearby_avs.push_back(avatar);              } -            nearby_max_complexity = llmax(nearby_max_complexity, avatar->getGPURenderTime()); -            valid_nearby_avs.push_back(*char_iter);          } -        char_iter++;      } +      return nearby_max_complexity;  } diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h index 01f666d19a..dc95a4eff1 100644 --- a/indra/newview/llworld.h +++ b/indra/newview/llworld.h @@ -172,7 +172,7 @@ public:      // profile nearby avatars using gPipeline.profileAvatar and update their render times      // return max GPU time -    F32 getNearbyAvatarsAndMaxGPUTime(std::vector<LLCharacter*> &valid_nearby_avs); +    F32 getNearbyAvatarsAndMaxGPUTime(std::vector<LLVOAvatar*> &valid_nearby_avs);  private:      void clearHoleWaterObjects(); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 056affb68e..2a461ca84b 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -6438,16 +6438,14 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start,          }      } -    //check all avatar nametags (silly, isn't it?) -    for (std::vector< LLCharacter* >::iterator iter = LLCharacter::sInstances.begin(); -        iter != LLCharacter::sInstances.end(); -        ++iter) +    // check all avatar nametags (silly, isn't it?) +    for (LLCharacter* character : LLCharacter::sInstances)      { -        LLVOAvatar* av = (LLVOAvatar*) *iter; -        if (av->mNameText.notNull() -            && av->mNameText->lineSegmentIntersect(start, local_end, position)) +        LLVOAvatar* avatar = (LLVOAvatar*)character; +        if (avatar->mNameText.notNull() && +            avatar->mNameText->lineSegmentIntersect(start, local_end, position))          { -            drawable = av->mDrawable; +            drawable = avatar->mDrawable;              local_end = position;          }      } | 
