From 34e79c8f4e251200496651f9ae2b5126a6f7faa3 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 11 Mar 2022 10:21:08 -0600 Subject: SL-17005 WIP Simplify what feeds texture loading bias to only pay attention to available memory according to OS and GL driver, not (broken) internal accounting (breaks intel GPUs, compatibility pass incoming). --- indra/llimage/llimage.cpp | 5 ---- indra/llimage/llimage.h | 1 - indra/llrender/llimagegl.cpp | 22 +---------------- indra/llrender/llimagegl.h | 8 +----- indra/llrender/llrender.cpp | 6 ++--- indra/newview/llfloaterlagmeter.cpp | 2 +- indra/newview/lltextureview.cpp | 11 +-------- indra/newview/llviewerstats.cpp | 5 +--- indra/newview/llviewerstats.h | 6 ++--- indra/newview/llviewertexture.cpp | 46 ++--------------------------------- indra/newview/llviewertexture.h | 8 ++---- indra/newview/llviewertexturelist.cpp | 3 --- indra/newview/llviewerwindow.cpp | 2 -- indra/newview/llvoavatarself.cpp | 1 - indra/newview/pipeline.cpp | 2 +- 15 files changed, 15 insertions(+), 113 deletions(-) diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index 0fa027c9c3..3a3011d99b 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -798,7 +798,6 @@ U8* LLImageBase::allocateDataSize(S32 width, S32 height, S32 ncomponents, S32 si // LLImageRaw //--------------------------------------------------------------------------- -S32 LLImageRaw::sGlobalRawMemory = 0; S32 LLImageRaw::sRawImageCount = 0; LLImageRaw::LLImageRaw() @@ -847,16 +846,13 @@ LLImageRaw::~LLImageRaw() U8* LLImageRaw::allocateData(S32 size) { U8* res = LLImageBase::allocateData(size); - sGlobalRawMemory += getDataSize(); return res; } // virtual U8* LLImageRaw::reallocateData(S32 size) { - sGlobalRawMemory -= getDataSize(); U8* res = LLImageBase::reallocateData(size); - sGlobalRawMemory += getDataSize(); return res; } @@ -869,7 +865,6 @@ void LLImageRaw::releaseData() // virtual void LLImageRaw::deleteData() { - sGlobalRawMemory -= getDataSize(); LLImageBase::deleteData(); } diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index 7a588cfb03..460d5e0f5b 100644 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -275,7 +275,6 @@ protected: void setDataAndSize(U8 *data, S32 width, S32 height, S8 components) ; public: - static S32 sGlobalRawMemory; static S32 sRawImageCount; private: diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 9bd3a0a6b0..c171f7051f 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -57,9 +57,6 @@ U32 wpo2(U32 i); U32 LLImageGL::sUniqueCount = 0; U32 LLImageGL::sBindCount = 0; -S32Bytes LLImageGL::sGlobalTextureMemory(0); -S32Bytes LLImageGL::sBoundTextureMemory(0); -S32Bytes LLImageGL::sCurBoundTextureMemory(0); S32 LLImageGL::sCount = 0; BOOL LLImageGL::sGlobalUseAnisotropic = FALSE; @@ -282,15 +279,6 @@ void LLImageGL::updateStats(F32 current_time) { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; sLastFrameTime = current_time; - sBoundTextureMemory = sCurBoundTextureMemory; - sCurBoundTextureMemory = S32Bytes(0); -} - -//static -S32 LLImageGL::updateBoundTexMem(const S32Bytes mem, const S32 ncomponents, S32 category) -{ - LLImageGL::sCurBoundTextureMemory += mem ; - return LLImageGL::sCurBoundTextureMemory.value(); } //---------------------------------------------------------------------------- @@ -623,7 +611,7 @@ void LLImageGL::forceUpdateBindStats(void) const mLastBindTime = sLastFrameTime; } -BOOL LLImageGL::updateBindStats(S32Bytes tex_mem) const +BOOL LLImageGL::updateBindStats() const { if (mTexName != 0) { @@ -635,7 +623,6 @@ BOOL LLImageGL::updateBindStats(S32Bytes tex_mem) const { // we haven't accounted for this texture yet this frame sUniqueCount++; - updateBoundTexMem(tex_mem, mComponents, mCategory); mLastBindTime = sLastFrameTime; return TRUE ; @@ -1599,11 +1586,6 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_ // things will break if we don't unbind after creation gGL.getTexUnit(0)->unbind(mBindTarget); - if (old_texname != 0) - { - sGlobalTextureMemory -= mTextureMemory; - } - //if we're on the image loading thread, be sure to delete old_texname and update mTexName on the main thread if (!defer_copy) { @@ -1624,7 +1606,6 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_ mTextureMemory = (S32Bytes)getMipBytes(mCurrentDiscardLevel); - sGlobalTextureMemory += mTextureMemory; mTexelsInGLTexture = getWidth() * getHeight(); // mark this as bound at this point, so we don't throw it out immediately @@ -1857,7 +1838,6 @@ void LLImageGL::destroyGLTexture() { if(mTextureMemory != S32Bytes(0)) { - sGlobalTextureMemory -= mTextureMemory; mTextureMemory = (S32Bytes)0; } diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 4d5b60d6bc..ae4ab7c9c3 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -61,7 +61,7 @@ public: static S32 dataFormatBytes(S32 dataformat, S32 width, S32 height); static S32 dataFormatComponents(S32 dataformat); - BOOL updateBindStats(S32Bytes tex_mem) const ; + BOOL updateBindStats() const ; F32 getTimePassedSinceLastBound(); void forceUpdateBindStats(void) const; @@ -73,9 +73,6 @@ public: static void restoreGL(); static void dirtyTexOptions(); - // Sometimes called externally for textures not using LLImageGL (should go away...) - static S32 updateBoundTexMem(const S32Bytes mem, const S32 ncomponents, S32 category) ; - static bool checkSize(S32 width, S32 height); //for server side use only. @@ -265,9 +262,6 @@ public: static F32 sLastFrameTime; // Global memory statistics - static S32Bytes sGlobalTextureMemory; // Tracks main memory texmem - static S32Bytes sBoundTextureMemory; // Tracks bound texmem for last completed frame - static S32Bytes sCurBoundTextureMemory; // Tracks bound texmem for current frame static U32 sBindCount; // Tracks number of texture binds for current frame static U32 sUniqueCount; // Tracks number of unique texture binds for current frame static BOOL sGlobalUseAnisotropic; diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index a03a27cf94..15c509dbfb 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -223,7 +223,7 @@ bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind) enable(gl_tex->getTarget()); mCurrTexture = gl_tex->getTexName(); glBindTexture(sGLTextureType[gl_tex->getTarget()], mCurrTexture); - if(gl_tex->updateBindStats(gl_tex->mTextureMemory)) + if(gl_tex->updateBindStats()) { texture->setActive() ; texture->updateBindStatsForTester() ; @@ -302,7 +302,7 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind, S32 mCurrTexture = texname; glBindTexture(sGLTextureType[texture->getTarget()], mCurrTexture); stop_glerror(); - texture->updateBindStats(texture->mTextureMemory); + texture->updateBindStats(); mHasMipMaps = texture->mHasMipMaps; if (texture->mTexOptionsDirty) { @@ -341,7 +341,7 @@ bool LLTexUnit::bind(LLCubeMap* cubeMap) mCurrTexture = cubeMap->mImages[0]->getTexName(); glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mCurrTexture); mHasMipMaps = cubeMap->mImages[0]->mHasMipMaps; - cubeMap->mImages[0]->updateBindStats(cubeMap->mImages[0]->mTextureMemory); + cubeMap->mImages[0]->updateBindStats(); if (cubeMap->mImages[0]->mTexOptionsDirty) { cubeMap->mImages[0]->mTexOptionsDirty = false; diff --git a/indra/newview/llfloaterlagmeter.cpp b/indra/newview/llfloaterlagmeter.cpp index f72f2631a1..db00f69f03 100644 --- a/indra/newview/llfloaterlagmeter.cpp +++ b/indra/newview/llfloaterlagmeter.cpp @@ -179,7 +179,7 @@ void LLFloaterLagMeter::determineClient() { mClientCause->setText( getString("client_texture_loading_cause_msg", mStringArgs) ); } - else if(LLViewerTexture::sBoundTextureMemory > LLViewerTexture::sMaxBoundTextureMemory) + else if(LLViewerTexture::isMemoryForTextureLow()) { mClientCause->setText( getString("client_texture_memory_cause_msg", mStringArgs) ); } diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index b74577315e..b58070526c 100644 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -500,10 +500,6 @@ private: void LLGLTexMemBar::draw() { - S32Megabytes bound_mem = LLViewerTexture::sBoundTextureMemory; - S32Megabytes max_bound_mem = LLViewerTexture::sMaxBoundTextureMemory; - S32Megabytes total_mem = LLViewerTexture::sTotalTextureMemory; - S32Megabytes max_total_mem = LLViewerTexture::sMaxTotalTextureMem; F32 discard_bias = LLViewerTexture::sDesiredDiscardBias; F32 cache_usage = LLAppViewer::getTextureCache()->getUsage().valueInUnits(); F32 cache_max_usage = LLAppViewer::getTextureCache()->getMaxUsage().valueInUnits(); @@ -549,15 +545,10 @@ void LLGLTexMemBar::draw() U32 texFetchLatMed = U32(recording.getMean(LLTextureFetch::sTexFetchLatency).value() * 1000.0f); U32 texFetchLatMax = U32(recording.getMax(LLTextureFetch::sTexFetchLatency).value() * 1000.0f); - text = llformat("GL Tot: %d/%d MB GL Free: %d Sys Free: %d MB Bound: %4d/%4d MB FBO: %d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB", - total_mem.value(), - max_total_mem.value(), + text = llformat("GL Free: %d Sys Free: %d MB FBO: %d MB Bias: %.2f Cache: %.1f/%.1f MB", LLImageGLThread::getFreeVRAMMegabytes(), LLMemory::getAvailableMemKB()/1024, - bound_mem.value(), - max_bound_mem.value(), LLRenderTarget::sBytesAllocated/(1024*1024), - LLImageRaw::sGlobalRawMemory >> 20, discard_bias, cache_usage, cache_max_usage); diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 57a3d011d5..d87afa9a41 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -155,10 +155,7 @@ LLTrace::SampleStatHandle > static LLTrace::SampleStatHandle CHAT_BUBBLES("chatbubbles", "Chat Bubbles Enabled"); -LLTrace::SampleStatHandle GL_TEX_MEM("gltexmemstat"), - GL_BOUND_MEM("glboundmemstat"), - RAW_MEM("rawmemstat"), - FORMATTED_MEM("formattedmemstat"); +LLTrace::SampleStatHandle FORMATTED_MEM("formattedmemstat"); LLTrace::SampleStatHandle DELTA_BANDWIDTH("deltabandwidth", "Increase/Decrease in bandwidth based on packet loss"), MAX_BANDWIDTH("maxbandwidth", "Max bandwidth setting"); diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h index 017c79b2e3..8d1182d054 100644 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h @@ -191,10 +191,8 @@ extern LLTrace::SampleStatHandle<> FPS_SAMPLE, extern LLTrace::SampleStatHandle > PACKETS_LOST_PERCENT; -extern LLTrace::SampleStatHandle GL_TEX_MEM, - GL_BOUND_MEM, - RAW_MEM, - FORMATTED_MEM; +extern LLTrace::SampleStatHandle FORMATTED_MEM; + extern LLTrace::SampleStatHandle DELTA_BANDWIDTH, MAX_BANDWIDTH; extern SimMeasurement SIM_FRAME_TIME, diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index e3ac56d0d3..be7ee3660e 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -84,11 +84,6 @@ S32 LLViewerTexture::sAuxCount = 0; LLFrameTimer LLViewerTexture::sEvaluationTimer; F32 LLViewerTexture::sDesiredDiscardBias = 0.f; F32 LLViewerTexture::sDesiredDiscardScale = 1.1f; -S32Bytes LLViewerTexture::sBoundTextureMemory; -S32Bytes LLViewerTexture::sTotalTextureMemory; -S32Megabytes LLViewerTexture::sMaxBoundTextureMemory; -S32Megabytes LLViewerTexture::sMaxTotalTextureMem; -S32Bytes LLViewerTexture::sMaxDesiredTextureMem; S8 LLViewerTexture::sCameraMovingDiscardBias = 0; F32 LLViewerTexture::sCameraMovingBias = 0.0f; S32 LLViewerTexture::sMaxSculptRez = 128; //max sculpt image size @@ -553,27 +548,7 @@ void LLViewerTexture::updateClass() LLViewerMediaTexture::updateClass(); - sBoundTextureMemory = LLImageGL::sBoundTextureMemory; - sTotalTextureMemory = LLImageGL::sGlobalTextureMemory; - sMaxBoundTextureMemory = gTextureList.getMaxResidentTexMem(); - sMaxTotalTextureMem = gTextureList.getMaxTotalTextureMem(); - sMaxDesiredTextureMem = sMaxTotalTextureMem; //in Bytes, by default and when total used texture memory is small. - - if (sBoundTextureMemory >= sMaxBoundTextureMemory || - sTotalTextureMemory >= sMaxTotalTextureMem) - { - //when texture memory overflows, lower down the threshold to release the textures more aggressively. - sMaxDesiredTextureMem = llmin(sMaxDesiredTextureMem * 0.75f, F32Bytes(gMaxVideoRam)); - - // If we are using more texture memory than we should, - // scale up the desired discard level - if (sEvaluationTimer.getElapsedTimeF32() > discard_delta_time) - { - sDesiredDiscardBias += discard_bias_delta; - sEvaluationTimer.reset(); - } - } - else if(isMemoryForTextureLow()) + if(isMemoryForTextureLow()) { // Note: isMemoryForTextureLow() uses 1s delay, make sure we waited enough for it to recheck if (sEvaluationTimer.getElapsedTimeF32() > GPU_MEMORY_CHECK_WAIT_TIME) @@ -583,8 +558,6 @@ void LLViewerTexture::updateClass() } } else if (sDesiredDiscardBias > 0.0f - && sBoundTextureMemory < sMaxBoundTextureMemory * texmem_lower_bound_scale - && sTotalTextureMemory < sMaxTotalTextureMem * texmem_lower_bound_scale && isMemoryForTextureSuficientlyFree()) { // If we are using less texture memory than we should, @@ -1352,10 +1325,7 @@ void LLViewerFetchedTexture::dump() void LLViewerFetchedTexture::destroyTexture() { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - if(LLImageGL::sGlobalTextureMemory < sMaxDesiredTextureMem * 0.95f)//not ready to release unused memory. - { - return ; - } + if (mNeedsCreateTexture)//return if in the process of generating a new texture. { return; @@ -3400,18 +3370,6 @@ void LLViewerLODTexture::processTextureStats() //needs to release texture memory urgently scaleDown(); } - // Limit the amount of GL memory bound each frame - else if ( sBoundTextureMemory > sMaxBoundTextureMemory * texmem_middle_bound_scale && - (!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel)) - { - scaleDown(); - } - // Only allow GL to have 2x the video card memory - else if ( sTotalTextureMemory > sMaxTotalTextureMem * texmem_middle_bound_scale && - (!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel)) - { - scaleDown(); - } } if (isUpdateFrozen() // we are out of memory and nearing max allowed bias diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index b953d7006b..0640efe6df 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -188,10 +188,11 @@ private: virtual void switchToCachedImage(); - static bool isMemoryForTextureLow() ; static bool isMemoryForTextureSuficientlyFree(); static void getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &physical); +public: + static bool isMemoryForTextureLow(); protected: LLUUID mID; S32 mTextureListType; // along with mID identifies where to search for this texture in TextureList @@ -226,11 +227,6 @@ public: static LLFrameTimer sEvaluationTimer; static F32 sDesiredDiscardBias; static F32 sDesiredDiscardScale; - static S32Bytes sBoundTextureMemory; - static S32Bytes sTotalTextureMemory; - static S32Megabytes sMaxBoundTextureMemory; - static S32Megabytes sMaxTotalTextureMem; - static S32Bytes sMaxDesiredTextureMem ; static S8 sCameraMovingDiscardBias; static F32 sCameraMovingBias; static S32 sMaxSculptRez ; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 94a91d4a72..66e113b45c 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -784,9 +784,6 @@ void LLViewerTextureList::updateImages(F32 max_time) using namespace LLStatViewer; sample(NUM_IMAGES, sNumImages); sample(NUM_RAW_IMAGES, LLImageRaw::sRawImageCount); - sample(GL_TEX_MEM, LLImageGL::sGlobalTextureMemory); - sample(GL_BOUND_MEM, LLImageGL::sBoundTextureMemory); - sample(RAW_MEM, F64Bytes(LLImageRaw::sGlobalRawMemory)); sample(FORMATTED_MEM, F64Bytes(LLImageFormatted::sGlobalFormattedMemory)); } diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index a54c29a404..47d612ab9a 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -5532,8 +5532,6 @@ void LLViewerWindow::stopGL(BOOL save_state) LLGLSLShader* shader = *(LLGLSLShader::sInstances.begin()); shader->unload(); } - - LL_INFOS() << "Remaining allocated texture memory: " << LLImageGL::sGlobalTextureMemory.value() << " bytes" << LL_ENDL; } } diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 60a69a4ac4..49f5f40f03 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -2823,7 +2823,6 @@ void LLVOAvatarSelf::deleteScratchTextures() LL_DEBUGS() << "Clearing Scratch Textures " << (S32Kilobytes)sScratchTexBytes << LL_ENDL; delete_and_clear(sScratchTexNames); - LLImageGL::sGlobalTextureMemory -= sScratchTexBytes; sScratchTexBytes = S32Bytes(0); } } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 34c4e2ddb9..2aff3de29b 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -3712,7 +3712,7 @@ void LLPipeline::touchTexture(LLViewerTexture* tex, F32 vsize) if (tex) { LLImageGL* gl_tex = tex->getGLTexture(); - if (gl_tex && gl_tex->updateBindStats(gl_tex->mTextureMemory)) + if (gl_tex && gl_tex->updateBindStats()) { tex->setActive(); tex->addTextureStats(vsize); -- cgit v1.2.3 From e60024f0afecb6f92e383221084f1a7af02f8542 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 29 Mar 2022 15:41:00 -0500 Subject: SL-17005 WIP - Use D3D/DXGI to query for available VRAM on Windows --- indra/llrender/llimagegl.cpp | 52 --------------- indra/llrender/llimagegl.h | 8 --- indra/llwindow/CMakeLists.txt | 2 + indra/llwindow/llwindow.h | 3 + indra/llwindow/llwindowheadless.h | 2 + indra/llwindow/llwindowwin32.cpp | 136 ++++++++++++++++++++++++++++++++++++++ indra/llwindow/llwindowwin32.h | 4 +- indra/newview/lltextureview.cpp | 6 +- indra/newview/llviewerdisplay.cpp | 2 - indra/newview/llviewertexture.cpp | 4 +- 10 files changed, 153 insertions(+), 66 deletions(-) diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index c171f7051f..0a5d258b3a 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -1615,51 +1615,6 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_ return TRUE; } -void LLImageGLThread::updateClass() -{ - LL_PROFILE_ZONE_SCOPED; - - // update available vram one per second - static LLFrameTimer sTimer; - - if (sTimer.getElapsedSeconds() < 1.f) - { - return; - } - - sTimer.reset(); - - auto func = []() - { - if (gGLManager.mHasATIMemInfo) - { - S32 meminfo[4]; - glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo); - LLImageGLThread::sFreeVRAMMegabytes = meminfo[0]; - - } - else if (gGLManager.mHasNVXMemInfo) - { - S32 free_memory; - glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &free_memory); - LLImageGLThread::sFreeVRAMMegabytes = free_memory / 1024; - } - }; - - - // post update to background thread if available, otherwise execute immediately - auto queue = LL::WorkQueue::getInstance("LLImageGL"); - if (sEnabled) - { - queue->post(func); - } - else - { - llassert(queue == nullptr); - func(); - } -} - void LLImageGL::syncToMainThread(LLGLuint new_tex_name) { LL_PROFILE_ZONE_SCOPED; @@ -2389,8 +2344,6 @@ void LLImageGL::checkActiveThread() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, nummips); */ -std::atomic LLImageGLThread::sFreeVRAMMegabytes(4096); //if free vram is unknown, default to 4GB - LLImageGLThread::LLImageGLThread(LLWindow* window) // We want exactly one thread, but a very large capacity: we never want // anyone, especially inner-loop render code, to have to block on post() @@ -2418,8 +2371,3 @@ void LLImageGLThread::run() mWindow->destroySharedContext(mContext); } -S32 LLImageGLThread::getFreeVRAMMegabytes() -{ - return sFreeVRAMMegabytes; -} - diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index ae4ab7c9c3..1716338c0b 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -321,12 +321,6 @@ public: // follows gSavedSettings "RenderGLMultiThreaded" static bool sEnabled; - // app should call this function periodically - static void updateClass(); - - // free video memory in megabytes - static std::atomic sFreeVRAMMegabytes; - LLImageGLThread(LLWindow* window); // post a function to be executed on the LLImageGL background thread @@ -338,8 +332,6 @@ public: void run() override; - static S32 getFreeVRAMMegabytes(); - private: LLWindow* mWindow; void* mContext = nullptr; diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt index 70eb99c86c..32f0fa14c4 100644 --- a/indra/llwindow/CMakeLists.txt +++ b/indra/llwindow/CMakeLists.txt @@ -145,6 +145,8 @@ if (WINDOWS) list(APPEND llwindow_LINK_LIBRARIES comdlg32 # Common Dialogs for ChooseColor ole32 + dxgi + d3d9 ) endif (WINDOWS) diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index 0edf39f6ef..507e6076d6 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -163,6 +163,9 @@ public: virtual F32 getPixelAspectRatio() = 0; virtual void setNativeAspectRatio(F32 aspect) = 0; + // query VRAM usage + virtual U32 getAvailableVRAMMegabytes() = 0; + virtual void beforeDialog() {}; // prepare to put up an OS dialog (if special measures are required, such as in fullscreen mode) virtual void afterDialog() {}; // undo whatever was done in beforeDialog() diff --git a/indra/llwindow/llwindowheadless.h b/indra/llwindow/llwindowheadless.h index 410da79623..0e1f603db7 100644 --- a/indra/llwindow/llwindowheadless.h +++ b/indra/llwindow/llwindowheadless.h @@ -96,6 +96,8 @@ public: /*virtual*/ F32 getPixelAspectRatio() { return 1.0f; }; /*virtual*/ void setNativeAspectRatio(F32 ratio) {} + U32 getAvailableVRAMMegabytes() override { return 4096; } + /*virtual*/ void *getPlatformWindow() { return 0; }; /*virtual*/ void bringToFront() {}; diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 9feccd7874..3afb78d1d2 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -47,6 +47,7 @@ #include "llglslshader.h" #include "llthreadsafequeue.h" #include "stringize.h" +#include "llframetimer.h" // System includes #include @@ -61,6 +62,10 @@ #include #include // std::pair +#include +#include + + // Require DirectInput version 8 #define DIRECTINPUT_VERSION 0x0800 @@ -347,6 +352,20 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool void run() override; + // initialzie DXGI adapter (for querying available VRAM) + void initDX(); + + // initialize D3D (if DXGI cannot be used) + void initD3D(); + + // call periodically to update available VRAM + void updateVRAMUsage(); + + U32 getAvailableVRAMMegabytes() + { + return mAvailableVRAM; + } + /// called by main thread to post work to this window thread template void post(CALLABLE&& func) @@ -395,6 +414,12 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool void gatherInput(); HWND mWindowHandle = NULL; HDC mhDC = 0; + + std::atomic mAvailableVRAM; + + IDXGIAdapter3* mDXGIAdapter = nullptr; + LPDIRECT3D9 mD3D = nullptr; + LPDIRECT3DDEVICE9 mD3DDevice = nullptr; }; @@ -4507,6 +4532,10 @@ std::vector LLWindowWin32::getDynamicFallbackFontList() return std::vector(); } +U32 LLWindowWin32::getAvailableVRAMMegabytes() +{ + return mWindowThread ? mWindowThread->getAvailableVRAMMegabytes() : 0; +} #endif // LL_WINDOWS @@ -4562,17 +4591,97 @@ private: std::string mPrev; }; +void LLWindowWin32::LLWindowWin32Thread::initDX() +{ + if (mDXGIAdapter == NULL) + { + IDXGIFactory4* pFactory = nullptr; + + HRESULT res = CreateDXGIFactory1(__uuidof(IDXGIFactory4), (void**)&pFactory); + + if (FAILED(res)) + { + LL_WARNS() << "CreateDXGIFactory1 failed: 0x" << std::hex << res << LL_ENDL; + } + else + { + res = pFactory->EnumAdapters(0, reinterpret_cast(&mDXGIAdapter)); + if (FAILED(res)) + { + LL_WARNS() << "EnumAdapters failed: 0x" << std::hex << res << LL_ENDL; + } + } + + pFactory->Release(); + } +} + +void LLWindowWin32::LLWindowWin32Thread::initD3D() +{ + if (mDXGIAdapter == NULL && mD3DDevice == NULL && mWindowHandle != 0) + { + mD3D = Direct3DCreate9(D3D_SDK_VERSION); + + D3DPRESENT_PARAMETERS d3dpp; + + ZeroMemory(&d3dpp, sizeof(d3dpp)); + d3dpp.Windowed = TRUE; + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + + mD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, mWindowHandle, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &mD3DDevice); + } +} + +void LLWindowWin32::LLWindowWin32Thread::updateVRAMUsage() +{ + LL_PROFILE_ZONE_SCOPED; + if (mDXGIAdapter != nullptr) + { + DXGI_QUERY_VIDEO_MEMORY_INFO info; + mDXGIAdapter->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_LOCAL, &info); + + // try to use no more than the available reserve minus 10% + U32 target = info.AvailableForReservation / 1024 / 1024; + target -= target / 10; + + U32 used_vram = info.CurrentUsage / 1024 / 1024; + + mAvailableVRAM = used_vram < target ? target - used_vram : 0; + + /*LL_INFOS() << "\nLocal\nAFR: " << info.AvailableForReservation / 1024 / 1024 + << "\nBudget: " << info.Budget / 1024 / 1024 + << "\nCR: " << info.CurrentReservation / 1024 / 1024 + << "\nCU: " << info.CurrentUsage / 1024 / 1024 << LL_ENDL; + + mDXGIAdapter->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL, &info); + LL_INFOS() << "\nNon-Local\nAFR: " << info.AvailableForReservation / 1024 / 1024 + << "\nBudget: " << info.Budget / 1024 / 1024 + << "\nCR: " << info.CurrentReservation / 1024 / 1024 + << "\nCU: " << info.CurrentUsage / 1024 / 1024 << LL_ENDL;*/ + } + else if (mD3DDevice != NULL) + { // fallback to D3D9 + mAvailableVRAM = mD3DDevice->GetAvailableTextureMem() / 1024 / 1024; + } + +} + void LLWindowWin32::LLWindowWin32Thread::run() { sWindowThreadId = std::this_thread::get_id(); LogChange logger("Window"); + initDX(); + while (! getQueue().done()) { LL_PROFILE_ZONE_SCOPED_CATEGORY_WIN32; if (mWindowHandle != 0) { + // lazily call initD3D inside this loop to catch when mWindowHandle has been set + initD3D(); + MSG msg; BOOL status; if (mhDC == 0) @@ -4605,6 +4714,13 @@ void LLWindowWin32::LLWindowWin32Thread::run() getQueue().runPending(); } + // update available vram once every 3 seconds + static LLFrameTimer vramTimer; + if (vramTimer.getElapsedTimeF32() > 3.f) + { + updateVRAMUsage(); + vramTimer.reset(); + } #if 0 { LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("w32t - Sleep"); @@ -4613,6 +4729,26 @@ void LLWindowWin32::LLWindowWin32Thread::run() } #endif } + + //clean up DXGI/D3D resources + if (mDXGIAdapter) + { + mDXGIAdapter->Release(); + mDXGIAdapter = nullptr; + } + + if (mD3DDevice) + { + mD3DDevice->Release(); + mD3DDevice = nullptr; + } + + if (mD3D) + { + mD3D->Release(); + mD3D = nullptr; + } + } void LLWindowWin32::post(const std::function& func) diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index b391acc12d..bd53b3e92a 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -108,7 +108,9 @@ public: /*virtual*/ F32 getPixelAspectRatio(); /*virtual*/ void setNativeAspectRatio(F32 ratio) { mOverrideAspectRatio = ratio; } - /*virtual*/ BOOL dialogColorPicker(F32 *r, F32 *g, F32 *b ); + U32 getAvailableVRAMMegabytes() override; + + /*virtual*/ BOOL dialogColorPicker(F32 *r, F32 *g, F32 *b ); /*virtual*/ void *getPlatformWindow(); /*virtual*/ void bringToFront(); diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index b58070526c..99ab854293 100644 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -49,6 +49,8 @@ #include "llviewerobjectlist.h" #include "llviewertexture.h" #include "llviewertexturelist.h" +#include "llviewerwindow.h" +#include "llwindow.h" #include "llvovolume.h" #include "llviewerstats.h" #include "llworld.h" @@ -545,8 +547,8 @@ void LLGLTexMemBar::draw() U32 texFetchLatMed = U32(recording.getMean(LLTextureFetch::sTexFetchLatency).value() * 1000.0f); U32 texFetchLatMax = U32(recording.getMax(LLTextureFetch::sTexFetchLatency).value() * 1000.0f); - text = llformat("GL Free: %d Sys Free: %d MB FBO: %d MB Bias: %.2f Cache: %.1f/%.1f MB", - LLImageGLThread::getFreeVRAMMegabytes(), + text = llformat("GL Free: %d Sys Free: %d MB FBO: %d MB Bias: %.2f Cache: %.1f/%.1f MB", + gViewerWindow->getWindow()->getAvailableVRAMMegabytes(), LLMemory::getAvailableMemKB()/1024, LLRenderTarget::sBytesAllocated/(1024*1024), discard_bias, diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 6a2b06d9b5..4fc1bdbec3 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -788,8 +788,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) LLViewerTexture::updateClass(); } - LLImageGLThread::updateClass(); - { LL_RECORD_BLOCK_TIME(FTM_IMAGE_UPDATE_BUMP); gBumpImageList.updateImages(); // must be called before gTextureList version so that it's textures are thrown out first. diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index be7ee3660e..ac6c86d9c6 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -58,6 +58,8 @@ #include "llvovolume.h" #include "llviewermedia.h" #include "lltexturecache.h" +#include "llviewerwindow.h" +#include "llwindow.h" /////////////////////////////////////////////////////////////////////////////// // extern @@ -523,7 +525,7 @@ void LLViewerTexture::getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &p timer.reset(); { - gpu_res = (S32Megabytes) LLImageGLThread::getFreeVRAMMegabytes(); + gpu_res = (S32Megabytes)gViewerWindow->getWindow()->getAvailableVRAMMegabytes(); //check main memory, only works for windows. LLMemory::updateMemoryInfo(); -- cgit v1.2.3 From b6841d75c2f259c84d5ab6b012bd2ae37d985451 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 15 Apr 2022 19:02:07 -0500 Subject: SL-17219 WIP - Texture pipeline overhaul --- indra/llappearance/lltexlayerparams.cpp | 2 +- indra/llappearance/lltexlayerparams.h | 2 +- indra/llcommon/llapr.cpp | 2 + indra/llcommon/llqueuedthread.cpp | 289 +++++++------- indra/llcommon/llqueuedthread.h | 51 +-- indra/llcommon/lltimer.cpp | 3 +- indra/llcommon/llworkerthread.cpp | 27 +- indra/llcommon/llworkerthread.h | 11 +- indra/llcommon/workqueue.h | 8 +- indra/llcorehttp/_httplibcurl.cpp | 59 +-- indra/llcorehttp/_httpoperation.cpp | 1 - indra/llcorehttp/_httpoperation.h | 1 - indra/llcorehttp/_httpoprequest.cpp | 48 ++- indra/llcorehttp/_httpoprequest.h | 22 -- indra/llcorehttp/_httpopsetpriority.cpp | 3 + indra/llcorehttp/_httpopsetpriority.h | 6 +- indra/llcorehttp/_httppolicy.cpp | 31 -- indra/llcorehttp/_httppolicy.h | 6 - indra/llcorehttp/_httpservice.cpp | 32 +- indra/llcorehttp/_httpservice.h | 9 - indra/llcorehttp/httprequest.cpp | 45 +-- indra/llcorehttp/httprequest.h | 30 -- indra/llfilesystem/lllfsthread.cpp | 25 +- indra/llfilesystem/lllfsthread.h | 13 +- indra/llimage/llimagej2c.cpp | 2 + indra/llimage/llimageworker.cpp | 36 +- indra/llimage/llimageworker.h | 9 +- indra/llimagej2coj/llimagej2coj.cpp | 1 + indra/llkdu/llimagej2ckdu.cpp | 29 +- indra/llmessage/llavatarnamecache.cpp | 2 - indra/llmessage/llcorehttputil.cpp | 27 +- indra/llmessage/llcorehttputil.h | 25 +- indra/llrender/llimagegl.cpp | 50 ++- indra/newview/app_settings/settings.xml | 28 +- indra/newview/featuretable.txt | 1 - indra/newview/featuretable_mac.txt | 1 - indra/newview/llappviewer.cpp | 2 +- indra/newview/lldrawpoolterrain.cpp | 2 +- indra/newview/llface.cpp | 1 + indra/newview/llfloaterpreference.cpp | 7 +- indra/newview/llinventorymodel.cpp | 3 - indra/newview/llinventorymodel.h | 2 - indra/newview/llmaterialmgr.cpp | 7 +- indra/newview/llmaterialmgr.h | 1 - indra/newview/llmediadataclient.cpp | 2 +- indra/newview/llmeshrepository.cpp | 8 +- indra/newview/llmeshrepository.h | 2 - indra/newview/llspatialpartition.cpp | 6 +- indra/newview/lltexturecache.cpp | 110 ++---- indra/newview/lltexturecache.h | 6 +- indra/newview/lltexturefetch.cpp | 275 ++++++------- indra/newview/lltexturefetch.h | 11 +- indra/newview/lltextureview.cpp | 39 +- indra/newview/llviewercontrol.cpp | 7 - indra/newview/llviewertexture.cpp | 316 +++++---------- indra/newview/llviewertexture.h | 27 +- indra/newview/llviewertexturelist.cpp | 433 ++++++++------------- indra/newview/llviewertexturelist.h | 17 +- indra/newview/llvoavatar.cpp | 9 - indra/newview/llvoavatarself.cpp | 8 +- indra/newview/llvovolume.cpp | 34 +- indra/newview/llxmlrpctransaction.cpp | 2 +- indra/newview/pipeline.cpp | 48 ++- .../en/floater_preferences_graphics_advanced.xml | 17 - 64 files changed, 893 insertions(+), 1446 deletions(-) diff --git a/indra/llappearance/lltexlayerparams.cpp b/indra/llappearance/lltexlayerparams.cpp index ce5c7142d5..06b4f6c75a 100644 --- a/indra/llappearance/lltexlayerparams.cpp +++ b/indra/llappearance/lltexlayerparams.cpp @@ -151,7 +151,7 @@ LLTexLayerParamAlpha::LLTexLayerParamAlpha(const LLTexLayerParamAlpha& pOther) mCachedProcessedTexture(pOther.mCachedProcessedTexture), mStaticImageTGA(pOther.mStaticImageTGA), mStaticImageRaw(pOther.mStaticImageRaw), - mNeedsCreateTexture(pOther.mNeedsCreateTexture), + mNeedsCreateTexture(pOther.mNeedsCreateTexture.load()), mStaticImageInvalid(pOther.mStaticImageInvalid), mAvgDistortionVec(pOther.mAvgDistortionVec), mCachedEffectiveWeight(pOther.mCachedEffectiveWeight) diff --git a/indra/llappearance/lltexlayerparams.h b/indra/llappearance/lltexlayerparams.h index e2440998b3..000f55685e 100644 --- a/indra/llappearance/lltexlayerparams.h +++ b/indra/llappearance/lltexlayerparams.h @@ -100,7 +100,7 @@ private: LLPointer mCachedProcessedTexture; LLPointer mStaticImageTGA; LLPointer mStaticImageRaw; - BOOL mNeedsCreateTexture; + std::atomic mNeedsCreateTexture; BOOL mStaticImageInvalid; LL_ALIGN_16(LLVector4a mAvgDistortionVec); F32 mCachedEffectiveWeight; diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp index db94765871..b537102510 100644 --- a/indra/llcommon/llapr.cpp +++ b/indra/llcommon/llapr.cpp @@ -526,6 +526,7 @@ S32 LLAPRFile::seek(apr_file_t* file_handle, apr_seek_where_t where, S32 offset) //static S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool) { + LL_PROFILE_ZONE_SCOPED; //***************************************** LLAPRFilePoolScope scope(pool); apr_file_t* file_handle = open(filename, scope.getVolatileAPRPool(), APR_READ|APR_BINARY); @@ -570,6 +571,7 @@ S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nb //static S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool) { + LL_PROFILE_ZONE_SCOPED; apr_int32_t flags = APR_CREATE|APR_WRITE|APR_BINARY; if (offset < 0) { diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp index 8cef4293cd..871c42f7ee 100644 --- a/indra/llcommon/llqueuedthread.cpp +++ b/indra/llcommon/llqueuedthread.cpp @@ -26,20 +26,25 @@ #include "linden_common.h" #include "llqueuedthread.h" +#include + #include "llstl.h" #include "lltimer.h" // ms_sleep() -#include "lltracethreadrecorder.h" +#include "llmutex.h" //============================================================================ // MAIN THREAD LLQueuedThread::LLQueuedThread(const std::string& name, bool threaded, bool should_pause) : - LLThread(name), - mThreaded(threaded), - mIdleThread(TRUE), - mNextHandle(0), - mStarted(FALSE) + LLThread(name), + mThreaded(threaded), + mIdleThread(TRUE), + mNextHandle(0), + mStarted(FALSE), + mRequestQueue(name, 1024 * 1024) { + mMainQueue = LL::WorkQueue::getInstance("mainloop"); + if (mThreaded) { if(should_pause) @@ -104,6 +109,8 @@ void LLQueuedThread::shutdown() { LL_WARNS() << "~LLQueuedThread() called with active requests: " << active_count << LL_ENDL; } + + mRequestQueue.close(); } //---------------------------------------------------------------------------- @@ -112,6 +119,7 @@ void LLQueuedThread::shutdown() // virtual S32 LLQueuedThread::update(F32 max_time_ms) { + LL_PROFILE_ZONE_SCOPED; if (!mStarted) { if (!mThreaded) @@ -125,29 +133,30 @@ S32 LLQueuedThread::update(F32 max_time_ms) S32 LLQueuedThread::updateQueue(F32 max_time_ms) { - F64 max_time = (F64)max_time_ms * .001; - LLTimer timer; - S32 pending = 1; - + LL_PROFILE_ZONE_SCOPED; // Frame Update if (mThreaded) { - pending = getPending(); - if(pending > 0) + // schedule a call to threadedUpdate for every call to updateQueue + mRequestQueue.post([=]() + { + LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("qt - update"); + mIdleThread = FALSE; + threadedUpdate(); + mIdleThread = TRUE; + } + ); + if(getPending() > 0) { - unpause(); - } + unpause(); + } } else { - while (pending > 0) - { - pending = processNextRequest(); - if (max_time && timer.getElapsedTimeF64() > max_time) - break; - } + mRequestQueue.runFor(std::chrono::microseconds((int) (max_time_ms*1000.f))); + threadedUpdate(); } - return pending; + return getPending(); } void LLQueuedThread::incQueue() @@ -166,11 +175,7 @@ void LLQueuedThread::incQueue() // May be called from any thread S32 LLQueuedThread::getPending() { - S32 res; - lockData(); - res = mRequestQueue.size(); - unlockData(); - return res; + return mRequestQueue.size(); } // MAIN thread @@ -195,35 +200,28 @@ void LLQueuedThread::waitOnPending() // MAIN thread void LLQueuedThread::printQueueStats() { - lockData(); - if (!mRequestQueue.empty()) + U32 size = mRequestQueue.size(); + if (size > 0) { - QueuedRequest *req = *mRequestQueue.begin(); - LL_INFOS() << llformat("Pending Requests:%d Current status:%d", mRequestQueue.size(), req->getStatus()) << LL_ENDL; + LL_INFOS() << llformat("Pending Requests:%d ", mRequestQueue.size()) << LL_ENDL; } else { LL_INFOS() << "Queued Thread Idle" << LL_ENDL; } - unlockData(); } // MAIN thread LLQueuedThread::handle_t LLQueuedThread::generateHandle() { - lockData(); - while ((mNextHandle == nullHandle()) || (mRequestHash.find(mNextHandle))) - { - mNextHandle++; - } - const LLQueuedThread::handle_t res = mNextHandle++; - unlockData(); + U32 res = ++mNextHandle; return res; } // MAIN thread bool LLQueuedThread::addRequest(QueuedRequest* req) { + LL_PROFILE_ZONE_SCOPED; if (mStatus == QUITTING) { return false; @@ -231,14 +229,14 @@ bool LLQueuedThread::addRequest(QueuedRequest* req) lockData(); req->setStatus(STATUS_QUEUED); - mRequestQueue.insert(req); - mRequestHash.insert(req); + mRequestHash.insert(req); #if _DEBUG // LL_INFOS() << llformat("LLQueuedThread::Added req [%08d]",handle) << LL_ENDL; #endif unlockData(); - incQueue(); + llassert(!mDataLock->isSelfLocked()); + mRequestQueue.post([this, req]() { processRequest(req); }); return true; } @@ -246,6 +244,7 @@ bool LLQueuedThread::addRequest(QueuedRequest* req) // MAIN thread bool LLQueuedThread::waitForResult(LLQueuedThread::handle_t handle, bool auto_complete) { + LL_PROFILE_ZONE_SCOPED; llassert (handle != nullHandle()); bool res = false; bool waspaused = isPaused(); @@ -312,6 +311,7 @@ LLQueuedThread::status_t LLQueuedThread::getRequestStatus(handle_t handle) void LLQueuedThread::abortRequest(handle_t handle, bool autocomplete) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; lockData(); QueuedRequest* req = (QueuedRequest*)mRequestHash.find(handle); if (req) @@ -333,30 +333,9 @@ void LLQueuedThread::setFlags(handle_t handle, U32 flags) unlockData(); } -void LLQueuedThread::setPriority(handle_t handle, U32 priority) -{ - lockData(); - QueuedRequest* req = (QueuedRequest*)mRequestHash.find(handle); - if (req) - { - if(req->getStatus() == STATUS_INPROGRESS) - { - // not in list - req->setPriority(priority); - } - else if(req->getStatus() == STATUS_QUEUED) - { - // remove from list then re-insert - llverify(mRequestQueue.erase(req) == 1); - req->setPriority(priority); - mRequestQueue.insert(req); - } - } - unlockData(); -} - bool LLQueuedThread::completeRequest(handle_t handle) { + LL_PROFILE_ZONE_SCOPED; bool res = false; lockData(); QueuedRequest* req = (QueuedRequest*)mRequestHash.find(handle); @@ -399,89 +378,115 @@ bool LLQueuedThread::check() //============================================================================ // Runs on its OWN thread -S32 LLQueuedThread::processNextRequest() +void LLQueuedThread::processRequest(LLQueuedThread::QueuedRequest* req) { - QueuedRequest *req; + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + + mIdleThread = FALSE; + //threadedUpdate(); + // Get next request from pool lockData(); - while(1) - { - req = NULL; - if (mRequestQueue.empty()) - { - break; - } - req = *mRequestQueue.begin(); - mRequestQueue.erase(mRequestQueue.begin()); - if ((req->getFlags() & FLAG_ABORT) || (mStatus == QUITTING)) - { - req->setStatus(STATUS_ABORTED); - req->finishRequest(false); - if (req->getFlags() & FLAG_AUTO_COMPLETE) - { - mRequestHash.erase(req); - req->deleteRequest(); -// check(); - } - continue; - } - llassert_always(req->getStatus() == STATUS_QUEUED); - break; - } - U32 start_priority = 0 ; - if (req) - { - req->setStatus(STATUS_INPROGRESS); - start_priority = req->getPriority(); - } - unlockData(); - - // This is the only place we will call req->setStatus() after - // it has initially been seet to STATUS_QUEUED, so it is - // safe to access req. - if (req) + if ((req->getFlags() & FLAG_ABORT) || (mStatus == QUITTING)) { - // process request - bool complete = req->processRequest(); - - if (complete) + LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("qtpr - abort"); + req->setStatus(STATUS_ABORTED); + req->finishRequest(false); + if (req->getFlags() & FLAG_AUTO_COMPLETE) { - lockData(); - req->setStatus(STATUS_COMPLETE); - req->finishRequest(true); - if (req->getFlags() & FLAG_AUTO_COMPLETE) - { - mRequestHash.erase(req); - req->deleteRequest(); + mRequestHash.erase(req); + req->deleteRequest(); // check(); - } - unlockData(); } - else - { - lockData(); - req->setStatus(STATUS_QUEUED); - mRequestQueue.insert(req); - unlockData(); - if (mThreaded && start_priority < PRIORITY_NORMAL) - { - ms_sleep(1); // sleep the thread a little - } - } - - LLTrace::get_thread_recorder()->pushToParent(); + unlockData(); } + else + { + llassert_always(req->getStatus() == STATUS_QUEUED); + + if (req) + { + req->setStatus(STATUS_INPROGRESS); + } + unlockData(); + + // This is the only place we will call req->setStatus() after + // it has initially been seet to STATUS_QUEUED, so it is + // safe to access req. + if (req) + { + // process request + bool complete = req->processRequest(); + + if (complete) + { + LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("qtpr - complete"); + lockData(); + req->setStatus(STATUS_COMPLETE); + req->finishRequest(true); + if (req->getFlags() & FLAG_AUTO_COMPLETE) + { + mRequestHash.erase(req); + req->deleteRequest(); + // check(); + } + unlockData(); + } + else + { + LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("qtpr - retry"); + //put back on queue and try again in 0.1ms + lockData(); + req->setStatus(STATUS_QUEUED); + + unlockData(); + + llassert(!mDataLock->isSelfLocked()); + +#if 0 + // try again on next frame + // NOTE: tried using "post" with a time in the future, but this + // would invariably cause this thread to wait for a long time (10+ ms) + // while work is pending + bool ret = LL::WorkQueue::postMaybe( + mMainQueue, + [=]() + { + LL_PROFILE_ZONE_NAMED("processRequest - retry"); + mRequestQueue.post([=]() + { + LL_PROFILE_ZONE_NAMED("processRequest - retry"); // <-- not redundant, track retry on both queues + processRequest(req); + }); + }); + llassert(ret); +#else + using namespace std::chrono_literals; + auto retry_time = LL::WorkQueue::TimePoint::clock::now() + 16ms; + mRequestQueue.post([=] + { + LL_PROFILE_ZONE_NAMED("processRequest - retry"); + while (LL::WorkQueue::TimePoint::clock::now() < retry_time) + { + std::this_thread::yield(); //note: don't use LLThread::yield here to avoid + } + processRequest(req); + }); +#endif + + } + } + } - S32 pending = getPending(); - return pending; + mIdleThread = TRUE; } // virtual bool LLQueuedThread::runCondition() { // mRunCondition must be locked here - if (mRequestQueue.empty() && mIdleThread) + if (mRequestQueue.size() == 0 && mIdleThread) return false; else return true; @@ -495,18 +500,13 @@ void LLQueuedThread::run() startThread(); mStarted = TRUE; - while (1) + + /*while (1) { + LL_PROFILE_ZONE_SCOPED; // this will block on the condition until runCondition() returns true, the thread is unpaused, or the thread leaves the RUNNING state. checkPause(); - if (isQuitting()) - { - LLTrace::get_thread_recorder()->pushToParent(); - endThread(); - break; - } - mIdleThread = FALSE; threadedUpdate(); @@ -515,12 +515,18 @@ void LLQueuedThread::run() if (pending_work == 0) { + //LL_PROFILE_ZONE_NAMED("LLQueuedThread - sleep"); mIdleThread = TRUE; - ms_sleep(1); + //ms_sleep(1); } //LLThread::yield(); // thread should yield after each request - } + }*/ + mRequestQueue.runUntilClose(); + + endThread(); LL_INFOS() << "LLQueuedThread " << mName << " EXITING." << LL_ENDL; + + } // virtual @@ -540,10 +546,9 @@ void LLQueuedThread::threadedUpdate() //============================================================================ -LLQueuedThread::QueuedRequest::QueuedRequest(LLQueuedThread::handle_t handle, U32 priority, U32 flags) : +LLQueuedThread::QueuedRequest::QueuedRequest(LLQueuedThread::handle_t handle, U32 flags) : LLSimpleHashEntry(handle), mStatus(STATUS_UNKNOWN), - mPriority(priority), mFlags(flags) { } diff --git a/indra/llcommon/llqueuedthread.h b/indra/llcommon/llqueuedthread.h index 5d3f873646..6b82ccc434 100644 --- a/indra/llcommon/llqueuedthread.h +++ b/indra/llcommon/llqueuedthread.h @@ -36,6 +36,7 @@ #include "llthread.h" #include "llsimplehash.h" +#include "workqueue.h" //============================================================================ // Note: ~LLQueuedThread is O(N) N=# of queued threads, assumed to be small @@ -45,15 +46,6 @@ class LL_COMMON_API LLQueuedThread : public LLThread { //------------------------------------------------------------------------ public: - enum priority_t { - PRIORITY_IMMEDIATE = 0x7FFFFFFF, - PRIORITY_URGENT = 0x40000000, - PRIORITY_HIGH = 0x30000000, - PRIORITY_NORMAL = 0x20000000, - PRIORITY_LOW = 0x10000000, - PRIORITY_LOWBITS = 0x0FFFFFFF, - PRIORITY_HIGHBITS = 0x70000000 - }; enum status_t { STATUS_EXPIRED = -1, STATUS_UNKNOWN = 0, @@ -82,28 +74,17 @@ public: virtual ~QueuedRequest(); // use deleteRequest() public: - QueuedRequest(handle_t handle, U32 priority, U32 flags = 0); + QueuedRequest(handle_t handle, U32 flags = 0); status_t getStatus() { return mStatus; } - U32 getPriority() const - { - return mPriority; - } U32 getFlags() const { return mFlags; } - bool higherPriority(const QueuedRequest& second) const - { - if ( mPriority == second.mPriority) - return mHashKey < second.mHashKey; - else - return mPriority > second.mPriority; - } - + protected: status_t setStatus(status_t newstatus) { @@ -121,28 +102,11 @@ public: virtual void finishRequest(bool completed); // Always called from thread after request has completed or aborted virtual void deleteRequest(); // Only method to delete a request - void setPriority(U32 pri) - { - // Only do this on a request that is not in a queued list! - mPriority = pri; - }; - protected: LLAtomicBase mStatus; - U32 mPriority; U32 mFlags; }; -protected: - struct queued_request_less - { - bool operator()(const QueuedRequest* lhs, const QueuedRequest* rhs) const - { - return lhs->higherPriority(*rhs); // higher priority in front of queue (set) - } - }; - - //------------------------------------------------------------------------ public: @@ -167,7 +131,7 @@ private: protected: handle_t generateHandle(); bool addRequest(QueuedRequest* req); - S32 processNextRequest(void); + void processRequest(QueuedRequest* req); void incQueue(); public: @@ -186,7 +150,6 @@ public: status_t getRequestStatus(handle_t handle); void abortRequest(handle_t handle, bool autocomplete); void setFlags(handle_t handle, U32 flags); - void setPriority(handle_t handle, U32 priority); bool completeRequest(handle_t handle); // This is public for support classes like LLWorkerThread, // but generally the methods above should be used. @@ -200,8 +163,10 @@ protected: BOOL mStarted; // required when mThreaded is false to call startThread() from update() LLAtomicBool mIdleThread; // request queue is empty (or we are quitting) and the thread is idle - typedef std::set request_queue_t; - request_queue_t mRequestQueue; + //typedef std::set request_queue_t; + //request_queue_t mRequestQueue; + LL::WorkQueue mRequestQueue; + LL::WorkQueue::weak_t mMainQueue; enum { REQUEST_HASH_SIZE = 512 }; // must be power of 2 typedef LLSimpleHash request_hash_t; diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp index aaa6df325c..b250bc3e1c 100644 --- a/indra/llcommon/lltimer.cpp +++ b/indra/llcommon/lltimer.cpp @@ -64,7 +64,8 @@ LLTimer* LLTimer::sTimer = NULL; #if LL_WINDOWS void ms_sleep(U32 ms) { - Sleep(ms); + LL_PROFILE_ZONE_SCOPED; + std::this_thread::sleep_for(std::chrono::microseconds(ms)); } U32 micro_sleep(U64 us, U32 max_yields) diff --git a/indra/llcommon/llworkerthread.cpp b/indra/llcommon/llworkerthread.cpp index 4b91b2caca..02ce4823b8 100644 --- a/indra/llcommon/llworkerthread.cpp +++ b/indra/llcommon/llworkerthread.cpp @@ -133,11 +133,11 @@ S32 LLWorkerThread::update(F32 max_time_ms) //---------------------------------------------------------------------------- -LLWorkerThread::handle_t LLWorkerThread::addWorkRequest(LLWorkerClass* workerclass, S32 param, U32 priority) +LLWorkerThread::handle_t LLWorkerThread::addWorkRequest(LLWorkerClass* workerclass, S32 param) { handle_t handle = generateHandle(); - WorkRequest* req = new WorkRequest(handle, priority, workerclass, param); + WorkRequest* req = new WorkRequest(handle, workerclass, param); bool res = addRequest(req); if (!res) @@ -160,8 +160,8 @@ void LLWorkerThread::deleteWorker(LLWorkerClass* workerclass) //============================================================================ // Runs on its OWN thread -LLWorkerThread::WorkRequest::WorkRequest(handle_t handle, U32 priority, LLWorkerClass* workerclass, S32 param) : - LLQueuedThread::QueuedRequest(handle, priority), +LLWorkerThread::WorkRequest::WorkRequest(handle_t handle, LLWorkerClass* workerclass, S32 param) : + LLQueuedThread::QueuedRequest(handle), mWorkerClass(workerclass), mParam(param) { @@ -180,6 +180,7 @@ void LLWorkerThread::WorkRequest::deleteRequest() // virtual bool LLWorkerThread::WorkRequest::processRequest() { + LL_PROFILE_ZONE_SCOPED; LLWorkerClass* workerclass = getWorkerClass(); workerclass->setWorking(true); bool complete = workerclass->doWork(getParam()); @@ -190,6 +191,7 @@ bool LLWorkerThread::WorkRequest::processRequest() // virtual void LLWorkerThread::WorkRequest::finishRequest(bool completed) { + LL_PROFILE_ZONE_SCOPED; LLWorkerClass* workerclass = getWorkerClass(); workerclass->finishWork(getParam(), completed); U32 flags = LLWorkerClass::WCF_WORK_FINISHED | (completed ? 0 : LLWorkerClass::WCF_WORK_ABORTED); @@ -203,7 +205,6 @@ LLWorkerClass::LLWorkerClass(LLWorkerThread* workerthread, const std::string& na : mWorkerThread(workerthread), mWorkerClassName(name), mRequestHandle(LLWorkerThread::nullHandle()), - mRequestPriority(LLWorkerThread::PRIORITY_NORMAL), mMutex(), mWorkFlags(0) { @@ -292,7 +293,7 @@ bool LLWorkerClass::yield() //---------------------------------------------------------------------------- // calls startWork, adds doWork() to queue -void LLWorkerClass::addWork(S32 param, U32 priority) +void LLWorkerClass::addWork(S32 param) { mMutex.lock(); llassert_always(!(mWorkFlags & (WCF_WORKING|WCF_HAVE_WORK))); @@ -306,7 +307,7 @@ void LLWorkerClass::addWork(S32 param, U32 priority) startWork(param); clearFlags(WCF_WORK_FINISHED|WCF_WORK_ABORTED); setFlags(WCF_HAVE_WORK); - mRequestHandle = mWorkerThread->addWorkRequest(this, param, priority); + mRequestHandle = mWorkerThread->addWorkRequest(this, param); mMutex.unlock(); } @@ -321,7 +322,6 @@ void LLWorkerClass::abortWork(bool autocomplete) if (mRequestHandle != LLWorkerThread::nullHandle()) { mWorkerThread->abortRequest(mRequestHandle, autocomplete); - mWorkerThread->setPriority(mRequestHandle, LLQueuedThread::PRIORITY_IMMEDIATE); setFlags(WCF_ABORT_REQUESTED); } mMutex.unlock(); @@ -395,16 +395,5 @@ void LLWorkerClass::scheduleDelete() } } -void LLWorkerClass::setPriority(U32 priority) -{ - mMutex.lock(); - if (mRequestHandle != LLWorkerThread::nullHandle() && mRequestPriority != priority) - { - mRequestPriority = priority; - mWorkerThread->setPriority(mRequestHandle, priority); - } - mMutex.unlock(); -} - //============================================================================ diff --git a/indra/llcommon/llworkerthread.h b/indra/llcommon/llworkerthread.h index 0387e75c65..06bbb7369e 100644 --- a/indra/llcommon/llworkerthread.h +++ b/indra/llcommon/llworkerthread.h @@ -56,7 +56,7 @@ public: virtual ~WorkRequest(); // use deleteRequest() public: - WorkRequest(handle_t handle, U32 priority, LLWorkerClass* workerclass, S32 param); + WorkRequest(handle_t handle, LLWorkerClass* workerclass, S32 param); S32 getParam() { @@ -90,7 +90,7 @@ public: /*virtual*/ S32 update(F32 max_time_ms); - handle_t addWorkRequest(LLWorkerClass* workerclass, S32 param, U32 priority = PRIORITY_NORMAL); + handle_t addWorkRequest(LLWorkerClass* workerclass, S32 param); S32 getNumDeletes() { return (S32)mDeleteList.size(); } // debug @@ -151,10 +151,6 @@ public: bool isWorking() { return getFlags(WCF_WORKING); } bool wasAborted() { return getFlags(WCF_ABORT_REQUESTED); } - // setPriority(): changes the priority of a request - void setPriority(U32 priority); - U32 getPriority() { return mRequestPriority; } - const std::string& getName() const { return mWorkerClassName; } protected: @@ -169,7 +165,7 @@ protected: void setWorkerThread(LLWorkerThread* workerthread); // addWork(): calls startWork, adds doWork() to queue - void addWork(S32 param, U32 priority = LLWorkerThread::PRIORITY_NORMAL); + void addWork(S32 param); // abortWork(): requests that work be aborted void abortWork(bool autocomplete); @@ -193,7 +189,6 @@ protected: LLWorkerThread* mWorkerThread; std::string mWorkerClassName; handle_t mRequestHandle; - U32 mRequestPriority; // last priority set private: LLMutex mMutex; diff --git a/indra/llcommon/workqueue.h b/indra/llcommon/workqueue.h index 96574a18b9..46f7363830 100644 --- a/indra/llcommon/workqueue.h +++ b/indra/llcommon/workqueue.h @@ -161,10 +161,16 @@ namespace LL void postEvery(const std::chrono::duration& interval, CALLABLE&& callable); + template + bool tryPost(const TimePoint& time, CALLABLE&& callable) + { + return mQueue.tryPush(TimedWork(time, std::move(callable))); + } + template bool tryPost(CALLABLE&& callable) { - return mQueue.tryPush(TimedWork(TimePoint::clock::now(), std::move(callable))); + return mQueue.tryPost(TimePoint::clock::now(), std::move(callable)); } /*------------------------- handshake API --------------------------*/ diff --git a/indra/llcorehttp/_httplibcurl.cpp b/indra/llcorehttp/_httplibcurl.cpp index 975ce8a4d5..bd0ac740db 100644 --- a/indra/llcorehttp/_httplibcurl.cpp +++ b/indra/llcorehttp/_httplibcurl.cpp @@ -113,6 +113,7 @@ void HttpLibcurl::shutdown() void HttpLibcurl::start(int policy_count) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; llassert_always(policy_count <= HTTP_POLICY_CLASS_LIMIT); llassert_always(! mMultiHandles); // One-time call only @@ -143,6 +144,7 @@ void HttpLibcurl::start(int policy_count) // sleep otherwise ask for a normal polling interval. HttpService::ELoopSpeed HttpLibcurl::processTransport() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; HttpService::ELoopSpeed ret(HttpService::REQUEST_SLEEP); // Give libcurl some cycles to do I/O & callbacks @@ -168,6 +170,7 @@ HttpService::ELoopSpeed HttpLibcurl::processTransport() CURLMcode status(CURLM_CALL_MULTI_PERFORM); do { + LL_PROFILE_ZONE_NAMED_CATEGORY_NETWORK("httppt - curl_multi_perform"); running = 0; status = curl_multi_perform(mMultiHandles[policy_class], &running); } @@ -176,31 +179,34 @@ HttpService::ELoopSpeed HttpLibcurl::processTransport() // Run completion on anything done CURLMsg * msg(NULL); int msgs_in_queue(0); - while ((msg = curl_multi_info_read(mMultiHandles[policy_class], &msgs_in_queue))) - { - if (CURLMSG_DONE == msg->msg) - { - CURL * handle(msg->easy_handle); - CURLcode result(msg->data.result); + { + LL_PROFILE_ZONE_NAMED_CATEGORY_NETWORK("httppt - curl_multi_info_read"); + while ((msg = curl_multi_info_read(mMultiHandles[policy_class], &msgs_in_queue))) + { + if (CURLMSG_DONE == msg->msg) + { + CURL* handle(msg->easy_handle); + CURLcode result(msg->data.result); - completeRequest(mMultiHandles[policy_class], handle, result); - handle = NULL; // No longer valid on return - ret = HttpService::NORMAL; // If anything completes, we may have a free slot. - // Turning around quickly reduces connection gap by 7-10mS. - } - else if (CURLMSG_NONE == msg->msg) - { - // Ignore this... it shouldn't mean anything. - ; - } - else - { - LL_WARNS_ONCE(LOG_CORE) << "Unexpected message from libcurl. Msg code: " - << msg->msg - << LL_ENDL; - } - msgs_in_queue = 0; - } + completeRequest(mMultiHandles[policy_class], handle, result); + handle = NULL; // No longer valid on return + ret = HttpService::NORMAL; // If anything completes, we may have a free slot. + // Turning around quickly reduces connection gap by 7-10mS. + } + else if (CURLMSG_NONE == msg->msg) + { + // Ignore this... it shouldn't mean anything. + ; + } + else + { + LL_WARNS_ONCE(LOG_CORE) << "Unexpected message from libcurl. Msg code: " + << msg->msg + << LL_ENDL; + } + msgs_in_queue = 0; + } + } } if (! mActiveOps.empty()) @@ -214,6 +220,7 @@ HttpService::ELoopSpeed HttpLibcurl::processTransport() // Caller has provided us with a ref count on op. void HttpLibcurl::addOp(const HttpOpRequest::ptr_t &op) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; llassert_always(op->mReqPolicy < mPolicyCount); llassert_always(mMultiHandles[op->mReqPolicy] != NULL); @@ -257,6 +264,7 @@ void HttpLibcurl::addOp(const HttpOpRequest::ptr_t &op) // method to kill the request. bool HttpLibcurl::cancel(HttpHandle handle) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; HttpOpRequest::ptr_t op = HttpOpRequest::fromHandle(handle); active_set_t::iterator it(mActiveOps.find(op)); if (mActiveOps.end() == it) @@ -282,6 +290,7 @@ bool HttpLibcurl::cancel(HttpHandle handle) // op to the reply queue with refcount intact. void HttpLibcurl::cancelRequest(const HttpOpRequest::ptr_t &op) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; // Deactivate request op->mCurlActive = false; @@ -308,6 +317,7 @@ void HttpLibcurl::cancelRequest(const HttpOpRequest::ptr_t &op) // Keep them synchronized as necessary. bool HttpLibcurl::completeRequest(CURLM * multi_handle, CURL * handle, CURLcode status) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; HttpHandle ophandle(NULL); CURLcode ccode(CURLE_OK); @@ -445,6 +455,7 @@ int HttpLibcurl::getActiveCountInClass(int policy_class) const void HttpLibcurl::policyUpdated(int policy_class) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; if (policy_class < 0 || policy_class >= mPolicyCount || ! mMultiHandles) { return; diff --git a/indra/llcorehttp/_httpoperation.cpp b/indra/llcorehttp/_httpoperation.cpp index 3fc4e28910..3b64018132 100644 --- a/indra/llcorehttp/_httpoperation.cpp +++ b/indra/llcorehttp/_httpoperation.cpp @@ -62,7 +62,6 @@ HttpOperation::HttpOperation(): mReplyQueue(), mUserHandler(), mReqPolicy(HttpRequest::DEFAULT_POLICY_ID), - mReqPriority(0U), mTracing(HTTP_TRACE_OFF), mMyHandle(LLCORE_HTTP_HANDLE_INVALID) { diff --git a/indra/llcorehttp/_httpoperation.h b/indra/llcorehttp/_httpoperation.h index 1a75921c09..8c1364bab4 100644 --- a/indra/llcorehttp/_httpoperation.h +++ b/indra/llcorehttp/_httpoperation.h @@ -181,7 +181,6 @@ protected: public: // Request Data HttpRequest::policy_t mReqPolicy; - HttpRequest::priority_t mReqPriority; // Reply Data HttpStatus mStatus; diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp index ba31290c24..d60eb6c95f 100644 --- a/indra/llcorehttp/_httpoprequest.cpp +++ b/indra/llcorehttp/_httpoprequest.cpp @@ -200,6 +200,7 @@ HttpOpRequest::~HttpOpRequest() void HttpOpRequest::stageFromRequest(HttpService * service) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; HttpOpRequest::ptr_t self(boost::dynamic_pointer_cast(shared_from_this())); service->getPolicy().addOp(self); // transfers refcount } @@ -207,6 +208,7 @@ void HttpOpRequest::stageFromRequest(HttpService * service) void HttpOpRequest::stageFromReady(HttpService * service) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; HttpOpRequest::ptr_t self(boost::dynamic_pointer_cast(shared_from_this())); service->getTransport().addOp(self); // transfers refcount } @@ -214,6 +216,7 @@ void HttpOpRequest::stageFromReady(HttpService * service) void HttpOpRequest::stageFromActive(HttpService * service) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; if (mReplyLength) { // If non-zero, we received and processed a Content-Range @@ -250,6 +253,7 @@ void HttpOpRequest::stageFromActive(HttpService * service) void HttpOpRequest::visitNotifier(HttpRequest * request) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; if (mUserHandler) { HttpResponse * response = new HttpResponse(); @@ -292,6 +296,7 @@ void HttpOpRequest::visitNotifier(HttpRequest * request) HttpStatus HttpOpRequest::cancel() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; mStatus = HttpStatus(HttpStatus::LLCORE, HE_OP_CANCELED); addAsReply(); @@ -301,12 +306,12 @@ HttpStatus HttpOpRequest::cancel() HttpStatus HttpOpRequest::setupGet(HttpRequest::policy_t policy_id, - HttpRequest::priority_t priority, const std::string & url, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers) { - setupCommon(policy_id, priority, url, NULL, options, headers); + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; + setupCommon(policy_id, url, NULL, options, headers); mReqMethod = HOR_GET; return HttpStatus(); @@ -314,14 +319,14 @@ HttpStatus HttpOpRequest::setupGet(HttpRequest::policy_t policy_id, HttpStatus HttpOpRequest::setupGetByteRange(HttpRequest::policy_t policy_id, - HttpRequest::priority_t priority, const std::string & url, size_t offset, size_t len, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers) { - setupCommon(policy_id, priority, url, NULL, options, headers); + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; + setupCommon(policy_id, url, NULL, options, headers); mReqMethod = HOR_GET; mReqOffset = offset; mReqLength = len; @@ -335,13 +340,13 @@ HttpStatus HttpOpRequest::setupGetByteRange(HttpRequest::policy_t policy_id, HttpStatus HttpOpRequest::setupPost(HttpRequest::policy_t policy_id, - HttpRequest::priority_t priority, const std::string & url, BufferArray * body, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers) { - setupCommon(policy_id, priority, url, body, options, headers); + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; + setupCommon(policy_id, url, body, options, headers); mReqMethod = HOR_POST; return HttpStatus(); @@ -349,13 +354,13 @@ HttpStatus HttpOpRequest::setupPost(HttpRequest::policy_t policy_id, HttpStatus HttpOpRequest::setupPut(HttpRequest::policy_t policy_id, - HttpRequest::priority_t priority, const std::string & url, BufferArray * body, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers) { - setupCommon(policy_id, priority, url, body, options, headers); + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; + setupCommon(policy_id, url, body, options, headers); mReqMethod = HOR_PUT; return HttpStatus(); @@ -363,12 +368,12 @@ HttpStatus HttpOpRequest::setupPut(HttpRequest::policy_t policy_id, HttpStatus HttpOpRequest::setupDelete(HttpRequest::policy_t policy_id, - HttpRequest::priority_t priority, const std::string & url, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers) { - setupCommon(policy_id, priority, url, NULL, options, headers); + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; + setupCommon(policy_id, url, NULL, options, headers); mReqMethod = HOR_DELETE; return HttpStatus(); @@ -376,13 +381,13 @@ HttpStatus HttpOpRequest::setupDelete(HttpRequest::policy_t policy_id, HttpStatus HttpOpRequest::setupPatch(HttpRequest::policy_t policy_id, - HttpRequest::priority_t priority, const std::string & url, BufferArray * body, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers) { - setupCommon(policy_id, priority, url, body, options, headers); + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; + setupCommon(policy_id, url, body, options, headers); mReqMethod = HOR_PATCH; return HttpStatus(); @@ -390,12 +395,12 @@ HttpStatus HttpOpRequest::setupPatch(HttpRequest::policy_t policy_id, HttpStatus HttpOpRequest::setupCopy(HttpRequest::policy_t policy_id, - HttpRequest::priority_t priority, const std::string & url, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t &headers) { - setupCommon(policy_id, priority, url, NULL, options, headers); + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; + setupCommon(policy_id, url, NULL, options, headers); mReqMethod = HOR_COPY; return HttpStatus(); @@ -403,12 +408,12 @@ HttpStatus HttpOpRequest::setupCopy(HttpRequest::policy_t policy_id, HttpStatus HttpOpRequest::setupMove(HttpRequest::policy_t policy_id, - HttpRequest::priority_t priority, const std::string & url, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t &headers) { - setupCommon(policy_id, priority, url, NULL, options, headers); + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; + setupCommon(policy_id, url, NULL, options, headers); mReqMethod = HOR_MOVE; return HttpStatus(); @@ -416,15 +421,14 @@ HttpStatus HttpOpRequest::setupMove(HttpRequest::policy_t policy_id, void HttpOpRequest::setupCommon(HttpRequest::policy_t policy_id, - HttpRequest::priority_t priority, const std::string & url, BufferArray * body, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; mProcFlags = 0U; mReqPolicy = policy_id; - mReqPriority = priority; mReqURL = url; if (body) { @@ -465,6 +469,7 @@ void HttpOpRequest::setupCommon(HttpRequest::policy_t policy_id, // *TODO: Move this to _httplibcurl where it belongs. HttpStatus HttpOpRequest::prepareRequest(HttpService * service) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; // Scrub transport and result data for retried op case mCurlActive = false; mCurlHandle = NULL; @@ -773,6 +778,7 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service) size_t HttpOpRequest::writeCallback(void * data, size_t size, size_t nmemb, void * userdata) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle(userdata)); if (! op->mReplyBody) @@ -788,6 +794,7 @@ size_t HttpOpRequest::writeCallback(void * data, size_t size, size_t nmemb, void size_t HttpOpRequest::readCallback(void * data, size_t size, size_t nmemb, void * userdata) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle(userdata)); if (! op->mReqBody) @@ -819,6 +826,7 @@ size_t HttpOpRequest::readCallback(void * data, size_t size, size_t nmemb, void int HttpOpRequest::seekCallback(void *userdata, curl_off_t offset, int origin) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle(userdata)); if (!op->mReqBody) @@ -850,6 +858,7 @@ int HttpOpRequest::seekCallback(void *userdata, curl_off_t offset, int origin) size_t HttpOpRequest::headerCallback(void * data, size_t size, size_t nmemb, void * userdata) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; static const char status_line[] = "HTTP/"; static const size_t status_line_len = sizeof(status_line) - 1; static const char con_ran_line[] = "content-range"; @@ -999,6 +1008,7 @@ size_t HttpOpRequest::headerCallback(void * data, size_t size, size_t nmemb, voi CURLcode HttpOpRequest::curlSslCtxCallback(CURL *curl, void *sslctx, void *userdata) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle(userdata)); if (op->mCallbackSSLVerify) @@ -1025,6 +1035,7 @@ CURLcode HttpOpRequest::curlSslCtxCallback(CURL *curl, void *sslctx, void *userd int HttpOpRequest::sslCertVerifyCallback(X509_STORE_CTX *ctx, void *param) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle(param)); if (op->mCallbackSSLVerify) @@ -1037,6 +1048,7 @@ int HttpOpRequest::sslCertVerifyCallback(X509_STORE_CTX *ctx, void *param) int HttpOpRequest::debugCallback(CURL * handle, curl_infotype info, char * buffer, size_t len, void * userdata) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle(userdata)); std::string safe_line; diff --git a/indra/llcorehttp/_httpoprequest.h b/indra/llcorehttp/_httpoprequest.h index cdbe350785..ec84822cf4 100644 --- a/indra/llcorehttp/_httpoprequest.h +++ b/indra/llcorehttp/_httpoprequest.h @@ -105,13 +105,11 @@ public: /// Threading: called by application thread /// HttpStatus setupGet(HttpRequest::policy_t policy_id, - HttpRequest::priority_t priority, const std::string & url, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers); HttpStatus setupGetByteRange(HttpRequest::policy_t policy_id, - HttpRequest::priority_t priority, const std::string & url, size_t offset, size_t len, @@ -119,40 +117,34 @@ public: const HttpHeaders::ptr_t & headers); HttpStatus setupPost(HttpRequest::policy_t policy_id, - HttpRequest::priority_t priority, const std::string & url, BufferArray * body, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers); HttpStatus setupPut(HttpRequest::policy_t policy_id, - HttpRequest::priority_t priority, const std::string & url, BufferArray * body, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers); HttpStatus setupDelete(HttpRequest::policy_t policy_id, - HttpRequest::priority_t priority, const std::string & url, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers); HttpStatus setupPatch(HttpRequest::policy_t policy_id, - HttpRequest::priority_t priority, const std::string & url, BufferArray * body, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers); HttpStatus setupCopy(HttpRequest::policy_t policy_id, - HttpRequest::priority_t priority, const std::string & url, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers); HttpStatus setupMove(HttpRequest::policy_t policy_id, - HttpRequest::priority_t priority, const std::string & url, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers); @@ -172,7 +164,6 @@ protected: // Threading: called by application thread // void setupCommon(HttpRequest::policy_t policy_id, - HttpRequest::priority_t priority, const std::string & url, BufferArray * body, const HttpOptions::ptr_t & options, @@ -239,19 +230,6 @@ public: -/// HttpOpRequestCompare isn't an operation but a uniform comparison -/// functor for STL containers that order by priority. Mainly -/// used for the ready queue container but defined here. -class HttpOpRequestCompare -{ -public: - bool operator()(const HttpOpRequest * lhs, const HttpOpRequest * rhs) - { - return lhs->mReqPriority > rhs->mReqPriority; - } -}; // end class HttpOpRequestCompare - - // --------------------------------------- // Free functions // --------------------------------------- diff --git a/indra/llcorehttp/_httpopsetpriority.cpp b/indra/llcorehttp/_httpopsetpriority.cpp index d48c7a0b7d..b99b4e9e4a 100644 --- a/indra/llcorehttp/_httpopsetpriority.cpp +++ b/indra/llcorehttp/_httpopsetpriority.cpp @@ -24,6 +24,7 @@ * $/LicenseInfo$ */ +#if 0 // DEPRECATED #include "_httpopsetpriority.h" #include "httpresponse.h" @@ -61,3 +62,5 @@ void HttpOpSetPriority::stageFromRequest(HttpService * service) } // end namespace LLCore + +#endif diff --git a/indra/llcorehttp/_httpopsetpriority.h b/indra/llcorehttp/_httpopsetpriority.h index 43e2aa081b..fd543f37cc 100644 --- a/indra/llcorehttp/_httpopsetpriority.h +++ b/indra/llcorehttp/_httpopsetpriority.h @@ -27,7 +27,7 @@ #ifndef _LLCORE_HTTP_SETPRIORITY_H_ #define _LLCORE_HTTP_SETPRIORITY_H_ - +#if 0 // DEPRECATED #include "httpcommon.h" #include "httprequest.h" #include "_httpoperation.h" @@ -49,7 +49,7 @@ namespace LLCore class HttpOpSetPriority : public HttpOperation { public: - HttpOpSetPriority(HttpHandle handle, HttpRequest::priority_t priority); + HttpOpSetPriority(HttpHandle handle); virtual ~HttpOpSetPriority(); @@ -63,10 +63,10 @@ public: protected: // Request Data HttpHandle mHandle; - HttpRequest::priority_t mPriority; }; // end class HttpOpSetPriority } // end namespace LLCore +#endif #endif // _LLCORE_HTTP_SETPRIORITY_H_ diff --git a/indra/llcorehttp/_httppolicy.cpp b/indra/llcorehttp/_httppolicy.cpp index 885f0ed61d..29f50c1693 100644 --- a/indra/llcorehttp/_httppolicy.cpp +++ b/indra/llcorehttp/_httppolicy.cpp @@ -330,37 +330,6 @@ HttpService::ELoopSpeed HttpPolicy::processReadyQueue() return result; } - -bool HttpPolicy::changePriority(HttpHandle handle, HttpRequest::priority_t priority) -{ - for (int policy_class(0); policy_class < mClasses.size(); ++policy_class) - { - ClassState & state(*mClasses[policy_class]); - // We don't scan retry queue because a priority change there - // is meaningless. The request will be issued based on retry - // intervals not priority value, which is now moot. - - // Scan ready queue for requests that match policy - HttpReadyQueue::container_type & c(state.mReadyQueue.get_container()); - for (HttpReadyQueue::container_type::iterator iter(c.begin()); c.end() != iter;) - { - HttpReadyQueue::container_type::iterator cur(iter++); - - if ((*cur)->getHandle() == handle) - { - HttpOpRequest::ptr_t op(*cur); - c.erase(cur); // All iterators are now invalidated - op->mReqPriority = priority; - state.mReadyQueue.push(op); // Re-insert using adapter class - return true; - } - } - } - - return false; -} - - bool HttpPolicy::cancel(HttpHandle handle) { for (int policy_class(0); policy_class < mClasses.size(); ++policy_class) diff --git a/indra/llcorehttp/_httppolicy.h b/indra/llcorehttp/_httppolicy.h index 3c4126e14b..0b8806a3e2 100644 --- a/indra/llcorehttp/_httppolicy.h +++ b/indra/llcorehttp/_httppolicy.h @@ -110,12 +110,6 @@ public: /// Threading: called by worker thread void retryOp(const opReqPtr_t &); - /// Attempt to change the priority of an earlier request. - /// Request that Shadows HttpService's method - /// - /// Threading: called by worker thread - bool changePriority(HttpHandle handle, HttpRequest::priority_t priority); - /// Attempt to cancel a previous request. /// Shadows HttpService's method as well /// diff --git a/indra/llcorehttp/_httpservice.cpp b/indra/llcorehttp/_httpservice.cpp index 56f52f1b09..294acd7f63 100644 --- a/indra/llcorehttp/_httpservice.cpp +++ b/indra/llcorehttp/_httpservice.cpp @@ -80,6 +80,7 @@ HttpService::HttpService() HttpService::~HttpService() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; mExitRequested = 1U; if (RUNNING == sState) { @@ -131,6 +132,7 @@ HttpService::~HttpService() void HttpService::init(HttpRequestQueue * queue) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; llassert_always(! sInstance); llassert_always(NOT_INITIALIZED == sState); sInstance = new HttpService(); @@ -145,6 +147,7 @@ void HttpService::init(HttpRequestQueue * queue) void HttpService::term() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; if (sInstance) { if (RUNNING == sState && sInstance->mThread) @@ -196,6 +199,7 @@ bool HttpService::isStopped() /// Threading: callable by consumer thread *once*. void HttpService::startThread() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; llassert_always(! mThread || STOPPED == sState); llassert_always(INITIALIZED == sState || STOPPED == sState); @@ -220,22 +224,6 @@ void HttpService::stopRequested() } -/// Threading: callable by worker thread. -bool HttpService::changePriority(HttpHandle handle, HttpRequest::priority_t priority) -{ - bool found(false); - - // Skip the request queue as we currently don't leave earlier - // requests sitting there. Start with the ready queue... - found = mPolicy->changePriority(handle, priority); - - // If not there, we could try the transport/active queue but priority - // doesn't really have much effect there so we don't waste cycles. - - return found; -} - - /// Try to find the given request handle on any of the request /// queues and cancel the operation. /// @@ -244,6 +232,7 @@ bool HttpService::changePriority(HttpHandle handle, HttpRequest::priority_t prio /// Threading: callable by worker thread. bool HttpService::cancel(HttpHandle handle) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; bool canceled(false); // Request can't be on request queue so skip that. @@ -264,6 +253,7 @@ bool HttpService::cancel(HttpHandle handle) /// Threading: callable by worker thread. void HttpService::shutdown() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; // Disallow future enqueue of requests mRequestQueue->stopQueue(); @@ -293,6 +283,8 @@ void HttpService::shutdown() // requested to stop. void HttpService::threadRun(LLCoreInt::HttpThread * thread) { + LL_PROFILER_SET_THREAD_NAME("HttpService"); + boost::this_thread::disable_interruption di; LLThread::registerThreadID(); @@ -300,6 +292,7 @@ void HttpService::threadRun(LLCoreInt::HttpThread * thread) ELoopSpeed loop(REQUEST_SLEEP); while (! mExitRequested) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; try { loop = processRequestQueue(loop); @@ -344,6 +337,7 @@ void HttpService::threadRun(LLCoreInt::HttpThread * thread) HttpService::ELoopSpeed HttpService::processRequestQueue(ELoopSpeed loop) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; HttpRequestQueue::OpContainer ops; const bool wait_for_req(REQUEST_SLEEP == loop); @@ -384,6 +378,7 @@ HttpService::ELoopSpeed HttpService::processRequestQueue(ELoopSpeed loop) HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass, long * ret_value) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; if (opt < HttpRequest::PO_CONNECTION_LIMIT // option must be in range || opt >= HttpRequest::PO_LAST // ditto || (! sOptionDesc[opt].mIsLong) // datatype is long @@ -416,6 +411,7 @@ HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequ HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass, std::string * ret_value) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG); if (opt < HttpRequest::PO_CONNECTION_LIMIT // option must be in range @@ -443,6 +439,7 @@ HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequ HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass, HttpRequest::policyCallback_t * ret_value) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG); if (opt < HttpRequest::PO_CONNECTION_LIMIT // option must be in range @@ -472,6 +469,7 @@ HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequ HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass, long value, long * ret_value) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG); if (opt < HttpRequest::PO_CONNECTION_LIMIT // option must be in range @@ -517,6 +515,7 @@ HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequ HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass, const std::string & value, std::string * ret_value) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG); if (opt < HttpRequest::PO_CONNECTION_LIMIT // option must be in range @@ -548,6 +547,7 @@ HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequ HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass, HttpRequest::policyCallback_t value, HttpRequest::policyCallback_t * ret_value) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG); if (opt < HttpRequest::PO_CONNECTION_LIMIT // option must be in range diff --git a/indra/llcorehttp/_httpservice.h b/indra/llcorehttp/_httpservice.h index d0c37ac195..551a718f20 100644 --- a/indra/llcorehttp/_httpservice.h +++ b/indra/llcorehttp/_httpservice.h @@ -146,15 +146,6 @@ public: /// Threading: callable by worker thread. void shutdown(); - /// Try to find the given request handle on any of the request - /// queues and reset the priority (and queue position) of the - /// request if found. - /// - /// @return True if the request was found somewhere. - /// - /// Threading: callable by worker thread. - bool changePriority(HttpHandle handle, HttpRequest::priority_t priority); - /// Try to find the given request handle on any of the request /// queues and cancel the operation. /// diff --git a/indra/llcorehttp/httprequest.cpp b/indra/llcorehttp/httprequest.cpp index 2687f77217..de3854a101 100644 --- a/indra/llcorehttp/httprequest.cpp +++ b/indra/llcorehttp/httprequest.cpp @@ -32,7 +32,6 @@ #include "_httppolicy.h" #include "_httpoperation.h" #include "_httpoprequest.h" -#include "_httpopsetpriority.h" #include "_httpopcancel.h" #include "_httpopsetget.h" @@ -183,16 +182,16 @@ HttpStatus HttpRequest::getStatus() const HttpHandle HttpRequest::requestGet(policy_t policy_id, - priority_t priority, const std::string & url, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers, HttpHandler::ptr_t user_handler) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; HttpStatus status; HttpOpRequest::ptr_t op(new HttpOpRequest()); - if (! (status = op->setupGet(policy_id, priority, url, options, headers))) + if (! (status = op->setupGet(policy_id, url, options, headers))) { mLastReqStatus = status; return LLCORE_HTTP_HANDLE_INVALID; @@ -210,7 +209,6 @@ HttpHandle HttpRequest::requestGet(policy_t policy_id, HttpHandle HttpRequest::requestGetByteRange(policy_t policy_id, - priority_t priority, const std::string & url, size_t offset, size_t len, @@ -218,10 +216,11 @@ HttpHandle HttpRequest::requestGetByteRange(policy_t policy_id, const HttpHeaders::ptr_t & headers, HttpHandler::ptr_t user_handler) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; HttpStatus status; HttpOpRequest::ptr_t op(new HttpOpRequest()); - if (! (status = op->setupGetByteRange(policy_id, priority, url, offset, len, options, headers))) + if (! (status = op->setupGetByteRange(policy_id, url, offset, len, options, headers))) { mLastReqStatus = status; return LLCORE_HTTP_HANDLE_INVALID; @@ -239,7 +238,6 @@ HttpHandle HttpRequest::requestGetByteRange(policy_t policy_id, HttpHandle HttpRequest::requestPost(policy_t policy_id, - priority_t priority, const std::string & url, BufferArray * body, const HttpOptions::ptr_t & options, @@ -249,7 +247,7 @@ HttpHandle HttpRequest::requestPost(policy_t policy_id, HttpStatus status; HttpOpRequest::ptr_t op(new HttpOpRequest()); - if (! (status = op->setupPost(policy_id, priority, url, body, options, headers))) + if (! (status = op->setupPost(policy_id, url, body, options, headers))) { mLastReqStatus = status; return LLCORE_HTTP_HANDLE_INVALID; @@ -267,7 +265,6 @@ HttpHandle HttpRequest::requestPost(policy_t policy_id, HttpHandle HttpRequest::requestPut(policy_t policy_id, - priority_t priority, const std::string & url, BufferArray * body, const HttpOptions::ptr_t & options, @@ -277,7 +274,7 @@ HttpHandle HttpRequest::requestPut(policy_t policy_id, HttpStatus status; HttpOpRequest::ptr_t op (new HttpOpRequest()); - if (! (status = op->setupPut(policy_id, priority, url, body, options, headers))) + if (! (status = op->setupPut(policy_id, url, body, options, headers))) { mLastReqStatus = status; return LLCORE_HTTP_HANDLE_INVALID; @@ -294,7 +291,6 @@ HttpHandle HttpRequest::requestPut(policy_t policy_id, } HttpHandle HttpRequest::requestDelete(policy_t policy_id, - priority_t priority, const std::string & url, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers, @@ -303,7 +299,7 @@ HttpHandle HttpRequest::requestDelete(policy_t policy_id, HttpStatus status; HttpOpRequest::ptr_t op(new HttpOpRequest()); - if (!(status = op->setupDelete(policy_id, priority, url, options, headers))) + if (!(status = op->setupDelete(policy_id, url, options, headers))) { mLastReqStatus = status; return LLCORE_HTTP_HANDLE_INVALID; @@ -320,7 +316,6 @@ HttpHandle HttpRequest::requestDelete(policy_t policy_id, } HttpHandle HttpRequest::requestPatch(policy_t policy_id, - priority_t priority, const std::string & url, BufferArray * body, const HttpOptions::ptr_t & options, @@ -330,7 +325,7 @@ HttpHandle HttpRequest::requestPatch(policy_t policy_id, HttpStatus status; HttpOpRequest::ptr_t op (new HttpOpRequest()); - if (!(status = op->setupPatch(policy_id, priority, url, body, options, headers))) + if (!(status = op->setupPatch(policy_id, url, body, options, headers))) { mLastReqStatus = status; return LLCORE_HTTP_HANDLE_INVALID; @@ -347,7 +342,6 @@ HttpHandle HttpRequest::requestPatch(policy_t policy_id, } HttpHandle HttpRequest::requestCopy(policy_t policy_id, - priority_t priority, const std::string & url, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers, @@ -356,7 +350,7 @@ HttpHandle HttpRequest::requestCopy(policy_t policy_id, HttpStatus status; HttpOpRequest::ptr_t op(new HttpOpRequest()); - if (!(status = op->setupCopy(policy_id, priority, url, options, headers))) + if (!(status = op->setupCopy(policy_id, url, options, headers))) { mLastReqStatus = status; return LLCORE_HTTP_HANDLE_INVALID; @@ -374,7 +368,6 @@ HttpHandle HttpRequest::requestCopy(policy_t policy_id, } HttpHandle HttpRequest::requestMove(policy_t policy_id, - priority_t priority, const std::string & url, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers, @@ -383,7 +376,7 @@ HttpHandle HttpRequest::requestMove(policy_t policy_id, HttpStatus status; HttpOpRequest::ptr_t op (new HttpOpRequest()); - if (!(status = op->setupMove(policy_id, priority, url, options, headers))) + if (!(status = op->setupMove(policy_id, url, options, headers))) { mLastReqStatus = status; return LLCORE_HTTP_HANDLE_INVALID; @@ -483,24 +476,6 @@ HttpHandle HttpRequest::requestCancel(HttpHandle request, HttpHandler::ptr_t use } -HttpHandle HttpRequest::requestSetPriority(HttpHandle request, priority_t priority, - HttpHandler::ptr_t handler) -{ - HttpStatus status; - - HttpOperation::ptr_t op (new HttpOpSetPriority(request, priority)); - op->setReplyPath(mReplyQueue, handler); - if (! (status = mRequestQueue->addOp(op))) // transfers refcount - { - mLastReqStatus = status; - return LLCORE_HTTP_HANDLE_INVALID; - } - - mLastReqStatus = status; - return op->getHandle(); -} - - // ==================================== // Utility Methods // ==================================== diff --git a/indra/llcorehttp/httprequest.h b/indra/llcorehttp/httprequest.h index a418eb6a7a..ca4b9e92bc 100644 --- a/indra/llcorehttp/httprequest.h +++ b/indra/llcorehttp/httprequest.h @@ -95,7 +95,6 @@ private: public: typedef unsigned int policy_t; - typedef unsigned int priority_t; typedef boost::shared_ptr ptr_t; typedef boost::weak_ptr wptr_t; @@ -316,8 +315,6 @@ public: /// /// @param policy_id Default or user-defined policy class under /// which this request is to be serviced. - /// @param priority Standard priority scheme inherited from - /// Indra code base (U32-type scheme). /// @param url URL with any encoded query parameters to /// be accessed. /// @param options Optional instance of an HttpOptions object @@ -346,7 +343,6 @@ public: /// case, @see getStatus() will return more info. /// HttpHandle requestGet(policy_t policy_id, - priority_t priority, const std::string & url, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers, @@ -377,7 +373,6 @@ public: /// - Referer: /// /// @param policy_id @see requestGet() - /// @param priority " /// @param url " /// @param offset Offset of first byte into resource to be returned. /// @param len Count of bytes to be returned @@ -387,7 +382,6 @@ public: /// @return " /// HttpHandle requestGetByteRange(policy_t policy_id, - priority_t priority, const std::string & url, size_t offset, size_t len, @@ -418,7 +412,6 @@ public: /// - Expect: /// /// @param policy_id @see requestGet() - /// @param priority " /// @param url " /// @param body Byte stream to be sent as the body. No /// further encoding or escaping will be done @@ -429,7 +422,6 @@ public: /// @return " /// HttpHandle requestPost(policy_t policy_id, - priority_t priority, const std::string & url, BufferArray * body, const HttpOptions::ptr_t & options, @@ -459,7 +451,6 @@ public: /// - Content-Type: /// /// @param policy_id @see requestGet() - /// @param priority " /// @param url " /// @param body Byte stream to be sent as the body. No /// further encoding or escaping will be done @@ -470,7 +461,6 @@ public: /// @return " /// HttpHandle requestPut(policy_t policy_id, - priority_t priority, const std::string & url, BufferArray * body, const HttpOptions::ptr_t & options, @@ -483,7 +473,6 @@ public: /// encoding and communicating the content types. /// /// @param policy_id @see requestGet() - /// @param priority " /// @param url " /// @param options @see requestGet()K(optional) /// @param headers " @@ -491,7 +480,6 @@ public: /// @return " /// HttpHandle requestDelete(policy_t policy_id, - priority_t priority, const std::string & url, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers, @@ -502,7 +490,6 @@ public: /// encoding and communicating the content types. /// /// @param policy_id @see requestGet() - /// @param priority " /// @param url " /// @param body Byte stream to be sent as the body. No /// further encoding or escaping will be done @@ -513,7 +500,6 @@ public: /// @return " /// HttpHandle requestPatch(policy_t policy_id, - priority_t priority, const std::string & url, BufferArray * body, const HttpOptions::ptr_t & options, @@ -525,7 +511,6 @@ public: /// encoding and communicating the content types. /// /// @param policy_id @see requestGet() - /// @param priority " /// @param url " /// @param options @see requestGet()K(optional) /// @param headers " @@ -533,7 +518,6 @@ public: /// @return " /// HttpHandle requestCopy(policy_t policy_id, - priority_t priority, const std::string & url, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers, @@ -544,7 +528,6 @@ public: /// encoding and communicating the content types. /// /// @param policy_id @see requestGet() - /// @param priority " /// @param url " /// @param options @see requestGet()K(optional) /// @param headers " @@ -552,7 +535,6 @@ public: /// @return " /// HttpHandle requestMove(policy_t policy_id, - priority_t priority, const std::string & url, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers, @@ -593,18 +575,6 @@ public: HttpHandle requestCancel(HttpHandle request, HttpHandler::ptr_t); - /// Request that a previously-issued request be reprioritized. - /// The status of whether the change itself succeeded arrives - /// via notification. - /// - /// @param request Handle of previously-issued request to - /// be changed. - /// @param priority New priority value. - /// @param handler @see requestGet() - /// @return " - /// - HttpHandle requestSetPriority(HttpHandle request, priority_t priority, HttpHandler::ptr_t handler); - /// @} /// @name UtilityMethods diff --git a/indra/llfilesystem/lllfsthread.cpp b/indra/llfilesystem/lllfsthread.cpp index be8e83a56f..944e981ecf 100644 --- a/indra/llfilesystem/lllfsthread.cpp +++ b/indra/llfilesystem/lllfsthread.cpp @@ -65,8 +65,7 @@ void LLLFSThread::cleanupClass() //---------------------------------------------------------------------------- LLLFSThread::LLLFSThread(bool threaded) : - LLQueuedThread("LFS", threaded), - mPriorityCounter(PRIORITY_LOWBITS) + LLQueuedThread("LFS", threaded) { if(!mLocalAPRFilePoolp) { @@ -84,14 +83,12 @@ LLLFSThread::~LLLFSThread() LLLFSThread::handle_t LLLFSThread::read(const std::string& filename, /* Flawfinder: ignore */ U8* buffer, S32 offset, S32 numbytes, - Responder* responder, U32 priority) + Responder* responder) { + LL_PROFILE_ZONE_SCOPED; handle_t handle = generateHandle(); - if (priority == 0) priority = PRIORITY_NORMAL | priorityCounter(); - else if (priority < PRIORITY_LOW) priority |= PRIORITY_LOW; // All reads are at least PRIORITY_LOW - - Request* req = new Request(this, handle, priority, + Request* req = new Request(this, handle, FILE_READ, filename, buffer, offset, numbytes, responder); @@ -107,13 +104,12 @@ LLLFSThread::handle_t LLLFSThread::read(const std::string& filename, /* Flawfind LLLFSThread::handle_t LLLFSThread::write(const std::string& filename, U8* buffer, S32 offset, S32 numbytes, - Responder* responder, U32 priority) + Responder* responder) { + LL_PROFILE_ZONE_SCOPED; handle_t handle = generateHandle(); - if (priority == 0) priority = PRIORITY_LOW | priorityCounter(); - - Request* req = new Request(this, handle, priority, + Request* req = new Request(this, handle, FILE_WRITE, filename, buffer, offset, numbytes, responder); @@ -130,11 +126,11 @@ LLLFSThread::handle_t LLLFSThread::write(const std::string& filename, //============================================================================ LLLFSThread::Request::Request(LLLFSThread* thread, - handle_t handle, U32 priority, + handle_t handle, operation_t op, const std::string& filename, U8* buffer, S32 offset, S32 numbytes, Responder* responder) : - QueuedRequest(handle, priority, FLAG_AUTO_COMPLETE), + QueuedRequest(handle, FLAG_AUTO_COMPLETE), mThread(thread), mOperation(op), mFileName(filename), @@ -157,6 +153,7 @@ LLLFSThread::Request::~Request() // virtual, called from own thread void LLLFSThread::Request::finishRequest(bool completed) { + LL_PROFILE_ZONE_SCOPED; if (mResponder.notNull()) { mResponder->completed(completed ? mBytesRead : 0); @@ -166,6 +163,7 @@ void LLLFSThread::Request::finishRequest(bool completed) void LLLFSThread::Request::deleteRequest() { + LL_PROFILE_ZONE_SCOPED; if (getStatus() == STATUS_QUEUED) { LL_ERRS() << "Attempt to delete a queued LLLFSThread::Request!" << LL_ENDL; @@ -180,6 +178,7 @@ void LLLFSThread::Request::deleteRequest() bool LLLFSThread::Request::processRequest() { + LL_PROFILE_ZONE_SCOPED; bool complete = false; if (mOperation == FILE_READ) { diff --git a/indra/llfilesystem/lllfsthread.h b/indra/llfilesystem/lllfsthread.h index 58f658f7ba..f2693a1172 100644 --- a/indra/llfilesystem/lllfsthread.h +++ b/indra/llfilesystem/lllfsthread.h @@ -68,7 +68,7 @@ public: public: Request(LLLFSThread* thread, - handle_t handle, U32 priority, + handle_t handle, operation_t op, const std::string& filename, U8* buffer, S32 offset, S32 numbytes, Responder* responder); @@ -120,22 +120,15 @@ public: // Return a Request handle handle_t read(const std::string& filename, /* Flawfinder: ignore */ U8* buffer, S32 offset, S32 numbytes, - Responder* responder, U32 pri=0); + Responder* responder); handle_t write(const std::string& filename, U8* buffer, S32 offset, S32 numbytes, - Responder* responder, U32 pri=0); - - // Misc - U32 priorityCounter() { return mPriorityCounter-- & PRIORITY_LOWBITS; } // Use to order IO operations + Responder* responder); // static initializers static void initClass(bool local_is_threaded = TRUE); // Setup sLocal static S32 updateClass(U32 ms_elapsed); static void cleanupClass(); // Delete sLocal - - -private: - U32 mPriorityCounter; public: static LLLFSThread* sLocal; // Default local file thread diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index e1809dbe59..8dba1641a6 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -146,6 +146,7 @@ bool LLImageJ2C::initEncode(LLImageRaw &raw_image, int blocks_size, int precinct bool LLImageJ2C::decode(LLImageRaw *raw_imagep, F32 decode_time) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; return decodeChannels(raw_imagep, decode_time, 0, 4); } @@ -153,6 +154,7 @@ bool LLImageJ2C::decode(LLImageRaw *raw_imagep, F32 decode_time) // Returns true to mean done, whether successful or not. bool LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 first_channel, S32 max_channel_count ) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; LLTimer elapsed; bool res = true; diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp index 0dbb744bcf..1aace5f3e8 100644 --- a/indra/llimage/llimageworker.cpp +++ b/indra/llimage/llimageworker.cpp @@ -49,33 +49,22 @@ LLImageDecodeThread::~LLImageDecodeThread() S32 LLImageDecodeThread::update(F32 max_time_ms) { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - LLMutexLock lock(mCreationMutex); - for (creation_list_t::iterator iter = mCreationList.begin(); - iter != mCreationList.end(); ++iter) - { - creation_info& info = *iter; - ImageRequest* req = new ImageRequest(info.handle, info.image, - info.priority, info.discard, info.needs_aux, - info.responder); - - bool res = addRequest(req); - if (!res) - { - LL_ERRS() << "request added after LLLFSThread::cleanupClass()" << LL_ENDL; - } - } - mCreationList.clear(); S32 res = LLQueuedThread::update(max_time_ms); return res; } LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* image, - U32 priority, S32 discard, BOOL needs_aux, Responder* responder) + S32 discard, BOOL needs_aux, Responder* responder) { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - LLMutexLock lock(mCreationMutex); handle_t handle = generateHandle(); - mCreationList.push_back(creation_info(handle, image, priority, discard, needs_aux, responder)); + + ImageRequest* req = new ImageRequest(handle, image, + discard, needs_aux, + responder); + + addRequest(req); + return handle; } @@ -84,8 +73,7 @@ LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* S32 LLImageDecodeThread::tut_size() { LLMutexLock lock(mCreationMutex); - S32 res = mCreationList.size(); - return res; + return 0; } LLImageDecodeThread::Responder::~Responder() @@ -95,9 +83,9 @@ LLImageDecodeThread::Responder::~Responder() //---------------------------------------------------------------------------- LLImageDecodeThread::ImageRequest::ImageRequest(handle_t handle, LLImageFormatted* image, - U32 priority, S32 discard, BOOL needs_aux, + S32 discard, BOOL needs_aux, LLImageDecodeThread::Responder* responder) - : LLQueuedThread::QueuedRequest(handle, priority, FLAG_AUTO_COMPLETE), + : LLQueuedThread::QueuedRequest(handle, FLAG_AUTO_COMPLETE), mFormattedImage(image), mDiscardLevel(discard), mNeedsAux(needs_aux), @@ -121,7 +109,7 @@ LLImageDecodeThread::ImageRequest::~ImageRequest() bool LLImageDecodeThread::ImageRequest::processRequest() { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - const F32 decode_time_slice = .1f; + const F32 decode_time_slice = 0.f; //disable time slicing bool done = true; if (!mDecodedRaw && mFormattedImage.notNull()) { diff --git a/indra/llimage/llimageworker.h b/indra/llimage/llimageworker.h index 1bfb0ddfd3..4619ddd6a2 100644 --- a/indra/llimage/llimageworker.h +++ b/indra/llimage/llimageworker.h @@ -49,7 +49,7 @@ public: public: ImageRequest(handle_t handle, LLImageFormatted* image, - U32 priority, S32 discard, BOOL needs_aux, + S32 discard, BOOL needs_aux, LLImageDecodeThread::Responder* responder); /*virtual*/ bool processRequest(); @@ -76,7 +76,7 @@ public: virtual ~LLImageDecodeThread(); handle_t decodeImage(LLImageFormatted* image, - U32 priority, S32 discard, BOOL needs_aux, + S32 discard, BOOL needs_aux, Responder* responder); S32 update(F32 max_time_ms); @@ -88,16 +88,13 @@ private: { handle_t handle; LLPointer image; - U32 priority; S32 discard; BOOL needs_aux; LLPointer responder; creation_info(handle_t h, LLImageFormatted* i, U32 p, S32 d, BOOL aux, Responder* r) - : handle(h), image(i), priority(p), discard(d), needs_aux(aux), responder(r) + : handle(h), image(i), discard(d), needs_aux(aux), responder(r) {} }; - typedef std::list creation_list_t; - creation_list_t mCreationList; LLMutex* mCreationMutex; }; diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp index 925da5674b..8a641617fa 100644 --- a/indra/llimagej2coj/llimagej2coj.cpp +++ b/indra/llimagej2coj/llimagej2coj.cpp @@ -118,6 +118,7 @@ bool LLImageJ2COJ::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int block bool LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; // // FIXME: Get the comment field out of the texture // diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index dac5349f57..2ad42d6b87 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -379,6 +379,7 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECod void LLImageJ2CKDU::cleanupCodeStream() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; mInputp.reset(); mDecodeState.reset(); mCodeStreamp.reset(); @@ -426,6 +427,7 @@ bool LLImageJ2CKDU::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int bloc // decodeImpl() usage matters for production. bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level, int* region) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; base.resetLastError(); // *FIX: kdu calls our callback function if there's an error, and then bombs. @@ -509,6 +511,7 @@ bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco // Returns true to mean done, whether successful or not. bool LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; ECodeStreamMode mode = MODE_FAST; LLTimer decode_timer; @@ -1332,6 +1335,7 @@ the `buf' pointer may actually point into a larger buffer representing multiple tiles. For this reason, `row_gap' is needed to identify the separation between consecutive rows in the real buffer. */ { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; S32 c; // Now walk through the lines of the buffer, recovering them from the // relevant tile-component processing engines. @@ -1339,18 +1343,27 @@ separation between consecutive rows in the real buffer. */ LLTimer decode_timer; while (mDims.size.y--) { - for (c = 0; c < mNumComponents; c++) - { - mEngines[c].pull(mLines[c]); - } + { + LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("kduptc - pull"); + for (c = 0; c < mNumComponents; c++) + { + mEngines[c].pull(mLines[c]); + } + } + if ((mNumComponents >= 3) && mUseYCC) { + LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("kduptc - convert"); kdu_convert_ycc_to_rgb(mLines[0],mLines[1],mLines[2]); } - for (c = 0; c < mNumComponents; c++) - { - transfer_bytes(mBuf+c,mLines[c],mNumComponents,mBitDepths[c]); - } + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("kduptc - transfer"); + for (c = 0; c < mNumComponents; c++) + { + transfer_bytes(mBuf + c, mLines[c], mNumComponents, mBitDepths[c]); + } + } mBuf += mRowGap; if (mDims.size.y % 10) { diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index c67f59bc0c..ae066112c1 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -64,7 +64,6 @@ LLCore::HttpRequest::ptr_t sHttpRequest; LLCore::HttpHeaders::ptr_t sHttpHeaders; LLCore::HttpOptions::ptr_t sHttpOptions; LLCore::HttpRequest::policy_t sHttpPolicy; -LLCore::HttpRequest::priority_t sHttpPriority; /* Sample response: @@ -121,7 +120,6 @@ LLAvatarNameCache::LLAvatarNameCache() sHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders()); sHttpOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()); sHttpPolicy = LLCore::HttpRequest::DEFAULT_POLICY_ID; - sHttpPriority = 0; } LLAvatarNameCache::~LLAvatarNameCache() diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp index 7031f1aa8c..96af8bacee 100644 --- a/indra/llmessage/llcorehttputil.cpp +++ b/indra/llmessage/llcorehttputil.cpp @@ -131,7 +131,6 @@ bool responseToLLSD(HttpResponse * response, bool log, LLSD & out_llsd) HttpHandle requestPostWithLLSD(HttpRequest * request, HttpRequest::policy_t policy_id, - HttpRequest::priority_t priority, const std::string & url, const LLSD & body, const HttpOptions::ptr_t &options, @@ -145,7 +144,6 @@ HttpHandle requestPostWithLLSD(HttpRequest * request, LLSDSerialize::toXML(body, bas); handle = request->requestPost(policy_id, - priority, url, ba, options, @@ -158,7 +156,6 @@ HttpHandle requestPostWithLLSD(HttpRequest * request, HttpHandle requestPutWithLLSD(HttpRequest * request, HttpRequest::policy_t policy_id, - HttpRequest::priority_t priority, const std::string & url, const LLSD & body, const HttpOptions::ptr_t &options, @@ -172,7 +169,6 @@ HttpHandle requestPutWithLLSD(HttpRequest * request, LLSDSerialize::toXML(body, bas); handle = request->requestPut(policy_id, - priority, url, ba, options, @@ -184,7 +180,6 @@ HttpHandle requestPutWithLLSD(HttpRequest * request, HttpHandle requestPatchWithLLSD(HttpRequest * request, HttpRequest::policy_t policy_id, - HttpRequest::priority_t priority, const std::string & url, const LLSD & body, const HttpOptions::ptr_t &options, @@ -198,7 +193,6 @@ HttpHandle requestPatchWithLLSD(HttpRequest * request, LLSDSerialize::toXML(body, bas); handle = request->requestPatch(policy_id, - priority, url, ba, options, @@ -672,10 +666,9 @@ const std::string HttpCoroutineAdapter::HTTP_RESULTS_CONTENT("content"); const std::string HttpCoroutineAdapter::HTTP_RESULTS_RAW("raw"); HttpCoroutineAdapter::HttpCoroutineAdapter(const std::string &name, - LLCore::HttpRequest::policy_t policyId, LLCore::HttpRequest::priority_t priority) : + LLCore::HttpRequest::policy_t policyId) : mAdapterName(name), mPolicyId(policyId), - mPriority(priority), mYieldingHandle(LLCORE_HTTP_HANDLE_INVALID), mWeakRequest(), mWeakHandler() @@ -709,7 +702,7 @@ LLSD HttpCoroutineAdapter::postAndSuspend_(LLCore::HttpRequest::ptr_t &request, // The HTTPCoroHandler does not self delete, so retrieval of a the contained // pointer from the smart pointer is safe in this case. LLCore::HttpHandle hhandle = requestPostWithLLSD(request, - mPolicyId, mPriority, url, body, options, headers, + mPolicyId, url, body, options, headers, handler); if (hhandle == LLCORE_HTTP_HANDLE_INVALID) @@ -832,7 +825,7 @@ LLSD HttpCoroutineAdapter::postAndSuspend_(LLCore::HttpRequest::ptr_t &request, // The HTTPCoroHandler does not self delete, so retrieval of a the contained // pointer from the smart pointer is safe in this case. - LLCore::HttpHandle hhandle = request->requestPost(mPolicyId, mPriority, url, rawbody.get(), + LLCore::HttpHandle hhandle = request->requestPost(mPolicyId, url, rawbody.get(), options, headers, handler); if (hhandle == LLCORE_HTTP_HANDLE_INVALID) @@ -890,7 +883,7 @@ LLSD HttpCoroutineAdapter::putAndSuspend_(LLCore::HttpRequest::ptr_t &request, // The HTTPCoroHandler does not self delete, so retrieval of a the contained // pointer from the smart pointer is safe in this case. LLCore::HttpHandle hhandle = requestPutWithLLSD(request, - mPolicyId, mPriority, url, body, options, headers, + mPolicyId, url, body, options, headers, handler); if (hhandle == LLCORE_HTTP_HANDLE_INVALID) @@ -916,7 +909,7 @@ LLSD HttpCoroutineAdapter::putAndSuspend_(LLCore::HttpRequest::ptr_t &request, // The HTTPCoroHandler does not self delete, so retrieval of a the contained // pointer from the smart pointer is safe in this case. - LLCore::HttpHandle hhandle = request->requestPut(mPolicyId, mPriority, + LLCore::HttpHandle hhandle = request->requestPut(mPolicyId, url, rawbody.get(), options, headers, handler); if (hhandle == LLCORE_HTTP_HANDLE_INVALID) @@ -972,7 +965,7 @@ LLSD HttpCoroutineAdapter::getAndSuspend_(LLCore::HttpRequest::ptr_t &request, // The HTTPCoroHandler does not self delete, so retrieval of a the contained // pointer from the smart pointer is safe in this case. - LLCore::HttpHandle hhandle = request->requestGet(mPolicyId, mPriority, + LLCore::HttpHandle hhandle = request->requestGet(mPolicyId, url, options, headers, handler); if (hhandle == LLCORE_HTTP_HANDLE_INVALID) @@ -1018,7 +1011,7 @@ LLSD HttpCoroutineAdapter::deleteAndSuspend_(LLCore::HttpRequest::ptr_t &request checkDefaultHeaders(headers); // The HTTPCoroHandler does not self delete, so retrieval of a the contained // pointer from the smart pointer is safe in this case. - LLCore::HttpHandle hhandle = request->requestDelete(mPolicyId, mPriority, + LLCore::HttpHandle hhandle = request->requestDelete(mPolicyId, url, options, headers, handler); if (hhandle == LLCORE_HTTP_HANDLE_INVALID) @@ -1056,7 +1049,7 @@ LLSD HttpCoroutineAdapter::patchAndSuspend_(LLCore::HttpRequest::ptr_t &request, // The HTTPCoroHandler does not self delete, so retrieval of a the contained // pointer from the smart pointer is safe in this case. LLCore::HttpHandle hhandle = requestPatchWithLLSD(request, - mPolicyId, mPriority, url, body, options, headers, + mPolicyId, url, body, options, headers, handler); if (hhandle == LLCORE_HTTP_HANDLE_INVALID) @@ -1098,7 +1091,7 @@ LLSD HttpCoroutineAdapter::copyAndSuspend_(LLCore::HttpRequest::ptr_t &request, // The HTTPCoroHandler does not self delete, so retrieval of a the contained // pointer from the smart pointer is safe in this case. // - LLCore::HttpHandle hhandle = request->requestCopy(mPolicyId, mPriority, url, + LLCore::HttpHandle hhandle = request->requestCopy(mPolicyId, url, options, headers, handler); if (hhandle == LLCORE_HTTP_HANDLE_INVALID) @@ -1140,7 +1133,7 @@ LLSD HttpCoroutineAdapter::moveAndSuspend_(LLCore::HttpRequest::ptr_t &request, // The HTTPCoroHandler does not self delete, so retrieval of a the contained // pointer from the smart pointer is safe in this case. // - LLCore::HttpHandle hhandle = request->requestMove(mPolicyId, mPriority, url, + LLCore::HttpHandle hhandle = request->requestMove(mPolicyId, url, options, headers, handler); if (hhandle == LLCORE_HTTP_HANDLE_INVALID) diff --git a/indra/llmessage/llcorehttputil.h b/indra/llmessage/llcorehttputil.h index 6f0b865f83..430dc417ac 100644 --- a/indra/llmessage/llcorehttputil.h +++ b/indra/llmessage/llcorehttputil.h @@ -116,7 +116,6 @@ std::string responseToString(LLCore::HttpResponse * response); /// LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest * request, LLCore::HttpRequest::policy_t policy_id, - LLCore::HttpRequest::priority_t priority, const std::string & url, const LLSD & body, const LLCore::HttpOptions::ptr_t &options, @@ -125,20 +124,18 @@ LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest * request, inline LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest::ptr_t & request, LLCore::HttpRequest::policy_t policy_id, - LLCore::HttpRequest::priority_t priority, const std::string & url, const LLSD & body, const LLCore::HttpOptions::ptr_t & options, const LLCore::HttpHeaders::ptr_t & headers, const LLCore::HttpHandler::ptr_t & handler) { - return requestPostWithLLSD(request.get(), policy_id, priority, + return requestPostWithLLSD(request.get(), policy_id, url, body, options, headers, handler); } inline LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest::ptr_t & request, LLCore::HttpRequest::policy_t policy_id, - LLCore::HttpRequest::priority_t priority, const std::string & url, const LLSD & body, const LLCore::HttpHandler::ptr_t &handler) @@ -146,7 +143,7 @@ inline LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest::ptr_t & reque LLCore::HttpOptions::ptr_t options; LLCore::HttpHeaders::ptr_t headers; - return requestPostWithLLSD(request.get(), policy_id, priority, + return requestPostWithLLSD(request.get(), policy_id, url, body, options, headers, handler); } @@ -169,7 +166,6 @@ inline LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest::ptr_t & reque /// LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest * request, LLCore::HttpRequest::policy_t policy_id, - LLCore::HttpRequest::priority_t priority, const std::string & url, const LLSD & body, const LLCore::HttpOptions::ptr_t &options, @@ -178,20 +174,18 @@ LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest * request, inline LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest::ptr_t & request, LLCore::HttpRequest::policy_t policy_id, - LLCore::HttpRequest::priority_t priority, const std::string & url, const LLSD & body, const LLCore::HttpOptions::ptr_t & options, const LLCore::HttpHeaders::ptr_t & headers, LLCore::HttpHandler::ptr_t handler) { - return requestPutWithLLSD(request.get(), policy_id, priority, + return requestPutWithLLSD(request.get(), policy_id, url, body, options, headers, handler); } inline LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest::ptr_t & request, LLCore::HttpRequest::policy_t policy_id, - LLCore::HttpRequest::priority_t priority, const std::string & url, const LLSD & body, LLCore::HttpHandler::ptr_t handler) @@ -199,7 +193,7 @@ inline LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest::ptr_t & reques LLCore::HttpOptions::ptr_t options; LLCore::HttpHeaders::ptr_t headers; - return requestPutWithLLSD(request.get(), policy_id, priority, + return requestPutWithLLSD(request.get(), policy_id, url, body, options, headers, handler); } @@ -221,7 +215,6 @@ inline LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest::ptr_t & reques /// LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest * request, LLCore::HttpRequest::policy_t policy_id, - LLCore::HttpRequest::priority_t priority, const std::string & url, const LLSD & body, const LLCore::HttpOptions::ptr_t &options, @@ -230,20 +223,18 @@ LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest * request, inline LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest::ptr_t & request, LLCore::HttpRequest::policy_t policy_id, - LLCore::HttpRequest::priority_t priority, const std::string & url, const LLSD & body, const LLCore::HttpOptions::ptr_t & options, const LLCore::HttpHeaders::ptr_t & headers, const LLCore::HttpHandler::ptr_t & handler) { - return requestPatchWithLLSD(request.get(), policy_id, priority, + return requestPatchWithLLSD(request.get(), policy_id, url, body, options, headers, handler); } inline LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest::ptr_t & request, LLCore::HttpRequest::policy_t policy_id, - LLCore::HttpRequest::priority_t priority, const std::string & url, const LLSD & body, const LLCore::HttpHandler::ptr_t &handler) @@ -251,7 +242,7 @@ inline LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest::ptr_t & requ LLCore::HttpOptions::ptr_t options; LLCore::HttpHeaders::ptr_t headers; - return requestPatchWithLLSD(request.get(), policy_id, priority, + return requestPatchWithLLSD(request.get(), policy_id, url, body, options, headers, handler); } @@ -329,8 +320,7 @@ public: typedef boost::shared_ptr ptr_t; typedef boost::weak_ptr wptr_t; - HttpCoroutineAdapter(const std::string &name, LLCore::HttpRequest::policy_t policyId, - LLCore::HttpRequest::priority_t priority = 0L); + HttpCoroutineAdapter(const std::string &name, LLCore::HttpRequest::policy_t policyId); ~HttpCoroutineAdapter(); /// Execute a Post transaction on the supplied URL and yield execution of @@ -673,7 +663,6 @@ private: void checkDefaultHeaders(LLCore::HttpHeaders::ptr_t &headers); std::string mAdapterName; - LLCore::HttpRequest::priority_t mPriority; LLCore::HttpRequest::policy_t mPolicyId; LLCore::HttpHandle mYieldingHandle; diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 0a5d258b3a..04974d9122 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -1624,26 +1624,38 @@ void LLImageGL::syncToMainThread(LLGLuint new_tex_name) LL_PROFILE_ZONE_NAMED("cglt - sync"); if (gGLManager.mHasSync) { - // post a sync to the main thread (will execute before tex name swap lambda below) - // glFlush calls here are partly superstitious and partly backed by observation - // on AMD hardware - glFlush(); - auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - glFlush(); - LL::WorkQueue::postMaybe( - mMainQueue, - [=]() - { - LL_PROFILE_ZONE_NAMED("cglt - wait sync"); - { - LL_PROFILE_ZONE_NAMED("glWaitSync"); - glWaitSync(sync, 0, GL_TIMEOUT_IGNORED); - } + if (gGLManager.mIsNVIDIA) + { + // wait for texture upload to finish before notifying main thread + // upload is complete + auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + glFlush(); + glClientWaitSync(sync, 0, GL_TIMEOUT_IGNORED); + glDeleteSync(sync); + } + else + { + // post a sync to the main thread (will execute before tex name swap lambda below) + // glFlush calls here are partly superstitious and partly backed by observation + // on AMD hardware + glFlush(); + auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + glFlush(); + LL::WorkQueue::postMaybe( + mMainQueue, + [=]() { - LL_PROFILE_ZONE_NAMED("glDeleteSync"); - glDeleteSync(sync); - } - }); + LL_PROFILE_ZONE_NAMED("cglt - wait sync"); + { + LL_PROFILE_ZONE_NAMED("glWaitSync"); + glWaitSync(sync, 0, GL_TIMEOUT_IGNORED); + } + { + LL_PROFILE_ZONE_NAMED("glDeleteSync"); + glDeleteSync(sync); + } + }); + } } else { diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 17071d4a65..ffb2fa326d 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -3913,7 +3913,7 @@ Type F32 Value - 0.1 + 1.0 QueueInventoryFetchTimeout @@ -10368,17 +10368,6 @@ Value 12.0 - RenderTextureMemoryMultiple - - Comment - Multiple of texture memory value to use (should fit: 0 < value <= 1.0) - Persist - 1 - Type - F32 - Value - 1.0 - RenderTrackerBeacon Comment @@ -12456,7 +12445,7 @@ Type F32 Value - 1.0 + 2.0 TextureCameraMotionThreshold @@ -12683,20 +12672,9 @@ Comment If TRUE, always load textures at full resolution (discard = 0) Persist - 0 - Type - Boolean - Value - 0 - - TextureMemory - - Comment - Amount of memory to use for textures in MB (0 = autodetect) - Persist 1 Type - S32 + Boolean Value 0 diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index 1ccde98283..e04e38b9de 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -60,7 +60,6 @@ WindLightUseAtmosShaders 1 1 WLSkyDetail 1 128 Disregard128DefaultDrawDistance 1 1 Disregard96DefaultDrawDistance 1 1 -RenderTextureMemoryMultiple 1 1.0 RenderCompressTextures 1 1 RenderShaderLightingMaxLevel 1 3 RenderDeferred 1 1 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index c9efd89cc8..d319d26e1f 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -60,7 +60,6 @@ WindLightUseAtmosShaders 1 1 WLSkyDetail 1 128 Disregard128DefaultDrawDistance 1 1 Disregard96DefaultDrawDistance 1 1 -RenderTextureMemoryMultiple 1 1.0 RenderCompressTextures 1 1 RenderShaderLightingMaxLevel 1 3 RenderDeferred 1 1 diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 61fc693b99..7625547dd9 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3227,7 +3227,7 @@ LLSD LLAppViewer::getViewerInfo() const info["LOD_FACTOR"] = gSavedSettings.getF32("RenderVolumeLODFactor"); info["RENDER_QUALITY"] = (F32)gSavedSettings.getU32("RenderQualityPerformance"); info["GPU_SHADERS"] = gSavedSettings.getBOOL("RenderDeferred") ? "Enabled" : "Disabled"; - info["TEXTURE_MEMORY"] = gSavedSettings.getS32("TextureMemory"); + info["TEXTURE_MEMORY"] = gGLManager.mVRAM; #if LL_DARWIN info["HIDPI"] = gHiDPISupport; diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index cc5cb667f0..be33e1b30a 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -148,7 +148,7 @@ void LLDrawPoolTerrain::boostTerrainDetailTextures() for (S32 i = 0; i < 4; i++) { compp->mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN); - compp->mDetailTextures[i]->addTextureStats(1024.f*1024.f); // assume large pixel area + gPipeline.touchTexture(compp->mDetailTextures[i], 1024.f * 1024.f); } } diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index b328dd2962..9bf9e7503e 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -2311,6 +2311,7 @@ void LLFace::resetVirtualSize() F32 LLFace::getTextureVirtualSize() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; F32 radius; F32 cos_angle_to_view_dir; BOOL in_frustum = calcPixelArea(cos_angle_to_view_dir, radius); diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 90bb80a08b..f94c53a08b 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -1275,12 +1275,7 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState() shadow_text->setEnabled(enabled); // Hardware settings - F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple"); - S32Megabytes min_tex_mem = LLViewerTextureList::getMinVideoRamSetting(); - S32Megabytes max_tex_mem = LLViewerTextureList::getMaxVideoRamSetting(false, mem_multiplier); - getChild("GraphicsCardTextureMemory")->setMinValue(min_tex_mem.value()); - getChild("GraphicsCardTextureMemory")->setMaxValue(max_tex_mem.value()); - + if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") || !gGLManager.mHasVertexBufferObject) { diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index b4fc832596..fa7deb78f8 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -215,8 +215,6 @@ LLInventoryModel::LLInventoryModel() mHttpOptions(), mHttpHeaders(), mHttpPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID), - mHttpPriorityFG(0), - mHttpPriorityBG(0), mCategoryLock(), mItemLock(), mValidationInfo(new LLInventoryValidationInfo) @@ -2778,7 +2776,6 @@ LLCore::HttpHandle LLInventoryModel::requestPost(bool foreground, handle = LLCoreHttpUtil::requestPostWithLLSD(request, mHttpPolicyClass, - (foreground ? mHttpPriorityFG : mHttpPriorityBG), url, body, mHttpOptions, diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index e81652820f..fdbc6426ad 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -610,8 +610,6 @@ private: LLCore::HttpOptions::ptr_t mHttpOptions; LLCore::HttpHeaders::ptr_t mHttpHeaders; LLCore::HttpRequest::policy_t mHttpPolicyClass; - LLCore::HttpRequest::priority_t mHttpPriorityFG; - LLCore::HttpRequest::priority_t mHttpPriorityBG; /** HTTP Transport ** ** diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp index 11aa607393..27a9758ec3 100644 --- a/indra/newview/llmaterialmgr.cpp +++ b/indra/newview/llmaterialmgr.cpp @@ -133,8 +133,7 @@ LLMaterialMgr::LLMaterialMgr(): mHttpRequest(), mHttpHeaders(), mHttpOptions(), - mHttpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID), - mHttpPriority(0) + mHttpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID) { LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp()); @@ -699,7 +698,7 @@ void LLMaterialMgr::processGetQueue() << "\ndata: " << ll_pretty_print_sd(materialsData) << LL_ENDL; LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest, - mHttpPolicy, mHttpPriority, capURL, + mHttpPolicy, capURL, postData, mHttpOptions, mHttpHeaders, handler); if (handle == LLCORE_HTTP_HANDLE_INVALID) @@ -985,7 +984,7 @@ void LLMaterialMgr::processPutQueue() )); LLCore::HttpHandle handle = LLCoreHttpUtil::requestPutWithLLSD( - mHttpRequest, mHttpPolicy, mHttpPriority, capURL, + mHttpRequest, mHttpPolicy, capURL, putData, mHttpOptions, mHttpHeaders, handler); if (handle == LLCORE_HTTP_HANDLE_INVALID) diff --git a/indra/newview/llmaterialmgr.h b/indra/newview/llmaterialmgr.h index 843dc66fbc..f76cc27db1 100644 --- a/indra/newview/llmaterialmgr.h +++ b/indra/newview/llmaterialmgr.h @@ -141,7 +141,6 @@ private: LLCore::HttpHeaders::ptr_t mHttpHeaders; LLCore::HttpOptions::ptr_t mHttpOptions; LLCore::HttpRequest::policy_t mHttpPolicy; - LLCore::HttpRequest::priority_t mHttpPriority; U32 getMaxEntries(const LLViewerRegion* regionp); }; diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp index bc45eb6d3a..142977e939 100644 --- a/indra/newview/llmediadataclient.cpp +++ b/indra/newview/llmediadataclient.cpp @@ -355,7 +355,7 @@ void LLMediaDataClient::serviceQueue() // and make the post LLCore::HttpHandler::ptr_t handler = request->createHandler(); - LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest, mHttpPolicy, 0, + LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest, mHttpPolicy, url, sd_payload, mHttpOpts, mHttpHeaders, handler); if (handle == LLCORE_HTTP_HANDLE_INVALID) diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index d28e929b48..6fa71e130e 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -823,8 +823,7 @@ LLMeshRepoThread::LLMeshRepoThread() mHttpLargeOptions(), mHttpHeaders(), mHttpPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID), - mHttpLargePolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID), - mHttpPriority(0) + mHttpLargePolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID) { LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp()); @@ -1268,7 +1267,6 @@ LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url, if (len < LARGE_MESH_FETCH_THRESHOLD) { handle = mHttpRequest->requestGetByteRange( mHttpPolicyClass, - mHttpPriority, url, (disable_range_req ? size_t(0) : offset), (disable_range_req ? size_t(0) : len), @@ -1283,7 +1281,6 @@ LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url, else { handle = mHttpRequest->requestGetByteRange(mHttpLargePolicyClass, - mHttpPriority, url, (disable_range_req ? size_t(0) : offset), (disable_range_req ? size_t(0) : len), @@ -2130,7 +2127,6 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data, mHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders); mHttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_LLSD_XML); mHttpPolicyClass = LLAppViewer::instance()->getAppCoreHttp().getPolicy(LLAppCoreHttp::AP_UPLOADS); - mHttpPriority = 0; } LLMeshUploadThread::~LLMeshUploadThread() @@ -2649,7 +2645,6 @@ void LLMeshUploadThread::doWholeModelUpload() LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest, mHttpPolicyClass, - mHttpPriority, mWholeModelUploadURL, body, mHttpOptions, @@ -2700,7 +2695,6 @@ void LLMeshUploadThread::requestWholeModelFee() dump_llsd_to_file(mModelData, make_dump_name("whole_model_fee_request_", dump_num)); LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest, mHttpPolicyClass, - mHttpPriority, mWholeModelFeeCapability, mModelData, mHttpOptions, diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 1989350303..5459bbb4af 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -321,7 +321,6 @@ public: LLCore::HttpHeaders::ptr_t mHttpHeaders; LLCore::HttpRequest::policy_t mHttpPolicyClass; LLCore::HttpRequest::policy_t mHttpLargePolicyClass; - LLCore::HttpRequest::priority_t mHttpPriority; typedef std::set http_request_set; http_request_set mHttpRequestSet; // Outstanding HTTP requests @@ -489,7 +488,6 @@ private: LLCore::HttpOptions::ptr_t mHttpOptions; LLCore::HttpHeaders::ptr_t mHttpHeaders; LLCore::HttpRequest::policy_t mHttpPolicyClass; - LLCore::HttpRequest::priority_t mHttpPriority; }; // Params related to streaming cost, render cost, and scene complexity tracking. diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 5c648c11e1..99d7c81c8d 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -3364,10 +3364,10 @@ public: } } - if (drawable->getVOVolume() && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)) + /*if (drawable->getVOVolume() && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)) { renderTexturePriority(drawable); - } + }*/ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_POINTS)) { @@ -3694,7 +3694,7 @@ void LLSpatialPartition::renderDebug() LLPipeline::RENDER_DEBUG_BBOXES | LLPipeline::RENDER_DEBUG_NORMALS | LLPipeline::RENDER_DEBUG_POINTS | - LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY | + //LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY | LLPipeline::RENDER_DEBUG_TEXTURE_ANIM | LLPipeline::RENDER_DEBUG_RAYCAST | LLPipeline::RENDER_DEBUG_AVATAR_VOLUME | diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index d4fc6f3de2..8f4eb9438b 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -95,14 +95,13 @@ private: }; public: - LLTextureCacheWorker(LLTextureCache* cache, U32 priority, const LLUUID& id, + LLTextureCacheWorker(LLTextureCache* cache, const LLUUID& id, U8* data, S32 datasize, S32 offset, S32 imagesize, // for writes LLTextureCache::Responder* responder) : LLWorkerClass(cache, "LLTextureCacheWorker"), mID(id), mCache(cache), - mPriority(priority), mReadData(NULL), mWriteData(data), mDataSize(datasize), @@ -115,7 +114,6 @@ public: mBytesToRead(0), mBytesRead(0) { - mPriority &= LLWorkerThread::PRIORITY_LOWBITS; } ~LLTextureCacheWorker() { @@ -129,13 +127,12 @@ public: virtual bool doWork(S32 param); // Called from LLWorkerThread::processRequest() - handle_t read() { addWork(0, LLWorkerThread::PRIORITY_HIGH | mPriority); return mRequestHandle; } - handle_t write() { addWork(1, LLWorkerThread::PRIORITY_HIGH | mPriority); return mRequestHandle; } + handle_t read() { addWork(0); return mRequestHandle; } + handle_t write() { addWork(1); return mRequestHandle; } bool complete() { return checkWork(); } void ioComplete(S32 bytes) { mBytesRead = bytes; - setPriority(LLWorkerThread::PRIORITY_HIGH | mPriority); } private: @@ -145,7 +142,6 @@ private: protected: LLTextureCache* mCache; - U32 mPriority; LLUUID mID; U8* mReadData; @@ -164,11 +160,11 @@ protected: class LLTextureCacheLocalFileWorker : public LLTextureCacheWorker { public: - LLTextureCacheLocalFileWorker(LLTextureCache* cache, U32 priority, const std::string& filename, const LLUUID& id, + LLTextureCacheLocalFileWorker(LLTextureCache* cache, const std::string& filename, const LLUUID& id, U8* data, S32 datasize, S32 offset, S32 imagesize, // for writes LLTextureCache::Responder* responder) - : LLTextureCacheWorker(cache, priority, id, data, datasize, offset, imagesize, responder), + : LLTextureCacheWorker(cache, id, data, datasize, offset, imagesize, responder), mFileName(filename) { @@ -183,6 +179,7 @@ private: bool LLTextureCacheLocalFileWorker::doRead() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; S32 local_size = LLAPRFile::size(mFileName, mCache->getLocalAPRFilePool()); if (local_size > 0 && mFileName.size() > 4) @@ -207,50 +204,6 @@ bool LLTextureCacheLocalFileWorker::doRead() return true; } -#if USE_LFS_READ - if (mFileHandle == LLLFSThread::nullHandle()) - { - mImageLocal = TRUE; - mImageSize = local_size; - if (!mDataSize || mDataSize + mOffset > local_size) - { - mDataSize = local_size - mOffset; - } - if (mDataSize <= 0) - { - // no more data to read - mDataSize = 0; - return true; - } - mReadData = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), mDataSize); - mBytesRead = -1; - mBytesToRead = mDataSize; - setPriority(LLWorkerThread::PRIORITY_LOW | mPriority); - mFileHandle = LLLFSThread::sLocal->read(local_filename, mReadData, mOffset, mDataSize, - new ReadResponder(mCache, mRequestHandle)); - return false; - } - else - { - if (mBytesRead >= 0) - { - if (mBytesRead != mBytesToRead) - { -// LL_WARNS() << "Error reading file from local cache: " << local_filename -// << " Bytes: " << mDataSize << " Offset: " << mOffset -// << " / " << mDataSize << LL_ENDL; - mDataSize = 0; // failed - ll_aligned_free_16(mReadData); - mReadData = NULL; - } - return true; - } - else - { - return false; - } - } -#else if (!mDataSize || mDataSize > local_size) { mDataSize = local_size; @@ -274,7 +227,6 @@ bool LLTextureCacheLocalFileWorker::doRead() mImageLocal = TRUE; } return true; -#endif } bool LLTextureCacheLocalFileWorker::doWrite() @@ -286,12 +238,12 @@ bool LLTextureCacheLocalFileWorker::doWrite() class LLTextureCacheRemoteWorker : public LLTextureCacheWorker { public: - LLTextureCacheRemoteWorker(LLTextureCache* cache, U32 priority, const LLUUID& id, + LLTextureCacheRemoteWorker(LLTextureCache* cache, const LLUUID& id, U8* data, S32 datasize, S32 offset, S32 imagesize, // for writes LLPointer raw, S32 discardlevel, LLTextureCache::Responder* responder) - : LLTextureCacheWorker(cache, priority, id, data, datasize, offset, imagesize, responder), + : LLTextureCacheWorker(cache, id, data, datasize, offset, imagesize, responder), mState(INIT), mRawImage(raw), mRawDiscardLevel(discardlevel) @@ -329,6 +281,7 @@ void LLTextureCacheWorker::startWork(S32 param) // - the code supports offset reading but this is actually never exercised in the viewer bool LLTextureCacheRemoteWorker::doRead() { + LL_PROFILE_ZONE_SCOPED; bool done = false; S32 idx = -1; @@ -580,6 +533,7 @@ bool LLTextureCacheRemoteWorker::doRead() // - the code *does not* support offset writing so there are no difference between buffer addresses and start of data bool LLTextureCacheRemoteWorker::doWrite() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; bool done = false; S32 idx = -1; @@ -756,6 +710,7 @@ bool LLTextureCacheRemoteWorker::doWrite() //virtual bool LLTextureCacheWorker::doWork(S32 param) { + LL_PROFILE_ZONE_SCOPED; bool res = false; if (param == 0) // read { @@ -775,11 +730,13 @@ bool LLTextureCacheWorker::doWork(S32 param) //virtual (WORKER THREAD) void LLTextureCacheWorker::finishWork(S32 param, bool completed) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if (mResponder.notNull()) { bool success = (completed && mDataSize > 0); if (param == 0) { + LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("tcwfw - read"); // read if (success) { @@ -789,12 +746,14 @@ void LLTextureCacheWorker::finishWork(S32 param, bool completed) } else { + LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("tcwfw - read fail"); ll_aligned_free_16(mReadData); mReadData = NULL; } } else { + LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("tcwfw - write"); // write mWriteData = NULL; // we never owned data mDataSize = 0; @@ -806,6 +765,7 @@ void LLTextureCacheWorker::finishWork(S32 param, bool completed) //virtual (MAIN THREAD) void LLTextureCacheWorker::endWork(S32 param, bool aborted) { + LL_PROFILE_ZONE_SCOPED; if (aborted) { // Let the destructor handle any cleanup @@ -861,6 +821,7 @@ LLTextureCache::~LLTextureCache() //virtual S32 LLTextureCache::update(F32 max_time_ms) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; static LLFrameTimer timer ; static const F32 MAX_TIME_INTERVAL = 300.f ; //seconds. @@ -874,22 +835,6 @@ S32 LLTextureCache::update(F32 max_time_ms) mCompletedList.clear(); mListMutex.unlock(); - lockWorkers(); - - for (handle_list_t::iterator iter1 = priorty_list.begin(); - iter1 != priorty_list.end(); ++iter1) - { - handle_t handle = *iter1; - handle_map_t::iterator iter2 = mWriters.find(handle); - if(iter2 != mWriters.end()) - { - LLTextureCacheWorker* worker = iter2->second; - worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mPriority); - } - } - - unlockWorkers(); - // call 'completed' with workers list unlocked (may call readComplete() or writeComplete() for (responder_list_t::iterator iter1 = completed_list.begin(); iter1 != completed_list.end(); ++iter1) @@ -1323,6 +1268,7 @@ void LLTextureCache::updateEntryTimeStamp(S32 idx, Entry& entry) //update an existing entry, write to header file immediately. bool LLTextureCache::updateEntry(S32& idx, Entry& entry, S32 new_image_size, S32 new_data_size) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; S32 new_body_size = llmax(0, new_data_size - TEXTURE_CACHE_ENTRY_SIZE) ; if(new_image_size == entry.mImageSize && new_body_size == entry.mBodySize) @@ -1872,6 +1818,7 @@ void LLTextureCache::purgeTextures(bool validate) // call lockWorkers() first! LLTextureCacheWorker* LLTextureCache::getReader(handle_t handle) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; LLTextureCacheWorker* res = NULL; handle_map_t::iterator iter = mReaders.find(handle); if (iter != mReaders.end()) @@ -1883,6 +1830,7 @@ LLTextureCacheWorker* LLTextureCache::getReader(handle_t handle) LLTextureCacheWorker* LLTextureCache::getWriter(handle_t handle) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; LLTextureCacheWorker* res = NULL; handle_map_t::iterator iter = mWriters.find(handle); if (iter != mWriters.end()) @@ -1898,6 +1846,7 @@ LLTextureCacheWorker* LLTextureCache::getWriter(handle_t handle) // Reads imagesize from the header, updates timestamp S32 LLTextureCache::getHeaderCacheEntry(const LLUUID& id, Entry& entry) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; LLMutexLock lock(&mHeaderMutex); S32 idx = openAndReadEntry(id, entry, false); if (idx >= 0) @@ -1910,6 +1859,7 @@ S32 LLTextureCache::getHeaderCacheEntry(const LLUUID& id, Entry& entry) // Writes imagesize to the header, updates timestamp S32 LLTextureCache::setHeaderCacheEntry(const LLUUID& id, Entry& entry, S32 imagesize, S32 datasize) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; mHeaderMutex.lock(); S32 idx = openAndReadEntry(id, entry, true); // read or create mHeaderMutex.unlock(); @@ -1942,13 +1892,14 @@ S32 LLTextureCache::setHeaderCacheEntry(const LLUUID& id, Entry& entry, S32 imag // Calls from texture pipeline thread (i.e. LLTextureFetch) -LLTextureCache::handle_t LLTextureCache::readFromCache(const std::string& filename, const LLUUID& id, U32 priority, +LLTextureCache::handle_t LLTextureCache::readFromCache(const std::string& filename, const LLUUID& id, S32 offset, S32 size, ReadResponder* responder) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; // Note: checking to see if an entry exists can cause a stall, // so let the thread handle it LLMutexLock lock(&mWorkersMutex); - LLTextureCacheWorker* worker = new LLTextureCacheLocalFileWorker(this, priority, filename, id, + LLTextureCacheWorker* worker = new LLTextureCacheLocalFileWorker(this, filename, id, NULL, size, offset, 0, responder); handle_t handle = worker->read(); @@ -1956,13 +1907,14 @@ LLTextureCache::handle_t LLTextureCache::readFromCache(const std::string& filena return handle; } -LLTextureCache::handle_t LLTextureCache::readFromCache(const LLUUID& id, U32 priority, +LLTextureCache::handle_t LLTextureCache::readFromCache(const LLUUID& id, S32 offset, S32 size, ReadResponder* responder) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; // Note: checking to see if an entry exists can cause a stall, // so let the thread handle it LLMutexLock lock(&mWorkersMutex); - LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, priority, id, + LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, id, NULL, size, offset, 0, NULL, 0, responder); handle_t handle = worker->read(); @@ -1973,6 +1925,7 @@ LLTextureCache::handle_t LLTextureCache::readFromCache(const LLUUID& id, U32 pri bool LLTextureCache::readComplete(handle_t handle, bool abort) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; lockWorkers(); handle_map_t::iterator iter = mReaders.find(handle); LLTextureCacheWorker* worker = NULL; @@ -2000,7 +1953,7 @@ bool LLTextureCache::readComplete(handle_t handle, bool abort) return (complete || abort); } -LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 priority, +LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U8* data, S32 datasize, S32 imagesize, LLPointer rawimage, S32 discardlevel, WriteResponder* responder) @@ -2018,7 +1971,7 @@ LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 prio mDoPurge = !mPurgeEntryList.empty(); } LLMutexLock lock(&mWorkersMutex); - LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, priority, id, + LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, id, data, datasize, 0, imagesize, rawimage, discardlevel, responder); handle_t handle = worker->write(); @@ -2086,6 +2039,7 @@ LLPointer LLTextureCache::readFromFastCache(const LLUUID& id, S32& d //return the fast cache location bool LLTextureCache::writeToFastCache(LLUUID image_id, S32 id, LLPointer raw, S32 discardlevel) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; //rescale image if needed if (raw.isNull() || raw->isBufferInvalid() || !raw->getData()) { diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h index e1c752b58e..f2a5978a7c 100644 --- a/indra/newview/lltexturecache.h +++ b/indra/newview/lltexturecache.h @@ -119,13 +119,13 @@ public: void setReadOnly(BOOL read_only) ; S64 initCache(ELLPath location, S64 maxsize, BOOL texture_cache_mismatch); - handle_t readFromCache(const std::string& local_filename, const LLUUID& id, U32 priority, S32 offset, S32 size, + handle_t readFromCache(const std::string& local_filename, const LLUUID& id, S32 offset, S32 size, ReadResponder* responder); - handle_t readFromCache(const LLUUID& id, U32 priority, S32 offset, S32 size, + handle_t readFromCache(const LLUUID& id, S32 offset, S32 size, ReadResponder* responder); bool readComplete(handle_t handle, bool abort); - handle_t writeToCache(const LLUUID& id, U32 priority, U8* data, S32 datasize, S32 imagesize, LLPointer rawimage, S32 discardlevel, + handle_t writeToCache(const LLUUID& id, U8* data, S32 datasize, S32 imagesize, LLPointer rawimage, S32 discardlevel, WriteResponder* responder); LLPointer readFromFastCache(const LLUUID& id, S32& discardlevel); bool writeComplete(handle_t handle, bool abort = false); diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 0edaf40c66..8ad28074de 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -213,35 +213,17 @@ const std::string sTesterName("TextureFetchTester"); // // Worker State Machine // -// (ASCII art needed) -// -// -// Priority Scheme -// -// [PRIORITY_LOW, PRIORITY_NORMAL) - for WAIT_HTTP_RESOURCE state -// and other wait states -// [PRIORITY_HIGH, PRIORITY_URGENT) - External event delivered, -// rapidly transitioning through states, -// no waiting allowed -// -// By itself, the above work queue model would fail the concurrency -// and liveness requirements of the interface. A high priority -// request could find itself on the head and stalled for external -// reasons (see VWR-28996). So a few additional constraints are -// required to keep things running: -// * Anything that can make forward progress must be kept at a -// higher priority than anything that can't. -// * On completion of external events, the associated request -// needs to be elevated beyond the normal range to handle -// any data delivery and release any external resource. -// -// This effort is made to keep higher-priority entities moving -// forward in their state machines at every possible step of -// processing. It's not entirely proven that this produces the -// experiencial benefits promised. +// "doWork" will be executed for a given worker on its respective +// LLQueuedThread. If doWork returns true, the worker is treated +// as completed. If doWork returns false, the worker will be +// put on the back of the work queue at the start of the next iteration +// of the mainloop. If a worker is waiting on a resource, it should +// return false as soon as possible and not block to avoid starving +// other workers of cpu cycles. // + ////////////////////////////////////////////////////////////////////////////// // Tuning/Parameterization Constants @@ -386,14 +368,7 @@ private: bool operator()(const LLTextureFetchWorker* lhs, const LLTextureFetchWorker* rhs) const { // greater priority is "less" - const F32 lpriority = lhs->mImagePriority; - const F32 rpriority = rhs->mImagePriority; - if (lpriority > rpriority) // higher priority - return true; - else if (lpriority < rpriority) - return false; - else - return lhs < rhs; + return lhs->mImagePriority > rhs->mImagePriority; } }; @@ -484,6 +459,9 @@ private: // Locks: Mw void resetFormattedData(); + // get the relative priority of this worker (should map to max virtual size) + F32 getImagePriority() const; + // Locks: Mw void setImagePriority(F32 priority); @@ -500,9 +478,6 @@ private: // Locks: Mw void setupPacketData(); - // Locks: Mw (ctor invokes without lock) - U32 calcWorkPriority(); - // Locks: Mw void removeFromCache(); @@ -573,8 +548,7 @@ private: LLHost mHost; std::string mUrl; U8 mType; - F32 mImagePriority; - U32 mWorkPriority; + F32 mImagePriority; // should map to max virtual size F32 mRequestedPriority; S32 mDesiredDiscard; S32 mSimRequestedDiscard; @@ -923,7 +897,6 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher, mHost(host), mUrl(url), mImagePriority(priority), - mWorkPriority(0), mRequestedPriority(0.f), mDesiredDiscard(-1), mSimRequestedDiscard(-1), @@ -970,17 +943,15 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher, mCacheReadCount(0U), mCacheWriteCount(0U), mResourceWaitCount(0U), - mFetchRetryPolicy(10.0,3600.0,2.0,10) + mFetchRetryPolicy(10.f,3600.f,2.f,10) { mCanUseNET = mUrl.empty() ; - calcWorkPriority(); mType = host.isOk() ? LLImageBase::TYPE_AVATAR_BAKE : LLImageBase::TYPE_NORMAL; // LL_INFOS(LOG_TXT) << "Create: " << mID << " mHost:" << host << " Discard=" << discard << LL_ENDL; if (!mFetcher->mDebugPause) { - U32 work_priority = mWorkPriority | LLWorkerThread::PRIORITY_HIGH; - addWork(0, work_priority ); + addWork(0); } setDesiredDiscard(discard, size); } @@ -1070,16 +1041,6 @@ void LLTextureFetchWorker::setupPacketData() } } -// Locks: Mw (ctor invokes without lock) -U32 LLTextureFetchWorker::calcWorkPriority() -{ - //llassert_always(mImagePriority >= 0 && mImagePriority <= LLViewerFetchedTexture::maxDecodePriority()); - static const F32 PRIORITY_SCALE = (F32)LLWorkerThread::PRIORITY_LOWBITS / LLViewerFetchedTexture::maxDecodePriority(); - - mWorkPriority = llmin((U32)LLWorkerThread::PRIORITY_LOWBITS, (U32)(mImagePriority * PRIORITY_SCALE)); - return mWorkPriority; -} - // Locks: Mw (ctor invokes without lock) void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size) { @@ -1088,11 +1049,9 @@ void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size) { if (!haveWork()) { - calcWorkPriority(); if (!mFetcher->mDebugPause) { - U32 work_priority = mWorkPriority | LLWorkerThread::PRIORITY_HIGH; - addWork(0, work_priority); + addWork(0); } } else if (mDesiredDiscard < discard) @@ -1111,23 +1070,13 @@ void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size) if ((prioritize && mState == INIT) || mState == DONE) { setState(INIT); - U32 work_priority = mWorkPriority | LLWorkerThread::PRIORITY_HIGH; - setPriority(work_priority); } } // Locks: Mw void LLTextureFetchWorker::setImagePriority(F32 priority) { -// llassert_always(priority >= 0 && priority <= LLViewerTexture::maxDecodePriority()); - F32 delta = fabs(priority - mImagePriority); - if (delta > (mImagePriority * .05f) || mState == DONE) - { - mImagePriority = priority; - calcWorkPriority(); - U32 work_priority = mWorkPriority | (getPriority() & LLWorkerThread::PRIORITY_HIGHBITS); - setPriority(work_priority); - } + mImagePriority = priority; //should map to max virtual size } // Locks: Mw @@ -1147,6 +1096,11 @@ void LLTextureFetchWorker::resetFormattedData() mHaveAllData = FALSE; } +F32 LLTextureFetchWorker::getImagePriority() const +{ + return mImagePriority; +} + // Threads: Tmain void LLTextureFetchWorker::startWork(S32 param) { @@ -1156,7 +1110,7 @@ void LLTextureFetchWorker::startWork(S32 param) // Threads: Ttf bool LLTextureFetchWorker::doWork(S32 param) { - LL_PROFILE_ZONE_SCOPED; + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; if (gNonInteractive) { return true; @@ -1171,20 +1125,23 @@ bool LLTextureFetchWorker::doWork(S32 param) { if (mState < DECODE_IMAGE) { + LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - state < decode"); return true; // abort } } - if(mImagePriority < F_ALMOST_ZERO) + if (mImagePriority < F_ALMOST_ZERO) { if (mState == INIT || mState == LOAD_FROM_NETWORK || mState == LOAD_FROM_SIMULATOR) { + LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - priority < 0"); LL_DEBUGS(LOG_TXT) << mID << " abort: mImagePriority < F_ALMOST_ZERO" << LL_ENDL; return true; // abort } } if(mState > CACHE_POST && !mCanUseNET && !mCanUseHTTP) { + LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - state > cache_post"); //nowhere to get data, abort. LL_WARNS(LOG_TXT) << mID << " abort, nowhere to get data" << LL_ENDL; return true ; @@ -1206,6 +1163,7 @@ bool LLTextureFetchWorker::doWork(S32 param) if (mState == INIT) { + LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - INIT"); mStateTimer.reset(); mFetchTimer.reset(); for(auto i : LOGGED_STATES) @@ -1247,15 +1205,16 @@ bool LLTextureFetchWorker::doWork(S32 param) if (mState == LOAD_FROM_TEXTURE_CACHE) { + LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - LOAD_FROM_TEXTURE_CACHE"); if (mCacheReadHandle == LLTextureCache::nullHandle()) { - U32 cache_priority = mWorkPriority; S32 offset = mFormattedImage.notNull() ? mFormattedImage->getDataSize() : 0; S32 size = mDesiredSize - offset; if (size <= 0) { setState(CACHE_POST); - return false; + return doWork(param); + // return false; } mFileSize = 0; mLoaded = FALSE; @@ -1264,35 +1223,28 @@ bool LLTextureFetchWorker::doWork(S32 param) if (mUrl.compare(0, 7, "file://") == 0) { - setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it - // read file from local disk ++mCacheReadCount; std::string filename = mUrl.substr(7, std::string::npos); CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage); mCacheReadTimer.reset(); - mCacheReadHandle = mFetcher->mTextureCache->readFromCache(filename, mID, cache_priority, - offset, size, responder); + mCacheReadHandle = mFetcher->mTextureCache->readFromCache(filename, mID, offset, size, responder); } else if ((mUrl.empty() || mFTType==FTT_SERVER_BAKE) && mFetcher->canLoadFromCache()) { - setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it - ++mCacheReadCount; CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage); mCacheReadTimer.reset(); - mCacheReadHandle = mFetcher->mTextureCache->readFromCache(mID, cache_priority, + mCacheReadHandle = mFetcher->mTextureCache->readFromCache(mID, offset, size, responder);; } else if(!mUrl.empty() && mCanUseHTTP) { - setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); setState(WAIT_HTTP_RESOURCE); } else { - setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); setState(LOAD_FROM_NETWORK); } } @@ -1325,6 +1277,7 @@ bool LLTextureFetchWorker::doWork(S32 param) if (mState == CACHE_POST) { + LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - CACHE_POST"); mCachedSize = mFormattedImage.notNull() ? mFormattedImage->getDataSize() : 0; // Successfully loaded if ((mCachedSize >= mDesiredSize) || mHaveAllData) @@ -1366,6 +1319,7 @@ bool LLTextureFetchWorker::doWork(S32 param) if (mState == LOAD_FROM_NETWORK) { + LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - LOAD_FROM_NETWORK"); // Check for retries to previous server failures. F32 wait_seconds; if (mFetchRetryPolicy.shouldRetry(wait_seconds)) @@ -1427,7 +1381,6 @@ bool LLTextureFetchWorker::doWork(S32 param) if (mCanUseHTTP && !mUrl.empty()) { setState(WAIT_HTTP_RESOURCE); - setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); if(mWriteToCacheState != NOT_WRITE) { mWriteToCacheState = CAN_WRITE ; @@ -1444,25 +1397,19 @@ bool LLTextureFetchWorker::doWork(S32 param) mSentRequest = QUEUED; mFetcher->addToNetworkQueue(this); recordTextureStart(false); - setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); - return false; } else { // Shouldn't need to do anything here - //llassert_always(mFetcher->mNetworkQueue.find(mID) != mFetcher->mNetworkQueue.end()); - // Make certain this is in the network queue - //mFetcher->addToNetworkQueue(this); - //recordTextureStart(false); - //setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); - + llassert(mFetcher->mNetworkQueue.find(mID) != mFetcher->mNetworkQueue.end()); return false; } } if (mState == LOAD_FROM_SIMULATOR) { + LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - LOAD_FROM_SIMULATOR"); if (mFormattedImage.isNull()) { mFormattedImage = new LLImageJ2C; @@ -1492,7 +1439,7 @@ bool LLTextureFetchWorker::doWork(S32 param) LL_WARNS(LOG_TXT) << mID << " processSimulatorPackets() failed to load buffer" << LL_ENDL; return true; // failed } - setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); + if (mLoadedDiscard < 0) { LL_WARNS(LOG_TXT) << mID << " mLoadedDiscard is " << mLoadedDiscard @@ -1506,7 +1453,6 @@ bool LLTextureFetchWorker::doWork(S32 param) else { mFetcher->addToNetworkQueue(this); // failsafe - setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); recordTextureStart(false); } return false; @@ -1514,6 +1460,7 @@ bool LLTextureFetchWorker::doWork(S32 param) if (mState == WAIT_HTTP_RESOURCE) { + LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - WAIT_HTTP_RESOURCE"); // NOTE: // control the number of the http requests issued for: // 1, not openning too many file descriptors at the same time; @@ -1524,7 +1471,6 @@ bool LLTextureFetchWorker::doWork(S32 param) if (mFetcher->getHttpWaitersCount() || ! acquireHttpSemaphore()) { setState(WAIT_HTTP_RESOURCE2); - setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); mFetcher->addHttpWaiter(this->mID); ++mResourceWaitCount; return false; @@ -1538,12 +1484,14 @@ bool LLTextureFetchWorker::doWork(S32 param) if (mState == WAIT_HTTP_RESOURCE2) { + LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - WAIT_HTTP_RESOURCE2"); // Just idle it if we make it to the head... return false; } if (mState == SEND_HTTP_REQ) { + LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - SEND_HTTP_REQ"); // Also used in llmeshrepository static LLCachedControl disable_range_req(gSavedSettings, "HttpRangeRequestsDisable", false); @@ -1566,7 +1514,6 @@ bool LLTextureFetchWorker::doWork(S32 param) { // We already have all the data, just decode it mLoadedDiscard = mFormattedImage->getDiscardLevel(); - setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); if (mLoadedDiscard < 0) { LL_WARNS(LOG_TXT) << mID << " mLoadedDiscard is " << mLoadedDiscard @@ -1574,7 +1521,8 @@ bool LLTextureFetchWorker::doWork(S32 param) } setState(DECODE_IMAGE); releaseHttpSemaphore(); - return false; + //return false; + return doWork(param); } else { @@ -1635,7 +1583,6 @@ bool LLTextureFetchWorker::doWork(S32 param) // by people with questionable ISPs or networking gear that // doesn't handle these well. mHttpHandle = mFetcher->mHttpRequest->requestGet(mHttpPolicyClass, - mWorkPriority, mUrl, options, mFetcher->mHttpHeaders, @@ -1644,7 +1591,6 @@ bool LLTextureFetchWorker::doWork(S32 param) else { mHttpHandle = mFetcher->mHttpRequest->requestGetByteRange(mHttpPolicyClass, - mWorkPriority, mUrl, mRequestedOffset, (mRequestedOffset + mRequestedSize) > HTTP_REQUESTS_RANGE_END_MAX @@ -1669,7 +1615,6 @@ bool LLTextureFetchWorker::doWork(S32 param) mHttpActive = true; mFetcher->addToHTTPQueue(mID); recordTextureStart(true); - setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); setState(WAIT_HTTP_REQ); // fall through @@ -1677,6 +1622,7 @@ bool LLTextureFetchWorker::doWork(S32 param) if (mState == WAIT_HTTP_REQ) { + LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - WAIT_HTTP_REQ"); // *NOTE: As stated above, all transitions out of this state should // call releaseHttpSemaphore(). if (mLoaded) @@ -1708,9 +1654,9 @@ bool LLTextureFetchWorker::doWork(S32 param) setState(INIT); mCanUseHTTP = false; mUrl.clear(); - setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); releaseHttpSemaphore(); - return false; + //return false; + return doWork(param); } } else if (http_service_unavail == mGetStatus) @@ -1738,7 +1684,6 @@ bool LLTextureFetchWorker::doWork(S32 param) { // Use available data mLoadedDiscard = mFormattedImage->getDiscardLevel(); - setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); if (mLoadedDiscard < 0) { LL_WARNS(LOG_TXT) << mID << " mLoadedDiscard is " << mLoadedDiscard @@ -1746,7 +1691,8 @@ bool LLTextureFetchWorker::doWork(S32 param) } setState(DECODE_IMAGE); releaseHttpSemaphore(); - return false; + //return false; + return doWork(param); } // Fail harder @@ -1863,9 +1809,9 @@ bool LLTextureFetchWorker::doWork(S32 param) { mWriteToCacheState = SHOULD_WRITE ; } - setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); releaseHttpSemaphore(); - return false; + //return false; + return doWork(param); } else { @@ -1875,17 +1821,16 @@ bool LLTextureFetchWorker::doWork(S32 param) // an enormous amount of time to load textures. We'll revisit the // various possible timeout components (total request time, connection // time, I/O time, with and without retries, etc.) in the future. - - setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); + return false; } } if (mState == DECODE_IMAGE) { + LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - DECODE_IMAGE"); static LLCachedControl textures_decode_disabled(gSavedSettings, "TextureDecodeDisabled", false); - setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it if (textures_decode_disabled) { // for debug use, don't decode @@ -1924,18 +1869,18 @@ bool LLTextureFetchWorker::doWork(S32 param) mAuxImage = NULL; llassert_always(mFormattedImage.notNull()); S32 discard = mHaveAllData ? 0 : mLoadedDiscard; - U32 image_priority = LLWorkerThread::PRIORITY_NORMAL | mWorkPriority; mDecoded = FALSE; setState(DECODE_IMAGE_UPDATE); LL_DEBUGS(LOG_TXT) << mID << ": Decoding. Bytes: " << mFormattedImage->getDataSize() << " Discard: " << discard << " All Data: " << mHaveAllData << LL_ENDL; - mDecodeHandle = mFetcher->mImageDecodeThread->decodeImage(mFormattedImage, image_priority, discard, mNeedsAux, + mDecodeHandle = mFetcher->mImageDecodeThread->decodeImage(mFormattedImage, discard, mNeedsAux, new DecodeResponder(mFetcher, mID, this)); // fall though } if (mState == DECODE_IMAGE_UPDATE) { + LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - DECODE_IMAGE_UPDATE"); if (mDecoded) { if(mFetcher->getFetchDebugger() && !mInLocalCache) @@ -1954,9 +1899,9 @@ bool LLTextureFetchWorker::doWork(S32 param) llassert_always(mDecodeHandle == 0); mFormattedImage = NULL; ++mRetryAttempt; - setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); setState(INIT); - return false; + //return false; + return doWork(param); } else { @@ -1969,7 +1914,6 @@ bool LLTextureFetchWorker::doWork(S32 param) llassert_always(mRawImage.notNull()); LL_DEBUGS(LOG_TXT) << mID << ": Decoded. Discard: " << mDecodedDiscard << " Raw Image: " << llformat("%dx%d",mRawImage->getWidth(),mRawImage->getHeight()) << LL_ENDL; - setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); setState(WRITE_TO_CACHE); } // fall through @@ -1982,12 +1926,14 @@ bool LLTextureFetchWorker::doWork(S32 param) if (mState == WRITE_TO_CACHE) { + LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - WRITE_TO_CACHE"); if (mWriteToCacheState != SHOULD_WRITE || mFormattedImage.isNull()) { // If we're in a local cache or we didn't actually receive any new data, // or we failed to load anything, skip setState(DONE); - return false; + //return false; + return doWork(param); } S32 datasize = mFormattedImage->getDataSize(); if(mFileSize < datasize)//This could happen when http fetching and sim fetching mixed. @@ -2002,8 +1948,6 @@ bool LLTextureFetchWorker::doWork(S32 param) } } llassert_always(datasize); - setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it - U32 cache_priority = mWorkPriority; mWritten = FALSE; setState(WAIT_ON_WRITE); ++mCacheWriteCount; @@ -2014,7 +1958,7 @@ bool LLTextureFetchWorker::doWork(S32 param) // So make sure users of getRequestFinished() does not attempt to modify image while // fetcher is working mCacheWriteTimer.reset(); - mCacheWriteHandle = mFetcher->mTextureCache->writeToCache(mID, cache_priority, + mCacheWriteHandle = mFetcher->mTextureCache->writeToCache(mID, mFormattedImage->getData(), datasize, mFileSize, mRawImage, mDecodedDiscard, responder); // fall through @@ -2022,6 +1966,7 @@ bool LLTextureFetchWorker::doWork(S32 param) if (mState == WAIT_ON_WRITE) { + LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - WAIT_ON_WRITE"); if (writeToCacheComplete()) { mCacheWriteTime = mCacheWriteTimer.getElapsedTimeF32(); @@ -2043,6 +1988,7 @@ bool LLTextureFetchWorker::doWork(S32 param) if (mState == DONE) { + LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - DONE"); if (mDecodedDiscard >= 0 && mDesiredDiscard < mDecodedDiscard) { // More data was requested, return to INIT @@ -2050,12 +1996,11 @@ bool LLTextureFetchWorker::doWork(S32 param) LL_DEBUGS(LOG_TXT) << mID << " more data requested, returning to INIT: " << " mDecodedDiscard " << mDecodedDiscard << ">= 0 && mDesiredDiscard " << mDesiredDiscard << "<" << " mDecodedDiscard " << mDecodedDiscard << LL_ENDL; - setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); - return false; + // return false; + return doWork(param); } else { - setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); mFetchTime = mFetchTimer.getElapsedTimeF32(); return true; } @@ -2068,6 +2013,7 @@ bool LLTextureFetchWorker::doWork(S32 param) // virtual void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response) { + LL_PROFILE_ZONE_SCOPED; static LLCachedControl log_to_viewer_log(gSavedSettings, "LogTextureDownloadsToViewerLog", false); static LLCachedControl log_to_sim(gSavedSettings, "LogTextureDownloadsToSimulator", false); static LLCachedControl log_texture_traffic(gSavedSettings, "LogTextureNetworkTraffic", false) ; @@ -2177,6 +2123,7 @@ void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRe // Threads: Tmain void LLTextureFetchWorker::endWork(S32 param, bool aborted) { + LL_PROFILE_ZONE_SCOPED; if (mDecodeHandle != 0) { mFetcher->mImageDecodeThread->abortRequest(mDecodeHandle, false); @@ -2192,6 +2139,7 @@ void LLTextureFetchWorker::endWork(S32 param, bool aborted) // virtual void LLTextureFetchWorker::finishWork(S32 param, bool completed) { + LL_PROFILE_ZONE_SCOPED; // The following are required in case the work was aborted if (mCacheReadHandle != LLTextureCache::nullHandle()) { @@ -2445,7 +2393,6 @@ S32 LLTextureFetchWorker::callbackHttpGet(LLCore::HttpResponse * response, } mLoaded = TRUE; - setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); if (LLViewerStatsRecorder::instanceExists()) { @@ -2461,6 +2408,7 @@ S32 LLTextureFetchWorker::callbackHttpGet(LLCore::HttpResponse * response, void LLTextureFetchWorker::callbackCacheRead(bool success, LLImageFormatted* image, S32 imagesize, BOOL islocal) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; LLMutexLock lock(&mWorkMutex); // +Mw if (mState != LOAD_FROM_TEXTURE_CACHE) { @@ -2480,7 +2428,6 @@ void LLTextureFetchWorker::callbackCacheRead(bool success, LLImageFormatted* ima } } mLoaded = TRUE; - setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); } // -Mw // Threads: Ttc @@ -2493,7 +2440,6 @@ void LLTextureFetchWorker::callbackCacheWrite(bool success) return; } mWritten = TRUE; - setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); } // -Mw ////////////////////////////////////////////////////////////////////////////// @@ -2532,7 +2478,6 @@ void LLTextureFetchWorker::callbackDecoded(bool success, LLImageRaw* raw, LLImag } mDecoded = TRUE; // LL_INFOS(LOG_TXT) << mID << " : DECODE COMPLETE " << LL_ENDL; - setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); } // -Mw ////////////////////////////////////////////////////////////////////////////// @@ -2595,6 +2540,16 @@ void LLTextureFetchWorker::recordTextureDone(bool is_http, F64 byte_count) ////////////////////////////////////////////////////////////////////////////// // public +const char* LLTextureFetch::getStateString(S32 state) +{ + if (state < 0 || state > sizeof(e_state_name) / sizeof(char*)) + { + return llformat("%d", state).c_str(); + } + + return e_state_name[state]; +} + LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* imagedecodethread, bool threaded, bool qa_mode) : LLWorkerThread("TextureFetch", threaded, true), mDebugCount(0), @@ -2695,6 +2650,7 @@ LLTextureFetch::~LLTextureFetch() bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority, S32 w, S32 h, S32 c, S32 desired_discard, bool needs_aux, bool can_use_http) { + LL_PROFILE_ZONE_SCOPED; if(mFetcherLocked) { return false; @@ -2786,7 +2742,7 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const worker->setState(LLTextureFetchWorker::INIT); worker->unlockWorkMutex(); // -Mw - worker->addWork(0, LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority); + worker->addWork(0); } else { @@ -2818,6 +2774,7 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const // protected void LLTextureFetch::addToNetworkQueue(LLTextureFetchWorker* worker) { + LL_PROFILE_ZONE_SCOPED; lockQueue(); // +Mfq bool in_request_map = (mRequestMap.find(worker->mID) != mRequestMap.end()) ; unlockQueue(); // -Mfq @@ -2839,6 +2796,7 @@ void LLTextureFetch::addToNetworkQueue(LLTextureFetchWorker* worker) // Threads: T* void LLTextureFetch::removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel) { + LL_PROFILE_ZONE_SCOPED; LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq size_t erased = mNetworkQueue.erase(worker->mID); if (cancel && erased > 0) @@ -2852,6 +2810,7 @@ void LLTextureFetch::removeFromNetworkQueue(LLTextureFetchWorker* worker, bool c // protected void LLTextureFetch::addToHTTPQueue(const LLUUID& id) { + LL_PROFILE_ZONE_SCOPED; LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq mHTTPTextureQueue.insert(id); mTotalHTTPRequests++; @@ -2860,6 +2819,7 @@ void LLTextureFetch::addToHTTPQueue(const LLUUID& id) // Threads: T* void LLTextureFetch::removeFromHTTPQueue(const LLUUID& id, S32Bytes received_size) { + LL_PROFILE_ZONE_SCOPED; LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq mHTTPTextureQueue.erase(id); mHTTPTextureBits += received_size; // Approximate - does not include header bits @@ -2872,6 +2832,7 @@ void LLTextureFetch::removeFromHTTPQueue(const LLUUID& id, S32Bytes received_siz // Threads: T* void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel) { + LL_PROFILE_ZONE_SCOPED; lockQueue(); // +Mfq LLTextureFetchWorker* worker = getWorkerAfterLock(id); if (worker) @@ -2898,6 +2859,7 @@ void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel) // Threads: T* void LLTextureFetch::removeRequest(LLTextureFetchWorker* worker, bool cancel) { + LL_PROFILE_ZONE_SCOPED; if(!worker) { return; @@ -2967,6 +2929,7 @@ U32 LLTextureFetch::getTotalNumHTTPRequests() // Locks: Mfq LLTextureFetchWorker* LLTextureFetch::getWorkerAfterLock(const LLUUID& id) { + LL_PROFILE_ZONE_SCOPED; LLTextureFetchWorker* res = NULL; map_t::iterator iter = mRequestMap.find(id); if (iter != mRequestMap.end()) @@ -2990,6 +2953,7 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level, LLPointer& raw, LLPointer& aux, LLCore::HttpStatus& last_http_get_status) { + LL_PROFILE_ZONE_SCOPED; bool res = false; LLTextureFetchWorker* worker = getWorker(id); if (worker) @@ -3004,7 +2968,7 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level, if (!mDebugPause) { // LL_WARNS(LOG_TXT) << "Adding work for inactive worker: " << id << LL_ENDL; - worker->addWork(0, LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority); + worker->addWork(0); } } else if (worker->checkWork()) @@ -3080,6 +3044,7 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level, // Threads: T* bool LLTextureFetch::updateRequestPriority(const LLUUID& id, F32 priority) { + LL_PROFILE_ZONE_SCOPED; bool res = false; LLTextureFetchWorker* worker = getWorker(id); if (worker) @@ -3106,6 +3071,7 @@ bool LLTextureFetch::updateRequestPriority(const LLUUID& id, F32 priority) //virtual S32 LLTextureFetch::getPending() { + LL_PROFILE_ZONE_SCOPED; S32 res; lockData(); // +Ct { @@ -3139,7 +3105,7 @@ bool LLTextureFetch::runCondition() } // -Mfq return ! (have_no_commands - && (mRequestQueue.empty() && mIdleThread)); // From base class + && (mRequestQueue.size() == 0 && mIdleThread)); // From base class } ////////////////////////////////////////////////////////////////////////////// @@ -3147,6 +3113,7 @@ bool LLTextureFetch::runCondition() // Threads: Ttf void LLTextureFetch::commonUpdate() { + LL_PROFILE_ZONE_SCOPED; // Update low/high water levels based on pipelining. We pick // up setting eventually, so the semaphore/request level can // fall outside the [0..HIGH_WATER] range. Expect that. @@ -3183,6 +3150,7 @@ void LLTextureFetch::commonUpdate() //virtual S32 LLTextureFetch::update(F32 max_time_ms) { + LL_PROFILE_ZONE_SCOPED; static LLCachedControl band_width(gSavedSettings,"ThrottleBandwidthKBPS", 3000.0); { @@ -3266,6 +3234,7 @@ void LLTextureFetch::endThread() // Threads: Ttf void LLTextureFetch::threadedUpdate() { + LL_PROFILE_ZONE_SCOPED; llassert_always(mHttpRequest); #if 0 @@ -3301,6 +3270,7 @@ void LLTextureFetch::threadedUpdate() // Threads: Tmain void LLTextureFetch::sendRequestListToSimulators() { + LL_PROFILE_ZONE_SCOPED; // All requests const F32 REQUEST_DELTA_TIME = 0.10f; // 10 fps @@ -3351,7 +3321,6 @@ void LLTextureFetch::sendRequestListToSimulators() req->mLastPacket >= req->mTotalPackets-1) { // We have all the packets... make sure this is high priority -// req->setPriority(LLWorkerThread::PRIORITY_HIGH | req->mWorkPriority); continue; } F32 elapsed = req->mRequestedDeltaTimer.getElapsedTimeF32(); @@ -3498,6 +3467,7 @@ void LLTextureFetch::sendRequestListToSimulators() // Locks: Mw bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size) { + LL_PROFILE_ZONE_SCOPED; mRequestedDeltaTimer.reset(); if (index >= mTotalPackets) { @@ -3530,6 +3500,7 @@ bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size) void LLTextureFetchWorker::setState(e_state new_state) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if (mFTType == FTT_SERVER_BAKE) { // NOTE: turning on these log statements is a reliable way to get @@ -3551,7 +3522,7 @@ void LLTextureFetchWorker::setState(e_state new_state) mSkippedStatesTime += d_time; } } - + mStateTimer.reset(); mState = new_state; } @@ -3560,6 +3531,7 @@ void LLTextureFetchWorker::setState(e_state new_state) bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes, U16 data_size, U8* data) { + LL_PROFILE_ZONE_SCOPED; LLTextureFetchWorker* worker = getWorker(id); bool res = true; @@ -3611,7 +3583,6 @@ bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8 llassert_always(totalbytes > 0); llassert_always(data_size == FIRST_PACKET_SIZE || data_size == worker->mFileSize); res = worker->insertPacket(0, data, data_size); - worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority); worker->setState(LLTextureFetchWorker::LOAD_FROM_SIMULATOR); worker->unlockWorkMutex(); // -Mw return res; @@ -3621,6 +3592,7 @@ bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8 // Threads: T* bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U16 packet_num, U16 data_size, U8* data) { + LL_PROFILE_ZONE_SCOPED; LLTextureFetchWorker* worker = getWorker(id); bool res = true; @@ -3661,7 +3633,6 @@ bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U1 if ((worker->mState == LLTextureFetchWorker::LOAD_FROM_SIMULATOR) || (worker->mState == LLTextureFetchWorker::LOAD_FROM_NETWORK)) { - worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority); worker->setState(LLTextureFetchWorker::LOAD_FROM_SIMULATOR); } else @@ -3706,10 +3677,23 @@ BOOL LLTextureFetch::isFromLocalCache(const LLUUID& id) return from_cache ; } +S32 LLTextureFetch::getFetchState(const LLUUID& id) +{ + S32 state = LLTextureFetchWorker::INVALID; + LLTextureFetchWorker* worker = getWorker(id); + if (worker && worker->haveWork()) + { + state = worker->mState; + } + + return state; +} + // Threads: T* S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& requested_priority_p, U32& fetch_priority_p, F32& fetch_dtime_p, F32& request_dtime_p, bool& can_use_http) { + LL_PROFILE_ZONE_SCOPED; S32 state = LLTextureFetchWorker::INVALID; F32 data_progress = 0.0f; F32 requested_priority = 0.0f; @@ -3745,7 +3729,7 @@ S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& r { requested_priority = worker->mImagePriority; } - fetch_priority = worker->getPriority(); + fetch_priority = worker->getImagePriority(); can_use_http = worker->getCanUseHTTP() ; worker->unlockWorkMutex(); // -Mw } @@ -3759,19 +3743,6 @@ S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& r void LLTextureFetch::dump() { - LL_INFOS(LOG_TXT) << "LLTextureFetch REQUESTS:" << LL_ENDL; - for (request_queue_t::iterator iter = mRequestQueue.begin(); - iter != mRequestQueue.end(); ++iter) - { - LLQueuedThread::QueuedRequest* qreq = *iter; - LLWorkerThread::WorkRequest* wreq = (LLWorkerThread::WorkRequest*)qreq; - LLTextureFetchWorker* worker = (LLTextureFetchWorker*)wreq->getWorkerClass(); - LL_INFOS(LOG_TXT) << " ID: " << worker->mID - << " PRI: " << llformat("0x%08x",wreq->getPriority()) - << " STATE: " << sStateDescs[worker->mState] - << LL_ENDL; - } - LL_INFOS(LOG_TXT) << "LLTextureFetch ACTIVE_HTTP:" << LL_ENDL; for (queue_t::const_iterator iter(mHTTPTextureQueue.begin()); mHTTPTextureQueue.end() != iter; @@ -3838,6 +3809,7 @@ bool LLTextureFetch::isHttpWaiter(const LLUUID & tid) // Locks: -Mw (must not hold any worker when called) void LLTextureFetch::releaseHttpWaiters() { + LL_PROFILE_ZONE_SCOPED; // Use mHttpSemaphore rather than mHTTPTextureQueue.size() // to avoid a lock. if (mHttpSemaphore >= mHttpLowWater) @@ -3934,7 +3906,6 @@ void LLTextureFetch::releaseHttpWaiters() } worker->setState(LLTextureFetchWorker::SEND_HTTP_REQ); - worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority); worker->unlockWorkMutex(); // -Mw removeHttpWaiter(worker->mID); @@ -4024,6 +3995,7 @@ void LLTextureFetch::commandDataBreak() // Threads: T* void LLTextureFetch::cmdEnqueue(TFRequest * req) { + LL_PROFILE_ZONE_SCOPED; lockQueue(); // +Mfq mCommands.push_back(req); unlockQueue(); // -Mfq @@ -4034,6 +4006,7 @@ void LLTextureFetch::cmdEnqueue(TFRequest * req) // Threads: T* LLTextureFetch::TFRequest * LLTextureFetch::cmdDequeue() { + LL_PROFILE_ZONE_SCOPED; TFRequest * ret = 0; lockQueue(); // +Mfq @@ -4050,6 +4023,7 @@ LLTextureFetch::TFRequest * LLTextureFetch::cmdDequeue() // Threads: Ttf void LLTextureFetch::cmdDoWork() { + LL_PROFILE_ZONE_SCOPED; if (mDebugPause) { return; // debug: don't do any work @@ -4140,6 +4114,7 @@ TFReqSendMetrics::~TFReqSendMetrics() bool TFReqSendMetrics::doWork(LLTextureFetch * fetcher) { + LL_PROFILE_ZONE_SCOPED; static const U32 report_priority(1); //if (! gViewerAssetStatsThread1) @@ -4183,7 +4158,6 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher) // Don't care about handle, this is a fire-and-forget operation. LLCoreHttpUtil::requestPostWithLLSD(&fetcher->getHttpRequest(), fetcher->getMetricsPolicyClass(), - report_priority, mCapsURL, mStatsSD, LLCore::HttpOptions::ptr_t(), @@ -4630,7 +4604,7 @@ void LLTextureFetchDebugger::debugCacheRead() for(S32 i = 0 ; i < size ; i++) { mFetchingHistory[i].mFormattedImage = NULL; - mFetchingHistory[i].mCacheHandle = mTextureCache->readFromCache(mFetchingHistory[i].mID, LLWorkerThread::PRIORITY_NORMAL, 0, mFetchingHistory[i].mFetchedSize, + mFetchingHistory[i].mCacheHandle = mTextureCache->readFromCache(mFetchingHistory[i].mID, 0, mFetchingHistory[i].mFetchedSize, new LLDebuggerCacheReadResponder(this, i, mFetchingHistory[i].mFormattedImage)); } } @@ -4667,8 +4641,8 @@ void LLTextureFetchDebugger::debugCacheWrite() { if(mFetchingHistory[i].mFormattedImage.notNull()) { - mFetchingHistory[i].mCacheHandle = mTextureCache->writeToCache(mFetchingHistory[i].mID, LLWorkerThread::PRIORITY_NORMAL, - mFetchingHistory[i].mFormattedImage->getData(), mFetchingHistory[i].mFetchedSize, + mFetchingHistory[i].mCacheHandle = mTextureCache->writeToCache(mFetchingHistory[i].mID, + mFetchingHistory[i].mFormattedImage->getData(), mFetchingHistory[i].mFetchedSize, mFetchingHistory[i].mDecodedLevel == 0 ? mFetchingHistory[i].mFetchedSize : mFetchingHistory[i].mFetchedSize + 1, NULL, 0, new LLDebuggerCacheWriteResponder(this, i)); } @@ -4699,7 +4673,7 @@ void LLTextureFetchDebugger::debugDecoder() continue; } - mImageDecodeThread->decodeImage(mFetchingHistory[i].mFormattedImage, LLWorkerThread::PRIORITY_NORMAL, + mImageDecodeThread->decodeImage(mFetchingHistory[i].mFormattedImage, mFetchingHistory[i].mDecodedLevel, mFetchingHistory[i].mNeedsAux, new LLDebuggerDecodeResponder(this, i)); } @@ -4767,7 +4741,6 @@ S32 LLTextureFetchDebugger::fillCurlQueue() requestedSize = (requestedSize == 33554432 ? 0 : requestedSize); LLCore::HttpHandle handle = mFetcher->getHttpRequest().requestGetByteRange(mHttpPolicyClass, - LLWorkerThread::PRIORITY_LOWBITS, texture_url, 0, requestedSize, diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index bf6732963f..0cf9775af2 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -59,6 +59,8 @@ class LLTextureFetch : public LLWorkerThread friend class LLTextureFetchWorker; public: + static const char* getStateString(S32 state); + LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* imagedecodethread, bool threaded, bool qa_mode); ~LLTextureFetch(); @@ -116,10 +118,11 @@ public: // Threads: T* BOOL isFromLocalCache(const LLUUID& id); - // @return Magic number giving the internal state of the - // request. We should make these codes public if we're - // going to return them as a status value. - // + // get the current fetch state, if any, from the given UUID + S32 getFetchState(const LLUUID& id); + + // @return Fetch state of given image and associates statistics + // See also getStateString // Threads: T* S32 getFetchState(const LLUUID& id, F32& decode_progress_p, F32& requested_priority_p, U32& fetch_priority_p, F32& fetch_dtime_p, F32& request_dtime_p, bool& can_use_http); diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index 99ab854293..f0e9cee101 100644 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -119,8 +119,8 @@ public: LLTextureBar* bar2p = (LLTextureBar*)i2; LLViewerFetchedTexture *i1p = bar1p->mImagep; LLViewerFetchedTexture *i2p = bar2p->mImagep; - F32 pri1 = i1p->getDecodePriority(); // i1p->mRequestedDownloadPriority - F32 pri2 = i2p->getDecodePriority(); // i2p->mRequestedDownloadPriority + F32 pri1 = i1p->getMaxVirtualSize(); + F32 pri2 = i2p->getMaxVirtualSize(); if (pri1 > pri2) return true; else if (pri2 > pri1) @@ -179,7 +179,7 @@ void LLTextureBar::draw() { color = LLColor4::magenta; // except none and alm } - else if (mImagep->getDecodePriority() <= 0.0f) + else if (mImagep->getMaxVirtualSize() <= 0.0f) { color = LLColor4::grey; color[VALPHA] = .7f; } @@ -204,26 +204,13 @@ void LLTextureBar::draw() std::string uuid_str; mImagep->mID.toString(uuid_str); uuid_str = uuid_str.substr(0,7); - if (mTextureView->mOrderFetch) - { - tex_str = llformat("%s %7.0f %d(%d) 0x%08x(%8.0f)", - uuid_str.c_str(), - mImagep->mMaxVirtualSize, - mImagep->mDesiredDiscardLevel, - mImagep->mRequestedDiscardLevel, - mImagep->mFetchPriority, - mImagep->getDecodePriority()); - } - else - { - tex_str = llformat("%s %7.0f %d(%d) %8.0f(0x%08x)", - uuid_str.c_str(), - mImagep->mMaxVirtualSize, - mImagep->mDesiredDiscardLevel, - mImagep->mRequestedDiscardLevel, - mImagep->getDecodePriority(), - mImagep->mFetchPriority); - } + + tex_str = llformat("%s %7.0f %d(%d)", + uuid_str.c_str(), + mImagep->mMaxVirtualSize, + mImagep->mDesiredDiscardLevel, + mImagep->mRequestedDiscardLevel); + LLFontGL::getFontMonospace()->renderUTF8(tex_str, 0, title_x1, getRect().getHeight(), color, LLFontGL::LEFT, LLFontGL::TOP); @@ -547,7 +534,7 @@ void LLGLTexMemBar::draw() U32 texFetchLatMed = U32(recording.getMean(LLTextureFetch::sTexFetchLatency).value() * 1000.0f); U32 texFetchLatMax = U32(recording.getMax(LLTextureFetch::sTexFetchLatency).value() * 1000.0f); - text = llformat("GL Free: %d Sys Free: %d MB FBO: %d MB Bias: %.2f Cache: %.1f/%.1f MB", + text = llformat("GL Free: %d MB Sys Free: %d MB FBO: %d MB Bias: %.2f Cache: %.1f/%.1f MB", gViewerWindow->getWindow()->getAvailableVRAMMegabytes(), LLMemory::getAvailableMemKB()/1024, LLRenderTarget::sBytesAllocated/(1024*1024), @@ -830,7 +817,7 @@ void LLTextureView::draw() LL_INFOS() << imagep->getID() << "\t" << tex_mem << "\t" << imagep->getBoostLevel() - << "\t" << imagep->getDecodePriority() + << "\t" << imagep->getMaxVirtualSize() << "\t" << imagep->getWidth() << "\t" << imagep->getHeight() << "\t" << cur_discard @@ -850,7 +837,7 @@ void LLTextureView::draw() } else { - pri = imagep->getDecodePriority(); + pri = imagep->getMaxVirtualSize(); } pri = llclamp(pri, 0.0f, HIGH_PRIORITY-1.f); diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 4618871630..602597a86b 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -341,12 +341,6 @@ static bool handleMaxPartCountChanged(const LLSD& newvalue) return true; } -static bool handleVideoMemoryChanged(const LLSD& newvalue) -{ - gTextureList.updateMaxResidentTexMem(S32Megabytes(newvalue.asInteger())); - return true; -} - static bool handleChatFontSizeChanged(const LLSD& newvalue) { if(gConsole) @@ -697,7 +691,6 @@ void settings_setup_listeners() gSavedSettings.getControl("RenderShadowDetail")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); gSavedSettings.getControl("RenderDeferredSSAO")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); gSavedSettings.getControl("RenderPerformanceTest")->getSignal()->connect(boost::bind(&handleRenderPerfTestChanged, _2)); - gSavedSettings.getControl("TextureMemory")->getSignal()->connect(boost::bind(&handleVideoMemoryChanged, _2)); gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&handleChatFontSizeChanged, _2)); gSavedSettings.getControl("ChatPersistTime")->getSignal()->connect(boost::bind(&handleChatPersistTimeChanged, _2)); gSavedSettings.getControl("ConsoleMaxLines")->getSignal()->connect(boost::bind(&handleConsoleMaxLinesChanged, _2)); diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index ac6c86d9c6..06673b50fa 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -78,6 +78,8 @@ LLPointer LLViewerFetchedTexture::sSmokeImagep = NULL; LLPointer LLViewerFetchedTexture::sFlatNormalImagep = NULL; LLViewerMediaTexture::media_map_t LLViewerMediaTexture::sMediaMap; LLTexturePipelineTester* LLViewerTextureManager::sTesterp = NULL; +F32 LLViewerFetchedTexture::sMaxVirtualSize = F32_MAX/2.f; + const std::string sTesterName("TextureTester"); S32 LLViewerTexture::sImageCount = 0; @@ -490,7 +492,7 @@ bool LLViewerTexture::isMemoryForTextureLow() S32Megabytes physical; getGPUMemoryForTextures(gpu, physical); - return (gpu < MIN_FREE_TEXTURE_MEMORY) || (physical < MIN_FREE_MAIN_MEMORY); + return (gpu < MIN_FREE_TEXTURE_MEMORY); // || (physical < MIN_FREE_MAIN_MEMORY); } //static @@ -504,7 +506,7 @@ bool LLViewerTexture::isMemoryForTextureSuficientlyFree() S32Megabytes physical; getGPUMemoryForTextures(gpu, physical); - return (gpu > DESIRED_FREE_TEXTURE_MEMORY) && (physical > DESIRED_FREE_MAIN_MEMORY); + return (gpu > DESIRED_FREE_TEXTURE_MEMORY); // && (physical > DESIRED_FREE_MAIN_MEMORY); } //static @@ -629,7 +631,6 @@ void LLViewerTexture::init(bool firstinit) mMaxVirtualSize = 0.f; mMaxVirtualSizeResetInterval = 1; mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval; - mAdditionalDecodePriority = 0.f; mParcelMedia = NULL; memset(&mNumVolumes, 0, sizeof(U32)* LLRender::NUM_VOLUME_TEXTURE_CHANNELS); @@ -796,15 +797,14 @@ void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) co } virtual_size *= sTexelPixelRatio; - if(!mMaxVirtualSizeResetCounter) + /*if (!mMaxVirtualSizeResetCounter) { //flag to reset the values because the old values are used. resetMaxVirtualSizeResetCounter(); mMaxVirtualSize = virtual_size; - mAdditionalDecodePriority = 0.f; mNeedsGLTexture = needs_gltexture; } - else if (virtual_size > mMaxVirtualSize) + else*/ if (virtual_size > mMaxVirtualSize) { mMaxVirtualSize = virtual_size; } @@ -813,7 +813,6 @@ void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) co void LLViewerTexture::resetTextureStats() { mMaxVirtualSize = 0.0f; - mAdditionalDecodePriority = 0.f; mMaxVirtualSizeResetCounter = 0; } @@ -1082,7 +1081,6 @@ void LLViewerFetchedTexture::init(bool firstinit) if (firstinit) { - mDecodePriority = 0.f; mInImageList = 0; } @@ -1131,6 +1129,7 @@ void LLViewerFetchedTexture::init(bool firstinit) LLViewerFetchedTexture::~LLViewerFetchedTexture() { + assert_main_thread(); //*NOTE getTextureFetch can return NULL when Viewer is shutting down. // This is due to LLWearableList is singleton and is destroyed after // LLAppViewer::cleanup() was called. (see ticket EXT-177) @@ -1563,6 +1562,7 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/) void LLViewerFetchedTexture::postCreateTexture() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if (!mNeedsCreateTexture) { return; @@ -1586,6 +1586,8 @@ void LLViewerFetchedTexture::postCreateTexture() void LLViewerFetchedTexture::scheduleCreateTexture() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; + if (!mNeedsCreateTexture) { mNeedsCreateTexture = TRUE; @@ -1662,6 +1664,7 @@ void LLViewerFetchedTexture::scheduleCreateTexture() //virtual void LLViewerFetchedTexture::setKnownDrawSize(S32 width, S32 height) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if(mKnownDrawWidth < width || mKnownDrawHeight < height) { mKnownDrawWidth = llmax(mKnownDrawWidth, width); @@ -1673,9 +1676,31 @@ void LLViewerFetchedTexture::setKnownDrawSize(S32 width, S32 height) addTextureStats((F32)(mKnownDrawWidth * mKnownDrawHeight)); } +void LLViewerFetchedTexture::setDebugText(const std::string& text) +{ + for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch) + { + llassert(mNumFaces[ch] <= mFaceList[ch].size()); + + for (U32 i = 0; i < mNumFaces[ch]; i++) + { + LLFace* facep = mFaceList[ch][i]; + if (facep) + { + LLDrawable* drawable = facep->getDrawable(); + if (drawable) + { + drawable->getVObj()->setDebugText(text); + } + } + } + } +} + //virtual void LLViewerFetchedTexture::processTextureStats() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if(mFullyLoaded) { if(mDesiredDiscardLevel > mMinDesiredDiscardLevel)//need to load more @@ -1683,6 +1708,7 @@ void LLViewerFetchedTexture::processTextureStats() mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, mMinDesiredDiscardLevel); mFullyLoaded = FALSE; } + //setDebugText("fully loaded"); } else { @@ -1695,7 +1721,7 @@ void LLViewerFetchedTexture::processTextureStats() mDesiredDiscardLevel = 0; } else if (!LLPipeline::sRenderDeferred && mBoostLevel == LLGLTexture::BOOST_ALM) - { + { // ??? don't load spec and normal maps when alm is disabled ??? mDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1; } else if (mDontDiscard && mBoostLevel == LLGLTexture::BOOST_ICON) @@ -1760,191 +1786,9 @@ const S32 MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY = 4; const F32 PRIORITY_ADDITIONAL_FACTOR = 1000000.f; //additional const S32 MAX_ADDITIONAL_LEVEL_FOR_PRIORITY = 8; const F32 PRIORITY_BOOST_HIGH_FACTOR = 10000000.f;//boost high -F32 LLViewerFetchedTexture::calcDecodePriority() -{ -#ifndef LL_RELEASE_FOR_DOWNLOAD - if (mID == LLAppViewer::getTextureFetch()->mDebugID) - { - LLAppViewer::getTextureFetch()->mDebugCount++; // for setting breakpoints - } -#endif - - if (mNeedsCreateTexture) - { - return mDecodePriority; // no change while waiting to create - } - if(mFullyLoaded && !mForceToSaveRawImage)//already loaded for static texture - { - return -1.0f; //alreay fetched - } - - S32 cur_discard = getCurrentDiscardLevelForFetching(); - bool have_all_data = (cur_discard >= 0 && (cur_discard <= mDesiredDiscardLevel)); - F32 pixel_priority = (F32) sqrt(mMaxVirtualSize); - - F32 priority = 0.f; - - if (mIsMissingAsset) - { - priority = 0.0f; - } - else if(mDesiredDiscardLevel >= cur_discard && cur_discard > -1) - { - priority = -2.0f; - } - else if(mCachedRawDiscardLevel > -1 && mDesiredDiscardLevel >= mCachedRawDiscardLevel) - { - priority = -3.0f; - } - else if (mDesiredDiscardLevel > getMaxDiscardLevel()) - { - // Don't decode anything we don't need - priority = -4.0f; - } - else if ((mBoostLevel == LLGLTexture::BOOST_UI || mBoostLevel == LLGLTexture::BOOST_ICON) && !have_all_data) - { - priority = 1.f; - } - else if (pixel_priority < 0.001f && !have_all_data) - { - // Not on screen but we might want some data - if (mBoostLevel > BOOST_SELECTED) - { - // Always want high boosted images - priority = 1.f; - } - else - { - priority = -5.f; //stop fetching - } - } - else if (cur_discard < 0) - { - //texture does not have any data, so we don't know the size of the image, treat it like 32 * 32. - // priority range = 100,000 - 500,000 - static const F64 log_2 = log(2.0); - F32 desired = (F32)(log(32.0/pixel_priority) / log_2); - S32 ddiscard = MAX_DISCARD_LEVEL - (S32)desired; - ddiscard = llclamp(ddiscard, 0, MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY); - priority = (ddiscard + 1) * PRIORITY_DELTA_DISCARD_LEVEL_FACTOR; - setAdditionalDecodePriority(0.1f);//boost the textures without any data so far. - } - else if ((mMinDiscardLevel > 0) && (cur_discard <= mMinDiscardLevel)) - { - // larger mips are corrupted - priority = -6.0f; - } - else - { - // priority range = 100,000 - 500,000 - S32 desired_discard = mDesiredDiscardLevel; - if (!isJustBound() && mCachedRawImageReady) - { - if(mBoostLevel < BOOST_HIGH) - { - // We haven't rendered this in a while, de-prioritize it - desired_discard += 2; - } - else - { - // We haven't rendered this in the last half second, and we have a cached raw image, leave the desired discard as-is - desired_discard = cur_discard; - } - } - - S32 ddiscard = cur_discard - desired_discard; - ddiscard = llclamp(ddiscard, -1, MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY); - priority = (ddiscard + 1) * PRIORITY_DELTA_DISCARD_LEVEL_FACTOR; - } - - // Priority Formula: - // BOOST_HIGH + ADDITIONAL PRI + DELTA DISCARD + BOOST LEVEL + PIXELS - // [10,000,000] + [1,000,000-9,000,000] + [100,000-500,000] + [1-20,000] + [0-999] - if (priority > 0.0f) - { - bool large_enough = mCachedRawImageReady && ((S32)mTexelsPerImage > sMinLargeImageSize); - if(large_enough) - { - //Note: - //to give small, low-priority textures some chance to be fetched, - //cut the priority in half if the texture size is larger than 256 * 256 and has a 64*64 ready. - priority *= 0.5f; - } - - pixel_priority = llclamp(pixel_priority, 0.0f, MAX_PRIORITY_PIXEL); - - priority += pixel_priority + PRIORITY_BOOST_LEVEL_FACTOR * mBoostLevel; - - if ( mBoostLevel > BOOST_HIGH) - { - if(mBoostLevel > BOOST_SUPER_HIGH) - { - //for very important textures, always grant the highest priority. - priority += PRIORITY_BOOST_HIGH_FACTOR; - } - else if(mCachedRawImageReady) - { - //Note: - //to give small, low-priority textures some chance to be fetched, - //if high priority texture has a 64*64 ready, lower its fetching priority. - setAdditionalDecodePriority(0.5f); - } - else - { - priority += PRIORITY_BOOST_HIGH_FACTOR; - } - } - - if(mAdditionalDecodePriority > 0.0f) - { - // priority range += 1,000,000.f-9,000,000.f - F32 additional = PRIORITY_ADDITIONAL_FACTOR * (1.0 + mAdditionalDecodePriority * MAX_ADDITIONAL_LEVEL_FOR_PRIORITY); - if(large_enough) - { - //Note: - //to give small, low-priority textures some chance to be fetched, - //cut the additional priority to a quarter if the texture size is larger than 256 * 256 and has a 64*64 ready. - additional *= 0.25f; - } - priority += additional; - } - } - return priority; -} - -//static -F32 LLViewerFetchedTexture::maxDecodePriority() -{ - static const F32 max_priority = PRIORITY_BOOST_HIGH_FACTOR + //boost_high - PRIORITY_ADDITIONAL_FACTOR * (MAX_ADDITIONAL_LEVEL_FOR_PRIORITY + 1) + //additional (view dependent factors) - PRIORITY_DELTA_DISCARD_LEVEL_FACTOR * (MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY + 1) + //delta discard - PRIORITY_BOOST_LEVEL_FACTOR * (BOOST_MAX_LEVEL - 1) + //boost level - MAX_PRIORITY_PIXEL + 1.0f; //pixel area. - - return max_priority; -} //============================================================================ -void LLViewerFetchedTexture::setDecodePriority(F32 priority) -{ - mDecodePriority = priority; - - if(mDecodePriority < F_ALMOST_ZERO) - { - mStopFetchingTimer.reset(); - } -} - -void LLViewerFetchedTexture::setAdditionalDecodePriority(F32 priority) -{ - priority = llclamp(priority, 0.f, 1.f); - if(mAdditionalDecodePriority < priority) - { - mAdditionalDecodePriority = priority; - } -} - void LLViewerFetchedTexture::updateVirtualSize() { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; @@ -1953,6 +1797,12 @@ void LLViewerFetchedTexture::updateVirtualSize() addTextureStats(0.f, FALSE);//reset } + if (getBoostLevel() >= LLViewerTexture::BOOST_HIGH) + { //always load boosted textures at highest priority full res + addTextureStats(sMaxVirtualSize); + return; + } + for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch) { llassert(mNumFaces[ch] <= mFaceList[ch].size()); @@ -1974,8 +1824,12 @@ void LLViewerFetchedTexture::updateVirtualSize() setBoostLevel(LLViewerTexture::BOOST_SELECTED); } addTextureStats(facep->getVirtualSize()); - setAdditionalDecodePriority(facep->getImportanceToCamera()); + //drawable->getVObj()->setDebugText(llformat("%d:%d", (S32)sqrtf(facep->getVirtualSize()), (S32)sqrtf(getMaxVirtualSize()))); } + else + { + //drawable->getVObj()->setDebugText(""); + } } } } @@ -2063,31 +1917,35 @@ bool LLViewerFetchedTexture::updateFetch() if (mNeedsCreateTexture) { + LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - needs create"); // We may be fetching still (e.g. waiting on write) // but don't check until we've processed the raw data we have return false; } if (mIsMissingAsset) { + LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - missing asset"); llassert_always(!mHasFetcher); return false; // skip } if (!mLoadedCallbackList.empty() && mRawImage.notNull()) { + LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - callback pending"); return false; // process any raw image data in callbacks before replacing } if(mInFastCacheList) { + LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - in fast cache"); return false; } S32 current_discard = getCurrentDiscardLevelForFetching(); S32 desired_discard = getDesiredDiscardLevel(); - F32 decode_priority = getDecodePriority(); - decode_priority = llclamp(decode_priority, 0.0f, maxDecodePriority()); + F32 decode_priority = mMaxVirtualSize; if (mIsFetching) { + LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - is fetching"); // Sets mRawDiscardLevel, mRawImage, mAuxRawImage S32 fetch_discard = current_discard; @@ -2105,17 +1963,25 @@ bool LLViewerFetchedTexture::updateFetch() if (finished) { mIsFetching = FALSE; + mLastFetchState = -1; + setDebugText(""); mLastPacketTimer.reset(); } else { mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority, mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP); + if (mFetchState != mLastFetchState) + { + setDebugText(LLTextureFetch::getStateString(mFetchState)); + mLastFetchState = mFetchState; + } } // We may have data ready regardless of whether or not we are finished (e.g. waiting on write) if (mRawImage.notNull()) { + LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - has raw image"); LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); if (tester) { @@ -2126,6 +1992,7 @@ bool LLViewerFetchedTexture::updateFetch() if ((mRawImage->getDataSize() > 0 && mRawDiscardLevel >= 0) && (current_discard < 0 || mRawDiscardLevel < current_discard)) { + LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - data good"); mFullWidth = mRawImage->getWidth() << mRawDiscardLevel; mFullHeight = mRawImage->getHeight() << mRawDiscardLevel; setTexelsPerImage(); @@ -2162,6 +2029,7 @@ bool LLViewerFetchedTexture::updateFetch() } else { + LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - data not needed"); // Data is ready but we don't need it // (received it already while fetcher was writing to disk) destroyRawImage(); @@ -2194,13 +2062,13 @@ bool LLViewerFetchedTexture::updateFetch() if(current_discard >= 0) { mMinDiscardLevel = current_discard; - desired_discard = current_discard; + //desired_discard = current_discard; } else { S32 dis_level = getDiscardLevel(); mMinDiscardLevel = dis_level; - desired_discard = dis_level; + //desired_discard = dis_level; } } destroyRawImage(); @@ -2214,12 +2082,6 @@ bool LLViewerFetchedTexture::updateFetch() } else { -// // Useful debugging code for undesired deprioritization of textures. -// if (decode_priority <= 0.0f && desired_discard >= 0 && desired_discard < current_discard) -// { -// LL_INFOS() << "Calling updateRequestPriority() with decode_priority = 0.0f" << LL_ENDL; -// calcDecodePriority(); -// } static const F32 MAX_HOLD_TIME = 5.0f; //seconds to wait before canceling fecthing if decode_priority is 0.f. if(decode_priority > 0.0f || mStopFetchingTimer.getElapsedTimeF32() > MAX_HOLD_TIME) { @@ -2229,21 +2091,27 @@ bool LLViewerFetchedTexture::updateFetch() } } + desired_discard = llmin(desired_discard, getMaxDiscardLevel()); + bool make_request = true; - if (decode_priority <= 0) + /*if (decode_priority <= 0) { + LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - priority <= 0"); make_request = false; } else if(mDesiredDiscardLevel > getMaxDiscardLevel()) { + LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - desired > max"); make_request = false; } - else if (mNeedsCreateTexture || mIsMissingAsset) + else */ if (mNeedsCreateTexture || mIsMissingAsset) { + LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - create or missing"); make_request = false; } else if (current_discard >= 0 && current_discard <= mMinDiscardLevel) { + LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - current < min"); make_request = false; } else if(mCachedRawImage.notNull() // can be empty @@ -2260,6 +2128,7 @@ bool LLViewerFetchedTexture::updateFetch() if (make_request) { +#if 0 // Load the texture progressively: we try not to rush to the desired discard too fast. // If the camera is not moving, we do not tweak the discard level notch by notch but go to the desired discard with larger boosted steps // This mitigates the "textures stay blurry" problem when loading while not killing the texture memory while moving around @@ -2276,18 +2145,23 @@ bool LLViewerFetchedTexture::updateFetch() { desired_discard = llmax(desired_discard, current_discard - delta_level); } +#endif if (mIsFetching) { + // already requested a higher resolution mip if (mRequestedDiscardLevel <= desired_discard) { + LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - requested < desired"); make_request = false; } } else { + // already at a higher resolution mip, don't discard if (current_discard >= 0 && current_discard <= desired_discard) { + LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - current <= desired"); make_request = false; } } @@ -2295,6 +2169,7 @@ bool LLViewerFetchedTexture::updateFetch() if (make_request) { + LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - make request"); S32 w=0, h=0, c=0; if (getDiscardLevel() >= 0) { @@ -2316,6 +2191,7 @@ bool LLViewerFetchedTexture::updateFetch() if (fetch_request_created) { + LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - request created"); mHasFetcher = TRUE; mIsFetching = TRUE; mRequestedDiscardLevel = desired_discard; @@ -2331,7 +2207,7 @@ bool LLViewerFetchedTexture::updateFetch() // Only delete requests that haven't received any network data // for a while. Note - this is the normal mechanism for // deleting requests, not just a place to handle timeouts. - const F32 FETCH_IDLE_TIME = 5.f; + const F32 FETCH_IDLE_TIME = 0.1f; if (mLastPacketTimer.getElapsedTimeF32() > FETCH_IDLE_TIME) { LL_DEBUGS("Texture") << "exceeded idle time " << FETCH_IDLE_TIME << ", deleting request: " << getID() << LL_ENDL; @@ -2641,7 +2517,7 @@ bool LLViewerFetchedTexture::doLoadedCallbacks() LL_INFOS() << "baked texture: " << mID << "clears all call backs due to inactivity." << LL_ENDL; LL_INFOS() << mUrl << LL_ENDL; LL_INFOS() << "current discard: " << getDiscardLevel() << " current discard for fetch: " << getCurrentDiscardLevelForFetching() << - " Desired discard: " << getDesiredDiscardLevel() << "decode Pri: " << getDecodePriority() << LL_ENDL; + " Desired discard: " << getDesiredDiscardLevel() << "decode Pri: " << mMaxVirtualSize << LL_ENDL; } clearCallbackEntryList() ; //remove all callbacks. @@ -2872,7 +2748,7 @@ void LLViewerFetchedTexture::forceImmediateUpdate() return; } //if already called forceImmediateUpdate() - if(mInImageList && mDecodePriority == LLViewerFetchedTexture::maxDecodePriority()) + if(mInImageList && mMaxVirtualSize == LLViewerFetchedTexture::sMaxVirtualSize) { return; } @@ -2941,6 +2817,7 @@ bool LLViewerFetchedTexture::needsToSaveRawImage() void LLViewerFetchedTexture::destroyRawImage() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if (mAuxRawImage.notNull() && !needsToSaveRawImage()) { sAuxCount--; @@ -3024,6 +2901,7 @@ void LLViewerFetchedTexture::setCachedRawImage(S32 discard_level, LLImageRaw* im void LLViewerFetchedTexture::setCachedRawImage() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if(mRawImage == mCachedRawImage) { return; @@ -3099,6 +2977,7 @@ void LLViewerFetchedTexture::checkCachedRawSculptImage() void LLViewerFetchedTexture::saveRawImage() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if(mRawImage.isNull() || mRawImage == mSavedRawImage || (mSavedRawDiscardLevel >= 0 && mSavedRawDiscardLevel <= mRawDiscardLevel)) { return; @@ -3314,25 +3193,10 @@ void LLViewerLODTexture::processTextureStats() } else { - if(isLargeImage() && !isJustBound() && mAdditionalDecodePriority < 0.3f) - { - //if is a big image and not being used recently, nor close to the view point, do not load hi-res data. - mMaxVirtualSize = llmin(mMaxVirtualSize, (F32)LLViewerTexture::sMinLargeImageSize); - } - - if ((mCalculatedDiscardLevel >= 0.f) && - (llabs(mMaxVirtualSize - mDiscardVirtualSize) < mMaxVirtualSize*.20f)) - { - // < 20% change in virtual size = no change in desired discard - discard_level = mCalculatedDiscardLevel; - } - else - { - // Calculate the required scale factor of the image using pixels per texel - discard_level = (F32)(log(mTexelsPerImage/mMaxVirtualSize) / log_4); - mDiscardVirtualSize = mMaxVirtualSize; - mCalculatedDiscardLevel = discard_level; - } + // Calculate the required scale factor of the image using pixels per texel + discard_level = (F32)(log(mTexelsPerImage/mMaxVirtualSize) / log_4); + mDiscardVirtualSize = mMaxVirtualSize; + mCalculatedDiscardLevel = discard_level; } if (mBoostLevel < LLGLTexture::BOOST_SCULPTED) { diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index 0640efe6df..ece6794592 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -194,14 +194,14 @@ private: public: static bool isMemoryForTextureLow(); protected: + friend class LLViewerTextureList; LLUUID mID; S32 mTextureListType; // along with mID identifies where to search for this texture in TextureList F32 mSelectedTime; // time texture was last selected mutable F32 mMaxVirtualSize; // The largest virtual size of the image, in pixels - how much data to we need? - mutable S32 mMaxVirtualSizeResetCounter ; + mutable S32 mMaxVirtualSizeResetCounter; mutable S32 mMaxVirtualSizeResetInterval; - mutable F32 mAdditionalDecodePriority; // priority add to mDecodePriority. LLFrameTimer mLastReferencedTimer; ll_face_list_t mFaceList[LLRender::NUM_TEXTURE_CHANNELS]; //reverse pointer pointing to the faces using this image as texture @@ -281,7 +281,6 @@ public: LLViewerFetchedTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps = TRUE); public: - static F32 maxDecodePriority(); struct Compare { @@ -290,9 +289,10 @@ public: { const LLViewerFetchedTexture* lhsp = (const LLViewerFetchedTexture*)lhs; const LLViewerFetchedTexture* rhsp = (const LLViewerFetchedTexture*)rhs; + // greater priority is "less" - const F32 lpriority = lhsp->getDecodePriority(); - const F32 rpriority = rhsp->getDecodePriority(); + const F32 lpriority = lhsp->mMaxVirtualSize; + const F32 rpriority = rhsp->mMaxVirtualSize; if (lpriority > rpriority) // higher priority return true; if (lpriority < rpriority) @@ -331,7 +331,6 @@ public: void destroyTexture() ; virtual void processTextureStats() ; - F32 calcDecodePriority() ; BOOL needsAux() const { return mNeedsAux; } @@ -339,15 +338,6 @@ public: void setTargetHost(LLHost host) { mTargetHost = host; } LLHost getTargetHost() const { return mTargetHost; } - // Set the decode priority for this image... - // DON'T CALL THIS UNLESS YOU KNOW WHAT YOU'RE DOING, it can mess up - // the priority list, and cause horrible things to happen. - void setDecodePriority(F32 priority = -1.0f); - F32 getDecodePriority() const { return mDecodePriority; }; - F32 getAdditionalDecodePriority() const { return mAdditionalDecodePriority; }; - - void setAdditionalDecodePriority(F32 priority) ; - void updateVirtualSize() ; S32 getDesiredDiscardLevel() { return mDesiredDiscardLevel; } @@ -367,6 +357,10 @@ public: // more data. /*virtual*/ void setKnownDrawSize(S32 width, S32 height); + // Set the debug text of all Viewer Objects associated with this texture + // to the specified text + void setDebugText(const std::string& text); + void setIsMissingAsset(BOOL is_missing = true); /*virtual*/ BOOL isMissingAsset() const { return mIsMissingAsset; } @@ -468,11 +462,11 @@ protected: S32 mRequestedDiscardLevel; F32 mRequestedDownloadPriority; S32 mFetchState; + S32 mLastFetchState = -1; // DEBUG U32 mFetchPriority; F32 mDownloadProgress; F32 mFetchDeltaTime; F32 mRequestDeltaTime; - F32 mDecodePriority; // The priority for decoding this image. S32 mMinDiscardLevel; S8 mDesiredDiscardLevel; // The discard level we'd LIKE to have - if we have it and there's space S8 mMinDesiredDiscardLevel; // The minimum discard level we'd like to have @@ -530,6 +524,7 @@ protected: BOOL mIsFetched ; //is loaded from remote or from cache, not generated locally. public: + static F32 sMaxVirtualSize; //maximum possible value of mMaxVirtualSize static LLPointer sMissingAssetImagep; // Texture to show for an image asset that is not in the database static LLPointer sWhiteImagep; // Texture to show NOTHING (whiteness) static LLPointer sDefaultImagep; // "Default" texture for error cases, the only case of fetched texture which is generated in local. diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 2a88d9314b..80565b0238 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -89,8 +89,6 @@ LLTextureKey::LLTextureKey(LLUUID id, ETexListType tex_type) LLViewerTextureList::LLViewerTextureList() : mForceResetTextureStats(FALSE), - mMaxResidentTexMemInMegaBytes(0), - mMaxTotalTextureMemInMegaBytes(0), mInitialized(FALSE) { } @@ -99,12 +97,6 @@ void LLViewerTextureList::init() { mInitialized = TRUE ; sNumImages = 0; - mMaxResidentTexMemInMegaBytes = (U32Bytes)0; - mMaxTotalTextureMemInMegaBytes = (U32Bytes)0; - - // Update how much texture RAM we're allowed to use. - updateMaxResidentTexMem(S32Megabytes(0)); // 0 = use current - doPreloadImages(); } @@ -342,7 +334,7 @@ void LLViewerTextureList::dump() { LLViewerFetchedTexture* image = *it; - LL_INFOS() << "priority " << image->getDecodePriority() + LL_INFOS() << "priority " << image->getMaxVirtualSize() << " boost " << image->getBoostLevel() << " size " << image->getWidth() << "x" << image->getHeight() << " discard " << image->getDiscardLevel() @@ -667,13 +659,14 @@ void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image) assert_main_thread(); llassert_always(mInitialized) ; llassert(image); + image->validateRefCount(); S32 count = 0; if (image->isInImageList()) { count = mImageList.erase(image) ; if(count != 1) - { + { LL_INFOS() << "Image " << image->getID() << " had mInImageList set but mImageList.erase() returned " << count << LL_ENDL; @@ -699,6 +692,7 @@ void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image) LL_INFOS() << "Image " << image->getID() << " was in mUUIDMap with same pointer" << LL_ENDL ; } count = mImageList.erase(image) ; + llassert(count != 0); if(count != 0) { // it was in the list already? LL_WARNS() << "Image " << image->getID() @@ -822,7 +816,6 @@ void LLViewerTextureList::updateImages(F32 max_time) didone = image->doLoadedCallbacks(); } } - updateImagesUpdateStats(); } @@ -847,118 +840,102 @@ void LLViewerTextureList::clearFetchingRequests() void LLViewerTextureList::updateImagesDecodePriorities() { +#if 0 LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - // Update the decode priority for N images each frame - { - F32 lazy_flush_timeout = 30.f; // stop decoding - F32 max_inactive_time = 20.f; // actually delete - S32 min_refs = 3; // 1 for mImageList, 1 for mUUIDMap, 1 for local reference - - //reset imagep->getLastReferencedTimer() when screen is showing the progress view to avoid removing pre-fetched textures too soon. - bool reset_timer = gViewerWindow->getProgressView()->getVisible(); - - static const S32 MAX_PRIO_UPDATES = gSavedSettings.getS32("TextureFetchUpdatePriorities"); // default: 32 - const size_t max_update_count = llmin((S32) (MAX_PRIO_UPDATES*MAX_PRIO_UPDATES*gFrameIntervalSeconds.value()) + 1, MAX_PRIO_UPDATES); - S32 update_counter = llmin(max_update_count, mUUIDMap.size()); - uuid_map_t::iterator iter = mUUIDMap.upper_bound(mLastUpdateKey); - while ((update_counter-- > 0) && !mUUIDMap.empty()) - { - if (iter == mUUIDMap.end()) - { - iter = mUUIDMap.begin(); - } - mLastUpdateKey = iter->first; - LLPointer imagep = iter->second; - ++iter; // safe to increment now + // Update the decode priority for N images each frame + + /*static const S32 MAX_PRIO_UPDATES = gSavedSettings.getS32("TextureFetchUpdatePriorities"); // default: 32 + const size_t max_update_count = llmin((S32) (MAX_PRIO_UPDATES*MAX_PRIO_UPDATES*gFrameIntervalSeconds.value()) + 1, MAX_PRIO_UPDATES); + S32 update_counter = llmin(max_update_count, mUUIDMap.size()); + uuid_map_t::iterator iter = mUUIDMap.upper_bound(mLastUpdateKey);*/ + //while ((update_counter-- > 0) && !mUUIDMap.empty()) + for (uuid_map_t::iterator iter = mUUIDMap.begin(); iter != mUUIDMap.end(); ++iter) + { + /*if (iter == mUUIDMap.end()) + { + iter = mUUIDMap.begin(); + }*/ + mLastUpdateKey = iter->first; + LLPointer imagep = iter->second; + //++iter; // safe to increment now - if(imagep->isInDebug() || imagep->isUnremovable()) - { - update_counter--; - continue; //is in debug, ignore. - } + updateImageDecodePriority(imagep); + } +#endif +} - // - // Flush formatted images using a lazy flush - // - S32 num_refs = imagep->getNumRefs(); - if (num_refs == min_refs) - { - if(reset_timer) - { - imagep->getLastReferencedTimer()->reset(); - } - else if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > lazy_flush_timeout) - { - // Remove the unused image from the image list - deleteImage(imagep); - imagep = NULL; // should destroy the image - } - continue; - } - else - { - if(imagep->hasSavedRawImage()) - { - if(imagep->getElapsedLastReferencedSavedRawImageTime() > max_inactive_time) - { - imagep->destroySavedRawImage() ; - } - } +void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imagep) +{ + if (imagep->isInDebug() || imagep->isUnremovable()) + { + //update_counter--; + return; //is in debug, ignore. + } - if(imagep->isDeleted()) - { - continue ; - } - else if(imagep->isDeletionCandidate()) - { - imagep->destroyTexture() ; - continue ; - } - else if(imagep->isInactive()) - { - if(reset_timer) - { - imagep->getLastReferencedTimer()->reset(); - } - else if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > max_inactive_time) - { - imagep->setDeletionCandidate() ; - } - continue ; - } - else - { - imagep->getLastReferencedTimer()->reset(); + F32 lazy_flush_timeout = 30.f; // stop decoding + F32 max_inactive_time = 20.f; // actually delete + S32 min_refs = 3; // 1 for mImageList, 1 for mUUIDMap, 1 for local reference - //reset texture state. - imagep->setInactive() ; - } - } + // + // Flush formatted images using a lazy flush + // + S32 num_refs = imagep->getNumRefs(); + if (num_refs == min_refs) + { + if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > lazy_flush_timeout) + { + // Remove the unused image from the image list + deleteImage(imagep); + imagep = NULL; // should destroy the image + } + return; + } + else + { + if (imagep->hasSavedRawImage()) + { + if (imagep->getElapsedLastReferencedSavedRawImageTime() > max_inactive_time) + { + imagep->destroySavedRawImage(); + } + } - if (!imagep->isInImageList()) - { - continue; - } - if(imagep->isInFastCacheList()) - { - continue; //wait for loading from the fast cache. - } + if (imagep->isDeleted()) + { + return; + } + else if (imagep->isDeletionCandidate()) + { + imagep->destroyTexture(); + return; + } + else if (imagep->isInactive()) + { + if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > max_inactive_time) + { + imagep->setDeletionCandidate(); + } + return; + } + else + { + imagep->getLastReferencedTimer()->reset(); - imagep->processTextureStats(); - F32 old_priority = imagep->getDecodePriority(); - F32 old_priority_test = llmax(old_priority, 0.0f); - F32 decode_priority = imagep->calcDecodePriority(); - F32 decode_priority_test = llmax(decode_priority, 0.0f); - // Ignore < 20% difference - if ((decode_priority_test < old_priority_test * .8f) || - (decode_priority_test > old_priority_test * 1.25f)) - { - mImageList.erase(imagep) ; - imagep->setDecodePriority(decode_priority); - mImageList.insert(imagep); - } - } - } + //reset texture state. + imagep->setInactive(); + } + } + + if (!imagep->isInImageList()) + { + return; + } + if (imagep->isInFastCacheList()) + { + return; //wait for loading from the fast cache. + } + + imagep->processTextureStats(); } void LLViewerTextureList::setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level) @@ -970,17 +947,9 @@ void LLViewerTextureList::setDebugFetching(LLViewerFetchedTexture* tex, S32 debu } const F32 DEBUG_PRIORITY = 100000.f; - F32 old_priority_test = llmax(tex->getDecodePriority(), 0.0f); - F32 decode_priority_test = DEBUG_PRIORITY; - - // Ignore < 20% difference - if ((decode_priority_test < old_priority_test * .8f) || - (decode_priority_test > old_priority_test * 1.25f)) - { - removeImageFromList(tex); - tex->setDecodePriority(decode_priority_test); - addImageToList(tex); - } + removeImageFromList(tex); + tex->mMaxVirtualSize = DEBUG_PRIORITY; + addImageToList(tex); } /* @@ -1030,10 +999,6 @@ F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time) LLViewerFetchedTexture *imagep = *curiter; imagep->createTexture(); imagep->postCreateTexture(); - if (create_timer.getElapsedTimeF32() > max_time) - { - break; - } } mCreateTextureList.erase(mCreateTextureList.begin(), enditer); return create_timer.getElapsedTimeF32(); @@ -1061,10 +1026,6 @@ F32 LLViewerTextureList::updateImagesLoadingFastCache(F32 max_time) enditer = iter; LLViewerFetchedTexture *imagep = *curiter; imagep->loadFromFastCache(); - if (timer.getElapsedTimeF32() > max_time) - { - break; - } } mFastCacheList.erase(mFastCacheList.begin(), enditer); return timer.getElapsedTimeF32(); @@ -1083,8 +1044,7 @@ void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep) } imagep->processTextureStats(); - F32 decode_priority = LLViewerFetchedTexture::maxDecodePriority() ; - imagep->setDecodePriority(decode_priority); + imagep->sMaxVirtualSize = LLViewerFetchedTexture::sMaxVirtualSize; addImageToList(imagep); return ; @@ -1093,12 +1053,17 @@ void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep) F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - LLTimer image_op_timer; - + LLTimer image_op_timer; + + typedef std::vector entries_list_t; + entries_list_t entries; + // Update fetch for N images each frame static const S32 MAX_HIGH_PRIO_COUNT = gSavedSettings.getS32("TextureFetchUpdateHighPriority"); // default: 32 + static const S32 MIN_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMinMediumPriority"); // default: 32 +#if 0 static const S32 MAX_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMaxMediumPriority"); // default: 256 - static const S32 MIN_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMinMediumPriority"); // default: 32 + static const F32 MIN_PRIORITY_THRESHOLD = gSavedSettings.getF32("TextureFetchUpdatePriorityThreshold"); // default: 0.0 static const bool SKIP_LOW_PRIO = gSavedSettings.getBOOL("TextureFetchUpdateSkipLowPriority"); // default: false @@ -1110,9 +1075,9 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) max_update_count = llmin(max_update_count, total_update_count); // MAX_HIGH_PRIO_COUNT high priority entries - typedef std::vector entries_list_t; - entries_list_t entries; - size_t update_counter = max_priority_count; + + //size_t update_counter = max_priority_count; + size_t update_counter = mImageList.size(); image_priority_list_t::iterator iter1 = mImageList.begin(); while(update_counter > 0) { @@ -1123,7 +1088,7 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) } // MAX_UPDATE_COUNT cycled entries - update_counter = max_update_count; + update_counter = max_update_count; if(update_counter > 0) { uuid_map_t::iterator iter2 = mUUIDMap.upper_bound(mLastFetchKey); @@ -1147,22 +1112,65 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) } S32 fetch_count = 0; - size_t min_update_count = llmin(MIN_UPDATE_COUNT,(S32)(entries.size()-max_priority_count)); - S32 min_count = max_priority_count + min_update_count; + //size_t min_update_count = llmin(MIN_UPDATE_COUNT,(S32)(entries.size()-max_priority_count)); + //S32 min_count = max_priority_count + min_update_count; for (entries_list_t::iterator iter3 = entries.begin(); iter3 != entries.end(); ) { LLViewerFetchedTexture* imagep = *iter3++; + updateImageDecodePriority(imagep); fetch_count += (imagep->updateFetch() ? 1 : 0); - if (min_count <= min_update_count) + //if (min_count <= min_update_count) { mLastFetchKey = LLTextureKey(imagep->getID(), (ETexListType)imagep->getTextureListType()); } - if ((min_count-- <= 0) && (image_op_timer.getElapsedTimeF32() > max_time)) + /*if ((min_count-- <= 0) && (image_op_timer.getElapsedTimeF32() > max_time)) { break; - } + }*/ } +#else + + // update N textures at beginning of mImageList + U32 update_count = 0; + + /*for (auto& imagep : mImageList) + { + if (update_count++ > MAX_HIGH_PRIO_COUNT) + { + break; + } + + entries.push_back(imagep); + }*/ + + // WIP -- dumb code here + //update MIN_UPDATE_COUNT or 10% of other textures, whichever is greater + //update_count = llmax((U32) MIN_UPDATE_COUNT, (U32) mUUIDMap.size()/10); + //update_count = llmin(update_count, (U32) mUUIDMap.size()); + update_count -= mUUIDMap.size(); + + entries.reserve(update_count); + //uuid_map_t::iterator iter2 = mUUIDMap.upper_bound(mLastFetchKey); + //while (update_count-- > 0) + for (auto iter2 = mUUIDMap.begin(); iter2 != mUUIDMap.end(); ++iter2) + { + entries.push_back(iter2->second); + } + + for (auto* imagep : entries) + { + updateImageDecodePriority(imagep); + imagep->updateFetch(); + } + + if (entries.size() > 0) + { + LLViewerFetchedTexture* imagep = *entries.rbegin(); + mLastFetchKey = LLTextureKey(imagep->getID(), (ETexListType)imagep->getTextureListType()); + } + +#endif return image_op_timer.getElapsedTimeF32(); } @@ -1206,8 +1214,6 @@ void LLViewerTextureList::decodeAllImages(F32 max_time) { LLViewerFetchedTexture* imagep = *iter; imagep->processTextureStats(); - F32 decode_priority = imagep->calcDecodePriority(); - imagep->setDecodePriority(decode_priority); addImageToList(imagep); } image_list.clear(); @@ -1346,69 +1352,6 @@ LLPointer LLViewerTextureList::convertToUploadFile(LLPointer U32Megabytes(1500)) ? S32Megabytes(64) : gMinVideoRam ; -} - -//static -// Returns max setting for TextureMemory (in MB) -S32Megabytes LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended, float mem_multiplier) -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - S32Megabytes max_texmem; - if (gGLManager.mVRAM != 0) - { - // Treat any card with < 32 MB (shudder) as having 32 MB - // - it's going to be swapping constantly regardless - S32Megabytes max_vram(gGLManager.mVRAM); - - if(gGLManager.mIsAMD) - { - //shrink the availabe vram for ATI cards because some of them do not handel texture swapping well. - max_vram = max_vram * 0.75f; - } - - max_vram = llmax(max_vram, getMinVideoRamSetting()); - max_texmem = max_vram; - if (!get_recommended) - max_texmem *= 2; - } - else - { - if (!get_recommended) - { - max_texmem = (S32Megabytes)512; - } - else if (gSavedSettings.getBOOL("NoHardwareProbe")) //did not do hardware detection at startup - { - max_texmem = (S32Megabytes)512; - } - else - { - max_texmem = (S32Megabytes)128; - } - } - - S32Megabytes system_ram = gSysMemory.getPhysicalMemoryKB(); // In MB - //LL_INFOS() << "*** DETECTED " << system_ram << " MB of system memory." << LL_ENDL; - if (get_recommended) - max_texmem = llmin(max_texmem, system_ram/2); - else - max_texmem = llmin(max_texmem, system_ram); - - // limit the texture memory to a multiple of the default if we've found some cards to behave poorly otherwise - max_texmem = llmin(max_texmem, (S32Megabytes) (mem_multiplier * max_texmem)); - - max_texmem = llclamp(max_texmem, getMinVideoRamSetting(), gMaxVideoRam); - - return max_texmem; -} - bool LLViewerTextureList::isPrioRequestsFetched() { static LLCachedControl prio_threshold(gSavedSettings, "TextureFetchUpdatePriorityThreshold", 0.0f); @@ -1420,7 +1363,7 @@ bool LLViewerTextureList::isPrioRequestsFetched() iter != gTextureList.mImageList.end(); ) { LLPointer imagep = *iter++; - if (imagep->getDecodePriority() > prio_threshold) + if (imagep->getMaxVirtualSize() > prio_threshold) { if (imagep->hasFetcher() || imagep->isFetching()) { @@ -1436,66 +1379,6 @@ bool LLViewerTextureList::isPrioRequestsFetched() return true; } -const S32Megabytes VIDEO_CARD_FRAMEBUFFER_MEM(12); -const S32Megabytes MIN_MEM_FOR_NON_TEXTURE(512); -void LLViewerTextureList::updateMaxResidentTexMem(S32Megabytes mem) -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - // Initialize the image pipeline VRAM settings - S32Megabytes cur_mem(gSavedSettings.getS32("TextureMemory")); - F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple"); - S32Megabytes default_mem = getMaxVideoRamSetting(true, mem_multiplier); // recommended default - if (mem == (S32Bytes)0) - { - mem = cur_mem > (S32Bytes)0 ? cur_mem : default_mem; - } - else if (mem < (S32Bytes)0) - { - mem = default_mem; - } - - mem = llclamp(mem, getMinVideoRamSetting(), getMaxVideoRamSetting(false, mem_multiplier)); - if (mem != cur_mem) - { - gSavedSettings.setS32("TextureMemory", mem.value()); - return; //listener will re-enter this function - } - - if (gGLManager.mVRAM == 0) - { - LL_WARNS() << "VRAM amount not detected, defaulting to " << mem << " MB" << LL_ENDL; - } - - // TODO: set available resident texture mem based on use by other subsystems - // currently max(12MB, VRAM/4) assumed... - - S32Megabytes vb_mem = mem; - S32Megabytes fb_mem = llmax(VIDEO_CARD_FRAMEBUFFER_MEM, vb_mem/4); - mMaxResidentTexMemInMegaBytes = (vb_mem - fb_mem) ; //in MB - - mMaxTotalTextureMemInMegaBytes = mMaxResidentTexMemInMegaBytes * 2; - if (mMaxResidentTexMemInMegaBytes > (S32Megabytes)640) - { - mMaxTotalTextureMemInMegaBytes -= (mMaxResidentTexMemInMegaBytes / 4); - } - - //system mem - S32Megabytes system_ram = gSysMemory.getPhysicalMemoryKB(); - - //minimum memory reserved for non-texture use. - //if system_raw >= 1GB, reserve at least 512MB for non-texture use; - //otherwise reserve half of the system_ram for non-texture use. - S32Megabytes min_non_texture_mem = llmin(system_ram / 2, MIN_MEM_FOR_NON_TEXTURE) ; - - if (mMaxTotalTextureMemInMegaBytes > system_ram - min_non_texture_mem) - { - mMaxTotalTextureMemInMegaBytes = system_ram - min_non_texture_mem ; - } - - LL_INFOS() << "Total Video Memory set to: " << vb_mem << " MB" << LL_ENDL; - LL_INFOS() << "Available Texture Memory set to: " << (vb_mem - fb_mem) << " MB" << LL_ENDL; -} - /////////////////////////////////////////////////////////////////////////////// // static diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index fead2e52b2..8d70add792 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -124,25 +124,24 @@ public: void handleIRCallback(void **data, const S32 number); - S32Megabytes getMaxResidentTexMem() const { return mMaxResidentTexMemInMegaBytes; } - S32Megabytes getMaxTotalTextureMem() const { return mMaxTotalTextureMemInMegaBytes;} S32 getNumImages() { return mImageList.size(); } - void updateMaxResidentTexMem(S32Megabytes mem); - void doPreloadImages(); void doPrefetchImages(); void clearFetchingRequests(); void setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level); - static S32Megabytes getMinVideoRamSetting(); - static S32Megabytes getMaxVideoRamSetting(bool get_recommended, float mem_multiplier); - static bool isPrioRequestsFetched(); private: void updateImagesDecodePriorities(); + + // do some book keeping on the specified texture + // - updates decode priority + // - updates desired discard level + // - cleans up textures that haven't been referenced in awhile + void updateImageDecodePriority(LLViewerFetchedTexture* imagep); F32 updateImagesCreateTextures(F32 max_time); F32 updateImagesFetchTextures(F32 max_time); void updateImagesUpdateStats(); @@ -217,15 +216,13 @@ private: LLTextureKey mLastUpdateKey; LLTextureKey mLastFetchKey; - typedef std::set, LLViewerFetchedTexture::Compare> image_priority_list_t; + typedef std::set < LLPointer > image_priority_list_t; image_priority_list_t mImageList; // simply holds on to LLViewerFetchedTexture references to stop them from being purged too soon std::set > mImagePreloads; BOOL mInitialized ; - S32Megabytes mMaxResidentTexMemInMegaBytes; - S32Megabytes mMaxTotalTextureMemInMegaBytes; LLFrameTimer mForceDecodeTimer; private: diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 5ee661f6c0..151e03ac3b 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -5687,15 +5687,6 @@ void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel mMinPixelArea = llmin(pixel_area, mMinPixelArea); imagep->addTextureStats(pixel_area / texel_area_ratio); imagep->setBoostLevel(boost_level); - - if(boost_level != LLGLTexture::BOOST_AVATAR_BAKED_SELF) - { - imagep->setAdditionalDecodePriority(ADDITIONAL_PRI) ; - } - else - { - imagep->setAdditionalDecodePriority(SELF_ADDITIONAL_PRI) ; - } } //virtual diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 49f5f40f03..4080a61fb0 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -1825,7 +1825,7 @@ void LLVOAvatarSelf::dumpLocalTextures() const } else { - const LLViewerFetchedTexture* image = dynamic_cast( local_tex_obj->getImage() ); + LLViewerFetchedTexture* image = dynamic_cast( local_tex_obj->getImage() ); LL_INFOS() << "LocTex " << name << ": " << "Discard " << image->getDiscardLevel() << ", " @@ -1835,7 +1835,7 @@ void LLVOAvatarSelf::dumpLocalTextures() const // makes textures easier to steal << image->getID() << " " #endif - << "Priority: " << image->getDecodePriority() + << "Priority: " << image->getMaxVirtualSize() << LL_ENDL; } } @@ -2074,8 +2074,7 @@ const std::string LLVOAvatarSelf::verboseDebugDumpLocalTextureDataInfo(const LLV << " glocdisc: " << getLocalDiscardLevel(tex_index, wearable_index) << " discard: " << image->getDiscardLevel() << " desired: " << image->getDesiredDiscardLevel() - << " decode: " << image->getDecodePriority() - << " addl: " << image->getAdditionalDecodePriority() + << " vsize: " << image->getMaxVirtualSize() << " ts: " << image->getTextureState() << " bl: " << image->getBoostLevel() << " fl: " << image->isFullyLoaded() // this is not an accessor for mFullyLoaded - see comment there. @@ -2453,7 +2452,6 @@ void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTe desired_pixels = llmin(mPixelArea, (F32)getTexImageArea()); imagep->setBoostLevel(getAvatarBoostLevel()); - imagep->setAdditionalDecodePriority(SELF_ADDITIONAL_PRI) ; imagep->resetTextureStats(); imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTUAL_SIZE_RESET_INTERVAL); imagep->addTextureStats( desired_pixels / texel_area_ratio ); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index f18f6b1116..a0d034850f 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -668,12 +668,13 @@ void LLVOVolume::animateTextures() void LLVOVolume::updateTextures() { - const F32 TEXTURE_AREA_REFRESH_TIME = 5.f; // seconds - if (mTextureUpdateTimer.getElapsedTimeF32() > TEXTURE_AREA_REFRESH_TIME) + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; + //const F32 TEXTURE_AREA_REFRESH_TIME = 1.f; // seconds + //if (mTextureUpdateTimer.getElapsedTimeF32() > TEXTURE_AREA_REFRESH_TIME) { updateTextureVirtualSize(); - if (mDrawable.notNull() && !isVisible() && !mDrawable->isActive()) + /*if (mDrawable.notNull() && !isVisible() && !mDrawable->isActive()) { //delete vertex buffer to free up some VRAM LLSpatialGroup* group = mDrawable->getSpatialGroup(); if (group && (group->mVertexBuffer.notNull() || !group->mBufferMap.empty() || !group->mDrawMap.empty())) @@ -684,9 +685,7 @@ void LLVOVolume::updateTextures() //it becomes visible group->setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); } - } - - + }*/ } } @@ -760,6 +759,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced) const S32 num_faces = mDrawable->getNumFaces(); F32 min_vsize=999999999.f, max_vsize=0.f; LLViewerCamera* camera = LLViewerCamera::getInstance(); + std::stringstream debug_text; for (S32 i = 0; i < num_faces; i++) { LLFace* face = mDrawable->getFace(i); @@ -786,10 +786,14 @@ void LLVOVolume::updateTextureVirtualSize(bool forced) else { vsize = face->getTextureVirtualSize(); + imagep->addTextureStats(vsize); } - mPixelArea = llmax(mPixelArea, face->getPixelArea()); + mPixelArea = llmax(mPixelArea, face->getPixelArea()); + // if the face has gotten small enough to turn off texture animation and texture + // animation is running, rebuild the render batch for this face to turn off + // texture animation if (face->mTextureMatrix != NULL) { if ((vsize < MIN_TEX_ANIM_SIZE && old_size > MIN_TEX_ANIM_SIZE) || @@ -809,10 +813,11 @@ void LLVOVolume::updateTextureVirtualSize(bool forced) LLViewerFetchedTexture* img = LLViewerTextureManager::staticCastToFetchedTexture(imagep) ; if(img) { - F32 pri = img->getDecodePriority(); + debug_text << img->getDiscardLevel() << ":" << img->getDesiredDiscardLevel() << ":" << img->getWidth() << ":" << (S32) sqrtf(vsize) << ":" << (S32) sqrtf(img->getMaxVirtualSize()) << "\n"; + /*F32 pri = img->getDecodePriority(); pri = llmax(pri, 0.0f); if (pri < min_vsize) min_vsize = pri; - if (pri > max_vsize) max_vsize = pri; + if (pri > max_vsize) max_vsize = pri;*/ } } else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_AREA)) @@ -844,14 +849,6 @@ void LLVOVolume::updateTextureVirtualSize(bool forced) F32 lodf = ((F32)(lod + 1.0f)/4.f); F32 tex_size = lodf * LLViewerTexture::sMaxSculptRez ; mSculptTexture->addTextureStats(2.f * tex_size * tex_size, FALSE); - - //if the sculpty very close to the view point, load first - { - LLVector3 lookAt = getPositionAgent() - camera->getOrigin(); - F32 dist = lookAt.normVec() ; - F32 cos_angle_to_view_dir = lookAt * camera->getXAxis() ; - mSculptTexture->setAdditionalDecodePriority(0.8f * LLFace::calcImportanceToCamera(cos_angle_to_view_dir, dist)) ; - } } S32 texture_discard = mSculptTexture->getCachedRawImageLevel(); //try to match the texture @@ -895,7 +892,8 @@ void LLVOVolume::updateTextureVirtualSize(bool forced) } else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)) { - setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize))); + //setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize))); + setDebugText(debug_text.str()); } else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_AREA)) { diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp index 32c8ce66a0..2b400c5586 100644 --- a/indra/newview/llxmlrpctransaction.cpp +++ b/indra/newview/llxmlrpctransaction.cpp @@ -395,7 +395,7 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip, const mHandler = LLXMLRPCTransaction::Handler::ptr_t(new Handler( mHttpRequest, this )); - mPostH = mHttpRequest->requestPost(LLCore::HttpRequest::DEFAULT_POLICY_ID, 0, + mPostH = mHttpRequest->requestPost(LLCore::HttpRequest::DEFAULT_POLICY_ID, mURI, body.get(), httpOpts, httpHeaders, mHandler); } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index a5ae52af93..bc0d89f4ad 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -3776,25 +3776,47 @@ void LLPipeline::postSort(LLCamera& camera) group->rebuildGeom(); } - for (LLSpatialGroup::draw_map_t::iterator j = group->mDrawMap.begin(); j != group->mDrawMap.end(); ++j) - { - LLSpatialGroup::drawmap_elem_t& src_vec = j->second; - if (!hasRenderType(j->first)) - { - continue; - } - - for (LLSpatialGroup::drawmap_elem_t::iterator k = src_vec.begin(); k != src_vec.end(); ++k) - { + for (LLSpatialGroup::draw_map_t::iterator j = group->mDrawMap.begin(); j != group->mDrawMap.end(); ++j) + { + LLSpatialGroup::drawmap_elem_t& src_vec = j->second; + if (!hasRenderType(j->first)) + { + continue; + } + + // DEBUG -- force a texture virtual size update every frame + /*if (group->getSpatialPartition()->mDrawableType == LLPipeline::RENDER_TYPE_VOLUME) + { + LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("plps - update vsize"); + auto& entries = group->getData(); + for (auto& entry : entries) + { + if (entry) + { + auto* data = entry->getDrawable(); + if (data) + { + LLVOVolume* volume = ((LLDrawable*)data)->getVOVolume(); + if (volume) + { + volume->updateTextureVirtualSize(true); + } + } + } + } + }*/ + + for (LLSpatialGroup::drawmap_elem_t::iterator k = src_vec.begin(); k != src_vec.end(); ++k) + { LLDrawInfo* info = *k; - - sCull->pushDrawInfo(j->first, info); + + sCull->pushDrawInfo(j->first, info); if (!sShadowRender && !sReflectionRender) { touchTextures(info); addTrianglesDrawn(info->mCount, info->mDrawMode); } - } + } } if (hasRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA)) 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 d1e167df64..0a4acd979a 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 @@ -272,23 +272,6 @@ Hardware - - Date: Tue, 10 May 2022 12:18:27 -0400 Subject: SL-17219: WorkQueue::tryPost() must call ThreadSafeSchedule::tryPush(). We inadvertently changed tryPost() to call ThreadSafeSchedule::tryPost(), which doesn't exist. --- indra/llcommon/workqueue.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/llcommon/workqueue.h b/indra/llcommon/workqueue.h index 46f7363830..784327f929 100644 --- a/indra/llcommon/workqueue.h +++ b/indra/llcommon/workqueue.h @@ -170,7 +170,7 @@ namespace LL template bool tryPost(CALLABLE&& callable) { - return mQueue.tryPost(TimePoint::clock::now(), std::move(callable)); + return mQueue.tryPush(TimePoint::clock::now(), std::move(callable)); } /*------------------------- handshake API --------------------------*/ -- cgit v1.2.3 From 3604edc27eedff24dc1f17624a77c130b498e9f1 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 10 May 2022 12:20:19 -0400 Subject: SL-17219: LLWindowMacOSX needs getAvailableVRAMMegabytes(). This is just a placeholder, but without it the viewer won't even build on Mac. --- indra/llwindow/llwindow.h | 6 +++--- indra/llwindow/llwindowmacosx.h | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index 507e6076d6..2c538a60c9 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -162,9 +162,9 @@ public: virtual F32 getNativeAspectRatio() = 0; virtual F32 getPixelAspectRatio() = 0; virtual void setNativeAspectRatio(F32 aspect) = 0; - - // query VRAM usage - virtual U32 getAvailableVRAMMegabytes() = 0; + + // query VRAM usage + virtual U32 getAvailableVRAMMegabytes() = 0; virtual void beforeDialog() {}; // prepare to put up an OS dialog (if special measures are required, such as in fullscreen mode) virtual void afterDialog() {}; // undo whatever was done in beforeDialog() diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h index b0f339e1db..309d1377ea 100644 --- a/indra/llwindow/llwindowmacosx.h +++ b/indra/llwindow/llwindowmacosx.h @@ -100,6 +100,10 @@ public: F32 getPixelAspectRatio() override; void setNativeAspectRatio(F32 ratio) override { mOverrideAspectRatio = ratio; } + // query VRAM usage + // FIXME FIXME + virtual U32 getAvailableVRAMMegabytes() override { return 0; } + void beforeDialog() override; void afterDialog() override; -- cgit v1.2.3 From 4dddb17dfc0dc2c0bdd21263574707a91f2b00a9 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 10 May 2022 12:26:44 -0400 Subject: SL-17219: Mark LLWindowHeadless virtual overrides 'override'. Also LLSplashScreenHeadless methods. Without this Mac builds fail. --- indra/llwindow/llwindowheadless.h | 133 ++++++++++++++++++++------------------ 1 file changed, 69 insertions(+), 64 deletions(-) diff --git a/indra/llwindow/llwindowheadless.h b/indra/llwindow/llwindowheadless.h index 0e1f603db7..2f2c0de5bd 100644 --- a/indra/llwindow/llwindowheadless.h +++ b/indra/llwindow/llwindowheadless.h @@ -32,74 +32,79 @@ class LLWindowHeadless : public LLWindow { public: - /*virtual*/ void show() {}; - /*virtual*/ void hide() {}; - /*virtual*/ void close() {}; - /*virtual*/ BOOL getVisible() {return FALSE;}; - /*virtual*/ BOOL getMinimized() {return FALSE;}; - /*virtual*/ BOOL getMaximized() {return FALSE;}; - /*virtual*/ BOOL maximize() {return FALSE;}; - /*virtual*/ void minimize() {}; - /*virtual*/ void restore() {}; - /*virtual*/ BOOL getFullscreen() {return FALSE;}; - /*virtual*/ BOOL getPosition(LLCoordScreen *position) {return FALSE;}; - /*virtual*/ BOOL getSize(LLCoordScreen *size) {return FALSE;}; - /*virtual*/ BOOL getSize(LLCoordWindow *size) {return FALSE;}; - /*virtual*/ BOOL setPosition(LLCoordScreen position) {return FALSE;}; - /*virtual*/ BOOL setSizeImpl(LLCoordScreen size) {return FALSE;}; - /*virtual*/ BOOL setSizeImpl(LLCoordWindow size) {return FALSE;}; - /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL enable_vsync, const LLCoordScreen * const posp = NULL) {return FALSE;}; - void* createSharedContext() { return nullptr; } - void makeContextCurrent(void*) {} - void destroySharedContext(void*) {} - /*virtual*/ void toggleVSync(bool enable_vsync) { } - /*virtual*/ BOOL setCursorPosition(LLCoordWindow position) {return FALSE;}; - /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position) {return FALSE;}; + /*virtual*/ void show() override {} + /*virtual*/ void hide() override {} + /*virtual*/ void close() override {} + /*virtual*/ BOOL getVisible() override {return FALSE;} + /*virtual*/ BOOL getMinimized() override {return FALSE;} + /*virtual*/ BOOL getMaximized() override {return FALSE;} + /*virtual*/ BOOL maximize() override {return FALSE;} + /*virtual*/ void minimize() override {} + /*virtual*/ void restore() override {} + // TODO: LLWindow::getFullscreen() is (intentionally?) NOT virtual. + // Apparently the coder of LLWindowHeadless didn't realize that. Is it a + // mistake to shadow the base-class method with an LLWindowHeadless + // override when called on the subclass, yet call the base-class method + // when indirecting through a polymorphic pointer or reference? + BOOL getFullscreen() {return FALSE;} + /*virtual*/ BOOL getPosition(LLCoordScreen *position) override {return FALSE;} + /*virtual*/ BOOL getSize(LLCoordScreen *size) override {return FALSE;} + /*virtual*/ BOOL getSize(LLCoordWindow *size) override {return FALSE;} + /*virtual*/ BOOL setPosition(LLCoordScreen position) override {return FALSE;} + /*virtual*/ BOOL setSizeImpl(LLCoordScreen size) override {return FALSE;} + /*virtual*/ BOOL setSizeImpl(LLCoordWindow size) override {return FALSE;} + /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL enable_vsync, const LLCoordScreen * const posp = NULL) override {return FALSE;} + void* createSharedContext() override { return nullptr; } + void makeContextCurrent(void*) override {} + void destroySharedContext(void*) override {} + /*virtual*/ void toggleVSync(bool enable_vsync) override { } + /*virtual*/ BOOL setCursorPosition(LLCoordWindow position) override {return FALSE;} + /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position) override {return FALSE;} #if LL_WINDOWS - /*virtual*/ BOOL getCursorDelta(LLCoordCommon* delta) { return FALSE; } + /*virtual*/ BOOL getCursorDelta(LLCoordCommon* delta) override { return FALSE; } #endif - /*virtual*/ void showCursor() {}; - /*virtual*/ void hideCursor() {}; - /*virtual*/ void showCursorFromMouseMove() {}; - /*virtual*/ void hideCursorUntilMouseMove() {}; - /*virtual*/ BOOL isCursorHidden() {return FALSE;}; - /*virtual*/ void updateCursor() {}; - //virtual ECursorType getCursor() { return mCurrentCursor; }; - /*virtual*/ void captureMouse() {}; - /*virtual*/ void releaseMouse() {}; - /*virtual*/ void setMouseClipping( BOOL b ) {}; - /*virtual*/ BOOL isClipboardTextAvailable() {return FALSE; }; - /*virtual*/ BOOL pasteTextFromClipboard(LLWString &dst) {return FALSE; }; - /*virtual*/ BOOL copyTextToClipboard(const LLWString &src) {return FALSE; }; - /*virtual*/ void flashIcon(F32 seconds) {}; - /*virtual*/ F32 getGamma() {return 1.0f; }; - /*virtual*/ BOOL setGamma(const F32 gamma) {return FALSE; }; // Set the gamma - /*virtual*/ void setFSAASamples(const U32 fsaa_samples) { } - /*virtual*/ U32 getFSAASamples() { return 0; } - /*virtual*/ BOOL restoreGamma() {return FALSE; }; // Restore original gamma table (before updating gamma) - //virtual ESwapMethod getSwapMethod() { return mSwapMethod; } - /*virtual*/ void gatherInput() {}; - /*virtual*/ void delayInputProcessing() {}; - /*virtual*/ void swapBuffers(); + /*virtual*/ void showCursor() override {} + /*virtual*/ void hideCursor() override {} + /*virtual*/ void showCursorFromMouseMove() override {} + /*virtual*/ void hideCursorUntilMouseMove() override {} + /*virtual*/ BOOL isCursorHidden() override {return FALSE;} + /*virtual*/ void updateCursor() override {} + //virtual ECursorType getCursor() override { return mCurrentCursor; } + /*virtual*/ void captureMouse() override {} + /*virtual*/ void releaseMouse() override {} + /*virtual*/ void setMouseClipping( BOOL b ) override {} + /*virtual*/ BOOL isClipboardTextAvailable() override {return FALSE; } + /*virtual*/ BOOL pasteTextFromClipboard(LLWString &dst) override {return FALSE; } + /*virtual*/ BOOL copyTextToClipboard(const LLWString &src) override {return FALSE; } + /*virtual*/ void flashIcon(F32 seconds) override {} + /*virtual*/ F32 getGamma() override {return 1.0f; } + /*virtual*/ BOOL setGamma(const F32 gamma) override {return FALSE; } // Set the gamma + /*virtual*/ void setFSAASamples(const U32 fsaa_samples) override { } + /*virtual*/ U32 getFSAASamples() override { return 0; } + /*virtual*/ BOOL restoreGamma() override {return FALSE; } // Restore original gamma table (before updating gamma) + //virtual ESwapMethod getSwapMethod() override { return mSwapMethod; } + /*virtual*/ void gatherInput() override {} + /*virtual*/ void delayInputProcessing() override {} + /*virtual*/ void swapBuffers() override; // handy coordinate space conversion routines - /*virtual*/ BOOL convertCoords(LLCoordScreen from, LLCoordWindow *to) { return FALSE; }; - /*virtual*/ BOOL convertCoords(LLCoordWindow from, LLCoordScreen *to) { return FALSE; }; - /*virtual*/ BOOL convertCoords(LLCoordWindow from, LLCoordGL *to) { return FALSE; }; - /*virtual*/ BOOL convertCoords(LLCoordGL from, LLCoordWindow *to) { return FALSE; }; - /*virtual*/ BOOL convertCoords(LLCoordScreen from, LLCoordGL *to) { return FALSE; }; - /*virtual*/ BOOL convertCoords(LLCoordGL from, LLCoordScreen *to) { return FALSE; }; + /*virtual*/ BOOL convertCoords(LLCoordScreen from, LLCoordWindow *to) override { return FALSE; } + /*virtual*/ BOOL convertCoords(LLCoordWindow from, LLCoordScreen *to) override { return FALSE; } + /*virtual*/ BOOL convertCoords(LLCoordWindow from, LLCoordGL *to) override { return FALSE; } + /*virtual*/ BOOL convertCoords(LLCoordGL from, LLCoordWindow *to) override { return FALSE; } + /*virtual*/ BOOL convertCoords(LLCoordScreen from, LLCoordGL *to) override { return FALSE; } + /*virtual*/ BOOL convertCoords(LLCoordGL from, LLCoordScreen *to) override { return FALSE; } - /*virtual*/ LLWindowResolution* getSupportedResolutions(S32 &num_resolutions) { return NULL; }; - /*virtual*/ F32 getNativeAspectRatio() { return 1.0f; }; - /*virtual*/ F32 getPixelAspectRatio() { return 1.0f; }; - /*virtual*/ void setNativeAspectRatio(F32 ratio) {} + /*virtual*/ LLWindowResolution* getSupportedResolutions(S32 &num_resolutions) override { return NULL; } + /*virtual*/ F32 getNativeAspectRatio() override { return 1.0f; } + /*virtual*/ F32 getPixelAspectRatio() override { return 1.0f; } + /*virtual*/ void setNativeAspectRatio(F32 ratio) override {} U32 getAvailableVRAMMegabytes() override { return 4096; } - /*virtual*/ void *getPlatformWindow() { return 0; }; - /*virtual*/ void bringToFront() {}; + /*virtual*/ void *getPlatformWindow() override { return 0; } + /*virtual*/ void bringToFront() override {} LLWindowHeadless(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, @@ -115,12 +120,12 @@ private: class LLSplashScreenHeadless : public LLSplashScreen { public: - LLSplashScreenHeadless() {}; - virtual ~LLSplashScreenHeadless() {}; + LLSplashScreenHeadless() {} + virtual ~LLSplashScreenHeadless() {} - /*virtual*/ void showImpl() {}; - /*virtual*/ void updateImpl(const std::string& mesg) {}; - /*virtual*/ void hideImpl() {}; + /*virtual*/ void showImpl() override {} + /*virtual*/ void updateImpl(const std::string& mesg) override {} + /*virtual*/ void hideImpl() override {} }; -- cgit v1.2.3 From 5bed414ba9418ba8599d3b333eb30e63f62124ae Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 10 May 2022 12:30:59 -0400 Subject: SL-17219: Fix bug: dangling pointer to destroyed std::string. --- indra/newview/lltexturefetch.cpp | 4 ++-- indra/newview/lltexturefetch.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 8ad28074de..f30e640f80 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -2540,11 +2540,11 @@ void LLTextureFetchWorker::recordTextureDone(bool is_http, F64 byte_count) ////////////////////////////////////////////////////////////////////////////// // public -const char* LLTextureFetch::getStateString(S32 state) +std::string LLTextureFetch::getStateString(S32 state) { if (state < 0 || state > sizeof(e_state_name) / sizeof(char*)) { - return llformat("%d", state).c_str(); + return llformat("%d", state); } return e_state_name[state]; diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index 0cf9775af2..ff6bb8b505 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -59,7 +59,7 @@ class LLTextureFetch : public LLWorkerThread friend class LLTextureFetchWorker; public: - static const char* getStateString(S32 state); + static std::string getStateString(S32 state); LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* imagedecodethread, bool threaded, bool qa_mode); ~LLTextureFetch(); -- cgit v1.2.3 From 06aa68c2fbcd83cb00465c9f14933bda276b11e8 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 10 May 2022 12:32:43 -0400 Subject: SL-17219: Delete some unused declarations. These trigger fatal warnings on Mac. --- indra/newview/lltexturefetch.cpp | 1 - indra/newview/llviewertexture.cpp | 8 -------- indra/newview/llviewertexturelist.cpp | 2 -- indra/newview/llvoavatar.cpp | 1 - 4 files changed, 12 deletions(-) diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index f30e640f80..543e8b0dab 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -4115,7 +4115,6 @@ bool TFReqSendMetrics::doWork(LLTextureFetch * fetcher) { LL_PROFILE_ZONE_SCOPED; - static const U32 report_priority(1); //if (! gViewerAssetStatsThread1) // return true; diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 06673b50fa..0f2af77f9d 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -1779,14 +1779,6 @@ void LLViewerFetchedTexture::processTextureStats() } } -const F32 MAX_PRIORITY_PIXEL = 999.f; //pixel area -const F32 PRIORITY_BOOST_LEVEL_FACTOR = 1000.f; //boost level -const F32 PRIORITY_DELTA_DISCARD_LEVEL_FACTOR = 100000.f; //delta discard -const S32 MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY = 4; -const F32 PRIORITY_ADDITIONAL_FACTOR = 1000000.f; //additional -const S32 MAX_ADDITIONAL_LEVEL_FOR_PRIORITY = 8; -const F32 PRIORITY_BOOST_HIGH_FACTOR = 10000000.f;//boost high - //============================================================================ void LLViewerFetchedTexture::updateVirtualSize() diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 80565b0238..5ac792aad0 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -1059,8 +1059,6 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) entries_list_t entries; // Update fetch for N images each frame - static const S32 MAX_HIGH_PRIO_COUNT = gSavedSettings.getS32("TextureFetchUpdateHighPriority"); // default: 32 - static const S32 MIN_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMinMediumPriority"); // default: 32 #if 0 static const S32 MAX_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMaxMediumPriority"); // default: 256 diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 151e03ac3b..ed947a7eaa 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -5672,7 +5672,6 @@ void LLVOAvatar::checkTextureLoading() } const F32 SELF_ADDITIONAL_PRI = 0.75f ; -const F32 ADDITIONAL_PRI = 0.5f; void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel_area, F32 texel_area_ratio, S32 boost_level) { //Note: -- cgit v1.2.3 From 9bcc01e3e33c9152a0fb71de2b33e3e41b5a5534 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 24 May 2022 14:30:30 -0500 Subject: SL-17484 Build fix. --- indra/llcommon/lltimer.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp index b250bc3e1c..466f98f9b2 100644 --- a/indra/llcommon/lltimer.cpp +++ b/indra/llcommon/lltimer.cpp @@ -30,6 +30,9 @@ #include "u64.h" +#include +#include + #if LL_WINDOWS # include "llwin32headerslean.h" #elif LL_LINUX || LL_DARWIN -- cgit v1.2.3 From 3e9dcba813a8263635e06b8e49c4aa5c54742139 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 24 May 2022 17:03:11 -0500 Subject: SL-17486 Fix for many texture types failing to load. --- indra/newview/llviewertexture.cpp | 12 +++++++++--- indra/newview/llviewertexture.h | 4 ++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 0f2af77f9d..b8de5d34eb 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -714,6 +714,12 @@ void LLViewerTexture::setBoostLevel(S32 level) } } + // strongly encourage anything boosted to load at full res + if (mBoostLevel >= LLViewerTexture::BOOST_HIGH) + { + mMaxVirtualSize = 2048.f * 2048.f; + } + if (mBoostLevel == LLViewerTexture::BOOST_SELECTED) { mSelectedTime = gFrameTimeSeconds; @@ -1963,11 +1969,11 @@ bool LLViewerFetchedTexture::updateFetch() { mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority, mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP); - if (mFetchState != mLastFetchState) + /*if (mFetchState != mLastFetchState) { setDebugText(LLTextureFetch::getStateString(mFetchState)); mLastFetchState = mFetchState; - } + }*/ } // We may have data ready regardless of whether or not we are finished (e.g. waiting on write) @@ -2031,7 +2037,7 @@ bool LLViewerFetchedTexture::updateFetch() if (!mIsFetching) { - if ((decode_priority > 0) && (mRawDiscardLevel < 0 || mRawDiscardLevel == INVALID_DISCARD_LEVEL)) + if ((decode_priority > 0) && (mRawDiscardLevel < 0)) { // We finished but received no data if (getDiscardLevel() < 0) diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index ece6794592..49d030bcb8 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -199,7 +199,7 @@ protected: S32 mTextureListType; // along with mID identifies where to search for this texture in TextureList F32 mSelectedTime; // time texture was last selected - mutable F32 mMaxVirtualSize; // The largest virtual size of the image, in pixels - how much data to we need? + mutable F32 mMaxVirtualSize = 0.f; // The largest virtual size of the image, in pixels - how much data to we need? mutable S32 mMaxVirtualSizeResetCounter; mutable S32 mMaxVirtualSizeResetInterval; LLFrameTimer mLastReferencedTimer; @@ -490,7 +490,7 @@ protected: F32 mLastCallBackActiveTime; LLPointer mRawImage; - S32 mRawDiscardLevel; + S32 mRawDiscardLevel = -1; // Used ONLY for cloth meshes right now. Make SURE you know what you're // doing if you use it for anything else! - djs -- cgit v1.2.3 From 41e32126d4b4b5d7bd810484a0f6c732f4367169 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 24 May 2022 17:48:41 -0500 Subject: SL-17484 Unit test build fix (remove priority parameters). --- indra/llcorehttp/examples/http_texture_load.cpp | 4 ++-- indra/llcorehttp/tests/test_httprequest.hpp | 20 -------------------- indra/llcrashlogger/llcrashlogger.cpp | 2 +- indra/llimage/tests/llimageworker_test.cpp | 6 +++--- 4 files changed, 6 insertions(+), 26 deletions(-) diff --git a/indra/llcorehttp/examples/http_texture_load.cpp b/indra/llcorehttp/examples/http_texture_load.cpp index c7376042b3..cc53b20add 100644 --- a/indra/llcorehttp/examples/http_texture_load.cpp +++ b/indra/llcorehttp/examples/http_texture_load.cpp @@ -469,11 +469,11 @@ bool WorkingSet::reload(LLCore::HttpRequest * hr, LLCore::HttpOptions::ptr_t & o LLCore::HttpHandle handle; if (offset || length) { - handle = hr->requestGetByteRange(0, 0, buffer, offset, length, opt, mHeaders, LLCore::HttpHandler::ptr_t(this, NoOpDeletor)); + handle = hr->requestGetByteRange(0, buffer, offset, length, opt, mHeaders, LLCore::HttpHandler::ptr_t(this, NoOpDeletor)); } else { - handle = hr->requestGet(0, 0, buffer, opt, mHeaders, LLCore::HttpHandler::ptr_t(this, NoOpDeletor)); + handle = hr->requestGet(0, buffer, opt, mHeaders, LLCore::HttpHandler::ptr_t(this, NoOpDeletor)); } if (! handle) { diff --git a/indra/llcorehttp/tests/test_httprequest.hpp b/indra/llcorehttp/tests/test_httprequest.hpp index 154f6b12e9..3eaac10aeb 100644 --- a/indra/llcorehttp/tests/test_httprequest.hpp +++ b/indra/llcorehttp/tests/test_httprequest.hpp @@ -614,7 +614,6 @@ void HttpRequestTestObjectType::test<7>() // Issue a GET that can't connect mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_CONNECT); HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, - 0U, "http://127.0.0.1:2/nothing/here", 0, 0, @@ -716,7 +715,6 @@ void HttpRequestTestObjectType::test<8>() // Issue a GET that *can* connect mStatus = HttpStatus(200); HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID, - 0U, url_base, HttpOptions::ptr_t(), HttpHeaders::ptr_t(), @@ -812,7 +810,6 @@ void HttpRequestTestObjectType::test<9>() // Issue a GET that *can* connect mStatus = HttpStatus(200); HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, - 0U, url_base, 0, 0, @@ -913,7 +910,6 @@ void HttpRequestTestObjectType::test<10>() body->append(body_text, strlen(body_text)); mStatus = HttpStatus(200); HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID, - 0U, url_base, body, HttpOptions::ptr_t(), @@ -1020,7 +1016,6 @@ void HttpRequestTestObjectType::test<11>() body->append(body_text, strlen(body_text)); mStatus = HttpStatus(200); HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID, - 0U, url_base, body, HttpOptions::ptr_t(), @@ -1127,7 +1122,6 @@ void HttpRequestTestObjectType::test<12>() // Issue a GET that *can* connect mStatus = HttpStatus(200); HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, - 0U, url_base, 0, 0, @@ -1240,7 +1234,6 @@ void HttpRequestTestObjectType::test<13>() regex_container_t::value_type(boost::regex("X-LL-Special", boost::regex::icase), boost::regex(".*", boost::regex::icase))); HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, - 0U, url_base, 0, 0, @@ -1346,7 +1339,6 @@ void HttpRequestTestObjectType::test<14>() // Issue a GET that sleeps mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_OPERATION_TIMEDOUT); HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, - 0U, url_base, 0, 0, @@ -1454,7 +1446,6 @@ void HttpRequestTestObjectType::test<15>() mStatus = HttpStatus(200); handler.mCheckContentType = "application/llsd+xml"; HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID, - 0U, url_base, HttpOptions::ptr_t(), HttpHeaders::ptr_t(), @@ -1609,7 +1600,6 @@ void HttpRequestTestObjectType::test<16>() boost::regex("X-Reflect-content-encoding", boost::regex::icase), boost::regex(".*", boost::regex::icase))); HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID, - 0U, url_base + "reflect/", options, HttpHeaders::ptr_t(), @@ -1684,7 +1674,6 @@ void HttpRequestTestObjectType::test<16>() boost::regex("X-Reflect-content-encoding", boost::regex::icase), boost::regex(".*", boost::regex::icase))); handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, - 0U, url_base + "reflect/", 0, 47, @@ -1863,7 +1852,6 @@ void HttpRequestTestObjectType::test<17>() boost::regex("X-Reflect-transfer_encoding", boost::regex::icase), boost::regex(".*chunked.*", boost::regex::icase))); HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID, - 0U, url_base + "reflect/", ba, options, @@ -2049,7 +2037,6 @@ void HttpRequestTestObjectType::test<18>() boost::regex(".*", boost::regex::icase))); HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID, - 0U, url_base + "reflect/", ba, options, @@ -2249,7 +2236,6 @@ void HttpRequestTestObjectType::test<19>() boost::regex("X-Reflect-content-encoding", boost::regex::icase), boost::regex(".*", boost::regex::icase))); HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID, - 0U, url_base + "reflect/", options, headers, @@ -2457,7 +2443,6 @@ void HttpRequestTestObjectType::test<20>() boost::regex(".*", boost::regex::icase))); HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID, - 0U, url_base + "reflect/", ba, options, @@ -2666,7 +2651,6 @@ void HttpRequestTestObjectType::test<21>() boost::regex("X-Reflect-content-type", boost::regex::icase), boost::regex("text/html", boost::regex::icase))); HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID, - 0U, url_base + "reflect/", ba, options, @@ -2797,7 +2781,6 @@ void HttpRequestTestObjectType::test<22>() char buffer[128]; sprintf(buffer, "/bug2295/%d/", i); HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, - 0U, url_base + buffer, 0, 25, @@ -2829,7 +2812,6 @@ void HttpRequestTestObjectType::test<22>() char buffer[128]; sprintf(buffer, "/bug2295/00000012/%d/", i); HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, - 0U, url_base + buffer, 0, 25, @@ -2861,7 +2843,6 @@ void HttpRequestTestObjectType::test<22>() char buffer[128]; sprintf(buffer, "/bug2295/inv_cont_range/%d/", i); HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, - 0U, url_base + buffer, 0, 25, @@ -2984,7 +2965,6 @@ void HttpRequestTestObjectType::test<23>() std::ostringstream url; url << url_base << i << "/"; HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, - 0U, url.str(), 0, 0, diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp index 0d8fb4863b..bb603d3d7f 100644 --- a/indra/llcrashlogger/llcrashlogger.cpp +++ b/indra/llcrashlogger/llcrashlogger.cpp @@ -418,7 +418,7 @@ bool LLCrashLogger::runCrashLogPost(std::string host, LLSD data, std::string msg updateApplication(llformat("%s, try %d...", msg.c_str(), i+1)); LL_INFOS("CRASHREPORT") << "POST crash data to " << host << LL_ENDL; - LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(httpRequest.get(), LLCore::HttpRequest::DEFAULT_POLICY_ID, 0, + LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(httpRequest.get(), LLCore::HttpRequest::DEFAULT_POLICY_ID, host, data, httpOpts, LLCore::HttpHeaders::ptr_t(), LLCore::HttpHandler::ptr_t(new LLCrashLoggerHandler)); if (handle == LLCORE_HTTP_HANDLE_INVALID) diff --git a/indra/llimage/tests/llimageworker_test.cpp b/indra/llimage/tests/llimageworker_test.cpp index 9011ac615c..462dde9fb8 100644 --- a/indra/llimage/tests/llimageworker_test.cpp +++ b/indra/llimage/tests/llimageworker_test.cpp @@ -141,7 +141,7 @@ namespace tut done = false; mRequest = new LLImageDecodeThread::ImageRequest(0, 0, - LLQueuedThread::PRIORITY_NORMAL, 0, FALSE, + 0, FALSE, new responder_test(&done)); } ~imagerequest_test() @@ -198,7 +198,7 @@ namespace tut ensure("LLImageDecodeThread: non threaded init state incorrect", mThread->tut_size() == 0); // Insert something in the queue bool done = false; - LLImageDecodeThread::handle_t decodeHandle = mThread->decodeImage(NULL, LLQueuedThread::PRIORITY_NORMAL, 0, FALSE, new responder_test(&done)); + LLImageDecodeThread::handle_t decodeHandle = mThread->decodeImage(NULL, 0, FALSE, new responder_test(&done)); // Verifies we got a valid handle ensure("LLImageDecodeThread: non threaded decodeImage(), returned handle is null", decodeHandle != 0); // Verifies that we do now have something in the queued list @@ -221,7 +221,7 @@ namespace tut ensure("LLImageDecodeThread: threaded init state incorrect", mThread->tut_size() == 0); // Insert something in the queue bool done = false; - LLImageDecodeThread::handle_t decodeHandle = mThread->decodeImage(NULL, LLQueuedThread::PRIORITY_NORMAL, 0, FALSE, new responder_test(&done)); + LLImageDecodeThread::handle_t decodeHandle = mThread->decodeImage(NULL, 0, FALSE, new responder_test(&done)); // Verifies we get back a valid handle ensure("LLImageDecodeThread: threaded decodeImage(), returned handle is null", decodeHandle != 0); // Wait a little so to simulate the main thread doing something on its main loop... -- cgit v1.2.3 From 8c5697a2d6b3976979d22da5c16569ef1c5aa9fd Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 31 May 2022 08:33:18 -0500 Subject: SL-17490 Update Tracy --- autobuild.xml | 4 ++-- indra/cmake/Tracy.cmake | 1 + indra/llcommon/llframetimer.cpp | 5 ----- indra/llcommon/llprofiler.h | 6 ++++-- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 9185b8af22..d6d9488530 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3142,11 +3142,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - b649ee6591e67d2341e886b3fc3484a7 + dff3dd1db6a4cb0b73f60a5db3ee0de2 hash_algorithm md5 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/86974/801642/tracy-v0.7.8.563351-windows64-563351.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/100101/882119/tracy-v0.8.1.571983-windows64-571983.tar.bz2 name windows64 diff --git a/indra/cmake/Tracy.cmake b/indra/cmake/Tracy.cmake index cfff956bcf..dba57eb920 100644 --- a/indra/cmake/Tracy.cmake +++ b/indra/cmake/Tracy.cmake @@ -12,6 +12,7 @@ if (USE_TRACY) if (WINDOWS) MESSAGE(STATUS "Including Tracy for Windows: '${TRACY_INCLUDE_DIR}'") + set(TRACY_LIBRARY "TracyClient") endif (WINDOWS) if (DARWIN) diff --git a/indra/llcommon/llframetimer.cpp b/indra/llcommon/llframetimer.cpp index c54029e8b4..1e9920746b 100644 --- a/indra/llcommon/llframetimer.cpp +++ b/indra/llcommon/llframetimer.cpp @@ -29,11 +29,6 @@ #include "llframetimer.h" -// We don't bother building a stand alone lib; we just need to include the one source file for Tracy support -#if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY || LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER - #include "TracyClient.cpp" -#endif // LL_PROFILER_CONFIGURATION - // Static members //LLTimer LLFrameTimer::sInternalTimer; U64 LLFrameTimer::sStartTotalTime = totalTime(); diff --git a/indra/llcommon/llprofiler.h b/indra/llcommon/llprofiler.h index f9d7ae7ce4..7a593092da 100644 --- a/indra/llcommon/llprofiler.h +++ b/indra/llcommon/llprofiler.h @@ -138,8 +138,10 @@ extern thread_local bool gProfilerEnabled; #define LL_PROFILE_ZONE_ERR(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0XFF0000 ) // RGB yellow #define LL_PROFILE_ZONE_INFO(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0X00FFFF ) // RGB cyan #define LL_PROFILE_ZONE_WARN(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0x0FFFF00 ) // RGB red - #define LL_PROFILE_ALLOC(ptr, size) TracyAlloc(ptr, size) - #define LL_PROFILE_FREE(ptr) TracyFree(ptr) + //#define LL_PROFILE_ALLOC(ptr, size) TracyAlloc(ptr, size) // memory allocation tracking currently not working + //#define LL_PROFILE_FREE(ptr) TracyFree(ptr) + #define LL_PROFILE_ALLOC(ptr, size) (void)(ptr); (void)(size); + #define LL_PROFILE_FREE(ptr) (void)(ptr); #endif #else #define LL_PROFILER_FRAME_END -- cgit v1.2.3 From dfa71e2bb59e81de93f626fada6975ae46b01bb6 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 31 May 2022 11:57:15 -0500 Subject: SL-17490 Only update a subset of textures each frame and remove dead debug code. --- indra/newview/CMakeLists.txt | 2 - indra/newview/app_settings/settings.xml | 103 +- indra/newview/llappviewer.cpp | 19 +- indra/newview/llfloatertexturefetchdebugger.cpp | 480 ---------- indra/newview/llfloatertexturefetchdebugger.h | 77 -- indra/newview/lltexturefetch.cpp | 1005 +------------------- indra/newview/lltexturefetch.h | 219 ----- indra/newview/llviewerfloaterreg.cpp | 5 - indra/newview/llviewermenu.cpp | 10 - indra/newview/llviewerstats.cpp | 15 - indra/newview/llviewerstats.h | 1 - indra/newview/llviewertexture.cpp | 13 - indra/newview/llviewertexture.h | 1 - indra/newview/llviewertexturelist.cpp | 171 +--- indra/newview/llviewertexturelist.h | 5 - indra/newview/llviewerwindow.cpp | 12 - .../xui/en/floater_texture_fetch_debugger.xml | 440 --------- indra/newview/skins/default/xui/en/menu_viewer.xml | 14 - 18 files changed, 25 insertions(+), 2567 deletions(-) delete mode 100644 indra/newview/llfloatertexturefetchdebugger.cpp delete mode 100644 indra/newview/llfloatertexturefetchdebugger.h delete mode 100644 indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 964615320d..c253eca94e 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -319,7 +319,6 @@ set(viewer_SOURCE_FILES llfloatertelehub.cpp llfloatertestinspectors.cpp llfloatertestlistview.cpp - llfloatertexturefetchdebugger.cpp llfloatertools.cpp llfloatertopobjects.cpp llfloatertos.cpp @@ -958,7 +957,6 @@ set(viewer_HEADER_FILES llfloatertelehub.h llfloatertestinspectors.h llfloatertestlistview.h - llfloatertexturefetchdebugger.h llfloatertools.h llfloatertopobjects.h llfloatertos.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index c41118d6a7..6426964190 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -12436,17 +12436,6 @@ Value 20.0 - TexelPixelRatio - - Comment - texel pixel ratio = texel / pixel - Persist - 1 - Type - F32 - Value - 2.0 - TextureCameraMotionThreshold Comment @@ -12546,17 +12535,6 @@ Value 0 - TextureFetchDebuggerEnabled - - Comment - Enable the texture fetching debugger if set - Persist - 1 - Type - Boolean - Value - 0 - TextureFetchMinTimeToLog Comment @@ -12579,76 +12557,10 @@ Value 0.0 - TextureFetchSource - - Comment - Debug use: Source to fetch textures - Persist - 1 - Type - S32 - Value - 0 - - TextureFetchUpdateHighPriority - - Comment - Number of high priority textures to update per frame - Persist - 1 - Type - S32 - Value - 32 - - TextureFetchUpdateMaxMediumPriority - - Comment - Maximum number of medium priority textures to update per frame - Persist - 1 - Type - S32 - Value - 256 - - TextureFetchUpdateMinMediumPriority - - Comment - Minimum number of medium priority textures to update per frame - Persist - 1 - Type - S32 - Value - 32 - - TextureFetchUpdatePriorityThreshold - - Comment - Threshold under which textures will be considered too low priority and skipped for update - Persist - 1 - Type - F32 - Value - 0.0 - - TextureFetchUpdateSkipLowPriority - - Comment - Flag indicating if we want to skip textures with too low of a priority - Persist - 1 - Type - Boolean - Value - 0 - - TextureFetchUpdatePriorities + TextureFetchUpdateMinCount Comment - Number of priority texture to update per frame + Minimum number of textures to update per frame Persist 1 Type @@ -12656,17 +12568,6 @@ Value 32 - TextureListFetchingThreshold - - Comment - If the ratio between fetched and all textures in the list is greater than this threshold, which we assume that almost all textures are fetched - Persist - 1 - Type - F32 - Value - 0.97 - TextureLoadFullRes Comment diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index e9bf6bf4e5..a172308d2a 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -103,7 +103,6 @@ #include "lldiskcache.h" #include "llvopartgroup.h" #include "llweb.h" -#include "llfloatertexturefetchdebugger.h" #include "llspellcheck.h" #include "llscenemonitor.h" #include "llavatarrenderinfoaccountant.h" @@ -1627,21 +1626,9 @@ bool LLAppViewer::doFrame() LLLFSThread::sLocal->pause(); } - //texture fetching debugger - if(LLTextureFetchDebugger::isEnabled()) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df tex_fetch_debugger_instance" ) - LLFloaterTextureFetchDebugger* tex_fetch_debugger_instance = - LLFloaterReg::findTypedInstance("tex_fetch_debugger"); - if(tex_fetch_debugger_instance) - { - tex_fetch_debugger_instance->idle() ; - } - } - { LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df resumeMainloopTimeout" ) - resumeMainloopTimeout(); + resumeMainloopTimeout(); } pingMainloopTimeout("Main:End"); } @@ -4679,10 +4666,6 @@ void LLAppViewer::idle() // // Special case idle if still starting up // - if (LLStartUp::getStartupState() >= STATE_WORLD_INIT) - { - update_texture_time(); - } if (LLStartUp::getStartupState() < STATE_STARTED) { // Skip rest if idle startup returns false (essentially, no world yet) diff --git a/indra/newview/llfloatertexturefetchdebugger.cpp b/indra/newview/llfloatertexturefetchdebugger.cpp deleted file mode 100644 index cda4dc8bcc..0000000000 --- a/indra/newview/llfloatertexturefetchdebugger.cpp +++ /dev/null @@ -1,480 +0,0 @@ -/** - * @file llfloatertexturefetchdebugger.cpp - * @brief LLFloaterTextureFetchDebugger class definition - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2012, 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 "llfloatertexturefetchdebugger.h" - -#include "lluictrlfactory.h" -#include "llbutton.h" -#include "llspinctrl.h" -#include "llresmgr.h" - -#include "llmath.h" -#include "llviewerwindow.h" -#include "llappviewer.h" -#include "lltexturefetch.h" -#include "llviewercontrol.h" -#include "llviewerassetstats.h" //gTextureTimer - -LLFloaterTextureFetchDebugger::LLFloaterTextureFetchDebugger(const LLSD& key) - : LLFloater(key), - mDebugger(NULL) -{ - setTitle("Texture Fetching Debugger Floater"); - - mCommitCallbackRegistrar.add("TexFetchDebugger.ChangeTexelPixelRatio", boost::bind(&LLFloaterTextureFetchDebugger::onChangeTexelPixelRatio, this)); - - mCommitCallbackRegistrar.add("TexFetchDebugger.Start", boost::bind(&LLFloaterTextureFetchDebugger::onClickStart, this)); - mCommitCallbackRegistrar.add("TexFetchDebugger.Clear", boost::bind(&LLFloaterTextureFetchDebugger::onClickClear, this)); - mCommitCallbackRegistrar.add("TexFetchDebugger.Close", boost::bind(&LLFloaterTextureFetchDebugger::onClickClose, this)); - mCommitCallbackRegistrar.add("TexFetchDebugger.ResetFetchTime", boost::bind(&LLFloaterTextureFetchDebugger::onClickResetFetchTime, this)); - - mCommitCallbackRegistrar.add("TexFetchDebugger.CacheRead", boost::bind(&LLFloaterTextureFetchDebugger::onClickCacheRead, this)); - mCommitCallbackRegistrar.add("TexFetchDebugger.CacheWrite", boost::bind(&LLFloaterTextureFetchDebugger::onClickCacheWrite, this)); - mCommitCallbackRegistrar.add("TexFetchDebugger.HTTPLoad", boost::bind(&LLFloaterTextureFetchDebugger::onClickHTTPLoad, this)); - mCommitCallbackRegistrar.add("TexFetchDebugger.Decode", boost::bind(&LLFloaterTextureFetchDebugger::onClickDecode, this)); - mCommitCallbackRegistrar.add("TexFetchDebugger.GLTexture", boost::bind(&LLFloaterTextureFetchDebugger::onClickGLTexture, this)); - - mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchVisCache", boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchVisCache, this)); - mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchVisHTTP", boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchVisHTTP, this)); - mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchAllCache", boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchAllCache, this)); - mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchAllHTTP", boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchAllHTTP, this)); -} -//---------------------------------------------- - -BOOL LLFloaterTextureFetchDebugger::postBuild(void) -{ - mDebugger = LLAppViewer::getTextureFetch()->getFetchDebugger(); - mStartStatus = (S32)LLTextureFetchDebugger::IDLE; - - //set states for buttons - mButtonStateMap["start_btn"] = true; - mButtonStateMap["close_btn"] = true; - mButtonStateMap["clear_btn"] = true; - mButtonStateMap["cacheread_btn"] = false; - mButtonStateMap["cachewrite_btn"] = false; - mButtonStateMap["http_btn"] = false; - mButtonStateMap["decode_btn"] = false; - mButtonStateMap["gl_btn"] = false; - - mButtonStateMap["refetchviscache_btn"] = false; - mButtonStateMap["refetchvishttp_btn"] = false; - mButtonStateMap["refetchallcache_btn"] = false; - mButtonStateMap["refetchallhttp_btn"] = false; - - updateButtons(); - - getChild("texel_pixel_ratio")->setValue(gSavedSettings.getF32("TexelPixelRatio")); - - return TRUE ; -} - -LLFloaterTextureFetchDebugger::~LLFloaterTextureFetchDebugger() -{ - //stop everything - mDebugger->setStopDebug(); -} - -void LLFloaterTextureFetchDebugger::updateButtons() -{ - for(std::map::iterator iter = mButtonStateMap.begin(); iter != mButtonStateMap.end(); ++iter) - { - if(iter->second) - { - childEnable(iter->first.c_str()); - } - else - { - childDisable(iter->first.c_str()); - } - } -} - -void LLFloaterTextureFetchDebugger::disableButtons() -{ - childDisable("start_btn"); - childDisable("clear_btn"); - childDisable("cacheread_btn"); - childDisable("cachewrite_btn"); - childDisable("http_btn"); - childDisable("decode_btn"); - childDisable("gl_btn"); - childDisable("refetchviscache_btn"); - childDisable("refetchvishttp_btn"); - childDisable("refetchallcache_btn"); - childDisable("refetchallhttp_btn"); -} -void LLFloaterTextureFetchDebugger::setStartStatus(S32 status) -{ - llassert_always(LLTextureFetchDebugger::IDLE == (LLTextureFetchDebugger::e_debug_state)mStartStatus) ; - mStartStatus = status; -} - -bool LLFloaterTextureFetchDebugger::idleStart() -{ - if(mStartStatus != (S32)LLTextureFetchDebugger::IDLE) - { - mDebugger->startWork((LLTextureFetchDebugger::e_debug_state)mStartStatus); - mStartStatus = (S32)LLTextureFetchDebugger::IDLE; - return true; - } - - return false; -} - -void LLFloaterTextureFetchDebugger::idle() -{ - if(idleStart()) - { - return; - } - - const F32 max_time = 0.005f; //5ms - LLTextureFetchDebugger::e_debug_state state = mDebugger->getState(); - if(mDebugger->update(max_time)) - { - switch(state) - { - case LLTextureFetchDebugger::IDLE: - break; - case LLTextureFetchDebugger::START_DEBUG: - mButtonStateMap["cacheread_btn"] = true; - mButtonStateMap["http_btn"] = true; - mButtonStateMap["refetchviscache_btn"] = true; - mButtonStateMap["refetchvishttp_btn"] = true; - mButtonStateMap["refetchallcache_btn"] = true; - mButtonStateMap["refetchallhttp_btn"] = true; - break; - case LLTextureFetchDebugger::READ_CACHE: - mButtonStateMap["decode_btn"] = true; - break; - case LLTextureFetchDebugger::WRITE_CACHE: - break; - case LLTextureFetchDebugger::DECODING: - mButtonStateMap["gl_btn"] = true; - break; - case LLTextureFetchDebugger::HTTP_FETCHING: - mButtonStateMap["cacheread_btn"] = true; - mButtonStateMap["cachewrite_btn"] = true; - mButtonStateMap["decode_btn"] = true; - break; - case LLTextureFetchDebugger::GL_TEX: - break; - case LLTextureFetchDebugger::REFETCH_VIS_CACHE: - break; - case LLTextureFetchDebugger::REFETCH_VIS_HTTP: - break; - case LLTextureFetchDebugger::REFETCH_ALL_CACHE: - break; - case LLTextureFetchDebugger::REFETCH_ALL_HTTP: - break; - default: - break; - } - - if(state != LLTextureFetchDebugger::IDLE) - { - updateButtons(); - } - } -} - -//---------------------- -void LLFloaterTextureFetchDebugger::onChangeTexelPixelRatio() -{ - gSavedSettings.setF32("TexelPixelRatio", getChild("texel_pixel_ratio")->getValue().asReal()); -} - -void LLFloaterTextureFetchDebugger::onClickStart() -{ - disableButtons(); - - setStartStatus((S32)LLTextureFetchDebugger::START_DEBUG); - - mButtonStateMap["start_btn"] = false; - - updateButtons(); -} - -void LLFloaterTextureFetchDebugger::onClickClose() -{ - setVisible(FALSE); - - //stop everything - mDebugger->setStopDebug(); - - delete this; -} - -void LLFloaterTextureFetchDebugger::onClickResetFetchTime() -{ - gTextureTimer.start(); - gTextureTimer.pause(); -} - -void LLFloaterTextureFetchDebugger::onClickClear() -{ - mButtonStateMap["start_btn"] = true; - mButtonStateMap["close_btn"] = true; - mButtonStateMap["clear_btn"] = true; - mButtonStateMap["cacheread_btn"] = false; - mButtonStateMap["cachewrite_btn"] = false; - mButtonStateMap["http_btn"] = false; - mButtonStateMap["decode_btn"] = false; - mButtonStateMap["gl_btn"] = false; - mButtonStateMap["refetchviscache_btn"] = true; - mButtonStateMap["refetchvishttp_btn"] = true; - updateButtons(); - - //stop everything - mDebugger->setStopDebug(); - mDebugger->clearHistory(); -} - -void LLFloaterTextureFetchDebugger::onClickCacheRead() -{ - disableButtons(); - - setStartStatus((S32)LLTextureFetchDebugger::READ_CACHE); -} - -void LLFloaterTextureFetchDebugger::onClickCacheWrite() -{ - disableButtons(); - - setStartStatus((S32)LLTextureFetchDebugger::WRITE_CACHE); -} - -void LLFloaterTextureFetchDebugger::onClickHTTPLoad() -{ - disableButtons(); - - setStartStatus((S32)LLTextureFetchDebugger::HTTP_FETCHING); -} - -void LLFloaterTextureFetchDebugger::onClickDecode() -{ - disableButtons(); - - setStartStatus((S32)LLTextureFetchDebugger::DECODING); -} - -void LLFloaterTextureFetchDebugger::onClickGLTexture() -{ - disableButtons(); - - setStartStatus((S32)LLTextureFetchDebugger::GL_TEX); -} - -void LLFloaterTextureFetchDebugger::onClickRefetchVisCache() -{ - disableButtons(); - - setStartStatus((S32)LLTextureFetchDebugger::REFETCH_VIS_CACHE); -} - -void LLFloaterTextureFetchDebugger::onClickRefetchVisHTTP() -{ - disableButtons(); - - setStartStatus((S32)LLTextureFetchDebugger::REFETCH_VIS_HTTP); -} - -void LLFloaterTextureFetchDebugger::onClickRefetchAllCache() -{ - disableButtons(); - - setStartStatus((S32)LLTextureFetchDebugger::REFETCH_ALL_CACHE); -} - -void LLFloaterTextureFetchDebugger::onClickRefetchAllHTTP() -{ - disableButtons(); - - setStartStatus((S32)LLTextureFetchDebugger::REFETCH_ALL_HTTP); -} - -void LLFloaterTextureFetchDebugger::draw() -{ - //total number of fetched textures - { - getChild("total_num_fetched_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumFetchedTextures())); - } - - //total number of fetching requests - { - getChild("total_num_fetching_requests_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumFetchingRequests())); - } - - //total number of cache hits - { - getChild("total_num_cache_hits_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumCacheHits())); - } - - //total number of visible textures - { - getChild("total_num_visible_tex_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumVisibleFetchedTextures())); - } - - //total number of visible texture fetching requests - { - getChild("total_num_visible_tex_fetch_req_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumVisibleFetchingRequests())); - } - - //total number of fetched data - { - getChild("total_fetched_data_label")->setTextArg("[SIZE1]", llformat("%d", mDebugger->getFetchedData() >> 10)); - getChild("total_fetched_data_label")->setTextArg("[SIZE2]", llformat("%d", mDebugger->getDecodedData() >> 10)); - getChild("total_fetched_data_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getFetchedPixels() / 1000000.f)); - } - - //total number of visible fetched data - { - getChild("total_fetched_vis_data_label")->setTextArg("[SIZE1]", llformat("%d", mDebugger->getVisibleFetchedData() >> 10)); - getChild("total_fetched_vis_data_label")->setTextArg("[SIZE2]", llformat("%d", mDebugger->getVisibleDecodedData() >> 10)); - } - - //total number of rendered fetched data - { - getChild("total_fetched_rendered_data_label")->setTextArg("[SIZE1]", llformat("%d", mDebugger->getRenderedData() >> 10)); - getChild("total_fetched_rendered_data_label")->setTextArg("[SIZE2]", llformat("%d", mDebugger->getRenderedDecodedData() >> 10)); - getChild("total_fetched_rendered_data_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRenderedPixels() / 1000000.f)); - } - - //total time on cache readings - if(mDebugger->getCacheReadTime() < 0.f) - { - getChild("total_time_cache_read_label")->setTextArg("[TIME]", std::string("----")); - } - else - { - getChild("total_time_cache_read_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getCacheReadTime())); - } - - //total time on cache writings - if(mDebugger->getCacheWriteTime() < 0.f) - { - getChild("total_time_cache_write_label")->setTextArg("[TIME]", std::string("----")); - } - else - { - getChild("total_time_cache_write_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getCacheWriteTime())); - } - - //total time on decoding - if(mDebugger->getDecodeTime() < 0.f) - { - getChild("total_time_decode_label")->setTextArg("[TIME]", std::string("----")); - } - else - { - getChild("total_time_decode_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getDecodeTime())); - } - - //total time on gl texture creation - if(mDebugger->getGLCreationTime() < 0.f) - { - getChild("total_time_gl_label")->setTextArg("[TIME]", std::string("----")); - } - else - { - getChild("total_time_gl_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getGLCreationTime())); - } - - //total time on HTTP fetching - if(mDebugger->getHTTPTime() < 0.f) - { - getChild("total_time_http_label")->setTextArg("[TIME]", std::string("----")); - } - else - { - getChild("total_time_http_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getHTTPTime())); - } - - //total time on entire fetching - { - getChild("total_time_fetch_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getTotalFetchingTime())); - } - - //total time on refetching visible textures from cache - if(mDebugger->getRefetchVisCacheTime() < 0.f) - { - getChild("total_time_refetch_vis_cache_label")->setTextArg("[TIME]", std::string("----")); - getChild("total_time_refetch_vis_cache_label")->setTextArg("[SIZE]", std::string("----")); - getChild("total_time_refetch_vis_cache_label")->setTextArg("[PIXEL]", std::string("----")); - } - else - { - getChild("total_time_refetch_vis_cache_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchVisCacheTime())); - getChild("total_time_refetch_vis_cache_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedVisData() >> 10)); - getChild("total_time_refetch_vis_cache_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedVisPixels() / 1000000.f)); - } - - //total time on refetching all textures from cache - if(mDebugger->getRefetchAllCacheTime() < 0.f) - { - getChild("total_time_refetch_all_cache_label")->setTextArg("[TIME]", std::string("----")); - getChild("total_time_refetch_all_cache_label")->setTextArg("[SIZE]", std::string("----")); - getChild("total_time_refetch_all_cache_label")->setTextArg("[PIXEL]", std::string("----")); - } - else - { - getChild("total_time_refetch_all_cache_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchAllCacheTime())); - getChild("total_time_refetch_all_cache_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedAllData() >> 10)); - getChild("total_time_refetch_all_cache_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedAllPixels() / 1000000.f)); - } - - //total time on refetching visible textures from http - if(mDebugger->getRefetchVisHTTPTime() < 0.f) - { - getChild("total_time_refetch_vis_http_label")->setTextArg("[TIME]", std::string("----")); - getChild("total_time_refetch_vis_http_label")->setTextArg("[SIZE]", std::string("----")); - getChild("total_time_refetch_vis_http_label")->setTextArg("[PIXEL]", std::string("----")); - } - else - { - getChild("total_time_refetch_vis_http_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchVisHTTPTime())); - getChild("total_time_refetch_vis_http_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedVisData() >> 10)); - getChild("total_time_refetch_vis_http_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedVisPixels() / 1000000.f)); - } - - //total time on refetching all textures from http - if(mDebugger->getRefetchAllHTTPTime() < 0.f) - { - getChild("total_time_refetch_all_http_label")->setTextArg("[TIME]", std::string("----")); - getChild("total_time_refetch_all_http_label")->setTextArg("[SIZE]", std::string("----")); - getChild("total_time_refetch_all_http_label")->setTextArg("[PIXEL]", std::string("----")); - } - else - { - getChild("total_time_refetch_all_http_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchAllHTTPTime())); - getChild("total_time_refetch_all_http_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedAllData() >> 10)); - getChild("total_time_refetch_all_http_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedAllPixels() / 1000000.f)); - } - - LLFloater::draw(); -} diff --git a/indra/newview/llfloatertexturefetchdebugger.h b/indra/newview/llfloatertexturefetchdebugger.h deleted file mode 100644 index 637f3b03e5..0000000000 --- a/indra/newview/llfloatertexturefetchdebugger.h +++ /dev/null @@ -1,77 +0,0 @@ -/** - * @file llfloatertexturefetchdebugger.h - * @brief texture fetching debugger window, debug use only - * - * $LicenseInfo:firstyear=2004&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, 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_FLOATER_TEXTURE_FETCH_DEBUGGER__H -#define LL_FLOATER_TEXTURE_FETCH_DEBUGGER__H - -#include "llfloater.h" -class LLTextureFetchDebugger; - -class LLFloaterTextureFetchDebugger : public LLFloater -{ - friend class LLFloaterReg; -public: - /// initialize all the callbacks for the menu - - virtual BOOL postBuild() ; - virtual void draw() ; - - void onChangeTexelPixelRatio(); - - void onClickStart(); - void onClickClear(); - void onClickClose(); - void onClickResetFetchTime(); - - void onClickCacheRead(); - void onClickCacheWrite(); - void onClickHTTPLoad(); - void onClickDecode(); - void onClickGLTexture(); - - void onClickRefetchVisCache(); - void onClickRefetchVisHTTP(); - void onClickRefetchAllCache(); - void onClickRefetchAllHTTP(); -public: - void idle() ; - -private: - LLFloaterTextureFetchDebugger(const LLSD& key); - virtual ~LLFloaterTextureFetchDebugger(); - - void updateButtons(); - void disableButtons(); - - void setStartStatus(S32 status); - bool idleStart(); -private: - LLTextureFetchDebugger* mDebugger; - std::map mButtonStateMap; - S32 mStartStatus; -}; - -#endif // LL_FLOATER_TEXTURE_FETCH_DEBUGGER__H diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 543e8b0dab..d811b32f4f 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -62,8 +62,6 @@ #include "llcorehttputil.h" #include "llhttpretrypolicy.h" -bool LLTextureFetchDebugger::sDebuggerEnabled = false ; - LLTrace::CountStatHandle LLTextureFetch::sCacheHit("texture_cache_hit"); LLTrace::CountStatHandle LLTextureFetch::sCacheAttempt("texture_cache_attempt"); LLTrace::EventStatHandle > LLTextureFetch::sCacheHitRate("texture_cache_hits"); @@ -244,8 +242,8 @@ static const S32 HTTP_REQUESTS_RANGE_END_MAX = 20000000; ////////////////////////////////////////////////////////////////////////////// namespace { - // The NoOpDeletor is used when passing certain objects (the LLTextureFetchWorker and - // the LLTextureFetchDebugger) in a smart pointer below for passage into + // The NoOpDeletor is used when passing certain objects (the LLTextureFetchWorker) + // in a smart pointer below for passage into // the LLCore::Http libararies. When the smart pointer is destroyed, no // action will be taken since we do not in these cases want the object to // be destroyed at the end of the call. @@ -283,7 +281,6 @@ class LLTextureFetchWorker : public LLWorkerClass, public LLCore::HttpHandler { friend class LLTextureFetch; - friend class LLTextureFetchDebugger; private: class CacheReadResponder : public LLTextureCache::ReadResponder @@ -1883,11 +1880,6 @@ bool LLTextureFetchWorker::doWork(S32 param) LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - DECODE_IMAGE_UPDATE"); if (mDecoded) { - if(mFetcher->getFetchDebugger() && !mInLocalCache) - { - mFetcher->getFetchDebugger()->addHistoryEntry(this); - } - mDecodeTime = mDecodeTimer.getElapsedTimeF32(); if (mDecodedDiscard < 0) @@ -2574,10 +2566,8 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image mTotalCacheReadCount(0U), mTotalCacheWriteCount(0U), mTotalResourceWaitCount(0U), - mFetchDebugger(NULL), mFetchSource(LLTextureFetch::FROM_ALL), mOriginFetchSource(LLTextureFetch::FROM_ALL), - mFetcherLocked(FALSE), mTextureInfoMainThread(false) { mMaxBandwidth = gSavedSettings.getF32("ThrottleBandwidthKBPS"); @@ -2598,21 +2588,6 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image mHttpLowWater = HTTP_NONPIPE_REQUESTS_LOW_WATER; mHttpSemaphore = 0; - // Conditionally construct debugger object after 'this' is - // fully initialized. - LLTextureFetchDebugger::sDebuggerEnabled = gSavedSettings.getBOOL("TextureFetchDebuggerEnabled"); - if(LLTextureFetchDebugger::isEnabled()) - { - mFetchDebugger = new LLTextureFetchDebugger(this, cache, imagedecodethread) ; - mFetchSource = (e_tex_source)gSavedSettings.getS32("TextureFetchSource"); - if(mFetchSource < 0 && mFetchSource >= INVALID_SOURCE) - { - mFetchSource = LLTextureFetch::FROM_ALL; - gSavedSettings.setS32("TextureFetchSource", 0); - } - mOriginFetchSource = mFetchSource; - } - // If that test log has ben requested but not yet created, create it if (LLMetricPerformanceTesterBasic::isMetricLogRequested(sTesterName) && !LLMetricPerformanceTesterBasic::getTester(sTesterName)) { @@ -2641,9 +2616,6 @@ LLTextureFetch::~LLTextureFetch() delete mHttpRequest; mHttpRequest = NULL; - delete mFetchDebugger; - mFetchDebugger = NULL; - // ~LLQueuedThread() called here } @@ -2651,10 +2623,6 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const S32 w, S32 h, S32 c, S32 desired_discard, bool needs_aux, bool can_use_http) { LL_PROFILE_ZONE_SCOPED; - if(mFetcherLocked) - { - return false; - } if (mDebugPause) { return false; @@ -3181,11 +3149,6 @@ S32 LLTextureFetch::update(F32 max_time_ms) commonUpdate(); } - if (mFetchDebugger) - { - mFetchDebugger->tryToStopDebug(); //check if need to stop debugger. - } - return res; } @@ -4218,970 +4181,6 @@ truncate_viewer_metrics(int max_regions, LLSD & metrics) } // end of anonymous namespace - -/////////////////////////////////////////////////////////////////////////////////////////// -//Start LLTextureFetchDebugger -/////////////////////////////////////////////////////////////////////////////////////////// -//--------------------- -class LLDebuggerCacheReadResponder : public LLTextureCache::ReadResponder -{ -public: - LLDebuggerCacheReadResponder(LLTextureFetchDebugger* debugger, S32 id, LLImageFormatted* image) - : mDebugger(debugger), mID(id) - { - setImage(image); - } - virtual void completed(bool success) - { - mDebugger->callbackCacheRead(mID, success, mFormattedImage, mImageSize, mImageLocal); - } -private: - LLTextureFetchDebugger* mDebugger; - S32 mID; -}; - -class LLDebuggerCacheWriteResponder : public LLTextureCache::WriteResponder -{ -public: - LLDebuggerCacheWriteResponder(LLTextureFetchDebugger* debugger, S32 id) - : mDebugger(debugger), mID(id) - { - } - virtual void completed(bool success) - { - mDebugger->callbackCacheWrite(mID, success); - } -private: - LLTextureFetchDebugger* mDebugger; - S32 mID; -}; - -class LLDebuggerDecodeResponder : public LLImageDecodeThread::Responder -{ -public: - LLDebuggerDecodeResponder(LLTextureFetchDebugger* debugger, S32 id) - : mDebugger(debugger), mID(id) - { - } - virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux) - { - mDebugger->callbackDecoded(mID, success, raw, aux); - } -private: - LLTextureFetchDebugger* mDebugger; - S32 mID; -}; - - -LLTextureFetchDebugger::LLTextureFetchDebugger(LLTextureFetch* fetcher, LLTextureCache* cache, LLImageDecodeThread* imagedecodethread) : - LLCore::HttpHandler(), - mFetcher(fetcher), - mTextureCache(cache), - mImageDecodeThread(imagedecodethread), - mHttpHeaders(), - mHttpPolicyClass(fetcher->getPolicyClass()), - mNbCurlCompleted(0), - mTempIndex(0), - mHistoryListIndex(0) -{ - init(); -} - -LLTextureFetchDebugger::~LLTextureFetchDebugger() -{ - mFetchingHistory.clear(); - mStopDebug = TRUE; - tryToStopDebug(); -} - -void LLTextureFetchDebugger::init() -{ - setDebuggerState(IDLE); - - mCacheReadTime = -1.f; - mCacheWriteTime = -1.f; - mDecodingTime = -1.f; - mHTTPTime = -1.f; - mGLCreationTime = -1.f; - - mTotalFetchingTime = 0.f; - mRefetchVisCacheTime = -1.f; - mRefetchVisHTTPTime = -1.f; - mRefetchAllCacheTime = -1.f; - mRefetchAllHTTPTime = -1.f; - - mNumFetchedTextures = 0; - mNumCacheHits = 0; - mNumVisibleFetchedTextures = 0; - mNumVisibleFetchingRequests = 0; - mFetchedData = 0; - mDecodedData = 0; - mVisibleFetchedData = 0; - mVisibleDecodedData = 0; - mRenderedData = 0; - mRenderedDecodedData = 0; - mFetchedPixels = 0; - mRenderedPixels = 0; - mRefetchedVisData = 0; - mRefetchedVisPixels = 0; - mRefetchedAllData = 0; - mRefetchedAllPixels = 0; - - mFreezeHistory = FALSE; - mStopDebug = FALSE; - mClearHistory = FALSE; - mRefetchNonVis = FALSE; - - mNbCurlRequests = 0; - - if (! mHttpHeaders) - { - mHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders); - mHttpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_IMAGE_X_J2C); - } -} - -void LLTextureFetchDebugger::startWork(e_debug_state state) -{ - switch(state) - { - case IDLE: - break; - case START_DEBUG: - startDebug(); - break; - case READ_CACHE: - debugCacheRead(); - break; - case WRITE_CACHE: - debugCacheWrite(); - break; - case DECODING: - debugDecoder(); - break; - case HTTP_FETCHING: - debugHTTP(); - break; - case GL_TEX: - debugGLTextureCreation(); - break; - case REFETCH_VIS_CACHE: - debugRefetchVisibleFromCache(); - break; - case REFETCH_VIS_HTTP: - debugRefetchVisibleFromHTTP(); - break; - case REFETCH_ALL_CACHE: - debugRefetchAllFromCache(); - break; - case REFETCH_ALL_HTTP: - debugRefetchAllFromHTTP(); - break; - default: - break; - } - return; -} - -void LLTextureFetchDebugger::startDebug() -{ - //lock the fetcher - mFetcher->lockFetcher(true); - mFreezeHistory = TRUE; - mFetcher->resetLoadSource(); - - //clear the current fetching queue - gTextureList.clearFetchingRequests(); - - setDebuggerState(START_DEBUG); -} - -bool LLTextureFetchDebugger::processStartDebug(F32 max_time) -{ - mTimer.reset(); - - //wait for all works to be done - while(1) - { - S32 pending = 0; - pending += LLAppViewer::getTextureCache()->update(1); - pending += LLAppViewer::getImageDecodeThread()->update(1); - // pending += LLAppViewer::getTextureFetch()->update(1); // This causes infinite recursion in some cases - pending += mNbCurlRequests; - if(!pending) - { - break; - } - - if(mTimer.getElapsedTimeF32() > max_time) - { - return false; - } - } - - //collect statistics - mTotalFetchingTime = gTextureTimer.getElapsedTimeF32() - mTotalFetchingTime; - - std::set fetched_textures; - S32 size = mFetchingHistory.size(); - for(S32 i = 0 ; i < size; i++) - { - bool in_list = true; - if(fetched_textures.find(mFetchingHistory[i].mID) == fetched_textures.end()) - { - fetched_textures.insert(mFetchingHistory[i].mID); - in_list = false; - } - - std::vector textures; - LLViewerTextureManager::findFetchedTextures(mFetchingHistory[i].mID, textures); - std::vector::iterator iter = textures.begin(); - while (iter != textures.end()) - { - LLViewerFetchedTexture* tex = *iter++; - // fetched data will be counted for both ui and regular elements - if (tex && tex->isJustBound()) //visible - { - if (!in_list) - { - mNumVisibleFetchedTextures++; - } - mNumVisibleFetchingRequests++; - - mVisibleFetchedData += mFetchingHistory[i].mFetchedSize; - mVisibleDecodedData += mFetchingHistory[i].mDecodedSize; - - if (tex->getDiscardLevel() >= mFetchingHistory[i].mDecodedLevel) - { - mRenderedData += mFetchingHistory[i].mFetchedSize; - mRenderedDecodedData += mFetchingHistory[i].mDecodedSize; - mRenderedPixels += tex->getWidth() * tex->getHeight(); - } - } - } - } - - mNumFetchedTextures = fetched_textures.size(); - - return true; -} - -void LLTextureFetchDebugger::tryToStopDebug() -{ - if(!mStopDebug) - { - return; - } - - //clear the current debug work - S32 size = mFetchingHistory.size(); - switch(mDebuggerState) - { - case READ_CACHE: - for(S32 i = 0 ; i < size; i++) - { - if (mFetchingHistory[i]. mCacheHandle != LLTextureCache::nullHandle()) - { - mTextureCache->readComplete(mFetchingHistory[i].mCacheHandle, true); - } - } - break; - case WRITE_CACHE: - for(S32 i = 0 ; i < size; i++) - { - if (mFetchingHistory[i].mCacheHandle != LLTextureCache::nullHandle()) - { - mTextureCache->writeComplete(mFetchingHistory[i].mCacheHandle, true); - } - } - break; - case DECODING: - break; - case HTTP_FETCHING: - break; - case GL_TEX: - break; - case REFETCH_VIS_CACHE: - break; - case REFETCH_VIS_HTTP: - break; - case REFETCH_ALL_CACHE: - mRefetchList.clear(); - break; - case REFETCH_ALL_HTTP: - mRefetchList.clear(); - break; - default: - break; - } - - if(update(0.005f)) - { - //unlock the fetcher - mFetcher->lockFetcher(false); - mFetcher->resetLoadSource(); - mFreezeHistory = FALSE; - mStopDebug = FALSE; - - if(mClearHistory) - { - mFetchingHistory.clear(); - mHandleToFetchIndex.clear(); - init(); - mTotalFetchingTime = gTextureTimer.getElapsedTimeF32(); //reset - } - } -} - -//called in the main thread and when the fetching queue is empty -void LLTextureFetchDebugger::clearHistory() -{ - mClearHistory = TRUE; -} - -void LLTextureFetchDebugger::addHistoryEntry(LLTextureFetchWorker* worker) -{ - if(worker->mRawImage.isNull() || worker->mFormattedImage.isNull()) - { - return; - } - - if(mFreezeHistory) - { - if(mDebuggerState == REFETCH_VIS_CACHE || mDebuggerState == REFETCH_VIS_HTTP) - { - mRefetchedVisPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight(); - mRefetchedVisData += worker->mFormattedImage->getDataSize(); - } - else - { - mRefetchedAllPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight(); - mRefetchedAllData += worker->mFormattedImage->getDataSize(); - - // refetch list only requests/creates normal images, so requesting ui='false' - LLViewerFetchedTexture* tex = LLViewerTextureManager::findFetchedTexture(worker->mID, TEX_LIST_STANDARD); - if(tex && mRefetchList[tex].begin() != mRefetchList[tex].end()) - { - if(worker->mDecodedDiscard == mFetchingHistory[mRefetchList[tex][0]].mDecodedLevel) - { - mRefetchList[tex].erase(mRefetchList[tex].begin()); - } - } - } - return; - } - - if(worker->mInCache) - { - mNumCacheHits++; - } - mFetchedData += worker->mFormattedImage->getDataSize(); - mDecodedData += worker->mRawImage->getDataSize(); - mFetchedPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight(); - - mFetchingHistory.push_back(FetchEntry(worker->mID, worker->mDesiredSize, worker->mDecodedDiscard, - worker->mFormattedImage->getDataSize(), worker->mRawImage->getDataSize())); -} - -void LLTextureFetchDebugger::lockCache() -{ -} - -void LLTextureFetchDebugger::unlockCache() -{ -} - -void LLTextureFetchDebugger::debugCacheRead() -{ - lockCache(); - llassert_always(mDebuggerState == IDLE); - mTimer.reset(); - setDebuggerState(READ_CACHE); - mCacheReadTime = -1.f; - - S32 size = mFetchingHistory.size(); - for(S32 i = 0 ; i < size ; i++) - { - mFetchingHistory[i].mFormattedImage = NULL; - mFetchingHistory[i].mCacheHandle = mTextureCache->readFromCache(mFetchingHistory[i].mID, 0, mFetchingHistory[i].mFetchedSize, - new LLDebuggerCacheReadResponder(this, i, mFetchingHistory[i].mFormattedImage)); - } -} - -void LLTextureFetchDebugger::clearCache() -{ - S32 size = mFetchingHistory.size(); - { - std::set deleted_list; - for(S32 i = 0 ; i < size ; i++) - { - if(deleted_list.find(mFetchingHistory[i].mID) == deleted_list.end()) - { - deleted_list.insert(mFetchingHistory[i].mID); - mTextureCache->removeFromCache(mFetchingHistory[i].mID); - } - } - } -} - -void LLTextureFetchDebugger::debugCacheWrite() -{ - //remove from cache - clearCache(); - - lockCache(); - llassert_always(mDebuggerState == IDLE); - mTimer.reset(); - setDebuggerState(WRITE_CACHE); - mCacheWriteTime = -1.f; - - S32 size = mFetchingHistory.size(); - for(S32 i = 0 ; i < size ; i++) - { - if(mFetchingHistory[i].mFormattedImage.notNull()) - { - mFetchingHistory[i].mCacheHandle = mTextureCache->writeToCache(mFetchingHistory[i].mID, - mFetchingHistory[i].mFormattedImage->getData(), mFetchingHistory[i].mFetchedSize, - mFetchingHistory[i].mDecodedLevel == 0 ? mFetchingHistory[i].mFetchedSize : mFetchingHistory[i].mFetchedSize + 1, - NULL, 0, new LLDebuggerCacheWriteResponder(this, i)); - } - } -} - -void LLTextureFetchDebugger::lockDecoder() -{ -} - -void LLTextureFetchDebugger::unlockDecoder() -{ -} - -void LLTextureFetchDebugger::debugDecoder() -{ - lockDecoder(); - llassert_always(mDebuggerState == IDLE); - mTimer.reset(); - setDebuggerState(DECODING); - mDecodingTime = -1.f; - - S32 size = mFetchingHistory.size(); - for(S32 i = 0 ; i < size ; i++) - { - if(mFetchingHistory[i].mFormattedImage.isNull()) - { - continue; - } - - mImageDecodeThread->decodeImage(mFetchingHistory[i].mFormattedImage, - mFetchingHistory[i].mDecodedLevel, mFetchingHistory[i].mNeedsAux, - new LLDebuggerDecodeResponder(this, i)); - } -} - -void LLTextureFetchDebugger::debugHTTP() -{ - llassert_always(mDebuggerState == IDLE); - - LLViewerRegion* region = gAgent.getRegion(); - if (!region) - { - LL_INFOS(LOG_TXT) << "Fetch Debugger : Current region undefined. Cannot fetch textures through HTTP." << LL_ENDL; - return; - } - - mHTTPUrl = region->getViewerAssetUrl(); - if (mHTTPUrl.empty()) - { - LL_INFOS(LOG_TXT) << "Fetch Debugger : Current region URL undefined. Cannot fetch textures through HTTP." << LL_ENDL; - return; - } - - mTimer.reset(); - setDebuggerState(HTTP_FETCHING); - mHTTPTime = -1.f; - - S32 size = mFetchingHistory.size(); - for (S32 i = 0 ; i < size ; i++) - { - mFetchingHistory[i].mCurlState = FetchEntry::CURL_NOT_DONE; - mFetchingHistory[i].mCurlReceivedSize = 0; - mFetchingHistory[i].mFormattedImage = NULL; - } - mNbCurlRequests = 0; - mNbCurlCompleted = 0; - - fillCurlQueue(); -} - -S32 LLTextureFetchDebugger::fillCurlQueue() -{ - if(mStopDebug) //stop - { - mNbCurlCompleted = mFetchingHistory.size(); - return 0; - } - if (mNbCurlRequests > HTTP_NONPIPE_REQUESTS_LOW_WATER) - { - return mNbCurlRequests; - } - - S32 size = mFetchingHistory.size(); - for (S32 i = 0 ; i < size ; i++) - { - if (mFetchingHistory[i].mCurlState != FetchEntry::CURL_NOT_DONE) - { - continue; - } - std::string texture_url = mHTTPUrl + "/?texture_id=" + mFetchingHistory[i].mID.asString().c_str(); - S32 requestedSize = mFetchingHistory[i].mRequestedSize; - // We request the whole file if the size was not set. - requestedSize = llmax(0,requestedSize); - // We request the whole file if the size was set to an absurdly high value (meaning all file) - requestedSize = (requestedSize == 33554432 ? 0 : requestedSize); - - LLCore::HttpHandle handle = mFetcher->getHttpRequest().requestGetByteRange(mHttpPolicyClass, - texture_url, - 0, - requestedSize, - LLCore::HttpOptions::ptr_t(), - mHttpHeaders, - LLCore::HttpHandler::ptr_t(this, &NoOpDeletor)); - if (LLCORE_HTTP_HANDLE_INVALID != handle) - { - mHandleToFetchIndex[handle] = i; - mFetchingHistory[i].mHttpHandle = handle; - mFetchingHistory[i].mCurlState = FetchEntry::CURL_IN_PROGRESS; - mNbCurlRequests++; - if (mNbCurlRequests >= HTTP_NONPIPE_REQUESTS_HIGH_WATER) // emulate normal pipeline - { - break; - } - } - else - { - // Failed to queue request, log it and mark it done. - LLCore::HttpStatus status(mFetcher->getHttpRequest().getStatus()); - - LL_WARNS(LOG_TXT) << "Couldn't issue HTTP request in debugger for texture " - << mFetchingHistory[i].mID - << ", status: " << status.toTerseString() - << " reason: " << status.toString() - << LL_ENDL; - mFetchingHistory[i].mCurlState = FetchEntry::CURL_DONE; - } - } - //LL_INFOS(LOG_TXT) << "Fetch Debugger : Having " << mNbCurlRequests << " requests through the curl thread." << LL_ENDL; - return mNbCurlRequests; -} - -void LLTextureFetchDebugger::debugGLTextureCreation() -{ - llassert_always(mDebuggerState == IDLE); - setDebuggerState(GL_TEX); - mTempTexList.clear(); - - S32 size = mFetchingHistory.size(); - for(S32 i = 0 ; i < size ; i++) - { - if(mFetchingHistory[i].mRawImage.notNull()) - { - std::vector textures; - gTextureList.findTexturesByID(mFetchingHistory[i].mID, textures); - std::vector::iterator iter = textures.begin(); - while (iter != textures.end()) - { - LLViewerFetchedTexture* tex = *iter++; - if (tex && !tex->isForSculptOnly()) - { - tex->destroyGLTexture(); - mTempTexList.push_back(tex); - } - } - } - } - - mGLCreationTime = -1.f; - mTempIndex = 0; - mHistoryListIndex = 0; - - return; -} - -bool LLTextureFetchDebugger::processGLCreation(F32 max_time) -{ - mTimer.reset(); - - bool done = true; - S32 size = mFetchingHistory.size(); - S32 size1 = mTempTexList.size(); - for(; mHistoryListIndex < size && mTempIndex < size1; mHistoryListIndex++) - { - if(mFetchingHistory[mHistoryListIndex].mRawImage.notNull()) - { - if(mFetchingHistory[mHistoryListIndex].mID == mTempTexList[mTempIndex]->getID()) - { - mTempTexList[mTempIndex]->createGLTexture(mFetchingHistory[mHistoryListIndex].mDecodedLevel, - mFetchingHistory[mHistoryListIndex].mRawImage, 0, TRUE, mTempTexList[mTempIndex]->getBoostLevel()); - mTempIndex++; - } - } - - if(mTimer.getElapsedTimeF32() > max_time) - { - done = false; - break; - } - } - - if(mGLCreationTime < 0.f) - { - mGLCreationTime = mTimer.getElapsedTimeF32() ; - } - else - { - mGLCreationTime += mTimer.getElapsedTimeF32() ; - } - - return done; -} - -//clear fetching results of all textures. -void LLTextureFetchDebugger::clearTextures() -{ - S32 size = mFetchingHistory.size(); - for(S32 i = 0 ; i < size ; i++) - { - std::vector textures; - gTextureList.findTexturesByID(mFetchingHistory[i].mID, textures); - std::vector::iterator iter = textures.begin(); - while (iter != textures.end()) - { - LLViewerFetchedTexture* tex = *iter++; - if (tex) - { - tex->clearFetchedResults(); - } - } - } -} - -void LLTextureFetchDebugger::makeRefetchList() -{ - mRefetchList.clear(); - S32 size = mFetchingHistory.size(); - for(S32 i = 0 ; i < size; i++) - { - LLViewerFetchedTexture* tex = LLViewerTextureManager::getFetchedTexture(mFetchingHistory[i].mID); - if(tex && tex->isJustBound()) //visible - { - continue; //the texture fetch pipeline will take care of visible textures. - } - - // todo: Will attempt to refetch icons and ui elements as normal images (boost_none) - // thus will create unnecessary LLViewerFetchedTexture, consider supporting separate UI textures - mRefetchList[tex].push_back(i); - } -} - -void LLTextureFetchDebugger::scanRefetchList() -{ - if(mStopDebug) - { - return; - } - if(!mRefetchNonVis) - { - return; - } - - for(std::map< LLPointer, std::vector >::iterator iter = mRefetchList.begin(); - iter != mRefetchList.end(); ) - { - if(iter->second.empty()) - { - gTextureList.setDebugFetching(iter->first, -1); - mRefetchList.erase(iter++); // This is the correct method to "erase and move on" in an std::map - } - else - { - gTextureList.setDebugFetching(iter->first, mFetchingHistory[iter->second[0]].mDecodedLevel); - ++iter; - } - } -} - -void LLTextureFetchDebugger::debugRefetchVisibleFromCache() -{ - llassert_always(mDebuggerState == IDLE); - setDebuggerState(REFETCH_VIS_CACHE); - - clearTextures(); - mFetcher->setLoadSource(LLTextureFetch::FROM_ALL); - - mTimer.reset(); - mFetcher->lockFetcher(false); - mRefetchVisCacheTime = -1.f; - mRefetchedVisData = 0; - mRefetchedVisPixels = 0; -} - -void LLTextureFetchDebugger::debugRefetchVisibleFromHTTP() -{ - llassert_always(mDebuggerState == IDLE); - setDebuggerState(REFETCH_VIS_HTTP); - - clearTextures(); - mFetcher->setLoadSource(LLTextureFetch::FROM_HTTP_ONLY); - - mTimer.reset(); - mFetcher->lockFetcher(false); - mRefetchVisHTTPTime = -1.f; - mRefetchedVisData = 0; - mRefetchedVisPixels = 0; -} - -void LLTextureFetchDebugger::debugRefetchAllFromCache() -{ - llassert_always(mDebuggerState == IDLE); - setDebuggerState(REFETCH_ALL_CACHE); - - clearTextures(); - makeRefetchList(); - mFetcher->setLoadSource(LLTextureFetch::FROM_ALL); - - mTimer.reset(); - mFetcher->lockFetcher(false); - mRefetchAllCacheTime = -1.f; - mRefetchedAllData = 0; - mRefetchedAllPixels = 0; - mRefetchNonVis = FALSE; -} - -void LLTextureFetchDebugger::debugRefetchAllFromHTTP() -{ - llassert_always(mDebuggerState == IDLE); - setDebuggerState(REFETCH_ALL_HTTP); - - clearTextures(); - makeRefetchList(); - mFetcher->setLoadSource(LLTextureFetch::FROM_HTTP_ONLY); - - mTimer.reset(); - mFetcher->lockFetcher(false); - mRefetchAllHTTPTime = -1.f; - mRefetchedAllData = 0; - mRefetchedAllPixels = 0; - mRefetchNonVis = TRUE; -} - -bool LLTextureFetchDebugger::update(F32 max_time) -{ - switch(mDebuggerState) - { - case START_DEBUG: - if(processStartDebug(max_time)) - { - setDebuggerState(IDLE); - } - break; - case READ_CACHE: - if(!mTextureCache->update(1)) - { - mCacheReadTime = mTimer.getElapsedTimeF32() ; - setDebuggerState(IDLE); - unlockCache(); - } - break; - case WRITE_CACHE: - if(!mTextureCache->update(1)) - { - mCacheWriteTime = mTimer.getElapsedTimeF32() ; - setDebuggerState(IDLE); - unlockCache(); - } - break; - case DECODING: - if(!mImageDecodeThread->update(1)) - { - mDecodingTime = mTimer.getElapsedTimeF32() ; - setDebuggerState(IDLE); - unlockDecoder(); - } - break; - case HTTP_FETCHING: - // Do some notifications... - mFetcher->getHttpRequest().update(10); - if (!fillCurlQueue() && mNbCurlCompleted == mFetchingHistory.size()) - { - mHTTPTime = mTimer.getElapsedTimeF32() ; - setDebuggerState(IDLE); - } - break; - case GL_TEX: - if(processGLCreation(max_time)) - { - setDebuggerState(IDLE); - mTempTexList.clear(); - } - break; - case REFETCH_VIS_CACHE: - if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) - { - mRefetchVisCacheTime = mTimer.getElapsedTimeF32() ; - setDebuggerState(IDLE); - mFetcher->lockFetcher(true); - mFetcher->resetLoadSource(); - } - break; - case REFETCH_VIS_HTTP: - if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) - { - mRefetchVisHTTPTime = mTimer.getElapsedTimeF32() ; - setDebuggerState(IDLE); - mFetcher->lockFetcher(true); - mFetcher->resetLoadSource(); - } - break; - case REFETCH_ALL_CACHE: - scanRefetchList(); - if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) - { - if(!mRefetchNonVis) - { - mRefetchNonVis = TRUE; //start to fetch non-vis - scanRefetchList(); - break; - } - - mRefetchAllCacheTime = mTimer.getElapsedTimeF32() ; - setDebuggerState(IDLE); - mFetcher->lockFetcher(true); - mFetcher->resetLoadSource(); - mRefetchList.clear(); - mRefetchNonVis = FALSE; - } - break; - case REFETCH_ALL_HTTP: - scanRefetchList(); - if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) - { - mRefetchAllHTTPTime = mTimer.getElapsedTimeF32() ; - setDebuggerState(IDLE); - mFetcher->lockFetcher(true); - mFetcher->resetLoadSource(); - mRefetchList.clear(); - mRefetchNonVis = FALSE; - } - break; - default: - setDebuggerState(IDLE); - break; - } - - return mDebuggerState == IDLE; -} - -void LLTextureFetchDebugger::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response) -{ - handle_fetch_map_t::iterator iter(mHandleToFetchIndex.find(handle)); - if (mHandleToFetchIndex.end() == iter) - { - LL_INFOS(LOG_TXT) << "Fetch Debugger : Couldn't find handle " << handle << " in fetch list." << LL_ENDL; - return; - } - - S32 fetch_ind(iter->second); - mHandleToFetchIndex.erase(iter); - if (fetch_ind >= mFetchingHistory.size() || mFetchingHistory[fetch_ind].mHttpHandle != handle) - { - LL_INFOS(LOG_TXT) << "Fetch Debugger : Handle and fetch object in disagreement. Punting." << LL_ENDL; - } - else - { - callbackHTTP(mFetchingHistory[fetch_ind], response); - mFetchingHistory[fetch_ind].mHttpHandle = LLCORE_HTTP_HANDLE_INVALID; // Not valid after notification - } -} - -void LLTextureFetchDebugger::callbackCacheRead(S32 id, bool success, LLImageFormatted* image, - S32 imagesize, BOOL islocal) -{ - if (success) - { - mFetchingHistory[id].mFormattedImage = image; - } - mTextureCache->readComplete(mFetchingHistory[id].mCacheHandle, false); - mFetchingHistory[id].mCacheHandle = LLTextureCache::nullHandle(); -} - -void LLTextureFetchDebugger::callbackCacheWrite(S32 id, bool success) -{ - mTextureCache->writeComplete(mFetchingHistory[id].mCacheHandle); - mFetchingHistory[id].mCacheHandle = LLTextureCache::nullHandle(); -} - -void LLTextureFetchDebugger::callbackDecoded(S32 id, bool success, LLImageRaw* raw, LLImageRaw* aux) -{ - if (success) - { - llassert_always(raw); - mFetchingHistory[id].mRawImage = raw; - } -} - -void LLTextureFetchDebugger::callbackHTTP(FetchEntry & fetch, LLCore::HttpResponse * response) -{ - static const LLCore::HttpStatus par_status(HTTP_PARTIAL_CONTENT); - - LLCore::HttpStatus status(response->getStatus()); - mNbCurlRequests--; - mNbCurlCompleted++; - fetch.mCurlState = FetchEntry::CURL_DONE; - if (status) - { - const bool partial(par_status == status); - LLCore::BufferArray * ba(response->getBody()); // *Not* holding reference to body - - S32 data_size = ba ? ba->size() : 0; - fetch.mCurlReceivedSize += data_size; - //LL_INFOS(LOG_TXT) << "Fetch Debugger : got results for " << fetch.mID << ", data_size = " << data_size << ", received = " << fetch.mCurlReceivedSize << ", requested = " << fetch.mRequestedSize << ", partial = " << partial << LL_ENDL; - if ((fetch.mCurlReceivedSize >= fetch.mRequestedSize) || !partial || (fetch.mRequestedSize == 600)) - { - U8* d_buffer = (U8*)ll_aligned_malloc_16(data_size); - if (ba) - { - ba->read(0, d_buffer, data_size); - } - - llassert_always(fetch.mFormattedImage.isNull()); - { - // For now, create formatted image based on extension - std::string texture_url = mHTTPUrl + "/?texture_id=" + fetch.mID.asString().c_str(); - std::string extension = gDirUtilp->getExtension(texture_url); - fetch.mFormattedImage = LLImageFormatted::createFromType(LLImageBase::getCodecFromExtension(extension)); - if (fetch.mFormattedImage.isNull()) - { - fetch.mFormattedImage = new LLImageJ2C; // default - } - } - - fetch.mFormattedImage->setData(d_buffer, data_size); - } - } - else //failed - { - LL_INFOS(LOG_TXT) << "Fetch Debugger : CURL GET FAILED, ID = " << fetch.mID - << ", status: " << status.toTerseString() - << " reason: " << status.toString() << LL_ENDL; - } -} - - -//--------------------- -/////////////////////////////////////////////////////////////////////////////////////////// -//End LLTextureFetchDebugger -/////////////////////////////////////////////////////////////////////////////////////////// - LLTextureFetchTester::LLTextureFetchTester() : LLMetricPerformanceTesterBasic(sTesterName) { mTextureFetchTime = 0; diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index ff6bb8b505..320511f343 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -48,7 +48,6 @@ class LLTextureFetchWorker; class LLImageDecodeThread; class LLHost; class LLViewerAssetStats; -class LLTextureFetchDebugger; class LLTextureCache; class LLTextureFetchTester; @@ -412,10 +411,6 @@ public: static LLTextureFetchTester* sTesterp; private: - //debug use - LLTextureFetchDebugger* mFetchDebugger; - bool mFetcherLocked; - e_tex_source mFetchSource; e_tex_source mOriginFetchSource; @@ -423,10 +418,6 @@ private: //LLAdaptiveRetryPolicy mFetchRetryPolicy; public: - //debug use - LLTextureFetchDebugger* getFetchDebugger() { return mFetchDebugger;} - void lockFetcher(bool lock) { mFetcherLocked = lock;} - void setLoadSource(e_tex_source source) {mFetchSource = source;} void resetLoadSource() {mFetchSource = mOriginFetchSource;} bool canLoadFromCache() { return mFetchSource != FROM_HTTP_ONLY;} @@ -434,216 +425,6 @@ public: //debug use class LLViewerFetchedTexture; -class LLTextureFetchDebugger : public LLCore::HttpHandler -{ - friend class LLTextureFetch; -public: - LLTextureFetchDebugger(LLTextureFetch* fetcher, LLTextureCache* cache, LLImageDecodeThread* imagedecodethread) ; - ~LLTextureFetchDebugger(); - -public: - enum e_debug_state - { - IDLE = 0, - START_DEBUG, - READ_CACHE, - WRITE_CACHE, - DECODING, - HTTP_FETCHING, - GL_TEX, - REFETCH_VIS_CACHE, - REFETCH_VIS_HTTP, - REFETCH_ALL_CACHE, - REFETCH_ALL_HTTP, - INVALID - }; - -private: - struct FetchEntry - { - enum e_curl_state - { - CURL_NOT_DONE = 0, - CURL_IN_PROGRESS, - CURL_DONE - }; - LLUUID mID; - S32 mRequestedSize; - S32 mDecodedLevel; - S32 mFetchedSize; - S32 mDecodedSize; - BOOL mNeedsAux; - U32 mCacheHandle; - LLPointer mFormattedImage; - LLPointer mRawImage; - e_curl_state mCurlState; - S32 mCurlReceivedSize; - LLCore::HttpHandle mHttpHandle; - - FetchEntry() : - mDecodedLevel(-1), - mFetchedSize(0), - mDecodedSize(0), - mHttpHandle(LLCORE_HTTP_HANDLE_INVALID) - {} - FetchEntry(LLUUID& id, S32 r_size, /*S32 f_discard, S32 c,*/ S32 level, S32 f_size, S32 d_size) : - mID(id), - mRequestedSize(r_size), - mDecodedLevel(level), - mFetchedSize(f_size), - mDecodedSize(d_size), - mNeedsAux(false), - mHttpHandle(LLCORE_HTTP_HANDLE_INVALID) - {} - }; - typedef std::vector fetch_list_t; - fetch_list_t mFetchingHistory; - - typedef std::map handle_fetch_map_t; - handle_fetch_map_t mHandleToFetchIndex; - - void setDebuggerState(e_debug_state new_state) { mDebuggerState = new_state; } - e_debug_state mDebuggerState; - - F32 mCacheReadTime; - F32 mCacheWriteTime; - F32 mDecodingTime; - F32 mHTTPTime; - F32 mGLCreationTime; - - F32 mTotalFetchingTime; - F32 mRefetchVisCacheTime; - F32 mRefetchVisHTTPTime; - F32 mRefetchAllCacheTime; - F32 mRefetchAllHTTPTime; - - LLTimer mTimer; - - LLTextureFetch* mFetcher; - LLTextureCache* mTextureCache; - LLImageDecodeThread* mImageDecodeThread; - LLCore::HttpHeaders::ptr_t mHttpHeaders; - LLCore::HttpRequest::policy_t mHttpPolicyClass; - - S32 mNumFetchedTextures; - S32 mNumCacheHits; - S32 mNumVisibleFetchedTextures; - S32 mNumVisibleFetchingRequests; - U32 mFetchedData; - U32 mDecodedData; - U32 mVisibleFetchedData; - U32 mVisibleDecodedData; - U32 mRenderedData; - U32 mRenderedDecodedData; - U32 mFetchedPixels; - U32 mRenderedPixels; - U32 mRefetchedVisData; - U32 mRefetchedVisPixels; - U32 mRefetchedAllData; - U32 mRefetchedAllPixels; - - BOOL mFreezeHistory; - BOOL mStopDebug; - BOOL mClearHistory; - BOOL mRefetchNonVis; - - std::string mHTTPUrl; - S32 mNbCurlRequests; - S32 mNbCurlCompleted; - - std::map< LLPointer, std::vector > mRefetchList; // treats UI textures as normal textures - std::vector< LLPointer > mTempTexList; - S32 mTempIndex; - S32 mHistoryListIndex; - -public: - bool update(F32 max_time); //called in the main thread once per frame - - //fetching history - void clearHistory(); - void addHistoryEntry(LLTextureFetchWorker* worker); - - // Inherited from LLCore::HttpHandler - // Threads: Ttf - virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response); - - void startWork(e_debug_state state); - void setStopDebug() {mStopDebug = TRUE;} - void tryToStopDebug(); //stop everything - void callbackCacheRead(S32 id, bool success, LLImageFormatted* image, - S32 imagesize, BOOL islocal); - void callbackCacheWrite(S32 id, bool success); - void callbackDecoded(S32 id, bool success, LLImageRaw* raw, LLImageRaw* aux); - void callbackHTTP(FetchEntry & fetch, LLCore::HttpResponse * response); - - e_debug_state getState() {return mDebuggerState;} - S32 getNumFetchedTextures() {return mNumFetchedTextures;} - S32 getNumFetchingRequests() {return mFetchingHistory.size();} - S32 getNumCacheHits() {return mNumCacheHits;} - S32 getNumVisibleFetchedTextures() {return mNumVisibleFetchedTextures;} - S32 getNumVisibleFetchingRequests() {return mNumVisibleFetchingRequests;} - U32 getFetchedData() {return mFetchedData;} - U32 getDecodedData() {return mDecodedData;} - U32 getVisibleFetchedData() {return mVisibleFetchedData;} - U32 getVisibleDecodedData() {return mVisibleDecodedData;} - U32 getRenderedData() {return mRenderedData;} - U32 getRenderedDecodedData() {return mRenderedDecodedData;} - U32 getFetchedPixels() {return mFetchedPixels;} - U32 getRenderedPixels() {return mRenderedPixels;} - U32 getRefetchedVisData() {return mRefetchedVisData;} - U32 getRefetchedVisPixels() {return mRefetchedVisPixels;} - U32 getRefetchedAllData() {return mRefetchedAllData;} - U32 getRefetchedAllPixels() {return mRefetchedAllPixels;} - - F32 getCacheReadTime() {return mCacheReadTime;} - F32 getCacheWriteTime() {return mCacheWriteTime;} - F32 getDecodeTime() {return mDecodingTime;} - F32 getGLCreationTime() {return mGLCreationTime;} - F32 getHTTPTime() {return mHTTPTime;} - F32 getTotalFetchingTime() {return mTotalFetchingTime;} - F32 getRefetchVisCacheTime() {return mRefetchVisCacheTime;} - F32 getRefetchVisHTTPTime() {return mRefetchVisHTTPTime;} - F32 getRefetchAllCacheTime() {return mRefetchAllCacheTime;} - F32 getRefetchAllHTTPTime() {return mRefetchAllHTTPTime;} - -private: - void init(); - void clearTextures();//clear fetching results of all textures. - void clearCache(); - void makeRefetchList(); - void scanRefetchList(); - - void lockFetcher(); - void unlockFetcher(); - - void lockCache(); - void unlockCache(); - - void lockDecoder(); - void unlockDecoder(); - - S32 fillCurlQueue(); - - void startDebug(); - void debugCacheRead(); - void debugCacheWrite(); - void debugHTTP(); - void debugDecoder(); - void debugGLTextureCreation(); - void debugRefetchVisibleFromCache(); - void debugRefetchVisibleFromHTTP(); - void debugRefetchAllFromCache(); - void debugRefetchAllFromHTTP(); - - bool processStartDebug(F32 max_time); - bool processGLCreation(F32 max_time); - -private: - static bool sDebuggerEnabled; -public: - static bool isEnabled() {return sDebuggerEnabled;} -}; - class LLTextureFetchTester : public LLMetricPerformanceTesterBasic { diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index dd03d6cfdd..5a3a358173 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -132,7 +132,6 @@ #include "llfloatertelehub.h" #include "llfloatertestinspectors.h" #include "llfloatertestlistview.h" -#include "llfloatertexturefetchdebugger.h" #include "llfloatertools.h" #include "llfloatertopobjects.h" #include "llfloatertos.h" @@ -283,10 +282,6 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("mem_leaking", "floater_mem_leaking.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - if(gSavedSettings.getBOOL("TextureFetchDebuggerEnabled")) - { - LLFloaterReg::add("tex_fetch_debugger", "floater_texture_fetch_debugger.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - } LLFloaterReg::add("media_settings", "floater_media_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("marketplace_listings", "floater_marketplace_listings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("marketplace_validation", "floater_marketplace_validation.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index e3de4267dc..d95948ac04 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -2519,14 +2519,6 @@ class LLDevelopSetLoggingLevel : public view_listener_t } }; -class LLDevelopTextureFetchDebugger : public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - return gSavedSettings.getBOOL("TextureFetchDebuggerEnabled"); - } -}; - ////////////////// // ADMIN MENU // ////////////////// @@ -9398,8 +9390,6 @@ void initialize_menus() view_listener_t::addMenu(new LLDevelopCheckLoggingLevel(), "Develop.CheckLoggingLevel"); view_listener_t::addMenu(new LLDevelopSetLoggingLevel(), "Develop.SetLoggingLevel"); - //Develop (Texture Fetch Debug Console) - view_listener_t::addMenu(new LLDevelopTextureFetchDebugger(), "Develop.SetTexFetchDebugger"); //Develop (clear cache immediately) commit.add("Develop.ClearCache", boost::bind(&handle_cache_clear_immediately) ); diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 71526e5e8c..57d52ae9ee 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -316,8 +316,6 @@ U32Bytes gTotalTextureBytesPerBoostLevel[LLViewerTexture::MAX_GL_IMAGE_CATEGOR extern U32 gVisCompared; extern U32 gVisTested; -LLFrameTimer gTextureTimer; - void update_statistics() { gTotalWorldData += gVLManager.getTotalBytes(); @@ -413,19 +411,6 @@ void update_statistics() } } -void update_texture_time() -{ - if (gTextureList.isPrioRequestsFetched()) - { - gTextureTimer.pause(); - } - else - { - gTextureTimer.unpause(); - } - - record(LLStatViewer::TEXTURE_FETCH_TIME, gTextureTimer.getElapsedTimeF32()); -} /* * The sim-side LLSD is in newsim/llagentinfo.cpp:forwardViewerStats. * diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h index 8d1182d054..c21c06256e 100644 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h @@ -294,7 +294,6 @@ void update_statistics(); void send_viewer_stats(bool include_preferences); void update_texture_time(); -extern LLFrameTimer gTextureTimer; extern U32Bytes gTotalTextureData; extern U32Bytes gTotalObjectData; extern U32Bytes gTotalTextureBytesPerBoostLevel[] ; diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index b8de5d34eb..0544bceb9f 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -463,11 +463,6 @@ void LLViewerTextureManager::cleanup() void LLViewerTexture::initClass() { LLImageGL::sDefaultGLTexture = LLViewerFetchedTexture::sDefaultImagep->getGLTexture(); - - if(gSavedSettings.getBOOL("TextureFetchDebuggerEnabled")) - { - sTexelPixelRatio = gSavedSettings.getF32("TexelPixelRatio"); - } } // tuning params @@ -4014,7 +4009,6 @@ void LLTexturePipelineTester::compareTestSessions(llofstream* os) *os << llformat("%s\n", getTesterName().c_str()); *os << llformat("AggregateResults\n"); - compareTestResults(os, "TotalFetchingTime", base_sessionp->mTotalFetchingTime, current_sessionp->mTotalFetchingTime); compareTestResults(os, "TotalGrayTime", base_sessionp->mTotalGrayTime, current_sessionp->mTotalGrayTime); compareTestResults(os, "TotalStablizingTime", base_sessionp->mTotalStablizingTime, current_sessionp->mTotalStablizingTime); compareTestResults(os, "StartTimeLoadingSculpties", base_sessionp->mStartTimeLoadingSculpties, current_sessionp->mStartTimeLoadingSculpties); @@ -4074,7 +4068,6 @@ LLMetricPerformanceTesterWithSession::LLTestSession* LLTexturePipelineTester::lo return NULL; } - F32 total_fetching_time = 0.f; F32 total_gray_time = 0.f; F32 total_stablizing_time = 0.f; F32 total_loading_sculpties_time = 0.f; @@ -4109,7 +4102,6 @@ LLMetricPerformanceTesterWithSession::LLTestSession* LLTexturePipelineTester::lo F32 cur_time = (*log)[label]["Time"].asReal(); if(start_time - start_fetching_time > F_ALMOST_ZERO) //fetching has paused for a while { - sessionp->mTotalFetchingTime += total_fetching_time; sessionp->mTotalGrayTime += total_gray_time; sessionp->mTotalStablizingTime += total_stablizing_time; @@ -4117,14 +4109,12 @@ LLMetricPerformanceTesterWithSession::LLTestSession* LLTexturePipelineTester::lo sessionp->mTotalTimeLoadingSculpties += total_loading_sculpties_time; start_fetching_time = start_time; - total_fetching_time = 0.0f; total_gray_time = 0.f; total_stablizing_time = 0.f; total_loading_sculpties_time = 0.f; } else { - total_fetching_time = cur_time - start_time; total_gray_time = (*log)[label]["TotalGrayTime"].asReal(); total_stablizing_time = (*log)[label]["TotalStablizingTime"].asReal(); @@ -4170,7 +4160,6 @@ LLMetricPerformanceTesterWithSession::LLTestSession* LLTexturePipelineTester::lo in_log = (*log).has(currentLabel); } - sessionp->mTotalFetchingTime += total_fetching_time; sessionp->mTotalGrayTime += total_gray_time; sessionp->mTotalStablizingTime += total_stablizing_time; @@ -4192,8 +4181,6 @@ LLTexturePipelineTester::LLTextureTestSession::~LLTextureTestSession() } void LLTexturePipelineTester::LLTextureTestSession::reset() { - mTotalFetchingTime = 0.0f; - mTotalGrayTime = 0.0f; mTotalStablizingTime = 0.0f; diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index 49d030bcb8..a5e5c37c22 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -763,7 +763,6 @@ private: void reset() ; - F32 mTotalFetchingTime ; F32 mTotalGrayTime ; F32 mTotalStablizingTime ; F32 mStartTimeLoadingSculpties ; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 71a5de1176..555355059a 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -196,10 +196,8 @@ static std::string get_texture_list_name() void LLViewerTextureList::doPrefetchImages() { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - gTextureTimer.start(); - gTextureTimer.pause(); - if (LLAppViewer::instance()->getPurgeCache()) + if (LLAppViewer::instance()->getPurgeCache()) { // cache was purged, no point return; @@ -784,8 +782,6 @@ void LLViewerTextureList::updateImages(F32 max_time) //loading from fast cache max_time -= updateImagesLoadingFastCache(max_time); - updateImagesDecodePriorities(); - F32 total_max_time = max_time; max_time -= updateImagesFetchTextures(max_time); @@ -838,32 +834,6 @@ void LLViewerTextureList::clearFetchingRequests() } } -void LLViewerTextureList::updateImagesDecodePriorities() -{ -#if 0 - LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - // Update the decode priority for N images each frame - - /*static const S32 MAX_PRIO_UPDATES = gSavedSettings.getS32("TextureFetchUpdatePriorities"); // default: 32 - const size_t max_update_count = llmin((S32) (MAX_PRIO_UPDATES*MAX_PRIO_UPDATES*gFrameIntervalSeconds.value()) + 1, MAX_PRIO_UPDATES); - S32 update_counter = llmin(max_update_count, mUUIDMap.size()); - uuid_map_t::iterator iter = mUUIDMap.upper_bound(mLastUpdateKey);*/ - //while ((update_counter-- > 0) && !mUUIDMap.empty()) - for (uuid_map_t::iterator iter = mUUIDMap.begin(); iter != mUUIDMap.end(); ++iter) - { - /*if (iter == mUUIDMap.end()) - { - iter = mUUIDMap.begin(); - }*/ - mLastUpdateKey = iter->first; - LLPointer imagep = iter->second; - //++iter; // safe to increment now - - updateImageDecodePriority(imagep); - } -#endif -} - void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imagep) { if (imagep->isInDebug() || imagep->isUnremovable()) @@ -1058,102 +1028,29 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) typedef std::vector entries_list_t; entries_list_t entries; - // Update fetch for N images each frame -#if 0 - static const S32 MAX_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMaxMediumPriority"); // default: 256 - - static const F32 MIN_PRIORITY_THRESHOLD = gSavedSettings.getF32("TextureFetchUpdatePriorityThreshold"); // default: 0.0 - static const bool SKIP_LOW_PRIO = gSavedSettings.getBOOL("TextureFetchUpdateSkipLowPriority"); // default: false - - size_t max_priority_count = llmin((S32) (MAX_HIGH_PRIO_COUNT*MAX_HIGH_PRIO_COUNT*gFrameIntervalSeconds.value())+1, MAX_HIGH_PRIO_COUNT); - max_priority_count = llmin(max_priority_count, mImageList.size()); - - size_t total_update_count = mUUIDMap.size(); - size_t max_update_count = llmin((S32) (MAX_UPDATE_COUNT*MAX_UPDATE_COUNT*gFrameIntervalSeconds.value())+1, MAX_UPDATE_COUNT); - max_update_count = llmin(max_update_count, total_update_count); - - // MAX_HIGH_PRIO_COUNT high priority entries - - //size_t update_counter = max_priority_count; - size_t update_counter = mImageList.size(); - image_priority_list_t::iterator iter1 = mImageList.begin(); - while(update_counter > 0) - { - entries.push_back(*iter1); - - ++iter1; - update_counter--; - } - - // MAX_UPDATE_COUNT cycled entries - update_counter = max_update_count; - if(update_counter > 0) - { - uuid_map_t::iterator iter2 = mUUIDMap.upper_bound(mLastFetchKey); - while ((update_counter > 0) && (total_update_count > 0)) - { - if (iter2 == mUUIDMap.end()) - { - iter2 = mUUIDMap.begin(); - } - LLViewerFetchedTexture* imagep = iter2->second; - // Skip the textures where there's really nothing to do so to give some times to others. Also skip the texture if it's already in the high prio set. - if (!SKIP_LOW_PRIO || (SKIP_LOW_PRIO && ((imagep->getDecodePriority() > MIN_PRIORITY_THRESHOLD) || imagep->hasFetcher()))) - { - entries.push_back(imagep); - update_counter--; - } - - iter2++; - total_update_count--; - } - } - - S32 fetch_count = 0; - //size_t min_update_count = llmin(MIN_UPDATE_COUNT,(S32)(entries.size()-max_priority_count)); - //S32 min_count = max_priority_count + min_update_count; - for (entries_list_t::iterator iter3 = entries.begin(); - iter3 != entries.end(); ) - { - LLViewerFetchedTexture* imagep = *iter3++; - updateImageDecodePriority(imagep); - fetch_count += (imagep->updateFetch() ? 1 : 0); - //if (min_count <= min_update_count) - { - mLastFetchKey = LLTextureKey(imagep->getID(), (ETexListType)imagep->getTextureListType()); - } - /*if ((min_count-- <= 0) && (image_op_timer.getElapsedTimeF32() > max_time)) - { - break; - }*/ - } -#else - // update N textures at beginning of mImageList U32 update_count = 0; - - /*for (auto& imagep : mImageList) - { - if (update_count++ > MAX_HIGH_PRIO_COUNT) - { - break; - } - - entries.push_back(imagep); - }*/ - + static const S32 MIN_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMinCount"); // default: 32 // WIP -- dumb code here //update MIN_UPDATE_COUNT or 10% of other textures, whichever is greater - //update_count = llmax((U32) MIN_UPDATE_COUNT, (U32) mUUIDMap.size()/10); - //update_count = llmin(update_count, (U32) mUUIDMap.size()); - update_count -= mUUIDMap.size(); - - entries.reserve(update_count); - //uuid_map_t::iterator iter2 = mUUIDMap.upper_bound(mLastFetchKey); - //while (update_count-- > 0) - for (auto iter2 = mUUIDMap.begin(); iter2 != mUUIDMap.end(); ++iter2) + update_count = llmax((U32) MIN_UPDATE_COUNT, (U32) mUUIDMap.size()/10); + update_count = llmin(update_count, (U32) mUUIDMap.size()); + { - entries.push_back(iter2->second); + LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vtluift - copy"); + + // copy entries out of UUID map for updating + entries.reserve(update_count); + uuid_map_t::iterator iter = mUUIDMap.upper_bound(mLastUpdateKey); + while (update_count-- > 0) + { + if (iter == mUUIDMap.end()) + { + iter = mUUIDMap.begin(); + } + entries.push_back(iter->second); + ++iter; + } } for (auto* imagep : entries) @@ -1165,10 +1062,9 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) if (entries.size() > 0) { LLViewerFetchedTexture* imagep = *entries.rbegin(); - mLastFetchKey = LLTextureKey(imagep->getID(), (ETexListType)imagep->getTextureListType()); + mLastUpdateKey = LLTextureKey(imagep->getID(), (ETexListType)imagep->getTextureListType()); } -#endif return image_op_timer.getElapsedTimeF32(); } @@ -1350,33 +1246,6 @@ LLPointer LLViewerTextureList::convertToUploadFile(LLPointer prio_threshold(gSavedSettings, "TextureFetchUpdatePriorityThreshold", 0.0f); - static LLCachedControl fetching_textures_threshold(gSavedSettings, "TextureListFetchingThreshold", 0.97f); - S32 fetching_tex_count = 0; - S32 tex_count_threshold = gTextureList.mImageList.size() * (1 - fetching_textures_threshold); - - for (LLViewerTextureList::image_priority_list_t::iterator iter = gTextureList.mImageList.begin(); - iter != gTextureList.mImageList.end(); ) - { - LLPointer imagep = *iter++; - if (imagep->getMaxVirtualSize() > prio_threshold) - { - if (imagep->hasFetcher() || imagep->isFetching()) - { - fetching_tex_count++; - if (fetching_tex_count >= tex_count_threshold) - { - return false; - } - } - } - } - - return true; -} - /////////////////////////////////////////////////////////////////////////////// // static diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index 8d70add792..bd60c990b5 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -132,11 +132,7 @@ public: void clearFetchingRequests(); void setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level); - static bool isPrioRequestsFetched(); - private: - void updateImagesDecodePriorities(); - // do some book keeping on the specified texture // - updates decode priority // - updates desired discard level @@ -214,7 +210,6 @@ private: typedef std::map< LLTextureKey, LLPointer > uuid_map_t; uuid_map_t mUUIDMap; LLTextureKey mLastUpdateKey; - LLTextureKey mLastFetchKey; typedef std::set < LLPointer > image_priority_list_t; image_priority_list_t mImageList; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 65010f1985..e27b5caab7 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -493,24 +493,12 @@ public: if (gSavedSettings.getBOOL("DebugShowTime")) { - { - const U32 y_inc2 = 15; - LLFrameTimer& timer = gTextureTimer; - F32 time = timer.getElapsedTimeF32(); - S32 hours = (S32)(time / (60*60)); - S32 mins = (S32)((time - hours*(60*60)) / 60); - S32 secs = (S32)((time - hours*(60*60) - mins*60)); - addText(xpos, ypos, llformat("Texture: %d:%02d:%02d", hours,mins,secs)); ypos += y_inc2; - } - - { F32 time = gFrameTimeSeconds; S32 hours = (S32)(time / (60*60)); S32 mins = (S32)((time - hours*(60*60)) / 60); S32 secs = (S32)((time - hours*(60*60) - mins*60)); addText(xpos, ypos, llformat("Time: %d:%02d:%02d", hours,mins,secs)); ypos += y_inc; } - } if (gSavedSettings.getBOOL("DebugShowMemory")) { diff --git a/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml deleted file mode 100644 index 9278a1a598..0000000000 --- a/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml +++ /dev/null @@ -1,440 +0,0 @@ - - - - 1, Total number of fetched textures: [NUM] - - - 2, Total number of fetching requests: [NUM] - - - 3, Total number of cache hits: [NUM] - - - 4, Total number of visible textures: [NUM] - - - 5, Total number of visible texture fetching requests: [NUM] - - - 6, Total number of fetched data: [SIZE1]KB, Decoded Data: [SIZE2]KB, [PIXEL]MPixels - - - 7, Total number of visible data: [SIZE1]KB, Decoded Data: [SIZE2]KB - - - 8, Total number of rendered data: [SIZE1]KB, Decoded Data: [SIZE2]KB, [PIXEL]MPixels - - - 9, Total time on cache readings: [TIME] seconds - - - 10, Total time on cache writings: [TIME] seconds - - - 11, Total time on decodings: [TIME] seconds - - - 12, Total time on gl texture creation: [TIME] seconds - - - 13, Total time on HTTP fetching: [TIME] seconds - - - 14, Total time on entire fetching: [TIME] seconds - - - 15, Refetching visibles from cache, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels - - - 16, Refetching all textures from cache, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels - - - 17, Refetching visibles from HTTP, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels - - - 18, Refetching all textures from HTTP, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels - - - - - - 20, Texture Source: - - - - - - - - - - - - - - - - - - - diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 8d7cfe1116..85c20268d0 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -2438,20 +2438,6 @@ function="World.EnvPreset" function="Advanced.ToggleConsole" parameter="scene monitor" /> - - - - - - Date: Tue, 31 May 2022 16:54:05 -0500 Subject: SL-17484 Fix for unit tests. Deprecate non-threaded LLQueuedThread and make lllfsthread threaded. --- indra/llcommon/llqueuedthread.cpp | 23 +++++++++++-------- indra/llcommon/lltimer.cpp | 7 +++++- indra/llfilesystem/lllfsthread.cpp | 4 ++-- indra/llimage/llimageworker.cpp | 8 ------- indra/llimage/llimageworker.h | 3 --- indra/llimage/tests/llimageworker_test.cpp | 25 --------------------- .../llmessage/tests/llcoproceduremanager_test.cpp | 2 +- indra/newview/llappviewer.cpp | 26 +++++++++++++--------- 8 files changed, 38 insertions(+), 60 deletions(-) diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp index 871c42f7ee..60304fff75 100644 --- a/indra/llcommon/llqueuedthread.cpp +++ b/indra/llcommon/llqueuedthread.cpp @@ -37,12 +37,13 @@ // MAIN THREAD LLQueuedThread::LLQueuedThread(const std::string& name, bool threaded, bool should_pause) : LLThread(name), - mThreaded(threaded), mIdleThread(TRUE), mNextHandle(0), mStarted(FALSE), + mThreaded(threaded), mRequestQueue(name, 1024 * 1024) { + llassert(threaded); // not threaded implementation is deprecated mMainQueue = LL::WorkQueue::getInstance("mainloop"); if (mThreaded) @@ -138,14 +139,18 @@ S32 LLQueuedThread::updateQueue(F32 max_time_ms) if (mThreaded) { // schedule a call to threadedUpdate for every call to updateQueue - mRequestQueue.post([=]() - { - LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("qt - update"); - mIdleThread = FALSE; - threadedUpdate(); - mIdleThread = TRUE; - } - ); + if (!isQuitting()) + { + mRequestQueue.post([=]() + { + LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("qt - update"); + mIdleThread = FALSE; + threadedUpdate(); + mIdleThread = TRUE; + } + ); + } + if(getPending() > 0) { unpause(); diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp index 466f98f9b2..39dfee3755 100644 --- a/indra/llcommon/lltimer.cpp +++ b/indra/llcommon/lltimer.cpp @@ -68,7 +68,12 @@ LLTimer* LLTimer::sTimer = NULL; void ms_sleep(U32 ms) { LL_PROFILE_ZONE_SCOPED; - std::this_thread::sleep_for(std::chrono::microseconds(ms)); + using TimePoint = std::chrono::steady_clock::time_point; + auto resume_time = TimePoint::clock::now() + std::chrono::milliseconds(ms); + while (TimePoint::clock::now() < resume_time) + { + std::this_thread::yield(); //note: don't use LLThread::yield here to avoid yielding for too long + } } U32 micro_sleep(U64 us, U32 max_yields) diff --git a/indra/llfilesystem/lllfsthread.cpp b/indra/llfilesystem/lllfsthread.cpp index 944e981ecf..dbb69cd605 100644 --- a/indra/llfilesystem/lllfsthread.cpp +++ b/indra/llfilesystem/lllfsthread.cpp @@ -45,8 +45,7 @@ void LLLFSThread::initClass(bool local_is_threaded) //static S32 LLLFSThread::updateClass(U32 ms_elapsed) { - sLocal->update((F32)ms_elapsed); - return sLocal->getPending(); + return sLocal->update((F32)ms_elapsed); } //static @@ -58,6 +57,7 @@ void LLLFSThread::cleanupClass() { sLocal->update(0); } + sLocal->shutdown(); delete sLocal; sLocal = NULL; } diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp index 1aace5f3e8..d8503396d7 100644 --- a/indra/llimage/llimageworker.cpp +++ b/indra/llimage/llimageworker.cpp @@ -68,14 +68,6 @@ LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* return handle; } -// Used by unit test only -// Returns the size of the mutex guarded list as an indication of sanity -S32 LLImageDecodeThread::tut_size() -{ - LLMutexLock lock(mCreationMutex); - return 0; -} - LLImageDecodeThread::Responder::~Responder() { } diff --git a/indra/llimage/llimageworker.h b/indra/llimage/llimageworker.h index 4619ddd6a2..e0a94d2841 100644 --- a/indra/llimage/llimageworker.h +++ b/indra/llimage/llimageworker.h @@ -80,9 +80,6 @@ public: Responder* responder); S32 update(F32 max_time_ms); - // Used by unit tests to check the consistency of the thread instance - S32 tut_size(); - private: struct creation_info { diff --git a/indra/llimage/tests/llimageworker_test.cpp b/indra/llimage/tests/llimageworker_test.cpp index 462dde9fb8..57d922b1a1 100644 --- a/indra/llimage/tests/llimageworker_test.cpp +++ b/indra/llimage/tests/llimageworker_test.cpp @@ -190,35 +190,10 @@ namespace tut template<> template<> void imagedecodethread_object_t::test<1>() - { - // Test a *non threaded* instance of the class - mThread = new LLImageDecodeThread(false); - ensure("LLImageDecodeThread: non threaded constructor failed", mThread != NULL); - // Test that we start with an empty list right at creation - ensure("LLImageDecodeThread: non threaded init state incorrect", mThread->tut_size() == 0); - // Insert something in the queue - bool done = false; - LLImageDecodeThread::handle_t decodeHandle = mThread->decodeImage(NULL, 0, FALSE, new responder_test(&done)); - // Verifies we got a valid handle - ensure("LLImageDecodeThread: non threaded decodeImage(), returned handle is null", decodeHandle != 0); - // Verifies that we do now have something in the queued list - ensure("LLImageDecodeThread: non threaded decodeImage() insertion in threaded list failed", mThread->tut_size() == 1); - // Trigger queue handling "manually" (on a threaded instance, this is done on the thread loop) - S32 res = mThread->update(0); - // Verifies that we successfully handled the list - ensure("LLImageDecodeThread: non threaded update() list handling test failed", res == 0); - // Verifies that the list is now empty - ensure("LLImageDecodeThread: non threaded update() list emptying test failed", mThread->tut_size() == 0); - } - - template<> template<> - void imagedecodethread_object_t::test<2>() { // Test a *threaded* instance of the class mThread = new LLImageDecodeThread(true); ensure("LLImageDecodeThread: threaded constructor failed", mThread != NULL); - // Test that we start with an empty list right at creation - ensure("LLImageDecodeThread: threaded init state incorrect", mThread->tut_size() == 0); // Insert something in the queue bool done = false; LLImageDecodeThread::handle_t decodeHandle = mThread->decodeImage(NULL, 0, FALSE, new responder_test(&done)); diff --git a/indra/llmessage/tests/llcoproceduremanager_test.cpp b/indra/llmessage/tests/llcoproceduremanager_test.cpp index 6424117ef3..78424a28c8 100644 --- a/indra/llmessage/tests/llcoproceduremanager_test.cpp +++ b/indra/llmessage/tests/llcoproceduremanager_test.cpp @@ -48,7 +48,7 @@ #pragma warning(disable: 4702) #endif -LLCoreHttpUtil::HttpCoroutineAdapter::HttpCoroutineAdapter(std::string const&, unsigned int, unsigned int) +LLCoreHttpUtil::HttpCoroutineAdapter::HttpCoroutineAdapter(std::string const&, unsigned int) { } diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index a172308d2a..d7ed2bb4df 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1680,16 +1680,20 @@ S32 LLAppViewer::updateTextureThreads(F32 max_time) void LLAppViewer::flushLFSIO() { - while (1) - { - S32 pending = LLLFSThread::updateClass(0); - if (!pending) - { - break; - } - LL_INFOS() << "Waiting for pending IO to finish: " << pending << LL_ENDL; - ms_sleep(100); - } + S32 pending = LLLFSThread::updateClass(0); + if (pending > 0) + { + LL_INFOS() << "Waiting for pending IO to finish: " << pending << LL_ENDL; + while (1) + { + pending = LLLFSThread::updateClass(0); + if (!pending) + { + break; + } + ms_sleep(100); + } + } } bool LLAppViewer::cleanup() @@ -2187,7 +2191,7 @@ bool LLAppViewer::initThreads() LLImage::initClass(gSavedSettings.getBOOL("TextureNewByteRange"),gSavedSettings.getS32("TextureReverseByteRange")); - LLLFSThread::initClass(enable_threads && false); + LLLFSThread::initClass(enable_threads && true); // TODO: fix crashes associated with this shutdo // Image decoding LLAppViewer::sImageDecodeThread = new LLImageDecodeThread(enable_threads && true); -- cgit v1.2.3 From 609476e607b18d303afa5f5b5eeabeca84f95d16 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 1 Jun 2022 09:25:16 -0500 Subject: SL-17484 More unit test pruning. Fix for crash when deleting textures. --- indra/llcommon/llqueuedthread.cpp | 5 +++++ indra/llimage/tests/llimageworker_test.cpp | 6 ------ indra/newview/llviewertexturelist.cpp | 6 +++++- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp index 60304fff75..155e32ebae 100644 --- a/indra/llcommon/llqueuedthread.cpp +++ b/indra/llcommon/llqueuedthread.cpp @@ -75,6 +75,11 @@ void LLQueuedThread::shutdown() unpause(); // MAIN THREAD if (mThreaded) { + if (mRequestQueue.size() == 0) + { + mRequestQueue.close(); + } + S32 timeout = 100; for ( ; timeout>0; timeout--) { diff --git a/indra/llimage/tests/llimageworker_test.cpp b/indra/llimage/tests/llimageworker_test.cpp index 57d922b1a1..d36d35aba4 100644 --- a/indra/llimage/tests/llimageworker_test.cpp +++ b/indra/llimage/tests/llimageworker_test.cpp @@ -199,12 +199,6 @@ namespace tut LLImageDecodeThread::handle_t decodeHandle = mThread->decodeImage(NULL, 0, FALSE, new responder_test(&done)); // Verifies we get back a valid handle ensure("LLImageDecodeThread: threaded decodeImage(), returned handle is null", decodeHandle != 0); - // Wait a little so to simulate the main thread doing something on its main loop... - ms_sleep(500); // 500 milliseconds - // Verifies that the responder has *not* been called yet in the meantime - ensure("LLImageDecodeThread: responder creation failed", done == false); - // Ask the thread to update: that means tells the queue to check itself and creates work requests - mThread->update(1); // Wait till the thread has time to handle the work order (though it doesn't do much per work order...) const U32 INCREMENT_TIME = 500; // 500 milliseconds const U32 MAX_TIME = 20 * INCREMENT_TIME; // Do the loop 20 times max, i.e. wait 10 seconds but no more diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 555355059a..ac036bce31 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -1048,7 +1048,11 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) { iter = mUUIDMap.begin(); } - entries.push_back(iter->second); + + if (iter->second->getGLTexture()) + { + entries.push_back(iter->second); + } ++iter; } } -- cgit v1.2.3 From 4261cbba783359e71b691d6e0e9477ce53f60251 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 1 Jun 2022 10:34:33 -0500 Subject: SL-17485 Add texture memory accounting for OS X --- indra/llrender/llimagegl.cpp | 87 ++++++++++++++++++++++++++++++++++++++++++++ indra/llrender/llimagegl.h | 6 ++- 2 files changed, 92 insertions(+), 1 deletion(-) diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 04974d9122..46f0e1d69e 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -53,6 +53,88 @@ const F32 MIN_TEXTURE_LIFETIME = 10.f; //assumes i is a power of 2 > 0 U32 wpo2(U32 i); + +#if LL_DARWIN +// texture memory accounting (for OS X) +static LLMutex sTexMemMutex; +static std::unordered_map sTextureAllocs; +static U64 sTextureBytes = 0; + +// track a texture alloc on the currently bound texture. +// asserts that no currently tracked alloc exists +static void alloc_tex_image(U32 width, U32 height, U32 pixformat) +{ + U32 texUnit = gGL.getCurrentTexUnitIndex(); + U32 texName = gGL.getTexUnit(texUnit)->getCurrTexture(); + S32 size = LLImageGL::dataFormatBytes(pixformat, width, height); + + llassert(size >= 0); + + sTexMemMutex.lock(); + llassert(sTextureAllocs.find(texName) == sTextureAllocs.end()); + + sTextureAllocs[texName] = size; + sTextureBytes += size; + + sTexMemMutex.unlock(); +} + +// track texture free on given texName +static void free_tex_image(U32 texName) +{ + sTexMemMutex.lock(); + auto iter = sTextureAllocs.find(texName); + if (iter != sTextureAllocs.end()) + { + llassert(iter->second <= sTextureBytes); // sTextureBytes MUST NOT go below zero + + sTextureBytes -= iter->second; + + sTextureAllocs.erase(iter); + } + + sTexMemMutex.unlock(); +} + +// track texture free on given texNames +static void free_tex_images(U32 count, const U32* texNames) +{ + for (int i = 0; i < count; ++i) + { + free_tex_image(texNames[i]); + } +} + +// track texture free on currently bound texture +static void free_cur_tex_image() +{ + U32 texUnit = gGL.getCurrentTexUnitIndex(); + U32 texName = gGL.getTexUnit(texUnit)->getCurrTexture(); + free_tex_image(texName); +} + +// static +U64 LLImageGL::getTextureBytesAllocated() +{ + return sTextureBytes; +} + +#else + +#define alloc_tex_image(width, height, pixformat) (void) width; (void) height; (void) pixformat; +#define free_tex_image(texName) (void) texName; +#define free_tex_images(count, texNames) (void) count; (void) texNames; +#define free_cur_tex_image() + +// static +U64 LLImageGL::getTextureBytesAllocated() +{ + // UNIMPLEMENTED OUTSIDE OF OS X, DO NOT CALL + llassert(false); + return 0; +} +#endif + //statics U32 LLImageGL::sUniqueCount = 0; @@ -217,6 +299,7 @@ S32 LLImageGL::dataFormatBits(S32 dataformat) case GL_RGBA: return 32; case GL_SRGB_ALPHA: return 32; case GL_BGRA: return 32; // Used for QuickTime media textures on the Mac + case GL_DEPTH_COMPONENT: return 24; default: LL_ERRS() << "LLImageGL::Unknown format: " << dataformat << LL_ENDL; return 0; @@ -1218,6 +1301,7 @@ void LLImageGL::deleteTextures(S32 numTextures, const U32 *textures) { if (gGLManager.mInited) { + free_tex_images(numTextures, textures); glDeleteTextures(numTextures, textures); } } @@ -1340,7 +1424,10 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt stop_glerror(); { LL_PROFILE_ZONE_NAMED("glTexImage2D"); + + free_cur_tex_image(); glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, use_scratch ? scratch : pixels); + alloc_tex_image(width, height, pixformat); } stop_glerror(); diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 1716338c0b..619421e68a 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -52,6 +52,10 @@ class LLImageGL : public LLRefCount { friend class LLTexUnit; public: + + // For OS X use only -- get an estimate of how many bytes have been allocated in vram for textures + static U64 getTextureBytesAllocated(); + // These 2 functions replace glGenTextures() and glDeleteTextures() static void generateTextures(S32 numTextures, U32 *textures); static void deleteTextures(S32 numTextures, const U32 *textures); @@ -162,7 +166,7 @@ public: void updatePickMask(S32 width, S32 height, const U8* data_in); BOOL getMask(const LLVector2 &tc); - void checkTexSize(bool forced = false) const ; + void checkTexSize(bool forced = false) const ; // Sets the addressing mode used to sample the texture // (such as wrapping, mirrored wrapping, and clamp) -- cgit v1.2.3 From f4473528eb3f37b4bec3c4cda2a83d9ca94ab133 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 1 Jun 2022 11:31:45 -0500 Subject: SL-17485 Remove unused members to make mac build happy. --- indra/newview/lltexturefetch.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index d811b32f4f..64ccbf5e4a 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -552,8 +552,6 @@ private: S32 mRequestedDiscard; S32 mLoadedDiscard; S32 mDecodedDiscard; - S32 mFullWidth; - S32 mFullHeight; LLFrameTimer mRequestedDeltaTimer; LLFrameTimer mFetchDeltaTimer; LLTimer mCacheReadTimer; -- cgit v1.2.3 From a562f6fe51a527a66884a0919d217ebb42270cc0 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Mon, 6 Jun 2022 14:59:03 -0700 Subject: SL-17489: Improve warning message for fetching texture with improper URL --- indra/newview/lltexturefetch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 64ccbf5e4a..873c9f3519 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -1348,7 +1348,7 @@ bool LLTextureFetchWorker::doWork(S32 param) { if (mFTType != FTT_DEFAULT) { - LL_WARNS(LOG_TXT) << "trying to seek a non-default texture on the sim. Bad!" << LL_ENDL; + LL_WARNS(LOG_TXT) << "Trying to fetch a texture of non-default type by UUID. This probably won't work!" << LL_ENDL; } setUrl(http_url + "/?texture_id=" + mID.asString().c_str()); LL_DEBUGS(LOG_TXT) << "Texture URL: " << mUrl << LL_ENDL; -- cgit v1.2.3 From 5259fa811c11892ef150f853c9de5a8927fa68a6 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 6 Jun 2022 21:12:48 -0500 Subject: SL-17486 Force desired discard level to 0 for high boosted textures (fix for fuzzy terrain textures etc). --- indra/newview/llviewertexture.cpp | 10 ++++++++++ indra/newview/llviewertexture.h | 3 ++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 0544bceb9f..2eb36a42be 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -1884,6 +1884,16 @@ bool LLViewerFetchedTexture::isActiveFetching() return mFetchState > 7 && mFetchState < 10 && monitor_enabled; //in state of WAIT_HTTP_REQ or DECODE_IMAGE. } +void LLViewerFetchedTexture::setBoostLevel(S32 level) +{ + LLViewerTexture::setBoostLevel(level); + + if (level >= LLViewerTexture::BOOST_HIGH) + { + mDesiredDiscardLevel = 0; + } +} + bool LLViewerFetchedTexture::updateFetch() { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index a5e5c37c22..f3bc9061a2 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -134,7 +134,7 @@ public: /*virtual*/ bool isActiveFetching(); /*virtual*/ const LLUUID& getID() const { return mID; } - void setBoostLevel(S32 level); + virtual void setBoostLevel(S32 level); S32 getBoostLevel() { return mBoostLevel; } void setTextureListType(S32 tex_type) { mTextureListType = tex_type; } S32 getTextureListType() { return mTextureListType; } @@ -343,6 +343,7 @@ public: S32 getDesiredDiscardLevel() { return mDesiredDiscardLevel; } void setMinDiscardLevel(S32 discard) { mMinDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel,(S8)discard); } + void setBoostLevel(S32 level) override; bool updateFetch(); bool setDebugFetching(S32 debug_level); bool isInDebug() const { return mInDebug; } -- cgit v1.2.3 From 7908ae701f245f6c15602b23b2073f6c0fe3fdb8 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 7 Jun 2022 11:42:51 -0700 Subject: SL-17489: Fix map tile log spam and resulting excessive invalid texture requests. This was affecting map tiles that the agent is not allowed to see (HTTP error: 403 forbidden). The URLs of these map tile requests were then getting cleared, so when these map tiles were re-requested (up to 10 times per second, from LLViewerFetchedTexture::updateFetch), the request would use the wrong URL and get a 404. Stay in DONE state if there is no new work to do, reducing unneeded requests for textures while leaving open the possibility to re-request a texture at different resolution. Alternatively, we could introduce a new FAILED state here. The current DONE state has nuance, and can either mean "texture loading failed" or "texture successfully loaded at a certain LOD." And a 4xx error is generally irrecoverable. Will strongly consider a FAILED state. Also, don't clear the map URL, so that any future network requests for the map textures request the correct resource. --- indra/newview/lltexturefetch.cpp | 7 ++++++- indra/newview/llviewertexture.cpp | 7 +++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 873c9f3519..5eeecb33f2 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -1671,7 +1671,7 @@ bool LLTextureFetchWorker::doWork(S32 param) << LL_ENDL; } - if (mFTType != FTT_SERVER_BAKE) + if (mFTType != FTT_SERVER_BAKE && mFTType != FTT_MAP_TILE) { mUrl.clear(); } @@ -2695,6 +2695,11 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const return false; // need to wait for previous aborted request to complete } worker->lockWorkMutex(); // +Mw + if (worker->mState == LLTextureFetchWorker::DONE && worker->mDesiredSize == llmax(desired_size, TEXTURE_CACHE_ENTRY_SIZE) && worker->mDesiredDiscard == desired_discard) { + worker->unlockWorkMutex(); // -Mw + + return false; // similar request has failed or is in a transitional state + } worker->mActiveCount++; worker->mNeedsAux = needs_aux; worker->setImagePriority(priority); diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 0544bceb9f..1deb4b5ca1 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -2192,8 +2192,11 @@ bool LLViewerFetchedTexture::updateFetch() mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP); } - // if createRequest() failed, we're finishing up a request for this UUID, - // wait for it to complete + // If createRequest() failed, that means one of two things: + // 1. We're finishing up a request for this UUID, so we + // should wait for it to complete + // 2. We've failed a request for this UUID, so there is + // no need to create another request } else if (mHasFetcher && !mIsFetching) { -- cgit v1.2.3 From 197baebc62d1e4b922730266f77f4e6b555e2cac Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 7 Jun 2022 15:12:58 -0500 Subject: SL-17547 Fix for crash in getCurrentDiscardLevelForFetching (and add runtime check and assertion to avoid crash in production and detect crash in development). --- indra/newview/lltexturefetch.cpp | 26 ++++++++++++++------------ indra/newview/llviewertexture.cpp | 7 +++++++ indra/newview/llviewertexturelist.cpp | 11 +++++++---- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 64ccbf5e4a..2bfdfe1789 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -1071,7 +1071,7 @@ void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size) // Locks: Mw void LLTextureFetchWorker::setImagePriority(F32 priority) { - mImagePriority = priority; //should map to max virtual size + mImagePriority = priority; //should map to max virtual size, abort if zero } // Locks: Mw @@ -1397,7 +1397,7 @@ bool LLTextureFetchWorker::doWork(S32 param) else { // Shouldn't need to do anything here - llassert(mFetcher->mNetworkQueue.find(mID) != mFetcher->mNetworkQueue.end()); + //llassert(mFetcher->mNetworkQueue.find(mID) != mFetcher->mNetworkQueue.end()); return false; } } @@ -3011,16 +3011,18 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level, bool LLTextureFetch::updateRequestPriority(const LLUUID& id, F32 priority) { LL_PROFILE_ZONE_SCOPED; - bool res = false; - LLTextureFetchWorker* worker = getWorker(id); - if (worker) - { - worker->lockWorkMutex(); // +Mw - worker->setImagePriority(priority); - worker->unlockWorkMutex(); // -Mw - res = true; - } - return res; + mRequestQueue.post([=]() + { + LLTextureFetchWorker* worker = getWorker(id); + if (worker) + { + worker->lockWorkMutex(); // +Mw + worker->setImagePriority(priority); + worker->unlockWorkMutex(); // -Mw + } + }); + + return true; } // Replicates and expands upon the base class's diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 2eb36a42be..ae480bcc35 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -653,6 +653,8 @@ void LLViewerTexture::cleanup() { notifyAboutMissingAsset(); + LLAppViewer::getTextureFetch()->updateRequestPriority(mID, 0.f); + mFaceList[LLRender::DIFFUSE_MAP].clear(); mFaceList[LLRender::NORMAL_MAP].clear(); mFaceList[LLRender::SPECULAR_MAP].clear(); @@ -1941,6 +1943,11 @@ bool LLViewerFetchedTexture::updateFetch() LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - in fast cache"); return false; } + if (mGLTexturep.isNull()) + { // fix for crash inside getCurrentDiscardLevelForFetching (shouldn't happen but appears to be happening) + llassert(false); + return false; + } S32 current_discard = getCurrentDiscardLevelForFetching(); S32 desired_discard = getDesiredDiscardLevel(); diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index ac036bce31..8faeb70553 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -1025,7 +1025,7 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; LLTimer image_op_timer; - typedef std::vector entries_list_t; + typedef std::vector > entries_list_t; entries_list_t entries; // update N textures at beginning of mImageList @@ -1057,10 +1057,13 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) } } - for (auto* imagep : entries) + for (auto& imagep : entries) { - updateImageDecodePriority(imagep); - imagep->updateFetch(); + if (imagep->getNumRefs() > 1) // make sure this image hasn't been deleted before attempting to update (may happen as a side effect of some other image updating) + { + updateImageDecodePriority(imagep); + imagep->updateFetch(); + } } if (entries.size() > 0) -- cgit v1.2.3 From 99189ff2d5e96434cdc58115bbc03614f8e50773 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 7 Jun 2022 15:24:40 -0500 Subject: SL-17547 Fix for crash on shutdown introduced in last commit. --- indra/newview/lltexturefetch.cpp | 2 +- indra/newview/llviewertexture.cpp | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 2bfdfe1789..0fa425cf22 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -3011,7 +3011,7 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level, bool LLTextureFetch::updateRequestPriority(const LLUUID& id, F32 priority) { LL_PROFILE_ZONE_SCOPED; - mRequestQueue.post([=]() + mRequestQueue.tryPost([=]() { LLTextureFetchWorker* worker = getWorker(id); if (worker) diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index ae480bcc35..b7633545f9 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -653,7 +653,10 @@ void LLViewerTexture::cleanup() { notifyAboutMissingAsset(); - LLAppViewer::getTextureFetch()->updateRequestPriority(mID, 0.f); + if (LLAppViewer::getTextureFetch()) + { + LLAppViewer::getTextureFetch()->updateRequestPriority(mID, 0.f); + } mFaceList[LLRender::DIFFUSE_MAP].clear(); mFaceList[LLRender::NORMAL_MAP].clear(); -- cgit v1.2.3 From 039c6689c9f3e10970d2617a1127c6a48891e619 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 7 Jun 2022 17:27:29 -0500 Subject: SL-17547 Fix for crash on shutdown cleaning up LLLFSThread --- indra/newview/llappviewer.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index d7ed2bb4df..0b80d32ac3 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1850,8 +1850,6 @@ bool LLAppViewer::cleanup() LL_INFOS() << "Cache files removed" << LL_ENDL; - // Wait for any pending LFS IO - flushLFSIO(); LL_INFOS() << "Shutting down Views" << LL_ENDL; // Destroy the UI @@ -2058,6 +2056,7 @@ bool LLAppViewer::cleanup() sTextureFetch->shutDownTextureCacheThread() ; sTextureFetch->shutDownImageDecodeThread() ; + LLLFSThread::sLocal->shutdown(); LL_INFOS() << "Shutting down message system" << LL_ENDL; end_messaging_system(); -- cgit v1.2.3 From da069765b1974e60df5ebf9e973c7fd00c52e329 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 8 Jun 2022 16:24:03 -0500 Subject: SL-17005 Tweak target VRAM usage and add some log spam to help zero in on good targets. --- indra/llwindow/llwindowwin32.cpp | 22 ++++++++++++++++------ indra/newview/llviewertexture.cpp | 16 ++++++++-------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index da79660239..20443988ab 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -65,7 +65,6 @@ #include #include - // Require DirectInput version 8 #define DIRECTINPUT_VERSION 0x0800 @@ -4649,23 +4648,34 @@ void LLWindowWin32::LLWindowWin32Thread::updateVRAMUsage() mDXGIAdapter->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_LOCAL, &info); // try to use no more than the available reserve minus 10% - U32 target = info.AvailableForReservation / 1024 / 1024; - target -= target / 10; + U32 target = info.Budget / 1024 / 1024; + + // EXPERIMENTAL + // Trying to zero in on a good target usage, code here should be tuned against observed behavior + // of various hardware. + if (target > 4096) // if 4GB are installed, try to leave 2GB free + { + target -= 2048; + } + else // if less than 4GB are installed, try not to use more than half of it + { + target /= 2; + } U32 used_vram = info.CurrentUsage / 1024 / 1024; mAvailableVRAM = used_vram < target ? target - used_vram : 0; - /*LL_INFOS() << "\nLocal\nAFR: " << info.AvailableForReservation / 1024 / 1024 + LL_INFOS("Window") << "\nLocal\nAFR: " << info.AvailableForReservation / 1024 / 1024 << "\nBudget: " << info.Budget / 1024 / 1024 << "\nCR: " << info.CurrentReservation / 1024 / 1024 << "\nCU: " << info.CurrentUsage / 1024 / 1024 << LL_ENDL; mDXGIAdapter->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL, &info); - LL_INFOS() << "\nNon-Local\nAFR: " << info.AvailableForReservation / 1024 / 1024 + LL_INFOS("Window") << "\nNon-Local\nAFR: " << info.AvailableForReservation / 1024 / 1024 << "\nBudget: " << info.Budget / 1024 / 1024 << "\nCR: " << info.CurrentReservation / 1024 / 1024 - << "\nCU: " << info.CurrentUsage / 1024 / 1024 << LL_ENDL;*/ + << "\nCU: " << info.CurrentUsage / 1024 / 1024 << LL_ENDL; } else if (mD3DDevice != NULL) { // fallback to D3D9 diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 16b07159ba..e31bc5ec6e 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -803,14 +803,8 @@ void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) co } virtual_size *= sTexelPixelRatio; - /*if (!mMaxVirtualSizeResetCounter) - { - //flag to reset the values because the old values are used. - resetMaxVirtualSizeResetCounter(); - mMaxVirtualSize = virtual_size; - mNeedsGLTexture = needs_gltexture; - } - else*/ if (virtual_size > mMaxVirtualSize) + + if (virtual_size > mMaxVirtualSize) { mMaxVirtualSize = virtual_size; } @@ -1801,6 +1795,12 @@ void LLViewerFetchedTexture::updateVirtualSize() return; } + if (sDesiredDiscardBias > 0.f) + { + // running out of video memory, don't hold onto high res textures in the background + mMaxVirtualSize = 0.f; + } + for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch) { llassert(mNumFaces[ch] <= mFaceList[ch].size()); -- cgit v1.2.3 From ef87eb7fa80a72b94d67d5ab680f60a837dd1ddd Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 31 May 2022 12:49:53 -0700 Subject: SL-17483: Make ThreadPool inherit LLInstanceTracker (cherry picked from commit 41d6a0e222241606c317281e2f0b211e16813dd5) --- indra/llcommon/threadpool.cpp | 1 + indra/llcommon/threadpool.h | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/indra/llcommon/threadpool.cpp b/indra/llcommon/threadpool.cpp index ba914035e2..d5adf11264 100644 --- a/indra/llcommon/threadpool.cpp +++ b/indra/llcommon/threadpool.cpp @@ -22,6 +22,7 @@ #include "stringize.h" LL::ThreadPool::ThreadPool(const std::string& name, size_t threads, size_t capacity): + super(name), mQueue(name, capacity), mName("ThreadPool:" + name), mThreadCount(threads) diff --git a/indra/llcommon/threadpool.h b/indra/llcommon/threadpool.h index b79c9b9090..f8eec3b457 100644 --- a/indra/llcommon/threadpool.h +++ b/indra/llcommon/threadpool.h @@ -22,8 +22,10 @@ namespace LL { - class ThreadPool + class ThreadPool: public LLInstanceTracker { + private: + using super = LLInstanceTracker; public: /** * Pass ThreadPool a string name. This can be used to look up the -- cgit v1.2.3 From ac99e979f43d49402a24b2f58a154c4ef1583efd Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 9 Jun 2022 10:18:29 -0400 Subject: SL-17483: Make it possible to override width of any ThreadPool. Introduce CommonControl, which in a running viewer (or any program containing an LLViewerControlListener instance) gives access to LLViewerControl functionality, e.g. getting, setting or enumerating control variables -- without introducing a link dependency on newview. Make ThreadPool's constructor consult CommonControl to check for an override for the width of the new ThreadPool in the Global (i.e. gSavedSettings) setting ThreadPoolSizes, and honor that if found. Introduce static ThreadPool methods getConfiguredWidth(), to query for such an override on any particular ThreadPool name; and getWidth(), to ask for the width of an instance if that instance already exists, else the width with which it *would* be instantiated. --- indra/llcommon/CMakeLists.txt | 2 + indra/llcommon/commoncontrol.cpp | 104 +++++++++++++++++++++++++++++++++++++++ indra/llcommon/commoncontrol.h | 75 ++++++++++++++++++++++++++++ indra/llcommon/threadpool.cpp | 51 ++++++++++++++++++- indra/llcommon/threadpool.h | 30 ++++++++++- 5 files changed, 260 insertions(+), 2 deletions(-) create mode 100644 indra/llcommon/commoncontrol.cpp create mode 100644 indra/llcommon/commoncontrol.h diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index ca8b5e946f..4dbf1282c4 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -29,6 +29,7 @@ include_directories( # ${LLCOMMON_LIBRARIES}) set(llcommon_SOURCE_FILES + commoncontrol.cpp indra_constants.cpp llallocator.cpp llallocator_heap_profile.cpp @@ -129,6 +130,7 @@ set(llcommon_HEADER_FILES CMakeLists.txt chrono.h + commoncontrol.h ctype_workaround.h fix_macros.h indra_constants.h diff --git a/indra/llcommon/commoncontrol.cpp b/indra/llcommon/commoncontrol.cpp new file mode 100644 index 0000000000..2c2a2abeb0 --- /dev/null +++ b/indra/llcommon/commoncontrol.cpp @@ -0,0 +1,104 @@ +/** + * @file commoncontrol.cpp + * @author Nat Goodspeed + * @date 2022-06-08 + * @brief Implementation for commoncontrol. + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Copyright (c) 2022, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "commoncontrol.h" +// STL headers +// std headers +// external library headers +// other Linden headers +#include "llevents.h" +#include "llsdutil.h" + +LLSD LL::CommonControl::access(const LLSD& params) +{ + // We can't actually introduce a link-time dependency on llxml, or on any + // global LLControlGroup (*koff* gSavedSettings *koff*) but we can issue a + // runtime query. If we're running as part of a viewer with + // LLViewerControlListener, we can use that to interact with any + // instantiated LLControGroup. + LLSD response; + { + LLEventStream reply("reply"); + LLTempBoundListener connection = reply.listen("listener", + [&response] (const LLSD& event) + { + response = event; + return false; + }); + LLSD rparams{ params }; + rparams["reply"] = reply.getName(); + LLEventPumps::instance().obtain("LLViewerControl").post(rparams); + } + // LLViewerControlListener responds immediately. If it's listening at all, + // it will already have set response. + if (! response.isDefined()) + { + LLTHROW(NoListener("No LLViewerControl listener instantiated")); + } + LLSD error{ response["error"] }; + if (error.isDefined()) + { + LLTHROW(ParamError(error)); + } + return response; +} + +/// set control group.key to defined default value +LLSD LL::CommonControl::set_default(const std::string& group, const std::string& key) +{ + return access(llsd::map("op", "set", + "group", group, "key", key))["value"]; +} + +/// set control group.key to specified value +LLSD LL::CommonControl::set(const std::string& group, const std::string& key, const LLSD& value) +{ + return access(llsd::map("op", "set", + "group", group, "key", key, "value", value))["value"]; +} + +/// toggle boolean control group.key +LLSD LL::CommonControl::toggle(const std::string& group, const std::string& key) +{ + return access(llsd::map("op", "toggle", + "group", group, "key", key))["value"]; +} + +/// get the definition for control group.key, (! isDefined()) if bad +/// ["name"], ["type"], ["value"], ["comment"] +LLSD LL::CommonControl::get_def(const std::string& group, const std::string& key) +{ + return access(llsd::map("op", "get", + "group", group, "key", key)); +} + +/// get the value of control group.key +LLSD LL::CommonControl::get(const std::string& group, const std::string& key) +{ + return access(llsd::map("op", "get", + "group", group, "key", key))["value"]; +} + +/// get defined groups +std::vector LL::CommonControl::get_groups() +{ + auto groups{ access(llsd::map("op", "groups"))["groups"] }; + return { groups.beginArray(), groups.endArray() }; +} + +/// get definitions for all variables in group +LLSD LL::CommonControl::get_vars(const std::string& group) +{ + return access(llsd::map("op", "vars", "group", group))["vars"]; +} diff --git a/indra/llcommon/commoncontrol.h b/indra/llcommon/commoncontrol.h new file mode 100644 index 0000000000..07d4a45ac5 --- /dev/null +++ b/indra/llcommon/commoncontrol.h @@ -0,0 +1,75 @@ +/** + * @file commoncontrol.h + * @author Nat Goodspeed + * @date 2022-06-08 + * @brief Access LLViewerControl LLEventAPI, if process has one. + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Copyright (c) 2022, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_COMMONCONTROL_H) +#define LL_COMMONCONTROL_H + +#include +#include "llexception.h" +#include "llsd.h" + +namespace LL +{ + class CommonControl + { + public: + struct Error: public LLException + { + Error(const std::string& what): LLException(what) {} + }; + + /// Exception thrown if there's no LLViewerControl LLEventAPI + struct NoListener: public Error + { + NoListener(const std::string& what): Error(what) {} + }; + + struct ParamError: public Error + { + ParamError(const std::string& what): Error(what) {} + }; + + /// set control group.key to defined default value + static + LLSD set_default(const std::string& group, const std::string& key); + + /// set control group.key to specified value + static + LLSD set(const std::string& group, const std::string& key, const LLSD& value); + + /// toggle boolean control group.key + static + LLSD toggle(const std::string& group, const std::string& key); + + /// get the definition for control group.key, (! isDefined()) if bad + /// ["name"], ["type"], ["value"], ["comment"] + static + LLSD get_def(const std::string& group, const std::string& key); + + /// get the value of control group.key + static + LLSD get(const std::string& group, const std::string& key); + + /// get defined groups + static + std::vector get_groups(); + + /// get definitions for all variables in group + static + LLSD get_vars(const std::string& group); + + private: + static + LLSD access(const LLSD& params); + }; +} // namespace LL + +#endif /* ! defined(LL_COMMONCONTROL_H) */ diff --git a/indra/llcommon/threadpool.cpp b/indra/llcommon/threadpool.cpp index d5adf11264..10d67abf37 100644 --- a/indra/llcommon/threadpool.cpp +++ b/indra/llcommon/threadpool.cpp @@ -17,15 +17,17 @@ // std headers // external library headers // other Linden headers +#include "commoncontrol.h" #include "llerror.h" #include "llevents.h" +#include "llsd.h" #include "stringize.h" LL::ThreadPool::ThreadPool(const std::string& name, size_t threads, size_t capacity): super(name), mQueue(name, capacity), mName("ThreadPool:" + name), - mThreadCount(threads) + mThreadCount(getConfiguredWidth(name, threads)) {} void LL::ThreadPool::start() @@ -87,3 +89,50 @@ void LL::ThreadPool::run() { mQueue.runUntilClose(); } + +//static +size_t LL::ThreadPool::getConfiguredWidth(const std::string& name, size_t dft=0) +{ + LLSD poolSizes{ LL::CommonControl::get("Global", "ThreadPoolSizes") }; + // "ThreadPoolSizes" is actually a map containing the sizes of interest -- + // or should be, if this process has an "LLViewerControl" LLEventAPI + // instance and its settings include "ThreadPoolSizes". If we failed to + // retrieve it, perhaps we're in a program that doesn't define that, or + // perhaps there's no such setting, or perhaps we're asking too early, + // before the LLEventAPI itself has been instantiated. In any of those + // cases, it seems worth warning. + if (! poolSizes.isDefined()) + { + // Note: we don't warn about absence of an override key for a + // particular ThreadPool name, that's fine. This warning is about + // complete absence of a ThreadPoolSizes setting, which we expect in a + // normal viewer session. + LL_WARNS("ThreadPool") << "No 'ThreadPoolSizes' setting for ThreadPool '" + << name << "'" << LL_ENDL; + } + else + { + //LL_DEBUGS + LL_INFOS("ThreadPool") << "ThreadPoolSizes = " << poolSizes << LL_ENDL; + } + // LLSD treats an undefined value as an empty map when asked to retrieve a + // key, so we don't need this to be conditional. + LLSD sizeSpec{ poolSizes[name] }; + // We retrieve sizeSpec as LLSD, rather than immediately as LLSD::Integer, + // so we can distinguish the case when it's undefined. + return sizeSpec.isInteger() ? sizeSpec.asInteger() : dft; +} + +//static +size_t LL::ThreadPool::getWidth(const std::string& name, size_t dft) +{ + auto instance{ getInstance(name) }; + if (instance) + { + return instance->getWidth(); + } + else + { + return getConfiguredWidth(name, dft); + } +} diff --git a/indra/llcommon/threadpool.h b/indra/llcommon/threadpool.h index f8eec3b457..b49d511257 100644 --- a/indra/llcommon/threadpool.h +++ b/indra/llcommon/threadpool.h @@ -30,8 +30,17 @@ namespace LL /** * Pass ThreadPool a string name. This can be used to look up the * relevant WorkQueue. + * + * The number of threads you pass sets the compile-time default. But + * if the user has overridden the LLSD map in the "ThreadPoolSizes" + * setting with a key matching this ThreadPool name, that setting + * overrides this parameter. + * + * Pass an explicit capacity to limit the size of the queue. + * Constraining the queue can cause a submitter to block. Do not + * constrain any ThreadPool accepting work from the main thread. */ - ThreadPool(const std::string& name, size_t threads=1, size_t capacity=1024); + ThreadPool(const std::string& name, size_t threads=1, size_t capacity=1024*1024); virtual ~ThreadPool(); /** @@ -59,6 +68,25 @@ namespace LL */ virtual void run(); + /** + * getConfiguredWidth() returns the setting, if any, for the specified + * ThreadPool name. Returns dft if the "ThreadPoolSizes" map does not + * contain the specified name. + */ + static + size_t getConfiguredWidth(const std::string& name, size_t dft=0); + + /** + * This getWidth() returns the width of the instantiated ThreadPool + * with the specified name, if any. If no instance exists, returns its + * getConfiguredWidth() if any. If there's no instance and no relevant + * override, return dft. Presumably dft should match the threads + * parameter passed to the ThreadPool constructor call that will + * eventually instantiate the ThreadPool with that name. + */ + static + size_t getWidth(const std::string& name, size_t dft); + private: void run(const std::string& name); -- cgit v1.2.3 From 276647789a7080c0d44ec8e4375daf0f42b73f17 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 9 Jun 2022 10:36:13 -0400 Subject: SL-17483: Simplify ThreadPool instantiations. Now that LL::ThreadPool's constructor has subsumed the work of discovering a runtime override width, LLAppViewer::initGeneralThread() can simply pass the compile-time default width instead of redundantly checking ThreadPoolSizes. Also the default ThreadPool capacity has been bumped up to what "General" and "LLImageGL" were requesting, so they need not pass that explicitly or explain in comments why they're doing it. But until we start throwing work at the "General" ThreadPool, configure it down to 1 thread in settings.xml. --- indra/llrender/llimagegl.cpp | 6 ++---- indra/newview/app_settings/settings.xml | 2 +- indra/newview/llappviewer.cpp | 9 +-------- 3 files changed, 4 insertions(+), 13 deletions(-) diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 9bd3a0a6b0..42460d23b8 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -2412,10 +2412,8 @@ void LLImageGL::checkActiveThread() std::atomic LLImageGLThread::sFreeVRAMMegabytes(4096); //if free vram is unknown, default to 4GB LLImageGLThread::LLImageGLThread(LLWindow* window) - // We want exactly one thread, but a very large capacity: we never want - // anyone, especially inner-loop render code, to have to block on post() - // because we're full. - : ThreadPool("LLImageGL", 1, 1024*1024) + // We want exactly one thread. + : ThreadPool("LLImageGL", 1) , mWindow(window) { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 0000ae18bd..9c27e2a42e 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -12766,7 +12766,7 @@ Value General - 4 + 1 ThrottleBandwidthKBPS diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 3bcd4f9a49..334df4ee20 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2183,14 +2183,7 @@ void LLAppViewer::initGeneralThread() return; } - LLSD poolSizes{ gSavedSettings.getLLSD("ThreadPoolSizes") }; - LLSD sizeSpec{ poolSizes["General"] }; - LLSD::Integer poolSize{ sizeSpec.isInteger() ? sizeSpec.asInteger() : 3 }; - LL_DEBUGS("ThreadPool") << "Instantiating General pool with " - << poolSize << " threads" << LL_ENDL; - // We don't want anyone, especially the main thread, to have to block - // due to this ThreadPool being full. - mGeneralThreadPool = new LL::ThreadPool("General", poolSize, 1024 * 1024); + mGeneralThreadPool = new LL::ThreadPool("General", 3); mGeneralThreadPool->start(); } -- cgit v1.2.3 From 1ff79a430d9d55cbb4b4ba55018c791a8a933916 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 9 Jun 2022 11:19:21 -0400 Subject: SL-17483: Fix ThreadPool::getConfiguredWidth() compile error. Log ThreadPoolSizes at DEBUG level, not INFO. --- indra/llcommon/threadpool.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/indra/llcommon/threadpool.cpp b/indra/llcommon/threadpool.cpp index 10d67abf37..e8daf549ef 100644 --- a/indra/llcommon/threadpool.cpp +++ b/indra/llcommon/threadpool.cpp @@ -91,7 +91,7 @@ void LL::ThreadPool::run() } //static -size_t LL::ThreadPool::getConfiguredWidth(const std::string& name, size_t dft=0) +size_t LL::ThreadPool::getConfiguredWidth(const std::string& name, size_t dft) { LLSD poolSizes{ LL::CommonControl::get("Global", "ThreadPoolSizes") }; // "ThreadPoolSizes" is actually a map containing the sizes of interest -- @@ -112,8 +112,7 @@ size_t LL::ThreadPool::getConfiguredWidth(const std::string& name, size_t dft=0) } else { - //LL_DEBUGS - LL_INFOS("ThreadPool") << "ThreadPoolSizes = " << poolSizes << LL_ENDL; + LL_DEBUGS("ThreadPool") << "ThreadPoolSizes = " << poolSizes << LL_ENDL; } // LLSD treats an undefined value as an empty map when asked to retrieve a // key, so we don't need this to be conditional. -- cgit v1.2.3 From 50dca86f64a167fe0db901310d04784b2f0dfa1f Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 9 Jun 2022 12:06:23 -0400 Subject: SL-17483: Recast LLImageDecodeThread as a facade for ThreadPool. Remove all references to LLQueuedThread (but emulate a couple bits of its API such as handle_t and getPending()). Migrate ImageRequest into llimageworker.cpp. It has never been part of LLImageDecodeThread's public API. Remove ImageRequest tests. Remove all references to LLImageDecodeThread::pause(). The idea of pausing another thread is bizarre to me, and LLThreadPool has no such operation. Nor does it have an abortRequest(). --- indra/llimage/llimageworker.cpp | 99 ++++++++++++++++++++---------- indra/llimage/llimageworker.h | 61 +++++------------- indra/llimage/tests/llimageworker_test.cpp | 66 -------------------- indra/newview/app_settings/settings.xml | 2 + indra/newview/llappviewer.cpp | 11 ++-- indra/newview/lltexturefetch.cpp | 6 +- indra/newview/llviewerwindow.cpp | 1 - indra/test/test.cpp | 2 +- 8 files changed, 91 insertions(+), 157 deletions(-) diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp index d8503396d7..3c21499673 100644 --- a/indra/llimage/llimageworker.cpp +++ b/indra/llimage/llimageworker.cpp @@ -28,44 +28,83 @@ #include "llimageworker.h" #include "llimagedxt.h" +#include "threadpool.h" + +/*--------------------------------------------------------------------------*/ +class ImageRequest +{ +public: + ImageRequest(LLPointer image, + S32 discard, BOOL needs_aux, + LLPointer responder); + virtual ~ImageRequest(); + + /*virtual*/ bool processRequest(); + /*virtual*/ void finishRequest(bool completed); + +private: + // input + LLPointer mFormattedImage; + S32 mDiscardLevel; + BOOL mNeedsAux; + // output + LLPointer mDecodedImageRaw; + LLPointer mDecodedImageAux; + BOOL mDecodedRaw; + BOOL mDecodedAux; + LLPointer mResponder; +}; + //---------------------------------------------------------------------------- // MAIN THREAD -LLImageDecodeThread::LLImageDecodeThread(bool threaded) - : LLQueuedThread("imagedecode", threaded) +LLImageDecodeThread::LLImageDecodeThread(bool /*threaded*/) { - mCreationMutex = new LLMutex(); + mThreadPool.reset(new LL::ThreadPool("ImageDecode", 8)); + mThreadPool->start(); } //virtual LLImageDecodeThread::~LLImageDecodeThread() -{ - delete mCreationMutex ; -} +{} // MAIN THREAD // virtual S32 LLImageDecodeThread::update(F32 max_time_ms) { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - S32 res = LLQueuedThread::update(max_time_ms); - return res; + return getPending(); } -LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* image, - S32 discard, BOOL needs_aux, Responder* responder) +S32 LLImageDecodeThread::getPending() { - LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - handle_t handle = generateHandle(); + return mThreadPool->getQueue().size(); +} - ImageRequest* req = new ImageRequest(handle, image, - discard, needs_aux, - responder); +LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLPointer image, + S32 discard, BOOL needs_aux, LLPointer responder) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - addRequest(req); + // Instantiate the ImageRequest right in the lambda, why not? + mThreadPool->getQueue().post( + [req = ImageRequest(image, discard, needs_aux, responder)] + () mutable + { + auto done = req.processRequest(); + req.finishRequest(done); + }); + + // It's important to our consumer (LLTextureFetchWorker) that we return a + // nonzero handle. It is NOT important that the nonzero handle be unique: + // nothing is ever done with it except to compare it to zero, or zero it. + return 17; +} - return handle; +void LLImageDecodeThread::shutdown() +{ + mThreadPool->close(); } LLImageDecodeThread::Responder::~Responder() @@ -74,11 +113,10 @@ LLImageDecodeThread::Responder::~Responder() //---------------------------------------------------------------------------- -LLImageDecodeThread::ImageRequest::ImageRequest(handle_t handle, LLImageFormatted* image, - S32 discard, BOOL needs_aux, - LLImageDecodeThread::Responder* responder) - : LLQueuedThread::QueuedRequest(handle, FLAG_AUTO_COMPLETE), - mFormattedImage(image), +ImageRequest::ImageRequest(LLPointer image, + S32 discard, BOOL needs_aux, + LLPointer responder) + : mFormattedImage(image), mDiscardLevel(discard), mNeedsAux(needs_aux), mDecodedRaw(FALSE), @@ -87,7 +125,7 @@ LLImageDecodeThread::ImageRequest::ImageRequest(handle_t handle, LLImageFormatte { } -LLImageDecodeThread::ImageRequest::~ImageRequest() +ImageRequest::~ImageRequest() { mDecodedImageRaw = NULL; mDecodedImageAux = NULL; @@ -98,7 +136,7 @@ LLImageDecodeThread::ImageRequest::~ImageRequest() // Returns true when done, whether or not decode was successful. -bool LLImageDecodeThread::ImageRequest::processRequest() +bool ImageRequest::processRequest() { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; const F32 decode_time_slice = 0.f; //disable time slicing @@ -125,7 +163,7 @@ bool LLImageDecodeThread::ImageRequest::processRequest() mFormattedImage->getHeight(), mFormattedImage->getComponents()); } - done = mFormattedImage->decode(mDecodedImageRaw, decode_time_slice); // 1ms + done = mFormattedImage->decode(mDecodedImageRaw, decode_time_slice); // some decoders are removing data when task is complete and there were errors mDecodedRaw = done && mDecodedImageRaw->getData(); } @@ -138,14 +176,14 @@ bool LLImageDecodeThread::ImageRequest::processRequest() mFormattedImage->getHeight(), 1); } - done = mFormattedImage->decodeChannels(mDecodedImageAux, decode_time_slice, 4, 4); // 1ms + done = mFormattedImage->decodeChannels(mDecodedImageAux, decode_time_slice, 4, 4); mDecodedAux = done && mDecodedImageAux->getData(); } return done; } -void LLImageDecodeThread::ImageRequest::finishRequest(bool completed) +void ImageRequest::finishRequest(bool completed) { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if (mResponder.notNull()) @@ -155,10 +193,3 @@ void LLImageDecodeThread::ImageRequest::finishRequest(bool completed) } // Will automatically be deleted } - -// Used by unit test only -// Checks that a responder exists for this instance so that something can happen when completion is reached -bool LLImageDecodeThread::ImageRequest::tut_isOK() -{ - return mResponder.notNull(); -} diff --git a/indra/llimage/llimageworker.h b/indra/llimage/llimageworker.h index e0a94d2841..6a0b2b4681 100644 --- a/indra/llimage/llimageworker.h +++ b/indra/llimage/llimageworker.h @@ -29,9 +29,13 @@ #include "llimage.h" #include "llpointer.h" -#include "llworkerthread.h" -class LLImageDecodeThread : public LLQueuedThread +namespace LL +{ + class ThreadPool; +} // namespace LL + +class LLImageDecodeThread { public: class Responder : public LLThreadSafeRefCount @@ -42,57 +46,24 @@ public: virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux) = 0; }; - class ImageRequest : public LLQueuedThread::QueuedRequest - { - protected: - virtual ~ImageRequest(); // use deleteRequest() - - public: - ImageRequest(handle_t handle, LLImageFormatted* image, - S32 discard, BOOL needs_aux, - LLImageDecodeThread::Responder* responder); - - /*virtual*/ bool processRequest(); - /*virtual*/ void finishRequest(bool completed); - - // Used by unit tests to check the consitency of the request instance - bool tut_isOK(); - - private: - // input - LLPointer mFormattedImage; - S32 mDiscardLevel; - BOOL mNeedsAux; - // output - LLPointer mDecodedImageRaw; - LLPointer mDecodedImageAux; - BOOL mDecodedRaw; - BOOL mDecodedAux; - LLPointer mResponder; - }; - public: LLImageDecodeThread(bool threaded = true); virtual ~LLImageDecodeThread(); - handle_t decodeImage(LLImageFormatted* image, + // meant to resemble LLQueuedThread::handle_t + typedef U32 handle_t; + handle_t decodeImage(LLPointer image, S32 discard, BOOL needs_aux, - Responder* responder); + LLPointer responder); + S32 getPending(); S32 update(F32 max_time_ms); + void shutdown(); private: - struct creation_info - { - handle_t handle; - LLPointer image; - S32 discard; - BOOL needs_aux; - LLPointer responder; - creation_info(handle_t h, LLImageFormatted* i, U32 p, S32 d, BOOL aux, Responder* r) - : handle(h), image(i), discard(d), needs_aux(aux), responder(r) - {} - }; - LLMutex* mCreationMutex; + // As of SL-17483, LLImageDecodeThread is no longer itself an + // LLQueuedThread - instead this is the API by which we submit work to the + // "ImageDecode" ThreadPool. + std::unique_ptr mThreadPool; }; #endif diff --git a/indra/llimage/tests/llimageworker_test.cpp b/indra/llimage/tests/llimageworker_test.cpp index d36d35aba4..0a97b739b0 100644 --- a/indra/llimage/tests/llimageworker_test.cpp +++ b/indra/llimage/tests/llimageworker_test.cpp @@ -125,42 +125,11 @@ namespace tut } }; - // Test wrapper declaration : image worker - // Note: this class is not meant to be instantiated outside an LLImageDecodeThread instance - // but it's not a bad idea to get its public API a good shake as part of a thorough unit test set. - // Some gotcha with the destructor though (see below). - struct imagerequest_test - { - // Instance to be tested - LLImageDecodeThread::ImageRequest* mRequest; - bool done; - - // Constructor and destructor of the test wrapper - imagerequest_test() - { - done = false; - - mRequest = new LLImageDecodeThread::ImageRequest(0, 0, - 0, FALSE, - new responder_test(&done)); - } - ~imagerequest_test() - { - // We should delete the object *but*, because its destructor is protected, that cannot be - // done from outside an LLImageDecodeThread instance... So we leak memory here... It's fine... - //delete mRequest; - } - }; - // Tut templating thingamagic: test group, object and test instance typedef test_group imagedecodethread_t; typedef imagedecodethread_t::object imagedecodethread_object_t; tut::imagedecodethread_t tut_imagedecodethread("LLImageDecodeThread"); - typedef test_group imagerequest_t; - typedef imagerequest_t::object imagerequest_object_t; - tut::imagerequest_t tut_imagerequest("LLImageRequest"); - // --------------------------------------------------------------------------------------- // Test functions // Notes: @@ -172,21 +141,6 @@ namespace tut // --------------------------------------------------------------------------------------- // Test the LLImageDecodeThread interface // --------------------------------------------------------------------------------------- - // - // Note on Unit Testing Queued Thread Classes - // - // Since methods on such a class are called on a separate loop and that we can't insert tut - // ensure() calls in there, we exercise the class with 2 sets of tests: - // - 1: Test as a single threaded instance: We declare the class but ask for no thread - // to be spawned (easy with LLThreads since there's a boolean argument on the constructor - // just for that). We can then unit test each public method like we do on a normal class. - // - 2: Test as a threaded instance: We let the thread launch and check that its external - // behavior is as expected (i.e. it runs, can accept a work order and processes - // it). Typically though there's no guarantee that this exercises all the methods of the - // class which is why we also need the previous "non threaded" set of unit tests for - // complete coverage. - // - // --------------------------------------------------------------------------------------- template<> template<> void imagedecodethread_object_t::test<1>() @@ -211,24 +165,4 @@ namespace tut // Verifies that the responder has now been called ensure("LLImageDecodeThread: threaded work unit not processed", done == true); } - - // --------------------------------------------------------------------------------------- - // Test the LLImageDecodeThread::ImageRequest interface - // --------------------------------------------------------------------------------------- - - template<> template<> - void imagerequest_object_t::test<1>() - { - // Test that we start with a correct request at creation - ensure("LLImageDecodeThread::ImageRequest::ImageRequest() constructor test failed", mRequest->tut_isOK()); - bool res = mRequest->processRequest(); - // Verifies that we processed the request successfully - ensure("LLImageDecodeThread::ImageRequest::processRequest() processing request test failed", res == true); - // Check that we can call the finishing call safely - try { - mRequest->finishRequest(false); - } catch (...) { - fail("LLImageDecodeThread::ImageRequest::finishRequest() test failed"); - } - } } diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 3201848f38..bc4945eca5 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -12646,6 +12646,8 @@ General 1 + ImageDecode + 9 ThrottleBandwidthKBPS diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index bc38a96ef2..ae0c9d4dd6 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1548,7 +1548,6 @@ bool LLAppViewer::doFrame() { S32 non_interactive_ms_sleep_time = 100; LLAppViewer::getTextureCache()->pause(); - LLAppViewer::getImageDecodeThread()->pause(); ms_sleep(non_interactive_ms_sleep_time); } @@ -1568,7 +1567,6 @@ bool LLAppViewer::doFrame() ms_sleep(milliseconds_to_sleep); // also pause worker threads during this wait period LLAppViewer::getTextureCache()->pause(); - LLAppViewer::getImageDecodeThread()->pause(); } } @@ -1617,7 +1615,6 @@ bool LLAppViewer::doFrame() { LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df getTextureCache" ) LLAppViewer::getTextureCache()->pause(); - LLAppViewer::getImageDecodeThread()->pause(); LLAppViewer::getTextureFetch()->pause(); } if(!total_io_pending) //pause file threads if nothing to process. @@ -2051,10 +2048,10 @@ bool LLAppViewer::cleanup() sTextureCache->shutdown(); sImageDecodeThread->shutdown(); sPurgeDiskCacheThread->shutdown(); - if (mGeneralThreadPool) - { - mGeneralThreadPool->close(); - } + if (mGeneralThreadPool) + { + mGeneralThreadPool->close(); + } sTextureFetch->shutDownTextureCacheThread() ; sTextureFetch->shutDownImageDecodeThread() ; diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 64ccbf5e4a..539e2454ea 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -2113,10 +2113,10 @@ void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRe // Threads: Tmain void LLTextureFetchWorker::endWork(S32 param, bool aborted) { - LL_PROFILE_ZONE_SCOPED; + LL_PROFILE_ZONE_SCOPED; if (mDecodeHandle != 0) { - mFetcher->mImageDecodeThread->abortRequest(mDecodeHandle, false); + // LL::ThreadPool has no operation to cancel a particular work item mDecodeHandle = 0; } mFormattedImage = NULL; @@ -3169,7 +3169,7 @@ void LLTextureFetch::shutDownImageDecodeThread() { if(mImageDecodeThread) { - llassert_always(mImageDecodeThread->isQuitting() || mImageDecodeThread->isStopped()) ; + delete mImageDecodeThread; mImageDecodeThread = NULL ; } } diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index e27b5caab7..15f20d1d34 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -5476,7 +5476,6 @@ void LLViewerWindow::stopGL(BOOL save_state) // Pause texture decode threads (will get unpaused during main loop) LLAppViewer::getTextureCache()->pause(); - LLAppViewer::getImageDecodeThread()->pause(); LLAppViewer::getTextureFetch()->pause(); gSky.destroyGL(); diff --git a/indra/test/test.cpp b/indra/test/test.cpp index bb48216b2b..28f25087ac 100644 --- a/indra/test/test.cpp +++ b/indra/test/test.cpp @@ -401,7 +401,7 @@ public: { // Per http://confluence.jetbrains.net/display/TCD65/Build+Script+Interaction+with+TeamCity#BuildScriptInteractionwithTeamCity-ServiceMessages std::string result; - BOOST_FOREACH(char c, str) + for (char c : str) { switch (c) { -- cgit v1.2.3 From 1e28b8d992e6f24f85fde5c86bf9824bf7c7d277 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 9 Jun 2022 17:03:28 -0400 Subject: SL-17483: Let one override keyword into your class... and all the rest require it, too. --- indra/newview/llviewertexture.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index f3bc9061a2..088d11538a 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -302,10 +302,10 @@ public: }; public: - /*virtual*/ S8 getType() const ; + /*virtual*/ S8 getType() const override ; FTType getFTType() const; - /*virtual*/ void forceImmediateUpdate() ; - /*virtual*/ void dump() ; + /*virtual*/ void forceImmediateUpdate() override; + /*virtual*/ void dump() override; // Set callbacks to get called when the image gets updated with higher // resolution versions. @@ -356,14 +356,14 @@ public: // Override the computation of discard levels if we know the exact output // size of the image. Used for UI textures to not decode, even if we have // more data. - /*virtual*/ void setKnownDrawSize(S32 width, S32 height); + /*virtual*/ void setKnownDrawSize(S32 width, S32 height) override; // Set the debug text of all Viewer Objects associated with this texture // to the specified text void setDebugText(const std::string& text); void setIsMissingAsset(BOOL is_missing = true); - /*virtual*/ BOOL isMissingAsset() const { return mIsMissingAsset; } + /*virtual*/ BOOL isMissingAsset() const override { return mIsMissingAsset; } // returns dimensions of original image for local files (before power of two scaling) // and returns 0 for all asset system images @@ -406,7 +406,7 @@ public: BOOL isRawImageValid()const { return mIsRawImageValid ; } void forceToSaveRawImage(S32 desired_discard = 0, F32 kept_time = 0.f) ; void forceToRefetchTexture(S32 desired_discard = 0, F32 kept_time = 60.f); - /*virtual*/ void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) ; + /*virtual*/ void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) override; void destroySavedRawImage() ; LLImageRaw* getSavedRawImage() ; BOOL hasSavedRawImage() const ; @@ -422,10 +422,10 @@ public: void setInFastCacheList(bool in_list) { mInFastCacheList = in_list; } bool isInFastCacheList() { return mInFastCacheList; } - /*virtual*/bool isActiveFetching(); //is actively in fetching by the fetching pipeline. + /*virtual*/bool isActiveFetching() override; //is actively in fetching by the fetching pipeline. protected: - /*virtual*/ void switchToCachedImage(); + /*virtual*/ void switchToCachedImage() override; S32 getCurrentDiscardLevelForFetching() ; private: -- cgit v1.2.3 From 64209ddeeafd944f82da6f13a6e790f9b542b3ff Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 9 Jun 2022 17:04:26 -0400 Subject: SL-17483: Add integration test for CommonControl and for LLViewerControlListener, to which it talks. Fix glitches detected by the tests. --- indra/llcommon/commoncontrol.cpp | 2 + indra/llcommon/threadpool.cpp | 43 +++-- indra/newview/CMakeLists.txt | 13 ++ .../newview/tests/llviewercontrollistener_test.cpp | 174 +++++++++++++++++++++ 4 files changed, 215 insertions(+), 17 deletions(-) create mode 100644 indra/newview/tests/llviewercontrollistener_test.cpp diff --git a/indra/llcommon/commoncontrol.cpp b/indra/llcommon/commoncontrol.cpp index 2c2a2abeb0..81e66baf8c 100644 --- a/indra/llcommon/commoncontrol.cpp +++ b/indra/llcommon/commoncontrol.cpp @@ -51,6 +51,8 @@ LLSD LL::CommonControl::access(const LLSD& params) { LLTHROW(ParamError(error)); } + response.erase("error"); + response.erase("reqid"); return response; } diff --git a/indra/llcommon/threadpool.cpp b/indra/llcommon/threadpool.cpp index e8daf549ef..f49dd40a8b 100644 --- a/indra/llcommon/threadpool.cpp +++ b/indra/llcommon/threadpool.cpp @@ -93,27 +93,36 @@ void LL::ThreadPool::run() //static size_t LL::ThreadPool::getConfiguredWidth(const std::string& name, size_t dft) { - LLSD poolSizes{ LL::CommonControl::get("Global", "ThreadPoolSizes") }; - // "ThreadPoolSizes" is actually a map containing the sizes of interest -- - // or should be, if this process has an "LLViewerControl" LLEventAPI - // instance and its settings include "ThreadPoolSizes". If we failed to - // retrieve it, perhaps we're in a program that doesn't define that, or - // perhaps there's no such setting, or perhaps we're asking too early, - // before the LLEventAPI itself has been instantiated. In any of those - // cases, it seems worth warning. - if (! poolSizes.isDefined()) + LLSD poolSizes; + try { - // Note: we don't warn about absence of an override key for a - // particular ThreadPool name, that's fine. This warning is about - // complete absence of a ThreadPoolSizes setting, which we expect in a - // normal viewer session. - LL_WARNS("ThreadPool") << "No 'ThreadPoolSizes' setting for ThreadPool '" - << name << "'" << LL_ENDL; + poolSizes = LL::CommonControl::get("Global", "ThreadPoolSizes"); + // "ThreadPoolSizes" is actually a map containing the sizes of + // interest -- or should be, if this process has an + // LLViewerControlListener instance and its settings include + // "ThreadPoolSizes". If we failed to retrieve it, perhaps we're in a + // program that doesn't define that, or perhaps there's no such + // setting, or perhaps we're asking too early, before the LLEventAPI + // itself has been instantiated. In any of those cases, it seems worth + // warning. + if (! poolSizes.isDefined()) + { + // Note: we don't warn about absence of an override key for a + // particular ThreadPool name, that's fine. This warning is about + // complete absence of a ThreadPoolSizes setting, which we expect + // in a normal viewer session. + LL_WARNS("ThreadPool") << "No 'ThreadPoolSizes' setting for ThreadPool '" + << name << "'" << LL_ENDL; + } } - else + catch (const LL::CommonControl::Error& exc) { - LL_DEBUGS("ThreadPool") << "ThreadPoolSizes = " << poolSizes << LL_ENDL; + // We don't want ThreadPool to *require* LLViewerControlListener. + // Just log it and carry on. + LL_WARNS("ThreadPool") << "Can't check 'ThreadPoolSizes': " << exc.what() << LL_ENDL; } + + LL_DEBUGS("ThreadPool") << "ThreadPoolSizes = " << poolSizes << LL_ENDL; // LLSD treats an undefined value as an empty map when asked to retrieve a // key, so we don't need this to be conditional. LLSD sizeSpec{ poolSizes[name] }; diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index c253eca94e..f13ce85495 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -2506,6 +2506,19 @@ if (LL_TESTS) "${test_libs}" ) + set(llviewercontrollistener_test_sources + llviewercontrollistener.cpp + ../llxml/llcontrol.cpp + ../llxml/llxmltree.cpp + ../llxml/llxmlparser.cpp + ../llcommon/commoncontrol.cpp + ) + + LL_ADD_INTEGRATION_TEST(llviewercontrollistener + "${llviewercontrollistener_test_sources}" + "${test_libs}" + ) + LL_ADD_INTEGRATION_TEST(llviewernetwork llviewernetwork.cpp "${test_libs}" diff --git a/indra/newview/tests/llviewercontrollistener_test.cpp b/indra/newview/tests/llviewercontrollistener_test.cpp new file mode 100644 index 0000000000..6d100ef984 --- /dev/null +++ b/indra/newview/tests/llviewercontrollistener_test.cpp @@ -0,0 +1,174 @@ +/** + * @file llviewercontrollistener_test.cpp + * @author Nat Goodspeed + * @date 2022-06-09 + * @brief Test for llviewercontrollistener. + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Copyright (c) 2022, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "llviewerprecompiledheaders.h" +// associated header +#include "llviewercontrollistener.h" +// STL headers +// std headers +// external library headers +// other Linden headers +#include "../test/lltut.h" +#include "../test/catch_and_store_what_in.h" // catch_what() +#include "commoncontrol.h" +#include "llcontrol.h" // LLControlGroup +#include "llviewercontrollistener.h" + +/***************************************************************************** +* TUT +*****************************************************************************/ +namespace tut +{ + void ensure_contains(const std::string& msg, const std::string& substr) + { + ensure_contains("Exception does not contain " + substr, msg, substr); + } + + struct llviewercontrollistener_data + { + LLControlGroup Global{"FakeGlobal"}; + + llviewercontrollistener_data() + { + Global.declareString("strvar", "woof", "string variable"); + // together we will stroll the boolvar, ma cherie + Global.declareBOOL("boolvar", TRUE, "bool variable"); + } + }; + typedef test_group llviewercontrollistener_group; + typedef llviewercontrollistener_group::object object; + llviewercontrollistener_group llviewercontrollistenergrp("llviewercontrollistener"); + + template<> template<> + void object::test<1>() + { + set_test_name("CommonControl no listener"); + // Not implemented: the linker drags in LLViewerControlListener when + // we bring in LLViewerControl. + } + + template<> template<> + void object::test<2>() + { + set_test_name("CommonControl bad group"); + std::string threw{ catch_what( + [](){ LL::CommonControl::get("Nonexistent", "Variable"); }) }; + ensure_contains(threw, "group"); + ensure_contains(threw, "Nonexistent"); + } + + template<> template<> + void object::test<3>() + { + set_test_name("CommonControl bad variable"); + std::string threw{ catch_what( + [](){ LL::CommonControl::get("FakeGlobal", "Nonexistent"); }) }; + ensure_contains(threw, "key"); + ensure_contains(threw, "Nonexistent"); + } + + template<> template<> + void object::test<4>() + { + set_test_name("CommonControl toggle string"); + std::string threw{ catch_what( + [](){ LL::CommonControl::toggle("FakeGlobal", "strvar"); }) }; + ensure_contains(threw, "non-boolean"); + ensure_contains(threw, "strvar"); + } + + template<> template<> + void object::test<5>() + { + set_test_name("CommonControl list bad group"); + std::string threw{ catch_what( + [](){ LL::CommonControl::get_vars("Nonexistent"); }) }; + ensure_contains(threw, "group"); + ensure_contains(threw, "Nonexistent"); + } + + template<> template<> + void object::test<6>() + { + set_test_name("CommonControl get"); + auto strvar{ LL::CommonControl::get("FakeGlobal", "strvar") }; + ensure_equals(strvar, "woof"); + auto boolvar{ LL::CommonControl::get("FakeGlobal", "boolvar") }; + ensure(boolvar); + } + + template<> template<> + void object::test<7>() + { + set_test_name("CommonControl set, set_default, toggle"); + + std::string newstr{ LL::CommonControl::set("FakeGlobal", "strvar", "mouse").asString() }; + ensure_equals(newstr, "mouse"); + ensure_equals(LL::CommonControl::get("FakeGlobal", "strvar").asString(), "mouse"); + ensure_equals(LL::CommonControl::set_default("FakeGlobal", "strvar").asString(), "woof"); + + bool newbool{ LL::CommonControl::set("FakeGlobal", "boolvar", false) }; + ensure(! newbool); + ensure(! LL::CommonControl::get("FakeGlobal", "boolvar").asBoolean()); + ensure(LL::CommonControl::set_default("FakeGlobal", "boolvar").asBoolean()); + ensure(! LL::CommonControl::toggle("FakeGlobal", "boolvar").asBoolean()); + } + + template<> template<> + void object::test<8>() + { + set_test_name("CommonControl get_def"); + LLSD def{ LL::CommonControl::get_def("FakeGlobal", "strvar") }; + ensure_equals( + def, + llsd::map("name", "strvar", + "type", "String", + "value", "woof", + "comment", "string variable")); + } + + template<> template<> + void object::test<9>() + { + set_test_name("CommonControl get_groups"); + std::vector groups{ LL::CommonControl::get_groups() }; + ensure_equals(groups.size(), 1); + ensure_equals(groups[0], "FakeGlobal"); + } + + template<> template<> + void object::test<10>() + { + set_test_name("CommonControl get_vars"); + LLSD vars{ LL::CommonControl::get_vars("FakeGlobal") }; + // convert from array (unpredictable order) to map + LLSD varsmap{ LLSD::emptyMap() }; + for (auto& var : llsd::inArray(vars)) + { + varsmap[var["name"].asString()] = var; + } + // comparing maps is order-insensitive + ensure_equals( + varsmap, + llsd::map( + "strvar", + llsd::map("name", "strvar", + "type", "String", + "value", "woof", + "comment", "string variable"), + "boolvar", + llsd::map("name", "boolvar", + "type", "Boolean", + "value", TRUE, + "comment", "bool variable"))); + } +} // namespace tut -- cgit v1.2.3 From 3b043d90b60eca17dfcc014b21c4c8fc5b432384 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 13 Jun 2022 15:18:14 -0400 Subject: SL-17483: Per review feedback, avoid LLPointer refcount twiddling when passing LLPointers into functions. Only increment the refcount when storing in new ImageRequest. --- indra/llimage/llimageworker.cpp | 17 +++++++++++------ indra/llimage/llimageworker.h | 4 ++-- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp index 3c21499673..0093958e6d 100644 --- a/indra/llimage/llimageworker.cpp +++ b/indra/llimage/llimageworker.cpp @@ -34,15 +34,17 @@ class ImageRequest { public: - ImageRequest(LLPointer image, + ImageRequest(const LLPointer& image, S32 discard, BOOL needs_aux, - LLPointer responder); + const LLPointer& responder); virtual ~ImageRequest(); /*virtual*/ bool processRequest(); /*virtual*/ void finishRequest(bool completed); private: + // LLPointers stored in ImageRequest MUST be LLPointer instances rather + // than references: we need to increment the refcount when storing these. // input LLPointer mFormattedImage; S32 mDiscardLevel; @@ -82,8 +84,11 @@ S32 LLImageDecodeThread::getPending() return mThreadPool->getQueue().size(); } -LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLPointer image, - S32 discard, BOOL needs_aux, LLPointer responder) +LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage( + const LLPointer& image, + S32 discard, + BOOL needs_aux, + const LLPointer& responder) { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; @@ -113,9 +118,9 @@ LLImageDecodeThread::Responder::~Responder() //---------------------------------------------------------------------------- -ImageRequest::ImageRequest(LLPointer image, +ImageRequest::ImageRequest(const LLPointer& image, S32 discard, BOOL needs_aux, - LLPointer responder) + const LLPointer& responder) : mFormattedImage(image), mDiscardLevel(discard), mNeedsAux(needs_aux), diff --git a/indra/llimage/llimageworker.h b/indra/llimage/llimageworker.h index 6a0b2b4681..18398d9ae2 100644 --- a/indra/llimage/llimageworker.h +++ b/indra/llimage/llimageworker.h @@ -52,9 +52,9 @@ public: // meant to resemble LLQueuedThread::handle_t typedef U32 handle_t; - handle_t decodeImage(LLPointer image, + handle_t decodeImage(const LLPointer& image, S32 discard, BOOL needs_aux, - LLPointer responder); + const LLPointer& responder); S32 getPending(); S32 update(F32 max_time_ms); void shutdown(); -- cgit v1.2.3 From 758a602f20340c5efde626fcace5a11133cfb859 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Mon, 13 Jun 2022 13:47:34 -0700 Subject: SL-17485 - mac getVramSize should return all vram, not just texture-specific, and use to compute getAvailableVRAMMegabytes. --- indra/llwindow/llopenglview-objc.mm | 7 ++++++- indra/llwindow/llwindowmacosx.cpp | 10 ++++++++++ indra/llwindow/llwindowmacosx.h | 3 +-- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm index fd20f2ad15..8d064ec86c 100644 --- a/indra/llwindow/llopenglview-objc.mm +++ b/indra/llwindow/llopenglview-objc.mm @@ -141,7 +141,12 @@ attributedStringInfo getSegments(NSAttributedString *str) CGLError the_err = CGLQueryRendererInfo (CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay), &info, &num_renderers); if(0 == the_err) { - CGLDescribeRenderer (info, 0, kCGLRPTextureMemoryMegabytes, &vram_megabytes); + // The name, uses, and other platform definitions of gGLManager.mVRAM suggest that this is supposed to be total vram in MB, + // rather than, say, just the texture memory. The two exceptions are: + // 1. LLAppViewer::getViewerInfo() puts the value in a field labeled "TEXTURE_MEMORY" + // 2. For years, this present function used kCGLRPTextureMemoryMegabytes + // Now we use kCGLRPVideoMemoryMegabytes to bring it in line with everything else (except thatone label). + CGLDescribeRenderer (info, 0, kCGLRPVideoMemoryMegabytes, &vram_megabytes); CGLDestroyRendererInfo (info); } else diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index bc4f07941b..4bcb9b3aef 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -1222,6 +1222,16 @@ F32 LLWindowMacOSX::getPixelAspectRatio() return 1.f; } +U32 LLWindowMacOSX::getAvailableVRAMMegabytes() { + // MTL (and MoltenVK) has some additional gpu data, such as recommendedMaxWorkingSetSize and currentAllocatedSize. + // But these are not available for OpenGL and/or our current mimimum OS version. + // So we will estimate. + static const U32 mb = 1024*1024; + // We're asked for total available gpu memory, but we only have allocation info on texture usage. So estimate by doubling that. + static const U32 total_factor = 2; // estimated total/textures + return gGLManager.mVRAM - (LLImageGL::getTextureBytesAllocated() * total_factor/mb); +} + //static SInt32 oldWindowLevel; // MBW -- XXX -- There's got to be a better way than this. Find it, please... diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h index 309d1377ea..0f316f1ddf 100644 --- a/indra/llwindow/llwindowmacosx.h +++ b/indra/llwindow/llwindowmacosx.h @@ -101,8 +101,7 @@ public: void setNativeAspectRatio(F32 ratio) override { mOverrideAspectRatio = ratio; } // query VRAM usage - // FIXME FIXME - virtual U32 getAvailableVRAMMegabytes() override { return 0; } + /*virtual*/ U32 getAvailableVRAMMegabytes() override; void beforeDialog() override; void afterDialog() override; -- cgit v1.2.3 From bdd76a6a1d0ee0fa5a8da76f1e8c8583822eeabe Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Mon, 13 Jun 2022 13:59:07 -0700 Subject: SL-17485 - Provide corrected missing memory data on mac: sAllocatedPageSizeInKB, sAllocatedMemInKB, sAvailPhysicalMemInKB, sMaxPhysicalMemInKB --- indra/llcommon/llmemory.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index 849867586a..267159e7cc 100644 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -35,6 +35,7 @@ # include # include # include +#include #elif LL_LINUX # include #endif @@ -46,6 +47,9 @@ #include "lltrace.h" #include "llerror.h" //---------------------------------------------------------------------------- +#if defined(LL_DARWIN) +extern LLMemoryInfo gSysMemory; +#endif //static U32Kilobytes LLMemory::sAvailPhysicalMemInKB(U32_MAX); @@ -109,6 +113,51 @@ void LLMemory::updateMemoryInfo() { sAvailPhysicalMemInKB = U32Kilobytes(0); } + +#elif defined(LL_DARWIN) + task_vm_info info; + mach_msg_type_number_t infoCount = TASK_VM_INFO_COUNT; + // MACH_TASK_BASIC_INFO reports the same resident_size, but does not tell us the reusable bytes or phys_footprint. + if (task_info(mach_task_self(), TASK_VM_INFO, reinterpret_cast(&info), &infoCount) == KERN_SUCCESS) + { + // Our Windows definition of PagefileUsage is documented by Microsoft as "the total amount of + // memory that the memory manager has committed for a running process", which is rss. + sAllocatedPageSizeInKB = U32Bytes(info.resident_size); + + // Activity Monitor => Inspect Process => Real Memory Size appears to report resident_size + // Activity monitor => main window memory column appears to report phys_footprint, which spot checks as at least 30% less. + // I think that is because of compression, which isn't going to give us a consistent measurement. We want uncompressed totals. + // + // In between is resident_size - reusable. This is what Chrome source code uses, with source comments saying it is 'the "Real Memory" value + // reported for the app by the Memory Monitor in Instruments.' It is still about 8% bigger than phys_footprint. + // + // (On Windows, we use WorkingSetSize.) + sAllocatedMemInKB = U32Bytes(info.resident_size - info.reusable); + } + else + { + LL_WARNS() << "task_info failed" << LL_ENDL; + } + + // Total installed and available physical memory are properties of the host, not just our process. + vm_statistics64_data_t vmstat; + mach_msg_type_number_t count = HOST_VM_INFO64_COUNT; + mach_port_t host = mach_host_self(); + vm_size_t page_size; + host_page_size(host, &page_size); + kern_return_t result = host_statistics64(host, HOST_VM_INFO64, reinterpret_cast(&vmstat), &count); + if (result == KERN_SUCCESS) { + // This is what Chrome reports as 'the "Physical Memory Free" value reported by the Memory Monitor in Instruments.' + // Note though that inactive pages are not included here and not yet free, but could become so under memory pressure. + sAvailPhysicalMemInKB = U32Bytes(vmstat.free_count * page_size); + + sMaxPhysicalMemInKB = gSysMemory.getPhysicalMemoryKB(); + } + else + { + LL_WARNS() << "task_info failed" << LL_ENDL; + } + #else //not valid for other systems for now. sAllocatedMemInKB = U64Bytes(LLMemory::getCurrentRSS()); -- cgit v1.2.3 From 91a9665e35a3bfeb5a2bc81586a23e70bb2c7596 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Mon, 13 Jun 2022 14:00:13 -0700 Subject: SL-17485 - Make mac compiler happier. --- indra/cmake/00-Common.cmake | 2 +- indra/newview/llviewertexture.cpp | 2 +- indra/newview/llviewertexture.h | 16 ++++++++-------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index bb5dd8f847..3e672cb128 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -201,7 +201,7 @@ if (LINUX OR DARWIN) endif() if (NOT GCC_DISABLE_FATAL_WARNINGS) - set(GCC_WARNINGS "${GCC_WARNINGS} -Werror") + set(GCC_WARNINGS "${GCC_WARNINGS} -Werror -Wno-error=unused-but-set-variable") endif (NOT GCC_DISABLE_FATAL_WARNINGS) set(GCC_CXX_WARNINGS "${GCC_WARNINGS} -Wno-reorder -Wno-non-virtual-dtor") diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 16b07159ba..a6e7b01df7 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -524,7 +524,7 @@ void LLViewerTexture::getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &p { gpu_res = (S32Megabytes)gViewerWindow->getWindow()->getAvailableVRAMMegabytes(); - //check main memory, only works for windows. + //check main memory, only works for windows and macos. LLMemory::updateMemoryInfo(); physical_res = LLMemory::getAvailableMemKB(); diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index f3bc9061a2..8c41c4a6bc 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -302,10 +302,10 @@ public: }; public: - /*virtual*/ S8 getType() const ; + /*virtual*/ S8 getType() const override; FTType getFTType() const; - /*virtual*/ void forceImmediateUpdate() ; - /*virtual*/ void dump() ; + /*virtual*/ void forceImmediateUpdate() override; + /*virtual*/ void dump() override; // Set callbacks to get called when the image gets updated with higher // resolution versions. @@ -356,14 +356,14 @@ public: // Override the computation of discard levels if we know the exact output // size of the image. Used for UI textures to not decode, even if we have // more data. - /*virtual*/ void setKnownDrawSize(S32 width, S32 height); + /*virtual*/ void setKnownDrawSize(S32 width, S32 height) override; // Set the debug text of all Viewer Objects associated with this texture // to the specified text void setDebugText(const std::string& text); void setIsMissingAsset(BOOL is_missing = true); - /*virtual*/ BOOL isMissingAsset() const { return mIsMissingAsset; } + /*virtual*/ BOOL isMissingAsset() const override { return mIsMissingAsset; } // returns dimensions of original image for local files (before power of two scaling) // and returns 0 for all asset system images @@ -406,7 +406,7 @@ public: BOOL isRawImageValid()const { return mIsRawImageValid ; } void forceToSaveRawImage(S32 desired_discard = 0, F32 kept_time = 0.f) ; void forceToRefetchTexture(S32 desired_discard = 0, F32 kept_time = 60.f); - /*virtual*/ void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) ; + /*virtual*/ void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) override; void destroySavedRawImage() ; LLImageRaw* getSavedRawImage() ; BOOL hasSavedRawImage() const ; @@ -422,10 +422,10 @@ public: void setInFastCacheList(bool in_list) { mInFastCacheList = in_list; } bool isInFastCacheList() { return mInFastCacheList; } - /*virtual*/bool isActiveFetching(); //is actively in fetching by the fetching pipeline. + /*virtual*/bool isActiveFetching() override; //is actively in fetching by the fetching pipeline. protected: - /*virtual*/ void switchToCachedImage(); + /*virtual*/ void switchToCachedImage() override; S32 getCurrentDiscardLevelForFetching() ; private: -- cgit v1.2.3 From 2037e4008098e884d2b136b9ac24304f880288ed Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Fri, 17 Jun 2022 10:40:52 -0700 Subject: SL-17485-a - remove xcode compiler flag not supported on current teamcity build host --- indra/cmake/00-Common.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index 3e672cb128..bb5dd8f847 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -201,7 +201,7 @@ if (LINUX OR DARWIN) endif() if (NOT GCC_DISABLE_FATAL_WARNINGS) - set(GCC_WARNINGS "${GCC_WARNINGS} -Werror -Wno-error=unused-but-set-variable") + set(GCC_WARNINGS "${GCC_WARNINGS} -Werror") endif (NOT GCC_DISABLE_FATAL_WARNINGS) set(GCC_CXX_WARNINGS "${GCC_WARNINGS} -Wno-reorder -Wno-non-virtual-dtor") -- cgit v1.2.3 From 33fe18c335375ecdaf57ddd0138fc7a6cb227843 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Fri, 17 Jun 2022 16:29:39 -0700 Subject: SL-17485-b - Attempt to make teamcity builds happy by not referencing a newview global from an llcommon file. --- indra/llcommon/llmemory.cpp | 6 +----- indra/llcommon/llsys.cpp | 24 ++++++++++++++++-------- indra/llcommon/llsys.h | 5 ++++- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index 267159e7cc..749b66b472 100644 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -47,9 +47,6 @@ #include "lltrace.h" #include "llerror.h" //---------------------------------------------------------------------------- -#if defined(LL_DARWIN) -extern LLMemoryInfo gSysMemory; -#endif //static U32Kilobytes LLMemory::sAvailPhysicalMemInKB(U32_MAX); @@ -150,8 +147,7 @@ void LLMemory::updateMemoryInfo() // This is what Chrome reports as 'the "Physical Memory Free" value reported by the Memory Monitor in Instruments.' // Note though that inactive pages are not included here and not yet free, but could become so under memory pressure. sAvailPhysicalMemInKB = U32Bytes(vmstat.free_count * page_size); - - sMaxPhysicalMemInKB = gSysMemory.getPhysicalMemoryKB(); + sMaxPhysicalMemInKB = LLMemoryInfo::getHardwareMemSize(); } else { diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index f717b2cf34..aeb6ae1b0a 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -684,20 +684,28 @@ static U32Kilobytes LLMemoryAdjustKBResult(U32Kilobytes inKB) } #endif +#if LL_DARWIN +// static +U32Kilobytes LLMemoryInfo::getHardwareMemSize() +{ + // This might work on Linux as well. Someone check... + uint64_t phys = 0; + int mib[2] = { CTL_HW, HW_MEMSIZE }; + + size_t len = sizeof(phys); + sysctl(mib, 2, &phys, &len, NULL, 0); + + return U64Bytes(phys); +} +#endif + U32Kilobytes LLMemoryInfo::getPhysicalMemoryKB() const { #if LL_WINDOWS return LLMemoryAdjustKBResult(U32Kilobytes(mStatsMap["Total Physical KB"].asInteger())); #elif LL_DARWIN - // This might work on Linux as well. Someone check... - uint64_t phys = 0; - int mib[2] = { CTL_HW, HW_MEMSIZE }; - - size_t len = sizeof(phys); - sysctl(mib, 2, &phys, &len, NULL, 0); - - return U64Bytes(phys); + return getHardwareMemSize(); #elif LL_LINUX U64 phys = 0; diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h index 5ab97939b9..b2f9b6a4ab 100644 --- a/indra/llcommon/llsys.h +++ b/indra/llcommon/llsys.h @@ -113,7 +113,10 @@ public: LLMemoryInfo(); ///< Default constructor void stream(std::ostream& s) const; ///< output text info to s - U32Kilobytes getPhysicalMemoryKB() const; + U32Kilobytes getPhysicalMemoryKB() const; +#if LL_DARWIN + static U32Kilobytes getHardwareMemSize(); // Because some Mac linkers won't let us reference extern gSysMemory from a different lib. +#endif //get the available memory infomation in KiloBytes. static void getAvailableMemoryKB(U32Kilobytes& avail_physical_mem_kb, U32Kilobytes& avail_virtual_mem_kb); -- cgit v1.2.3 From 47ee4aff475e5086bc532acf1b79a86adcb70d73 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 9 Aug 2022 11:34:09 -0700 Subject: SL-17005: Fix crash in initDX when no factory --- indra/llwindow/llwindowwin32.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 20443988ab..6e5c1e504a 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -4619,7 +4619,10 @@ void LLWindowWin32::LLWindowWin32Thread::initDX() } } - pFactory->Release(); + if (pFactory) + { + pFactory->Release(); + } } } -- cgit v1.2.3 From eac4540fc359b1390c8828f92c5ba75d44fd1308 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 9 Aug 2022 11:48:51 -0700 Subject: SL-17005: (WIP) (DEBUG) Add logging for graphics adapters --- indra/llwindow/llwindowwin32.cpp | 67 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 6e5c1e504a..9e7ea15cd7 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -4598,10 +4598,77 @@ private: std::string mPrev; }; +// Print hardware debug info about available graphics adapters in ordinal order +void debugEnumerateGraphicsAdapters() +{ + LL_INFOS("Window") << "Enumerating graphics adapters..." << LL_ENDL; + + IDXGIFactory1* factory; + HRESULT res = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&factory); + if (FAILED(res) || !factory) + { + LL_WARNS() << "CreateDXGIFactory1 failed: 0x" << std::hex << res << LL_ENDL; + } + else + { + UINT graphics_adapter_index = 0; + IDXGIAdapter3* dxgi_adapter; + while (true) + { + res = factory->EnumAdapters(graphics_adapter_index, reinterpret_cast(&dxgi_adapter)); + if (FAILED(res)) + { + if (graphics_adapter_index == 0) + { + LL_WARNS() << "EnumAdapters failed: 0x" << std::hex << res << LL_ENDL; + } + else + { + LL_INFOS("Window") << "Done enumerating graphics adapters" << LL_ENDL; + } + } + else + { + DXGI_ADAPTER_DESC desc; + dxgi_adapter->GetDesc(&desc); + std::wstring description_w((wchar_t*)desc.Description); + std::string description(description_w.begin(), description_w.end()); + LL_INFOS("Window") << "Graphics adapter index: " << graphics_adapter_index << ", " + << "Description: " << description << ", " + << "DeviceId: " << desc.DeviceId << ", " + << "SubSysId: " << desc.SubSysId << ", " + << "AdapterLuid: " << desc.AdapterLuid.HighPart << "_" << desc.AdapterLuid.LowPart << ", " + << "DedicatedVideoMemory: " << desc.DedicatedVideoMemory / 1024 / 1024 << ", " + << "DedicatedSystemMemory: " << desc.DedicatedSystemMemory / 1024 / 1024 << ", " + << "SharedSystemMemory: " << desc.SharedSystemMemory / 1024 / 1024 << LL_ENDL; + } + + if (dxgi_adapter) + { + dxgi_adapter->Release(); + dxgi_adapter = NULL; + } + else + { + break; + } + + graphics_adapter_index++; + } + } + + if (factory) + { + factory->Release(); + } +} + void LLWindowWin32::LLWindowWin32Thread::initDX() { if (mDXGIAdapter == NULL) { + debugEnumerateGraphicsAdapters(); + IDXGIFactory4* pFactory = nullptr; HRESULT res = CreateDXGIFactory1(__uuidof(IDXGIFactory4), (void**)&pFactory); -- cgit v1.2.3 From c790bf7f49328b479f1bcbfe0268ca0bec6e2376 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Thu, 11 Aug 2022 11:10:25 -0700 Subject: SL-17005: (WIP) (Debug) Add logging and debug settings to assist in understanding Windows 8 failure modes. Most of this should be removed later --- indra/llwindow/llwindowwin32.cpp | 32 +++++++++++++++++++++++++++++--- indra/newview/app_settings/settings.xml | 23 +++++++++++++++++++++++ indra/newview/pipeline.cpp | 4 ++++ 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 9e7ea15cd7..9e2e07102e 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -48,6 +48,8 @@ #include "llthreadsafequeue.h" #include "stringize.h" #include "llframetimer.h" +#include "commoncontrol.h" // TODO: Remove after testing +#include "llsd.h" // TODO: Remove after testing // System includes #include @@ -416,7 +418,9 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool std::atomic mAvailableVRAM; + bool mTryUseDXGIAdapter; // TODO: Remove after testing IDXGIAdapter3* mDXGIAdapter = nullptr; + bool mTryUseD3DDevice; // TODO: Remove after testing LPDIRECT3D9 mD3D = nullptr; LPDIRECT3DDEVICE9 mD3DDevice = nullptr; }; @@ -4549,6 +4553,14 @@ U32 LLWindowWin32::getAvailableVRAMMegabytes() inline LLWindowWin32::LLWindowWin32Thread::LLWindowWin32Thread() : ThreadPool("Window Thread", 1, MAX_QUEUE_SIZE) { + const LLSD skipDXGI{ LL::CommonControl::get("Global", "DisablePrimaryGraphicsMemoryAccounting") }; // TODO: Remove after testing + LL_WARNS() << "DisablePrimaryGraphicsMemoryAccounting: " << skipDXGI << ", as boolean: " << skipDXGI.asBoolean() << LL_ENDL; + mTryUseDXGIAdapter = !skipDXGI.asBoolean(); + LL_WARNS() << "mTryUseDXGIAdapter: " << mTryUseDXGIAdapter << LL_ENDL; + const LLSD skipD3D{ LL::CommonControl::get("Global", "DisableSecondaryGraphicsMemoryAccounting") }; // TODO: Remove after testing + LL_WARNS() << "DisableSecondaryGraphicsMemoryAccounting: " << skipD3D << ", as boolean: " << skipD3D.asBoolean() << LL_ENDL; + mTryUseD3DDevice = !skipD3D.asBoolean(); + LL_WARNS() << "mTryUseD3DDevice: " << mTryUseD3DDevice << LL_ENDL; ThreadPool::start(); } @@ -4665,7 +4677,7 @@ void debugEnumerateGraphicsAdapters() void LLWindowWin32::LLWindowWin32Thread::initDX() { - if (mDXGIAdapter == NULL) + if (mDXGIAdapter == NULL && mTryUseDXGIAdapter) { debugEnumerateGraphicsAdapters(); @@ -4684,6 +4696,10 @@ void LLWindowWin32::LLWindowWin32Thread::initDX() { LL_WARNS() << "EnumAdapters failed: 0x" << std::hex << res << LL_ENDL; } + else + { + LL_INFOS() << "EnumAdapters success" << LL_ENDL; + } } if (pFactory) @@ -4695,7 +4711,7 @@ void LLWindowWin32::LLWindowWin32Thread::initDX() void LLWindowWin32::LLWindowWin32Thread::initD3D() { - if (mDXGIAdapter == NULL && mD3DDevice == NULL && mWindowHandle != 0) + if (mDXGIAdapter == NULL && mD3DDevice == NULL && mTryUseD3DDevice && mWindowHandle != 0) { mD3D = Direct3DCreate9(D3D_SDK_VERSION); @@ -4705,7 +4721,16 @@ void LLWindowWin32::LLWindowWin32Thread::initD3D() d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; - mD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, mWindowHandle, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &mD3DDevice); + HRESULT res = mD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, mWindowHandle, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &mD3DDevice); + + if (FAILED(res)) + { + LL_WARNS() << "(fallback) CreateDevice failed: 0x" << std::hex << res << LL_ENDL; + } + else + { + LL_INFOS() << "(fallback) CreateDevice success" << LL_ENDL; + } } } @@ -4768,6 +4793,7 @@ void LLWindowWin32::LLWindowWin32Thread::run() if (mWindowHandle != 0) { // lazily call initD3D inside this loop to catch when mWindowHandle has been set + // *TODO: Shutdown if this fails when mWindowHandle exists initD3D(); MSG msg; diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index bc4945eca5..afa8217af2 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -3387,6 +3387,29 @@ Value 0 + + DisablePrimaryGraphicsMemoryAccounting + + Comment + Disable the first method used to detect GPU memory use + Persist + 1 + Type + Boolean + Value + 0 + + DisableSecondaryGraphicsMemoryAccounting + + Comment + Disable the second method used to detect GPU memory use, used as a fallback when the first method fails + Persist + 1 + Type + Boolean + Value + 0 + DisableTextHyperlinkActions Comment diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 9ec3418132..d4e667bcc6 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -434,6 +434,7 @@ void LLPipeline::connectRefreshCachedSettingsSafe(const std::string name) void LLPipeline::init() { + LL_WARNS() << "Begin pipeline initialization" << LL_ENDL; // TODO: Remove after testing refreshCachedSettings(); gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity"); @@ -450,6 +451,7 @@ void LLPipeline::init() mInitialized = true; stop_glerror(); + LL_WARNS() << "No GL errors yet. Pipeline initialization will continue." << LL_ENDL; // TODO: Remove after testing //create render pass pools getPool(LLDrawPool::POOL_ALPHA); @@ -510,7 +512,9 @@ void LLPipeline::init() // Enable features + LL_WARNS() << "Shader initialization start" << LL_ENDL; // TODO: Remove after testing LLViewerShaderMgr::instance()->setShaders(); + LL_WARNS() << "Shader initialization end" << LL_ENDL; // TODO: Remove after testing stop_glerror(); -- cgit v1.2.3 From 9bee2a92d2eb1f48f8ca0061e546c5e9df38fe79 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 26 Aug 2022 10:51:42 -0500 Subject: SL-17997 Follow up from beta breakers results. --- indra/llrender/llimagegl.cpp | 17 ------------- indra/llrender/llimagegl.h | 5 +++- indra/llwindow/llwindowwin32.cpp | 55 +++++++++++++++++++++++++++++----------- 3 files changed, 44 insertions(+), 33 deletions(-) diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index ae10142e7a..7ba0cc2fde 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -54,7 +54,6 @@ const F32 MIN_TEXTURE_LIFETIME = 10.f; U32 wpo2(U32 i); -#if LL_DARWIN // texture memory accounting (for OS X) static LLMutex sTexMemMutex; static std::unordered_map sTextureAllocs; @@ -119,22 +118,6 @@ U64 LLImageGL::getTextureBytesAllocated() return sTextureBytes; } -#else - -#define alloc_tex_image(width, height, pixformat) (void) width; (void) height; (void) pixformat; -#define free_tex_image(texName) (void) texName; -#define free_tex_images(count, texNames) (void) count; (void) texNames; -#define free_cur_tex_image() - -// static -U64 LLImageGL::getTextureBytesAllocated() -{ - // UNIMPLEMENTED OUTSIDE OF OS X, DO NOT CALL - llassert(false); - return 0; -} -#endif - //statics U32 LLImageGL::sUniqueCount = 0; diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 619421e68a..1bcdd040e0 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -53,7 +53,10 @@ class LLImageGL : public LLRefCount friend class LLTexUnit; public: - // For OS X use only -- get an estimate of how many bytes have been allocated in vram for textures + // Get an estimate of how many bytes have been allocated in vram for textures. + // Does not include mipmaps. + // NOTE: multiplying this number by two gives a good estimate for total + // video memory usage based on testing in lagland against an NVIDIA GPU. static U64 getTextureBytesAllocated(); // These 2 functions replace glGenTextures() and glDeleteTextures() diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 20443988ab..656439e71e 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -414,6 +414,7 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool HWND mWindowHandle = NULL; HDC mhDC = 0; + // best guess at available video memory in MB std::atomic mAvailableVRAM; IDXGIAdapter3* mDXGIAdapter = nullptr; @@ -4644,44 +4645,68 @@ void LLWindowWin32::LLWindowWin32Thread::updateVRAMUsage() LL_PROFILE_ZONE_SCOPED; if (mDXGIAdapter != nullptr) { + // NOTE: what lies below is hand wavy math based on compatibility testing and observation against a variety of hardware + // It doesn't make sense, but please don't refactor it to make sense. -- davep + DXGI_QUERY_VIDEO_MEMORY_INFO info; mDXGIAdapter->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_LOCAL, &info); - // try to use no more than the available reserve minus 10% - U32 target = info.Budget / 1024 / 1024; +#if 0 // debug 0 budget and 0 CU + info.Budget = 0; + info.CurrentUsage = 0; +#endif + + U32 budget_mb = info.Budget / 1024 / 1024; + U32 afr_mb = info.AvailableForReservation / 1024 / 1024; + // correct for systems that misreport budget + if (budget_mb == 0) + { + // fall back to available for reservation clamped between 512MB and 2GB + budget_mb = llclamp(afr_mb, (U32) 512, (U32) 2048); + } + + U32 cu_mb = info.CurrentUsage / 1024 / 1024; + + // get an estimated usage based on texture bytes allocated + U32 eu_mb = LLImageGL::getTextureBytesAllocated() * 2 / 1024 / 1024; - // EXPERIMENTAL - // Trying to zero in on a good target usage, code here should be tuned against observed behavior - // of various hardware. - if (target > 4096) // if 4GB are installed, try to leave 2GB free + if (cu_mb == 0) + { // current usage is sometimes unreliable on Intel GPUs, fall back to estimated usage + cu_mb = llmax((U32)1, eu_mb); + } + F32 eu_error = (F32)((S32)eu_mb - (S32)cu_mb) / (F32)cu_mb; + + U32 target_mb = info.Budget / 1024 / 1024; + + if (target_mb > 4096) // if 4GB are installed, try to leave 2GB free { - target -= 2048; + target_mb -= 2048; } else // if less than 4GB are installed, try not to use more than half of it { - target /= 2; + target_mb /= 2; } - U32 used_vram = info.CurrentUsage / 1024 / 1024; - - mAvailableVRAM = used_vram < target ? target - used_vram : 0; + mAvailableVRAM = cu_mb < target_mb ? target_mb - cu_mb : 0; LL_INFOS("Window") << "\nLocal\nAFR: " << info.AvailableForReservation / 1024 / 1024 << "\nBudget: " << info.Budget / 1024 / 1024 << "\nCR: " << info.CurrentReservation / 1024 / 1024 - << "\nCU: " << info.CurrentUsage / 1024 / 1024 << LL_ENDL; + << "\nCU: " << info.CurrentUsage / 1024 / 1024 + << "\nEU: " << eu_mb << llformat(" (%.2f)", eu_error) + << "\nTU: " << target_mb + << "\nAM: " << mAvailableVRAM << LL_ENDL; - mDXGIAdapter->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL, &info); + /*mDXGIAdapter->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL, &info); LL_INFOS("Window") << "\nNon-Local\nAFR: " << info.AvailableForReservation / 1024 / 1024 << "\nBudget: " << info.Budget / 1024 / 1024 << "\nCR: " << info.CurrentReservation / 1024 / 1024 - << "\nCU: " << info.CurrentUsage / 1024 / 1024 << LL_ENDL; + << "\nCU: " << info.CurrentUsage / 1024 / 1024 << LL_ENDL;*/ } else if (mD3DDevice != NULL) { // fallback to D3D9 mAvailableVRAM = mD3DDevice->GetAvailableTextureMem() / 1024 / 1024; } - } void LLWindowWin32::LLWindowWin32Thread::run() -- cgit v1.2.3 From 71ae65ae175a33c7f60442f62b0ef59415528bf5 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Mon, 29 Aug 2022 14:06:48 -0700 Subject: SL-17703: PBR: Fix missing ORM to use 1,0,0 --- indra/newview/lldrawpoolpbropaque.cpp | 2 +- indra/newview/llviewertexture.cpp | 11 ++++++++++- indra/newview/llviewertexture.h | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/indra/newview/lldrawpoolpbropaque.cpp b/indra/newview/lldrawpoolpbropaque.cpp index 3930e11cf3..35beafaa40 100644 --- a/indra/newview/lldrawpoolpbropaque.cpp +++ b/indra/newview/lldrawpoolpbropaque.cpp @@ -120,7 +120,7 @@ void LLDrawPoolPBROpaque::renderDeferred(S32 pass) } else { - shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep); + shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerTexture::sDefaultPBRORMImagep); // ORM 1,0,0 } if (pparams->mEmissiveMap) diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index c389d2122e..3ecab2c647 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -69,6 +69,7 @@ const S32Megabytes gMaxVideoRam(512); LLPointer LLViewerTexture::sNullImagep = NULL; LLPointer LLViewerTexture::sBlackImagep = NULL; LLPointer LLViewerTexture::sCheckerBoardImagep = NULL; +LLPointer LLViewerTexture::sDefaultPBRORMImagep = NULL; // PBR: When ORM is missing use 1,0,0 LLPointer LLViewerFetchedTexture::sMissingAssetImagep = NULL; LLPointer LLViewerFetchedTexture::sWhiteImagep = NULL; LLPointer LLViewerFetchedTexture::sDefaultImagep = NULL; @@ -367,6 +368,13 @@ void LLViewerTextureManager::init() LLViewerTexture::sNullImagep = LLViewerTextureManager::getLocalTexture(raw.get(), TRUE); } + // Create Default PBR ORM Texture 1,0,0 + { + LLPointer red = new LLImageRaw(8,8,3); + red->clear(0xFF, 0x00, 0x00, 0xFF); + LLViewerTexture::sDefaultPBRORMImagep = LLViewerTextureManager::getLocalTexture(red.get(), TRUE); + } + const S32 dim = 128; LLPointer image_raw = new LLImageRaw(dim,dim,3); U8* data = image_raw->getData(); @@ -451,8 +459,9 @@ void LLViewerTextureManager::cleanup() LLImageGL::sDefaultGLTexture = NULL; LLViewerTexture::sNullImagep = NULL; LLViewerTexture::sBlackImagep = NULL; + LLViewerFetchedTexture::sDefaultPBRORMImagep = NULL; LLViewerTexture::sCheckerBoardImagep = NULL; - LLViewerFetchedTexture::sDefaultImagep = NULL; + LLViewerFetchedTexture::sDefaultImagep = NULL; LLViewerFetchedTexture::sSmokeImagep = NULL; LLViewerFetchedTexture::sMissingAssetImagep = NULL; LLTexUnit::sWhiteTexture = 0; diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index 53cf911102..89ded4ded7 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -252,6 +252,7 @@ public: static LLPointer sNullImagep; // Null texture for non-textured objects. static LLPointer sBlackImagep; // Texture to show NOTHING (pure black) static LLPointer sCheckerBoardImagep; // Texture to show NOTHING (pure black) + static LLPointer sDefaultPBRORMImagep; // PBR: When ORM is missing use 1,0,0 }; -- cgit v1.2.3 From 826bd47cc1355844dea7cfc838ba5f685b91251e Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Mon, 29 Aug 2022 14:08:27 -0700 Subject: SL-17703: PBR: Fix default OMR if pbr shader compiled sans HAS_SPECULAR_MAP --- .../app_settings/shaders/class1/deferred/pbropaqueF.glsl | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl index 87c1ff5517..b5c38bba04 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl @@ -104,15 +104,16 @@ void main() tnorm = normalize(tnorm.xyz); norm.xyz = normalize(tnorm.xyz); + // RGB = Occlusion, Roughness, Metal - // default values - // occlusion ? - // roughness 1.0 - // metal 1.0 + // default values, see LLViewerTexture::sDefaultPBRORMImagep + // occlusion 1.0 + // roughness 0.0 + // metal 0.0 #ifdef HAS_SPECULAR_MAP vec3 spec = texture2D(specularMap, vary_texcoord2.xy).rgb; #else - vec3 spec = vec3(1,1,1); + vec3 spec = vec3(1,0,0); #endif spec.g *= roughnessFactor; -- cgit v1.2.3 From 9c6b197b3eacabb21ba098b7d1f6017f3de34432 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 29 Aug 2022 18:46:48 -0500 Subject: SL-18037 Workaround AMD driver bug (drop reflection probe count to 16 on amd) --- indra/newview/app_settings/settings.xml | 11 ++++++++ indra/newview/featuretable.txt | 6 +++- indra/newview/llreflectionmapmanager.cpp | 47 ++++++++++++++++++-------------- indra/newview/llreflectionmapmanager.h | 10 +++++-- 4 files changed, 51 insertions(+), 23 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 8a86faa18d..0d1870903b 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10313,6 +10313,17 @@ Value 1 + RenderReflectionProbeCount + + Comment + Number of reflection probes (maximum is 256, requires restart) + Persist + 1 + Type + S32 + Value + 256 + RenderReflectionProbeDrawDistance diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index ec8605aa5c..3269158903 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -1,4 +1,4 @@ -version 35 +version 36 // The version number above should be incremented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended @@ -64,6 +64,7 @@ RenderTextureMemoryMultiple 1 1.0 RenderCompressTextures 1 1 RenderShaderLightingMaxLevel 1 3 RenderPBR 1 1 +RenderReflectionProbeCount 1 256 RenderDeferred 1 1 RenderDeferredSSAO 1 1 RenderUseAdvancedAtmospherics 1 0 @@ -291,8 +292,11 @@ RenderGLContextCoreProfile 1 0 // AMD cards generally perform better when not using VBOs for streaming data // AMD cards also prefer an OpenGL Compatibility Profile Context +// HACK: Current AMD drivers have bugged cubemap arrays, limit number of reflection probes to 16 list AMD RenderUseStreamVBO 1 0 RenderGLContextCoreProfile 1 0 +RenderReflectionProbeCount 1 16 + diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 583c6de77b..b285cc531e 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -40,7 +40,7 @@ extern BOOL gTeleportDisplay; LLReflectionMapManager::LLReflectionMapManager() { - for (int i = 0; i < LL_REFLECTION_PROBE_COUNT; ++i) + for (int i = 0; i < LL_MAX_REFLECTION_PROBE_COUNT; ++i) { mCubeFree[i] = true; } @@ -76,16 +76,7 @@ void LLReflectionMapManager::update() } // =============== TODO -- move to an init function ================= - - if (mTexture.isNull()) - { - mTexture = new LLCubeMapArray(); - // store LL_REFLECTION_PROBE_COUNT+2 cube maps, final two cube maps are used for render target and radiance map generation source) - mTexture->allocate(LL_REFLECTION_PROBE_RESOLUTION, 3, LL_REFLECTION_PROBE_COUNT+2); - - mIrradianceMaps = new LLCubeMapArray(); - mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, LL_REFLECTION_PROBE_COUNT); - } + initReflectionMaps(); if (!mRenderTarget.isComplete()) { @@ -167,7 +158,7 @@ void LLReflectionMapManager::update() LLVector4a d; if (!did_update && - i < LL_REFLECTION_PROBE_COUNT && + i < mReflectionProbeCount && (oldestProbe == nullptr || probe->mLastUpdateTime < oldestProbe->mLastUpdateTime)) { oldestProbe = probe; @@ -317,7 +308,7 @@ LLReflectionMap* LLReflectionMapManager::registerViewerObject(LLViewerObject* vo S32 LLReflectionMapManager::allocateCubeIndex() { - for (int i = 0; i < LL_REFLECTION_PROBE_COUNT; ++i) + for (int i = 0; i < mReflectionProbeCount; ++i) { if (mCubeFree[i]) { @@ -327,7 +318,7 @@ S32 LLReflectionMapManager::allocateCubeIndex() } // no cubemaps free, steal one from the back of the probe list - for (int i = mProbes.size() - 1; i >= LL_REFLECTION_PROBE_COUNT; --i) + for (int i = mProbes.size() - 1; i >= mReflectionProbeCount; --i) { if (mProbes[i]->mCubeIndex != -1) { @@ -392,7 +383,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) gPipeline.mRT = &gPipeline.mMainRT; mRenderTarget.flush(); - S32 targetIdx = LL_REFLECTION_PROBE_COUNT; + S32 targetIdx = mReflectionProbeCount; if (probe != mUpdatingProbe) { // this is the "realtime" probe that's updating every frame, use the secondary scratch space channel @@ -625,15 +616,15 @@ void LLReflectionMapManager::updateUniforms() // see class3/deferred/reflectionProbeF.glsl struct ReflectionProbeData { - LLMatrix4 refBox[LL_REFLECTION_PROBE_COUNT]; // object bounding box as needed - LLVector4 refSphere[LL_REFLECTION_PROBE_COUNT]; //origin and radius of refmaps in clip space - LLVector4 refParams[LL_REFLECTION_PROBE_COUNT]; //extra parameters (currently only ambiance) - GLint refIndex[LL_REFLECTION_PROBE_COUNT][4]; + LLMatrix4 refBox[LL_MAX_REFLECTION_PROBE_COUNT]; // object bounding box as needed + LLVector4 refSphere[LL_MAX_REFLECTION_PROBE_COUNT]; //origin and radius of refmaps in clip space + LLVector4 refParams[LL_MAX_REFLECTION_PROBE_COUNT]; //extra parameters (currently only ambiance) + GLint refIndex[LL_MAX_REFLECTION_PROBE_COUNT][4]; GLint refNeighbor[4096]; GLint refmapCount; }; - mReflectionMaps.resize(LL_REFLECTION_PROBE_COUNT); + mReflectionMaps.resize(mReflectionProbeCount); getReflectionMaps(mReflectionMaps); ReflectionProbeData rpd; @@ -830,3 +821,19 @@ void LLReflectionMapManager::renderDebug() gDebugProgram.unbind(); } + +void LLReflectionMapManager::initReflectionMaps() +{ + if (mTexture.isNull()) + { + mReflectionProbeCount = llclamp(gSavedSettings.getS32("RenderReflectionProbeCount"), 1, LL_MAX_REFLECTION_PROBE_COUNT); + + mTexture = new LLCubeMapArray(); + + // store mReflectionProbeCount+2 cube maps, final two cube maps are used for render target and radiance map generation source) + mTexture->allocate(LL_REFLECTION_PROBE_RESOLUTION, 3, mReflectionProbeCount + 2); + + mIrradianceMaps = new LLCubeMapArray(); + mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount); + } +} diff --git a/indra/newview/llreflectionmapmanager.h b/indra/newview/llreflectionmapmanager.h index 5f0b11ec17..29a9ece2f8 100644 --- a/indra/newview/llreflectionmapmanager.h +++ b/indra/newview/llreflectionmapmanager.h @@ -35,7 +35,7 @@ class LLSpatialGroup; class LLViewerObject; // number of reflection probes to keep in vram -#define LL_REFLECTION_PROBE_COUNT 256 +#define LL_MAX_REFLECTION_PROBE_COUNT 256 // reflection probe resolution #define LL_REFLECTION_PROBE_RESOLUTION 256 @@ -88,6 +88,9 @@ public: // probe debug display is active void renderDebug(); + // call once at startup to allocate cubemap arrays + void initReflectionMaps(); + private: friend class LLPipeline; @@ -120,7 +123,7 @@ private: LLPointer mIrradianceMaps; // array indicating if a particular cubemap is free - bool mCubeFree[LL_REFLECTION_PROBE_COUNT]; + bool mCubeFree[LL_MAX_REFLECTION_PROBE_COUNT]; // start tracking the given spatial group void trackGroup(LLSpatialGroup* group); @@ -148,5 +151,8 @@ private: LLReflectionMap* mUpdatingProbe = nullptr; U32 mUpdatingFace = 0; + + // number of reflection probes to use for rendering (based on saved setting RenderReflectionProbeCount) + U32 mReflectionProbeCount; }; -- cgit v1.2.3 From e81b149c4a24a8ade827e34fa600207cfa86fc7f Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Mon, 29 Aug 2022 17:34:49 -0700 Subject: Revert "SL-17703: PBR: Fix missing ORM to use 1,0,0" If ORM is blank the roughness and metal are multiplied into a default white ORM texture. This reverts commit 71ae65ae175a33c7f60442f62b0ef59415528bf5. --- indra/newview/lldrawpoolpbropaque.cpp | 2 +- indra/newview/llviewertexture.cpp | 11 +---------- indra/newview/llviewertexture.h | 1 - 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/indra/newview/lldrawpoolpbropaque.cpp b/indra/newview/lldrawpoolpbropaque.cpp index 35beafaa40..3930e11cf3 100644 --- a/indra/newview/lldrawpoolpbropaque.cpp +++ b/indra/newview/lldrawpoolpbropaque.cpp @@ -120,7 +120,7 @@ void LLDrawPoolPBROpaque::renderDeferred(S32 pass) } else { - shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerTexture::sDefaultPBRORMImagep); // ORM 1,0,0 + shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep); } if (pparams->mEmissiveMap) diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 3ecab2c647..c389d2122e 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -69,7 +69,6 @@ const S32Megabytes gMaxVideoRam(512); LLPointer LLViewerTexture::sNullImagep = NULL; LLPointer LLViewerTexture::sBlackImagep = NULL; LLPointer LLViewerTexture::sCheckerBoardImagep = NULL; -LLPointer LLViewerTexture::sDefaultPBRORMImagep = NULL; // PBR: When ORM is missing use 1,0,0 LLPointer LLViewerFetchedTexture::sMissingAssetImagep = NULL; LLPointer LLViewerFetchedTexture::sWhiteImagep = NULL; LLPointer LLViewerFetchedTexture::sDefaultImagep = NULL; @@ -368,13 +367,6 @@ void LLViewerTextureManager::init() LLViewerTexture::sNullImagep = LLViewerTextureManager::getLocalTexture(raw.get(), TRUE); } - // Create Default PBR ORM Texture 1,0,0 - { - LLPointer red = new LLImageRaw(8,8,3); - red->clear(0xFF, 0x00, 0x00, 0xFF); - LLViewerTexture::sDefaultPBRORMImagep = LLViewerTextureManager::getLocalTexture(red.get(), TRUE); - } - const S32 dim = 128; LLPointer image_raw = new LLImageRaw(dim,dim,3); U8* data = image_raw->getData(); @@ -459,9 +451,8 @@ void LLViewerTextureManager::cleanup() LLImageGL::sDefaultGLTexture = NULL; LLViewerTexture::sNullImagep = NULL; LLViewerTexture::sBlackImagep = NULL; - LLViewerFetchedTexture::sDefaultPBRORMImagep = NULL; LLViewerTexture::sCheckerBoardImagep = NULL; - LLViewerFetchedTexture::sDefaultImagep = NULL; + LLViewerFetchedTexture::sDefaultImagep = NULL; LLViewerFetchedTexture::sSmokeImagep = NULL; LLViewerFetchedTexture::sMissingAssetImagep = NULL; LLTexUnit::sWhiteTexture = 0; diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index 89ded4ded7..53cf911102 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -252,7 +252,6 @@ public: static LLPointer sNullImagep; // Null texture for non-textured objects. static LLPointer sBlackImagep; // Texture to show NOTHING (pure black) static LLPointer sCheckerBoardImagep; // Texture to show NOTHING (pure black) - static LLPointer sDefaultPBRORMImagep; // PBR: When ORM is missing use 1,0,0 }; -- cgit v1.2.3 From 14af7cabdb80e1de0f5cb2c7e299bd61bc3321cc Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 30 Aug 2022 10:32:09 -0500 Subject: SL-17997 Fix for crash on shutdown --- indra/newview/llappviewer.cpp | 2 -- indra/newview/lltexturefetch.cpp | 17 ++--------------- indra/newview/lltexturefetch.h | 3 +-- 3 files changed, 3 insertions(+), 19 deletions(-) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 55c0b31bf6..1a38f2da91 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2052,7 +2052,6 @@ bool LLAppViewer::cleanup() } sTextureFetch->shutDownTextureCacheThread() ; - sTextureFetch->shutDownImageDecodeThread() ; LLLFSThread::sLocal->shutdown(); LL_INFOS() << "Shutting down message system" << LL_ENDL; @@ -2186,7 +2185,6 @@ bool LLAppViewer::initThreads() LLAppViewer::sImageDecodeThread = new LLImageDecodeThread(enable_threads && true); LLAppViewer::sTextureCache = new LLTextureCache(enable_threads && true); LLAppViewer::sTextureFetch = new LLTextureFetch(LLAppViewer::getTextureCache(), - sImageDecodeThread, enable_threads && true, app_metrics_qa_mode); LLAppViewer::sPurgeDiskCacheThread = new LLPurgeDiskCacheThread(); diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 604444b64a..544b0e6802 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -1868,7 +1868,7 @@ bool LLTextureFetchWorker::doWork(S32 param) setState(DECODE_IMAGE_UPDATE); LL_DEBUGS(LOG_TXT) << mID << ": Decoding. Bytes: " << mFormattedImage->getDataSize() << " Discard: " << discard << " All Data: " << mHaveAllData << LL_ENDL; - mDecodeHandle = mFetcher->mImageDecodeThread->decodeImage(mFormattedImage, discard, mNeedsAux, + mDecodeHandle = LLAppViewer::getImageDecodeThread()->decodeImage(mFormattedImage, discard, mNeedsAux, new DecodeResponder(mFetcher, mID, this)); // fall though } @@ -2540,7 +2540,7 @@ std::string LLTextureFetch::getStateString(S32 state) return e_state_name[state]; } -LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* imagedecodethread, bool threaded, bool qa_mode) +LLTextureFetch::LLTextureFetch(LLTextureCache* cache, bool threaded, bool qa_mode) : LLWorkerThread("TextureFetch", threaded, true), mDebugCount(0), mDebugPause(FALSE), @@ -2549,7 +2549,6 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image mQueueMutex(), mNetworkQueueMutex(), mTextureCache(cache), - mImageDecodeThread(imagedecodethread), mTextureBandwidth(0), mHTTPTextureBits(0), mTotalHTTPRequests(0), @@ -3169,18 +3168,6 @@ void LLTextureFetch::shutDownTextureCacheThread() } } -// called in the MAIN thread after the ImageDecodeThread shuts down. -// -// Threads: Tmain -void LLTextureFetch::shutDownImageDecodeThread() -{ - if(mImageDecodeThread) - { - delete mImageDecodeThread; - mImageDecodeThread = NULL ; - } -} - // Threads: Ttf void LLTextureFetch::startThread() { diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index 320511f343..3ca88422a2 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -60,7 +60,7 @@ class LLTextureFetch : public LLWorkerThread public: static std::string getStateString(S32 state); - LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* imagedecodethread, bool threaded, bool qa_mode); + LLTextureFetch(LLTextureCache* cache, bool threaded, bool qa_mode); ~LLTextureFetch(); class TFRequest; @@ -324,7 +324,6 @@ private: LLMutex mNetworkQueueMutex; //to protect mNetworkQueue, mHTTPTextureQueue and mCancelQueue. LLTextureCache* mTextureCache; - LLImageDecodeThread* mImageDecodeThread; // Map of all requests by UUID typedef std::map map_t; -- cgit v1.2.3