llviewertexture.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:101k
- /**
- * @file llviewertexture.cpp
- * @brief Object which handles a received image (and associated texture(s))
- *
- * $LicenseInfo:firstyear=2000&license=viewergpl$
- *
- * Copyright (c) 2000-2010, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
- #include "llviewerprecompiledheaders.h"
- #include "llviewertexture.h"
- // Library includes
- #include "imageids.h"
- #include "llmath.h"
- #include "llerror.h"
- #include "llgl.h"
- #include "llglheaders.h"
- #include "llhost.h"
- #include "llimage.h"
- #include "llimagebmp.h"
- #include "llimagej2c.h"
- #include "llimagetga.h"
- #include "llmemtype.h"
- #include "llstl.h"
- #include "llvfile.h"
- #include "llvfs.h"
- #include "message.h"
- #include "lltimer.h"
- // viewer includes
- #include "llimagegl.h"
- #include "lldrawpool.h"
- #include "lltexturefetch.h"
- #include "llviewertexturelist.h"
- #include "llviewercontrol.h"
- #include "pipeline.h"
- #include "llappviewer.h"
- #include "llface.h"
- #include "llviewercamera.h"
- #include "lltextureatlas.h"
- #include "lltextureatlasmanager.h"
- #include "lltextureentry.h"
- #include "llmediaentry.h"
- #include "llvovolume.h"
- #include "llviewermedia.h"
- ///////////////////////////////////////////////////////////////////////////////
- // statics
- LLPointer<LLViewerTexture> LLViewerTexture::sNullImagep = NULL;
- LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sMissingAssetImagep = NULL;
- LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sWhiteImagep = NULL;
- LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sDefaultImagep = NULL;
- LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sSmokeImagep = NULL;
- LLViewerMediaTexture::media_map_t LLViewerMediaTexture::sMediaMap ;
- LLTexturePipelineTester* LLViewerTextureManager::sTesterp = NULL ;
- S32 LLViewerTexture::sImageCount = 0;
- S32 LLViewerTexture::sRawCount = 0;
- S32 LLViewerTexture::sAuxCount = 0;
- LLTimer LLViewerTexture::sEvaluationTimer;
- F32 LLViewerTexture::sDesiredDiscardBias = 0.f;
- F32 LLViewerTexture::sDesiredDiscardScale = 1.1f;
- S32 LLViewerTexture::sBoundTextureMemoryInBytes = 0;
- S32 LLViewerTexture::sTotalTextureMemoryInBytes = 0;
- S32 LLViewerTexture::sMaxBoundTextureMemInMegaBytes = 0;
- S32 LLViewerTexture::sMaxTotalTextureMemInMegaBytes = 0;
- S32 LLViewerTexture::sMaxDesiredTextureMemInBytes = 0 ;
- S8 LLViewerTexture::sCameraMovingDiscardBias = 0 ;
- S32 LLViewerTexture::sMaxSculptRez = 128 ; //max sculpt image size
- const S32 MAX_CACHED_RAW_IMAGE_AREA = 64 * 64 ;
- const S32 MAX_CACHED_RAW_SCULPT_IMAGE_AREA = LLViewerTexture::sMaxSculptRez * LLViewerTexture::sMaxSculptRez ;
- const S32 MAX_CACHED_RAW_TERRAIN_IMAGE_AREA = 128 * 128 ;
- S32 LLViewerTexture::sMinLargeImageSize = 65536 ; //256 * 256.
- S32 LLViewerTexture::sMaxSmallImageSize = MAX_CACHED_RAW_IMAGE_AREA ;
- BOOL LLViewerTexture::sFreezeImageScalingDown = FALSE ;
- F32 LLViewerTexture::sCurrentTime = 0.0f ;
- BOOL LLViewerTexture::sUseTextureAtlas = FALSE ;
- const F32 desired_discard_bias_min = -2.0f; // -max number of levels to improve image quality by
- const F32 desired_discard_bias_max = 1.5f; // max number of levels to reduce image quality by
- const F64 log_2 = log(2.0);
- //----------------------------------------------------------------------------------------------
- //namespace: LLViewerTextureAccess
- //----------------------------------------------------------------------------------------------
- LLLoadedCallbackEntry::LLLoadedCallbackEntry(loaded_callback_func cb,
- S32 discard_level,
- BOOL need_imageraw, // Needs image raw for the callback
- void* userdata )
- : mCallback(cb),
- mLastUsedDiscard(MAX_DISCARD_LEVEL+1),
- mDesiredDiscard(discard_level),
- mNeedsImageRaw(need_imageraw),
- mUserData(userdata)
- {
- }
- LLViewerMediaTexture* LLViewerTextureManager::createMediaTexture(const LLUUID &media_id, BOOL usemipmaps, LLImageGL* gl_image)
- {
- return new LLViewerMediaTexture(media_id, usemipmaps, gl_image) ;
- }
-
- LLViewerTexture* LLViewerTextureManager::findTexture(const LLUUID& id)
- {
- LLViewerTexture* tex ;
- //search fetched texture list
- tex = gTextureList.findImage(id) ;
-
- //search media texture list
- if(!tex)
- {
- tex = LLViewerTextureManager::findMediaTexture(id) ;
- }
- return tex ;
- }
-
- LLViewerMediaTexture* LLViewerTextureManager::findMediaTexture(const LLUUID &media_id)
- {
- return LLViewerMediaTexture::findMediaTexture(media_id) ;
- }
- LLViewerMediaTexture* LLViewerTextureManager::getMediaTexture(const LLUUID& id, BOOL usemipmaps, LLImageGL* gl_image)
- {
- LLViewerMediaTexture* tex = LLViewerMediaTexture::findMediaTexture(id) ;
- if(!tex)
- {
- tex = LLViewerTextureManager::createMediaTexture(id, usemipmaps, gl_image) ;
- }
- tex->initVirtualSize() ;
- return tex ;
- }
- LLViewerFetchedTexture* LLViewerTextureManager::staticCastToFetchedTexture(LLTexture* tex, BOOL report_error)
- {
- if(!tex)
- {
- return NULL ;
- }
- S8 type = tex->getType() ;
- if(type == LLViewerTexture::FETCHED_TEXTURE || type == LLViewerTexture::LOD_TEXTURE)
- {
- return static_cast<LLViewerFetchedTexture*>(tex) ;
- }
- if(report_error)
- {
- llerrs << "not a fetched texture type: " << type << llendl ;
- }
- return NULL ;
- }
- LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(BOOL usemipmaps, BOOL generate_gl_tex)
- {
- LLPointer<LLViewerTexture> tex = new LLViewerTexture(usemipmaps) ;
- if(generate_gl_tex)
- {
- tex->generateGLTexture() ;
- tex->setCategory(LLViewerTexture::LOCAL) ;
- }
- return tex ;
- }
- LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const LLUUID& id, BOOL usemipmaps, BOOL generate_gl_tex)
- {
- LLPointer<LLViewerTexture> tex = new LLViewerTexture(id, usemipmaps) ;
- if(generate_gl_tex)
- {
- tex->generateGLTexture() ;
- tex->setCategory(LLViewerTexture::LOCAL) ;
- }
- return tex ;
- }
- LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const LLImageRaw* raw, BOOL usemipmaps)
- {
- LLPointer<LLViewerTexture> tex = new LLViewerTexture(raw, usemipmaps) ;
- tex->setCategory(LLViewerTexture::LOCAL) ;
- return tex ;
- }
- LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex)
- {
- LLPointer<LLViewerTexture> tex = new LLViewerTexture(width, height, components, usemipmaps) ;
- if(generate_gl_tex)
- {
- tex->generateGLTexture() ;
- tex->setCategory(LLViewerTexture::LOCAL) ;
- }
- return tex ;
- }
- LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(
- const LLUUID &image_id,
- BOOL usemipmaps,
- LLViewerTexture::EBoostLevel boost_priority,
- S8 texture_type,
- LLGLint internal_format,
- LLGLenum primary_format,
- LLHost request_from_host)
- {
- return gTextureList.getImage(image_id, usemipmaps, boost_priority, texture_type, internal_format, primary_format, request_from_host) ;
- }
-
- LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromFile(
- const std::string& filename,
- BOOL usemipmaps,
- LLViewerTexture::EBoostLevel boost_priority,
- S8 texture_type,
- LLGLint internal_format,
- LLGLenum primary_format,
- const LLUUID& force_id)
- {
- return gTextureList.getImageFromFile(filename, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id) ;
- }
- //static
- LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string& url,
- BOOL usemipmaps,
- LLViewerTexture::EBoostLevel boost_priority,
- S8 texture_type,
- LLGLint internal_format,
- LLGLenum primary_format,
- const LLUUID& force_id
- )
- {
- return gTextureList.getImageFromUrl(url, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id) ;
- }
- LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromHost(const LLUUID& image_id, LLHost host)
- {
- return gTextureList.getImageFromHost(image_id, host) ;
- }
- void LLViewerTextureManager::init()
- {
- LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,3);
- raw->clear(0x77, 0x77, 0x77, 0xFF);
- LLViewerTexture::sNullImagep = LLViewerTextureManager::getLocalTexture(raw.get(), TRUE) ;
- #if 1
- LLPointer<LLViewerFetchedTexture> imagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT);
- LLViewerFetchedTexture::sDefaultImagep = imagep;
- const S32 dim = 128;
- LLPointer<LLImageRaw> image_raw = new LLImageRaw(dim,dim,3);
- U8* data = image_raw->getData();
- for (S32 i = 0; i<dim; i++)
- {
- for (S32 j = 0; j<dim; j++)
- {
- #if 0
- const S32 border = 2;
- if (i<border || j<border || i>=(dim-border) || j>=(dim-border))
- {
- *data++ = 0xff;
- *data++ = 0xff;
- *data++ = 0xff;
- }
- else
- #endif
- {
- *data++ = 0x7f;
- *data++ = 0x7f;
- *data++ = 0x7f;
- }
- }
- }
- imagep->createGLTexture(0, image_raw);
- image_raw = NULL;
- #else
- LLViewerFetchedTexture::sDefaultImagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, LLViewerTexture::BOOST_UI);
- #endif
- LLViewerFetchedTexture::sDefaultImagep->dontDiscard();
- LLViewerFetchedTexture::sDefaultImagep->setCategory(LLViewerTexture::OTHER) ;
- LLViewerFetchedTexture::sSmokeImagep = LLViewerTextureManager::getFetchedTexture(IMG_SMOKE, TRUE, LLViewerTexture::BOOST_UI);
- LLViewerFetchedTexture::sSmokeImagep->setNoDelete() ;
- LLViewerTexture::initClass() ;
- if(LLFastTimer::sMetricLog)
- {
- LLViewerTextureManager::sTesterp = new LLTexturePipelineTester() ;
- }
- }
- void LLViewerTextureManager::cleanup()
- {
- stop_glerror();
- LLImageGL::sDefaultGLTexture = NULL ;
- LLViewerTexture::sNullImagep = NULL;
- LLViewerFetchedTexture::sDefaultImagep = NULL;
- LLViewerFetchedTexture::sSmokeImagep = NULL;
- LLViewerFetchedTexture::sMissingAssetImagep = NULL;
- LLViewerFetchedTexture::sWhiteImagep = NULL;
- LLViewerMediaTexture::cleanup() ;
- LLViewerTexture::cleanupClass() ;
- }
- //----------------------------------------------------------------------------------------------
- //----------------------------------------------------------------------------------------------
- //start of LLViewerTexture
- //----------------------------------------------------------------------------------------------
- // static
- void LLViewerTexture::initClass()
- {
- LLImageGL::sDefaultGLTexture = LLViewerFetchedTexture::sDefaultImagep->getGLTexture() ;
- if(gAuditTexture)
- {
- LLImageGL::setHighlightTexture(LLViewerTexture::OTHER) ;
- }
- }
- // static
- void LLViewerTexture::cleanupClass()
- {
- }
- // static
- S32 LLViewerTexture::getTotalNumOfCategories()
- {
- return MAX_GL_IMAGE_CATEGORY - (BOOST_HIGH - BOOST_SCULPTED) + 2 ;
- }
- // static
- //index starts from zero.
- S32 LLViewerTexture::getIndexFromCategory(S32 category)
- {
- return (category < BOOST_HIGH) ? category : category - (BOOST_HIGH - BOOST_SCULPTED) + 1 ;
- }
- //static
- S32 LLViewerTexture::getCategoryFromIndex(S32 index)
- {
- return (index < BOOST_HIGH) ? index : index + (BOOST_HIGH - BOOST_SCULPTED) - 1 ;
- }
- // tuning params
- const F32 discard_bias_delta = .05f;
- const F32 discard_delta_time = 0.5f;
- const S32 min_non_tex_system_mem = (128<<20); // 128 MB
- // non-const (used externally
- F32 texmem_lower_bound_scale = 0.85f;
- F32 texmem_middle_bound_scale = 0.925f;
- //static
- void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity)
- {
- sCurrentTime = gFrameTimeSeconds ;
- if(LLViewerTextureManager::sTesterp)
- {
- LLViewerTextureManager::sTesterp->update() ;
- }
- LLViewerMediaTexture::updateClass() ;
- sBoundTextureMemoryInBytes = LLImageGL::sBoundTextureMemoryInBytes;//in bytes
- sTotalTextureMemoryInBytes = LLImageGL::sGlobalTextureMemoryInBytes;//in bytes
- sMaxBoundTextureMemInMegaBytes = gTextureList.getMaxResidentTexMem();//in MB
- sMaxTotalTextureMemInMegaBytes = gTextureList.getMaxTotalTextureMem() ;//in MB
- sMaxDesiredTextureMemInBytes = MEGA_BYTES_TO_BYTES(sMaxTotalTextureMemInMegaBytes) ; //in Bytes, by default and when total used texture memory is small.
- if (BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) >= sMaxBoundTextureMemInMegaBytes ||
- BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) >= sMaxTotalTextureMemInMegaBytes)
- {
- //when texture memory overflows, lower down the threashold to release the textures more aggressively.
- sMaxDesiredTextureMemInBytes = llmin((S32)(sMaxDesiredTextureMemInBytes * 0.75f) , MEGA_BYTES_TO_BYTES(MAX_VIDEO_RAM_IN_MEGA_BYTES)) ;//512 MB
-
- // 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 (sDesiredDiscardBias > 0.0f &&
- BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) < sMaxBoundTextureMemInMegaBytes * texmem_lower_bound_scale &&
- BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) < sMaxTotalTextureMemInMegaBytes * texmem_lower_bound_scale)
- {
- // If we are using less texture memory than we should,
- // scale down the desired discard level
- if (sEvaluationTimer.getElapsedTimeF32() > discard_delta_time)
- {
- sDesiredDiscardBias -= discard_bias_delta;
- sEvaluationTimer.reset();
- }
- }
- sDesiredDiscardBias = llclamp(sDesiredDiscardBias, desired_discard_bias_min, desired_discard_bias_max);
- LLViewerTexture::sUseTextureAtlas = gSavedSettings.getBOOL("EnableTextureAtlas") ;
-
- F32 camera_moving_speed = LLViewerCamera::getInstance()->getAverageSpeed() ;
- F32 camera_angular_speed = LLViewerCamera::getInstance()->getAverageAngularSpeed();
- sCameraMovingDiscardBias = (S8)llmax(0.2f * camera_moving_speed, 2.0f * camera_angular_speed - 1) ;
- LLViewerTexture::sFreezeImageScalingDown = (BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) < 0.75f * sMaxBoundTextureMemInMegaBytes * texmem_middle_bound_scale) &&
- (BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) < 0.75f * sMaxTotalTextureMemInMegaBytes * texmem_middle_bound_scale) ;
- }
- //end of static functions
- //-------------------------------------------------------------------------------------------
- const U32 LLViewerTexture::sCurrentFileVersion = 1;
- LLViewerTexture::LLViewerTexture(BOOL usemipmaps)
- {
- init(true);
- mUseMipMaps = usemipmaps ;
- mID.generate();
- sImageCount++;
- }
- LLViewerTexture::LLViewerTexture(const LLUUID& id, BOOL usemipmaps)
- : mID(id)
- {
- init(true);
- mUseMipMaps = usemipmaps ;
-
- sImageCount++;
- }
- LLViewerTexture::LLViewerTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps)
- {
- init(true);
- mFullWidth = width ;
- mFullHeight = height ;
- mUseMipMaps = usemipmaps ;
- mComponents = components ;
- mID.generate();
- sImageCount++;
- }
- LLViewerTexture::LLViewerTexture(const LLImageRaw* raw, BOOL usemipmaps)
- {
- init(true);
- mUseMipMaps = usemipmaps ;
- mGLTexturep = new LLImageGL(raw, usemipmaps) ;
-
- // Create an empty image of the specified size and width
- mID.generate();
- sImageCount++;
- }
- LLViewerTexture::~LLViewerTexture()
- {
- sImageCount--;
- }
- void LLViewerTexture::init(bool firstinit)
- {
- mBoostLevel = LLViewerTexture::BOOST_NONE;
- mFullWidth = 0;
- mFullHeight = 0;
- mUseMipMaps = FALSE ;
- mComponents = 0 ;
- mTextureState = NO_DELETE ;
- mDontDiscard = FALSE;
- mMaxVirtualSize = 0.f;
- mNeedsGLTexture = FALSE ;
- mNeedsResetMaxVirtualSize = FALSE ;
- mAdditionalDecodePriority = 0.f ;
- mParcelMedia = NULL ;
- mNumFaces = 0 ;
- mNumVolumes = 0;
- mFaceList.clear() ;
- mVolumeList.clear();
- }
- //virtual
- S8 LLViewerTexture::getType() const
- {
- return LLViewerTexture::LOCAL_TEXTURE ;
- }
- void LLViewerTexture::cleanup()
- {
- mFaceList.clear() ;
- mVolumeList.clear();
- if(mGLTexturep)
- {
- mGLTexturep->cleanup();
- }
- }
- // virtual
- void LLViewerTexture::dump()
- {
- if(mGLTexturep)
- {
- mGLTexturep->dump();
- }
- llinfos << "LLViewerTexture"
- << " mID " << mID
- << llendl;
- }
- void LLViewerTexture::setBoostLevel(S32 level)
- {
- if(mBoostLevel != level)
- {
- mBoostLevel = level ;
- if(mBoostLevel != LLViewerTexture::BOOST_NONE)
- {
- setNoDelete() ;
- }
- if(gAuditTexture)
- {
- setCategory(mBoostLevel);
- }
- }
- }
- bool LLViewerTexture::bindDefaultImage(S32 stage)
- {
- if (stage < 0) return false;
- bool res = true;
- if (LLViewerFetchedTexture::sDefaultImagep.notNull() && (this != LLViewerFetchedTexture::sDefaultImagep.get()))
- {
- // use default if we've got it
- res = gGL.getTexUnit(stage)->bind(LLViewerFetchedTexture::sDefaultImagep);
- }
- if (!res && LLViewerTexture::sNullImagep.notNull() && (this != LLViewerTexture::sNullImagep))
- {
- res = gGL.getTexUnit(stage)->bind(LLViewerTexture::sNullImagep) ;
- }
- if (!res)
- {
- llwarns << "LLViewerTexture::bindDefaultImage failed." << llendl;
- }
- stop_glerror();
- //check if there is cached raw image and switch to it if possible
- switchToCachedImage() ;
- if(LLViewerTextureManager::sTesterp)
- {
- LLViewerTextureManager::sTesterp->updateGrayTextureBinding() ;
- }
- return res;
- }
- //virtual
- BOOL LLViewerTexture::isMissingAsset()const
- {
- return FALSE;
- }
- //virtual
- void LLViewerTexture::forceImmediateUpdate()
- {
- }
- void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) const
- {
- if(needs_gltexture)
- {
- mNeedsGLTexture = TRUE ;
- }
- if(mNeedsResetMaxVirtualSize)
- {
- //flag to reset the values because the old values are used.
- mNeedsResetMaxVirtualSize = FALSE ;
- mMaxVirtualSize = virtual_size;
- mAdditionalDecodePriority = 0.f ;
- mNeedsGLTexture = needs_gltexture ;
- }
- else if (virtual_size > mMaxVirtualSize)
- {
- mMaxVirtualSize = virtual_size;
- }
- }
- void LLViewerTexture::resetTextureStats()
- {
- mMaxVirtualSize = 0.0f;
- mAdditionalDecodePriority = 0.f ;
- mNeedsResetMaxVirtualSize = FALSE ;
- }
- //virtual
- F32 LLViewerTexture::getMaxVirtualSize()
- {
- return mMaxVirtualSize ;
- }
- //virtual
- void LLViewerTexture::setKnownDrawSize(S32 width, S32 height)
- {
- //nothing here.
- }
- //virtual
- void LLViewerTexture::addFace(LLFace* facep)
- {
- if(mNumFaces >= mFaceList.size())
- {
- mFaceList.resize(2 * mNumFaces + 1) ;
- }
- mFaceList[mNumFaces] = facep ;
- facep->setIndexInTex(mNumFaces) ;
- mNumFaces++ ;
- mLastFaceListUpdateTimer.reset() ;
- }
- //virtual
- void LLViewerTexture::removeFace(LLFace* facep)
- {
- if(mNumFaces > 1)
- {
- S32 index = facep->getIndexInTex() ;
- mFaceList[index] = mFaceList[--mNumFaces] ;
- mFaceList[index]->setIndexInTex(index) ;
- }
- else
- {
- mFaceList.clear() ;
- mNumFaces = 0 ;
- }
- mLastFaceListUpdateTimer.reset() ;
- }
- S32 LLViewerTexture::getNumFaces() const
- {
- return mNumFaces ;
- }
- //virtual
- void LLViewerTexture::addVolume(LLVOVolume* volumep)
- {
- if( mNumVolumes >= mVolumeList.size())
- {
- mVolumeList.resize(2 * mNumVolumes + 1) ;
- }
- mVolumeList[mNumVolumes] = volumep ;
- volumep->setIndexInTex(mNumVolumes) ;
- mNumVolumes++ ;
- mLastVolumeListUpdateTimer.reset() ;
- }
- //virtual
- void LLViewerTexture::removeVolume(LLVOVolume* volumep)
- {
- if(mNumVolumes > 1)
- {
- S32 index = volumep->getIndexInTex() ;
- mVolumeList[index] = mVolumeList[--mNumVolumes] ;
- mVolumeList[index]->setIndexInTex(index) ;
- }
- else
- {
- mVolumeList.clear() ;
- mNumVolumes = 0 ;
- }
- mLastVolumeListUpdateTimer.reset() ;
- }
- S32 LLViewerTexture::getNumVolumes() const
- {
- return mNumVolumes ;
- }
- void LLViewerTexture::reorganizeFaceList()
- {
- static const F32 MAX_WAIT_TIME = 20.f; // seconds
- static const U32 MAX_EXTRA_BUFFER_SIZE = 4 ;
- if(mNumFaces + MAX_EXTRA_BUFFER_SIZE > mFaceList.size())
- {
- return ;
- }
- if(mLastFaceListUpdateTimer.getElapsedTimeF32() < MAX_WAIT_TIME)
- {
- return ;
- }
- mLastFaceListUpdateTimer.reset() ;
- mFaceList.erase(mFaceList.begin() + mNumFaces, mFaceList.end());
- }
- void LLViewerTexture::reorganizeVolumeList()
- {
- static const F32 MAX_WAIT_TIME = 20.f; // seconds
- static const U32 MAX_EXTRA_BUFFER_SIZE = 4 ;
- if(mNumVolumes + MAX_EXTRA_BUFFER_SIZE > mVolumeList.size())
- {
- return ;
- }
- if(mLastVolumeListUpdateTimer.getElapsedTimeF32() < MAX_WAIT_TIME)
- {
- return ;
- }
- mLastVolumeListUpdateTimer.reset() ;
- mVolumeList.erase(mVolumeList.begin() + mNumVolumes, mVolumeList.end());
- }
- //virtual
- void LLViewerTexture::switchToCachedImage()
- {
- //nothing here.
- }
- void LLViewerTexture::forceActive()
- {
- mTextureState = ACTIVE ;
- }
- void LLViewerTexture::setActive()
- {
- if(mTextureState != NO_DELETE)
- {
- mTextureState = ACTIVE ;
- }
- }
- //set the texture to stay in memory
- void LLViewerTexture::setNoDelete()
- {
- mTextureState = NO_DELETE ;
- }
- void LLViewerTexture::generateGLTexture()
- {
- if(mGLTexturep.isNull())
- {
- mGLTexturep = new LLImageGL(mFullWidth, mFullHeight, mComponents, mUseMipMaps) ;
- }
- }
- LLImageGL* LLViewerTexture::getGLTexture() const
- {
- llassert(mGLTexturep.notNull()) ;
-
- return mGLTexturep ;
- }
- BOOL LLViewerTexture::createGLTexture()
- {
- if(mGLTexturep.isNull())
- {
- generateGLTexture() ;
- }
- return mGLTexturep->createGLTexture() ;
- }
- BOOL LLViewerTexture::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename, BOOL to_create, S32 category)
- {
- llassert(mGLTexturep.notNull()) ;
- BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename, to_create, category) ;
-
- if(ret)
- {
- mFullWidth = mGLTexturep->getCurrentWidth() ;
- mFullHeight = mGLTexturep->getCurrentHeight() ;
- mComponents = mGLTexturep->getComponents() ;
- }
- return ret ;
- }
- void LLViewerTexture::setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes)
- {
- llassert(mGLTexturep.notNull()) ;
-
- mGLTexturep->setExplicitFormat(internal_format, primary_format, type_format, swap_bytes) ;
- }
- void LLViewerTexture::setAddressMode(LLTexUnit::eTextureAddressMode mode)
- {
- llassert(mGLTexturep.notNull()) ;
- mGLTexturep->setAddressMode(mode) ;
- }
- void LLViewerTexture::setFilteringOption(LLTexUnit::eTextureFilterOptions option)
- {
- llassert(mGLTexturep.notNull()) ;
- mGLTexturep->setFilteringOption(option) ;
- }
- //virtual
- S32 LLViewerTexture::getWidth(S32 discard_level) const
- {
- llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->getWidth(discard_level) ;
- }
- //virtual
- S32 LLViewerTexture::getHeight(S32 discard_level) const
- {
- llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->getHeight(discard_level) ;
- }
- S32 LLViewerTexture::getMaxDiscardLevel() const
- {
- llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->getMaxDiscardLevel() ;
- }
- S32 LLViewerTexture::getDiscardLevel() const
- {
- llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->getDiscardLevel() ;
- }
- S8 LLViewerTexture::getComponents() const
- {
- llassert(mGLTexturep.notNull()) ;
-
- return mGLTexturep->getComponents() ;
- }
- LLGLuint LLViewerTexture::getTexName() const
- {
- llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->getTexName() ;
- }
- BOOL LLViewerTexture::hasGLTexture() const
- {
- if(mGLTexturep.notNull())
- {
- return mGLTexturep->getHasGLTexture() ;
- }
- return FALSE ;
- }
- BOOL LLViewerTexture::getBoundRecently() const
- {
- if(mGLTexturep.notNull())
- {
- return mGLTexturep->getBoundRecently() ;
- }
- return FALSE ;
- }
- LLTexUnit::eTextureType LLViewerTexture::getTarget(void) const
- {
- llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->getTarget() ;
- }
- BOOL LLViewerTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height)
- {
- llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height) ;
- }
- BOOL LLViewerTexture::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height)
- {
- llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height) ;
- }
- void LLViewerTexture::setGLTextureCreated (bool initialized)
- {
- llassert(mGLTexturep.notNull()) ;
- mGLTexturep->setGLTextureCreated (initialized) ;
- }
- void LLViewerTexture::setCategory(S32 category)
- {
- llassert(mGLTexturep.notNull()) ;
- mGLTexturep->setCategory(category) ;
- }
- LLTexUnit::eTextureAddressMode LLViewerTexture::getAddressMode(void) const
- {
- llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->getAddressMode() ;
- }
- S32 LLViewerTexture::getTextureMemory() const
- {
- llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->mTextureMemory ;
- }
- LLGLenum LLViewerTexture::getPrimaryFormat() const
- {
- llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->getPrimaryFormat() ;
- }
- BOOL LLViewerTexture::getIsAlphaMask() const
- {
- llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->getIsAlphaMask() ;
- }
- BOOL LLViewerTexture::getMask(const LLVector2 &tc)
- {
- llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->getMask(tc) ;
- }
- F32 LLViewerTexture::getTimePassedSinceLastBound()
- {
- llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->getTimePassedSinceLastBound() ;
- }
- BOOL LLViewerTexture::getMissed() const
- {
- llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->getMissed() ;
- }
- BOOL LLViewerTexture::isJustBound() const
- {
- llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->isJustBound() ;
- }
- void LLViewerTexture::forceUpdateBindStats(void) const
- {
- llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->forceUpdateBindStats() ;
- }
- U32 LLViewerTexture::getTexelsInAtlas() const
- {
- llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->getTexelsInAtlas() ;
- }
- U32 LLViewerTexture::getTexelsInGLTexture() const
- {
- llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->getTexelsInGLTexture() ;
- }
- BOOL LLViewerTexture::isGLTextureCreated() const
- {
- llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->isGLTextureCreated() ;
- }
- S32 LLViewerTexture::getDiscardLevelInAtlas() const
- {
- llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->getDiscardLevelInAtlas() ;
- }
- void LLViewerTexture::destroyGLTexture()
- {
- if(mGLTexturep.notNull() && mGLTexturep->getHasGLTexture())
- {
- mGLTexturep->destroyGLTexture() ;
- mTextureState = DELETED ;
- }
- }
- BOOL LLViewerTexture::isLargeImage()
- {
- return mFullWidth * mFullHeight > LLViewerTexture::sMinLargeImageSize ;
- }
- //virtual
- void LLViewerTexture::updateBindStatsForTester()
- {
- if(LLViewerTextureManager::sTesterp)
- {
- LLViewerTextureManager::sTesterp->updateTextureBindingStats(this) ;
- }
- }
- //----------------------------------------------------------------------------------------------
- //end of LLViewerTexture
- //----------------------------------------------------------------------------------------------
- //----------------------------------------------------------------------------------------------
- //start of LLViewerFetchedTexture
- //----------------------------------------------------------------------------------------------
- LLViewerFetchedTexture::LLViewerFetchedTexture(const LLUUID& id, const LLHost& host, BOOL usemipmaps)
- : LLViewerTexture(id, usemipmaps),
- mTargetHost(host)
- {
- init(TRUE) ;
- generateGLTexture() ;
- }
-
- LLViewerFetchedTexture::LLViewerFetchedTexture(const LLImageRaw* raw, BOOL usemipmaps)
- : LLViewerTexture(raw, usemipmaps)
- {
- init(TRUE) ;
- }
-
- LLViewerFetchedTexture::LLViewerFetchedTexture(const std::string& url, const LLUUID& id, BOOL usemipmaps)
- : LLViewerTexture(id, usemipmaps),
- mUrl(url)
- {
- init(TRUE) ;
- generateGLTexture() ;
- }
- void LLViewerFetchedTexture::init(bool firstinit)
- {
- mOrigWidth = 0;
- mOrigHeight = 0;
- mNeedsAux = FALSE;
- mRequestedDiscardLevel = -1;
- mRequestedDownloadPriority = 0.f;
- mFullyLoaded = FALSE;
- mDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1;
- mMinDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1;
-
- mDecodingAux = FALSE;
- mKnownDrawWidth = 0;
- mKnownDrawHeight = 0;
- mKnownDrawSizeChanged = FALSE ;
- if (firstinit)
- {
- mDecodePriority = 0.f;
- mInImageList = 0;
- }
- // Only set mIsMissingAsset true when we know for certain that the database
- // does not contain this image.
- mIsMissingAsset = FALSE;
- mLoadedCallbackDesiredDiscardLevel = 0;
- mNeedsCreateTexture = FALSE;
-
- mIsRawImageValid = FALSE;
- mRawDiscardLevel = INVALID_DISCARD_LEVEL;
- mMinDiscardLevel = 0;
- mHasFetcher = FALSE;
- mIsFetching = FALSE;
- mFetchState = 0;
- mFetchPriority = 0;
- mDownloadProgress = 0.f;
- mFetchDeltaTime = 999999.f;
- mRequestDeltaTime = 0.f;
- mForSculpt = FALSE ;
- mIsFetched = FALSE ;
- mCachedRawImage = NULL ;
- mCachedRawDiscardLevel = -1 ;
- mCachedRawImageReady = FALSE ;
- mSavedRawImage = NULL ;
- mForceToSaveRawImage = FALSE ;
- mSavedRawDiscardLevel = -1 ;
- mDesiredSavedRawDiscardLevel = -1 ;
- mLastReferencedSavedRawImageTime = 0.0f ;
- }
- LLViewerFetchedTexture::~LLViewerFetchedTexture()
- {
- //*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)
- if (mHasFetcher && LLAppViewer::getTextureFetch())
- {
- LLAppViewer::getTextureFetch()->deleteRequest(getID(), true);
- }
- cleanup();
- }
- //virtual
- S8 LLViewerFetchedTexture::getType() const
- {
- return LLViewerTexture::FETCHED_TEXTURE ;
- }
- void LLViewerFetchedTexture::cleanup()
- {
- for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
- iter != mLoadedCallbackList.end(); )
- {
- LLLoadedCallbackEntry *entryp = *iter++;
- // We never finished loading the image. Indicate failure.
- // Note: this allows mLoadedCallbackUserData to be cleaned up.
- entryp->mCallback( FALSE, this, NULL, NULL, 0, TRUE, entryp->mUserData );
- delete entryp;
- }
- mLoadedCallbackList.clear();
- mNeedsAux = FALSE;
-
- // Clean up image data
- destroyRawImage();
- mCachedRawImage = NULL ;
- mCachedRawDiscardLevel = -1 ;
- mCachedRawImageReady = FALSE ;
- mSavedRawImage = NULL ;
- }
- void LLViewerFetchedTexture::setForSculpt()
- {
- mForSculpt = TRUE ;
- if(isForSculptOnly() && !getBoundRecently())
- {
- destroyGLTexture() ; //sculpt image does not need gl texture.
- }
- checkCachedRawSculptImage() ;
- }
- BOOL LLViewerFetchedTexture::isForSculptOnly() const
- {
- return mForSculpt && !mNeedsGLTexture ;
- }
- BOOL LLViewerFetchedTexture::isDeleted()
- {
- return mTextureState == DELETED ;
- }
- BOOL LLViewerFetchedTexture::isInactive()
- {
- return mTextureState == INACTIVE ;
- }
- BOOL LLViewerFetchedTexture::isDeletionCandidate()
- {
- return mTextureState == DELETION_CANDIDATE ;
- }
- void LLViewerFetchedTexture::setDeletionCandidate()
- {
- if(mGLTexturep.notNull() && mGLTexturep->getTexName() && (mTextureState == INACTIVE))
- {
- mTextureState = DELETION_CANDIDATE ;
- }
- }
- //set the texture inactive
- void LLViewerFetchedTexture::setInactive()
- {
- if(mTextureState == ACTIVE && mGLTexturep.notNull() && mGLTexturep->getTexName() && !mGLTexturep->getBoundRecently())
- {
- mTextureState = INACTIVE ;
- }
- }
- BOOL LLViewerFetchedTexture::isFullyLoaded() const
- {
- // Unfortunately, the boolean "mFullyLoaded" is never updated correctly so we use that logic
- // to check if the texture is there and completely downloaded
- return (mFullWidth != 0) && (mFullHeight != 0) && !mIsFetching && !mHasFetcher;
- }
- // virtual
- void LLViewerFetchedTexture::dump()
- {
- LLViewerTexture::dump();
- llinfos << "Dump : " << mID
- << ", mIsMissingAsset = " << (S32)mIsMissingAsset
- << ", mFullWidth = " << (S32)mFullWidth
- << ", mFullHeight = " << (S32)mFullHeight
- << ", mOrigWidth = " << (S32)mOrigWidth
- << ", mOrigHeight = " << (S32)mOrigHeight
- << llendl;
- llinfos << " : "
- << " mFullyLoaded = " << (S32)mFullyLoaded
- << ", mFetchState = " << (S32)mFetchState
- << ", mFetchPriority = " << (S32)mFetchPriority
- << ", mDownloadProgress = " << (F32)mDownloadProgress
- << llendl;
- llinfos << " : "
- << " mHasFetcher = " << (S32)mHasFetcher
- << ", mIsFetching = " << (S32)mIsFetching
- << ", mIsFetched = " << (S32)mIsFetched
- << ", mBoostLevel = " << (S32)mBoostLevel
- << llendl;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // ONLY called from LLViewerFetchedTextureList
- void LLViewerFetchedTexture::destroyTexture()
- {
- if(LLImageGL::sGlobalTextureMemoryInBytes < sMaxDesiredTextureMemInBytes)//not ready to release unused memory.
- {
- return ;
- }
- if (mNeedsCreateTexture)//return if in the process of generating a new texture.
- {
- return ;
- }
-
- destroyGLTexture() ;
- mFullyLoaded = FALSE ;
- }
- //
- //do not change the discard level of the loaded texture image.
- BOOL LLViewerFetchedTexture::keepReuestedDiscardLevel()
- {
- if (!mLoadedCallbackList.empty())
- {
- return TRUE ;
- }
- return FALSE ;
- }
- void LLViewerFetchedTexture::addToCreateTexture()
- {
- if(isForSculptOnly())
- {
- //just update some variables, not to create a real GL texture.
- createGLTexture(mRawDiscardLevel, mRawImage, 0, FALSE) ;
- mNeedsCreateTexture = FALSE ;
- destroyRawImage();
- }
- else
- {
- #if 1
- //
- //if mRequestedDiscardLevel > mDesiredDiscardLevel, we assume the required image res keep going up,
- //so do not scale down the over qualified image.
- //Note: scaling down image is expensensive. Do it only when very necessary.
- //
- if(mRequestedDiscardLevel <= mDesiredDiscardLevel && !keepReuestedDiscardLevel())
- {
- S32 w = mFullWidth >> mRawDiscardLevel;
- S32 h = mFullHeight >> mRawDiscardLevel;
- //if big image, do not load extra data
- //scale it down to size >= LLViewerTexture::sMinLargeImageSize
- if(w * h > LLViewerTexture::sMinLargeImageSize)
- {
- S32 d_level = llmin(mRequestedDiscardLevel, (S32)mDesiredDiscardLevel) - mRawDiscardLevel ;
-
- if(d_level > 0)
- {
- S32 i = 0 ;
- while((d_level > 0) && ((w >> i) * (h >> i) > LLViewerTexture::sMinLargeImageSize))
- {
- i++;
- d_level--;
- }
- if(i > 0)
- {
- mRawDiscardLevel += i ;
- if(mRawDiscardLevel >= getDiscardLevel() && getDiscardLevel() > 0)
- {
- mNeedsCreateTexture = FALSE ;
- destroyRawImage();
- return ;
- }
- mRawImage->scale(w >> i, h >> i) ;
- }
- }
- }
- }
- #endif
- mNeedsCreateTexture = TRUE;
- gTextureList.mCreateTextureList.insert(this);
- }
- return ;
- }
- // ONLY called from LLViewerTextureList
- BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
- {
- if (!mNeedsCreateTexture)
- {
- destroyRawImage();
- return FALSE;
- }
- mNeedsCreateTexture = FALSE;
- if (mRawImage.isNull())
- {
- llerrs << "LLViewerTexture trying to create texture with no Raw Image" << llendl;
- }
- // llinfos << llformat("IMAGE Creating (%d) [%d x %d] Bytes: %d ",
- // mRawDiscardLevel,
- // mRawImage->getWidth(), mRawImage->getHeight(),mRawImage->getDataSize())
- // << mID.getString() << llendl;
- BOOL res = TRUE;
- if (!gNoRender)
- {
- // store original size only for locally-sourced images
- if (mUrl.compare(0, 7, "file://") == 0)
- {
- mOrigWidth = mRawImage->getWidth();
- mOrigHeight = mRawImage->getHeight();
- // leave black border, do not scale image content
- mRawImage->expandToPowerOfTwo(MAX_IMAGE_SIZE, FALSE);
-
- mFullWidth = mRawImage->getWidth();
- mFullHeight = mRawImage->getHeight();
- }
- else
- {
- mOrigWidth = mFullWidth;
- mOrigHeight = mFullHeight;
- }
- bool size_okay = true;
-
- U32 raw_width = mRawImage->getWidth() << mRawDiscardLevel;
- U32 raw_height = mRawImage->getHeight() << mRawDiscardLevel;
- if( raw_width > MAX_IMAGE_SIZE || raw_height > MAX_IMAGE_SIZE )
- {
- llinfos << "Width or height is greater than " << MAX_IMAGE_SIZE << ": (" << raw_width << "," << raw_height << ")" << llendl;
- size_okay = false;
- }
-
- if (!LLImageGL::checkSize(mRawImage->getWidth(), mRawImage->getHeight()))
- {
- // A non power-of-two image was uploaded (through a non standard client)
- llinfos << "Non power of two width or height: (" << mRawImage->getWidth() << "," << mRawImage->getHeight() << ")" << llendl;
- size_okay = false;
- }
-
- if( !size_okay )
- {
- // An inappropriately-sized image was uploaded (through a non standard client)
- // We treat these images as missing assets which causes them to
- // be renderd as 'missing image' and to stop requesting data
- setIsMissingAsset();
- destroyRawImage();
- return FALSE;
- }
-
- if(!(res = insertToAtlas()))
- {
- res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel);
- resetFaceAtlas() ;
- }
- setActive() ;
- }
- //
- // Iterate through the list of image loading callbacks to see
- // what sort of data they need.
- //
- // *TODO: Fix image callback code
- BOOL imageraw_callbacks = FALSE;
- for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
- iter != mLoadedCallbackList.end(); )
- {
- LLLoadedCallbackEntry *entryp = *iter++;
- if (entryp->mNeedsImageRaw)
- {
- imageraw_callbacks = TRUE;
- break;
- }
- }
- if (!imageraw_callbacks)
- {
- mNeedsAux = FALSE;
- destroyRawImage();
- }
- return res;
- }
- // Call with 0,0 to turn this feature off.
- //virtual
- void LLViewerFetchedTexture::setKnownDrawSize(S32 width, S32 height)
- {
- if(mKnownDrawWidth != width || mKnownDrawHeight != height)
- {
- mKnownDrawWidth = width;
- mKnownDrawHeight = height;
- mKnownDrawSizeChanged = TRUE ;
- mFullyLoaded = FALSE ;
- }
- addTextureStats((F32)(width * height));
- }
- //virtual
- void LLViewerFetchedTexture::processTextureStats()
- {
- if(mFullyLoaded)//already loaded
- {
- return ;
- }
- updateVirtualSize() ;
-
- static LLCachedControl<bool> textures_fullres(gSavedSettings,"TextureLoadFullRes");
-
- if (textures_fullres)
- {
- mDesiredDiscardLevel = 0;
- }
- else if(!mFullWidth || !mFullHeight)
- {
- mDesiredDiscardLevel = getMaxDiscardLevel() ;
- }
- else
- {
- if(!mKnownDrawWidth || !mKnownDrawHeight || mFullWidth <= mKnownDrawWidth || mFullHeight <= mKnownDrawHeight)
- {
- if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT)
- {
- mDesiredDiscardLevel = 1; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048
- }
- else
- {
- mDesiredDiscardLevel = 0;
- }
- }
- else if(mKnownDrawSizeChanged)//known draw size is set
- {
- mDesiredDiscardLevel = (S8)llmin(log((F32)mFullWidth / mKnownDrawWidth) / log_2,
- log((F32)mFullHeight / mKnownDrawHeight) / log_2) ;
- mDesiredDiscardLevel = llclamp(mDesiredDiscardLevel, (S8)0, (S8)getMaxDiscardLevel()) ;
- }
- mKnownDrawSizeChanged = FALSE ;
-
- if(getDiscardLevel() >= 0 && (getDiscardLevel() <= mDesiredDiscardLevel))
- {
- mFullyLoaded = TRUE ;
- }
- }
- }
- 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
- F32 LLViewerFetchedTexture::calcDecodePriority()
- {
- #ifndef LL_RELEASE_FOR_DOWNLOAD
- if (mID == LLAppViewer::getTextureFetch()->mDebugID)
- {
- LLAppViewer::getTextureFetch()->mDebugCount++; // for setting breakpoints
- }
- #endif
-
- if(mFullyLoaded)//already loaded for static texture
- {
- return -4.0f ; //alreay fetched
- }
- if (mNeedsCreateTexture)
- {
- return mDecodePriority; // no change while waiting to create
- }
- if(mForceToSaveRawImage)
- {
- return maxDecodePriority() ;
- }
-
- S32 cur_discard = getDiscardLevel();
- bool have_all_data = (cur_discard >= 0 && (cur_discard <= mDesiredDiscardLevel));
- F32 pixel_priority = fsqrtf(mMaxVirtualSize);
- F32 priority = 0.f;
- if (mIsMissingAsset)
- {
- priority = 0.0f;
- }
- else if(mDesiredDiscardLevel >= cur_discard && cur_discard > -1)
- {
- priority = -1.0f ;
- }
- else if(mCachedRawDiscardLevel > -1 && mDesiredDiscardLevel >= mCachedRawDiscardLevel)
- {
- priority = -1.0f;
- }
- else if (mDesiredDiscardLevel > getMaxDiscardLevel())
- {
- // Don't decode anything we don't need
- priority = -1.0f;
- }
- else if ((mBoostLevel == LLViewerTexture::BOOST_UI || mBoostLevel == LLViewerTexture::BOOST_ICON) && !have_all_data)
- {
- priority = 1.f;
- }
- else if (pixel_priority <= 0.f && !have_all_data)
- {
- // Not on screen but we might want some data
- if (mBoostLevel > BOOST_HIGH)
- {
- // Always want high boosted images
- priority = 1.f;
- }
- else
- {
- // Leave the priority as-is
- return mDecodePriority;
- }
- }
- 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;
- }
- else if ((mMinDiscardLevel > 0) && (cur_discard <= mMinDiscardLevel))
- {
- // larger mips are corrupted
- priority = -3.0f;
- }
- else if (cur_discard <= mDesiredDiscardLevel)
- {
- priority = -4.0f;
- }
- else
- {
- // priority range = 100,000 - 500,000
- S32 desired_discard = mDesiredDiscardLevel;
- if (getDontDiscard())
- {
- desired_discard -= 2;
- }
- else 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, 0, 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)
- {
- pixel_priority = llclamp(pixel_priority, 0.0f, MAX_PRIORITY_PIXEL);
- priority += pixel_priority + PRIORITY_BOOST_LEVEL_FACTOR * mBoostLevel;
- if ( mBoostLevel > BOOST_HIGH)
- {
- priority += PRIORITY_BOOST_HIGH_FACTOR;
- }
- if(mAdditionalDecodePriority > 0.0f)
- {
- // priority range += 1,000,000.f-9,000,000.f
- priority += PRIORITY_ADDITIONAL_FACTOR * (1.0 + mAdditionalDecodePriority * MAX_ADDITIONAL_LEVEL_FOR_PRIORITY);
- }
- }
- 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)
- {
- //llassert(!mInImageList); // firing a lot, figure out why
- if (mInImageList) // above llassert() softened to a warning
- {
- llwarns << "BAD STUFF! mInImageList" << llendl;
- }
- mDecodePriority = priority;
- }
- void LLViewerFetchedTexture::setAdditionalDecodePriority(F32 priority)
- {
- priority = llclamp(priority, 0.f, 1.f);
- if(mAdditionalDecodePriority < priority)
- {
- mAdditionalDecodePriority = priority;
- }
- }
- void LLViewerFetchedTexture::updateVirtualSize()
- {
- if(mNeedsResetMaxVirtualSize)
- {
- addTextureStats(0.f, FALSE) ;//reset
- }
- for(U32 i = 0 ; i < mNumFaces ; i++)
- {
- LLFace* facep = mFaceList[i] ;
- if(facep->getDrawable()->isRecentlyVisible())
- {
- addTextureStats(facep->getVirtualSize()) ;
- setAdditionalDecodePriority(facep->getImportanceToCamera()) ;
- }
- }
- mNeedsResetMaxVirtualSize = TRUE ;
- reorganizeFaceList() ;
- reorganizeVolumeList();
- }
- bool LLViewerFetchedTexture::updateFetch()
- {
- static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled");
- if(textures_decode_disabled)
- {
- return false ;
- }
- mFetchState = 0;
- mFetchPriority = 0;
- mFetchDeltaTime = 999999.f;
- mRequestDeltaTime = 999999.f;
- #ifndef LL_RELEASE_FOR_DOWNLOAD
- if (mID == LLAppViewer::getTextureFetch()->mDebugID)
- {
- LLAppViewer::getTextureFetch()->mDebugCount++; // for setting breakpoints
- }
- #endif
- if (mNeedsCreateTexture)
- {
- // 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)
- {
- llassert_always(!mHasFetcher);
- return false; // skip
- }
- if (!mLoadedCallbackList.empty() && mRawImage.notNull())
- {
- return false; // process any raw image data in callbacks before replacing
- }
-
- S32 current_discard = getDiscardLevel() ;
- S32 desired_discard = getDesiredDiscardLevel();
- F32 decode_priority = getDecodePriority();
- decode_priority = llmax(decode_priority, 0.0f);
- if (mIsFetching)
- {
- // Sets mRawDiscardLevel, mRawImage, mAuxRawImage
- S32 fetch_discard = current_discard;
-
- if(mForceToSaveRawImage)
- {
- if(fetch_discard >= 0)
- {
- fetch_discard = llmax(fetch_discard, mSavedRawDiscardLevel) ;
- }
- }
- if (mRawImage.notNull()) sRawCount--;
- if (mAuxRawImage.notNull()) sAuxCount--;
- bool finished = LLAppViewer::getTextureFetch()->getRequestFinished(getID(), fetch_discard, mRawImage, mAuxRawImage);
- if (mRawImage.notNull()) sRawCount++;
- if (mAuxRawImage.notNull()) sAuxCount++;
- if (finished)
- {
- mIsFetching = FALSE;
- }
- else
- {
- mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority,
- mFetchPriority, mFetchDeltaTime, mRequestDeltaTime);
- }
-
- // We may have data ready regardless of whether or not we are finished (e.g. waiting on write)
- if (mRawImage.notNull())
- {
- if(LLViewerTextureManager::sTesterp)
- {
- mIsFetched = TRUE ;
- LLViewerTextureManager::sTesterp->updateTextureLoadingStats(this, mRawImage, LLAppViewer::getTextureFetch()->isFromLocalCache(mID)) ;
- }
- mRawDiscardLevel = fetch_discard;
- if ((mRawImage->getDataSize() > 0 && mRawDiscardLevel >= 0) &&
- (current_discard < 0 || mRawDiscardLevel < current_discard))
- {
- if (getComponents() != mRawImage->getComponents())
- {
- // We've changed the number of components, so we need to move any
- // objects using this pool to a different pool.
- mComponents = mRawImage->getComponents();
- mGLTexturep->setComponents(mComponents) ;
- for(U32 i = 0 ; i < mNumFaces ; i++)
- {
- mFaceList[i]->dirtyTexture() ;
- }
- }
- mFullWidth = mRawImage->getWidth() << mRawDiscardLevel;
- mFullHeight = mRawImage->getHeight() << mRawDiscardLevel;
- if(mFullWidth > MAX_IMAGE_SIZE || mFullHeight > MAX_IMAGE_SIZE)
- {
- //discard all oversized textures.
- destroyRawImage();
- setIsMissingAsset();
- mRawDiscardLevel = INVALID_DISCARD_LEVEL ;
- mIsFetching = FALSE ;
- }
- else
- {
- mIsRawImageValid = TRUE;
- addToCreateTexture() ;
- }
- return TRUE ;
- }
- else
- {
- // Data is ready but we don't need it
- // (received it already while fetcher was writing to disk)
- destroyRawImage();
- return false; // done
- }
- }
-
- if (!mIsFetching)
- {
- if ((decode_priority > 0) && (mRawDiscardLevel < 0 || mRawDiscardLevel == INVALID_DISCARD_LEVEL))
- {
- // We finished but received no data
- if (current_discard < 0)
- {
- setIsMissingAsset();
- desired_discard = -1;
- }
- else
- {
- //llwarns << mID << ": Setting min discard to " << current_discard << llendl;
- mMinDiscardLevel = current_discard;
- desired_discard = current_discard;
- }
- destroyRawImage();
- }
- else if (mRawImage.notNull())
- {
- // We have data, but our fetch failed to return raw data
- // *TODO: FIgure out why this is happening and fix it
- destroyRawImage();
- }
- }
- else
- {
- // // Useful debugging code for undesired deprioritization of textures.
- // if (decode_priority <= 0.0f && desired_discard >= 0 && desired_discard < current_discard)
- // {
- // llinfos << "Calling updateRequestPriority() with decode_priority = 0.0f" << llendl;
- // calcDecodePriority();
- // }
- LLAppViewer::getTextureFetch()->updateRequestPriority(mID, decode_priority);
- }
- }
- if (!mDontDiscard)
- {
- if (mBoostLevel == 0)
- {
- desired_discard = llmax(desired_discard, current_discard-1);
- }
- else
- {
- desired_discard = llmax(desired_discard, current_discard-2);
- }
- }
- bool make_request = true;
- if (decode_priority <= 0)
- {
- make_request = false;
- }
- else if (mNeedsCreateTexture || mIsMissingAsset)
- {
- make_request = false;
- }
- else if (current_discard >= 0 && current_discard <= mMinDiscardLevel)
- {
- make_request = false;
- }
- //else if (!isJustBound() && mCachedRawImageReady)
- //{
- // make_request = false;
- //}
- else
- {
- if (mIsFetching)
- {
- if (mRequestedDiscardLevel <= desired_discard)
- {
- make_request = false;
- }
- }
- else
- {
- if (current_discard >= 0 && current_discard <= desired_discard)
- {
- make_request = false;
- }
- }
- }
-
- if (make_request)
- {
- S32 w=0, h=0, c=0;
- if (current_discard >= 0)
- {
- w = mGLTexturep->getWidth(0);
- h = mGLTexturep->getHeight(0);
- c = mComponents;
- }
-
- // bypass texturefetch directly by pulling from LLTextureCache
- bool fetch_request_created = false;
- fetch_request_created = LLAppViewer::getTextureFetch()->createRequest(mUrl, getID(),getTargetHost(), decode_priority,
- w, h, c, desired_discard, needsAux());
-
- if (fetch_request_created)
- {
- mHasFetcher = TRUE;
- mIsFetching = TRUE;
- mRequestedDiscardLevel = desired_discard;
- mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority,
- mFetchPriority, mFetchDeltaTime, mRequestDeltaTime);
- }
- // if createRequest() failed, we're finishing up a request for this UUID,
- // wait for it to complete
- }
- else if (mHasFetcher && !mIsFetching)
- {
- // Only delete requests that haven't receeived any network data for a while
- const F32 FETCH_IDLE_TIME = 5.f;
- if (mLastPacketTimer.getElapsedTimeF32() > FETCH_IDLE_TIME)
- {
- // llinfos << "Deleting request: " << getID() << " Discard: " << current_discard << " <= min:" << mMinDiscardLevel << " or priority == 0: " << decode_priority << llendl;
- LLAppViewer::getTextureFetch()->deleteRequest(getID(), true);
- mHasFetcher = FALSE;
- }
- }
-
- llassert_always(mRawImage.notNull() || (!mNeedsCreateTexture && !mIsRawImageValid));
-
- return mIsFetching ? true : false;
- }
- //
- //force to fetch a new raw image for this texture
- //
- BOOL LLViewerFetchedTexture::forceFetch()
- {
- if(!mForceToSaveRawImage)
- {
- return false ;
- }
- //if(mDesiredSavedRawDiscardLevel < getDiscardLevel())
- {
- //no need to force fetching. normal fetching flow will do the work.
- //return false ;
- }
- //if (mNeedsCreateTexture)
- {
- // 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(mIsFetching)
- {
- return false ;
- }
- if (mIsMissingAsset)
- {
- mForceToSaveRawImage = false ;
- llassert_always(!mHasFetcher);
- return false; // skip
- }
- if (!mLoadedCallbackList.empty() && mRawImage.notNull())
- {
- return false; // process any raw image data in callbacks before replacing
- }
- if(mRawImage.notNull() && mRawDiscardLevel <= mDesiredSavedRawDiscardLevel)
- {
- return false ; // mRawImage is enough
- }
- S32 desired_discard = mDesiredSavedRawDiscardLevel ;
- S32 current_discard = getDiscardLevel();
-
- bool fetch_request_created = false;
- S32 w=0, h=0, c=0;
- if (current_discard >= 0)
- {
- w = getWidth(0);
- h = getHeight(0);
- c = getComponents();
- }
- setDecodePriority(maxDecodePriority()) ;
- fetch_request_created = LLAppViewer::getTextureFetch()->createRequest(mUrl, getID(),getTargetHost(), getDecodePriority(),
- w, h, c, desired_discard, needsAux());
- if (fetch_request_created)
- {
- mHasFetcher = TRUE;
- mIsFetching = TRUE;
- mRequestedDiscardLevel = desired_discard ;
- mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority,
- mFetchPriority, mFetchDeltaTime, mRequestDeltaTime);
- }
- return mIsFetching ? true : false;
- }
- void LLViewerFetchedTexture::setIsMissingAsset()
- {
- if (mUrl.empty())
- {
- llwarns << mID << ": Marking image as missing" << llendl;
- }
- else
- {
- llwarns << mUrl << ": Marking image as missing" << llendl;
- }
- if (mHasFetcher)
- {
- LLAppViewer::getTextureFetch()->deleteRequest(getID(), true);
- mHasFetcher = FALSE;
- mIsFetching = FALSE;
- mFetchState = 0;
- mFetchPriority = 0;
- }
- mIsMissingAsset = TRUE;
- }
- void LLViewerFetchedTexture::setLoadedCallback( loaded_callback_func loaded_callback,
- S32 discard_level, BOOL keep_imageraw, BOOL needs_aux, void* userdata)
- {
- //
- // Don't do ANYTHING here, just add it to the global callback list
- //
- if (mLoadedCallbackList.empty())
- {
- // Put in list to call this->doLoadedCallbacks() periodically
- gTextureList.mCallbackList.insert(this);
- mLoadedCallbackDesiredDiscardLevel = (S8)discard_level;
- }
- else
- {
- mLoadedCallbackDesiredDiscardLevel = llmin(mLoadedCallbackDesiredDiscardLevel, (S8)discard_level) ;
- }
- LLLoadedCallbackEntry* entryp = new LLLoadedCallbackEntry(loaded_callback, discard_level, keep_imageraw, userdata);
- mLoadedCallbackList.push_back(entryp);
- mNeedsAux |= needs_aux;
- if (mNeedsAux && mAuxRawImage.isNull() && getDiscardLevel() >= 0)
- {
- // We need aux data, but we've already loaded the image, and it didn't have any
- llwarns << "No aux data available for callback for image:" << getID() << llendl;
- }
- }
- bool LLViewerFetchedTexture::doLoadedCallbacks()
- {
- if (mNeedsCreateTexture)
- {
- return false;
- }
- bool res = false;
-
- if (isMissingAsset())
- {
- for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
- iter != mLoadedCallbackList.end(); )
- {
- LLLoadedCallbackEntry *entryp = *iter++;
- // We never finished loading the image. Indicate failure.
- // Note: this allows mLoadedCallbackUserData to be cleaned up.
- entryp->mCallback(FALSE, this, NULL, NULL, 0, TRUE, entryp->mUserData);
- delete entryp;
- }
- mLoadedCallbackList.clear();
- // Remove ourself from the global list of textures with callbacks
- gTextureList.mCallbackList.erase(this);
- }
- S32 gl_discard = getDiscardLevel();
- // If we don't have a legit GL image, set it to be lower than the worst discard level
- if (gl_discard == -1)
- {
- gl_discard = MAX_DISCARD_LEVEL + 1;
- }
- //
- // Determine the quality levels of textures that we can provide to callbacks
- // and whether we need to do decompression/readback to get it
- //
- S32 current_raw_discard = MAX_DISCARD_LEVEL + 1; // We can always do a readback to get a raw discard
- S32 best_raw_discard = gl_discard; // Current GL quality level
- S32 current_aux_discard = MAX_DISCARD_LEVEL + 1;
- S32 best_aux_discard = MAX_DISCARD_LEVEL + 1;
- if (mIsRawImageValid)
- {
- // If we have an existing raw image, we have a baseline for the raw and auxiliary quality levels.
- best_raw_discard = llmin(best_raw_discard, mRawDiscardLevel);
- best_aux_discard = llmin(best_aux_discard, mRawDiscardLevel); // We always decode the aux when we decode the base raw
- current_aux_discard = llmin(current_aux_discard, best_aux_discard);
- }
- else
- {
- // We have no data at all, we need to get it
- // Do this by forcing the best aux discard to be 0.
- best_aux_discard = 0;
- }
- //
- // See if any of the callbacks would actually run using the data that we can provide,
- // and also determine if we need to perform any readbacks or decodes.
- //
- bool run_gl_callbacks = false;
- bool run_raw_callbacks = false;
- bool need_readback = false;
- for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
- iter != mLoadedCallbackList.end(); )
- {
- LLLoadedCallbackEntry *entryp = *iter++;
- if (entryp->mNeedsImageRaw)
- {
- if (mNeedsAux)
- {
- //
- // Need raw and auxiliary channels
- //
- if (entryp->mLastUsedDiscard > current_aux_discard)
- {
- // We have useful data, run the callbacks
- run_raw_callbacks = true;
- }
- }
- else
- {
- if (entryp->mLastUsedDiscard > current_raw_discard)
- {
- // We have useful data, just run the callbacks
- run_raw_callbacks = true;
- }
- else if (entryp->mLastUsedDiscard > best_raw_discard)
- {
- // We can readback data, and then run the callbacks
- need_readback = true;
- run_raw_callbacks = true;
- }
- }
- }
- else
- {
- // Needs just GL
- if (entryp->mLastUsedDiscard > gl_discard)
- {
- // We have enough data, run this callback requiring GL data
- run_gl_callbacks = true;
- }
- }
- }
- //
- // Do a readback if required, OR start off a texture decode
- //
- if (need_readback && (getMaxDiscardLevel() > gl_discard))
- {
- // Do a readback to get the GL data into the raw image
- // We have GL data.
- destroyRawImage();
- reloadRawImage(mLoadedCallbackDesiredDiscardLevel);
- llassert_always(mRawImage.notNull());
- llassert_always(!mNeedsAux || mAuxRawImage.notNull());
- }
- //
- // Run raw/auxiliary data callbacks
- //
- if (run_raw_callbacks && mIsRawImageValid && (mRawDiscardLevel <= getMaxDiscardLevel()))
- {
- // Do callbacks which require raw image data.
- //llinfos << "doLoadedCallbacks raw for " << getID() << llendl;
- // Call each party interested in the raw data.
- for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
- iter != mLoadedCallbackList.end(); )
- {
- callback_list_t::iterator curiter = iter++;
- LLLoadedCallbackEntry *entryp = *curiter;
- if (entryp->mNeedsImageRaw && (entryp->mLastUsedDiscard > mRawDiscardLevel))
- {
- // If we've loaded all the data there is to load or we've loaded enough
- // to satisfy the interested party, then this is the last time that
- // we're going to call them.
- llassert_always(mRawImage.notNull());
- if(mNeedsAux && mAuxRawImage.isNull())
- {
- llwarns << "Raw Image with no Aux Data for callback" << llendl;
- }
- BOOL final = mRawDiscardLevel <= entryp->mDesiredDiscard ? TRUE : FALSE;
- //llinfos << "Running callback for " << getID() << llendl;
- //llinfos << mRawImage->getWidth() << "x" << mRawImage->getHeight() << llendl;
- if (final)
- {
- //llinfos << "Final!" << llendl;
- }
- entryp->mLastUsedDiscard = mRawDiscardLevel;
- entryp->mCallback(TRUE, this, mRawImage, mAuxRawImage, mRawDiscardLevel, final, entryp->mUserData);
- if (final)
- {
- iter = mLoadedCallbackList.erase(curiter);
- delete entryp;
- }
- res = true;
- }
- }
- }
- //
- // Run GL callbacks
- //
- if (run_gl_callbacks && (gl_discard <= getMaxDiscardLevel()))
- {
- //llinfos << "doLoadedCallbacks GL for " << getID() << llendl;
- // Call the callbacks interested in GL data.
- for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
- iter != mLoadedCallbackList.end(); )
- {
- callback_list_t::iterator curiter = iter++;
- LLLoadedCallbackEntry *entryp = *curiter;
- if (!entryp->mNeedsImageRaw && (entryp->mLastUsedDiscard > gl_discard))
- {
- BOOL final = gl_discard <= entryp->mDesiredDiscard ? TRUE : FALSE;
- entryp->mLastUsedDiscard = gl_discard;
- entryp->mCallback(TRUE, this, NULL, NULL, gl_discard, final, entryp->mUserData);
- if (final)
- {
- iter = mLoadedCallbackList.erase(curiter);
- delete entryp;
- }
- res = true;
- }
- }
- }
- //
- // If we have no callbacks, take us off of the image callback list.
- //
- if (mLoadedCallbackList.empty())
- {
- gTextureList.mCallbackList.erase(this);
- }
- // Done with any raw image data at this point (will be re-created if we still have callbacks)
- destroyRawImage();
-
- return res;
- }
- //virtual
- void LLViewerFetchedTexture::forceImmediateUpdate()
- {
- //only immediately update a deleted texture which is now being re-used.
- if(!isDeleted())
- {
- return ;
- }
- //if already called forceImmediateUpdate()
- if(mInImageList && mDecodePriority == LLViewerFetchedTexture::maxDecodePriority())
- {
- return ;
- }
- gTextureList.forceImmediateUpdate(this) ;
- return ;
- }
- LLImageRaw* LLViewerFetchedTexture::reloadRawImage(S8 discard_level)
- {
- llassert_always(mGLTexturep.notNull()) ;
- llassert_always(discard_level >= 0);
- llassert_always(mComponents > 0);
- if (mRawImage.notNull())
- {
- //mRawImage is in use by somebody else, do not delete it.
- return NULL ;
- }
- if(mSavedRawDiscardLevel >= 0 && mSavedRawDiscardLevel <= discard_level)
- {
- mRawImage = new LLImageRaw(getWidth(discard_level), getHeight(discard_level), getComponents()) ;
- mRawImage->copy(getSavedRawImage()) ;
- mRawDiscardLevel = discard_level ;
- }
- else
- {
- //force to fetch raw image again if cached raw image is not good enough.
- if(mCachedRawDiscardLevel > discard_level)
- {
- mRawImage = mCachedRawImage ;
- mRawDiscardLevel = mCachedRawDiscardLevel;
- forceToSaveRawImage(discard_level) ;
- }
- else //cached raw image is good enough, copy it.
- {
- mRawImage = new LLImageRaw(getWidth(discard_level), getHeight(discard_level), getComponents()) ;
- mRawImage->copy(mCachedRawImage) ;
- mRawDiscardLevel = discard_level ;
- }
- }
- mIsRawImageValid = TRUE ;
- sRawCount++;
-
- return mRawImage;
- }
- void LLViewerFetchedTexture::destroyRawImage()
- {
- if (mAuxRawImage.notNull()) sAuxCount--;
- if (mRawImage.notNull())
- {
- sRawCount--;
- if(mForceToSaveRawImage)
- {
- saveRawImage() ;
- }
- setCachedRawImage() ;
- }
- mRawImage = NULL;
- mAuxRawImage = NULL;
- mIsRawImageValid = FALSE;
- mRawDiscardLevel = INVALID_DISCARD_LEVEL;
- if(mForceToSaveRawImage)
- {
- forceFetch() ;
- }
- }
- //use the mCachedRawImage to (re)generate the gl texture.
- //virtual
- void LLViewerFetchedTexture::switchToCachedImage()
- {
- if(mCachedRawImage.notNull())
- {
- mRawImage = mCachedRawImage ;
-
- if (getComponents() != mRawImage->getComponents())
- {
- // We've changed the number of components, so we need to move any
- // objects using this pool to a different pool.
- mComponents = mRawImage->getComponents();
- mGLTexturep->setComponents(mComponents) ;
- gTextureList.dirtyImage(this);
- }
- mIsRawImageValid = TRUE;
- mRawDiscardLevel = mCachedRawDiscardLevel ;
- gTextureList.mCreateTextureList.insert(this);
- mNeedsCreateTexture = TRUE;
- }
- }
- void LLViewerFetchedTexture::setCachedRawImage()
- {
- if(mRawImage == mCachedRawImage)
- {
- return ;
- }
- if(!mIsRawImageValid)
- {
- return ;
- }
- if(mCachedRawImageReady)
- {
- return ;
- }
- if(mCachedRawDiscardLevel < 0 || mCachedRawDiscardLevel > mRawDiscardLevel)
- {
- S32 i = 0 ;
- S32 w = mRawImage->getWidth() ;
- S32 h = mRawImage->getHeight() ;
- S32 max_size = MAX_CACHED_RAW_IMAGE_AREA ;
- if(LLViewerTexture::BOOST_TERRAIN == mBoostLevel)
- {
- max_size = MAX_CACHED_RAW_TERRAIN_IMAGE_AREA ;
- }
- if(mForSculpt)
- {
- max_size = MAX_CACHED_RAW_SCULPT_IMAGE_AREA ;
- mCachedRawImageReady = !mRawDiscardLevel ;
- }
- else
- {
- mCachedRawImageReady = (!mRawDiscardLevel || ((w * h) >= max_size)) ;
- }
- while(((w >> i) * (h >> i)) > max_size)
- {
- ++i ;
- }
-
- if(i)
- {
- if(!(w >> i) || !(h >> i))
- {
- --i ;
- }
-
- mRawImage->scale(w >> i, h >> i) ;
- }
- mCachedRawImage = mRawImage ;
- mRawDiscardLevel += i ;
- mCachedRawDiscardLevel = mRawDiscardLevel ;
- }
- }
- void LLViewerFetchedTexture::checkCachedRawSculptImage()
- {
- if(mCachedRawImageReady && mCachedRawDiscardLevel > 0)
- {
- if(getDiscardLevel() != 0)
- {
- mCachedRawImageReady = FALSE ;
- }
- else if(isForSculptOnly())
- {
- resetTextureStats() ; //do not update this image any more.
- }
- }
- }
- void LLViewerFetchedTexture::saveRawImage()
- {
- if(mRawImage.isNull() || mSavedRawDiscardLevel == mRawDiscardLevel)
- {
- return ;
- }
- mSavedRawDiscardLevel = mRawDiscardLevel ;
- mSavedRawImage = new LLImageRaw(mRawImage->getData(), mRawImage->getWidth(), mRawImage->getHeight(), mRawImage->getComponents()) ;
- if(mSavedRawDiscardLevel <= mDesiredSavedRawDiscardLevel)
- {
- mForceToSaveRawImage = FALSE ;
- }
- mLastReferencedSavedRawImageTime = sCurrentTime ;
- }
- void LLViewerFetchedTexture::forceToSaveRawImage(S32 desired_discard)
- {
- if(!mForceToSaveRawImage && (mDesiredSavedRawDiscardLevel < 0 || mDesiredSavedRawDiscardLevel > desired_discard))
- {
- mForceToSaveRawImage = TRUE ;
- mDesiredSavedRawDiscardLevel = desired_discard ;
-
- forceFetch() ;
- }
- }
- void LLViewerFetchedTexture::destroySavedRawImage()
- {
- mSavedRawImage = NULL ;
- mForceToSaveRawImage = FALSE ;
- mSavedRawDiscardLevel = -1 ;
- mDesiredSavedRawDiscardLevel = -1 ;
- mLastReferencedSavedRawImageTime = 0.0f ;
- }
- LLImageRaw* LLViewerFetchedTexture::getSavedRawImage()
- {
- mLastReferencedSavedRawImageTime = sCurrentTime ;
- return mSavedRawImage ;
- }
-
- BOOL LLViewerFetchedTexture::hasSavedRawImage() const
- {
- return mSavedRawImage.notNull() ;
- }
-
- F32 LLViewerFetchedTexture::getElapsedLastReferencedSavedRawImageTime() const
- {
- return sCurrentTime - mLastReferencedSavedRawImageTime ;
- }
- //----------------------------------------------------------------------------------------------
- //atlasing
- //----------------------------------------------------------------------------------------------
- void LLViewerFetchedTexture::resetFaceAtlas()
- {
- //Nothing should be done here.
- }
- //invalidate all atlas slots for this image.
- void LLViewerFetchedTexture::invalidateAtlas(BOOL rebuild_geom)
- {
- for(U32 i = 0 ; i < mNumFaces ; i++)
- {
- LLFace* facep = mFaceList[i] ;
- facep->removeAtlas() ;
- if(rebuild_geom && facep->getDrawable() && facep->getDrawable()->getSpatialGroup())
- {
- facep->getDrawable()->getSpatialGroup()->setState(LLSpatialGroup::GEOM_DIRTY);
- }
- }
- }
- BOOL LLViewerFetchedTexture::insertToAtlas()
- {
- if(!LLViewerTexture::sUseTextureAtlas)
- {
- return FALSE ;
- }
- if(getNumFaces() < 1)
- {
- return FALSE ;
- }
- if(mGLTexturep->getDiscardLevelInAtlas() > 0 && mRawDiscardLevel >= mGLTexturep->getDiscardLevelInAtlas())
- {
- return FALSE ;
- }
- if(!LLTextureAtlasManager::getInstance()->canAddToAtlas(mRawImage->getWidth(), mRawImage->getHeight(), mRawImage->getComponents(), mGLTexturep->getTexTarget()))
- {
- return FALSE ;
- }
- BOOL ret = TRUE ;//if ret is set to false, will generate a gl texture for this image.
- S32 raw_w = mRawImage->getWidth() ;
- S32 raw_h = mRawImage->getHeight() ;
- F32 xscale = 1.0f, yscale = 1.0f ;
- LLPointer<LLTextureAtlasSlot> slot_infop;
- LLTextureAtlasSlot* cur_slotp ;//no need to be smart pointer.
- LLSpatialGroup* groupp ;
- LLFace* facep;
- //if the atlas slot pointers for some faces are null, process them later.
- ll_face_list_t waiting_list ;
- for(U32 i = 0 ; i < mNumFaces ; i++)
- {
- {
- facep = mFaceList[i] ;
-
- //face can not use atlas.
- if(!facep->canUseAtlas())
- {
- if(facep->getAtlasInfo())
- {
- facep->removeAtlas() ;
- }
- ret = FALSE ;
- continue ;
- }
- //the atlas slot is updated
- slot_infop = facep->getAtlasInfo() ;
- groupp = facep->getDrawable()->getSpatialGroup() ;
- if(slot_infop)
- {
- if(slot_infop->getSpatialGroup() != groupp)
- {
- if((cur_slotp = groupp->getCurUpdatingSlot(this))) //switch slot
- {
- facep->setAtlasInfo(cur_slotp) ;
- facep->setAtlasInUse(TRUE) ;
- continue ;
- }
- else //do not forget to update slot_infop->getSpatialGroup().
- {
- LLSpatialGroup* gp = slot_infop->getSpatialGroup() ;
- gp->setCurUpdatingTime(gFrameCount) ;
- gp->setCurUpdatingTexture(this) ;
- gp->setCurUpdatingSlot(slot_infop) ;
- }
- }
- else //same group
- {
- if(gFrameCount && slot_infop->getUpdatedTime() == gFrameCount)//slot is just updated
- {
- facep->setAtlasInUse(TRUE) ;
- continue ;
- }
- }
- }
- else
- {
- //if the slot is null, wait to process them later.
- waiting_list.push_back(facep) ;
- continue ;
- }
-
- //----------
- //insert to atlas
- if(!slot_infop->getAtlas()->insertSubTexture(mGLTexturep, mRawDiscardLevel, mRawImage, slot_infop->getSlotCol(), slot_infop->getSlotRow()))
- {
-
- //the texture does not qualify to add to atlas, do not bother to try for other faces.
- //invalidateAtlas();
- return FALSE ;
- }
-
- //update texture scale
- slot_infop->getAtlas()->getTexCoordScale(raw_w, raw_h, xscale, yscale) ;
- slot_infop->setTexCoordScale(xscale, yscale) ;
- slot_infop->setValid() ;
- slot_infop->setUpdatedTime(gFrameCount) ;
-
- //update spatial group atlas info
- groupp->setCurUpdatingTime(gFrameCount) ;
- groupp->setCurUpdatingTexture(this) ;
- groupp->setCurUpdatingSlot(slot_infop) ;
- //make the face to switch to the atlas.
- facep->setAtlasInUse(TRUE) ;
- }
- }
- //process the waiting_list
- for(ll_face_list_t::iterator iter = waiting_list.begin(); iter != waiting_list.end(); ++iter)
- {
- facep = (LLFace*)*iter ;
- groupp = facep->getDrawable()->getSpatialGroup() ;
- //check if this texture already inserted to atlas for this group
- if((cur_slotp = groupp->getCurUpdatingSlot(this)))
- {
- facep->setAtlasInfo(cur_slotp) ;
- facep->setAtlasInUse(TRUE) ;
- continue ;
- }
- //need to reserve a slot from atlas
- slot_infop = LLTextureAtlasManager::getInstance()->reserveAtlasSlot(llmax(mFullWidth, mFullHeight), getComponents(), groupp, this) ;
- facep->setAtlasInfo(slot_infop) ;
-
- groupp->setCurUpdatingTime(gFrameCount) ;
- groupp->setCurUpdatingTexture(this) ;
- groupp->setCurUpdatingSlot(slot_infop) ;
- //slot allocation failed.
- if(!slot_infop || !slot_infop->getAtlas())
- {
- ret = FALSE ;
- facep->setAtlasInUse(FALSE) ;
- continue ;
- }
-
- //insert to atlas
- if(!slot_infop->getAtlas()->insertSubTexture(mGLTexturep, mRawDiscardLevel, mRawImage, slot_infop->getSlotCol(), slot_infop->getSlotRow()))
- {
- //the texture does not qualify to add to atlas, do not bother to try for other faces.
- ret = FALSE ;
- //invalidateAtlas();
- break ;
- }
-
- //update texture scale
- slot_infop->getAtlas()->getTexCoordScale(raw_w, raw_h, xscale, yscale) ;
- slot_infop->setTexCoordScale(xscale, yscale) ;
- slot_infop->setValid() ;
- slot_infop->setUpdatedTime(gFrameCount) ;
- //make the face to switch to the atlas.
- facep->setAtlasInUse(TRUE) ;
- }
-
- return ret ;
- }
- //----------------------------------------------------------------------------------------------
- //end of LLViewerFetchedTexture
- //----------------------------------------------------------------------------------------------
- //----------------------------------------------------------------------------------------------
- //start of LLViewerLODTexture
- //----------------------------------------------------------------------------------------------
- LLViewerLODTexture::LLViewerLODTexture(const LLUUID& id, const LLHost& host, BOOL usemipmaps)
- : LLViewerFetchedTexture(id, host, usemipmaps)
- {
- init(TRUE) ;
- }
- LLViewerLODTexture::LLViewerLODTexture(const std::string& url, const LLUUID& id, BOOL usemipmaps)
- : LLViewerFetchedTexture(url, id, usemipmaps)
- {
- init(TRUE) ;
- }
- void LLViewerLODTexture::init(bool firstinit)
- {
- mTexelsPerImage = 64.f*64.f;
- mDiscardVirtualSize = 0.f;
- mCalculatedDiscardLevel = -1.f;
- }
- //virtual
- S8 LLViewerLODTexture::getType() const
- {
- return LLViewerTexture::LOD_TEXTURE ;
- }
- BOOL LLViewerLODTexture::isUpdateFrozen()
- {
- return LLViewerTexture::sFreezeImageScalingDown && !getDiscardLevel() ;
- }
- // This is gauranteed to get called periodically for every texture
- //virtual
- void LLViewerLODTexture::processTextureStats()
- {
- updateVirtualSize() ;
- static LLCachedControl<bool> textures_fullres(gSavedSettings,"TextureLoadFullRes");
-
- if (textures_fullres)
- {
- mDesiredDiscardLevel = 0;
- }
- // Generate the request priority and render priority
- else if (mDontDiscard || !mUseMipMaps)
- {
- mDesiredDiscardLevel = 0;
- if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT)
- mDesiredDiscardLevel = 1; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048
- }
- else if (mBoostLevel < LLViewerTexture::BOOST_HIGH && mMaxVirtualSize <= 10.f)
- {
- // If the image has not been significantly visible in a while, we don't want it
- mDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel, (S8)(MAX_DISCARD_LEVEL + 1));
- }
- else if (!mFullWidth || !mFullHeight)
- {
- mDesiredDiscardLevel = getMaxDiscardLevel() ;
- }
- else
- {
- //static const F64 log_2 = log(2.0);
- static const F64 log_4 = log(4.0);
- S32 fullwidth = llmin(mFullWidth,(S32)MAX_IMAGE_SIZE_DEFAULT);
- S32 fullheight = llmin(mFullHeight,(S32)MAX_IMAGE_SIZE_DEFAULT);
- mTexelsPerImage = (F32)fullwidth * fullheight;
- F32 discard_level = 0.f;
- // If we know the output width and height, we can force the discard
- // level to the correct value, and thus not decode more texture
- // data than we need to.
- if (mKnownDrawWidth && mKnownDrawHeight)
- {
- S32 draw_texels = mKnownDrawWidth * mKnownDrawHeight;
- // Use log_4 because we're in square-pixel space, so an image
- // with twice the width and twice the height will have mTexelsPerImage
- // 4 * draw_size
- discard_level = (F32)(log(mTexelsPerImage/draw_texels) / log_4);
- }
- 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;
- }
- }
- if (mBoostLevel < LLViewerTexture::BOOST_HIGH)
- {
- discard_level += sDesiredDiscardBias;
- discard_level *= sDesiredDiscardScale; // scale
- discard_level += sCameraMovingDiscardBias ;
- }
- discard_level = floorf(discard_level);
- F32 min_discard = 0.f;
- if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT)
- min_discard = 1.f; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048
- discard_level = llclamp(discard_level, min_discard, (F32)MAX_DISCARD_LEVEL);
-
- // Can't go higher than the max discard level
- mDesiredDiscardLevel = llmin(getMaxDiscardLevel() + 1, (S32)discard_level);
- // Clamp to min desired discard
- mDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel, mDesiredDiscardLevel);
- //
- // At this point we've calculated the quality level that we want,
- // if possible. Now we check to see if we have it, and take the
- // proper action if we don't.
- //
- S32 current_discard = getDiscardLevel();
- if ((sDesiredDiscardBias > 0.0f) &&
- (current_discard >= 0 && mDesiredDiscardLevel >= current_discard))
- {
- // Limit the amount of GL memory bound each frame
- if ( BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) > sMaxBoundTextureMemInMegaBytes * texmem_middle_bound_scale &&
- (!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel))
- {
- scaleDown() ;
- }
- // Only allow GL to have 2x the video card memory
- else if ( BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) > sMaxTotalTextureMemInMegaBytes*texmem_middle_bound_scale &&
- (!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel))
- {
- scaleDown() ;
-
- }
- }
- }
- }
- void LLViewerLODTexture::scaleDown()
- {
- if(hasGLTexture() && mCachedRawDiscardLevel > getDiscardLevel())
- {
- switchToCachedImage() ;
- if(LLViewerTextureManager::sTesterp)
- {
- LLViewerTextureManager::sTesterp->setStablizingTime() ;
- }
- }
- }
- //----------------------------------------------------------------------------------------------
- //end of LLViewerLODTexture
- //----------------------------------------------------------------------------------------------
- //----------------------------------------------------------------------------------------------
- //start of LLViewerMediaTexture
- //----------------------------------------------------------------------------------------------
- //static
- void LLViewerMediaTexture::updateClass()
- {
- static const F32 MAX_INACTIVE_TIME = 30.f ;
- #if 0
- //force to play media.
- gSavedSettings.setBOOL("AudioStreamingMedia", true) ;
- #endif
- for(media_map_t::iterator iter = sMediaMap.begin() ; iter != sMediaMap.end(); )
- {
- LLViewerMediaTexture* mediap = iter->second;
-
- if(mediap->getNumRefs() == 1) //one reference by sMediaMap
- {
- //
- //Note: delay some time to delete the media textures to stop endlessly creating and immediately removing media texture.
- //
- if(mediap->getLastReferencedTimer()->getElapsedTimeF32() > MAX_INACTIVE_TIME)
- {
- media_map_t::iterator cur = iter++ ;
- sMediaMap.erase(cur) ;
- continue ;
- }
- }
- ++iter ;
- }
- }
- //static
- void LLViewerMediaTexture::removeMediaImplFromTexture(const LLUUID& media_id)
- {
- LLViewerMediaTexture* media_tex = findMediaTexture(media_id) ;
- if(media_tex)
- {
- media_tex->invalidateMediaImpl() ;
- }
- }
- //static
- void LLViewerMediaTexture::cleanup()
- {
- sMediaMap.clear() ;
- }
- //static
- LLViewerMediaTexture* LLViewerMediaTexture::findMediaTexture(const LLUUID& media_id)
- {
- media_map_t::iterator iter = sMediaMap.find(media_id);
- if(iter == sMediaMap.end())
- {
- return NULL;
- }
- LLViewerMediaTexture* media_tex = iter->second ;
- media_tex->setMediaImpl() ;
- media_tex->getLastReferencedTimer()->reset() ;
- return media_tex;
- }
- LLViewerMediaTexture::LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps, LLImageGL* gl_image)
- : LLViewerTexture(id, usemipmaps),
- mMediaImplp(NULL),
- mUpdateVirtualSizeTime(0)
- {
- sMediaMap.insert(std::make_pair(id, this));
- mGLTexturep = gl_image ;
- if(mGLTexturep.isNull())
- {
- generateGLTexture() ;
- }
- mGLTexturep->setNeedsAlphaAndPickMask(FALSE) ;
- mIsPlaying = FALSE ;
- setMediaImpl() ;
- setCategory(LLViewerTexture::MEDIA) ;
-
- LLViewerTexture* tex = gTextureList.findImage(mID) ;
- if(tex) //this media is a parcel media for tex.
- {
- tex->setParcelMedia(this) ;
- }
- }
- //virtual
- LLViewerMediaTexture::~LLViewerMediaTexture()
- {
- LLViewerTexture* tex = gTextureList.findImage(mID) ;
- if(tex) //this media is a parcel media for tex.
- {
- tex->setParcelMedia(NULL) ;
- }
- }
- void LLViewerMediaTexture::reinit(BOOL usemipmaps /* = TRUE */)
- {
- llassert(mGLTexturep.notNull()) ;
- mUseMipMaps = usemipmaps ;
- getLastReferencedTimer()->reset() ;
- mGLTexturep->setUseMipMaps(mUseMipMaps) ;
- mGLTexturep->setNeedsAlphaAndPickMask(FALSE) ;
- }
- void LLViewerMediaTexture::setUseMipMaps(BOOL mipmap)
- {
- mUseMipMaps = mipmap;
- if(mGLTexturep.notNull())
- {
- mGLTexturep->setUseMipMaps(mipmap) ;
- }
- }
- //virtual
- S8 LLViewerMediaTexture::getType() const
- {
- return LLViewerTexture::MEDIA_TEXTURE ;
- }
- void LLViewerMediaTexture::invalidateMediaImpl()
- {
- mMediaImplp = NULL ;
- }
- void LLViewerMediaTexture::setMediaImpl()
- {
- if(!mMediaImplp)
- {
- mMediaImplp = LLViewerMedia::getMediaImplFromTextureID(mID) ;
- }
- }
- //return true if all faces to reference to this media texture are found
- //Note: mMediaFaceList is valid only for the current instant
- // because it does not check the face validity after the current frame.
- BOOL LLViewerMediaTexture::findFaces()
- {
- mMediaFaceList.clear() ;
- BOOL ret = TRUE ;
-
- LLViewerTexture* tex = gTextureList.findImage(mID) ;
- if(tex) //this media is a parcel media for tex.
- {
- const ll_face_list_t* face_list = tex->getFaceList() ;
- U32 end = tex->getNumFaces() ;
- for(U32 i = 0 ; i < end ; i++)
- {
- mMediaFaceList.push_back((*face_list)[i]) ;
- }
- }
-
- if(!mMediaImplp)
- {
- return TRUE ;
- }
- //for media on a face.
- const std::list< LLVOVolume* >* obj_list = mMediaImplp->getObjectList() ;
- std::list< LLVOVolume* >::const_iterator iter = obj_list->begin() ;
- for(; iter != obj_list->end(); ++iter)
- {
- LLVOVolume* obj = *iter ;
- if(obj->mDrawable.isNull())
- {
- ret = FALSE ;
- continue ;
- }
- S32 face_id = -1 ;
- S32 num_faces = obj->mDrawable->getNumFaces() ;
- while((face_id = obj->getFaceIndexWithMediaImpl(mMediaImplp, face_id)) > -1 && face_id < num_faces)
- {
- LLFace* facep = obj->mDrawable->getFace(face_id) ;
- if(facep)
- {
- mMediaFaceList.push_back(facep) ;
- }
- else
- {
- ret = FALSE ;
- }
- }
- }
- return ret ;
- }
- void LLViewerMediaTexture::initVirtualSize()
- {
- if(mIsPlaying)
- {
- return ;
- }
- findFaces() ;
- for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter)
- {
- addTextureStats((*iter)->getVirtualSize()) ;
- }
- }
- void LLViewerMediaTexture::addMediaToFace(LLFace* facep)
- {
- if(facep)
- {
- facep->setHasMedia(true) ;
- }
- if(!mIsPlaying)
- {
- return ; //no need to add the face because the media is not in playing.
- }
- switchTexture(facep) ;
- }
-
- void LLViewerMediaTexture::removeMediaFromFace(LLFace* facep)
- {
- if(!facep)
- {
- return ;
- }
- facep->setHasMedia(false) ;
- if(!mIsPlaying)
- {
- return ; //no need to remove the face because the media is not in playing.
- }
- mIsPlaying = FALSE ; //set to remove the media from the face.
- switchTexture(facep) ;
- mIsPlaying = TRUE ; //set the flag back.
- if(getNumFaces() < 1) //no face referencing to this media
- {
- stopPlaying() ;
- }
- }
- //virtual
- void LLViewerMediaTexture::addFace(LLFace* facep)
- {
- LLViewerTexture::addFace(facep) ;
- const LLTextureEntry* te = facep->getTextureEntry() ;
- if(te && te->getID().notNull())
- {
- LLViewerTexture* tex = gTextureList.findImage(te->getID()) ;
- if(tex)
- {
- mTextureList.push_back(tex) ;//increase the reference number by one for tex to avoid deleting it.
- return ;
- }
- }
- //check if it is a parcel media
- if(facep->getTexture() && facep->getTexture() != this && facep->getTexture()->getID() == mID)
- {
- mTextureList.push_back(facep->getTexture()) ; //a parcel media.
- return ;
- }
-
- if(te && te->getID().notNull()) //should have a texture
- {
- llerrs << "The face does not have a valid texture before media texture." << llendl ;
- }
- }
- //virtual
- void LLViewerMediaTexture::removeFace(LLFace* facep)
- {
- LLViewerTexture::removeFace(facep) ;
- const LLTextureEntry* te = facep->getTextureEntry() ;
- if(te && te->getID().notNull())
- {
- LLViewerTexture* tex = gTextureList.findImage(te->getID()) ;
- if(tex)
- {
- for(std::list< LLPointer<LLViewerTexture> >::iterator iter = mTextureList.begin();
- iter != mTextureList.end(); ++iter)
- {
- if(*iter == tex)
- {
- mTextureList.erase(iter) ; //decrease the reference number for tex by one.
- return ;
- }
- }
- //
- //we have some trouble here: the texture of the face is changed.
- //we need to find the former texture, and remove it from the list to avoid memory leaking.
- if(!mNumFaces)
- {
- mTextureList.clear() ;
- return ;
- }
- S32 end = getNumFaces() ;
- std::vector<const LLTextureEntry*> te_list(end) ;
- S32 i = 0 ;
- for(U32 j = 0 ; j < mNumFaces ; j++)
- {
- te_list[i++] = mFaceList[j]->getTextureEntry() ;//all textures are in use.
- }
- for(std::list< LLPointer<LLViewerTexture> >::iterator iter = mTextureList.begin();
- iter != mTextureList.end(); ++iter)
- {
- for(i = 0 ; i < end ; i++)
- {
- if(te_list[i] && te_list[i]->getID() == (*iter)->getID())//the texture is in use.
- {
- te_list[i] = NULL ;
- break ;
- }
- }
- if(i == end) //no hit for this texture, remove it.
- {
- mTextureList.erase(iter) ; //decrease the reference number for tex by one.
- return ;
- }
- }
- }
- }
- //check if it is a parcel media
- for(std::list< LLPointer<LLViewerTexture> >::iterator iter = mTextureList.begin();
- iter != mTextureList.end(); ++iter)
- {
- if((*iter)->getID() == mID)
- {
- mTextureList.erase(iter) ; //decrease the reference number for tex by one.
- return ;
- }
- }
- if(te && te->getID().notNull()) //should have a texture
- {
- llerrs << "mTextureList texture reference number is corrupted." << llendl ;
- }
- }
- void LLViewerMediaTexture::stopPlaying()
- {
- // Don't stop the media impl playing here -- this breaks non-inworld media (login screen, search, and media browser).
- // if(mMediaImplp)
- // {
- // mMediaImplp->stop() ;
- // }
- mIsPlaying = FALSE ;
- }
- void LLViewerMediaTexture::switchTexture(LLFace* facep)
- {
- if(facep)
- {
- //check if another media is playing on this face.
- if(facep->getTexture() && facep->getTexture() != this
- && facep->getTexture()->getType() == LLViewerTexture::MEDIA_TEXTURE)
- {
- if(mID == facep->getTexture()->getID()) //this is a parcel media
- {
- return ; //let the prim media win.
- }
- }
- if(mIsPlaying) //old textures switch to the media texture
- {
- facep->switchTexture(this) ;
- }
- else //switch to old textures.
- {
- const LLTextureEntry* te = facep->getTextureEntry() ;
- if(te)
- {
- LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID()) : NULL ;
- if(!tex && te->getID() != mID)//try parcel media.
- {
- tex = gTextureList.findImage(mID) ;
- }
- if(!tex)
- {
- tex = LLViewerFetchedTexture::sDefaultImagep ;
- }
- facep->switchTexture(tex) ;
- }
- }
- }
- }
- void LLViewerMediaTexture::setPlaying(BOOL playing)
- {
- if(!mMediaImplp)
- {
- return ;
- }
- if(!playing && !mIsPlaying)
- {
- return ; //media is already off
- }
- if(playing == mIsPlaying && !mMediaImplp->isUpdated())
- {
- return ; //nothing has changed since last time.
- }
- mIsPlaying = playing ;
- if(mIsPlaying) //is about to play this media
- {
- if(findFaces())
- {
- //about to update all faces.
- mMediaImplp->setUpdated(FALSE) ;
- }
- if(mMediaFaceList.empty())//no face pointing to this media
- {
- stopPlaying() ;
- return ;
- }
- for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter)
- {
- switchTexture(*iter) ;
- }
- }
- else //stop playing this media
- {
- for(U32 i = mNumFaces ; i ; i--)
- {
- switchTexture(mFaceList[i - 1]) ; //current face could be removed in this function.
- }
- }
- return ;
- }
- //virtual
- F32 LLViewerMediaTexture::getMaxVirtualSize()
- {
- if(LLFrameTimer::getFrameCount() == mUpdateVirtualSizeTime)
- {
- return mMaxVirtualSize ;
- }
- mUpdateVirtualSizeTime = LLFrameTimer::getFrameCount() ;
- if(mNeedsResetMaxVirtualSize)
- {
- addTextureStats(0.f, FALSE) ;//reset
- }
- if(mIsPlaying) //media is playing
- {
- for(U32 i = 0 ; i < mNumFaces ; i++)
- {
- LLFace* facep = mFaceList[i] ;
- if(facep->getDrawable()->isRecentlyVisible())
- {
- addTextureStats(facep->getVirtualSize()) ;
- }
- }
- }
- else //media is not in playing
- {
- findFaces() ;
-
- if(!mMediaFaceList.empty())
- {
- for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter)
- {
- LLFace* facep = *iter ;
- if(facep->getDrawable()->isRecentlyVisible())
- {
- addTextureStats(facep->getVirtualSize()) ;
- }
- }
- }
- }
- mNeedsResetMaxVirtualSize = TRUE ;
- reorganizeFaceList() ;
- reorganizeVolumeList();
- return mMaxVirtualSize ;
- }
- //----------------------------------------------------------------------------------------------
- //end of LLViewerMediaTexture
- //----------------------------------------------------------------------------------------------
- //----------------------------------------------------------------------------------------------
- //start of LLTexturePipelineTester
- //----------------------------------------------------------------------------------------------
- LLTexturePipelineTester::LLTexturePipelineTester() :
- LLMetricPerformanceTester("TextureTester", FALSE)
- {
- addMetricString("TotalBytesLoaded") ;
- addMetricString("TotalBytesLoadedFromCache") ;
- addMetricString("TotalBytesLoadedForLargeImage") ;
- addMetricString("TotalBytesLoadedForSculpties") ;
- addMetricString("StartFetchingTime") ;
- addMetricString("TotalGrayTime") ;
- addMetricString("TotalStablizingTime") ;
- addMetricString("StartTimeLoadingSculpties") ;
- addMetricString("EndTimeLoadingSculpties") ;
- addMetricString("Time") ;
- addMetricString("TotalBytesBound") ;
- addMetricString("TotalBytesBoundForLargeImage") ;
- addMetricString("PercentageBytesBound") ;
-
- mTotalBytesLoaded = 0 ;
- mTotalBytesLoadedFromCache = 0 ;
- mTotalBytesLoadedForLargeImage = 0 ;
- mTotalBytesLoadedForSculpties = 0 ;
- reset() ;
- }
- LLTexturePipelineTester::~LLTexturePipelineTester()
- {
- LLViewerTextureManager::sTesterp = NULL ;
- }
- void LLTexturePipelineTester::update()
- {
- mLastTotalBytesUsed = mTotalBytesUsed ;
- mLastTotalBytesUsedForLargeImage = mTotalBytesUsedForLargeImage ;
- mTotalBytesUsed = 0 ;
- mTotalBytesUsedForLargeImage = 0 ;
-
- if(LLAppViewer::getTextureFetch()->getNumRequests() > 0) //fetching list is not empty
- {
- if(mPause)
- {
- //start a new fetching session
- reset() ;
- mStartFetchingTime = LLImageGL::sLastFrameTime ;
- mPause = FALSE ;
- }
- //update total gray time
- if(mUsingDefaultTexture)
- {
- mUsingDefaultTexture = FALSE ;
- mTotalGrayTime = LLImageGL::sLastFrameTime - mStartFetchingTime ;
- }
- //update the stablizing timer.
- updateStablizingTime() ;
- outputTestResults() ;
- }
- else if(!mPause)
- {
- //stop the current fetching session
- mPause = TRUE ;
- outputTestResults() ;
- reset() ;
- }
- }
-
- void LLTexturePipelineTester::reset()
- {
- mPause = TRUE ;
- mUsingDefaultTexture = FALSE ;
- mStartStablizingTime = 0.0f ;
- mEndStablizingTime = 0.0f ;
- mTotalBytesUsed = 0 ;
- mTotalBytesUsedForLargeImage = 0 ;
- mLastTotalBytesUsed = 0 ;
- mLastTotalBytesUsedForLargeImage = 0 ;
-
- mStartFetchingTime = 0.0f ;
-
- mTotalGrayTime = 0.0f ;
- mTotalStablizingTime = 0.0f ;
- mStartTimeLoadingSculpties = 1.0f ;
- mEndTimeLoadingSculpties = 0.0f ;
- }
- //virtual
- void LLTexturePipelineTester::outputTestRecord(LLSD *sd)
- {
- (*sd)[mCurLabel]["TotalBytesLoaded"] = (LLSD::Integer)mTotalBytesLoaded ;
- (*sd)[mCurLabel]["TotalBytesLoadedFromCache"] = (LLSD::Integer)mTotalBytesLoadedFromCache ;
- (*sd)[mCurLabel]["TotalBytesLoadedForLargeImage"] = (LLSD::Integer)mTotalBytesLoadedForLargeImage ;
- (*sd)[mCurLabel]["TotalBytesLoadedForSculpties"] = (LLSD::Integer)mTotalBytesLoadedForSculpties ;
- (*sd)[mCurLabel]["StartFetchingTime"] = (LLSD::Real)mStartFetchingTime ;
- (*sd)[mCurLabel]["TotalGrayTime"] = (LLSD::Real)mTotalGrayTime ;
- (*sd)[mCurLabel]["TotalStablizingTime"] = (LLSD::Real)mTotalStablizingTime ;
- (*sd)[mCurLabel]["StartTimeLoadingSculpties"] = (LLSD::Real)mStartTimeLoadingSculpties ;
- (*sd)[mCurLabel]["EndTimeLoadingSculpties"] = (LLSD::Real)mEndTimeLoadingSculpties ;
- (*sd)[mCurLabel]["Time"] = LLImageGL::sLastFrameTime ;
- (*sd)[mCurLabel]["TotalBytesBound"] = (LLSD::Integer)mLastTotalBytesUsed ;
- (*sd)[mCurLabel]["TotalBytesBoundForLargeImage"] = (LLSD::Integer)mLastTotalBytesUsedForLargeImage ;
- (*sd)[mCurLabel]["PercentageBytesBound"] = (LLSD::Real)(100.f * mLastTotalBytesUsed / mTotalBytesLoaded) ;
- }
- void LLTexturePipelineTester::updateTextureBindingStats(const LLViewerTexture* imagep)
- {
- U32 mem_size = (U32)imagep->getTextureMemory() ;
- mTotalBytesUsed += mem_size ;
- if(MIN_LARGE_IMAGE_AREA <= (U32)(mem_size / (U32)imagep->getComponents()))
- {
- mTotalBytesUsedForLargeImage += mem_size ;
- }
- }
-
- void LLTexturePipelineTester::updateTextureLoadingStats(const LLViewerFetchedTexture* imagep, const LLImageRaw* raw_imagep, BOOL from_cache)
- {
- U32 data_size = (U32)raw_imagep->getDataSize() ;
- mTotalBytesLoaded += data_size ;
- if(from_cache)
- {
- mTotalBytesLoadedFromCache += data_size ;
- }
- if(MIN_LARGE_IMAGE_AREA <= (U32)(data_size / (U32)raw_imagep->getComponents()))
- {
- mTotalBytesLoadedForLargeImage += data_size ;
- }
- if(imagep->forSculpt())
- {
- mTotalBytesLoadedForSculpties += data_size ;
- if(mStartTimeLoadingSculpties > mEndTimeLoadingSculpties)
- {
- mStartTimeLoadingSculpties = LLImageGL::sLastFrameTime ;
- }
- mEndTimeLoadingSculpties = LLImageGL::sLastFrameTime ;
- }
- }
- void LLTexturePipelineTester::updateGrayTextureBinding()
- {
- mUsingDefaultTexture = TRUE ;
- }
- void LLTexturePipelineTester::setStablizingTime()
- {
- if(mStartStablizingTime <= mStartFetchingTime)
- {
- mStartStablizingTime = LLImageGL::sLastFrameTime ;
- }
- mEndStablizingTime = LLImageGL::sLastFrameTime ;
- }
- void LLTexturePipelineTester::updateStablizingTime()
- {
- if(mStartStablizingTime > mStartFetchingTime)
- {
- F32 t = mEndStablizingTime - mStartStablizingTime ;
- if(t > 0.0001f && (t - mTotalStablizingTime) < 0.0001f)
- {
- //already stablized
- mTotalStablizingTime = LLImageGL::sLastFrameTime - mStartStablizingTime ;
- //cancel the timer
- mStartStablizingTime = 0.f ;
- mEndStablizingTime = 0.f ;
- }
- else
- {
- mTotalStablizingTime = t ;
- }
- }
- mTotalStablizingTime = 0.f ;
- }
- //virtual
- void LLTexturePipelineTester::compareTestSessions(std::ofstream* os)
- {
- LLTexturePipelineTester::LLTextureTestSession* base_sessionp = dynamic_cast<LLTexturePipelineTester::LLTextureTestSession*>(mBaseSessionp) ;
- LLTexturePipelineTester::LLTextureTestSession* current_sessionp = dynamic_cast<LLTexturePipelineTester::LLTextureTestSession*>(mCurrentSessionp) ;
- if(!base_sessionp || !current_sessionp)
- {
- llerrs << "type of test session does not match!" << llendl ;
- }
- //compare and output the comparison
- *os << llformat("%sn", mName.c_str()) ;
- *os << llformat("AggregateResultsn") ;
- 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) ;
- compareTestResults(os, "TotalTimeLoadingSculpties", base_sessionp->mTotalTimeLoadingSculpties, current_sessionp->mTotalTimeLoadingSculpties) ;
-
- compareTestResults(os, "TotalBytesLoaded", base_sessionp->mTotalBytesLoaded, current_sessionp->mTotalBytesLoaded) ;
- compareTestResults(os, "TotalBytesLoadedFromCache", base_sessionp->mTotalBytesLoadedFromCache, current_sessionp->mTotalBytesLoadedFromCache) ;
- compareTestResults(os, "TotalBytesLoadedForLargeImage", base_sessionp->mTotalBytesLoadedForLargeImage, current_sessionp->mTotalBytesLoadedForLargeImage) ;
- compareTestResults(os, "TotalBytesLoadedForSculpties", base_sessionp->mTotalBytesLoadedForSculpties, current_sessionp->mTotalBytesLoadedForSculpties) ;
-
- *os << llformat("InstantResultsn") ;
- S32 size = llmin(base_sessionp->mInstantPerformanceListCounter, current_sessionp->mInstantPerformanceListCounter) ;
- for(S32 i = 0 ; i < size ; i++)
- {
- *os << llformat("Time(B-T)-%.4f-%.4fn", base_sessionp->mInstantPerformanceList[i].mTime, current_sessionp->mInstantPerformanceList[i].mTime) ;
- compareTestResults(os, "AverageBytesUsedPerSecond", base_sessionp->mInstantPerformanceList[i].mAverageBytesUsedPerSecond,
- current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedPerSecond) ;
-
- compareTestResults(os, "AverageBytesUsedForLargeImagePerSecond", base_sessionp->mInstantPerformanceList[i].mAverageBytesUsedForLargeImagePerSecond,
- current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedForLargeImagePerSecond) ;
-
- compareTestResults(os, "AveragePercentageBytesUsedPerSecond", base_sessionp->mInstantPerformanceList[i].mAveragePercentageBytesUsedPerSecond,
- current_sessionp->mInstantPerformanceList[i].mAveragePercentageBytesUsedPerSecond) ;
- }
-
- if(size < base_sessionp->mInstantPerformanceListCounter)
- {
- for(S32 i = size ; i < base_sessionp->mInstantPerformanceListCounter ; i++)
- {
- *os << llformat("Time(B-T)-%.4f- n", base_sessionp->mInstantPerformanceList[i].mTime) ;
- *os << llformat(", AverageBytesUsedPerSecond, %d, N/A n", base_sessionp->mInstantPerformanceList[i].mAverageBytesUsedPerSecond) ;
- *os << llformat(", AverageBytesUsedForLargeImagePerSecond, %d, N/A n", base_sessionp->mInstantPerformanceList[i].mAverageBytesUsedForLargeImagePerSecond) ;
- *os << llformat(", AveragePercentageBytesUsedPerSecond, %.4f, N/A n", base_sessionp->mInstantPerformanceList[i].mAveragePercentageBytesUsedPerSecond) ;
- }
- }
- else if(size < current_sessionp->mInstantPerformanceListCounter)
- {
- for(S32 i = size ; i < current_sessionp->mInstantPerformanceListCounter ; i++)
- {
- *os << llformat("Time(B-T)- -%.4fn", current_sessionp->mInstantPerformanceList[i].mTime) ;
- *os << llformat(", AverageBytesUsedPerSecond, N/A, %dn", current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedPerSecond) ;
- *os << llformat(", AverageBytesUsedForLargeImagePerSecond, N/A, %dn", current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedForLargeImagePerSecond) ;
- *os << llformat(", AveragePercentageBytesUsedPerSecond, N/A, %.4fn", current_sessionp->mInstantPerformanceList[i].mAveragePercentageBytesUsedPerSecond) ;
- }
- }
- }
- //virtual
- LLMetricPerformanceTester::LLTestSession* LLTexturePipelineTester::loadTestSession(LLSD* log)
- {
- LLTexturePipelineTester::LLTextureTestSession* sessionp = new LLTexturePipelineTester::LLTextureTestSession() ;
- if(!sessionp)
- {
- 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 ;
- F32 start_fetching_time = -1.f ;
- F32 start_fetching_sculpties_time = 0.f ;
- F32 last_time = 0.0f ;
- S32 frame_count = 0 ;
- sessionp->mInstantPerformanceListCounter = 0 ;
- sessionp->mInstantPerformanceList.resize(128) ;
- sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedPerSecond = 0 ;
- sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond = 0 ;
- sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond = 0.f ;
- sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mTime = 0.f ;
-
- //load a session
- BOOL in_log = (*log).has(mCurLabel) ;
- while(in_log)
- {
- LLSD::String label = mCurLabel ;
- incLabel() ;
- in_log = (*log).has(mCurLabel) ;
- if(sessionp->mInstantPerformanceListCounter >= (S32)sessionp->mInstantPerformanceList.size())
- {
- sessionp->mInstantPerformanceList.resize(sessionp->mInstantPerformanceListCounter + 128) ;
- }
-
- //time
- F32 start_time = (*log)[label]["StartFetchingTime"].asReal() ;
- F32 cur_time = (*log)[label]["Time"].asReal() ;
- if(start_time - start_fetching_time > 0.0001f) //fetching has paused for a while
- {
- sessionp->mTotalFetchingTime += total_fetching_time ;
- sessionp->mTotalGrayTime += total_gray_time ;
- sessionp->mTotalStablizingTime += total_stablizing_time ;
- sessionp->mStartTimeLoadingSculpties = start_fetching_sculpties_time ;
- 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() ;
- total_loading_sculpties_time = (*log)[label]["EndTimeLoadingSculpties"].asReal() - (*log)[label]["StartTimeLoadingSculpties"].asReal() ;
- if(start_fetching_sculpties_time < 0.f && total_loading_sculpties_time > 0.f)
- {
- start_fetching_sculpties_time = (*log)[label]["StartTimeLoadingSculpties"].asReal() ;
- }
- }
-
- //total loaded bytes
- sessionp->mTotalBytesLoaded = (*log)[label]["TotalBytesLoaded"].asInteger() ;
- sessionp->mTotalBytesLoadedFromCache = (*log)[label]["TotalBytesLoadedFromCache"].asInteger() ;
- sessionp->mTotalBytesLoadedForLargeImage = (*log)[label]["TotalBytesLoadedForLargeImage"].asInteger() ;
- sessionp->mTotalBytesLoadedForSculpties = (*log)[label]["TotalBytesLoadedForSculpties"].asInteger() ;
- //instant metrics
- sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedPerSecond +=
- (*log)[label]["TotalBytesBound"].asInteger() ;
- sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond +=
- (*log)[label]["TotalBytesBoundForLargeImage"].asInteger() ;
- sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond +=
- (*log)[label]["PercentageBytesBound"].asReal() ;
- frame_count++ ;
- if(cur_time - last_time >= 1.0f)
- {
- sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedPerSecond /= frame_count ;
- sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond /= frame_count ;
- sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond /= frame_count ;
- sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mTime = last_time ;
- frame_count = 0 ;
- last_time = cur_time ;
- sessionp->mInstantPerformanceListCounter++ ;
- sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedPerSecond = 0 ;
- sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond = 0 ;
- sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond = 0.f ;
- sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mTime = 0.f ;
- }
- }
- sessionp->mTotalFetchingTime += total_fetching_time ;
- sessionp->mTotalGrayTime += total_gray_time ;
- sessionp->mTotalStablizingTime += total_stablizing_time ;
- if(sessionp->mStartTimeLoadingSculpties < 0.f)
- {
- sessionp->mStartTimeLoadingSculpties = start_fetching_sculpties_time ;
- }
- sessionp->mTotalTimeLoadingSculpties += total_loading_sculpties_time ;
- return sessionp;
- }
- LLTexturePipelineTester::LLTextureTestSession::LLTextureTestSession()
- {
- reset() ;
- }
- LLTexturePipelineTester::LLTextureTestSession::~LLTextureTestSession()
- {
- }
- void LLTexturePipelineTester::LLTextureTestSession::reset()
- {
- mTotalFetchingTime = 0.0f ;
- mTotalGrayTime = 0.0f ;
- mTotalStablizingTime = 0.0f ;
- mStartTimeLoadingSculpties = 0.0f ;
- mTotalTimeLoadingSculpties = 0.0f ;
- mTotalBytesLoaded = 0 ;
- mTotalBytesLoadedFromCache = 0 ;
- mTotalBytesLoadedForLargeImage = 0 ;
- mTotalBytesLoadedForSculpties = 0 ;
- mInstantPerformanceListCounter = 0 ;
- }
- //----------------------------------------------------------------------------------------------
- //end of LLTexturePipelineTester
- //----------------------------------------------------------------------------------------------