diff options
| -rw-r--r-- | indra/newview/llmeshrepository.cpp | 98 | ||||
| -rw-r--r-- | indra/newview/llmeshrepository.h | 5 | 
2 files changed, 48 insertions, 55 deletions
| diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 2969b42ca5..821288429d 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -895,6 +895,8 @@ LLMeshRepoThread::~LLMeshRepoThread()      mHeaderMutex = NULL;      delete mSignal;      mSignal = NULL; +    delete[] mDiskCacheBuffer; +    mDiskCacheBuffer = NULL;  }  void LLMeshRepoThread::run() @@ -1275,6 +1277,41 @@ void LLMeshRepoThread::loadMeshLOD(const LLUUID& mesh_id, const LLVolumeParams&      }  } +U8* LLMeshRepoThread::getDiskCacheBuffer(S32 size) +{ +    if (mDiskCacheBufferSize < size) +    { +        const S32 MINIMUM_BUFFER_SIZE = 8192; // a minimum to avoid frequent early reallocations +        size = llmax(MINIMUM_BUFFER_SIZE, size); +        delete[] mDiskCacheBuffer; +        try +        { +            mDiskCacheBuffer = new U8[size]; +        } +        catch (std::bad_alloc&) +        { +            LL_WARNS(LOG_MESH) << "Failed to allocate memory for mesh thread's buffer, size: " << size << LL_ENDL; +            mDiskCacheBuffer = NULL; + +            // Not sure what size is reasonable +            // but if 30MB 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 +        } +        mDiskCacheBufferSize = size; +    } +    else +    { +        // reusing old buffer, reset heading bytes to ensure +        // old content won't be parsable if something fails. +        memset(mDiskCacheBuffer, 0, 16); +    } +    return mDiskCacheBuffer; +} +  // Mutex:  must be holding mMutex when called  void LLMeshRepoThread::setGetMeshCap(const std::string & mesh_cap)  { @@ -1411,19 +1448,9 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry)              LLFileSystem file(mesh_id, LLAssetType::AT_MESH);              if (in_cache && file.getSize() >= disk_ofset + size)              { -                U8* buffer = new(std::nothrow) U8[size]; +                U8* buffer = getDiskCacheBuffer(size);                  if (!buffer)                  { -                    LL_WARNS(LOG_MESH) << "Failed to allocate memory for skin info, size: " << size << LL_ENDL; - -                    // 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;                  } @@ -1443,12 +1470,9 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry)                  { //attempt to parse                      if (skinInfoReceived(mesh_id, buffer, size))                      { -                        delete[] buffer;                          return true;                      }                  } - -                delete[] buffer;              }              //reading from cache failed for whatever reason, fetch from sim @@ -1537,18 +1561,9 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)              LLFileSystem file(mesh_id, LLAssetType::AT_MESH);              if (in_cache && file.getSize() >= disk_ofset + size)              { -                U8* buffer = new(std::nothrow) U8[size]; +                U8* buffer = getDiskCacheBuffer(size);                  if (!buffer)                  { -                    LL_WARNS(LOG_MESH) << "Failed to allocate memory for mesh decomposition, size: " << size << LL_ENDL; - -                    // 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; @@ -1568,12 +1583,9 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)                  { //attempt to parse                      if (decompositionReceived(mesh_id, buffer, size))                      { -                        delete[] buffer;                          return true;                      }                  } - -                delete[] buffer;              }              //reading from cache failed for whatever reason, fetch from sim @@ -1650,21 +1662,13 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)              {                  LLMeshRepository::sCacheBytesRead += size;                  ++LLMeshRepository::sCacheReads; -                file.seek(disk_ofset); -                U8* buffer = new(std::nothrow) U8[size]; + +                U8* buffer = getDiskCacheBuffer(size);                  if (!buffer)                  { -                    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.seek(disk_ofset);                  file.read(buffer, size);                  //make sure buffer isn't all 0's by checking the first 1KB (reserved block but not written) @@ -1678,12 +1682,9 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)                  { //attempt to parse                      if (physicsShapeReceived(mesh_id, buffer, size) == MESH_OK)                      { -                        delete[] buffer;                          return true;                      }                  } - -                delete[] buffer;              }              //reading from cache failed for whatever reason, fetch from sim @@ -1885,18 +1886,9 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod,              LLFileSystem file(mesh_id, LLAssetType::AT_MESH);              if (in_cache && file.getSize() >= disk_ofset + size)              { -                U8* buffer = new(std::nothrow) U8[size]; +                U8* buffer = getDiskCacheBuffer(size);                  if (!buffer)                  { -                    LL_WARNS(LOG_MESH) << "Can't allocate memory for mesh " << mesh_id << " LOD " << lod << ", size: " << size << LL_ENDL; - -                    // 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; @@ -1917,15 +1909,11 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod,                  { //attempt to parse                      if (lodReceived(mesh_params, lod, buffer, size) == MESH_OK)                      { -                        delete[] buffer; -                          LL_DEBUGS(LOG_MESH) << "Mesh/Cache: Mesh body for ID " << mesh_id << " - was retrieved from the cache." << LL_ENDL;                          return true;                      }                  } - -                delete[] buffer;              }              //reading from cache failed for whatever reason, fetch from sim diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index d11ea581cd..2e29daf9ec 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -576,6 +576,11 @@ private:      // Mutex:  mMutex must be alerady locked when calling      void loadMeshLOD(const LLUUID &mesh_id, const LLVolumeParams& mesh_params, S32 lod); + +    // Threads:  Repo thread only +    U8* getDiskCacheBuffer(S32 size); +    S32 mDiskCacheBufferSize = 0; +    U8* mDiskCacheBuffer = nullptr;  }; | 
