diff options
Diffstat (limited to 'indra/llrender/llimagegl.cpp')
-rw-r--r-- | indra/llrender/llimagegl.cpp | 150 |
1 files changed, 73 insertions, 77 deletions
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 89dd68da76..6215727de0 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -53,13 +53,75 @@ const F32 MIN_TEXTURE_LIFETIME = 10.f; //assumes i is a power of 2 > 0 U32 wpo2(U32 i); + +// texture memory accounting (for OS X) +static LLMutex sTexMemMutex; +static std::unordered_map<U32, U32> 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; +} + //statics 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; @@ -220,6 +282,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; @@ -282,15 +345,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 +677,7 @@ void LLImageGL::forceUpdateBindStats(void) const mLastBindTime = sLastFrameTime; } -BOOL LLImageGL::updateBindStats(S32Bytes tex_mem) const +BOOL LLImageGL::updateBindStats() const { if (mTexName != 0) { @@ -635,7 +689,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 ; @@ -1232,6 +1285,7 @@ void LLImageGL::deleteTextures(S32 numTextures, const U32 *textures) { if (gGLManager.mInited) { + free_tex_images(numTextures, textures); glDeleteTextures(numTextures, textures); } } @@ -1354,7 +1408,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(); @@ -1601,11 +1658,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) { @@ -1626,7 +1678,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 @@ -1636,51 +1687,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; @@ -1874,7 +1880,6 @@ void LLImageGL::destroyGLTexture() { if(mTextureMemory != S32Bytes(0)) { - sGlobalTextureMemory -= mTextureMemory; mTextureMemory = (S32Bytes)0; } @@ -2426,13 +2431,9 @@ void LLImageGL::checkActiveThread() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, nummips); */ -std::atomic<S32> 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; @@ -2455,8 +2456,3 @@ void LLImageGLThread::run() mWindow->destroySharedContext(mContext); } -S32 LLImageGLThread::getFreeVRAMMegabytes() -{ - return sFreeVRAMMegabytes; -} - |