diff options
Diffstat (limited to 'indra/newview/llviewertexture.cpp')
-rwxr-xr-x[-rw-r--r--] | indra/newview/llviewertexture.cpp | 1085 |
1 files changed, 433 insertions, 652 deletions
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 61236edc86..693eca8a06 100644..100755 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -39,7 +39,6 @@ #include "llimagebmp.h" #include "llimagej2c.h" #include "llimagetga.h" -#include "llmemtype.h" #include "llstl.h" #include "llvfile.h" #include "llvfs.h" @@ -56,21 +55,23 @@ #include "llappviewer.h" #include "llface.h" #include "llviewercamera.h" -#include "lltextureatlas.h" -#include "lltextureatlasmanager.h" #include "lltextureentry.h" +#include "lltexturemanagerbridge.h" #include "llmediaentry.h" #include "llvovolume.h" #include "llviewermedia.h" +#include "lltexturecache.h" /////////////////////////////////////////////////////////////////////////////// // statics LLPointer<LLViewerTexture> LLViewerTexture::sNullImagep = NULL; LLPointer<LLViewerTexture> LLViewerTexture::sBlackImagep = NULL; +LLPointer<LLViewerTexture> LLViewerTexture::sCheckerBoardImagep = NULL; LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sMissingAssetImagep = NULL; LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sWhiteImagep = NULL; LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sDefaultImagep = NULL; LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sSmokeImagep = NULL; +LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sFlatNormalImagep = NULL; LLViewerMediaTexture::media_map_t LLViewerMediaTexture::sMediaMap ; LLTexturePipelineTester* LLViewerTextureManager::sTesterp = NULL ; const std::string sTesterName("TextureTester"); @@ -87,6 +88,7 @@ S32 LLViewerTexture::sMaxBoundTextureMemInMegaBytes = 0; S32 LLViewerTexture::sMaxTotalTextureMemInMegaBytes = 0; S32 LLViewerTexture::sMaxDesiredTextureMemInBytes = 0 ; S8 LLViewerTexture::sCameraMovingDiscardBias = 0 ; +F32 LLViewerTexture::sCameraMovingBias = 0.0f ; 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 ; @@ -95,7 +97,9 @@ 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 ; +F32 LLViewerTexture::sTexelPixelRatio = 1.0f; + +LLViewerTexture::EDebugTexels LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_OFF; const F32 desired_discard_bias_min = -2.0f; // -max number of levels to improve image quality by const F32 desired_discard_bias_max = (F32)MAX_DISCARD_LEVEL; // max number of levels to reduce image quality by @@ -175,7 +179,12 @@ LLViewerTexture* LLViewerTextureManager::findTexture(const LLUUID& id) } return tex ; } - + +LLViewerFetchedTexture* LLViewerTextureManager::findFetchedTexture(const LLUUID& id) +{ + return gTextureList.findImage(id); +} + LLViewerMediaTexture* LLViewerTextureManager::findMediaTexture(const LLUUID &media_id) { return LLViewerMediaTexture::findMediaTexture(media_id) ; @@ -221,7 +230,7 @@ LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(BOOL usemipma if(generate_gl_tex) { tex->generateGLTexture() ; - tex->setCategory(LLViewerTexture::LOCAL) ; + tex->setCategory(LLGLTexture::LOCAL) ; } return tex ; } @@ -231,14 +240,14 @@ LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const LLUUID& if(generate_gl_tex) { tex->generateGLTexture() ; - tex->setCategory(LLViewerTexture::LOCAL) ; + tex->setCategory(LLGLTexture::LOCAL) ; } return tex ; } LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const LLImageRaw* raw, BOOL usemipmaps) { LLPointer<LLViewerTexture> tex = new LLViewerTexture(raw, usemipmaps) ; - tex->setCategory(LLViewerTexture::LOCAL) ; + tex->setCategory(LLGLTexture::LOCAL) ; return tex ; } LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex) @@ -247,13 +256,14 @@ LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const U32 wid if(generate_gl_tex) { tex->generateGLTexture() ; - tex->setCategory(LLViewerTexture::LOCAL) ; + tex->setCategory(LLGLTexture::LOCAL) ; } return tex ; } LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture( const LLUUID &image_id, + FTType f_type, BOOL usemipmaps, LLViewerTexture::EBoostLevel boost_priority, S8 texture_type, @@ -261,11 +271,12 @@ LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture( LLGLenum primary_format, LLHost request_from_host) { - return gTextureList.getImage(image_id, usemipmaps, boost_priority, texture_type, internal_format, primary_format, request_from_host) ; + return gTextureList.getImage(image_id, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, request_from_host) ; } LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromFile( const std::string& filename, + FTType f_type, BOOL usemipmaps, LLViewerTexture::EBoostLevel boost_priority, S8 texture_type, @@ -273,11 +284,12 @@ LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromFile( LLGLenum primary_format, const LLUUID& force_id) { - return gTextureList.getImageFromFile(filename, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id) ; + return gTextureList.getImageFromFile(filename, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id) ; } //static LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string& url, + FTType f_type, BOOL usemipmaps, LLViewerTexture::EBoostLevel boost_priority, S8 texture_type, @@ -286,14 +298,34 @@ LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const s const LLUUID& force_id ) { - return gTextureList.getImageFromUrl(url, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id) ; + return gTextureList.getImageFromUrl(url, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id) ; } -LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromHost(const LLUUID& image_id, LLHost host) +LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromHost(const LLUUID& image_id, FTType f_type, LLHost host) { - return gTextureList.getImageFromHost(image_id, host) ; + return gTextureList.getImageFromHost(image_id, f_type, host) ; } +// Create a bridge to the viewer texture manager. +class LLViewerTextureManagerBridge : public LLTextureManagerBridge +{ + /*virtual*/ LLPointer<LLGLTexture> getLocalTexture(BOOL usemipmaps = TRUE, BOOL generate_gl_tex = TRUE) + { + return LLViewerTextureManager::getLocalTexture(usemipmaps, generate_gl_tex); + } + + /*virtual*/ LLPointer<LLGLTexture> getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) + { + return LLViewerTextureManager::getLocalTexture(width, height, components, usemipmaps, generate_gl_tex); + } + + /*virtual*/ LLGLTexture* getFetchedTexture(const LLUUID &image_id) + { + return LLViewerTextureManager::getFetchedTexture(image_id); + } +}; + + void LLViewerTextureManager::init() { { @@ -339,16 +371,34 @@ void LLViewerTextureManager::init() imagep->setCachedRawImage(0, image_raw) ; image_raw = NULL; #else - LLViewerFetchedTexture::sDefaultImagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, LLViewerTexture::BOOST_UI); + LLViewerFetchedTexture::sDefaultImagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, LLGLTexture::BOOST_UI); #endif LLViewerFetchedTexture::sDefaultImagep->dontDiscard(); - LLViewerFetchedTexture::sDefaultImagep->setCategory(LLViewerTexture::OTHER) ; + LLViewerFetchedTexture::sDefaultImagep->setCategory(LLGLTexture::OTHER) ; - LLViewerFetchedTexture::sSmokeImagep = LLViewerTextureManager::getFetchedTexture(IMG_SMOKE, TRUE, LLViewerTexture::BOOST_UI); + LLViewerFetchedTexture::sSmokeImagep = LLViewerTextureManager::getFetchedTexture(IMG_SMOKE, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); LLViewerFetchedTexture::sSmokeImagep->setNoDelete() ; + image_raw = new LLImageRaw(32,32,3); + data = image_raw->getData(); + + for (S32 i = 0; i < (32*32*3); i+=3) + { + S32 x = (i % (32*3)) / (3*16); + S32 y = i / (32*3*16); + U8 color = ((x + y) % 2) * 255; + data[i] = color; + data[i+1] = color; + data[i+2] = color; + } + + LLViewerTexture::sCheckerBoardImagep = LLViewerTextureManager::getLocalTexture(image_raw.get(), TRUE); + LLViewerTexture::initClass() ; + // Create a texture manager bridge. + gTextureManagerBridgep = new LLViewerTextureManagerBridge; + if (LLMetricPerformanceTesterBasic::isMetricLogRequested(sTesterName) && !LLMetricPerformanceTesterBasic::getTester(sTesterName)) { sTesterp = new LLTexturePipelineTester() ; @@ -364,13 +414,16 @@ void LLViewerTextureManager::cleanup() { stop_glerror(); + delete gTextureManagerBridgep; LLImageGL::sDefaultGLTexture = NULL ; LLViewerTexture::sNullImagep = NULL; LLViewerTexture::sBlackImagep = NULL; + LLViewerTexture::sCheckerBoardImagep = NULL; LLViewerFetchedTexture::sDefaultImagep = NULL; LLViewerFetchedTexture::sSmokeImagep = NULL; LLViewerFetchedTexture::sMissingAssetImagep = NULL; LLViewerFetchedTexture::sWhiteImagep = NULL; + LLViewerFetchedTexture::sFlatNormalImagep = NULL; LLViewerMediaTexture::cleanUpClass() ; } @@ -383,32 +436,13 @@ void LLViewerTextureManager::cleanup() void LLViewerTexture::initClass() { LLImageGL::sDefaultGLTexture = LLViewerFetchedTexture::sDefaultImagep->getGLTexture() ; - - if(gAuditTexture) + + if(gSavedSettings.getBOOL("TextureFetchDebuggerEnabled")) { - LLImageGL::setHighlightTexture(LLViewerTexture::OTHER) ; + sTexelPixelRatio = gSavedSettings.getF32("TexelPixelRatio"); } } -// 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 = .25f; const F32 discard_delta_time = 0.5f; @@ -530,11 +564,11 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity } } 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) ; + sCameraMovingBias = llmax(0.2f * camera_moving_speed, 2.0f * camera_angular_speed - 1); + sCameraMovingDiscardBias = (S8)(sCameraMovingBias); 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) ; @@ -544,76 +578,66 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity //------------------------------------------------------------------------------------------- const U32 LLViewerTexture::sCurrentFileVersion = 1; -LLViewerTexture::LLViewerTexture(BOOL usemipmaps) +LLViewerTexture::LLViewerTexture(BOOL usemipmaps) : + LLGLTexture(usemipmaps) { init(true); - mUseMipMaps = usemipmaps ; mID.generate(); sImageCount++; } -LLViewerTexture::LLViewerTexture(const LLUUID& id, BOOL usemipmaps) - : mID(id) +LLViewerTexture::LLViewerTexture(const LLUUID& id, BOOL usemipmaps) : + LLGLTexture(usemipmaps), + mID(id) { init(true); - mUseMipMaps = usemipmaps ; sImageCount++; } -LLViewerTexture::LLViewerTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) +LLViewerTexture::LLViewerTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) : + LLGLTexture(width, height, components, usemipmaps) { init(true); - mFullWidth = width ; - mFullHeight = height ; - mUseMipMaps = usemipmaps ; - mComponents = components ; - setTexelsPerImage(); - mID.generate(); sImageCount++; } -LLViewerTexture::LLViewerTexture(const LLImageRaw* raw, BOOL usemipmaps) +LLViewerTexture::LLViewerTexture(const LLImageRaw* raw, BOOL usemipmaps) : + LLGLTexture(raw, 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() { + // LL_DEBUGS("Avatar") << mID << llendl; cleanup(); sImageCount--; } +// virtual void LLViewerTexture::init(bool firstinit) { - mBoostLevel = LLViewerTexture::BOOST_NONE; - - mFullWidth = 0; - mFullHeight = 0; - mTexelsPerImage = 0 ; - mUseMipMaps = FALSE ; - mComponents = 0 ; - - mTextureState = NO_DELETE ; - mDontDiscard = FALSE; + mSelectedTime = 0.f; mMaxVirtualSize = 0.f; - mNeedsGLTexture = FALSE ; mMaxVirtualSizeResetInterval = 1; mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval ; mAdditionalDecodePriority = 0.f ; mParcelMedia = NULL ; - mNumFaces = 0 ; + mNumVolumes = 0; - mFaceList.clear() ; + mFaceList[LLRender::DIFFUSE_MAP].clear() ; + mFaceList[LLRender::NORMAL_MAP].clear() ; + mFaceList[LLRender::SPECULAR_MAP].clear() ; + mNumFaces[LLRender::DIFFUSE_MAP] = + mNumFaces[LLRender::NORMAL_MAP] = + mNumFaces[LLRender::SPECULAR_MAP] = 0 ; mVolumeList.clear(); } @@ -625,21 +649,16 @@ S8 LLViewerTexture::getType() const void LLViewerTexture::cleanup() { - mFaceList.clear() ; + mFaceList[LLRender::DIFFUSE_MAP].clear() ; + mFaceList[LLRender::NORMAL_MAP].clear() ; + mFaceList[LLRender::SPECULAR_MAP].clear() ; mVolumeList.clear(); - if(mGLTexturep) - { - mGLTexturep->cleanup(); - } } // virtual void LLViewerTexture::dump() { - if(mGLTexturep) - { - mGLTexturep->dump(); - } + LLGLTexture::dump(); llinfos << "LLViewerTexture" << " mID " << mID @@ -651,17 +670,18 @@ void LLViewerTexture::setBoostLevel(S32 level) if(mBoostLevel != level) { mBoostLevel = level ; - if(mBoostLevel != LLViewerTexture::BOOST_NONE) + if(mBoostLevel != LLViewerTexture::BOOST_NONE && + mBoostLevel != LLViewerTexture::BOOST_SELECTED) { setNoDelete() ; } - if(gAuditTexture) - { - setCategory(mBoostLevel); - } } -} + if (mBoostLevel == LLViewerTexture::BOOST_SELECTED) + { + mSelectedTime = gFrameTimeSeconds; + } +} bool LLViewerTexture::bindDefaultImage(S32 stage) { @@ -712,6 +732,7 @@ void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) co mNeedsGLTexture = TRUE ; } + virtual_size *= sTexelPixelRatio; if(!mMaxVirtualSizeResetCounter) { //flag to reset the values because the old values are used. @@ -746,38 +767,57 @@ void LLViewerTexture::setKnownDrawSize(S32 width, S32 height) } //virtual -void LLViewerTexture::addFace(LLFace* facep) +void LLViewerTexture::addFace(U32 ch, LLFace* facep) { - if(mNumFaces >= mFaceList.size()) + llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); + + if(mNumFaces[ch] >= mFaceList[ch].size()) { - mFaceList.resize(2 * mNumFaces + 1) ; + mFaceList[ch].resize(2 * mNumFaces[ch] + 1) ; } - mFaceList[mNumFaces] = facep ; - facep->setIndexInTex(mNumFaces) ; - mNumFaces++ ; + mFaceList[ch][mNumFaces[ch]] = facep ; + facep->setIndexInTex(ch, mNumFaces[ch]) ; + mNumFaces[ch]++ ; mLastFaceListUpdateTimer.reset() ; } //virtual -void LLViewerTexture::removeFace(LLFace* facep) +void LLViewerTexture::removeFace(U32 ch, LLFace* facep) { - if(mNumFaces > 1) + llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); + + if(mNumFaces[ch] > 1) { - S32 index = facep->getIndexInTex() ; - mFaceList[index] = mFaceList[--mNumFaces] ; - mFaceList[index]->setIndexInTex(index) ; + S32 index = facep->getIndexInTex(ch) ; + llassert(index < mFaceList[ch].size()); + llassert(index < mNumFaces[ch]); + mFaceList[ch][index] = mFaceList[ch][--mNumFaces[ch]] ; + mFaceList[ch][index]->setIndexInTex(ch, index) ; } else { - mFaceList.clear() ; - mNumFaces = 0 ; + mFaceList[ch].clear() ; + mNumFaces[ch] = 0 ; } mLastFaceListUpdateTimer.reset() ; } -S32 LLViewerTexture::getNumFaces() const +S32 LLViewerTexture::getTotalNumFaces() const +{ + S32 ret = 0; + + for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i) + { + ret += mNumFaces[i]; + } + + return ret; +} + +S32 LLViewerTexture::getNumFaces(U32 ch) const { - return mNumFaces ; + llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); + return mNumFaces[ch]; } @@ -800,6 +840,8 @@ void LLViewerTexture::removeVolume(LLVOVolume* volumep) if(mNumVolumes > 1) { S32 index = volumep->getIndexInTex() ; + llassert(index < mVolumeList.size()); + llassert(index < mNumVolumes); mVolumeList[index] = mVolumeList[--mNumVolumes] ; mVolumeList[index]->setIndexInTex(index) ; } @@ -821,18 +863,22 @@ 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()) + if(mLastFaceListUpdateTimer.getElapsedTimeF32() < MAX_WAIT_TIME) { - return ; + return; } - if(mLastFaceListUpdateTimer.getElapsedTimeF32() < MAX_WAIT_TIME) + for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i) { - return ; + if(mNumFaces[i] + MAX_EXTRA_BUFFER_SIZE > mFaceList[i].size()) + { + return ; + } + + mFaceList[i].erase(mFaceList[i].begin() + mNumFaces[i], mFaceList[i].end()); } - + mLastFaceListUpdateTimer.reset() ; - mFaceList.erase(mFaceList.begin() + mNumFaces, mFaceList.end()); } void LLViewerTexture::reorganizeVolumeList() @@ -854,294 +900,18 @@ void LLViewerTexture::reorganizeVolumeList() 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() ; - setTexelsPerImage(); - } - - return ret ; -} - //virtual void LLViewerTexture::setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) { //nothing here. } -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 ; - } -} - -void LLViewerTexture::setTexelsPerImage() -{ - S32 fullwidth = llmin(mFullWidth,(S32)MAX_IMAGE_SIZE_DEFAULT); - S32 fullheight = llmin(mFullHeight,(S32)MAX_IMAGE_SIZE_DEFAULT); - mTexelsPerImage = (F32)fullwidth * fullheight; -} - BOOL LLViewerTexture::isLargeImage() { return (S32)mTexelsPerImage > LLViewerTexture::sMinLargeImageSize ; @@ -1165,25 +935,32 @@ void LLViewerTexture::updateBindStatsForTester() //start of LLViewerFetchedTexture //---------------------------------------------------------------------------------------------- -LLViewerFetchedTexture::LLViewerFetchedTexture(const LLUUID& id, const LLHost& host, BOOL usemipmaps) +LLViewerFetchedTexture::LLViewerFetchedTexture(const LLUUID& id, FTType f_type, const LLHost& host, BOOL usemipmaps) : LLViewerTexture(id, usemipmaps), mTargetHost(host) { init(TRUE) ; + mFTType = f_type; + if (mFTType == FTT_HOST_BAKE) + { + mCanUseHTTP = false; + } generateGLTexture() ; } -LLViewerFetchedTexture::LLViewerFetchedTexture(const LLImageRaw* raw, BOOL usemipmaps) +LLViewerFetchedTexture::LLViewerFetchedTexture(const LLImageRaw* raw, FTType f_type, BOOL usemipmaps) : LLViewerTexture(raw, usemipmaps) { init(TRUE) ; + mFTType = f_type; } -LLViewerFetchedTexture::LLViewerFetchedTexture(const std::string& url, const LLUUID& id, BOOL usemipmaps) +LLViewerFetchedTexture::LLViewerFetchedTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps) : LLViewerTexture(id, usemipmaps), mUrl(url) { init(TRUE) ; + mFTType = f_type; generateGLTexture() ; } @@ -1216,7 +993,7 @@ void LLViewerFetchedTexture::init(bool firstinit) mIsMissingAsset = FALSE; mLoadedCallbackDesiredDiscardLevel = S8_MAX; - mPauseLoadedCallBacks = TRUE ; + mPauseLoadedCallBacks = FALSE ; mNeedsCreateTexture = FALSE; @@ -1233,6 +1010,7 @@ void LLViewerFetchedTexture::init(bool firstinit) mRequestDeltaTime = 0.f; mForSculpt = FALSE ; mIsFetched = FALSE ; + mInFastCacheList = FALSE; mCachedRawImage = NULL ; mCachedRawDiscardLevel = -1 ; @@ -1246,6 +1024,10 @@ void LLViewerFetchedTexture::init(bool firstinit) mLastReferencedSavedRawImageTime = 0.0f ; mKeptSavedRawImageTime = 0.f ; mLastCallBackActiveTime = 0.f; + + mInDebug = FALSE; + + mFTType = FTT_UNKNOWN; } LLViewerFetchedTexture::~LLViewerFetchedTexture() @@ -1266,6 +1048,11 @@ S8 LLViewerFetchedTexture::getType() const return LLViewerTexture::FETCHED_TEXTURE ; } +FTType LLViewerFetchedTexture::getFTType() const +{ + return mFTType; +} + void LLViewerFetchedTexture::cleanup() { for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); @@ -1287,6 +1074,40 @@ void LLViewerFetchedTexture::cleanup() mCachedRawDiscardLevel = -1 ; mCachedRawImageReady = FALSE ; mSavedRawImage = NULL ; + mSavedRawDiscardLevel = -1; +} + +//access the fast cache +void LLViewerFetchedTexture::loadFromFastCache() +{ + if(!mInFastCacheList) + { + return; //no need to access the fast cache. + } + mInFastCacheList = FALSE; + + mRawImage = LLAppViewer::getTextureCache()->readFromFastCache(getID(), mRawDiscardLevel) ; + if(mRawImage.notNull()) + { + mFullWidth = mRawImage->getWidth() << mRawDiscardLevel; + mFullHeight = mRawImage->getHeight() << mRawDiscardLevel; + setTexelsPerImage(); + + if(mFullWidth > MAX_IMAGE_SIZE || mFullHeight > MAX_IMAGE_SIZE) + { + //discard all oversized textures. + destroyRawImage(); + llwarns << "oversized, setting as missing" << llendl; + setIsMissingAsset(); + mRawDiscardLevel = INVALID_DISCARD_LEVEL ; + } + else + { + mRequestedDiscardLevel = mDesiredDiscardLevel + 1; + mIsRawImageValid = TRUE; + addToCreateTexture() ; + } + } } void LLViewerFetchedTexture::setForSculpt() @@ -1294,9 +1115,10 @@ void LLViewerFetchedTexture::setForSculpt() static const S32 MAX_INTERVAL = 8 ; //frames mForSculpt = TRUE ; - if(isForSculptOnly() && !getBoundRecently()) + if(isForSculptOnly() && hasGLTexture() && !getBoundRecently()) { destroyGLTexture() ; //sculpt image does not need gl texture. + mTextureState = ACTIVE; } checkCachedRawSculptImage() ; setMaxVirtualSizeResetInterval(MAX_INTERVAL) ; @@ -1377,7 +1199,7 @@ void LLViewerFetchedTexture::dump() // ONLY called from LLViewerFetchedTextureList void LLViewerFetchedTexture::destroyTexture() { - if(LLImageGL::sGlobalTextureMemoryInBytes < sMaxDesiredTextureMemInBytes)//not ready to release unused memory. + if(LLImageGL::sGlobalTextureMemoryInBytes < sMaxDesiredTextureMemInBytes * 0.95f)//not ready to release unused memory. { return ; } @@ -1386,6 +1208,7 @@ void LLViewerFetchedTexture::destroyTexture() return ; } + //LL_DEBUGS("Avatar") << mID << llendl; destroyGLTexture() ; mFullyLoaded = FALSE ; } @@ -1401,9 +1224,14 @@ void LLViewerFetchedTexture::addToCreateTexture() mGLTexturep->setComponents(mComponents) ; force_update = true ; - for(U32 i = 0 ; i < mNumFaces ; i++) + for (U32 j = 0; j < LLRender::NUM_TEXTURE_CHANNELS; ++j) { - mFaceList[i]->dirtyTexture() ; + llassert(mNumFaces[j] <= mFaceList[j].size()); + + for(U32 i = 0 ; i < mNumFaces[j]; i++) + { + mFaceList[j][i]->dirtyTexture() ; + } } //discard the cached raw image and the saved raw image @@ -1462,7 +1290,12 @@ void LLViewerFetchedTexture::addToCreateTexture() destroyRawImage(); return ; } - mRawImage->scale(w >> i, h >> i) ; + + { + //make a duplicate in case somebody else is using this raw image + mRawImage = mRawImage->duplicate(); + mRawImage->scale(w >> i, h >> i) ; + } } } } @@ -1541,16 +1374,14 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/) // 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 + llwarns << "!size_ok, setting as missing" << llendl; setIsMissingAsset(); destroyRawImage(); return FALSE; } - if(!(res = insertToAtlas())) - { - res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel); - resetFaceAtlas() ; - } + res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel); + setActive() ; if (!needsToSaveRawImage()) @@ -1591,7 +1422,7 @@ void LLViewerFetchedTexture::processTextureStats() { updateVirtualSize() ; - static LLCachedControl<bool> textures_fullres(gSavedSettings,"TextureLoadFullRes"); + static LLCachedControl<bool> textures_fullres(gSavedSettings,"TextureLoadFullRes", false); if (textures_fullres) { @@ -1688,14 +1519,14 @@ F32 LLViewerFetchedTexture::calcDecodePriority() // Don't decode anything we don't need priority = -4.0f; } - else if ((mBoostLevel == LLViewerTexture::BOOST_UI || mBoostLevel == LLViewerTexture::BOOST_ICON) && !have_all_data) + else if ((mBoostLevel == LLGLTexture::BOOST_UI || mBoostLevel == LLGLTexture::BOOST_ICON) && !have_all_data) { priority = 1.f; } else if (pixel_priority < 0.001f && !have_all_data) { // Not on screen but we might want some data - if (mBoostLevel > BOOST_HIGH) + if (mBoostLevel > BOOST_SELECTED) { // Always want high boosted images priority = 1.f; @@ -1714,7 +1545,7 @@ F32 LLViewerFetchedTexture::calcDecodePriority() S32 ddiscard = MAX_DISCARD_LEVEL - (S32)desired; ddiscard = llclamp(ddiscard, 0, MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY); priority = (ddiscard + 1) * PRIORITY_DELTA_DISCARD_LEVEL_FACTOR; - setAdditionalDecodePriority(1.0f) ;//boost the textures without any data so far. + setAdditionalDecodePriority(0.1f) ;//boost the textures without any data so far. } else if ((mMinDiscardLevel > 0) && (cur_discard <= mMinDiscardLevel)) { @@ -1815,8 +1646,6 @@ F32 LLViewerFetchedTexture::maxDecodePriority() void LLViewerFetchedTexture::setDecodePriority(F32 priority) { - llassert(!mInImageList); - mDecodePriority = priority; if(mDecodePriority < F_ALMOST_ZERO) @@ -1841,15 +1670,40 @@ void LLViewerFetchedTexture::updateVirtualSize() 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()) ; + for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch) + { + llassert(mNumFaces[ch] <= mFaceList[ch].size()); + + for(U32 i = 0 ; i < mNumFaces[ch]; i++) + { + LLFace* facep = mFaceList[ch][i] ; + if( facep ) + { + LLDrawable* drawable = facep->getDrawable(); + if (drawable) + { + if(drawable->isRecentlyVisible()) + { + if (getBoostLevel() == LLViewerTexture::BOOST_NONE && + drawable->getVObj() && drawable->getVObj()->isSelected()) + { + setBoostLevel(LLViewerTexture::BOOST_SELECTED); + } + addTextureStats(facep->getVirtualSize()) ; + setAdditionalDecodePriority(facep->getImportanceToCamera()) ; + } + } + } } } + //reset whether or not a face was selected after 10 seconds + const F32 SELECTION_RESET_TIME = 10.f; + + if (getBoostLevel() == LLViewerTexture::BOOST_SELECTED && + gFrameTimeSeconds - mSelectedTime > SELECTION_RESET_TIME) + { + setBoostLevel(LLViewerTexture::BOOST_NONE); + } if(mMaxVirtualSizeResetCounter > 0) { @@ -1877,9 +1731,25 @@ S32 LLViewerFetchedTexture::getCurrentDiscardLevelForFetching() return current_discard ; } +bool LLViewerFetchedTexture::setDebugFetching(S32 debug_level) +{ + if(debug_level < 0) + { + mInDebug = FALSE; + return false; + } + mInDebug = TRUE; + + mDesiredDiscardLevel = debug_level; + + return true; +} + bool LLViewerFetchedTexture::updateFetch() { - static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled"); + static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled", false); + static LLCachedControl<F32> sCameraMotionThreshold(gSavedSettings,"TextureCameraMotionThreshold", 0.2); + static LLCachedControl<S32> sCameraMotionBoost(gSavedSettings,"TextureCameraMotionBoost", 3); if(textures_decode_disabled) { return false ; @@ -1912,6 +1782,10 @@ bool LLViewerFetchedTexture::updateFetch() { return false; // process any raw image data in callbacks before replacing } + if(mInFastCacheList) + { + return false; + } S32 current_discard = getCurrentDiscardLevelForFetching() ; S32 desired_discard = getDesiredDiscardLevel(); @@ -1960,6 +1834,7 @@ bool LLViewerFetchedTexture::updateFetch() { //discard all oversized textures. destroyRawImage(); + llwarns << "oversize, setting as missing" << llendl; setIsMissingAsset(); mRawDiscardLevel = INVALID_DISCARD_LEVEL ; mIsFetching = FALSE ; @@ -1989,6 +1864,10 @@ bool LLViewerFetchedTexture::updateFetch() // We finished but received no data if (current_discard < 0) { + llwarns << "!mIsFetching, setting as missing, decode_priority " << decode_priority + << " mRawDiscardLevel " << mRawDiscardLevel + << " current_discard " << current_discard + << llendl; setIsMissingAsset(); desired_discard = -1; } @@ -2029,6 +1908,10 @@ bool LLViewerFetchedTexture::updateFetch() { make_request = false; } + else if(mDesiredDiscardLevel > getMaxDiscardLevel()) + { + make_request = false; + } else if (mNeedsCreateTexture || mIsMissingAsset) { make_request = false; @@ -2037,23 +1920,34 @@ bool LLViewerFetchedTexture::updateFetch() { make_request = false; } + else if(mCachedRawImage.notNull() && (current_discard < 0 || current_discard > mCachedRawDiscardLevel)) + { + make_request = false; + switchToCachedImage() ; //use the cached raw data first + } //else if (!isJustBound() && mCachedRawImageReady) //{ // make_request = false; //} - if(make_request) + if (make_request) { - //load the texture progressively. - S32 delta_level = (mBoostLevel > LLViewerTexture::BOOST_NONE) ? 2 : 1 ; - if(current_discard < 0) + // Load the texture progressively: we try not to rush to the desired discard too fast. + // If the camera is not moving, we do not tweak the discard level notch by notch but go to the desired discard with larger boosted steps + // This mitigates the "textures stay blurry" problem when loading while not killing the texture memory while moving around + S32 delta_level = (mBoostLevel > LLGLTexture::BOOST_NONE) ? 2 : 1 ; + if (current_discard < 0) { desired_discard = llmax(desired_discard, getMaxDiscardLevel() - delta_level); } - else + else if (LLViewerTexture::sCameraMovingBias < sCameraMotionThreshold) { - desired_discard = llmax(desired_discard, current_discard - delta_level); + desired_discard = llmax(desired_discard, current_discard - sCameraMotionBoost); } + else + { + desired_discard = llmax(desired_discard, current_discard - delta_level); + } if (mIsFetching) { @@ -2089,7 +1983,7 @@ bool LLViewerFetchedTexture::updateFetch() // bypass texturefetch directly by pulling from LLTextureCache bool fetch_request_created = false; - fetch_request_created = LLAppViewer::getTextureFetch()->createRequest(mUrl, getID(),getTargetHost(), decode_priority, + fetch_request_created = LLAppViewer::getTextureFetch()->createRequest(mFTType, mUrl, getID(), getTargetHost(), decode_priority, w, h, c, desired_discard, needsAux(), mCanUseHTTP); if (fetch_request_created) @@ -2106,11 +2000,13 @@ bool LLViewerFetchedTexture::updateFetch() } else if (mHasFetcher && !mIsFetching) { - // Only delete requests that haven't receeived any network data for a while + // Only delete requests that haven't received any network data + // for a while. Note - this is the normal mechanism for + // deleting requests, not just a place to handle timeouts. const F32 FETCH_IDLE_TIME = 5.f; if (mLastPacketTimer.getElapsedTimeF32() > FETCH_IDLE_TIME) { -// llinfos << "Deleting request: " << getID() << " Discard: " << current_discard << " <= min:" << mMinDiscardLevel << " or priority == 0: " << decode_priority << llendl; + LL_DEBUGS("Texture") << "exceeded idle time " << FETCH_IDLE_TIME << ", deleting request: " << getID() << llendl; LLAppViewer::getTextureFetch()->deleteRequest(getID(), true); mHasFetcher = FALSE; } @@ -2121,6 +2017,35 @@ bool LLViewerFetchedTexture::updateFetch() return mIsFetching ? true : false; } +void LLViewerFetchedTexture::clearFetchedResults() +{ + if(mNeedsCreateTexture || mIsFetching) + { + return ; + } + + cleanup(); + destroyGLTexture(); + + if(getDiscardLevel() >= 0) //sculpty texture, force to invalidate + { + mGLTexturep->forceToInvalidateGLTexture(); + } +} + +void LLViewerFetchedTexture::forceToDeleteRequest() +{ + if (mHasFetcher) + { + mHasFetcher = FALSE; + mIsFetching = FALSE ; + } + + resetTextureStats(); + + mDesiredDiscardLevel = getMaxDiscardLevel() + 1; +} + void LLViewerFetchedTexture::setIsMissingAsset() { if (mUrl.empty()) @@ -2129,6 +2054,9 @@ void LLViewerFetchedTexture::setIsMissingAsset() } else { + // This may or may not be an error - it is normal to have no + // map tile on an empty region, but bad if we're failing on a + // server bake texture. llwarns << mUrl << ": Marking image as missing" << llendl; } if (mHasFetcher) @@ -2161,10 +2089,18 @@ void LLViewerFetchedTexture::setLoadedCallback( loaded_callback_func loaded_call mLoadedCallbackDesiredDiscardLevel = llmin(mLoadedCallbackDesiredDiscardLevel, (S8)discard_level) ; } - if(mPauseLoadedCallBacks && !pause) + if(mPauseLoadedCallBacks) + { + if(!pause) + { + unpauseLoadedCallbacks(src_callback_list) ; + } + } + else if(pause) { - unpauseLoadedCallbacks(src_callback_list) ; + pauseLoadedCallbacks(src_callback_list) ; } + LLLoadedCallbackEntry* entryp = new LLLoadedCallbackEntry(loaded_callback, discard_level, keep_imageraw, userdata, src_callback_list, this, pause); mLoadedCallbackList.push_back(entryp); @@ -2254,7 +2190,7 @@ void LLViewerFetchedTexture::deleteCallbackEntry(const LLLoadedCallbackEntry::so destroySavedRawImage() ; } } - else if(needsToSaveRawImage() && mBoostLevel != LLViewerTexture::BOOST_PREVIEW) + else if(needsToSaveRawImage() && mBoostLevel != LLGLTexture::BOOST_PREVIEW) { if(desired_raw_discard != INVALID_DISCARD_LEVEL) { @@ -2712,7 +2648,7 @@ void LLViewerFetchedTexture::setCachedRawImage() S32 h = mRawImage->getHeight() ; S32 max_size = MAX_CACHED_RAW_IMAGE_AREA ; - if(LLViewerTexture::BOOST_TERRAIN == mBoostLevel) + if(LLGLTexture::BOOST_TERRAIN == mBoostLevel) { max_size = MAX_CACHED_RAW_TERRAIN_IMAGE_AREA ; } @@ -2738,7 +2674,11 @@ void LLViewerFetchedTexture::setCachedRawImage() --i ; } - mRawImage->scale(w >> i, h >> i) ; + { + //make a duplicate in case somebody else is using this raw image + mRawImage = mRawImage->duplicate(); + mRawImage->scale(w >> i, h >> i) ; + } } mCachedRawImage = mRawImage ; mRawDiscardLevel += i ; @@ -2844,190 +2784,6 @@ 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(std::vector<LLFace*>::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 @@ -3036,14 +2792,14 @@ BOOL LLViewerFetchedTexture::insertToAtlas() //---------------------------------------------------------------------------------------------- //start of LLViewerLODTexture //---------------------------------------------------------------------------------------------- -LLViewerLODTexture::LLViewerLODTexture(const LLUUID& id, const LLHost& host, BOOL usemipmaps) - : LLViewerFetchedTexture(id, host, usemipmaps) +LLViewerLODTexture::LLViewerLODTexture(const LLUUID& id, FTType f_type, const LLHost& host, BOOL usemipmaps) + : LLViewerFetchedTexture(id, f_type, host, usemipmaps) { init(TRUE) ; } -LLViewerLODTexture::LLViewerLODTexture(const std::string& url, const LLUUID& id, BOOL usemipmaps) - : LLViewerFetchedTexture(url, id, usemipmaps) +LLViewerLODTexture::LLViewerLODTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps) + : LLViewerFetchedTexture(url, f_type, id, usemipmaps) { init(TRUE) ; } @@ -3072,7 +2828,7 @@ void LLViewerLODTexture::processTextureStats() { updateVirtualSize() ; - static LLCachedControl<bool> textures_fullres(gSavedSettings,"TextureLoadFullRes"); + static LLCachedControl<bool> textures_fullres(gSavedSettings,"TextureLoadFullRes", false); if (textures_fullres) { @@ -3085,7 +2841,7 @@ void LLViewerLODTexture::processTextureStats() 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) + else if (mBoostLevel < LLGLTexture::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)); @@ -3135,7 +2891,7 @@ void LLViewerLODTexture::processTextureStats() mCalculatedDiscardLevel = discard_level; } } - if (mBoostLevel < LLViewerTexture::BOOST_SCULPTED) + if (mBoostLevel < LLGLTexture::BOOST_SCULPTED) { discard_level += sDesiredDiscardBias; discard_level *= sDesiredDiscardScale; // scale @@ -3161,7 +2917,7 @@ void LLViewerLODTexture::processTextureStats() // S32 current_discard = getDiscardLevel(); - if (sDesiredDiscardBias > 0.0f && mBoostLevel < LLViewerTexture::BOOST_SCULPTED && current_discard >= 0) + if (sDesiredDiscardBias > 0.0f && mBoostLevel < LLGLTexture::BOOST_SCULPTED && current_discard >= 0) { if(desired_discard_bias_max <= sDesiredDiscardBias && !mForceToSaveRawImage) { @@ -3290,17 +3046,21 @@ LLViewerMediaTexture::LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps, LL sMediaMap.insert(std::make_pair(id, this)); mGLTexturep = gl_image ; + if(mGLTexturep.isNull()) { generateGLTexture() ; } + + mGLTexturep->setAllowCompression(false); + mGLTexturep->setNeedsAlphaAndPickMask(FALSE) ; mIsPlaying = FALSE ; setMediaImpl() ; - setCategory(LLViewerTexture::MEDIA) ; + setCategory(LLGLTexture::MEDIA) ; LLViewerTexture* tex = gTextureList.findImage(mID) ; if(tex) //this media is a parcel media for tex. @@ -3370,11 +3130,14 @@ BOOL LLViewerMediaTexture::findFaces() 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++) + for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch) { - mMediaFaceList.push_back((*face_list)[i]) ; + const ll_face_list_t* face_list = tex->getFaceList(ch) ; + U32 end = tex->getNumFaces(ch) ; + for(U32 i = 0 ; i < end ; i++) + { + mMediaFaceList.push_back((*face_list)[i]) ; + } } } @@ -3439,7 +3202,7 @@ void LLViewerMediaTexture::addMediaToFace(LLFace* facep) return ; //no need to add the face because the media is not in playing. } - switchTexture(facep) ; + switchTexture(LLRender::DIFFUSE_MAP, facep) ; } void LLViewerMediaTexture::removeMediaFromFace(LLFace* facep) @@ -3456,19 +3219,19 @@ void LLViewerMediaTexture::removeMediaFromFace(LLFace* facep) } mIsPlaying = FALSE ; //set to remove the media from the face. - switchTexture(facep) ; + switchTexture(LLRender::DIFFUSE_MAP, facep) ; mIsPlaying = TRUE ; //set the flag back. - if(getNumFaces() < 1) //no face referencing to this media + if(getTotalNumFaces() < 1) //no face referencing to this media { stopPlaying() ; } } //virtual -void LLViewerMediaTexture::addFace(LLFace* facep) +void LLViewerMediaTexture::addFace(U32 ch, LLFace* facep) { - LLViewerTexture::addFace(facep) ; + LLViewerTexture::addFace(ch, facep) ; const LLTextureEntry* te = facep->getTextureEntry() ; if(te && te->getID().notNull()) @@ -3495,9 +3258,9 @@ void LLViewerMediaTexture::addFace(LLFace* facep) } //virtual -void LLViewerMediaTexture::removeFace(LLFace* facep) +void LLViewerMediaTexture::removeFace(U32 ch, LLFace* facep) { - LLViewerTexture::removeFace(facep) ; + LLViewerTexture::removeFace(ch, facep) ; const LLTextureEntry* te = facep->getTextureEntry() ; if(te && te->getID().notNull()) @@ -3515,24 +3278,35 @@ void LLViewerMediaTexture::removeFace(LLFace* facep) } } - // - //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) + std::vector<const LLTextureEntry*> te_list; + + for (U32 ch = 0; ch < 3; ++ch) { - mTextureList.clear() ; - 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. + + llassert(mNumFaces[ch] <= mFaceList[ch].size()); + + for(U32 j = 0 ; j < mNumFaces[ch] ; j++) + { + te_list.push_back(mFaceList[ch][j]->getTextureEntry());//all textures are in use. + } } - S32 end = getNumFaces() ; - std::vector<const LLTextureEntry*> te_list(end) ; - S32 i = 0 ; - for(U32 j = 0 ; j < mNumFaces ; j++) + + if (te_list.empty()) { - te_list[i++] = mFaceList[j]->getTextureEntry() ;//all textures are in use. + mTextureList.clear() ; + return ; } + + S32 end = te_list.size(); + for(std::list< LLPointer<LLViewerTexture> >::iterator iter = mTextureList.begin(); iter != mTextureList.end(); ++iter) { + S32 i = 0; + for(i = 0 ; i < end ; i++) { if(te_list[i] && te_list[i]->getID() == (*iter)->getID())//the texture is in use. @@ -3577,7 +3351,7 @@ void LLViewerMediaTexture::stopPlaying() mIsPlaying = FALSE ; } -void LLViewerMediaTexture::switchTexture(LLFace* facep) +void LLViewerMediaTexture::switchTexture(U32 ch, LLFace* facep) { if(facep) { @@ -3593,7 +3367,7 @@ void LLViewerMediaTexture::switchTexture(LLFace* facep) if(mIsPlaying) //old textures switch to the media texture { - facep->switchTexture(this) ; + facep->switchTexture(ch, this) ; } else //switch to old textures. { @@ -3609,7 +3383,7 @@ void LLViewerMediaTexture::switchTexture(LLFace* facep) { tex = LLViewerFetchedTexture::sDefaultImagep ; } - facep->switchTexture(tex) ; + facep->switchTexture(ch, tex) ; } } } @@ -3648,14 +3422,17 @@ void LLViewerMediaTexture::setPlaying(BOOL playing) for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter) { - switchTexture(*iter) ; + switchTexture(LLRender::DIFFUSE_MAP, *iter) ; } } else //stop playing this media { - for(U32 i = mNumFaces ; i ; i--) + U32 ch = LLRender::DIFFUSE_MAP; + + llassert(mNumFaces[ch] <= mFaceList[ch].size()); + for(U32 i = mNumFaces[ch] ; i ; i--) { - switchTexture(mFaceList[i - 1]) ; //current face could be removed in this function. + switchTexture(ch, mFaceList[ch][i - 1]) ; //current face could be removed in this function. } } return ; @@ -3677,14 +3454,18 @@ F32 LLViewerMediaTexture::getMaxVirtualSize() if(mIsPlaying) //media is playing { - for(U32 i = 0 ; i < mNumFaces ; i++) + for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch) { - LLFace* facep = mFaceList[i] ; - if(facep->getDrawable()->isRecentlyVisible()) + llassert(mNumFaces[ch] <= mFaceList[ch].size()); + for(U32 i = 0 ; i < mNumFaces[ch] ; i++) { - addTextureStats(facep->getVirtualSize()) ; - } - } + LLFace* facep = mFaceList[ch][i] ; + if(facep->getDrawable()->isRecentlyVisible()) + { + addTextureStats(facep->getVirtualSize()) ; + } + } + } } else //media is not in playing { |