From 52aeaa32841e7d0b37abab0a2a2540c2be2f16b7 Mon Sep 17 00:00:00 2001 From: James Cook Date: Tue, 7 Jul 2009 00:53:05 +0000 Subject: Merge skinning-14 to viewer-2, including refactoring many floaters to register them with LLFloaterReg, support for introspection of ParamBlock based UI widgets to dump XML schema, splitting llfolderview.cpp into three separate files to unravel dependencies and skeleton for for LLListView widget. Resolved conflicts in these files: lldraghandle.h, lluictrl.h, llchiclet.cpp, llfolderview.h/cpp, lliinventorybridge.cpp, llpanelpicks.cpp, llviewermenu.cpp, floater_mute.xml, floater_preferences.xml, notifications.xml, panel_preferences_audio.xml, panel_preferences_graphics1.xml, panel_region_general.xml svn merge -r124961:126284 svn+ssh://svn.lindenlab.com/svn/linden/branches/skinning/skinning-14 --- indra/llrender/llfontgl.h | 6 +++--- indra/llrender/llfontregistry.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'indra/llrender') diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h index 204c6908af..77cd12250c 100644 --- a/indra/llrender/llfontgl.h +++ b/indra/llrender/llfontgl.h @@ -264,7 +264,7 @@ protected: typedef std::map embedded_map_t; mutable embedded_map_t mEmbeddedChars; - LLFontDescriptor mFontDesc; + LLFontDescriptor mFontDescriptor; // Registry holds all instantiated fonts. static LLFontRegistry* sFontRegistry; @@ -276,8 +276,8 @@ public: static LLCoordFont sCurOrigin; static std::vector sOriginStack; - const LLFontDescriptor &getFontDesc() const { return mFontDesc; } - void setFontDesc(const LLFontDescriptor& font_desc) { mFontDesc = font_desc; } + const LLFontDescriptor &getFontDesc() const { return mFontDescriptor; } + void setFontDesc(const LLFontDescriptor& font_desc) { mFontDescriptor = font_desc; } }; #endif diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp index 18e4a6915d..3b5c62a5ea 100644 --- a/indra/llrender/llfontregistry.cpp +++ b/indra/llrender/llfontregistry.cpp @@ -104,7 +104,7 @@ bool removeSubString(std::string& str, const std::string& substr) size_t pos = str.find(substr); if (pos != string::npos) { - str.replace(pos,substr.length(),(const char *)NULL, 0); + str.erase(pos); return true; } return false; -- cgit v1.3 From 77f56a3f3db72b2938eadb0868fc7be975dabafa Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Fri, 10 Jul 2009 22:02:26 +0000 Subject: merge QAR-1579: texture-cleanup-1. --- .../llui_libtest/llui_libtest.cpp | 3 +- indra/llrender/CMakeLists.txt | 2 + indra/llrender/llfontgl.cpp | 7 +- indra/llrender/llfontgl.h | 4 +- indra/llrender/llimagegl.cpp | 123 +- indra/llrender/llimagegl.h | 47 +- indra/llrender/llrender.cpp | 79 +- indra/llrender/llrender.h | 2 + indra/llrender/lltexture.cpp | 37 + indra/llrender/lltexture.h | 77 + indra/llui/llcombobox.h | 1 - indra/llui/lliconctrl.h | 1 - indra/llui/llmultislider.cpp | 1 - indra/llui/llprogressbar.cpp | 1 - indra/llui/llresizehandle.h | 1 - indra/llui/llscrolllistctrl.h | 1 - indra/llui/llslider.cpp | 1 - indra/llui/llslider.h | 2 - indra/llui/lltexteditor.cpp | 1 - indra/llui/llui.cpp | 15 +- indra/llui/llui.h | 15 +- indra/llui/lluiimage.cpp | 2 +- indra/llui/lluiimage.h | 14 +- indra/newview/CMakeLists.txt | 12 +- indra/newview/llappviewer.cpp | 6 +- indra/newview/llcolorswatch.cpp | 4 +- indra/newview/llcolorswatch.h | 4 +- indra/newview/lldrawable.cpp | 24 +- indra/newview/lldrawable.h | 10 +- indra/newview/lldrawpool.cpp | 19 +- indra/newview/lldrawpool.h | 22 +- indra/newview/lldrawpoolalpha.cpp | 8 +- indra/newview/lldrawpoolavatar.cpp | 4 +- indra/newview/lldrawpoolavatar.h | 2 +- indra/newview/lldrawpoolbump.cpp | 63 +- indra/newview/lldrawpoolbump.h | 16 +- indra/newview/lldrawpoolsky.cpp | 2 +- indra/newview/lldrawpoolterrain.cpp | 73 +- indra/newview/lldrawpoolterrain.h | 16 +- indra/newview/lldrawpooltree.cpp | 10 +- indra/newview/lldrawpooltree.h | 8 +- indra/newview/lldrawpoolwater.cpp | 37 +- indra/newview/lldrawpoolwater.h | 10 +- indra/newview/lldrawpoolwlsky.cpp | 20 +- indra/newview/lldrawpoolwlsky.h | 8 +- indra/newview/lldynamictexture.cpp | 110 +- indra/newview/lldynamictexture.h | 44 +- indra/newview/llface.cpp | 52 +- indra/newview/llface.h | 18 +- indra/newview/llfasttimerview.cpp | 2 +- indra/newview/llfeaturemanager.cpp | 2 +- indra/newview/llflexibleobject.cpp | 3 +- indra/newview/llfloateranimpreview.cpp | 12 +- indra/newview/llfloateranimpreview.h | 10 +- indra/newview/llfloaterauction.cpp | 6 +- indra/newview/llfloaterauction.h | 4 +- indra/newview/llfloatercolorpicker.cpp | 3 +- indra/newview/llfloatercolorpicker.h | 2 +- indra/newview/llfloatergesture.cpp | 2 +- indra/newview/llfloaterhardwaresettings.cpp | 7 +- indra/newview/llfloaterimagepreview.cpp | 31 +- indra/newview/llfloaterimagepreview.h | 22 +- indra/newview/llfloaterinventory.cpp | 1 - indra/newview/llfloaterlagmeter.cpp | 4 +- indra/newview/llfloaterland.cpp | 2 +- indra/newview/llfloaterland.h | 1 + indra/newview/llfloaterpostcard.cpp | 8 +- indra/newview/llfloaterpostcard.h | 8 +- indra/newview/llfloaterpreference.cpp | 5 - indra/newview/llfloaterregioninfo.cpp | 10 +- indra/newview/llfloaterreporter.cpp | 10 +- indra/newview/llfloaterreporter.h | 2 +- indra/newview/llfloaterscriptdebug.cpp | 4 +- indra/newview/llfloatersnapshot.cpp | 16 +- indra/newview/llfolderview.cpp | 4 +- indra/newview/llfolderview.h | 2 +- indra/newview/llhudeffect.cpp | 1 - indra/newview/llhudeffectbeam.cpp | 1 - indra/newview/llhudeffecttrail.cpp | 3 +- indra/newview/llhudicon.cpp | 10 +- indra/newview/llhudicon.h | 4 +- indra/newview/llhudrender.cpp | 1 - indra/newview/llhudtext.cpp | 3 +- indra/newview/llinventorybridge.cpp | 2 +- indra/newview/lljoystickbutton.cpp | 6 +- indra/newview/lljoystickbutton.h | 4 +- indra/newview/llmanip.cpp | 2 +- indra/newview/llmaniptranslate.cpp | 4 +- indra/newview/llnetmap.cpp | 5 +- indra/newview/llnetmap.h | 4 +- indra/newview/lloverlaybar.cpp | 2 +- indra/newview/llpanelface.cpp | 2 +- indra/newview/llpanelgrouproles.cpp | 2 +- indra/newview/llpanellogin.cpp | 4 +- indra/newview/llpreviewtexture.cpp | 22 +- indra/newview/llpreviewtexture.h | 6 +- indra/newview/llprogressview.cpp | 9 +- indra/newview/llselectmgr.cpp | 10 +- indra/newview/llselectmgr.h | 4 +- indra/newview/llspatialpartition.cpp | 6 +- indra/newview/llspatialpartition.h | 6 +- indra/newview/llsprite.cpp | 2 +- indra/newview/llsprite.h | 4 +- indra/newview/llstartup.cpp | 29 +- indra/newview/llstartup.h | 4 +- indra/newview/llsurface.cpp | 28 +- indra/newview/llsurface.h | 10 +- indra/newview/lltexlayer.cpp | 158 +- indra/newview/lltexlayer.h | 15 +- indra/newview/lltexlayerparams.cpp | 40 +- indra/newview/lltexlayerparams.h | 2 +- indra/newview/lltexturectrl.cpp | 26 +- indra/newview/lltexturectrl.h | 4 +- indra/newview/lltexturefetch.cpp | 14 +- indra/newview/lltexturefetch.h | 2 +- indra/newview/lltextureview.cpp | 65 +- indra/newview/lltextureview.h | 10 +- indra/newview/lltooldraganddrop.cpp | 8 +- indra/newview/lltoolgun.cpp | 2 +- indra/newview/lltoolmorph.cpp | 26 +- indra/newview/lltoolmorph.h | 17 +- indra/newview/llviewercontrol.cpp | 4 +- indra/newview/llviewerdisplay.cpp | 26 +- indra/newview/llviewerjointmesh.cpp | 21 +- indra/newview/llviewerjointmesh.h | 6 +- indra/newview/llviewermedia.cpp | 222 +- indra/newview/llviewermenu.cpp | 10 +- indra/newview/llviewermenufile.cpp | 12 +- indra/newview/llviewerobject.cpp | 54 +- indra/newview/llviewerobject.h | 11 +- indra/newview/llviewerobjectlist.cpp | 4 +- indra/newview/llviewerparcelmediaautoplay.cpp | 6 +- indra/newview/llviewerparcelmgr.cpp | 16 +- indra/newview/llviewerparcelmgr.h | 10 +- indra/newview/llviewerparceloverlay.cpp | 9 +- indra/newview/llviewerparceloverlay.h | 6 +- indra/newview/llviewerpartsim.cpp | 2 +- indra/newview/llviewerpartsim.h | 8 +- indra/newview/llviewerpartsource.cpp | 16 +- indra/newview/llviewerpartsource.h | 8 +- indra/newview/llviewerstats.cpp | 14 +- indra/newview/llviewertexteditor.cpp | 2 +- indra/newview/llviewertexture.cpp | 2375 ++++++++++++++++++++ indra/newview/llviewertexture.h | 672 ++++++ indra/newview/llviewertexturelist.cpp | 1510 +++++++++++++ indra/newview/llviewertexturelist.h | 243 ++ indra/newview/llviewerwindow.cpp | 29 +- indra/newview/llvlcomposition.cpp | 22 +- indra/newview/llvlcomposition.h | 6 +- indra/newview/llvoavatar.cpp | 59 +- indra/newview/llvoavatar.h | 24 +- indra/newview/llvoavatarself.cpp | 47 +- indra/newview/llvoavatarself.h | 17 +- indra/newview/llvoclouds.cpp | 6 +- indra/newview/llvoclouds.h | 2 +- indra/newview/llvograss.cpp | 4 +- indra/newview/llvograss.h | 2 +- indra/newview/llvoground.h | 2 +- indra/newview/llvoicevisualizer.cpp | 7 +- indra/newview/llvoicevisualizer.h | 2 +- indra/newview/llvosky.cpp | 34 +- indra/newview/llvosky.h | 16 +- indra/newview/llvotextbubble.cpp | 10 +- indra/newview/llvotree.cpp | 6 +- indra/newview/llvotree.h | 6 +- indra/newview/llvotreenew.h | 4 +- indra/newview/llvovolume.cpp | 48 +- indra/newview/llvovolume.h | 6 +- indra/newview/llvowater.cpp | 2 +- indra/newview/llvowater.h | 2 +- indra/newview/llwaterparamset.cpp | 2 +- indra/newview/llwearable.cpp | 10 +- indra/newview/llworld.cpp | 10 +- indra/newview/llworld.h | 6 +- indra/newview/llworldmap.cpp | 20 +- indra/newview/llworldmap.h | 8 +- indra/newview/llworldmapview.cpp | 26 +- indra/newview/llworldmapview.h | 4 +- indra/newview/pipeline.cpp | 29 +- indra/newview/pipeline.h | 18 +- 180 files changed, 6151 insertions(+), 1423 deletions(-) create mode 100644 indra/llrender/lltexture.cpp create mode 100644 indra/llrender/lltexture.h create mode 100644 indra/newview/llviewertexture.cpp create mode 100644 indra/newview/llviewertexture.h create mode 100644 indra/newview/llviewertexturelist.cpp create mode 100644 indra/newview/llviewertexturelist.h (limited to 'indra/llrender') diff --git a/indra/integration_tests/llui_libtest/llui_libtest.cpp b/indra/integration_tests/llui_libtest/llui_libtest.cpp index 1e5de74e92..481dd93493 100644 --- a/indra/integration_tests/llui_libtest/llui_libtest.cpp +++ b/indra/integration_tests/llui_libtest/llui_libtest.cpp @@ -72,6 +72,7 @@ public: } }; +class LLTexture ; // We need to supply dummy images class TestImageProvider : public LLImageProviderInterface { @@ -92,7 +93,7 @@ public: LLPointer makeImage() { - LLPointer image_gl; + LLPointer image_gl; LLPointer image = new LLUIImage( std::string(), image_gl); return image; } diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt index 0bb835970f..0e0fc6ce6c 100644 --- a/indra/llrender/CMakeLists.txt +++ b/indra/llrender/CMakeLists.txt @@ -36,6 +36,7 @@ set(llrender_SOURCE_FILES llpostprocess.cpp llrendersphere.cpp llshadermgr.cpp + lltexture.cpp llvertexbuffer.cpp ) @@ -58,6 +59,7 @@ set(llrender_HEADER_FILES llrender.h llrendersphere.h llshadermgr.h + lltexture.h llvertexbuffer.h ) diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 048bfe8e0d..0b57d86c78 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -43,6 +43,7 @@ #include "llrender.h" #include "llstl.h" #include "v4color.h" +#include "lltexture.h" // Third party library includes #include @@ -1114,15 +1115,15 @@ void LLFontGL::clearEmbeddedChars() mEmbeddedChars.clear(); } -void LLFontGL::addEmbeddedChar( llwchar wc, LLImageGL* image, const std::string& label ) const +void LLFontGL::addEmbeddedChar( llwchar wc, LLTexture* image, const std::string& label ) const { LLWString wlabel = utf8str_to_wstring(label); addEmbeddedChar(wc, image, wlabel); } -void LLFontGL::addEmbeddedChar( llwchar wc, LLImageGL* image, const LLWString& wlabel ) const +void LLFontGL::addEmbeddedChar( llwchar wc, LLTexture* image, const LLWString& wlabel ) const { - embedded_data_t* ext_data = new embedded_data_t(image, wlabel); + embedded_data_t* ext_data = new embedded_data_t(image->getGLTexture(), wlabel); mEmbeddedChars[wc] = ext_data; } diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h index 77cd12250c..2298db0ef3 100644 --- a/indra/llrender/llfontgl.h +++ b/indra/llrender/llfontgl.h @@ -206,8 +206,8 @@ public: LLImageGL *getImageGL() const; - void addEmbeddedChar( llwchar wc, LLImageGL* image, const std::string& label) const; - void addEmbeddedChar( llwchar wc, LLImageGL* image, const LLWString& label) const; + void addEmbeddedChar( llwchar wc, LLTexture* image, const std::string& label) const; + void addEmbeddedChar( llwchar wc, LLTexture* image, const LLWString& label) const; void removeEmbeddedChar( llwchar wc ) const; static std::string nameFromFont(const LLFontGL* fontp); diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index e1231eeeb4..c4d91209e6 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -46,7 +46,6 @@ //---------------------------------------------------------------------------- - const F32 MIN_TEXTURE_LIFETIME = 10.f; //statics @@ -61,7 +60,7 @@ S32 LLImageGL::sCount = 0; BOOL LLImageGL::sGlobalUseAnisotropic = FALSE; F32 LLImageGL::sLastFrameTime = 0.f; - +LLImageGL* LLImageGL::sDefaultGLTexture = NULL ; std::set LLImageGL::sImageList; //************************************************************************************** @@ -263,28 +262,6 @@ void LLImageGL::restoreGL() } //---------------------------------------------------------------------------- - -//static -BOOL LLImageGL::create(LLPointer& dest, BOOL usemipmaps) -{ - dest = new LLImageGL(usemipmaps); - return TRUE; -} - -BOOL LLImageGL::create(LLPointer& dest, U32 width, U32 height, U8 components, BOOL usemipmaps) -{ - dest = new LLImageGL(width, height, components, usemipmaps); - return TRUE; -} - -BOOL LLImageGL::create(LLPointer& dest, const LLImageRaw* imageraw, BOOL usemipmaps) -{ - dest = new LLImageGL(imageraw, usemipmaps); - return TRUE; -} - -//---------------------------------------------------------------------------- - LLImageGL::LLImageGL(BOOL usemipmaps) : mSaveData(0) { @@ -331,7 +308,6 @@ void LLImageGL::init(BOOL usemipmaps) #endif mPickMask = NULL; - mTextureState = NO_DELETE ; mTextureMemory = 0; mLastBindTime = 0.f; @@ -351,8 +327,7 @@ void LLImageGL::init(BOOL usemipmaps) mComponents = 0; mMaxDiscardLevel = MAX_DISCARD_LEVEL; - mCurrentDiscardLevel = -1; - mDontDiscard = FALSE; + mCurrentDiscardLevel = -1; mFormatInternal = -1; mFormatPrimary = (LLGLenum) 0; @@ -462,7 +437,7 @@ void LLImageGL::dump() //---------------------------------------------------------------------------- -void LLImageGL::updateBindStats(void) const +BOOL LLImageGL::updateBindStats(S32 tex_mem) const { if (mTexName != 0) { @@ -474,38 +449,18 @@ void LLImageGL::updateBindStats(void) const { // we haven't accounted for this texture yet this frame sUniqueCount++; - updateBoundTexMem(mTextureMemory); + updateBoundTexMem(tex_mem); mLastBindTime = sLastFrameTime; - if(LLFastTimer::sMetricLog) - { - updateTestStats() ; - } + return TRUE ; } } + return FALSE ; } -//virtual -void LLImageGL::updateTestStats(void) const -{ -} - -//virtual -bool LLImageGL::bindError(const S32 stage) const -{ - return false; -} - -//virtual -bool LLImageGL::bindDefaultImage(const S32 stage) const -{ - return false; -} - -//virtual -void LLImageGL::forceImmediateUpdate() +F32 LLImageGL::getTimePassedSinceLastBound() { - return ; + return sLastFrameTime - mLastBindTime ; } void LLImageGL::setExplicitFormat( LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes ) @@ -1052,7 +1007,6 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_ mTextureMemory = getMipBytes(discard_level); sGlobalTextureMemoryInBytes += mTextureMemory; - setActive() ; // mark this as bound at this point, so we don't throw it out immediately mLastBindTime = sLastFrameTime; @@ -1068,12 +1022,7 @@ BOOL LLImageGL::setDiscardLevel(S32 discard_level) discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel); - if (mDontDiscard) - { - // don't discard! - return FALSE; - } - else if (discard_level == mCurrentDiscardLevel) + if (discard_level == mCurrentDiscardLevel) { // nothing to do return FALSE; @@ -1255,8 +1204,7 @@ void LLImageGL::destroyGLTexture() sGlobalTextureMemoryInBytes -= mTextureMemory; mTextureMemory = 0; - LLImageGL::deleteTextures(1, &mTexName); - mTextureState = DELETED ; + LLImageGL::deleteTextures(1, &mTexName); mTexName = 0; mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel. mGLTextureCreated = FALSE ; @@ -1440,57 +1388,6 @@ void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h) } } -BOOL LLImageGL::isDeleted() -{ - return mTextureState == DELETED ; -} - -BOOL LLImageGL::isInactive() -{ - return mTextureState == INACTIVE ; -} - -BOOL LLImageGL::isDeletionCandidate() -{ - return mTextureState == DELETION_CANDIDATE ; -} - -void LLImageGL::setDeletionCandidate() -{ - if(mTexName && (mTextureState == INACTIVE)) - { - mTextureState = DELETION_CANDIDATE ; - } -} - -void LLImageGL::forceActive() -{ - mTextureState = ACTIVE ; -} - -void LLImageGL::setActive() -{ - if(mTextureState != NO_DELETE) - { - mTextureState = ACTIVE ; - } -} - -//set the texture inactive -void LLImageGL::setInactive() -{ - if(mTexName && (mTextureState == ACTIVE) && !getBoundRecently()) - { - mTextureState = INACTIVE ; - } -} - -//set the texture to stay in memory -void LLImageGL::setNoDelete() -{ - mTextureState = NO_DELETE ; -} - //---------------------------------------------------------------------------- void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in) { diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 1775ae7de9..84c0f8746e 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -57,8 +57,8 @@ public: static S32 dataFormatBytes(S32 dataformat, S32 width, S32 height); static S32 dataFormatComponents(S32 dataformat); - void updateBindStats(void) const; - virtual void updateTestStats(void) const; + BOOL updateBindStats(S32 tex_mem) const ; + F32 getTimePassedSinceLastBound(); // needs to be called every frame static void updateStats(F32 current_time); @@ -72,12 +72,6 @@ public: static bool checkSize(S32 width, S32 height); - // Not currently necessary for LLImageGL, but required in some derived classes, - // so include for compatability - static BOOL create(LLPointer& dest, BOOL usemipmaps = TRUE); - static BOOL create(LLPointer& dest, U32 width, U32 height, U8 components, BOOL usemipmaps = TRUE); - static BOOL create(LLPointer& dest, const LLImageRaw* imageraw, BOOL usemipmaps = TRUE); - public: LLImageGL(BOOL usemipmaps = TRUE); LLImageGL(U32 width, U32 height, U8 components, BOOL usemipmaps = TRUE); @@ -90,11 +84,9 @@ protected: public: virtual void dump(); // debugging info to llinfos - virtual bool bindError(const S32 stage = 0) const; - virtual bool bindDefaultImage(const S32 stage = 0) const; - virtual void forceImmediateUpdate() ; - + void setSize(S32 width, S32 height, S32 ncomponents); + void setComponents(S32 ncomponents) { mComponents = (S8)ncomponents ;} // These 3 functions currently wrap glGenTextures(), glDeleteTextures(), and glTexImage2D() // for tracking purposes and will be deprecated in the future @@ -116,7 +108,6 @@ public: void destroyGLTexture(); void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE); - void dontDiscard() { mDontDiscard = 1; mTextureState = NO_DELETE; } S32 getDiscardLevel() const { return mCurrentDiscardLevel; } S32 getMaxDiscardLevel() const { return mMaxDiscardLevel; } @@ -145,9 +136,7 @@ public: void setGLTextureCreated (bool initialized) { mGLTextureCreated = initialized; } BOOL getUseMipMaps() const { return mUseMipMaps; } - void setUseMipMaps(BOOL usemips) { mUseMipMaps = usemips; } - BOOL getUseDiscard() const { return mUseMipMaps && !mDontDiscard; } - BOOL getDontDiscard() const { return mDontDiscard; } + void setUseMipMaps(BOOL usemips) { mUseMipMaps = usemips; } BOOL isValidForSculpt(S32 discard_level, S32 image_width, S32 image_height, S32 ncomponents) ; @@ -168,16 +157,6 @@ public: void setFilteringOption(LLTexUnit::eTextureFilterOptions option); LLTexUnit::eTextureFilterOptions getFilteringOption(void) const { return mFilterOption; } - BOOL isDeleted() ; - BOOL isInactive() ; - BOOL isDeletionCandidate(); - void setDeletionCandidate() ; - void setInactive() ; - void setActive() ; - void forceActive() ; - void setNoDelete() ; - -protected: void init(BOOL usemipmaps); virtual void cleanup(); // Clean up the LLImageGL so it can be reinitialized. Be careful when using this in derived class destructors @@ -210,28 +189,15 @@ protected: S8 mComponents; S8 mMaxDiscardLevel; - S8 mDontDiscard; // Keep full res version of this image (for UI, etc) - + bool mTexOptionsDirty; LLTexUnit::eTextureAddressMode mAddressMode; // Defaults to TAM_WRAP LLTexUnit::eTextureFilterOptions mFilterOption; // Defaults to TFO_TRILINEAR - LLGLint mFormatInternal; // = GL internalformat LLGLenum mFormatPrimary; // = GL format (pixel data format) LLGLenum mFormatType; BOOL mFormatSwapBytes;// if true, use glPixelStorei(GL_UNPACK_SWAP_BYTES, 1) - -protected: - typedef enum - { - DELETED = 0, //removed from memory - DELETION_CANDIDATE, //ready to be removed from memory - INACTIVE, //not be used for the last certain period (i.e., 30 seconds). - ACTIVE, //just being used, can become inactive if not being used for a certain time (10 seconds). - NO_DELETE = 99 //stay in memory, can not be removed. - } LLGLTexureState; - LLGLTexureState mTextureState ; // STATICS public: @@ -249,6 +215,7 @@ public: static U32 sBindCount; // Tracks number of texture binds for current frame static U32 sUniqueCount; // Tracks number of unique texture binds for current frame static BOOL sGlobalUseAnisotropic; + static LLImageGL* sDefaultGLTexture ; #if DEBUG_MISS BOOL mMissed; // Missed on last bind? diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index d3a230b37b..d577daf3f4 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -38,6 +38,7 @@ #include "llcubemap.h" #include "llimagegl.h" #include "llrendertarget.h" +#include "lltexture.h" LLRender gGL; @@ -177,20 +178,21 @@ void LLTexUnit::disable(void) } } -bool LLTexUnit::bind(LLImageGL* texture, bool forceBind) +bool LLTexUnit::bind(LLTexture* texture, bool forceBind) { stop_glerror(); if (mIndex < 0) return false; gGL.flush(); - if (texture == NULL) + LLImageGL* gl_tex = NULL ; + if (texture == NULL || !(gl_tex = texture->getGLTexture())) { llwarns << "NULL LLTexUnit::bind texture" << llendl; return false; } - if (!texture->getTexName()) //if texture does not exist + if (!gl_tex->getTexName()) //if texture does not exist { //if deleted, will re-generate it immediately texture->forceImmediateUpdate() ; @@ -198,14 +200,57 @@ bool LLTexUnit::bind(LLImageGL* texture, bool forceBind) return texture->bindDefaultImage(mIndex); } + if ((mCurrTexture != gl_tex->getTexName()) || forceBind) + { + activate(); + enable(gl_tex->getTarget()); + mCurrTexture = gl_tex->getTexName(); + glBindTexture(sGLTextureType[gl_tex->getTarget()], mCurrTexture); + if(gl_tex->updateBindStats(gl_tex->mTextureMemory)) + { + texture->setActive() ; + texture->updateBindStatsForTester() ; + } + mHasMipMaps = gl_tex->mHasMipMaps; + if (gl_tex->mTexOptionsDirty) + { + gl_tex->mTexOptionsDirty = false; + setTextureAddressMode(gl_tex->mAddressMode); + setTextureFilteringOption(gl_tex->mFilterOption); + } + } + return true; +} + +bool LLTexUnit::bind(LLImageGL* texture, bool forceBind) +{ + stop_glerror(); + if (mIndex < 0) return false; + + if(!texture) + { + llwarns << "NULL LLTexUnit::bind texture" << llendl; + return false; + } + + if(!texture->getTexName()) + { + if(LLImageGL::sDefaultGLTexture && LLImageGL::sDefaultGLTexture->getTexName()) + { + return bind(LLImageGL::sDefaultGLTexture) ; + } + return false ; + } + + gGL.flush(); + if ((mCurrTexture != texture->getTexName()) || forceBind) { activate(); enable(texture->getTarget()); mCurrTexture = texture->getTexName(); glBindTexture(sGLTextureType[texture->getTarget()], mCurrTexture); - texture->updateBindStats(); - texture->setActive() ; + texture->updateBindStats(texture->mTextureMemory); mHasMipMaps = texture->mHasMipMaps; if (texture->mTexOptionsDirty) { @@ -238,7 +283,7 @@ bool LLTexUnit::bind(LLCubeMap* cubeMap) mCurrTexture = cubeMap->mImages[0]->getTexName(); glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mCurrTexture); mHasMipMaps = cubeMap->mImages[0]->mHasMipMaps; - cubeMap->mImages[0]->updateBindStats(); + cubeMap->mImages[0]->updateBindStats(cubeMap->mImages[0]->mTextureMemory); if (cubeMap->mImages[0]->mTexOptionsDirty) { cubeMap->mImages[0]->mTexOptionsDirty = false; @@ -279,15 +324,21 @@ bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth) bool LLTexUnit::bindManual(eTextureType type, U32 texture, bool hasMips) { - if (mIndex < 0 || mCurrTexture == texture) return false; + if (mIndex < 0) + { + return false; + } - gGL.flush(); - - activate(); - enable(type); - mCurrTexture = texture; - glBindTexture(sGLTextureType[type], texture); - mHasMipMaps = hasMips; + if(mCurrTexture != texture) + { + gGL.flush(); + + activate(); + enable(type); + mCurrTexture = texture; + glBindTexture(sGLTextureType[type], texture); + mHasMipMaps = hasMips; + } return true; } diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 31083d8286..74f87f6d40 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -51,6 +51,7 @@ class LLVertexBuffer; class LLCubeMap; class LLImageGL; class LLRenderTarget; +class LLTexture ; class LLTexUnit { @@ -149,6 +150,7 @@ public: // Binds the LLImageGL to this texture unit // (automatically enables the unit for the LLImageGL's texture type) bool bind(LLImageGL* texture, bool forceBind = false); + bool bind(LLTexture* texture, bool forceBind = false); // Binds a cubemap to this texture unit // (automatically enables the texture unit for cubemaps) diff --git a/indra/llrender/lltexture.cpp b/indra/llrender/lltexture.cpp new file mode 100644 index 0000000000..156ffb953c --- /dev/null +++ b/indra/llrender/lltexture.cpp @@ -0,0 +1,37 @@ +/** + * @file lltexture.cpp + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2009, 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 "linden_common.h" +#include "lltexture.h" + +//virtual +LLTexture::~LLTexture() +{ +} diff --git a/indra/llrender/lltexture.h b/indra/llrender/lltexture.h new file mode 100644 index 0000000000..c18917b663 --- /dev/null +++ b/indra/llrender/lltexture.h @@ -0,0 +1,77 @@ +/** + * @file lltexture.h + * @brief LLTexture definition + * + * This class acts as a wrapper for OpenGL calls. + * The goal of this class is to minimize the number of api calls due to legacy rendering + * code, to define an interface for a multiple rendering API abstraction of the UI + * rendering, and to abstract out direct rendering calls in a way that is cleaner and easier to maintain. + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, 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$ + */ + +#ifndef LL_TEXTURE_H +#define LL_TEXTURE_H + +#include "llrefcount.h" +class LLImageGL ; +class LLTexUnit ; +class LLFontGL ; + +// +//this is an abstract class as the parent for the class LLViewerTexture +//through the following virtual functions, the class LLViewerTexture can be reached from /llrender. +// +class LLTexture : public LLRefCount +{ + friend class LLTexUnit ; + friend class LLFontGL ; + +protected: + virtual ~LLTexture(); + +public: + LLTexture(){} + + // + //interfaces to access LLViewerTexture + // + virtual bool bindDefaultImage(const S32 stage = 0) const = 0 ; + virtual void forceImmediateUpdate() = 0 ; + virtual void setActive() = 0 ; + virtual S32 getWidth(S32 discard_level = -1) const = 0 ; + virtual S32 getHeight(S32 discard_level = -1) const = 0 ; + +private: + //note: do not make this function public. + virtual LLImageGL* getGLTexture() const = 0 ; + + virtual void updateBindStatsForTester() = 0 ; +}; +#endif + diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h index 4c0d10dc40..517210f629 100644 --- a/indra/llui/llcombobox.h +++ b/indra/llui/llcombobox.h @@ -39,7 +39,6 @@ #include "llbutton.h" #include "lluictrl.h" #include "llctrlselectioninterface.h" -#include "llimagegl.h" #include "llrect.h" #include "llscrolllistctrl.h" #include "lllineeditor.h" diff --git a/indra/llui/lliconctrl.h b/indra/llui/lliconctrl.h index a6cab0e9ee..ff25b0d53e 100644 --- a/indra/llui/lliconctrl.h +++ b/indra/llui/lliconctrl.h @@ -37,7 +37,6 @@ #include "v4color.h" #include "lluictrl.h" #include "stdenums.h" -#include "llimagegl.h" class LLTextBox; class LLUICtrlFactory; diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp index 0454771511..68e496aed1 100644 --- a/indra/llui/llmultislider.cpp +++ b/indra/llui/llmultislider.cpp @@ -40,7 +40,6 @@ #include "llfocusmgr.h" #include "llkeyboard.h" // for the MASK constants #include "llcontrol.h" -#include "llimagegl.h" #include "lluictrlfactory.h" #include diff --git a/indra/llui/llprogressbar.cpp b/indra/llui/llprogressbar.cpp index 12353e4c3e..7a34cc6792 100644 --- a/indra/llui/llprogressbar.cpp +++ b/indra/llui/llprogressbar.cpp @@ -39,7 +39,6 @@ #include "llgl.h" #include "llui.h" #include "llfontgl.h" -#include "llimagegl.h" #include "lltimer.h" #include "llglheaders.h" diff --git a/indra/llui/llresizehandle.h b/indra/llui/llresizehandle.h index e4e3c81cec..1560a03796 100644 --- a/indra/llui/llresizehandle.h +++ b/indra/llui/llresizehandle.h @@ -35,7 +35,6 @@ #include "stdtypes.h" #include "llview.h" -#include "llimagegl.h" #include "llcoord.h" diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 63d07cecfd..60cd9239e2 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -44,7 +44,6 @@ #include "llfontgl.h" #include "llui.h" #include "llstring.h" // LLWString -//#include "llimagegl.h" #include "lleditmenuhandler.h" #include "llframetimer.h" diff --git a/indra/llui/llslider.cpp b/indra/llui/llslider.cpp index fa782a1063..f167836bee 100644 --- a/indra/llui/llslider.cpp +++ b/indra/llui/llslider.cpp @@ -40,7 +40,6 @@ #include "llfocusmgr.h" #include "llkeyboard.h" // for the MASK constants #include "llcontrol.h" -#include "llimagegl.h" #include "lluictrlfactory.h" static LLDefaultChildRegistry::Register r1("slider_bar"); diff --git a/indra/llui/llslider.h b/indra/llui/llslider.h index dad65fcce0..50ed212656 100644 --- a/indra/llui/llslider.h +++ b/indra/llui/llslider.h @@ -36,8 +36,6 @@ #include "llf32uictrl.h" #include "v4color.h" -class LLImageGL; - class LLSlider : public LLF32UICtrl { public: diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index ce16f11d33..1bc0adf684 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -55,7 +55,6 @@ #include "llundo.h" #include "llviewborder.h" #include "llcontrol.h" -#include "llimagegl.h" #include "llwindow.h" #include "lltextparser.h" #include diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index c08abf3caf..7eaa118222 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -43,7 +43,6 @@ #include "v4color.h" #include "llrender.h" #include "llrect.h" -#include "llimagegl.h" #include "lldir.h" #include "llfontgl.h" @@ -424,7 +423,7 @@ void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max } -void gl_draw_image( S32 x, S32 y, LLImageGL* image, const LLColor4& color, const LLRectf& uv_rect ) +void gl_draw_image( S32 x, S32 y, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect ) { if (NULL == image) { @@ -434,7 +433,7 @@ void gl_draw_image( S32 x, S32 y, LLImageGL* image, const LLColor4& color, const gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), 0.f, image, color, uv_rect ); } -void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4& color, const LLRectf& uv_rect) +void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect) { if (NULL == image) { @@ -444,7 +443,7 @@ void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, gl_draw_scaled_rotated_image( x, y, width, height, 0.f, image, color, uv_rect ); } -void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLImageGL* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect) +void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect) { if (NULL == image) { @@ -460,7 +459,7 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border gl_draw_scaled_image_with_border(x, y, width, height, image, color, solid_color, uv_rect, scale_rect); } -void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect, const LLRectf& scale_rect) +void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect, const LLRectf& scale_rect) { stop_glerror(); @@ -646,12 +645,12 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLIma } } -void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLImageGL* image, const LLColor4& color, const LLRectf& uv_rect) +void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect) { gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), degrees, image, color, uv_rect ); } -void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLImageGL* image, const LLColor4& color, const LLRectf& uv_rect) +void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect) { if (NULL == image) { @@ -697,7 +696,7 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre } -void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4& color, const LLRectf& uv_rect) +void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect) { if (NULL == image) { diff --git a/indra/llui/llui.h b/indra/llui/llui.h index c4cdbf2c14..6f0da05535 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -58,7 +58,6 @@ class LLColor4; class LLHtmlHelp; -class LLImageGL; class LLVector3; class LLVector2; class LLUIImage; @@ -99,14 +98,14 @@ void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color); void gl_washer_spokes_2d(F32 outer_radius, F32 inner_radius, S32 count, const LLColor4& inner_color, const LLColor4& outer_color); -void gl_draw_image(S32 x, S32 y, LLImageGL* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); -void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); -void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLImageGL* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); -void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLImageGL* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); -void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLImageGL* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); -void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); +void gl_draw_image(S32 x, S32 y, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); +void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); +void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); +void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); +void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); +void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); // Flip vertical, used for LLFloaterHTML -void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); +void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); void gl_rect_2d_xor(S32 left, S32 top, S32 right, S32 bottom); void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase = 0.f ); diff --git a/indra/llui/lluiimage.cpp b/indra/llui/lluiimage.cpp index 84bc2d1bab..ab0d65e731 100644 --- a/indra/llui/lluiimage.cpp +++ b/indra/llui/lluiimage.cpp @@ -39,7 +39,7 @@ #include "lluiimage.h" #include "llui.h" -LLUIImage::LLUIImage(const std::string& name, LLPointer image) : +LLUIImage::LLUIImage(const std::string& name, LLPointer image) : mName(name), mImage(image), mScaleRegion(0.f, 1.f, 1.f, 0.f), diff --git a/indra/llui/lluiimage.h b/indra/llui/lluiimage.h index 0fb16876bf..4ec24e98dc 100644 --- a/indra/llui/lluiimage.h +++ b/indra/llui/lluiimage.h @@ -33,26 +33,28 @@ #ifndef LL_LLUIIMAGE_H #define LL_LLUIIMAGE_H -//#include "llgl.h" -#include "llimagegl.h" +#include "v4color.h" +#include "llpointer.h" +#include "llrefcount.h" #include "llrefcount.h" #include "llrect.h" #include #include "llinitparam.h" +#include "lltexture.h" extern const LLColor4 UI_VERTEX_COLOR; class LLUIImage : public LLRefCount { public: - LLUIImage(const std::string& name, LLPointer image); + LLUIImage(const std::string& name, LLPointer image); virtual ~LLUIImage(); void setClipRegion(const LLRectf& region); void setScaleRegion(const LLRectf& region); - LLPointer getImage() { return mImage; } - const LLPointer& getImage() const { return mImage; } + LLPointer getImage() { return mImage; } + const LLPointer& getImage() const { return mImage; } void draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color = UI_VERTEX_COLOR) const; void draw(S32 x, S32 y, const LLColor4& color = UI_VERTEX_COLOR) const; @@ -79,7 +81,7 @@ protected: std::string mName; LLRectf mScaleRegion; LLRectf mClipRegion; - LLPointer mImage; + LLPointer mImage; BOOL mUniformScaling; BOOL mNoClip; }; diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 9510dcd9cc..1fddf7043d 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -386,9 +386,7 @@ set(viewer_SOURCE_FILES llviewerdisplay.cpp llviewerfloaterreg.cpp llviewergenericmessage.cpp - llviewergesture.cpp - llviewerimage.cpp - llviewerimagelist.cpp + llviewergesture.cpp llviewerinventory.cpp llviewerjointattachment.cpp llviewerjoint.cpp @@ -416,7 +414,9 @@ set(viewer_SOURCE_FILES llviewershadermgr.cpp llviewerstats.cpp llviewertexteditor.cpp + llviewertexture.cpp llviewertextureanim.cpp + llviewertexturelist.cpp llviewerthrottle.cpp llviewervisualparam.cpp llviewerwindow.cpp @@ -815,9 +815,7 @@ set(viewer_HEADER_FILES llviewerdisplay.h llviewerfloaterreg.h llviewergenericmessage.h - llviewergesture.h - llviewerimage.h - llviewerimagelist.h + llviewergesture.h llviewerinventory.h llviewerjoint.h llviewerjointattachment.h @@ -843,7 +841,9 @@ set(viewer_HEADER_FILES llviewershadermgr.h llviewerstats.h llviewertexteditor.h + llviewertexture.h llviewertextureanim.h + llviewertexturelist.h llviewerthrottle.h llviewervisualparam.h llviewerwindow.h diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index c9b27e9802..51b6fc81cd 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -42,7 +42,7 @@ #include "lltexteditor.h" #include "llalertdialog.h" #include "llerrorcontrol.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llgroupmgr.h" #include "llagent.h" #include "llagentwearables.h" @@ -1440,10 +1440,10 @@ bool LLAppViewer::cleanup() LLMetricPerformanceTester::cleanClass() ; //Note: - //LLViewerMedia::cleanupClass() has to be put before gImageList.shutdown() + //LLViewerMedia::cleanupClass() has to be put before gTextureList.shutdown() //because some new image might be generated during cleaning up media. --bao LLViewerMedia::cleanupClass(); - gImageList.shutdown(); // shutdown again in case a callback added something + gTextureList.shutdown(); // shutdown again in case a callback added something LLUIImageList::getInstance()->cleanUp(); // This should eventually be done in LLAppViewer diff --git a/indra/newview/llcolorswatch.cpp b/indra/newview/llcolorswatch.cpp index 531e6d709a..31c2d93c05 100644 --- a/indra/newview/llcolorswatch.cpp +++ b/indra/newview/llcolorswatch.cpp @@ -48,7 +48,7 @@ #include "lltextbox.h" #include "llfloatercolorpicker.h" #include "llviewborder.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llfocusmgr.h" static LLDefaultChildRegistry::Register r("color_swatch"); @@ -227,7 +227,7 @@ void LLColorSwatchCtrl::draw() { if (!mFallbackImageName.empty()) { - LLPointer fallback_image = gImageList.getImageFromFile(mFallbackImageName); + LLPointer fallback_image = LLViewerTextureManager::getFetchedTextureFromFile(mFallbackImageName, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE); if( fallback_image->getComponents() == 4 ) { gl_rect_2d_checkerboard( interior ); diff --git a/indra/newview/llcolorswatch.h b/indra/newview/llcolorswatch.h index db771df6b3..e3e267f831 100644 --- a/indra/newview/llcolorswatch.h +++ b/indra/newview/llcolorswatch.h @@ -36,7 +36,7 @@ #include "lluictrl.h" #include "v4color.h" #include "llfloater.h" -#include "llviewerimage.h" +#include "llviewertexture.h" #include "lltextbox.h" // @@ -45,7 +45,7 @@ class LLColor4; class LLTextBox; class LLFloaterColorPicker; -class LLViewerImage; +class LLViewerTexture; class LLColorSwatchCtrl : public LLUICtrl diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 9f4afc9f17..d8bd32382f 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -229,7 +229,7 @@ S32 LLDrawable::findReferences(LLDrawable *drawablep) return count; } -LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerImage *texturep) +LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerTexture *texturep) { LLMemType mt(LLMemType::MTYPE_DRAWABLE); @@ -253,7 +253,7 @@ LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerImage *texturep) return face; } -LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerImage *texturep) +LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep) { LLMemType mt(LLMemType::MTYPE_DRAWABLE); @@ -275,7 +275,7 @@ LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerImage *texturep) } -void LLDrawable::setNumFaces(const S32 newFaces, LLFacePool *poolp, LLViewerImage *texturep) +void LLDrawable::setNumFaces(const S32 newFaces, LLFacePool *poolp, LLViewerTexture *texturep) { if (newFaces == (S32)mFaces.size()) { @@ -298,7 +298,7 @@ void LLDrawable::setNumFaces(const S32 newFaces, LLFacePool *poolp, LLViewerImag llassert_always(mFaces.size() == newFaces); } -void LLDrawable::setNumFacesFast(const S32 newFaces, LLFacePool *poolp, LLViewerImage *texturep) +void LLDrawable::setNumFacesFast(const S32 newFaces, LLFacePool *poolp, LLViewerTexture *texturep) { if (newFaces <= (S32)mFaces.size() && newFaces >= (S32)mFaces.size()/2) { @@ -673,7 +673,7 @@ BOOL LLDrawable::updateMoveDamped() return done_moving; } -void LLDrawable::updateDistance(LLCamera& camera) +void LLDrawable::updateDistance(LLCamera& camera, bool force_update) { //switch LOD with the spatial group to avoid artifacts //LLSpatialGroup* sg = getSpatialGroup(); @@ -695,7 +695,7 @@ void LLDrawable::updateDistance(LLCamera& camera) for (S32 i = 0; i < getNumFaces(); i++) { LLFace* facep = getFace(i); - if (facep->getPoolType() == LLDrawPool::POOL_ALPHA) + if (force_update || facep->getPoolType() == LLDrawPool::POOL_ALPHA) { LLVector3 box = (facep->mExtents[1] - facep->mExtents[0]) * 0.25f; LLVector3 v = (facep->mCenterLocal-camera.getOrigin()); @@ -736,11 +736,7 @@ void LLDrawable::updateTexture() if (getVOVolume()) { - if (!isActive()) - { - //gPipeline.markMoved(this); - } - else + if (isActive()) { if (isRoot()) { @@ -1273,7 +1269,7 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector* } } -void LLSpatialBridge::updateDistance(LLCamera& camera_in) +void LLSpatialBridge::updateDistance(LLCamera& camera_in, bool force_update) { if (mDrawable == NULL) { @@ -1283,7 +1279,7 @@ void LLSpatialBridge::updateDistance(LLCamera& camera_in) LLCamera camera = transformCamera(camera_in); - mDrawable->updateDistance(camera); + mDrawable->updateDistance(camera, force_update); if (mDrawable->getVObj()) { @@ -1300,7 +1296,7 @@ void LLSpatialBridge::updateDistance(LLCamera& camera_in) if (!drawable->isAvatar()) { - drawable->updateDistance(camera); + drawable->updateDistance(camera, force_update); } } } diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index f3ef0753e7..940e1fc968 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -58,7 +58,7 @@ class LLSpatialGroup; class LLSpatialBridge; class LLSpatialPartition; class LLVOVolume; -class LLViewerImage; +class LLViewerTexture; // Can have multiple silhouettes for each object const U32 SILHOUETTE_HIGHLIGHT = 0; @@ -125,11 +125,11 @@ public: inline S32 getNumFaces() const; //void removeFace(const S32 i); // SJB: Avoid using this, it's slow - LLFace* addFace(LLFacePool *poolp, LLViewerImage *texturep); - LLFace* addFace(const LLTextureEntry *te, LLViewerImage *texturep); + LLFace* addFace(LLFacePool *poolp, LLViewerTexture *texturep); + LLFace* addFace(const LLTextureEntry *te, LLViewerTexture *texturep); void deleteFaces(S32 offset, S32 count); - void setNumFaces(const S32 numFaces, LLFacePool *poolp, LLViewerImage *texturep); - void setNumFacesFast(const S32 numFaces, LLFacePool *poolp, LLViewerImage *texturep); + void setNumFaces(const S32 numFaces, LLFacePool *poolp, LLViewerTexture *texturep); + void setNumFacesFast(const S32 numFaces, LLFacePool *poolp, LLViewerTexture *texturep); void mergeFaces(LLDrawable* src); void init(); diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 9f05ce3c46..3a064a4e7d 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -60,7 +60,7 @@ S32 LLDrawPool::sNumDrawPools = 0; //============================= // Draw Pool Implementation //============================= -LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerImage *tex0) +LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0) { LLDrawPool *poolp = NULL; switch (type) @@ -129,7 +129,7 @@ LLDrawPool::~LLDrawPool() } -LLViewerImage *LLDrawPool::getDebugTexture() +LLViewerTexture *LLDrawPool::getDebugTexture() { return NULL; } @@ -244,7 +244,7 @@ void LLFacePool::destroy() } } -void LLFacePool::dirtyTextures(const std::set& textures) +void LLFacePool::dirtyTextures(const std::set& textures) { } @@ -279,7 +279,7 @@ S32 LLFacePool::drawLoopSetTex(face_array_t& face_list, S32 stage) iter != face_list.end(); iter++) { LLFace *facep = *iter; - gGL.getTexUnit(stage)->bind(facep->getTexture()); + gGL.getTexUnit(stage)->bind(facep->getTexture()) ; gGL.getTexUnit(0)->activate(); res += facep->renderIndexed(); } @@ -295,13 +295,6 @@ void LLFacePool::drawLoop() } } -void LLFacePool::renderFaceSelected(LLFace *facep, - LLImageGL *image, - const LLColor4 &color, - const S32 index_offset, const S32 index_count) -{ -} - void LLFacePool::enqueue(LLFace* facep) { mDrawFace.push_back(facep); @@ -330,7 +323,7 @@ void LLFacePool::resetDrawOrders() mDrawFace.resize(0); } -LLViewerImage *LLFacePool::getTexture() +LLViewerTexture *LLFacePool::getTexture() { return NULL; } @@ -481,7 +474,7 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture) { if (params.mTexture.notNull()) { - gGL.getTexUnit(0)->bind(params.mTexture.get()); + gGL.getTexUnit(0)->bind(params.mTexture) ; if (params.mTextureMatrix) { glMatrixMode(GL_TEXTURE); diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index 87c3ccaffe..966de41df3 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -39,8 +39,8 @@ #include "llvertexbuffer.h" class LLFace; -class LLImageGL; -class LLViewerImage; +class LLViewerTexture; +class LLViewerFetchedTexture; class LLSpatialGroup; class LLDrawInfo; @@ -77,7 +77,7 @@ public: S32 getId() const { return mId; } U32 getType() const { return mType; } - virtual LLViewerImage *getDebugTexture(); + virtual LLViewerTexture *getDebugTexture(); virtual void beginRenderPass( S32 pass ); virtual void endRenderPass( S32 pass ); virtual S32 getNumPasses(); @@ -103,9 +103,9 @@ public: virtual BOOL verify() const { return TRUE; } // Verify that all data in the draw pool is correct! virtual S32 getVertexShaderLevel() const { return mVertexShaderLevel; } - static LLDrawPool* createPool(const U32 type, LLViewerImage *tex0 = NULL); + static LLDrawPool* createPool(const U32 type, LLViewerTexture *tex0 = NULL); virtual LLDrawPool *instancePool() = 0; // Create an empty new instance of the pool. - virtual LLViewerImage* getTexture() = 0; + virtual LLViewerTexture* getTexture() = 0; virtual BOOL isFacePool() { return FALSE; } virtual void resetDrawOrders() = 0; @@ -139,8 +139,8 @@ public: LLRenderPass(const U32 type); virtual ~LLRenderPass(); /*virtual*/ LLDrawPool* instancePool(); - /*virtual*/ LLViewerImage* getDebugTexture() { return NULL; } - LLViewerImage* getTexture() { return NULL; } + /*virtual*/ LLViewerTexture* getDebugTexture() { return NULL; } + LLViewerTexture* getTexture() { return NULL; } BOOL isDead() { return FALSE; } void resetDrawOrders() { } @@ -169,11 +169,9 @@ public: virtual void renderForSelect() = 0; BOOL isDead() { return mReferences.empty(); } - virtual void renderFaceSelected(LLFace *facep, LLImageGL *image, const LLColor4 &color, - const S32 index_offset = 0, const S32 index_count = 0); - - virtual LLViewerImage *getTexture(); - virtual void dirtyTextures(const std::set& textures); + + virtual LLViewerTexture *getTexture(); + virtual void dirtyTextures(const std::set& textures); virtual void enqueue(LLFace *face); virtual BOOL addFace(LLFace *face); diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 7e470bd01f..267f83f295 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -46,7 +46,7 @@ #include "lldrawable.h" #include "llface.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" // For debugging +#include "llviewertexturelist.h" // For debugging #include "llviewerobjectlist.h" // For debugging #include "llviewerwindow.h" #include "pipeline.h" @@ -218,8 +218,8 @@ void LLDrawPoolAlpha::render(S32 pass) } gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); glColor4f(1,0,0,1); - LLViewerImage::sSmokeImagep->addTextureStats(1024.f*1024.f); - gGL.getTexUnit(0)->bind(LLViewerImage::sSmokeImagep.get()); + LLViewerFetchedTexture::sSmokeImagep->addTextureStats(1024.f*1024.f); + gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sSmokeImagep) ; renderAlphaHighlight(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); } @@ -294,7 +294,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) if (params.mTexture.notNull()) { gGL.getTexUnit(0)->activate(); - gGL.getTexUnit(0)->bind(params.mTexture.get()); + gGL.getTexUnit(0)->bind(params.mTexture) ; params.mTexture->addTextureStats(params.mVSize); if (params.mTextureMatrix) { diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 51f4bbac5c..b15cd0b0dc 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -633,7 +633,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) if (pass==1 && (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES) || LLViewerPartSim::getMaxPartCount() <= 0)) { // debug code to draw a sphere in place of avatar - gGL.getTexUnit(0)->bind(LLViewerImage::sWhiteImagep.get()); + gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep); gGL.setColorMask(true, true); LLVector3 pos = avatarp->getPositionAgent(); gGL.color4f(1.0f, 1.0f, 1.0f, 0.7f); @@ -819,7 +819,7 @@ void LLDrawPoolAvatar::renderForSelect() //----------------------------------------------------------------------------- // getDebugTexture() //----------------------------------------------------------------------------- -LLViewerImage *LLDrawPoolAvatar::getDebugTexture() +LLViewerTexture *LLDrawPoolAvatar::getDebugTexture() { if (mReferences.empty()) { diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index 1e2630e1fb..6a2b7fc218 100644 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -105,7 +105,7 @@ public: void endDeferredRigid(); void endDeferredSkinned(); - /*virtual*/ LLViewerImage *getDebugTexture(); + /*virtual*/ LLViewerTexture *getDebugTexture(); /*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display void renderAvatars(LLVOAvatar *single_avatar, S32 pass = -1); // renders only one avatar if single_avatar is not null. diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index ed6e55b7bc..971949e885 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -37,7 +37,6 @@ #include "llstl.h" #include "llviewercontrol.h" #include "lldir.h" -#include "llimagegl.h" #include "m3math.h" #include "m4math.h" #include "v4math.h" @@ -51,7 +50,7 @@ #include "llsky.h" #include "lltextureentry.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "pipeline.h" #include "llspatialpartition.h" #include "llviewershadermgr.h" @@ -143,9 +142,10 @@ void LLStandardBumpmap::restoreGL() // llinfos << "Loading bumpmap: " << bump_image_id << " from viewerart" << llendl; gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mLabel = label; gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage = - gImageList.getImage(LLUUID(bump_image_id), + LLViewerTextureManager::getFetchedTexture(LLUUID(bump_image_id), TRUE, FALSE, + LLViewerTexture::LOD_TEXTURE, 0, 0); gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setLoadedCallback(LLBumpImageList::onSourceStandardLoaded, 0, TRUE, FALSE, NULL ); @@ -569,22 +569,23 @@ void LLDrawPoolBump::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL // static BOOL LLDrawPoolBump::bindBumpMap(LLDrawInfo& params, S32 channel) { - LLImageGL* bump = NULL; + LLViewerTexture* bump = NULL; U8 bump_code = params.mBump; - LLViewerImage* tex = params.mTexture; + LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(params.mTexture) ; + if(!tex) + { + //if the texture is not a fetched texture + return FALSE; + } switch( bump_code ) { - case BE_NO_BUMP: - bump = NULL; + case BE_NO_BUMP: break; case BE_BRIGHTNESS: case BE_DARKNESS: - if( tex ) - { - bump = gBumpImageList.getBrightnessDarknessImage( tex, bump_code ); - } + bump = gBumpImageList.getBrightnessDarknessImage( tex, bump_code ); break; default: @@ -812,7 +813,7 @@ LLBumpImageList::~LLBumpImageList() void LLBumpImageList::addTextureStats(U8 bump, const LLUUID& base_image_id, F32 virtual_size) { bump &= TEM_BUMP_MASK; - LLViewerImage* bump_image = gStandardBumpmapList[bump].mImage; + LLViewerFetchedTexture* bump_image = gStandardBumpmapList[bump].mImage; if( bump_image ) { bump_image->addTextureStats(virtual_size); @@ -826,11 +827,11 @@ void LLBumpImageList::updateImages() for (bump_image_map_t::iterator iter = mBrightnessEntries.begin(); iter != mBrightnessEntries.end(); ) { bump_image_map_t::iterator curiter = iter++; - LLImageGL* image = curiter->second; + LLViewerTexture* image = curiter->second; if( image ) { BOOL destroy = TRUE; - if( image->getHasGLTexture()) + if( image->hasValidGLTexture()) { if( image->getBoundRecently() ) { @@ -853,11 +854,11 @@ void LLBumpImageList::updateImages() for (bump_image_map_t::iterator iter = mDarknessEntries.begin(); iter != mDarknessEntries.end(); ) { bump_image_map_t::iterator curiter = iter++; - LLImageGL* image = curiter->second; + LLViewerTexture* image = curiter->second; if( image ) { BOOL destroy = TRUE; - if( image->getHasGLTexture()) + if( image->hasValidGLTexture()) { if( image->getBoundRecently() ) { @@ -881,16 +882,16 @@ void LLBumpImageList::updateImages() // Note: the caller SHOULD NOT keep the pointer that this function returns. It may be updated as more data arrives. -LLImageGL* LLBumpImageList::getBrightnessDarknessImage(LLViewerImage* src_image, U8 bump_code ) +LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedTexture* src_image, U8 bump_code ) { llassert( (bump_code == BE_BRIGHTNESS) || (bump_code == BE_DARKNESS) ); - LLImageGL* bump = NULL; + LLViewerTexture* bump = NULL; const F32 BRIGHTNESS_DARKNESS_PIXEL_AREA_THRESHOLD = 1000; - if( src_image->mMaxVirtualSize > BRIGHTNESS_DARKNESS_PIXEL_AREA_THRESHOLD ) + if( src_image->getMaxVirtualSize() > BRIGHTNESS_DARKNESS_PIXEL_AREA_THRESHOLD ) { bump_image_map_t* entries_list = NULL; - void (*callback_func)( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) = NULL; + void (*callback_func)( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) = NULL; switch( bump_code ) { @@ -917,14 +918,8 @@ LLImageGL* LLBumpImageList::getBrightnessDarknessImage(LLViewerImage* src_image, LLPointer raw = new LLImageRaw(1,1,1); raw->clear(0x77, 0x77, 0x77, 0xFF); - //------------------------------ - bump = new LLImageGL( raw, TRUE); - //immediately assign bump to a global smart pointer in case some local smart pointer - //accidently releases it. - (*entries_list)[src_image->getID()] = bump; - //------------------------------ - - bump->setExplicitFormat(GL_ALPHA8, GL_ALPHA); + (*entries_list)[src_image->getID()] = LLViewerTextureManager::getLocalTexture( raw.get(), TRUE); + (*entries_list)[src_image->getID()]->setExplicitFormat(GL_ALPHA8, GL_ALPHA); // Note: this may create an LLImageGL immediately src_image->setLoadedCallback( callback_func, 0, TRUE, FALSE, new LLUUID(src_image->getID()) ); @@ -940,7 +935,7 @@ LLImageGL* LLBumpImageList::getBrightnessDarknessImage(LLViewerImage* src_image, // static -void LLBumpImageList::onSourceBrightnessLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) +void LLBumpImageList::onSourceBrightnessLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) { LLUUID* source_asset_id = (LLUUID*)userdata; LLBumpImageList::onSourceLoaded( success, src_vi, src, *source_asset_id, BE_BRIGHTNESS ); @@ -951,7 +946,7 @@ void LLBumpImageList::onSourceBrightnessLoaded( BOOL success, LLViewerImage *src } // static -void LLBumpImageList::onSourceDarknessLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) +void LLBumpImageList::onSourceDarknessLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) { LLUUID* source_asset_id = (LLUUID*)userdata; LLBumpImageList::onSourceLoaded( success, src_vi, src, *source_asset_id, BE_DARKNESS ); @@ -961,7 +956,7 @@ void LLBumpImageList::onSourceDarknessLoaded( BOOL success, LLViewerImage *src_v } } -void LLBumpImageList::onSourceStandardLoaded( BOOL success, LLViewerImage* src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) +void LLBumpImageList::onSourceStandardLoaded( BOOL success, LLViewerFetchedTexture* src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) { if (success && LLPipeline::sRenderDeferred) { @@ -1028,7 +1023,7 @@ void LLBumpImageList::generateNormalMapFromAlpha(LLImageRaw* src, LLImageRaw* nr } // static -void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLUUID& source_asset_id, EBumpEffect bump_code ) +void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLImageRaw* src, LLUUID& source_asset_id, EBumpEffect bump_code ) { if( success ) { @@ -1147,7 +1142,7 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerImage *src_vi, LLIma //--------------------------------------------------- //immediately assign bump to a global smart pointer in case some local smart pointer //accidently releases it. - LLPointer bump = new LLImageGL( TRUE); + LLPointer bump = LLViewerTextureManager::getLocalTexture( TRUE); if (!LLPipeline::sRenderDeferred) { @@ -1220,7 +1215,7 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture) { if (params.mTexture.notNull()) { - gGL.getTexUnit(diffuse_channel)->bind(params.mTexture.get()); + gGL.getTexUnit(diffuse_channel)->bind(params.mTexture) ; params.mTexture->addTextureStats(params.mVSize); } else diff --git a/indra/newview/lldrawpoolbump.h b/indra/newview/lldrawpoolbump.h index 34c1e9c29f..bf940cf1e4 100644 --- a/indra/newview/lldrawpoolbump.h +++ b/indra/newview/lldrawpoolbump.h @@ -41,6 +41,7 @@ class LLImageRaw; class LLSpatialGroup; class LLDrawInfo; +class LLViewerFetchedTexture; class LLDrawPoolBump : public LLRenderPass { @@ -110,7 +111,7 @@ public: LLStandardBumpmap( const std::string& label ) : mLabel(label) {} std::string mLabel; - LLPointer mImage; + LLPointer mImage; static U32 sStandardBumpmapCount; // Number of valid values in gStandardBumpmapList[] @@ -140,21 +141,20 @@ public: void updateImages(); - LLImageGL* getBrightnessDarknessImage(LLViewerImage* src_image, U8 bump_code); -// LLImageGL* getTestImage(); + LLViewerTexture* getBrightnessDarknessImage(LLViewerFetchedTexture* src_image, U8 bump_code); void addTextureStats(U8 bump, const LLUUID& base_image_id, F32 virtual_size); - static void onSourceBrightnessLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ); - static void onSourceDarknessLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ); - static void onSourceStandardLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ); + static void onSourceBrightnessLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ); + static void onSourceDarknessLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ); + static void onSourceStandardLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ); static void generateNormalMapFromAlpha(LLImageRaw* src, LLImageRaw* nrm_image); private: - static void onSourceLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLUUID& source_asset_id, EBumpEffect bump ); + static void onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLImageRaw* src, LLUUID& source_asset_id, EBumpEffect bump ); private: - typedef std::map > bump_image_map_t; + typedef std::map > bump_image_map_t; bump_image_map_t mBrightnessEntries; bump_image_map_t mDarknessEntries; }; diff --git a/indra/newview/lldrawpoolsky.cpp b/indra/newview/lldrawpoolsky.cpp index a9e0948ecf..8428be194f 100644 --- a/indra/newview/lldrawpoolsky.cpp +++ b/indra/newview/lldrawpoolsky.cpp @@ -41,7 +41,7 @@ #include "llface.h" #include "llsky.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerregion.h" #include "llvosky.h" #include "llworld.h" // To get water height diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 2c644b0fd5..a01c9026c8 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -49,7 +49,7 @@ #include "llviewerparceloverlay.h" #include "llvosurfacepatch.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" // To get alpha gradients +#include "llviewertexturelist.h" // To get alpha gradients #include "llworld.h" #include "pipeline.h" #include "llviewershadermgr.h" @@ -62,28 +62,32 @@ S32 LLDrawPoolTerrain::sDetailMode = 1; F32 LLDrawPoolTerrain::sDetailScale = DETAIL_SCALE; static LLGLSLShader* sShader = NULL; -LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerImage *texturep) : +LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) : LLFacePool(POOL_TERRAIN), mTexturep(texturep) { // Hack! sDetailScale = 1.f/gSavedSettings.getF32("RenderTerrainScale"); sDetailMode = gSavedSettings.getS32("RenderTerrainDetail"); - mAlphaRampImagep = gImageList.getImageFromFile("alpha_gradient.tga", - TRUE, TRUE, GL_ALPHA8, GL_ALPHA, + mAlphaRampImagep = LLViewerTextureManager::getFetchedTextureFromFile("alpha_gradient.tga", + TRUE, TRUE, + LLViewerTexture::FETCHED_TEXTURE, + GL_ALPHA8, GL_ALPHA, LLUUID("e97cf410-8e61-7005-ec06-629eba4cd1fb")); - gGL.getTexUnit(0)->bind(mAlphaRampImagep.get()); + gGL.getTexUnit(0)->bind(mAlphaRampImagep); mAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP); - m2DAlphaRampImagep = gImageList.getImageFromFile("alpha_gradient_2d.j2c", - TRUE, TRUE, GL_ALPHA8, GL_ALPHA, + m2DAlphaRampImagep = LLViewerTextureManager::getFetchedTextureFromFile("alpha_gradient_2d.j2c", + TRUE, TRUE, + LLViewerTexture::FETCHED_TEXTURE, + GL_ALPHA8, GL_ALPHA, LLUUID("38b86f85-2575-52a9-a531-23108d8da837")); - gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get()); + gGL.getTexUnit(0)->bind(m2DAlphaRampImagep); m2DAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP); - mTexturep->setBoostLevel(LLViewerImage::BOOST_TERRAIN); + mTexturep->setBoostLevel(LLViewerTexture::BOOST_TERRAIN); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } @@ -170,7 +174,7 @@ void LLDrawPoolTerrain::render(S32 pass) LLVLComposition *compp = regionp->getComposition(); for (S32 i = 0; i < 4; i++) { - compp->mDetailTextures[i]->setBoostLevel(LLViewerImage::BOOST_TERRAIN); + compp->mDetailTextures[i]->setBoostLevel(LLViewerTexture::BOOST_TERRAIN); compp->mDetailTextures[i]->addTextureStats(1024.f*1024.f); // assume large pixel area } @@ -289,10 +293,10 @@ void LLDrawPoolTerrain::renderFullShader() // Hack! Get the region that this draw pool is rendering from! LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion(); LLVLComposition *compp = regionp->getComposition(); - LLViewerImage *detail_texture0p = compp->mDetailTextures[0]; - LLViewerImage *detail_texture1p = compp->mDetailTextures[1]; - LLViewerImage *detail_texture2p = compp->mDetailTextures[2]; - LLViewerImage *detail_texture3p = compp->mDetailTextures[3]; + LLViewerTexture *detail_texture0p = compp->mDetailTextures[0]; + LLViewerTexture *detail_texture1p = compp->mDetailTextures[1]; + LLViewerTexture *detail_texture2p = compp->mDetailTextures[2]; + LLViewerTexture *detail_texture3p = compp->mDetailTextures[3]; LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal(); F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale; @@ -363,7 +367,7 @@ void LLDrawPoolTerrain::renderFullShader() // Alpha Ramp // S32 alpha_ramp = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_ALPHARAMP); - gGL.getTexUnit(alpha_ramp)->bind(m2DAlphaRampImagep.get()); + gGL.getTexUnit(alpha_ramp)->bind(m2DAlphaRampImagep); // GL_BLEND disabled by default drawLoop(); @@ -429,10 +433,10 @@ void LLDrawPoolTerrain::renderFull4TU() // Hack! Get the region that this draw pool is rendering from! LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion(); LLVLComposition *compp = regionp->getComposition(); - LLViewerImage *detail_texture0p = compp->mDetailTextures[0]; - LLViewerImage *detail_texture1p = compp->mDetailTextures[1]; - LLViewerImage *detail_texture2p = compp->mDetailTextures[2]; - LLViewerImage *detail_texture3p = compp->mDetailTextures[3]; + LLViewerTexture *detail_texture0p = compp->mDetailTextures[0]; + LLViewerTexture *detail_texture1p = compp->mDetailTextures[1]; + LLViewerTexture *detail_texture2p = compp->mDetailTextures[2]; + LLViewerTexture *detail_texture3p = compp->mDetailTextures[3]; LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal(); F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale; @@ -527,7 +531,7 @@ void LLDrawPoolTerrain::renderFull4TU() // // Stage 1: Generate alpha ramp for detail2/detail3 transition // - gGL.getTexUnit(1)->bind(m2DAlphaRampImagep.get()); + gGL.getTexUnit(1)->bind(m2DAlphaRampImagep); gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(1)->activate(); @@ -559,7 +563,7 @@ void LLDrawPoolTerrain::renderFull4TU() // // Stage 3: Generate alpha ramp for detail1/detail2 transition // - gGL.getTexUnit(3)->bind(m2DAlphaRampImagep.get()); + gGL.getTexUnit(3)->bind(m2DAlphaRampImagep); gGL.getTexUnit(3)->enable(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(3)->activate(); @@ -630,10 +634,10 @@ void LLDrawPoolTerrain::renderFull2TU() // Hack! Get the region that this draw pool is rendering from! LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion(); LLVLComposition *compp = regionp->getComposition(); - LLViewerImage *detail_texture0p = compp->mDetailTextures[0]; - LLViewerImage *detail_texture1p = compp->mDetailTextures[1]; - LLViewerImage *detail_texture2p = compp->mDetailTextures[2]; - LLViewerImage *detail_texture3p = compp->mDetailTextures[3]; + LLViewerTexture *detail_texture0p = compp->mDetailTextures[0]; + LLViewerTexture *detail_texture1p = compp->mDetailTextures[1]; + LLViewerTexture *detail_texture2p = compp->mDetailTextures[2]; + LLViewerTexture *detail_texture3p = compp->mDetailTextures[3]; LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal(); F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale; @@ -671,7 +675,7 @@ void LLDrawPoolTerrain::renderFull2TU() // // Stage 0: Generate alpha ramp for detail0/detail1 transition // - gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get()); + gGL.getTexUnit(0)->bind(m2DAlphaRampImagep); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); @@ -709,7 +713,7 @@ void LLDrawPoolTerrain::renderFull2TU() // // Stage 0: Generate alpha ramp for detail1/detail2 transition // - gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get()); + gGL.getTexUnit(0)->bind(m2DAlphaRampImagep); // Set the texture matrix glMatrixMode(GL_TEXTURE); @@ -749,7 +753,7 @@ void LLDrawPoolTerrain::renderFull2TU() // Stage 0: Generate alpha ramp for detail2/detail3 transition // gGL.getTexUnit(0)->activate(); - gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get()); + gGL.getTexUnit(0)->bind(m2DAlphaRampImagep); // Set the texture matrix glMatrixMode(GL_TEXTURE); glLoadIdentity(); @@ -822,7 +826,7 @@ void LLDrawPoolTerrain::renderSimple() gGL.getTexUnit(0)->activate(); gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(0)->bind(mTexturep.get()); + gGL.getTexUnit(0)->bind(mTexturep); LLVector3 origin_agent = mDrawFace[0]->getDrawable()->getVObj()->getRegion()->getOriginAgent(); F32 tscale = 1.f/256.f; @@ -872,7 +876,7 @@ void LLDrawPoolTerrain::renderOwnership() LLSurface *surfacep = surface_patchp->getSurface(); LLViewerRegion *regionp = surfacep->getRegion(); LLViewerParcelOverlay *overlayp = regionp->getParcelOverlay(); - LLImageGL *texturep = overlayp->getTexture(); + LLViewerTexture *texturep = overlayp->getTexture(); gGL.getTexUnit(0)->bind(texturep); @@ -920,9 +924,10 @@ void LLDrawPoolTerrain::renderForSelect() } } -void LLDrawPoolTerrain::dirtyTextures(const std::set& textures) +void LLDrawPoolTerrain::dirtyTextures(const std::set& textures) { - if (textures.find(mTexturep) != textures.end()) + LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(mTexturep) ; + if (tex && textures.find(tex) != textures.end()) { for (std::vector::iterator iter = mReferences.begin(); iter != mReferences.end(); iter++) @@ -933,12 +938,12 @@ void LLDrawPoolTerrain::dirtyTextures(const std::set& textures) } } -LLViewerImage *LLDrawPoolTerrain::getTexture() +LLViewerTexture *LLDrawPoolTerrain::getTexture() { return mTexturep; } -LLViewerImage *LLDrawPoolTerrain::getDebugTexture() +LLViewerTexture *LLDrawPoolTerrain::getDebugTexture() { return mTexturep; } diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h index 19d09e2feb..2e2a36d533 100644 --- a/indra/newview/lldrawpoolterrain.h +++ b/indra/newview/lldrawpoolterrain.h @@ -37,7 +37,7 @@ class LLDrawPoolTerrain : public LLFacePool { - LLPointer mTexturep; + LLPointer mTexturep; public: enum { @@ -53,7 +53,7 @@ public: virtual U32 getVertexDataMask(); static S32 getDetailMode(); - LLDrawPoolTerrain(LLViewerImage *texturep); + LLDrawPoolTerrain(LLViewerTexture *texturep); virtual ~LLDrawPoolTerrain(); /*virtual*/ LLDrawPool *instancePool(); @@ -73,14 +73,14 @@ public: /*virtual*/ void beginRenderPass( S32 pass ); /*virtual*/ void endRenderPass( S32 pass ); /*virtual*/ void renderForSelect(); - /*virtual*/ void dirtyTextures(const std::set& textures); - /*virtual*/ LLViewerImage *getTexture(); - /*virtual*/ LLViewerImage *getDebugTexture(); + /*virtual*/ void dirtyTextures(const std::set& textures); + /*virtual*/ LLViewerTexture *getTexture(); + /*virtual*/ LLViewerTexture *getDebugTexture(); /*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display - LLPointer mAlphaRampImagep; - LLPointer m2DAlphaRampImagep; - LLPointer mAlphaNoiseImagep; + LLPointer mAlphaRampImagep; + LLPointer m2DAlphaRampImagep; + LLPointer mAlphaNoiseImagep; static S32 sDetailMode; static F32 sDetailScale; // meters per texture diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp index 22634d96b0..f572e2cb44 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -47,11 +47,11 @@ S32 LLDrawPoolTree::sDiffTex = 0; static LLGLSLShader* shader = NULL; -LLDrawPoolTree::LLDrawPoolTree(LLViewerImage *texturep) : +LLDrawPoolTree::LLDrawPoolTree(LLViewerTexture *texturep) : LLFacePool(POOL_TREE), mTexturep(texturep) { - gGL.getTexUnit(0)->bind(mTexturep.get()); + gGL.getTexUnit(0)->bind(mTexturep); mTexturep->setAddressMode(LLTexUnit::TAM_WRAP); } @@ -246,7 +246,7 @@ void LLDrawPoolTree::renderTree(BOOL selecting) LLGLState normalize(GL_NORMALIZE, TRUE); // Bind the texture for this tree. - gGL.getTexUnit(sDiffTex)->bind(mTexturep.get()); + gGL.getTexUnit(sDiffTex)->bind(mTexturep); U32 indices_drawn = 0; @@ -376,12 +376,12 @@ BOOL LLDrawPoolTree::verify() const return TRUE; } -LLViewerImage *LLDrawPoolTree::getTexture() +LLViewerTexture *LLDrawPoolTree::getTexture() { return mTexturep; } -LLViewerImage *LLDrawPoolTree::getDebugTexture() +LLViewerTexture *LLDrawPoolTree::getDebugTexture() { return mTexturep; } diff --git a/indra/newview/lldrawpooltree.h b/indra/newview/lldrawpooltree.h index 80c4fdfffe..bc7711d4e8 100644 --- a/indra/newview/lldrawpooltree.h +++ b/indra/newview/lldrawpooltree.h @@ -37,7 +37,7 @@ class LLDrawPoolTree : public LLFacePool { - LLPointer mTexturep; + LLPointer mTexturep; public: enum { @@ -48,7 +48,7 @@ public: virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; } - LLDrawPoolTree(LLViewerImage *texturep); + LLDrawPoolTree(LLViewerTexture *texturep); /*virtual*/ LLDrawPool *instancePool(); @@ -70,8 +70,8 @@ public: /*virtual*/ S32 getNumPasses() { return 1; } /*virtual*/ void renderForSelect(); /*virtual*/ BOOL verify() const; - /*virtual*/ LLViewerImage *getTexture(); - /*virtual*/ LLViewerImage *getDebugTexture(); + /*virtual*/ LLViewerTexture *getTexture(); + /*virtual*/ LLViewerTexture *getDebugTexture(); /*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display static S32 sDiffTex; diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 4a593ac4f8..16623ca2b6 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -45,7 +45,7 @@ #include "lldrawable.h" #include "llface.h" #include "llsky.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerregion.h" #include "llvosky.h" #include "llvowater.h" @@ -69,17 +69,17 @@ LLVector3 LLDrawPoolWater::sLightDir; LLDrawPoolWater::LLDrawPoolWater() : LLFacePool(POOL_WATER) { - mHBTex[0] = gImageList.getImage(gSunTextureID, TRUE, TRUE); - gGL.getTexUnit(0)->bind(mHBTex[0].get()); + mHBTex[0] = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, TRUE); + gGL.getTexUnit(0)->bind(mHBTex[0]) ; mHBTex[0]->setAddressMode(LLTexUnit::TAM_CLAMP); - mHBTex[1] = gImageList.getImage(gMoonTextureID, TRUE, TRUE); - gGL.getTexUnit(0)->bind(mHBTex[1].get()); + mHBTex[1] = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, TRUE); + gGL.getTexUnit(0)->bind(mHBTex[1]); mHBTex[1]->setAddressMode(LLTexUnit::TAM_CLAMP); - mWaterImagep = gImageList.getImage(WATER_TEST); + mWaterImagep = LLViewerTextureManager::getFetchedTexture(WATER_TEST); mWaterImagep->setNoDelete() ; - mWaterNormp = gImageList.getImage(DEFAULT_WATER_NORMAL); + mWaterNormp = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL); mWaterNormp->setNoDelete() ; restoreGL(); @@ -184,7 +184,7 @@ void LLDrawPoolWater::render(S32 pass) mWaterImagep->addTextureStats(1024.f*1024.f); gGL.getTexUnit(1)->activate(); gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(1)->bind(mWaterImagep.get()); + gGL.getTexUnit(1)->bind(mWaterImagep) ; LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis(); F32 up_dot = camera_up * LLVector3::z_axis; @@ -329,7 +329,7 @@ void LLDrawPoolWater::renderReflection(LLFace* face) LLGLSNoFog noFog; - gGL.getTexUnit(0)->bind(mHBTex[dr].get()); + gGL.getTexUnit(0)->bind(mHBTex[dr]); LLOverrideFaceColor override(this, face->getFaceColor().mV); face->renderIndexed(); @@ -419,11 +419,11 @@ void LLDrawPoolWater::shade() // change mWaterNormp if needed if (mWaterNormp->getID() != param_mgr->getNormalMapID()) { - mWaterNormp = gImageList.getImage(param_mgr->getNormalMapID()); + mWaterNormp = LLViewerTextureManager::getFetchedTexture(param_mgr->getNormalMapID()); } mWaterNormp->addTextureStats(1024.f*1024.f); - gGL.getTexUnit(bumpTex)->bind(mWaterNormp.get()); + gGL.getTexUnit(bumpTex)->bind(mWaterNormp) ; if (gSavedSettings.getBOOL("RenderWaterMipNormal")) { mWaterNormp->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC); @@ -587,20 +587,9 @@ void LLDrawPoolWater::renderForSelect() return; } - -void LLDrawPoolWater::renderFaceSelected(LLFace *facep, - LLImageGL *image, - const LLColor4 &color, - const S32 index_offset, const S32 index_count) -{ - // Can't select water - return; -} - - -LLViewerImage *LLDrawPoolWater::getDebugTexture() +LLViewerTexture *LLDrawPoolWater::getDebugTexture() { - return LLViewerImage::sSmokeImagep; + return LLViewerFetchedTexture::sSmokeImagep; } LLColor3 LLDrawPoolWater::getDebugColor() const diff --git a/indra/newview/lldrawpoolwater.h b/indra/newview/lldrawpoolwater.h index 6351041140..e28ac1cfab 100644 --- a/indra/newview/lldrawpoolwater.h +++ b/indra/newview/lldrawpoolwater.h @@ -43,9 +43,9 @@ class LLWaterSurface; class LLDrawPoolWater: public LLFacePool { protected: - LLPointer mHBTex[2]; - LLPointer mWaterImagep; - LLPointer mWaterNormp; + LLPointer mHBTex[2]; + LLPointer mWaterImagep; + LLPointer mWaterNormp; const LLWaterSurface *mWaterSurface; public: @@ -78,12 +78,10 @@ public: /*virtual*/ S32 getNumPasses(); /*virtual*/ void render(S32 pass = 0); - /*virtual*/ void renderFaceSelected(LLFace *facep, LLImageGL *image, const LLColor4 &color, - const S32 index_offset = 0, const S32 index_count = 0); /*virtual*/ void prerender(); /*virtual*/ void renderForSelect(); - /*virtual*/ LLViewerImage *getDebugTexture(); + /*virtual*/ LLViewerTexture *getDebugTexture(); /*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display void renderReflection(LLFace* face); diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index 6ff65c7ed0..917b6fafbc 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -47,7 +47,7 @@ #include "llface.h" #include "llrender.h" -LLPointer LLDrawPoolWLSky::sCloudNoiseTexture = NULL; +LLPointer LLDrawPoolWLSky::sCloudNoiseTexture = NULL; LLPointer LLDrawPoolWLSky::sCloudNoiseRawImage = NULL; @@ -71,7 +71,7 @@ LLDrawPoolWLSky::LLDrawPoolWLSky(void) : cloudNoiseFile->decode(sCloudNoiseRawImage, 0.0f); - LLImageGL::create(sCloudNoiseTexture, sCloudNoiseRawImage, TRUE); + sCloudNoiseTexture = LLViewerTextureManager::getLocalTexture(sCloudNoiseRawImage.get(), TRUE); LLWLParamManager::instance()->propagateParameters(); } @@ -83,7 +83,7 @@ LLDrawPoolWLSky::~LLDrawPoolWLSky() sCloudNoiseRawImage = NULL; } -LLViewerImage *LLDrawPoolWLSky::getDebugTexture() +LLViewerTexture *LLDrawPoolWLSky::getDebugTexture() { return NULL; } @@ -224,7 +224,7 @@ void LLDrawPoolWLSky::renderHeavenlyBodies() LLFace * face = gSky.mVOSkyp->mFace[LLVOSky::FACE_SUN]; if (gSky.mVOSkyp->getSun().getDraw() && face->getGeomCount()) { - LLImageGL * tex = face->getTexture(); + LLViewerTexture * tex = face->getTexture(); gGL.getTexUnit(0)->bind(tex); LLColor4 color(gSky.mVOSkyp->getSun().getInterpColor()); LLFacePool::LLOverrideFaceColor color_override(this, color); @@ -239,8 +239,7 @@ void LLDrawPoolWLSky::renderHeavenlyBodies() // *NOTE: even though we already bound this texture above for the // stars register combiners, we bind again here for defensive reasons, // since LLImageGL::bind detects that it's a noop, and optimizes it out. - LLImageGL * tex = face->getTexture(); - gGL.getTexUnit(0)->bind(tex); + gGL.getTexUnit(0)->bind(face->getTexture()); LLColor4 color(gSky.mVOSkyp->getMoon().getInterpColor()); F32 a = gSky.mVOSkyp->getMoon().getDirection().mV[2]; if (a > 0.f) @@ -280,9 +279,8 @@ void LLDrawPoolWLSky::render(S32 pass) // *NOTE: have to bind a texture here since register combiners blending in // renderStars() requires something to be bound and we might as well only - // bind the moon's texture once. - LLImageGL * tex = gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]->getTexture(); - gGL.getTexUnit(0)->bind(tex); + // bind the moon's texture once. + gGL.getTexUnit(0)->bind(gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]->getTexture()); renderHeavenlyBodies(); @@ -306,7 +304,7 @@ LLDrawPoolWLSky *LLDrawPoolWLSky::instancePool() return new LLDrawPoolWLSky(); } -LLViewerImage* LLDrawPoolWLSky::getTexture() +LLViewerTexture* LLDrawPoolWLSky::getTexture() { return NULL; } @@ -324,5 +322,5 @@ void LLDrawPoolWLSky::cleanupGL() //static void LLDrawPoolWLSky::restoreGL() { - LLImageGL::create(sCloudNoiseTexture, sCloudNoiseRawImage, TRUE); + sCloudNoiseTexture = LLViewerTextureManager::getLocalTexture(sCloudNoiseRawImage.get(), TRUE); } diff --git a/indra/newview/lldrawpoolwlsky.h b/indra/newview/lldrawpoolwlsky.h index c7a1f3fe27..7ff760ac39 100644 --- a/indra/newview/lldrawpoolwlsky.h +++ b/indra/newview/lldrawpoolwlsky.h @@ -55,7 +55,7 @@ public: /*virtual*/ void endPostDeferredPass(S32 pass) { endRenderPass(pass); } /*virtual*/ void renderPostDeferred(S32 pass) { render(pass); } - /*virtual*/ LLViewerImage *getDebugTexture(); + /*virtual*/ LLViewerTexture *getDebugTexture(); /*virtual*/ void beginRenderPass( S32 pass ); /*virtual*/ void endRenderPass( S32 pass ); /*virtual*/ S32 getNumPasses() { return 1; } @@ -65,11 +65,11 @@ public: /*virtual*/ BOOL verify() const { return TRUE; } // Verify that all data in the draw pool is correct! /*virtual*/ S32 getVertexShaderLevel() const { return mVertexShaderLevel; } - //static LLDrawPool* createPool(const U32 type, LLViewerImage *tex0 = NULL); + //static LLDrawPool* createPool(const U32 type, LLViewerTexture *tex0 = NULL); // Create an empty new instance of the pool. /*virtual*/ LLDrawPoolWLSky *instancePool(); ///< covariant override - /*virtual*/ LLViewerImage* getTexture(); + /*virtual*/ LLViewerTexture* getTexture(); /*virtual*/ BOOL isFacePool() { return FALSE; } /*virtual*/ void resetDrawOrders(); @@ -83,7 +83,7 @@ private: void renderHeavenlyBodies(); private: - static LLPointer sCloudNoiseTexture; + static LLPointer sCloudNoiseTexture; static LLPointer sCloudNoiseRawImage; }; diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index 1953c29068..0bb5edf3f9 100644 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp @@ -1,6 +1,6 @@ /** * @file lldynamictexture.cpp - * @brief Implementation of LLDynamicTexture class + * @brief Implementation of LLViewerDynamicTexture class * * $LicenseInfo:firstyear=2001&license=viewergpl$ * @@ -42,24 +42,20 @@ #include "llviewerwindow.h" #include "llviewercamera.h" #include "llviewercontrol.h" -#include "llviewerimage.h" +#include "llviewertexture.h" #include "llvertexbuffer.h" #include "llviewerdisplay.h" #include "llrender.h" // static -LLDynamicTexture::instance_list_t LLDynamicTexture::sInstances[ LLDynamicTexture::ORDER_COUNT ]; -S32 LLDynamicTexture::sNumRenders = 0; +LLViewerDynamicTexture::instance_list_t LLViewerDynamicTexture::sInstances[ LLViewerDynamicTexture::ORDER_COUNT ]; +S32 LLViewerDynamicTexture::sNumRenders = 0; //----------------------------------------------------------------------------- -// LLDynamicTexture() +// LLViewerDynamicTexture() //----------------------------------------------------------------------------- -LLDynamicTexture::LLDynamicTexture(S32 width, S32 height, S32 components, EOrder order, BOOL clamp) : - mWidth(width), - mHeight(height), - mComponents(components), - mTexture(NULL), - mLastBindTime(0), +LLViewerDynamicTexture::LLViewerDynamicTexture(S32 width, S32 height, S32 components, EOrder order, BOOL clamp) : + LLViewerTexture(width, height, components, FALSE), mClamp(clamp) { llassert((1 <= components) && (components <= 4)); @@ -67,64 +63,56 @@ LLDynamicTexture::LLDynamicTexture(S32 width, S32 height, S32 components, EOrder generateGLTexture(); llassert( 0 <= order && order < ORDER_COUNT ); - LLDynamicTexture::sInstances[ order ].insert(this); + LLViewerDynamicTexture::sInstances[ order ].insert(this); } //----------------------------------------------------------------------------- -// LLDynamicTexture() +// LLViewerDynamicTexture() //----------------------------------------------------------------------------- -LLDynamicTexture::~LLDynamicTexture() +LLViewerDynamicTexture::~LLViewerDynamicTexture() { - releaseGLTexture(); for( S32 order = 0; order < ORDER_COUNT; order++ ) { - LLDynamicTexture::sInstances[order].erase(this); // will fail in all but one case. + LLViewerDynamicTexture::sInstances[order].erase(this); // will fail in all but one case. } } -//----------------------------------------------------------------------------- -// releaseGLTexture() -//----------------------------------------------------------------------------- -void LLDynamicTexture::releaseGLTexture() +//virtual +S8 LLViewerDynamicTexture::getType() const { - if (mTexture.notNull()) - { -// llinfos << "RELEASING " << (mWidth*mHeight*mComponents)/1024 << "K" << llendl; - mTexture = NULL; - } + return LLViewerTexture::DYNAMIC_TEXTURE ; } //----------------------------------------------------------------------------- // generateGLTexture() //----------------------------------------------------------------------------- -void LLDynamicTexture::generateGLTexture() +void LLViewerDynamicTexture::generateGLTexture() { + LLViewerTexture::generateGLTexture() ; generateGLTexture(-1, 0, 0, FALSE); } -void LLDynamicTexture::generateGLTexture(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes) +void LLViewerDynamicTexture::generateGLTexture(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes) { if (mComponents < 1 || mComponents > 4) { llerrs << "Bad number of components in dynamic texture: " << mComponents << llendl; } - releaseGLTexture(); - LLPointer raw_image = new LLImageRaw(mWidth, mHeight, mComponents); - mTexture = new LLViewerImage(mWidth, mHeight, mComponents, FALSE); + + LLPointer raw_image = new LLImageRaw(mFullWidth, mFullHeight, mComponents); if (internal_format >= 0) { - mTexture->setExplicitFormat(internal_format, primary_format, type_format, swap_bytes); + setExplicitFormat(internal_format, primary_format, type_format, swap_bytes); } -// llinfos << "ALLOCATING " << (mWidth*mHeight*mComponents)/1024 << "K" << llendl; - mTexture->createGLTexture(0, raw_image); - mTexture->setAddressMode((mClamp) ? LLTexUnit::TAM_CLAMP : LLTexUnit::TAM_WRAP); - mTexture->setGLTextureCreated(false); + createGLTexture(0, raw_image); + setAddressMode((mClamp) ? LLTexUnit::TAM_CLAMP : LLTexUnit::TAM_WRAP); + mGLTexturep->setGLTextureCreated(false); } //----------------------------------------------------------------------------- // render() //----------------------------------------------------------------------------- -BOOL LLDynamicTexture::render() +BOOL LLViewerDynamicTexture::render() { return FALSE; } @@ -132,13 +120,13 @@ BOOL LLDynamicTexture::render() //----------------------------------------------------------------------------- // preRender() //----------------------------------------------------------------------------- -void LLDynamicTexture::preRender(BOOL clear_depth) +void LLViewerDynamicTexture::preRender(BOOL clear_depth) { { // force rendering to on-screen portion of frame buffer LLCoordScreen window_pos; gViewerWindow->getWindow()->getPosition( &window_pos ); - mOrigin.set(0, gViewerWindow->getWindowDisplayHeight() - mHeight); // top left corner + mOrigin.set(0, gViewerWindow->getWindowDisplayHeight() - mFullHeight); // top left corner if (window_pos.mX < 0) { @@ -159,7 +147,7 @@ void LLDynamicTexture::preRender(BOOL clear_depth) mCamera.setView(LLViewerCamera::getInstance()->getView()); mCamera.setNear(LLViewerCamera::getInstance()->getNear()); - glViewport(mOrigin.mX, mOrigin.mY, mWidth, mHeight); + glViewport(mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight); if (clear_depth) { glClear(GL_DEPTH_BUFFER_BIT); @@ -169,12 +157,16 @@ void LLDynamicTexture::preRender(BOOL clear_depth) //----------------------------------------------------------------------------- // postRender() //----------------------------------------------------------------------------- -void LLDynamicTexture::postRender(BOOL success) +void LLViewerDynamicTexture::postRender(BOOL success) { { if (success) { - success = mTexture->setSubImageFromFrameBuffer(0, 0, mOrigin.mX, mOrigin.mY, mWidth, mHeight); + if(mGLTexturep.isNull()) + { + generateGLTexture() ; + } + success = mGLTexturep->setSubImageFromFrameBuffer(0, 0, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight); } } @@ -194,7 +186,7 @@ void LLDynamicTexture::postRender(BOOL success) // updateDynamicTextures() // Calls update on each dynamic texture. Calls each group in order: "first," then "middle," then "last." //----------------------------------------------------------------------------- -BOOL LLDynamicTexture::updateAllInstances() +BOOL LLViewerDynamicTexture::updateAllInstances() { sNumRenders = 0; if (gGLManager.mIsDisabled) @@ -206,10 +198,10 @@ BOOL LLDynamicTexture::updateAllInstances() BOOL ret = FALSE ; for( S32 order = 0; order < ORDER_COUNT; order++ ) { - for (instance_list_t::iterator iter = LLDynamicTexture::sInstances[order].begin(); - iter != LLDynamicTexture::sInstances[order].end(); ++iter) + for (instance_list_t::iterator iter = LLViewerDynamicTexture::sInstances[order].begin(); + iter != LLViewerDynamicTexture::sInstances[order].end(); ++iter) { - LLDynamicTexture *dynamicTexture = *iter; + LLViewerDynamicTexture *dynamicTexture = *iter; if (dynamicTexture->needsRender()) { glClear(GL_DEPTH_BUFFER_BIT); @@ -236,30 +228,18 @@ BOOL LLDynamicTexture::updateAllInstances() return ret; } -//virtual -void LLDynamicTexture::restoreGLTexture() -{ - generateGLTexture() ; -} - -//virtual -void LLDynamicTexture::destroyGLTexture() -{ - releaseGLTexture() ; -} - //----------------------------------------------------------------------------- // static // destroyGL() //----------------------------------------------------------------------------- -void LLDynamicTexture::destroyGL() +void LLViewerDynamicTexture::destroyGL() { for( S32 order = 0; order < ORDER_COUNT; order++ ) { - for (instance_list_t::iterator iter = LLDynamicTexture::sInstances[order].begin(); - iter != LLDynamicTexture::sInstances[order].end(); ++iter) + for (instance_list_t::iterator iter = LLViewerDynamicTexture::sInstances[order].begin(); + iter != LLViewerDynamicTexture::sInstances[order].end(); ++iter) { - LLDynamicTexture *dynamicTexture = *iter; + LLViewerDynamicTexture *dynamicTexture = *iter; dynamicTexture->destroyGLTexture() ; } } @@ -269,7 +249,7 @@ void LLDynamicTexture::destroyGL() // static // restoreGL() //----------------------------------------------------------------------------- -void LLDynamicTexture::restoreGL() +void LLViewerDynamicTexture::restoreGL() { if (gGLManager.mIsDisabled) { @@ -278,10 +258,10 @@ void LLDynamicTexture::restoreGL() for( S32 order = 0; order < ORDER_COUNT; order++ ) { - for (instance_list_t::iterator iter = LLDynamicTexture::sInstances[order].begin(); - iter != LLDynamicTexture::sInstances[order].end(); ++iter) + for (instance_list_t::iterator iter = LLViewerDynamicTexture::sInstances[order].begin(); + iter != LLViewerDynamicTexture::sInstances[order].end(); ++iter) { - LLDynamicTexture *dynamicTexture = *iter; + LLViewerDynamicTexture *dynamicTexture = *iter; dynamicTexture->restoreGLTexture() ; } } diff --git a/indra/newview/lldynamictexture.h b/indra/newview/lldynamictexture.h index 22e5a4819d..c5fc83f9bb 100644 --- a/indra/newview/lldynamictexture.h +++ b/indra/newview/lldynamictexture.h @@ -1,6 +1,6 @@ /** * @file lldynamictexture.h - * @brief Implementation of LLDynamicTexture class + * @brief Implementation of LLViewerDynamicTexture class * * $LicenseInfo:firstyear=2002&license=viewergpl$ * @@ -36,59 +36,51 @@ #include "llcamera.h" #include "llgl.h" #include "llcoord.h" -#include "llimagegl.h" +#include "llviewertexture.h" -class LLDynamicTexture +class LLViewerDynamicTexture : public LLViewerTexture { +protected: + /*virtual*/ ~LLViewerDynamicTexture(); + public: enum EOrder { ORDER_FIRST = 0, ORDER_MIDDLE = 1, ORDER_LAST = 2, ORDER_RESET = 3, ORDER_COUNT = 4 }; - LLDynamicTexture(S32 width, + LLViewerDynamicTexture(S32 width, S32 height, S32 components, // = 4, EOrder order, // = ORDER_MIDDLE, BOOL clamp); - virtual ~LLDynamicTexture(); + + /*virtual*/ S8 getType() const ; S32 getOriginX() { return mOrigin.mX; } S32 getOriginY() { return mOrigin.mY; } - S32 getWidth() { return mWidth; } - S32 getHeight() { return mHeight; } - S32 getComponents() { return mComponents; } - S32 getSize() { return mWidth * mHeight * mComponents; } + + S32 getSize() { return mFullWidth * mFullHeight * mComponents; } virtual BOOL needsRender() { return TRUE; } virtual void preRender(BOOL clear_depth = TRUE); virtual BOOL render(); virtual void postRender(BOOL success); - virtual void restoreGLTexture() ; - virtual void destroyGLTexture() ; - - LLImageGL* getTexture(void) const { return mTexture; } + virtual void restoreGLTexture() {} + virtual void destroyGLTexture() {} static BOOL updateAllInstances(); - - static void destroyGL(); - static void restoreGL(); - + static void destroyGL() ; + static void restoreGL() ; protected: - void releaseGLTexture(); void generateGLTexture(); void generateGLTexture(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes = FALSE); protected: - S32 mWidth; - S32 mHeight; - S32 mComponents; - LLPointer mTexture; - F32 mLastBindTime; BOOL mClamp; LLCoordGL mOrigin; - LLCamera mCamera; - typedef std::set instance_list_t; - static instance_list_t sInstances[ LLDynamicTexture::ORDER_COUNT ]; + + typedef std::set instance_list_t; + static instance_list_t sInstances[ LLViewerDynamicTexture::ORDER_COUNT ]; static S32 sNumRenders; }; diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 3dfe6a2820..bef9e40c49 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -47,7 +47,7 @@ #include "lllightconstants.h" #include "llsky.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llvosky.h" #include "llvovolume.h" #include "pipeline.h" @@ -179,6 +179,10 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp) void LLFace::destroy() { + if(mTexture.notNull()) + { + mTexture->removeFace(this) ; + } if (mDrawPoolp) { mDrawPoolp->removeFace(this); @@ -217,7 +221,7 @@ void LLFace::setWorldMatrix(const LLMatrix4 &mat) llerrs << "Faces on this drawable are not independently modifiable\n" << llendl; } -void LLFace::setPool(LLFacePool* new_pool, LLViewerImage *texturep) +void LLFace::setPool(LLFacePool* new_pool, LLViewerTexture *texturep) { LLMemType mt1(LLMemType::MTYPE_DRAWABLE); @@ -247,9 +251,28 @@ void LLFace::setPool(LLFacePool* new_pool, LLViewerImage *texturep) } mDrawPoolp = new_pool; } - mTexture = texturep; + setTexture(texturep) ; } +void LLFace::setTexture(LLViewerTexture* tex) +{ + if(mTexture == tex) + { + return ; + } + + if(mTexture.notNull()) + { + mTexture->removeFace(this) ; + } + + mTexture = tex ; + + if(mTexture.notNull()) + { + mTexture->addFace(this) ; + } +} void LLFace::setTEOffset(const S32 te_offset) { @@ -422,7 +445,7 @@ void LLFace::renderForSelect(U32 data_mask) } } -void LLFace::renderSelected(LLImageGL *imagep, const LLColor4& color) +void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color) { if(mDrawablep.isNull() || mVertexBuffer.isNull() || mDrawablep->getSpatialGroup() == NULL || mDrawablep->getSpatialGroup()->isState(LLSpatialGroup::GEOM_DIRTY)) @@ -463,8 +486,8 @@ void LLFace::renderSelected(LLImageGL *imagep, const LLColor4& color) /* removed in lieu of raycast uv detection void LLFace::renderSelectedUV() { - LLViewerImage* red_blue_imagep = gImageList.getImageFromFile("uv_test1.j2c", TRUE, TRUE); - LLViewerImage* green_imagep = gImageList.getImageFromFile("uv_test2.tga", TRUE, TRUE); + LLViewerTexture* red_blue_imagep = LLViewerTextureManager::getFetchedTextureFromFile("uv_test1.j2c", TRUE, TRUE); + LLViewerTexture* green_imagep = LLViewerTextureManager::getFetchedTextureFromFile("uv_test2.tga", TRUE, TRUE); LLGLSUVSelect object_select; @@ -998,7 +1021,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, break; case BE_BRIGHTNESS: case BE_DARKNESS: - if( mTexture.notNull() && mTexture->getHasGLTexture()) + if( mTexture.notNull() && mTexture->hasValidGLTexture()) { // Offset by approximately one texel S32 cur_discard = mTexture->getDiscardLevel(); @@ -1150,6 +1173,21 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, BOOL LLFace::verify(const U32* indices_array) const { BOOL ok = TRUE; + + if( mVertexBuffer.isNull() ) + { + if( mGeomCount ) + { + // This happens before teleports as faces are torn down. + // Stop the crash in DEV-31893 with a null pointer check, + // but present this info. + // To clean up the log, the geometry could be cleared, or the + // face could otherwise be marked for no ::verify. + llinfos << "Face with no vertex buffer and " << mGeomCount << " mGeomCount" << llendl; + } + return TRUE; + } + // First, check whether the face data fits within the pool's range. if ((mGeomIndex + mGeomCount) > mVertexBuffer->getNumVerts()) { diff --git a/indra/newview/llface.h b/indra/newview/llface.h index 8332eec19c..e0728fe15e 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -45,15 +45,15 @@ #include "xform.h" #include "lldarrayptr.h" #include "llvertexbuffer.h" -#include "llviewerimage.h" +#include "llviewertexture.h" #include "lldrawable.h" class LLFacePool; class LLVolume; -class LLViewerImage; +class LLViewerTexture; class LLTextureEntry; class LLVertexProgram; -class LLViewerImage; +class LLViewerTexture; class LLGeometryManager; const F32 MIN_ALPHA_SIZE = 1024.f; @@ -86,8 +86,8 @@ public: U16 getGeomCount() const { return mGeomCount; } // vertex count for this face U16 getGeomIndex() const { return mGeomIndex; } // index into draw pool U16 getGeomStart() const { return mGeomIndex; } // index into draw pool - LLViewerImage* getTexture() const { return mTexture; } - void setTexture(LLViewerImage* tex) { mTexture = tex; } + LLViewerTexture* getTexture() const { return mTexture; } + void setTexture(LLViewerTexture* tex) ; LLXformMatrix* getXform() const { return mXform; } BOOL hasGeometry() const { return mGeomCount > 0; } LLVector3 getPositionAgent() const; @@ -119,10 +119,10 @@ public: LLVertexBuffer* getVertexBuffer() const { return mVertexBuffer; } void setPoolType(U32 type) { mPoolType = type; } S32 getTEOffset() { return mTEOffset; } - LLViewerImage* getTexture() { return mTexture; } + LLViewerTexture* getTexture() { return mTexture; } void setViewerObject(LLViewerObject* object); - void setPool(LLFacePool *pool, LLViewerImage *texturep); + void setPool(LLFacePool *pool, LLViewerTexture *texturep); void setDrawable(LLDrawable *drawable); void setTEOffset(const S32 te_offset); @@ -171,7 +171,7 @@ public: void renderSelectedUV(); void renderForSelect(U32 data_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); - void renderSelected(LLImageGL *image, const LLColor4 &color); + void renderSelected(LLViewerTexture *image, const LLColor4 &color); F32 getKey() const { return mDistance; } @@ -222,7 +222,7 @@ protected: U32 mLastIndicesIndex; LLXformMatrix* mXform; - LLPointer mTexture; + LLPointer mTexture; LLPointer mDrawablep; LLPointer mVObjp; S32 mTEOffset; diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index b373dd2241..f22114d3c8 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -44,7 +44,7 @@ #include "llsdserialize.h" #include "llappviewer.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llui.h" #include "llviewercontrol.h" #include "llstat.h" diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index b8e2840fe6..2a8365b3f0 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -47,7 +47,7 @@ #include "llviewercontrol.h" #include "llworld.h" #include "lldrawpoolterrain.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llwindow.h" #include "llui.h" #include "llcontrol.h" diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp index 8f2c6d538b..bafb69a835 100644 --- a/indra/newview/llflexibleobject.cpp +++ b/indra/newview/llflexibleobject.cpp @@ -39,11 +39,10 @@ #include "llglheaders.h" #include "llrendersphere.h" #include "llviewerobject.h" -#include "llimagegl.h" #include "llagent.h" #include "llsky.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewercontrol.h" #include "llviewerobjectlist.h" #include "llviewerregion.h" diff --git a/indra/newview/llfloateranimpreview.cpp b/indra/newview/llfloateranimpreview.cpp index 12c4932293..a1d9fed567 100644 --- a/indra/newview/llfloateranimpreview.cpp +++ b/indra/newview/llfloateranimpreview.cpp @@ -325,7 +325,6 @@ BOOL LLFloaterAnimPreview::postBuild() } else { - delete mAnimPreview; mAnimPreview = NULL; mMotionID.setNull(); childSetValue("bad_animation_text", getString("failed_to_initialize")); @@ -367,7 +366,6 @@ BOOL LLFloaterAnimPreview::postBuild() //----------------------------------------------------------------------------- LLFloaterAnimPreview::~LLFloaterAnimPreview() { - delete mAnimPreview; mAnimPreview = NULL; setEnabled(FALSE); @@ -387,7 +385,7 @@ void LLFloaterAnimPreview::draw() { gGL.color3f(1.f, 1.f, 1.f); - gGL.getTexUnit(0)->bind(mAnimPreview->getTexture()); + gGL.getTexUnit(0)->bind(mAnimPreview); gGL.begin( LLRender::QUADS ); { @@ -1017,7 +1015,7 @@ void LLFloaterAnimPreview::onBtnOK(void* userdata) //----------------------------------------------------------------------------- // LLPreviewAnimation //----------------------------------------------------------------------------- -LLPreviewAnimation::LLPreviewAnimation(S32 width, S32 height) : LLDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE) +LLPreviewAnimation::LLPreviewAnimation(S32 width, S32 height) : LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE) { mNeedsUpdate = TRUE; mCameraDistance = PREVIEW_CAMERA_DISTANCE; @@ -1063,7 +1061,7 @@ BOOL LLPreviewAnimation::render() glMatrixMode(GL_PROJECTION); gGL.pushMatrix(); glLoadIdentity(); - glOrtho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f); + glOrtho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f); glMatrixMode(GL_MODELVIEW); gGL.pushMatrix(); @@ -1073,7 +1071,7 @@ BOOL LLPreviewAnimation::render() gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.color4f(0.15f, 0.2f, 0.3f, 1.f); - gl_rect_2d_simple( mWidth, mHeight ); + gl_rect_2d_simple( mFullWidth, mFullHeight ); glMatrixMode(GL_PROJECTION); gGL.popMatrix(); @@ -1095,7 +1093,7 @@ BOOL LLPreviewAnimation::render() target_pos + (mCameraOffset * av_rot) ); // point of interest LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom); - LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mWidth, mHeight, FALSE); + LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE); mCameraRelPos = LLViewerCamera::getInstance()->getOrigin() - avatarp->mHeadp->getWorldPosition(); diff --git a/indra/newview/llfloateranimpreview.h b/indra/newview/llfloateranimpreview.h index 2f228c3ecd..7031e9a716 100644 --- a/indra/newview/llfloateranimpreview.h +++ b/indra/newview/llfloateranimpreview.h @@ -41,12 +41,14 @@ class LLVOAvatar; class LLViewerJointMesh; -class LLPreviewAnimation : public LLDynamicTexture +class LLPreviewAnimation : public LLViewerDynamicTexture { -public: - LLPreviewAnimation(S32 width, S32 height); +protected: virtual ~LLPreviewAnimation(); +public: + LLPreviewAnimation(S32 width, S32 height); + BOOL render(); void requestUpdate(); void rotate(F32 yaw_radians, F32 pitch_radians); @@ -114,7 +116,7 @@ protected: void draw(); void resetMotion(); - LLPreviewAnimation* mAnimPreview; + LLPointer< LLPreviewAnimation > mAnimPreview; S32 mLastMouseX; S32 mLastMouseY; LLButton* mPlayButton; diff --git a/indra/newview/llfloaterauction.cpp b/indra/newview/llfloaterauction.cpp index f5d950a9a5..da2a4d9d93 100644 --- a/indra/newview/llfloaterauction.cpp +++ b/indra/newview/llfloaterauction.cpp @@ -47,7 +47,7 @@ #include "llcombobox.h" #include "llnotify.h" #include "llsavedsettingsglue.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerparcelmgr.h" #include "llviewerregion.h" #include "lluictrlfactory.h" @@ -186,7 +186,7 @@ void LLFloaterAuction::onClickSnapshot(void* data) tga->encode(raw); LLVFile::writeFile(tga->getData(), tga->getDataSize(), gVFS, self->mImageID, LLAssetType::AT_IMAGE_TGA); - raw->biasedScaleToPowerOfTwo(LLViewerImage::MAX_IMAGE_SIZE_DEFAULT); + raw->biasedScaleToPowerOfTwo(LLViewerTexture::MAX_IMAGE_SIZE_DEFAULT); llinfos << "Writing J2C..." << llendl; @@ -194,7 +194,7 @@ void LLFloaterAuction::onClickSnapshot(void* data) j2c->encode(raw, 0.0f); LLVFile::writeFile(j2c->getData(), j2c->getDataSize(), gVFS, self->mImageID, LLAssetType::AT_TEXTURE); - self->mImage = new LLImageGL((LLImageRaw*)raw, FALSE); + self->mImage = LLViewerTextureManager::getLocalTexture((LLImageRaw*)raw, FALSE); gGL.getTexUnit(0)->bind(self->mImage); self->mImage->setAddressMode(LLTexUnit::TAM_CLAMP); } diff --git a/indra/newview/llfloaterauction.h b/indra/newview/llfloaterauction.h index ebb1a0d1ae..86de0ae966 100644 --- a/indra/newview/llfloaterauction.h +++ b/indra/newview/llfloaterauction.h @@ -37,7 +37,7 @@ #include "llfloater.h" #include "lluuid.h" #include "llpointer.h" -#include "llviewerimage.h" +#include "llviewertexture.h" //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLFloaterAuction @@ -69,7 +69,7 @@ private: private: LLTransactionID mTransactionID; LLAssetID mImageID; - LLPointer mImage; + LLPointer mImage; LLSafeHandle mParcelp; S32 mParcelID; LLHost mParcelHost; diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp index edc96715cd..c140518759 100644 --- a/indra/newview/llfloatercolorpicker.cpp +++ b/indra/newview/llfloatercolorpicker.cpp @@ -56,7 +56,6 @@ #include "llpointer.h" #include "llimage.h" #include "llmousehandler.h" -#include "llimagegl.h" #include "llglheaders.h" #include "llcheckboxctrl.h" #include "lltextbox.h" @@ -161,7 +160,7 @@ void LLFloaterColorPicker::createUI () * ( bits + x + y * linesize + 2 ) = ( U8 )( bVal * 255.0f ); } } - mRGBImage = new LLImageGL ( (LLImageRaw*)raw, FALSE ); + mRGBImage = LLViewerTextureManager::getLocalTexture( (LLImageRaw*)raw, FALSE ); gGL.getTexUnit(0)->bind(mRGBImage); mRGBImage->setAddressMode(LLTexUnit::TAM_CLAMP); diff --git a/indra/newview/llfloatercolorpicker.h b/indra/newview/llfloatercolorpicker.h index 16f456b5bf..a16cde7f10 100644 --- a/indra/newview/llfloatercolorpicker.h +++ b/indra/newview/llfloatercolorpicker.h @@ -175,7 +175,7 @@ class LLFloaterColorPicker const S32 mPaletteRegionHeight; // image used to compose color grid - LLPointer mRGBImage; + LLPointer mRGBImage; // current swatch in use LLColorSwatchCtrl* mSwatch; diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp index 9999b58e5b..5a4de579c2 100644 --- a/indra/newview/llfloatergesture.cpp +++ b/indra/newview/llfloatergesture.cpp @@ -56,7 +56,7 @@ #include "lltrans.h" #include "lluictrlfactory.h" #include "llviewergesture.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerinventory.h" #include "llvoavatar.h" #include "llviewercontrol.h" diff --git a/indra/newview/llfloaterhardwaresettings.cpp b/indra/newview/llfloaterhardwaresettings.cpp index 38915ebff9..ef1d43f2f6 100644 --- a/indra/newview/llfloaterhardwaresettings.cpp +++ b/indra/newview/llfloaterhardwaresettings.cpp @@ -38,7 +38,7 @@ #include "llfloaterpreference.h" #include "llviewerwindow.h" #include "llviewercontrol.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llfeaturemanager.h" #include "llstartup.h" #include "pipeline.h" @@ -47,7 +47,6 @@ #include "llradiogroup.h" #include "lluictrlfactory.h" #include "llwindow.h" -#include "llimagegl.h" LLFloaterHardwareSettings* LLFloaterHardwareSettings::sHardwareSettings = NULL; @@ -91,8 +90,8 @@ void LLFloaterHardwareSettings::refresh() void LLFloaterHardwareSettings::refreshEnabledState() { - S32 min_tex_mem = LLViewerImageList::getMinVideoRamSetting(); - S32 max_tex_mem = LLViewerImageList::getMaxVideoRamSetting(); + S32 min_tex_mem = LLViewerTextureList::getMinVideoRamSetting(); + S32 max_tex_mem = LLViewerTextureList::getMaxVideoRamSetting(); childSetMinValue("GrapicsCardTextureMemory", min_tex_mem); childSetMaxValue("GrapicsCardTextureMemory", max_tex_mem); diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index faa4f0ec99..26b969224e 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -56,7 +56,7 @@ #include "llvoavatar.h" #include "pipeline.h" #include "lluictrlfactory.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llstring.h" //static @@ -142,9 +142,6 @@ LLFloaterImagePreview::~LLFloaterImagePreview() clearAllPreviewTextures(); mRawImagep = NULL; - delete mAvatarPreview; - delete mSculptedPreview; - mImagep = NULL ; } @@ -252,7 +249,7 @@ void LLFloaterImagePreview::draw() } else { - mImagep = new LLImageGL(mRawImagep, FALSE) ; + mImagep = LLViewerTextureManager::getLocalTexture(mRawImagep.get(), FALSE) ; gGL.getTexUnit(0)->unbind(mImagep->getTarget()) ; gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mImagep->getTexName()); @@ -294,11 +291,11 @@ void LLFloaterImagePreview::draw() if (selected == 9) { - gGL.getTexUnit(0)->bind(mSculptedPreview->getTexture()); + gGL.getTexUnit(0)->bind(mSculptedPreview); } else { - gGL.getTexUnit(0)->bind(mAvatarPreview->getTexture()); + gGL.getTexUnit(0)->bind(mAvatarPreview); } gGL.begin( LLRender::QUADS ); @@ -606,7 +603,7 @@ void LLFloaterImagePreview::onMouseCaptureLostImagePreview(LLMouseHandler* handl //----------------------------------------------------------------------------- // LLImagePreviewAvatar //----------------------------------------------------------------------------- -LLImagePreviewAvatar::LLImagePreviewAvatar(S32 width, S32 height) : LLDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE) +LLImagePreviewAvatar::LLImagePreviewAvatar(S32 width, S32 height) : LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE) { mNeedsUpdate = TRUE; mTargetJoint = NULL; @@ -697,7 +694,7 @@ BOOL LLImagePreviewAvatar::render() glMatrixMode(GL_PROJECTION); gGL.pushMatrix(); glLoadIdentity(); - glOrtho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f); + glOrtho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f); glMatrixMode(GL_MODELVIEW); gGL.pushMatrix(); @@ -706,7 +703,7 @@ BOOL LLImagePreviewAvatar::render() LLGLSUIDefault def; gGL.color4f(0.15f, 0.2f, 0.3f, 1.f); - gl_rect_2d_simple( mWidth, mHeight ); + gl_rect_2d_simple( mFullWidth, mFullHeight ); glMatrixMode(GL_PROJECTION); gGL.popMatrix(); @@ -728,9 +725,9 @@ BOOL LLImagePreviewAvatar::render() stop_glerror(); - LLViewerCamera::getInstance()->setAspect((F32)mWidth / mHeight); + LLViewerCamera::getInstance()->setAspect((F32)mFullWidth / mFullHeight); LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom); - LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mWidth, mHeight, FALSE); + LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE); LLVertexBuffer::unbind(); avatarp->updateLOD(); @@ -788,7 +785,7 @@ void LLImagePreviewAvatar::pan(F32 right, F32 up) // LLImagePreviewSculpted //----------------------------------------------------------------------------- -LLImagePreviewSculpted::LLImagePreviewSculpted(S32 width, S32 height) : LLDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE) +LLImagePreviewSculpted::LLImagePreviewSculpted(S32 width, S32 height) : LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE) { mNeedsUpdate = TRUE; mCameraDistance = 0.f; @@ -871,7 +868,7 @@ BOOL LLImagePreviewSculpted::render() glMatrixMode(GL_PROJECTION); gGL.pushMatrix(); glLoadIdentity(); - glOrtho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f); + glOrtho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f); glMatrixMode(GL_MODELVIEW); gGL.pushMatrix(); @@ -879,7 +876,7 @@ BOOL LLImagePreviewSculpted::render() gGL.color4f(0.15f, 0.2f, 0.3f, 1.f); - gl_rect_2d_simple( mWidth, mHeight ); + gl_rect_2d_simple( mFullWidth, mFullHeight ); glMatrixMode(GL_PROJECTION); gGL.popMatrix(); @@ -902,9 +899,9 @@ BOOL LLImagePreviewSculpted::render() stop_glerror(); - LLViewerCamera::getInstance()->setAspect((F32) mWidth / mHeight); + LLViewerCamera::getInstance()->setAspect((F32) mFullWidth / mFullHeight); LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom); - LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mWidth, mHeight, FALSE); + LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE); const LLVolumeFace &vf = mVolume->getVolumeFace(0); U32 num_indices = vf.mIndices.size(); diff --git a/indra/newview/llfloaterimagepreview.h b/indra/newview/llfloaterimagepreview.h index 6a4de3d3cc..e2781b8231 100644 --- a/indra/newview/llfloaterimagepreview.h +++ b/indra/newview/llfloaterimagepreview.h @@ -44,12 +44,14 @@ class LLVOAvatar; class LLTextBox; class LLVertexBuffer; -class LLImagePreviewSculpted : public LLDynamicTexture +class LLImagePreviewSculpted : public LLViewerDynamicTexture { - public: - LLImagePreviewSculpted(S32 width, S32 height); +protected: virtual ~LLImagePreviewSculpted(); + public: + LLImagePreviewSculpted(S32 width, S32 height); + void setPreviewTarget(LLImageRaw *imagep, F32 distance); void setTexture(U32 name) { mTextureName = name; } @@ -73,12 +75,14 @@ class LLImagePreviewSculpted : public LLDynamicTexture }; -class LLImagePreviewAvatar : public LLDynamicTexture +class LLImagePreviewAvatar : public LLViewerDynamicTexture { -public: - LLImagePreviewAvatar(S32 width, S32 height); +protected: virtual ~LLImagePreviewAvatar(); +public: + LLImagePreviewAvatar(S32 width, S32 height); + void setPreviewTarget(const std::string& joint_name, const std::string& mesh_name, LLImageRaw* imagep, F32 distance, BOOL male); void setTexture(U32 name) { mTextureName = name; } void clearPreviewTexture(const std::string& mesh_name); @@ -127,13 +131,13 @@ protected: bool loadImage(const std::string& filename); LLPointer mRawImagep; - LLImagePreviewAvatar* mAvatarPreview; - LLImagePreviewSculpted* mSculptedPreview; + LLPointer mAvatarPreview; + LLPointer mSculptedPreview; S32 mLastMouseX; S32 mLastMouseY; LLRect mPreviewRect; LLRectf mPreviewImageRect; - LLPointer mImagep ; + LLPointer mImagep ; static S32 sUploadAmount; }; diff --git a/indra/newview/llfloaterinventory.cpp b/indra/newview/llfloaterinventory.cpp index 0dd1d6adcd..634126202f 100644 --- a/indra/newview/llfloaterinventory.cpp +++ b/indra/newview/llfloaterinventory.cpp @@ -77,7 +77,6 @@ #include "lltabcontainer.h" #include "lltooldraganddrop.h" #include "lluictrlfactory.h" -#include "llviewerimagelist.h" #include "llviewerinventory.h" #include "llviewermessage.h" #include "llviewerobjectlist.h" diff --git a/indra/newview/llfloaterlagmeter.cpp b/indra/newview/llfloaterlagmeter.cpp index 262102b820..da6dceb149 100644 --- a/indra/newview/llfloaterlagmeter.cpp +++ b/indra/newview/llfloaterlagmeter.cpp @@ -36,7 +36,7 @@ #include "lluictrlfactory.h" #include "llviewerstats.h" -#include "llviewerimage.h" +#include "llviewertexture.h" #include "llviewercontrol.h" #include "llappviewer.h" @@ -185,7 +185,7 @@ void LLFloaterLagMeter::determineClient() { mClientCause->setText( getString("client_texture_loading_cause_msg", mStringArgs) ); } - else if((BYTES_TO_MEGA_BYTES(LLViewerImage::sBoundTextureMemoryInBytes)) > LLViewerImage::sMaxBoundTextureMemInMegaBytes) + else if((BYTES_TO_MEGA_BYTES(LLViewerTexture::sBoundTextureMemoryInBytes)) > LLViewerTexture::sMaxBoundTextureMemInMegaBytes) { mClientCause->setText( getString("client_texture_memory_cause_msg", mStringArgs) ); } diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 039873691d..f7e5eaadd3 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -68,7 +68,7 @@ #include "lltexturectrl.h" #include "lluiconstants.h" #include "lluictrlfactory.h" -#include "llviewerimagelist.h" // LLUIImageList +#include "llviewertexturelist.h" // LLUIImageList #include "llviewermessage.h" #include "llviewerparcelmgr.h" #include "llviewerregion.h" diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h index ee49da3f05..c04eae2c68 100644 --- a/indra/newview/llfloaterland.h +++ b/indra/newview/llfloaterland.h @@ -39,6 +39,7 @@ #include "llfloater.h" #include "llpointer.h" // LLPointer<> +//#include "llviewertexturelist.h" #include "llsafehandle.h" typedef std::set uuid_list_t; diff --git a/indra/newview/llfloaterpostcard.cpp b/indra/newview/llfloaterpostcard.cpp index 4a68e3092e..696531c208 100644 --- a/indra/newview/llfloaterpostcard.cpp +++ b/indra/newview/llfloaterpostcard.cpp @@ -61,7 +61,7 @@ #include "llimagej2c.h" #include "llvfile.h" #include "llvfs.h" - +#include "llviewertexture.h" #include "llassetuploadresponders.h" #include //boost.regex lib @@ -77,7 +77,7 @@ LLFloaterPostcard::instance_list_t LLFloaterPostcard::sInstances; /// Class LLFloaterPostcard ///---------------------------------------------------------------------------- -LLFloaterPostcard::LLFloaterPostcard(LLImageJPEG* jpeg, LLImageGL *img, const LLVector2& img_scale, const LLVector3d& pos_taken_global) +LLFloaterPostcard::LLFloaterPostcard(LLImageJPEG* jpeg, LLViewerTexture *img, const LLVector2& img_scale, const LLVector3d& pos_taken_global) : LLFloater(), mJPEGImage(jpeg), mViewerImage(img), @@ -130,7 +130,7 @@ BOOL LLFloaterPostcard::postBuild() // static -LLFloaterPostcard* LLFloaterPostcard::showFromSnapshot(LLImageJPEG *jpeg, LLImageGL *img, const LLVector2 &image_scale, const LLVector3d& pos_taken_global) +LLFloaterPostcard* LLFloaterPostcard::showFromSnapshot(LLImageJPEG *jpeg, LLViewerTexture *img, const LLVector2 &image_scale, const LLVector3d& pos_taken_global) { // Take the images from the caller // It's now our job to clean them up @@ -181,7 +181,7 @@ void LLFloaterPostcard::draw() rect.mBottom, rect.getWidth(), rect.getHeight(), - mViewerImage, + mViewerImage.get(), LLColor4::white); } glMatrixMode(GL_TEXTURE); diff --git a/indra/newview/llfloaterpostcard.h b/indra/newview/llfloaterpostcard.h index 5abb97e15f..98910f85f9 100644 --- a/indra/newview/llfloaterpostcard.h +++ b/indra/newview/llfloaterpostcard.h @@ -41,20 +41,20 @@ class LLTextEditor; class LLLineEditor; class LLButton; -class LLImageGL; +class LLViewerTexture; class LLImageJPEG; class LLFloaterPostcard : public LLFloater { public: - LLFloaterPostcard(LLImageJPEG* jpeg, LLImageGL *img, const LLVector2& img_scale, const LLVector3d& pos_taken_global); + LLFloaterPostcard(LLImageJPEG* jpeg, LLViewerTexture *img, const LLVector2& img_scale, const LLVector3d& pos_taken_global); virtual ~LLFloaterPostcard(); virtual BOOL postBuild(); virtual void draw(); - static LLFloaterPostcard* showFromSnapshot(LLImageJPEG *jpeg, LLImageGL *img, const LLVector2& img_scale, const LLVector3d& pos_taken_global); + static LLFloaterPostcard* showFromSnapshot(LLImageJPEG *jpeg, LLViewerTexture *img, const LLVector2& img_scale, const LLVector3d& pos_taken_global); static void onClickCancel(void* data); static void onClickSend(void* data); @@ -73,7 +73,7 @@ public: protected: LLPointer mJPEGImage; - LLPointer mViewerImage; + LLPointer mViewerImage; LLTransactionID mTransactionID; LLAssetID mAssetID; LLVector2 mImageScale; diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 53b88d9f57..f6a50057bc 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -91,13 +91,8 @@ #include "llspinctrl.h" #include "llstartup.h" #include "lltextbox.h" - #include "llui.h" - -#include "llviewerimage.h" -#include "llviewerimagelist.h" #include "llviewerobjectlist.h" - #include "llvoavatar.h" #include "llvovolume.h" #include "llwindow.h" diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 99c1414461..009902b453 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -76,8 +76,8 @@ #include "llviewercontrol.h" #include "lluictrlfactory.h" #include "llviewerinventory.h" -#include "llviewerimage.h" -#include "llviewerimagelist.h" +#include "llviewertexture.h" +#include "llviewertexturelist.h" #include "llviewerregion.h" #include "llviewerstats.h" #include "llviewertexteditor.h" @@ -1144,11 +1144,11 @@ BOOL LLPanelRegionTextureInfo::validateTextureSizes() if (!texture_ctrl) continue; LLUUID image_asset_id = texture_ctrl->getImageAssetID(); - LLViewerImage* img = gImageList.getImage(image_asset_id); + LLViewerTexture* img = LLViewerTextureManager::getFetchedTexture(image_asset_id); S32 components = img->getComponents(); // Must ask for highest resolution version's width. JC - S32 width = img->getWidth(0); - S32 height = img->getHeight(0); + S32 width = img->getFullWidth(); + S32 height = img->getFullHeight(); //llinfos << "texture detail " << i << " is " << width << "x" << height << "x" << components << llendl; diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp index 513a6a06b1..8c96734057 100644 --- a/indra/newview/llfloaterreporter.cpp +++ b/indra/newview/llfloaterreporter.cpp @@ -73,7 +73,7 @@ #include "lltoolmgr.h" #include "llresourcedata.h" // for LLResourceData #include "llviewerwindow.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llworldmap.h" #include "llfilepicker.h" #include "llfloateravatarpicker.h" @@ -825,7 +825,7 @@ void LLFloaterReporter::takeScreenshot() llwarns << "Unable to take screenshot" << llendl; return; } - LLPointer upload_data = LLViewerImageList::convertToUploadFile(raw); + LLPointer upload_data = LLViewerTextureList::convertToUploadFile(raw); // create a resource data mResourceDatap->mInventoryType = LLInventoryType::IT_NONE; @@ -855,10 +855,10 @@ void LLFloaterReporter::takeScreenshot() mResourceDatap->mAssetInfo.mType); // store in the image list so it doesn't try to fetch from the server - LLPointer image_in_list = new LLViewerImage(mResourceDatap->mAssetInfo.mUuid, TRUE); + LLPointer image_in_list = + LLViewerTextureManager::getFetchedTexture(mResourceDatap->mAssetInfo.mUuid, TRUE, FALSE, LLViewerTexture::FETCHED_TEXTURE); image_in_list->createGLTexture(0, raw); - gImageList.addImage(image_in_list); - + // the texture picker then uses that texture LLTexturePicker* texture = getChild("screenshot"); if (texture) diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h index da1dda9c78..52bea736bf 100644 --- a/indra/newview/llfloaterreporter.h +++ b/indra/newview/llfloaterreporter.h @@ -39,7 +39,7 @@ #include "v3math.h" class LLMessageSystem; -class LLViewerImage; +class LLViewerTexture; class LLInventoryItem; class LLViewerObject; class LLAgent; diff --git a/indra/newview/llfloaterscriptdebug.cpp b/indra/newview/llfloaterscriptdebug.cpp index b2bb343681..6cca4927a9 100644 --- a/indra/newview/llfloaterscriptdebug.cpp +++ b/indra/newview/llfloaterscriptdebug.cpp @@ -45,7 +45,7 @@ #include "llviewertexteditor.h" #include "llviewercontrol.h" #include "llviewerobjectlist.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" // // Statics @@ -131,7 +131,7 @@ void LLFloaterScriptDebug::addScriptLine(const std::string &utf8mesg, const std: if (objectp) { - objectp->setIcon(gImageList.getImageFromFile("script_error.j2c", TRUE, TRUE)); + objectp->setIcon(LLViewerTextureManager::getFetchedTextureFromFile("script_error.j2c", TRUE, TRUE)); floater_label = llformat("%s(%.2f, %.2f)", user_name.c_str(), objectp->getPositionRegion().mV[VX], objectp->getPositionRegion().mV[VY]); } else diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index fef0474062..38d8420c96 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -140,12 +140,12 @@ public: LLFloaterSnapshot::ESnapshotFormat getSnapshotFormat() const { return mSnapshotFormat; } BOOL getSnapshotUpToDate() const { return mSnapshotUpToDate; } BOOL isSnapshotActive() { return mSnapshotActive; } - LLImageGL* getThumbnailImage() const { return mThumbnailImage ; } + LLViewerTexture* getThumbnailImage() const { return mThumbnailImage ; } S32 getThumbnailWidth() const { return mThumbnailWidth ; } S32 getThumbnailHeight() const { return mThumbnailHeight ; } BOOL getThumbnailLock() const { return mThumbnailUpdateLock ; } BOOL getThumbnailUpToDate() const { return mThumbnailUpToDate ;} - LLImageGL* getCurrentImage(); + LLViewerTexture* getCurrentImage(); F32 getImageAspect(); F32 getAspect() ; LLRect getImageRect(); @@ -170,7 +170,7 @@ public: private: LLColor4 mColor; - LLPointer mViewerImage[2]; //used to represent the scene when the frame is frozen. + LLPointer mViewerImage[2]; //used to represent the scene when the frame is frozen. LLRect mImageRect[2]; S32 mWidth[2]; S32 mHeight[2]; @@ -178,7 +178,7 @@ private: S32 mMaxImageSize ; //thumbnail image - LLPointer mThumbnailImage ; + LLPointer mThumbnailImage ; S32 mThumbnailWidth ; S32 mThumbnailHeight ; LLRect mPreviewRect ; @@ -278,7 +278,7 @@ void LLSnapshotLivePreview::setMaxImageSize(S32 size) } } -LLImageGL* LLSnapshotLivePreview::getCurrentImage() +LLViewerTexture* LLSnapshotLivePreview::getCurrentImage() { return mViewerImage[mCurImageIndex]; } @@ -723,7 +723,7 @@ void LLSnapshotLivePreview::generateThumbnailImage(BOOL force_update) if(raw) { - mThumbnailImage = new LLImageGL(raw, FALSE); + mThumbnailImage = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE); mThumbnailUpToDate = TRUE ; } @@ -871,8 +871,8 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview ) scaled->expandToPowerOfTwo(1024, FALSE); } - previewp->mViewerImage[previewp->mCurImageIndex] = new LLImageGL(scaled, FALSE); - LLPointer curr_preview_image = previewp->mViewerImage[previewp->mCurImageIndex]; + previewp->mViewerImage[previewp->mCurImageIndex] = LLViewerTextureManager::getLocalTexture(scaled.get(), FALSE); + LLPointer curr_preview_image = previewp->mViewerImage[previewp->mCurImageIndex]; gGL.getTexUnit(0)->bind(curr_preview_image); if (previewp->getSnapshotType() != SNAPSHOT_TEXTURE) { diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index d0a82f283c..6ef011f1de 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -47,8 +47,8 @@ #include "lltooldraganddrop.h" #include "lltrans.h" #include "llui.h" -#include "llviewerimage.h" -#include "llviewerimagelist.h" +#include "llviewertexture.h" +#include "llviewertexturelist.h" #include "llviewerjointattachment.h" #include "llviewermenu.h" #include "lluictrlfactory.h" diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h index e8f0c4130e..d944a4fa18 100644 --- a/indra/newview/llfolderview.h +++ b/indra/newview/llfolderview.h @@ -55,7 +55,7 @@ #include "stdenums.h" #include "llfontgl.h" #include "lleditmenuhandler.h" -#include "llviewerimage.h" +#include "llviewertexture.h" #include "lldepthstack.h" #include "lltooldraganddrop.h" // JAMESDEBUG - move this up diff --git a/indra/newview/llhudeffect.cpp b/indra/newview/llhudeffect.cpp index c1d46f98d4..bfd62805a1 100644 --- a/indra/newview/llhudeffect.cpp +++ b/indra/newview/llhudeffect.cpp @@ -38,7 +38,6 @@ #include "llgl.h" #include "llagent.h" #include "llrendersphere.h" -#include "llimagegl.h" #include "llviewerobjectlist.h" #include "lldrawable.h" diff --git a/indra/newview/llhudeffectbeam.cpp b/indra/newview/llhudeffectbeam.cpp index 6cb3bef751..43a8dd1d81 100644 --- a/indra/newview/llhudeffectbeam.cpp +++ b/indra/newview/llhudeffectbeam.cpp @@ -43,7 +43,6 @@ #include "llgl.h" #include "llglheaders.h" #include "llhudrender.h" -#include "llimagegl.h" #include "llrendersphere.h" #include "llviewercamera.h" #include "llvoavatar.h" diff --git a/indra/newview/llhudeffecttrail.cpp b/indra/newview/llhudeffecttrail.cpp index 0ade6810ba..786491211d 100644 --- a/indra/newview/llhudeffecttrail.cpp +++ b/indra/newview/llhudeffecttrail.cpp @@ -35,14 +35,13 @@ #include "llhudeffecttrail.h" #include "llviewercontrol.h" -#include "llimagegl.h" #include "message.h" #include "llagent.h" #include "llbox.h" #include "lldrawable.h" #include "llhudrender.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerobjectlist.h" #include "llviewerpartsim.h" #include "llviewerpartsource.h" diff --git a/indra/newview/llhudicon.cpp b/indra/newview/llhudicon.cpp index 3535fe185c..eda1d3fc55 100644 --- a/indra/newview/llhudicon.cpp +++ b/indra/newview/llhudicon.cpp @@ -40,7 +40,7 @@ #include "llviewerobject.h" #include "lldrawable.h" #include "llviewercamera.h" -#include "llviewerimage.h" +#include "llviewertexture.h" #include "llviewerwindow.h" //----------------------------------------------------------------------------- @@ -144,7 +144,7 @@ void LLHUDIcon::renderIcon(BOOL for_select) alpha_factor *= clamp_rescale(time_elapsed, MAX_VISIBLE_TIME - FADE_OUT_TIME, MAX_VISIBLE_TIME, 1.f, 0.f); } - F32 image_aspect = (F32)mImagep->mFullWidth / (F32)mImagep->mFullHeight; + F32 image_aspect = (F32)mImagep->getFullWidth() / (F32)mImagep->getFullHeight() ; LLVector3 x_scale = image_aspect * (F32)gViewerWindow->getWindowHeight() * mScale * scale_factor * x_pixel_vec; LLVector3 y_scale = (F32)gViewerWindow->getWindowHeight() * mScale * scale_factor * y_pixel_vec; @@ -164,7 +164,7 @@ void LLHUDIcon::renderIcon(BOOL for_select) LLColor4 icon_color = LLColor4::white; icon_color.mV[VALPHA] = alpha_factor; gGL.color4fv(icon_color.mV); - gGL.getTexUnit(0)->bind(mImagep.get()); + gGL.getTexUnit(0)->bind(mImagep); } gGL.begin(LLRender::QUADS); @@ -181,7 +181,7 @@ void LLHUDIcon::renderIcon(BOOL for_select) gGL.end(); } -void LLHUDIcon::setImage(LLViewerImage* imagep) +void LLHUDIcon::setImage(LLViewerTexture* imagep) { mImagep = imagep; mImagep->setAddressMode(LLTexUnit::TAM_CLAMP); @@ -260,7 +260,7 @@ BOOL LLHUDIcon::lineSegmentIntersect(const LLVector3& start, const LLVector3& en return FALSE; } - F32 image_aspect = (F32)mImagep->mFullWidth / (F32)mImagep->mFullHeight; + F32 image_aspect = (F32)mImagep->getFullWidth() / (F32)mImagep->getFullHeight() ; LLVector3 x_scale = image_aspect * (F32)gViewerWindow->getWindowHeight() * mScale * scale_factor * x_pixel_vec; LLVector3 y_scale = (F32)gViewerWindow->getWindowHeight() * mScale * scale_factor * y_pixel_vec; diff --git a/indra/newview/llhudicon.h b/indra/newview/llhudicon.h index 2c1c549521..770e3bbcd0 100644 --- a/indra/newview/llhudicon.h +++ b/indra/newview/llhudicon.h @@ -61,7 +61,7 @@ public: /*virtual*/ void markDead(); /*virtual*/ F32 getDistance() const { return mDistance; } - void setImage(LLViewerImage* imagep); + void setImage(LLViewerTexture* imagep); void setScale(F32 fraction_of_fov); void restartLifeTimer() { mLifeTimer.reset(); } @@ -88,7 +88,7 @@ protected: void renderIcon(BOOL for_select); // common render code private: - LLPointer mImagep; + LLPointer mImagep; LLFrameTimer mAnimTimer; LLFrameTimer mLifeTimer; F32 mDistance; diff --git a/indra/newview/llhudrender.cpp b/indra/newview/llhudrender.cpp index fe65a12c47..4c8c1b5f7f 100644 --- a/indra/newview/llhudrender.cpp +++ b/indra/newview/llhudrender.cpp @@ -40,7 +40,6 @@ #include "v3math.h" #include "llquaternion.h" #include "llfontgl.h" -#include "llimagegl.h" #include "llglheaders.h" #include "llviewerwindow.h" diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp index abb3acd974..953d99c7ac 100644 --- a/indra/newview/llhudtext.cpp +++ b/indra/newview/llhudtext.cpp @@ -45,10 +45,9 @@ #include "llfontgl.h" #include "llglheaders.h" #include "llhudrender.h" -#include "llimagegl.h" #include "llui.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerobject.h" #include "llvovolume.h" #include "llviewerwindow.h" diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 9d1b24ae11..d4c40689ce 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -75,7 +75,7 @@ #include "llscrollcontainer.h" #include "llimview.h" #include "lltooldraganddrop.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerinventory.h" #include "llviewerobjectlist.h" #include "llviewerwindow.h" diff --git a/indra/newview/lljoystickbutton.cpp b/indra/newview/lljoystickbutton.cpp index d63eebfcac..efc03b3d88 100644 --- a/indra/newview/lljoystickbutton.cpp +++ b/indra/newview/lljoystickbutton.cpp @@ -42,8 +42,8 @@ // Project includes #include "llui.h" #include "llagent.h" -#include "llviewerimage.h" -#include "llviewerimagelist.h" +#include "llviewertexture.h" +#include "llviewertexturelist.h" #include "llviewerwindow.h" #include "llmoveview.h" @@ -552,7 +552,7 @@ void LLJoystickCameraRotate::draw() } // Draws image rotated by multiples of 90 degrees -void LLJoystickCameraRotate::drawRotatedImage( LLImageGL* image, S32 rotations ) +void LLJoystickCameraRotate::drawRotatedImage( LLTexture* image, S32 rotations ) { S32 width = image->getWidth(); S32 height = image->getHeight(); diff --git a/indra/newview/lljoystickbutton.h b/indra/newview/lljoystickbutton.h index d0f63803ea..8caef30fa4 100644 --- a/indra/newview/lljoystickbutton.h +++ b/indra/newview/lljoystickbutton.h @@ -35,7 +35,7 @@ #include "llbutton.h" #include "llcoord.h" -#include "llviewerimage.h" +#include "llviewertexture.h" typedef enum e_joystick_quadrant { @@ -150,7 +150,7 @@ public: protected: F32 getOrbitRate(); virtual void updateSlop(); - void drawRotatedImage( LLImageGL* image, S32 rotations ); + void drawRotatedImage( LLTexture* image, S32 rotations ); protected: BOOL mInLeft; diff --git a/indra/newview/llmanip.cpp b/indra/newview/llmanip.cpp index 062e781d49..3d1d6cad74 100644 --- a/indra/newview/llmanip.cpp +++ b/indra/newview/llmanip.cpp @@ -40,7 +40,7 @@ #include "llrender.h" #include "llprimitive.h" #include "llview.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llagent.h" #include "llviewercontrol.h" diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp index 3a1ffd6546..cc2531d139 100644 --- a/indra/newview/llmaniptranslate.cpp +++ b/indra/newview/llmaniptranslate.cpp @@ -78,7 +78,7 @@ const F32 PLANE_TICK_SIZE = 0.4f; const F32 MANIPULATOR_SCALE_HALF_LIFE = 0.07f; const F32 SNAP_ARROW_SCALE = 0.7f; -static LLPointer sGridTex = NULL ; +static LLPointer sGridTex = NULL ; const LLManip::EManipPart MANIPULATOR_IDS[9] = { @@ -154,7 +154,7 @@ void LLManipTranslate::restoreGL() U32 mip = 0; destroyGL() ; - sGridTex = new LLImageGL() ; + sGridTex = LLViewerTextureManager::getLocalTexture() ; if(!sGridTex->createGLTexture()) { sGridTex = NULL ; diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index 510933a331..7b0b0c2fb7 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -51,6 +51,9 @@ #include "llsurface.h" #include "llviewercamera.h" #include "llviewercontrol.h" +#include "llviewertexture.h" +#include "llviewertexturelist.h" +#include "llviewermenu.h" #include "llviewerobjectlist.h" #include "llviewerregion.h" #include "llworld.h" @@ -664,7 +667,7 @@ void LLNetMap::createObjectImage() mObjectRawImagep = new LLImageRaw(img_size, img_size, 4); U8* data = mObjectRawImagep->getData(); memset( data, 0, img_size * img_size * 4 ); - mObjectImagep = new LLImageGL( mObjectRawImagep, FALSE); + mObjectImagep = LLViewerTextureManager::getLocalTexture( mObjectRawImagep.get(), FALSE); setScale(mScale); } mUpdateNow = TRUE; diff --git a/indra/newview/llnetmap.h b/indra/newview/llnetmap.h index cebc4af165..a673ea3f57 100644 --- a/indra/newview/llnetmap.h +++ b/indra/newview/llnetmap.h @@ -39,11 +39,11 @@ #include "v3dmath.h" #include "v4color.h" #include "llimage.h" -#include "llimagegl.h" class LLColor4U; class LLCoordGL; class LLTextBox; +class LLViewerTexture ; class LLNetMap : public LLUICtrl { @@ -106,7 +106,7 @@ private: BOOL mUpdateNow; LLVector3d mObjectImageCenterGlobal; LLPointer mObjectRawImagep; - LLPointer mObjectImagep; + LLPointer mObjectImagep; LLUUID mClosestAgentToCursor; LLUUID mClosestAgentAtLastRightClick; diff --git a/indra/newview/lloverlaybar.cpp b/indra/newview/lloverlaybar.cpp index 2ccd729e0a..d03e39280f 100644 --- a/indra/newview/lloverlaybar.cpp +++ b/indra/newview/lloverlaybar.cpp @@ -49,7 +49,7 @@ #include "lltextbox.h" #include "llui.h" #include "llviewercontrol.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerjoystick.h" #include "llviewermedia.h" #include "llviewermenu.h" // handle_reset_view() diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 2ff22416ec..e9e71644b1 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -411,7 +411,7 @@ void LLPanelFace::getState() { LLUUID get(LLViewerObject* object, S32 te) { - LLViewerImage* image = object->getTEImage(te); + LLViewerTexture* image = object->getTEImage(te); return image ? image->getID() : LLUUID::null; } } func; diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index 9e537be425..365f07e4b6 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -49,7 +49,7 @@ #include "lltabcontainer.h" #include "lltextbox.h" #include "lltexteditor.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerwindow.h" #include "llfocusmgr.h" diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index 75df49e5e3..9beecf75eb 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -57,7 +57,7 @@ #include "lluiconstants.h" #include "llurlsimstring.h" #include "llviewerbuild.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewermenu.h" // for handle_preferences() #include "llviewernetwork.h" #include "llviewerwindow.h" // to link into child list @@ -362,7 +362,7 @@ LLPanelLogin::~LLPanelLogin() gResponsePtr->setParent( 0 ); //// We know we're done with the image, so be rid of it. - //gImageList.deleteImage( mLogoImage ); + //gTextureList.deleteImage( mLogoImage ); } // virtual diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp index d6ecb42255..9122e49a06 100644 --- a/indra/newview/llpreviewtexture.cpp +++ b/indra/newview/llpreviewtexture.cpp @@ -46,8 +46,8 @@ #include "lltextbox.h" #include "lltextureview.h" #include "llui.h" -#include "llviewerimage.h" -#include "llviewerimagelist.h" +#include "llviewertexture.h" +#include "llviewertexturelist.h" #include "lluictrlfactory.h" #include "llviewerwindow.h" #include "lllineeditor.h" @@ -205,7 +205,7 @@ void LLPreviewTexture::draw() LLFontGL::NORMAL, LLFontGL::DROP_SHADOW); - F32 data_progress = mImage->mDownloadProgress; + F32 data_progress = mImage->getDownloadProgress() ; // Draw the progress bar. const S32 BAR_HEIGHT = 12; @@ -295,7 +295,7 @@ void LLPreviewTexture::onFocusReceived() // static void LLPreviewTexture::onFileLoadedForSave(BOOL success, - LLViewerImage *src_vi, + LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, @@ -357,8 +357,8 @@ void LLPreviewTexture::updateDimensions() mUpdateDimensions = FALSE; - S32 image_height = llmax(1, mImage->getHeight(0)); - S32 image_width = llmax(1, mImage->getWidth(0)); + S32 image_height = llmax(1, mImage->getFullHeight()); + S32 image_width = llmax(1, mImage->getFullWidth()); // Attempt to make the image 1:1 on screen. // If that fails, cut width by half. S32 client_width = image_width; @@ -379,8 +379,8 @@ void LLPreviewTexture::updateDimensions() S32 view_height = client_height + vert_pad; // set text on dimensions display (should be moved out of here and into a callback of some sort) - childSetTextArg("dimensions", "[WIDTH]", llformat("%d", mImage->mFullWidth)); - childSetTextArg("dimensions", "[HEIGHT]", llformat("%d", mImage->mFullHeight)); + childSetTextArg("dimensions", "[WIDTH]", llformat("%d", mImage->getFullWidth())); + childSetTextArg("dimensions", "[HEIGHT]", llformat("%d", mImage->getFullHeight())); // add space for dimensions S32 info_height = 0; @@ -464,15 +464,15 @@ void LLPreviewTexture::updateDimensions() void LLPreviewTexture::loadAsset() { - mImage = gImageList.getImage(mImageID, MIPMAP_TRUE, FALSE); - mImage->setBoostLevel(LLViewerImage::BOOST_PREVIEW); + mImage = LLViewerTextureManager::getFetchedTexture(mImageID, MIPMAP_TRUE, FALSE, LLViewerTexture::LOD_TEXTURE); + mImage->setBoostLevel(LLViewerTexture::BOOST_PREVIEW); mAssetStatus = PREVIEW_ASSET_LOADING; updateDimensions(); } LLPreview::EAssetStatus LLPreviewTexture::getAssetStatus() { - if (mImage.notNull() && (mImage->mFullWidth * mImage->mFullHeight > 0)) + if (mImage.notNull() && (mImage->getFullWidth() * mImage->getFullHeight() > 0)) { mAssetStatus = PREVIEW_ASSET_LOADED; } diff --git a/indra/newview/llpreviewtexture.h b/indra/newview/llpreviewtexture.h index 45b173e7bf..9ace304fa6 100644 --- a/indra/newview/llpreviewtexture.h +++ b/indra/newview/llpreviewtexture.h @@ -36,7 +36,7 @@ #include "llpreview.h" #include "llbutton.h" #include "llframetimer.h" -#include "llviewerimage.h" +#include "llviewertexture.h" class LLImageRaw; @@ -60,7 +60,7 @@ public: static void saveToFile(void* userdata); static void onFileLoadedForSave( BOOL success, - LLViewerImage *src_vi, + LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, @@ -75,7 +75,7 @@ protected: private: void updateDimensions(); LLUUID mImageID; - LLPointer mImage; + LLPointer mImage; BOOL mLoadingFullImage; std::string mSaveFileName; LLFrameTimer mSavedFileTimer; diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp index 38d617e468..f70cfc59ec 100644 --- a/indra/newview/llprogressview.cpp +++ b/indra/newview/llprogressview.cpp @@ -40,7 +40,6 @@ #include "llrender.h" #include "llui.h" #include "llfontgl.h" -#include "llimagegl.h" #include "lltimer.h" #include "lltextbox.h" #include "llglheaders.h" @@ -51,7 +50,7 @@ #include "llprogressbar.h" #include "llstartup.h" #include "llviewercontrol.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerwindow.h" #include "llappviewer.h" #include "llweb.h" @@ -147,10 +146,10 @@ void LLProgressView::draw() // Paint bitmap if we've got one glPushMatrix(); - if (gStartImageGL) + if (gStartTexture) { LLGLSUIDefault gls_ui; - gGL.getTexUnit(0)->bind(gStartImageGL); + gGL.getTexUnit(0)->bind(gStartTexture.get()); gGL.color4f(1.f, 1.f, 1.f, mFadeTimer.getStarted() ? clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, FADE_IN_TIME, 1.f, 0.f) : 1.f); F32 image_aspect = (F32)gStartImageWidth / (F32)gStartImageHeight; S32 width = getRect().getWidth(); @@ -186,7 +185,7 @@ void LLProgressView::draw() { gFocusMgr.removeTopCtrlWithoutCallback(this); LLPanel::setVisible(FALSE); - gStartImageGL = NULL; + gStartTexture = NULL; } return; } diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index b3b850441c..c24b3f0d04 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -74,7 +74,7 @@ #include "llui.h" #include "llviewercamera.h" #include "llviewercontrol.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewermenu.h" #include "llviewerobject.h" #include "llviewerobjectlist.h" @@ -1425,7 +1425,7 @@ void LLSelectMgr::selectionSetImage(const LLUUID& imageid) // Texture picker defaults aren't inventory items // * Don't need to worry about permissions for them // * Can just apply the texture and be done with it. - objectp->setTEImage(te, gImageList.getImage(mImageID, TRUE, FALSE)); + objectp->setTEImage(te, LLViewerTextureManager::getFetchedTexture(mImageID, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE)); } return true; } @@ -1581,7 +1581,7 @@ BOOL LLSelectMgr::selectionRevertTextures() } else { - object->setTEImage(te, gImageList.getImage(id)); + object->setTEImage(te, LLViewerTextureManager::getFetchedTexture(id, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE)); } } } @@ -4544,7 +4544,7 @@ void LLSelectMgr::updateSilhouettes() if (!mSilhouetteImagep) { - mSilhouetteImagep = gImageList.getImageFromFile("silhouette.j2c", TRUE, TRUE); + mSilhouetteImagep = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", TRUE, TRUE); } mHighlightedObjects->cleanupNodes(); @@ -4814,7 +4814,7 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud) return; } - gGL.getTexUnit(0)->bind(mSilhouetteImagep.get()); + gGL.getTexUnit(0)->bind(mSilhouetteImagep); LLGLSPipelineSelection gls_select; gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f); LLGLEnable blend(GL_BLEND); diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 992cc1e906..cfc2b702fc 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -54,7 +54,7 @@ #include "boost/iterator/filter_iterator.hpp" class LLMessageSystem; -class LLViewerImage; +class LLViewerTexture; class LLViewerObject; class LLColor4; class LLVector3; @@ -690,7 +690,7 @@ private: static bool confirmDelete(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle handle); private: - LLPointer mSilhouetteImagep; + LLPointer mSilhouetteImagep; LLObjectSelectionHandle mSelectedObjects; LLObjectSelectionHandle mHoverObjects; LLObjectSelectionHandle mHighlightedObjects; diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index f8b824732f..435d010de3 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -2356,7 +2356,7 @@ void renderTexturePriority(LLDrawable* drawable) LLGLDisable blend(GL_BLEND); - //LLViewerImage* imagep = facep->getTexture(); + //LLViewerTexture* imagep = facep->getTexture(); //if (imagep) { @@ -2386,7 +2386,7 @@ void renderTexturePriority(LLDrawable* drawable) /*S32 boost = imagep->getBoostLevel(); if (boost) { - F32 t = (F32) boost / (F32) (LLViewerImage::BOOST_MAX_LEVEL-1); + F32 t = (F32) boost / (F32) (LLViewerTexture::BOOST_MAX_LEVEL-1); LLVector4 col = lerp(boost_cold, boost_hot, t); LLGLEnable blend_on(GL_BLEND); gGL.blendFunc(GL_SRC_ALPHA, GL_ONE); @@ -2896,7 +2896,7 @@ LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector3& start, con } LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, - LLViewerImage* texture, LLVertexBuffer* buffer, + LLViewerTexture* texture, LLVertexBuffer* buffer, BOOL fullbright, U8 bump, BOOL particle, F32 part_size) : mVertexBuffer(buffer), diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 8aec5c8377..13ab35402c 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -67,12 +67,12 @@ protected: public: LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, - LLViewerImage* image, LLVertexBuffer* buffer, + LLViewerTexture* image, LLVertexBuffer* buffer, BOOL fullbright = FALSE, U8 bump = 0, BOOL particle = FALSE, F32 part_size = 0); LLPointer mVertexBuffer; - LLPointer mTexture; + LLPointer mTexture; LLColor4U mGlowColor; S32 mDebugColor; const LLMatrix4* mTextureMatrix; @@ -164,7 +164,7 @@ public: typedef std::vector > drawmap_elem_t; typedef std::map draw_map_t; typedef std::vector > buffer_list_t; - typedef std::map, buffer_list_t> buffer_texture_map_t; + typedef std::map, buffer_list_t> buffer_texture_map_t; typedef std::map buffer_map_t; typedef LLOctreeListener BaseType; diff --git a/indra/newview/llsprite.cpp b/indra/newview/llsprite.cpp index 893ed22297..dce4e9d144 100644 --- a/indra/newview/llsprite.cpp +++ b/indra/newview/llsprite.cpp @@ -48,7 +48,7 @@ #include "lldrawable.h" #include "llface.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" LLVector3 LLSprite::sCameraUp(0.0f,0.0f,1.0f); LLVector3 LLSprite::sCameraRight(1.0f,0.0f,0.0f); diff --git a/indra/newview/llsprite.h b/indra/newview/llsprite.h index 28f4ec5d03..eefe2a2386 100644 --- a/indra/newview/llsprite.h +++ b/indra/newview/llsprite.h @@ -40,7 +40,7 @@ #include "v4color.h" #include "lluuid.h" #include "llgl.h" -#include "llviewerimage.h" +#include "llviewertexture.h" class LLViewerCamera; @@ -82,7 +82,7 @@ public: public: LLUUID mImageID; - LLPointer mImagep; + LLPointer mImagep; private: F32 mWidth; F32 mHeight; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index f78703f58d..e6a2ab4ace 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -152,7 +152,7 @@ #include "llviewerdisplay.h" #include "llviewergenericmessage.h" #include "llviewergesture.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewermedia.h" #include "llviewermenu.h" #include "llviewermessage.h" @@ -216,7 +216,7 @@ extern S32 gStartImageHeight; // local globals // -LLPointer gStartImageGL; +LLPointer gStartTexture; static LLHost gAgentSimHost; static BOOL gSkipOptionalUpdate = FALSE; @@ -305,7 +305,7 @@ void update_texture_fetch() LLAppViewer::getTextureCache()->update(1); // unpauses the texture cache thread LLAppViewer::getImageDecodeThread()->update(1); // unpauses the image thread LLAppViewer::getTextureFetch()->update(1); // unpauses the texture fetch thread - gImageList.updateImages(0.10f); + gTextureList.updateImages(0.10f); } static std::vector sAuthUris; @@ -382,7 +382,7 @@ bool idle_startup() else { // Update images? - gImageList.updateImages(0.01f); + gTextureList.updateImages(0.01f); } if ( STATE_FIRST == LLStartUp::getStartupState() ) @@ -1618,7 +1618,7 @@ bool idle_startup() // // Initialize classes w/graphics stuff. // - gImageList.doPrefetchImages(); + gTextureList.doPrefetchImages(); LLSurface::initClasses(); LLFace::initClass(); @@ -1832,7 +1832,7 @@ bool idle_startup() F32 frac = (F32)i / (F32)DECODE_TIME_SEC; set_startup_status(0.45f + frac*0.1f, LLTrans::getString("LoginDecodingImages"), gAgent.mMOTD); display_startup(); - gImageList.decodeAllImages(1.f); + gTextureList.decodeAllImages(1.f); } LLStartUp::setStartupState( STATE_WORLD_WAIT ); @@ -2991,8 +2991,8 @@ void use_circuit_callback(void**, S32 result) void register_viewer_callbacks(LLMessageSystem* msg) { msg->setHandlerFuncFast(_PREHASH_LayerData, process_layer_data ); - msg->setHandlerFuncFast(_PREHASH_ImageData, LLViewerImageList::receiveImageHeader ); - msg->setHandlerFuncFast(_PREHASH_ImagePacket, LLViewerImageList::receiveImagePacket ); + msg->setHandlerFuncFast(_PREHASH_ImageData, LLViewerTextureList::receiveImageHeader ); + msg->setHandlerFuncFast(_PREHASH_ImagePacket, LLViewerTextureList::receiveImagePacket ); msg->setHandlerFuncFast(_PREHASH_ObjectUpdate, process_object_update ); msg->setHandlerFunc("ObjectUpdateCompressed", process_compressed_object_update ); msg->setHandlerFunc("ObjectUpdateCached", process_cached_object_update ); @@ -3123,7 +3123,7 @@ void register_viewer_callbacks(LLMessageSystem* msg) msg->setHandlerFunc("TeleportFailed", process_teleport_failed, NULL); msg->setHandlerFunc("TeleportLocal", process_teleport_local, NULL); - msg->setHandlerFunc("ImageNotInDatabase", LLViewerImageList::processImageNotInDatabase, NULL); + msg->setHandlerFunc("ImageNotInDatabase", LLViewerTextureList::processImageNotInDatabase, NULL); msg->setHandlerFuncFast(_PREHASH_GroupMembersReply, LLGroupMgr::processGroupMembersReply); @@ -3254,9 +3254,9 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name, // Loads a bitmap to display during load void init_start_screen(S32 location_id) { - if (gStartImageGL.notNull()) + if (gStartTexture.notNull()) { - gStartImageGL = NULL; + gStartTexture = NULL; LL_INFOS("AppInit") << "re-initializing start screen" << LL_ENDL; } @@ -3288,7 +3288,6 @@ void init_start_screen(S32 location_id) return; } - gStartImageGL = new LLImageGL(FALSE); gStartImageWidth = start_image_bmp->getWidth(); gStartImageHeight = start_image_bmp->getHeight(); @@ -3296,12 +3295,12 @@ void init_start_screen(S32 location_id) if (!start_image_bmp->decode(raw, 0.0f)) { LL_WARNS("AppInit") << "Bitmap decode failed" << LL_ENDL; - gStartImageGL = NULL; + gStartTexture = NULL; return; } raw->expandToPowerOfTwo(); - gStartImageGL->createGLTexture(0, raw); + gStartTexture = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE) ; } @@ -3309,7 +3308,7 @@ void init_start_screen(S32 location_id) void release_start_screen() { LL_DEBUGS("AppInit") << "Releasing bitmap..." << LL_ENDL; - gStartImageGL = NULL; + gStartTexture = NULL; } diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h index 93701800e9..4532c5e586 100644 --- a/indra/newview/llstartup.h +++ b/indra/newview/llstartup.h @@ -33,7 +33,7 @@ #ifndef LL_LLSTARTUP_H #define LL_LLSTARTUP_H -#include "llimagegl.h" +class LLViewerTexture ; // functions bool idle_startup(); @@ -74,7 +74,7 @@ typedef enum { // exported symbols extern bool gAgentMovementCompleted; -extern LLPointer gStartImageGL; +extern LLPointer gStartTexture; extern std::string gInitialOutfit; extern std::string gInitialOutfitGender; // "male" or "female" diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp index 27a08e7d7b..de3d80f044 100644 --- a/indra/newview/llsurface.cpp +++ b/indra/newview/llsurface.cpp @@ -36,7 +36,7 @@ #include "llrender.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llpatchvertexarray.h" #include "patch_dct.h" #include "patch_code.h" @@ -47,7 +47,7 @@ #include "llappviewer.h" #include "llworld.h" #include "llviewercontrol.h" -#include "llviewerimage.h" +#include "llviewertexture.h" #include "llsurfacepatch.h" #include "llvosurfacepatch.h" #include "llvowater.h" @@ -137,12 +137,10 @@ LLSurface::~LLSurface() // Don't enable this until we blitz the draw pool for it as well. -- djs if (mSTexturep) { - gImageList.deleteImage(mSTexturep); mSTexturep = NULL; } if (mWaterTexturep) { - gImageList.deleteImage(mWaterTexturep); mWaterTexturep = NULL; } } @@ -214,18 +212,18 @@ void LLSurface::create(const S32 grids_per_edge, createPatchData(); } -LLViewerImage* LLSurface::getSTexture() +LLViewerTexture* LLSurface::getSTexture() { - if (mSTexturep.notNull() && !mSTexturep->getHasGLTexture()) + if (mSTexturep.notNull() && !mSTexturep->hasValidGLTexture()) { createSTexture(); } return mSTexturep; } -LLViewerImage* LLSurface::getWaterTexture() +LLViewerTexture* LLSurface::getWaterTexture() { - if (mWaterTexturep.notNull() && !mWaterTexturep->getHasGLTexture()) + if (mWaterTexturep.notNull() && !mWaterTexturep->hasValidGLTexture()) { createWaterTexture(); } @@ -249,11 +247,10 @@ void LLSurface::createSTexture() } } - mSTexturep = new LLViewerImage(raw, FALSE); + mSTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE); mSTexturep->dontDiscard(); - gGL.getTexUnit(0)->bind(mSTexturep.get()); - mSTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); - gImageList.addImage(mSTexturep); + gGL.getTexUnit(0)->bind(mSTexturep); + mSTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); } } @@ -274,11 +271,10 @@ void LLSurface::createWaterTexture() *(default_texture + (i*sTextureSize/2 + j)*4 + 3) = MAX_WATER_COLOR.mV[3]; } } - mWaterTexturep = new LLViewerImage(raw, FALSE); + mWaterTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE); mWaterTexturep->dontDiscard(); - gGL.getTexUnit(0)->bind(mWaterTexturep.get()); + gGL.getTexUnit(0)->bind(mWaterTexturep); mWaterTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); - gImageList.addImage(mWaterTexturep); } } @@ -1193,7 +1189,7 @@ F32 LLSurface::getWaterHeight() const BOOL LLSurface::generateWaterTexture(const F32 x, const F32 y, const F32 width, const F32 height) { - if (!getWaterTexture()) + if (!getWaterTexture() || !mWaterTexturep->hasGLTexture()) { return FALSE; } diff --git a/indra/newview/llsurface.h b/indra/newview/llsurface.h index 310ab5d2c3..1f672d2250 100644 --- a/indra/newview/llsurface.h +++ b/indra/newview/llsurface.h @@ -46,7 +46,7 @@ #include "llvowater.h" #include "llpatchvertexarray.h" -#include "llviewerimage.h" +#include "llviewertexture.h" class LLTimer; class LLUUID; @@ -133,8 +133,8 @@ public: void setWaterHeight(F32 height); F32 getWaterHeight() const; - LLViewerImage *getSTexture(); - LLViewerImage *getWaterTexture(); + LLViewerTexture *getSTexture(); + LLViewerTexture *getWaterTexture(); BOOL hasZData() const { return mHasZData; } void dirtyAllPatches(); // Use this to dirty all patches when changing terrain parameters @@ -205,8 +205,8 @@ protected: // The textures should never be directly initialized - use the setter methods! - LLPointer mSTexturep; // Texture for surface - LLPointer mWaterTexturep; // Water texture + LLPointer mSTexturep; // Texture for surface + LLPointer mWaterTexturep; // Water texture LLPointer mWaterObjp; diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp index 716ab8eef4..a570a89b28 100644 --- a/indra/newview/lltexlayer.cpp +++ b/indra/newview/lltexlayer.cpp @@ -72,7 +72,7 @@ LLTexLayerSetBuffer::LLTexLayerSetBuffer(LLTexLayerSet* const owner, S32 width, S32 height, BOOL has_bump) : // ORDER_LAST => must render these after the hints are created. - LLDynamicTexture( width, height, 4, LLDynamicTexture::ORDER_LAST, TRUE ), + LLViewerDynamicTexture( width, height, 4, LLViewerDynamicTexture::ORDER_LAST, TRUE ), mNeedsUpdate( TRUE ), mNeedsUpload( FALSE ), mUploadPending( FALSE ), // Not used for any logic here, just to sync sending of updates @@ -91,8 +91,8 @@ LLTexLayerSetBuffer::~LLTexLayerSetBuffer() if( mBumpTex.notNull()) { mBumpTex = NULL ; - LLImageGL::sGlobalTextureMemoryInBytes -= mWidth * mHeight * 4; - LLTexLayerSetBuffer::sGLBumpByteCount -= mWidth * mHeight * 4; + LLImageGL::sGlobalTextureMemoryInBytes -= mFullWidth * mFullHeight * 4; + LLTexLayerSetBuffer::sGLBumpByteCount -= mFullWidth * mFullHeight * 4; } } @@ -100,7 +100,7 @@ LLTexLayerSetBuffer::~LLTexLayerSetBuffer() void LLTexLayerSetBuffer::restoreGLTexture() { createBumpTexture() ; - LLDynamicTexture::restoreGLTexture() ; + LLViewerDynamicTexture::restoreGLTexture() ; } //virtual @@ -109,11 +109,11 @@ void LLTexLayerSetBuffer::destroyGLTexture() if( mBumpTex.notNull() ) { mBumpTex = NULL ; - LLImageGL::sGlobalTextureMemoryInBytes -= mWidth * mHeight * 4; - LLTexLayerSetBuffer::sGLBumpByteCount -= mWidth * mHeight * 4; + LLImageGL::sGlobalTextureMemoryInBytes -= mFullWidth * mFullHeight * 4; + LLTexLayerSetBuffer::sGLBumpByteCount -= mFullWidth * mFullHeight * 4; } - LLDynamicTexture::destroyGLTexture() ; + LLViewerDynamicTexture::destroyGLTexture() ; } void LLTexLayerSetBuffer::createBumpTexture() @@ -121,7 +121,7 @@ void LLTexLayerSetBuffer::createBumpTexture() if( mHasBump ) { LLGLSUIDefault gls_ui; - mBumpTex = new LLImageGL(FALSE) ; + mBumpTex = LLViewerTextureManager::getLocalTexture(FALSE) ; if(!mBumpTex->createGLTexture()) { mBumpTex = NULL ; @@ -135,13 +135,13 @@ void LLTexLayerSetBuffer::createBumpTexture() gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - LLImageGL::setManualImage(GL_TEXTURE_2D, 0, GL_RGBA8, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + LLImageGL::setManualImage(GL_TEXTURE_2D, 0, GL_RGBA8, mFullWidth, mFullHeight, GL_RGBA, GL_UNSIGNED_BYTE, NULL); stop_glerror(); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLImageGL::sGlobalTextureMemoryInBytes += mWidth * mHeight * 4; - LLTexLayerSetBuffer::sGLBumpByteCount += mWidth * mHeight * 4; + LLImageGL::sGlobalTextureMemoryInBytes += mFullWidth * mFullHeight * 4; + LLTexLayerSetBuffer::sGLBumpByteCount += mFullWidth * mFullHeight * 4; } } @@ -184,7 +184,7 @@ void LLTexLayerSetBuffer::pushProjection() const glMatrixMode(GL_PROJECTION); gGL.pushMatrix(); glLoadIdentity(); - glOrtho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f); + glOrtho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f); glMatrixMode(GL_MODELVIEW); gGL.pushMatrix(); @@ -230,14 +230,14 @@ void LLTexLayerSetBuffer::preRender(BOOL clear_depth) pushProjection(); // keep depth buffer, we don't need to clear it - LLDynamicTexture::preRender(FALSE); + LLViewerDynamicTexture::preRender(FALSE); } void LLTexLayerSetBuffer::postRender(BOOL success) { popProjection(); - LLDynamicTexture::postRender(success); + LLViewerDynamicTexture::postRender(success); } BOOL LLTexLayerSetBuffer::render() @@ -256,7 +256,7 @@ BOOL LLTexLayerSetBuffer::render() if( mBumpTex.notNull() ) { // Composite the bump data - success &= mTexLayerSet->renderBump( mOrigin.mX, mOrigin.mY, mWidth, mHeight ); + success &= mTexLayerSet->renderBump( mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight ); stop_glerror(); if (success) @@ -267,14 +267,14 @@ BOOL LLTexLayerSetBuffer::render() gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mBumpTex->getTexName()); stop_glerror(); - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mOrigin.mX, mOrigin.mY, mWidth, mHeight); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight); stop_glerror(); // if we need to upload the data, read it back into a buffer if( upload_now ) { - baked_bump_data = new U8[ mWidth * mHeight * 4 ]; - glReadPixels(mOrigin.mX, mOrigin.mY, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, baked_bump_data ); + baked_bump_data = new U8[ mFullWidth * mFullHeight * 4 ]; + glReadPixels(mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, GL_RGBA, GL_UNSIGNED_BYTE, baked_bump_data ); stop_glerror(); } } @@ -282,7 +282,7 @@ BOOL LLTexLayerSetBuffer::render() // Composite the color data LLGLSUIDefault gls_ui; - success &= mTexLayerSet->render( mOrigin.mX, mOrigin.mY, mWidth, mHeight ); + success &= mTexLayerSet->render( mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight ); gGL.flush(); if( upload_now ) @@ -303,7 +303,7 @@ BOOL LLTexLayerSetBuffer::render() gGL.setSceneBlendType(LLRender::BT_ALPHA); // we have valid texture data now - mTexture->setGLTextureCreated(true); + mGLTexturep->setGLTextureCreated(true); mNeedsUpdate = FALSE; delete [] baked_bump_data; @@ -312,7 +312,7 @@ BOOL LLTexLayerSetBuffer::render() bool LLTexLayerSetBuffer::isInitialized(void) const { - return mTexture.notNull() && mTexture->isGLTextureCreated(); + return mGLTexturep.notNull() && mGLTexturep->isGLTextureCreated(); } BOOL LLTexLayerSetBuffer::updateImmediate() @@ -333,9 +333,9 @@ BOOL LLTexLayerSetBuffer::updateImmediate() void LLTexLayerSetBuffer::readBackAndUpload(const U8* baked_bump_data) { // pointers for storing data to upload - U8* baked_color_data = new U8[ mWidth * mHeight * 4 ]; + U8* baked_color_data = new U8[ mFullWidth * mFullHeight * 4 ]; - glReadPixels(mOrigin.mX, mOrigin.mY, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, baked_color_data ); + glReadPixels(mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, GL_RGBA, GL_UNSIGNED_BYTE, baked_color_data ); stop_glerror(); llinfos << "Baked " << mTexLayerSet->getBodyRegion() << llendl; @@ -350,16 +350,16 @@ void LLTexLayerSetBuffer::readBackAndUpload(const U8* baked_bump_data) LLGLSUIDefault gls_ui; - LLPointer baked_mask_image = new LLImageRaw(mWidth, mHeight, 1 ); + LLPointer baked_mask_image = new LLImageRaw(mFullWidth, mFullHeight, 1 ); U8* baked_mask_data = baked_mask_image->getData(); - mTexLayerSet->gatherMorphMaskAlpha(baked_mask_data, mWidth, mHeight); + mTexLayerSet->gatherMorphMaskAlpha(baked_mask_data, mFullWidth, mFullHeight); // writes into baked_color_data const char* comment_text = NULL; S32 baked_image_components = mBumpTex.notNull() ? 5 : 4; // red green blue [bump] clothing - LLPointer baked_image = new LLImageRaw( mWidth, mHeight, baked_image_components ); + LLPointer baked_image = new LLImageRaw( mFullWidth, mFullHeight, baked_image_components ); U8* baked_image_data = baked_image->getData(); @@ -368,9 +368,9 @@ void LLTexLayerSetBuffer::readBackAndUpload(const U8* baked_bump_data) comment_text = LINDEN_J2C_COMMENT_PREFIX "RGBHM"; // 5 channels: rgb, heightfield/alpha, mask S32 i = 0; - for( S32 u = 0; u < mWidth; u++ ) + for( S32 u = 0; u < mFullWidth; u++ ) { - for( S32 v = 0; v < mHeight; v++ ) + for( S32 v = 0; v < mFullHeight; v++ ) { baked_image_data[5*i + 0] = baked_color_data[4*i + 0]; baked_image_data[5*i + 1] = baked_color_data[4*i + 1]; @@ -384,9 +384,9 @@ void LLTexLayerSetBuffer::readBackAndUpload(const U8* baked_bump_data) else { S32 i = 0; - for( S32 u = 0; u < mWidth; u++ ) + for( S32 u = 0; u < mFullWidth; u++ ) { - for( S32 v = 0; v < mHeight; v++ ) + for( S32 v = 0; v < mFullHeight; v++ ) { baked_image_data[4*i + 0] = baked_color_data[4*i + 0]; baked_image_data[4*i + 1] = baked_color_data[4*i + 1]; @@ -555,11 +555,7 @@ void LLTexLayerSetBuffer::bindBumpTexture( U32 stage ) gGL.getTexUnit(stage)->bindManual(LLTexUnit::TT_TEXTURE, mBumpTex->getTexName()); gGL.getTexUnit(0)->activate(); - if( mLastBindTime != LLImageGL::sLastFrameTime ) - { - mLastBindTime = LLImageGL::sLastFrameTime; - LLImageGL::updateBoundTexMem(mWidth * mHeight * 4); - } + mGLTexturep->updateBindStats(mFullWidth * mFullHeight * 4); } else { @@ -673,7 +669,6 @@ LLTexLayerSet::~LLTexLayerSet() deleteCaches(); std::for_each(mLayerList.begin(), mLayerList.end(), DeletePointer()); std::for_each(mMaskLayerList.begin(), mMaskLayerList.end(), DeletePointer()); - delete mComposite; } //----------------------------------------------------------------------------- @@ -886,7 +881,6 @@ void LLTexLayerSet::destroyComposite() { if( mComposite ) { - delete mComposite; mComposite = NULL; } } @@ -960,11 +954,11 @@ void LLTexLayerSet::renderAlphaMaskTextures(S32 width, S32 height, bool forceCle LLGLSNoAlphaTest gls_no_alpha_test; gGL.flush(); { - LLImageGL* image_gl = LLTexLayerStaticImageList::getInstance()->getImageGL(info->mStaticAlphaFileName, TRUE); - if( image_gl ) + LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(info->mStaticAlphaFileName, TRUE); + if( tex ) { LLGLSUIDefault gls_ui; - gGL.getTexUnit(0)->bind(image_gl); + gGL.getTexUnit(0)->bind(tex); gGL.getTexUnit(0)->setTextureBlendType( LLTexUnit::TB_REPLACE ); gl_rect_2d_simple_tex( width, height ); } @@ -1409,16 +1403,16 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height, BOOL render_morph) if( (getInfo()->mLocalTexture != -1) && !getInfo()->mUseLocalTextureAlphaOnly ) { { - LLImageGL* image_gl = NULL; - if( mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &image_gl ) ) + LLViewerTexture* tex = NULL; + if( mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &tex ) ) { - if( image_gl ) + if( tex ) { LLGLDisable alpha_test(getInfo()->mWriteAllChannels ? GL_ALPHA_TEST : 0); - LLTexUnit::eTextureAddressMode old_mode = image_gl->getAddressMode(); + LLTexUnit::eTextureAddressMode old_mode = tex->getAddressMode(); - gGL.getTexUnit(0)->bind(image_gl); + gGL.getTexUnit(0)->bind(tex); gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); gl_rect_2d_simple_tex( width, height ); @@ -1437,10 +1431,10 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height, BOOL render_morph) if( !getInfo()->mStaticImageFileName.empty() ) { { - LLImageGL* image_gl = LLTexLayerStaticImageList::getInstance()->getImageGL(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask); - if( image_gl ) + LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask); + if( tex ) { - gGL.getTexUnit(0)->bind(image_gl); + gGL.getTexUnit(0)->bind(tex); gl_rect_2d_simple_tex( width, height ); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } @@ -1548,11 +1542,11 @@ BOOL LLTexLayer::blendAlphaTexture(S32 width, S32 height) if( !getInfo()->mStaticImageFileName.empty() ) { - LLImageGL* image_gl = LLTexLayerStaticImageList::getInstance()->getImageGL( getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask ); - if( image_gl ) + LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture( getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask ); + if( tex ) { LLGLSNoAlphaTest gls_no_alpha_test; - gGL.getTexUnit(0)->bind(image_gl); + gGL.getTexUnit(0)->bind(tex); gl_rect_2d_simple_tex( width, height ); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } @@ -1565,13 +1559,13 @@ BOOL LLTexLayer::blendAlphaTexture(S32 width, S32 height) { if (getInfo()->mLocalTexture >=0 && getInfo()->mLocalTexture < TEX_NUM_INDICES) { - LLImageGL* image_gl = NULL; - if (mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &image_gl)) + LLViewerTexture* tex = NULL; + if (mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &tex)) { - if (image_gl) + if (tex) { LLGLSNoAlphaTest gls_no_alpha_test; - gGL.getTexUnit(0)->bind(image_gl); + gGL.getTexUnit(0)->bind(tex); gl_rect_2d_simple_tex( width, height ); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); success = TRUE; @@ -1623,16 +1617,16 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC // Accumulate the alpha component of the texture if( getInfo()->mLocalTexture != -1 ) { - LLImageGL* image_gl = NULL; - if( mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &image_gl ) ) + LLViewerTexture* tex = NULL; + if( mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &tex ) ) { - if( image_gl && (image_gl->getComponents() == 4) ) + if( tex && (tex->getComponents() == 4) ) { LLGLSNoAlphaTest gls_no_alpha_test; - LLTexUnit::eTextureAddressMode old_mode = image_gl->getAddressMode(); + LLTexUnit::eTextureAddressMode old_mode = tex->getAddressMode(); - gGL.getTexUnit(0)->bind(image_gl); + gGL.getTexUnit(0)->bind(tex); gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); gl_rect_2d_simple_tex( width, height ); @@ -1649,14 +1643,14 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC if( !getInfo()->mStaticImageFileName.empty() ) { - LLImageGL* image_gl = LLTexLayerStaticImageList::getInstance()->getImageGL(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask); - if( image_gl ) + LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask); + if( tex ) { - if( (image_gl->getComponents() == 4) || - ( (image_gl->getComponents() == 1) && getInfo()->mStaticImageIsMask ) ) + if( (tex->getComponents() == 4) || + ( (tex->getComponents() == 1) && getInfo()->mStaticImageIsMask ) ) { LLGLSNoAlphaTest gls_no_alpha_test; - gGL.getTexUnit(0)->bind(image_gl); + gGL.getTexUnit(0)->bind(tex); gl_rect_2d_simple_tex( width, height ); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } @@ -1856,16 +1850,16 @@ void LLTexLayerStaticImageList::deleteCachedImages() //mStaticImageLists uses LLPointers, clear() will cause deletion mStaticImageListTGA.clear(); - mStaticImageListGL.clear(); + mStaticImageList.clear(); mGLBytes = 0; mTGABytes = 0; } } -// Note: in general, for a given image image we'll call either getImageTga() or getImageGL(). +// Note: in general, for a given image image we'll call either getImageTga() or getTexture(). // We call getImageTga() if the image is used as an alpha gradient. -// Otherwise, we call getImageGL() +// Otherwise, we call getTexture() // Returns an LLImageTGA that contains the encoded data from a tga file named file_name. // Caches the result to speed identical subsequent requests. @@ -1897,19 +1891,19 @@ LLImageTGA* LLTexLayerStaticImageList::getImageTGA(const std::string& file_name) // Returns a GL Image (without a backing ImageRaw) that contains the decoded data from a tga file named file_name. // Caches the result to speed identical subsequent requests. -LLImageGL* LLTexLayerStaticImageList::getImageGL(const std::string& file_name, BOOL is_mask) +LLViewerTexture* LLTexLayerStaticImageList::getTexture(const std::string& file_name, BOOL is_mask) { - LLPointer image_gl; + LLPointer tex; const char *namekey = mImageNames.addString(file_name); - image_gl_map_t::const_iterator iter = mStaticImageListGL.find(namekey); - if( iter != mStaticImageListGL.end() ) + texture_map_t::const_iterator iter = mStaticImageList.find(namekey); + if( iter != mStaticImageList.end() ) { - image_gl = iter->second; + tex = iter->second; } else { - image_gl = new LLImageGL( FALSE ); + tex = LLViewerTextureManager::getLocalTexture( FALSE ); LLPointer image_raw = new LLImageRaw; if( loadImageRaw( file_name, image_raw ) ) { @@ -1917,23 +1911,23 @@ LLImageGL* LLTexLayerStaticImageList::getImageGL(const std::string& file_name, B { // Note: these are static, unchanging images so it's ok to assume // that once an image is a mask it's always a mask. - image_gl->setExplicitFormat( GL_ALPHA8, GL_ALPHA ); + tex->setExplicitFormat( GL_ALPHA8, GL_ALPHA ); } - image_gl->createGLTexture(0, image_raw); + tex->createGLTexture(0, image_raw); - gGL.getTexUnit(0)->bind(image_gl); - image_gl->setAddressMode(LLTexUnit::TAM_CLAMP); + gGL.getTexUnit(0)->bind(tex); + tex->setAddressMode(LLTexUnit::TAM_CLAMP); - mStaticImageListGL [ namekey ] = image_gl; - mGLBytes += (S32)image_gl->getWidth() * image_gl->getHeight() * image_gl->getComponents(); + mStaticImageList [ namekey ] = tex; + mGLBytes += (S32)tex->getWidth() * tex->getHeight() * tex->getComponents(); } else { - image_gl = NULL; + tex = NULL; } } - return image_gl; + return tex; } // Reads a .tga file, decodes it, and puts the decoded data in image_raw. diff --git a/indra/newview/lltexlayer.h b/indra/newview/lltexlayer.h index 5890440108..c3ad07a218 100644 --- a/indra/newview/lltexlayer.h +++ b/indra/newview/lltexlayer.h @@ -40,7 +40,6 @@ class LLVOAvatar; class LLVOAvatarSelf; -class LLImageGL; class LLImageTGA; class LLImageRaw; class LLXmlTreeNode; @@ -195,7 +194,7 @@ public: LLVOAvatarSelf* getAvatar() const { return mAvatar; } const std::string getBodyRegion() const; - BOOL hasComposite() const { return (mComposite != NULL); } + BOOL hasComposite() const { return (mComposite.notNull()); } void setBump(BOOL b) { mHasBump = b; } BOOL hasBump() const { return mHasBump; } LLVOAvatarDefines::EBakedTextureIndex getBakedTexIndex() { return mBakedTexIndex; } @@ -208,7 +207,7 @@ private: typedef std::vector layer_list_t; layer_list_t mLayerList; layer_list_t mMaskLayerList; - LLTexLayerSetBuffer* mComposite; + LLPointer mComposite; LLVOAvatarSelf* const mAvatar; // Backlink only; don't make this an LLPointer. BOOL mUpdatesEnabled; BOOL mHasBump; @@ -241,7 +240,7 @@ private: }; // The composite image that a LLTexLayerSet writes to. Each LLTexLayerSet has one. -class LLTexLayerSetBuffer : public LLDynamicTexture +class LLTexLayerSetBuffer : public LLViewerDynamicTexture { public: LLTexLayerSetBuffer(LLTexLayerSet* const owner, S32 width, S32 height, BOOL has_bump); @@ -282,7 +281,7 @@ private: BOOL mNeedsUpload; BOOL mUploadPending; LLUUID mUploadID; // Identifys the current upload process (null if none). Used to avoid overlaps (eg, when the user rapidly makes two changes outside of Face Edit) - LLPointer mBumpTex; // zero if none + LLPointer mBumpTex; // zero if none static S32 sGLByteCount; static S32 sGLBumpByteCount; @@ -302,7 +301,7 @@ public: LLTexLayerStaticImageList(); ~LLTexLayerStaticImageList(); - LLImageGL* getImageGL(const std::string& file_name, BOOL is_mask); + LLViewerTexture* getTexture(const std::string& file_name, BOOL is_mask); LLImageTGA* getImageTGA(const std::string& file_name); void deleteCachedImages(); @@ -314,8 +313,8 @@ private: private: LLStringTable mImageNames; - typedef std::map< const char*, LLPointer > image_gl_map_t; - image_gl_map_t mStaticImageListGL; + typedef std::map< const char*, LLPointer > texture_map_t; + texture_map_t mStaticImageList; typedef std::map< const char*, LLPointer > image_tga_map_t; image_tga_map_t mStaticImageListTGA; diff --git a/indra/newview/lltexlayerparams.cpp b/indra/newview/lltexlayerparams.cpp index e00f6aeb04..c9117a84a5 100644 --- a/indra/newview/lltexlayerparams.cpp +++ b/indra/newview/lltexlayerparams.cpp @@ -89,12 +89,12 @@ void LLTexLayerParamAlpha::getCacheByteCount(S32* gl_bytes) iter != sInstances.end(); iter++) { LLTexLayerParamAlpha* instance = *iter; - LLImageGL* image_gl = instance->mCachedProcessedImageGL; - if (image_gl) + LLViewerTexture* tex = instance->mCachedProcessedTexture; + if (tex) { - S32 bytes = (S32)image_gl->getWidth() * image_gl->getHeight() * image_gl->getComponents(); + S32 bytes = (S32)tex->getWidth() * tex->getHeight() * tex->getComponents(); - if (image_gl->getHasGLTexture()) + if (tex->hasValidGLTexture()) { *gl_bytes += bytes; } @@ -104,7 +104,7 @@ void LLTexLayerParamAlpha::getCacheByteCount(S32* gl_bytes) LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLTexLayer* layer) : LLTexLayerParam(layer), - mCachedProcessedImageGL(NULL), + mCachedProcessedTexture(NULL), mNeedsCreateTexture(FALSE), mStaticImageInvalid(FALSE), mAvgDistortionVec(1.f, 1.f, 1.f), @@ -115,7 +115,7 @@ LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLTexLayer* layer) : LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLVOAvatar* avatar) : LLTexLayerParam(avatar), - mCachedProcessedImageGL(NULL), + mCachedProcessedTexture(NULL), mNeedsCreateTexture(FALSE), mStaticImageInvalid(FALSE), mAvgDistortionVec(1.f, 1.f, 1.f), @@ -134,7 +134,7 @@ LLTexLayerParamAlpha::~LLTexLayerParamAlpha() void LLTexLayerParamAlpha::deleteCaches() { mStaticImageTGA = NULL; // deletes image - mCachedProcessedImageGL = NULL; + mCachedProcessedTexture = NULL; mStaticImageRaw = NULL; mNeedsCreateTexture = FALSE; } @@ -266,22 +266,22 @@ BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height) const S32 image_tga_width = mStaticImageTGA->getWidth(); const S32 image_tga_height = mStaticImageTGA->getHeight(); - if (!mCachedProcessedImageGL || - (mCachedProcessedImageGL->getWidth() != image_tga_width) || - (mCachedProcessedImageGL->getHeight() != image_tga_height) || + if (!mCachedProcessedTexture || + (mCachedProcessedTexture->getWidth() != image_tga_width) || + (mCachedProcessedTexture->getHeight() != image_tga_height) || (weight_changed)) { // llinfos << "Building Cached Alpha: " << mName << ": (" << mStaticImageRaw->getWidth() << ", " << mStaticImageRaw->getHeight() << ") " << effective_weight << llendl; mCachedEffectiveWeight = effective_weight; - if (!mCachedProcessedImageGL) + if (!mCachedProcessedTexture) { - mCachedProcessedImageGL = new LLImageGL(image_tga_width, image_tga_height, 1, FALSE); + mCachedProcessedTexture = LLViewerTextureManager::getLocalTexture(image_tga_width, image_tga_height, 1, FALSE); // We now have something in one of our caches - LLTexLayerSet::sHasCaches |= mCachedProcessedImageGL ? TRUE : FALSE; + LLTexLayerSet::sHasCaches |= mCachedProcessedTexture ? TRUE : FALSE; - mCachedProcessedImageGL->setExplicitFormat(GL_ALPHA8, GL_ALPHA); + mCachedProcessedTexture->setExplicitFormat(GL_ALPHA8, GL_ALPHA); } // Applies domain and effective weight to data as it is decoded. Also resizes the raw image if needed. @@ -291,20 +291,20 @@ BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height) mNeedsCreateTexture = TRUE; } - if (mCachedProcessedImageGL) + if (mCachedProcessedTexture) { { // Create the GL texture, and then hang onto it for future use. if (mNeedsCreateTexture) { - mCachedProcessedImageGL->createGLTexture(0, mStaticImageRaw); + mCachedProcessedTexture->createGLTexture(0, mStaticImageRaw); mNeedsCreateTexture = FALSE; - gGL.getTexUnit(0)->bind(mCachedProcessedImageGL); - mCachedProcessedImageGL->setAddressMode(LLTexUnit::TAM_CLAMP); + gGL.getTexUnit(0)->bind(mCachedProcessedTexture); + mCachedProcessedTexture->setAddressMode(LLTexUnit::TAM_CLAMP); } LLGLSNoAlphaTest gls_no_alpha_test; - gGL.getTexUnit(0)->bind(mCachedProcessedImageGL); + gGL.getTexUnit(0)->bind(mCachedProcessedTexture); gl_rect_2d_simple_tex(width, height); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); stop_glerror(); @@ -315,7 +315,7 @@ BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height) // (It's not really a "cache" in that case, but the logic is the same) if (mAvatar->isSelf()) { - mCachedProcessedImageGL = NULL; + mCachedProcessedTexture = NULL; } } else diff --git a/indra/newview/lltexlayerparams.h b/indra/newview/lltexlayerparams.h index 8c01738317..49feb01b5e 100644 --- a/indra/newview/lltexlayerparams.h +++ b/indra/newview/lltexlayerparams.h @@ -80,7 +80,7 @@ public: BOOL getMultiplyBlend() const; private: - LLPointer mCachedProcessedImageGL; + LLPointer mCachedProcessedTexture; LLPointer mStaticImageTGA; LLPointer mStaticImageRaw; BOOL mNeedsCreateTexture; diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 243ac7803e..211a441d64 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -37,13 +37,13 @@ #include "llrender.h" #include "llagent.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llcheckboxctrl.h" #include "llcombobox.h" #include "llbutton.h" #include "lldraghandle.h" #include "llfocusmgr.h" -#include "llviewerimage.h" +#include "llviewertexture.h" #include "llfolderview.h" #include "llfoldervieweventlistener.h" #include "llinventory.h" @@ -146,7 +146,7 @@ public: void onTextureSelect( const LLTextureEntry& te ); protected: - LLPointer mTexturep; + LLPointer mTexturep; LLTextureCtrl* mOwner; LLUUID mImageAssetID; // Currently selected texture @@ -263,9 +263,9 @@ void LLFloaterTexturePicker::updateImageStats() if (mTexturep.notNull()) { //RN: have we received header data for this image? - if (mTexturep->getWidth(0) > 0 && mTexturep->getHeight(0) > 0) + if (mTexturep->getFullWidth() > 0 && mTexturep->getFullHeight() > 0) { - std::string formatted_dims = llformat("%d x %d", mTexturep->getWidth(0),mTexturep->getHeight(0)); + std::string formatted_dims = llformat("%d x %d", mTexturep->getFullWidth(),mTexturep->getFullHeight()); mResolutionLabel->setTextArg("[DIMENSIONS]", formatted_dims); } else @@ -532,13 +532,13 @@ void LLFloaterTexturePicker::draw() mTexturep = NULL; if(mImageAssetID.notNull()) { - mTexturep = gImageList.getImage(mImageAssetID, MIPMAP_YES, IMMEDIATE_NO); - mTexturep->setBoostLevel(LLViewerImage::BOOST_PREVIEW); + mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID, MIPMAP_YES, IMMEDIATE_NO); + mTexturep->setBoostLevel(LLViewerTexture::BOOST_PREVIEW); } else if (!mFallbackImageName.empty()) { - mTexturep = gImageList.getImageFromFile(mFallbackImageName); - mTexturep->setBoostLevel(LLViewerImage::BOOST_PREVIEW); + mTexturep = LLViewerTextureManager::getFetchedTextureFromFile(mFallbackImageName); + mTexturep->setBoostLevel(LLViewerTexture::BOOST_PREVIEW); } if (mTentativeLabel) @@ -1191,14 +1191,14 @@ void LLTextureCtrl::draw() } else if (!mImageAssetID.isNull()) { - mTexturep = gImageList.getImage(mImageAssetID, MIPMAP_YES, IMMEDIATE_NO); - mTexturep->setBoostLevel(LLViewerImage::BOOST_PREVIEW); + mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID, MIPMAP_YES, IMMEDIATE_NO); + mTexturep->setBoostLevel(LLViewerTexture::BOOST_PREVIEW); } else if (!mFallbackImageName.empty()) { // Show fallback image. - mTexturep = gImageList.getImageFromFile(mFallbackImageName); - mTexturep->setBoostLevel(LLViewerImage::BOOST_PREVIEW); + mTexturep = LLViewerTextureManager::getFetchedTextureFromFile(mFallbackImageName); + mTexturep->setBoostLevel(LLViewerTexture::BOOST_PREVIEW); } // Border diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index ebe2cd2e5f..e30cdb2e97 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -45,7 +45,7 @@ class LLButton; class LLFloaterTexturePicker; class LLInventoryItem; -class LLViewerImage; +class LLViewerTexture; // used for setting drag & drop callbacks. typedef boost::function drag_n_drop_callback; @@ -189,7 +189,7 @@ private: drag_n_drop_callback mDropCallback; commit_callback_t mOnCancelCallback; commit_callback_t mOnSelectCallback; - LLPointer mTexturep; + LLPointer mTexturep; LLUIColor mBorderColor; LLUUID mImageItemID; LLUUID mImageAssetID; diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index be535761fc..63af170fa9 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -44,8 +44,8 @@ #include "llagent.h" #include "lltexturecache.h" -#include "llviewerimagelist.h" -#include "llviewerimage.h" +#include "llviewertexturelist.h" +#include "llviewertexture.h" #include "llviewerregion.h" ////////////////////////////////////////////////////////////////////////////// @@ -469,8 +469,8 @@ void LLTextureFetchWorker::clearPackets() U32 LLTextureFetchWorker::calcWorkPriority() { -// llassert_always(mImagePriority >= 0 && mImagePriority <= LLViewerImage::maxDecodePriority()); - F32 priority_scale = (F32)LLWorkerThread::PRIORITY_LOWBITS / LLViewerImage::maxDecodePriority(); +// llassert_always(mImagePriority >= 0 && mImagePriority <= LLViewerTexture::maxDecodePriority()); + F32 priority_scale = (F32)LLWorkerThread::PRIORITY_LOWBITS / LLViewerFetchedTexture::maxDecodePriority(); mWorkPriority = (U32)(mImagePriority * priority_scale); return mWorkPriority; } @@ -512,7 +512,7 @@ void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size) void LLTextureFetchWorker::setImagePriority(F32 priority) { -// llassert_always(priority >= 0 && priority <= LLViewerImage::maxDecodePriority()); +// llassert_always(priority >= 0 && priority <= LLViewerTexture::maxDecodePriority()); F32 delta = fabs(priority - mImagePriority); if (delta > (mImagePriority * .05f) || mState == DONE) { @@ -542,7 +542,7 @@ void LLTextureFetchWorker::startWork(S32 param) llassert(mFormattedImage.isNull()); } -#include "llviewerimagelist.h" // debug +#include "llviewertexturelist.h" // debug // Called from LLWorkerThread::processRequest() bool LLTextureFetchWorker::doWork(S32 param) @@ -796,7 +796,7 @@ bool LLTextureFetchWorker::doWork(S32 param) mFormattedImage->deleteData(); #endif mRequestedSize -= cur_size; - // F32 priority = mImagePriority / (F32)LLViewerImage::maxDecodePriority(); // 0-1 + // F32 priority = mImagePriority / (F32)LLViewerTexture::maxDecodePriority(); // 0-1 S32 offset = cur_size; mBufferSize = cur_size; // This will get modified by callbackHttpGet() std::string url; diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index 282fbb6481..97719a9468 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -38,7 +38,7 @@ #include "lluuid.h" #include "llworkerthread.h" -class LLViewerImage; +class LLViewerTexture; class LLTextureFetchWorker; class LLTextureCache; class LLHost; diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index 44cd8f0371..70a8ab9f61 100644 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -49,8 +49,8 @@ #include "lltexturecache.h" #include "lltexturefetch.h" #include "llviewerobject.h" -#include "llviewerimage.h" -#include "llviewerimagelist.h" +#include "llviewertexture.h" +#include "llviewertexturelist.h" #include "llappviewer.h" extern F32 texmem_lower_bound_scale; @@ -58,7 +58,7 @@ extern F32 texmem_lower_bound_scale; LLTextureView *gTextureView = NULL; //static -std::set LLTextureView::sDebugImages; +std::set LLTextureView::sDebugImages; //////////////////////////////////////////////////////////////////////////// @@ -79,7 +79,7 @@ static S32 texture_bar_height = 8; class LLTextureBar : public LLView { public: - LLPointer mImagep; + LLPointer mImagep; S32 mHilite; public: @@ -109,8 +109,8 @@ public: { LLTextureBar* bar1p = (LLTextureBar*)i1; LLTextureBar* bar2p = (LLTextureBar*)i2; - LLViewerImage *i1p = bar1p->mImagep; - LLViewerImage *i2p = bar2p->mImagep; + LLViewerFetchedTexture *i1p = bar1p->mImagep; + LLViewerFetchedTexture *i2p = bar2p->mImagep; F32 pri1 = i1p->getDecodePriority(); // i1p->mRequestedDownloadPriority F32 pri2 = i2p->getDecodePriority(); // i2p->mRequestedDownloadPriority if (pri1 > pri2) @@ -128,10 +128,10 @@ public: { LLTextureBar* bar1p = (LLTextureBar*)i1; LLTextureBar* bar2p = (LLTextureBar*)i2; - LLViewerImage *i1p = bar1p->mImagep; - LLViewerImage *i2p = bar2p->mImagep; - U32 pri1 = i1p->mFetchPriority; - U32 pri2 = i2p->mFetchPriority; + LLViewerFetchedTexture *i1p = bar1p->mImagep; + LLViewerFetchedTexture *i2p = bar2p->mImagep; + U32 pri1 = i1p->getFetchPriority() ; + U32 pri2 = i2p->getFetchPriority() ; if (pri1 > pri2) return true; else if (pri2 > pri1) @@ -315,10 +315,10 @@ void LLTextureBar::draw() pip_x += pip_width + pip_space; // we don't want to show bind/resident pips for textures using the default texture - if (mImagep->getHasGLTexture()) + if (mImagep->hasValidGLTexture()) { // Draw the bound pip - last_event = mImagep->sLastFrameTime - mImagep->mLastBindTime; + last_event = mImagep->getTimePassedSinceLastBound(); if (last_event < 1.f) { clr = mImagep->getMissed() ? LLColor4::red : LLColor4::magenta1; @@ -342,7 +342,7 @@ void LLTextureBar::draw() // draw the image size at the end { std::string num_str = llformat("%3dx%3d (%d) %7d", mImagep->getWidth(), mImagep->getHeight(), - mImagep->getDiscardLevel(), mImagep->mTextureMemory); + mImagep->getDiscardLevel(), mImagep->hasGLTexture() ? mImagep->getTextureMemory() : 0); LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, title_x4, getRect().getHeight(), color, LLFontGL::LEFT, LLFontGL::TOP); } @@ -400,13 +400,13 @@ private: void LLGLTexMemBar::draw() { - S32 bound_mem = BYTES_TO_MEGA_BYTES(LLViewerImage::sBoundTextureMemoryInBytes); - S32 max_bound_mem = LLViewerImage::sMaxBoundTextureMemInMegaBytes; - S32 total_mem = BYTES_TO_MEGA_BYTES(LLViewerImage::sTotalTextureMemoryInBytes); - S32 max_total_mem = LLViewerImage::sMaxTotalTextureMemInMegaBytes; - F32 discard_bias = LLViewerImage::sDesiredDiscardBias; + S32 bound_mem = BYTES_TO_MEGA_BYTES(LLViewerTexture::sBoundTextureMemoryInBytes); + S32 max_bound_mem = LLViewerTexture::sMaxBoundTextureMemInMegaBytes; + S32 total_mem = BYTES_TO_MEGA_BYTES(LLViewerTexture::sTotalTextureMemoryInBytes); + S32 max_total_mem = LLViewerTexture::sMaxTotalTextureMemInMegaBytes; + F32 discard_bias = LLViewerTexture::sDesiredDiscardBias; S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f); - S32 h_offset = (S32)((texture_bar_height + 2.8f) * mTextureView->mNumTextureBars); + S32 h_offset = (S32)((texture_bar_height + 2.5f) * mTextureView->mNumTextureBars + 2.5f); //---------------------------------------------------------------------------- LLGLSUIDefault gls_ui; F32 text_color[] = {1.f, 1.f, 1.f, 0.75f}; @@ -477,14 +477,14 @@ void LLGLTexMemBar::draw() //---------------------------------------------------------------------------- text = llformat("Textures: Count: %d Fetch: %d(%d) Pkts:%d(%d) Cache R/W: %d/%d LFS:%d IW:%d(%d) RAW:%d mRaw:%d mAux:%d CB:%d", - gImageList.getNumImages(), + gTextureList.getNumImages(), LLAppViewer::getTextureFetch()->getNumRequests(), LLAppViewer::getTextureFetch()->getNumDeletes(), LLAppViewer::getTextureFetch()->mPacketCount, LLAppViewer::getTextureFetch()->mBadPacketCount, LLAppViewer::getTextureCache()->getNumReads(), LLAppViewer::getTextureCache()->getNumWrites(), LLLFSThread::sLocal->getPending(), LLImageWorker::sCount, LLImageWorker::getWorkerThread()->getNumDeletes(), - LLImageRaw::sRawImageCount, LLViewerImage::sRawCount, LLViewerImage::sAuxCount, - gImageList.mCallbackList.size()); + LLImageRaw::sRawImageCount, LLViewerFetchedTexture::sRawCount, LLViewerFetchedTexture::sAuxCount, + gTextureList.mCallbackList.size()); LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, h_offset + line_height*2, text_color, LLFontGL::LEFT, LLFontGL::TOP); @@ -557,7 +557,7 @@ LLTextureView::~LLTextureView() mGLTexMemBar = 0; } -typedef std::pair decode_pair_t; +typedef std::pair decode_pair_t; struct compare_decode_pair { bool operator()(const decode_pair_t& a, const decode_pair_t& b) @@ -587,18 +587,19 @@ void LLTextureView::draw() llinfos << "ID\tMEM\tBOOST\tPRI\tWIDTH\tHEIGHT\tDISCARD" << llendl; } - for (LLViewerImageList::image_priority_list_t::iterator iter = gImageList.mImageList.begin(); - iter != gImageList.mImageList.end(); ) + for (LLViewerTextureList::image_priority_list_t::iterator iter = gTextureList.mImageList.begin(); + iter != gTextureList.mImageList.end(); ) { - LLPointer imagep = *iter++; + LLPointer imagep = *iter++; S32 cur_discard = imagep->getDiscardLevel(); S32 desired_discard = imagep->mDesiredDiscardLevel; if (mPrintList) { + S32 tex_mem = imagep->hasGLTexture() ? imagep->getTextureMemory() : 0 ; llinfos << imagep->getID() - << "\t" << imagep->mTextureMemory + << "\t" << tex_mem << "\t" << imagep->getBoostLevel() << "\t" << imagep->getDecodePriority() << "\t" << imagep->getWidth() @@ -643,8 +644,8 @@ void LLTextureView::draw() { struct f : public LLSelectedTEFunctor { - LLViewerImage* mImage; - f(LLViewerImage* image) : mImage(image) {} + LLViewerFetchedTexture* mImage; + f(LLViewerFetchedTexture* image) : mImage(image) {} virtual bool apply(LLViewerObject* object, S32 te) { return (mImage == object->getTEImage(te)); @@ -705,7 +706,7 @@ void LLTextureView::draw() for (display_list_t::iterator iter = display_image_list.begin(); iter != display_image_list.end(); iter++) { - LLViewerImage* imagep = iter->second; + LLViewerFetchedTexture* imagep = iter->second; S32 hilite = 0; F32 pri = iter->first; if (pri >= 1 * HIGH_PRIORITY) @@ -735,7 +736,7 @@ void LLTextureView::draw() reshape(getRect().getWidth(), getRect().getHeight(), TRUE); /* - count = gImageList.getNumImages(); + count = gTextureList.getNumImages(); std::string info_string; info_string = llformat("Global Info:\nTexture Count: %d", count); mInfoTextp->setText(info_string); @@ -757,7 +758,7 @@ void LLTextureView::draw() } -BOOL LLTextureView::addBar(LLViewerImage *imagep, S32 hilite) +BOOL LLTextureView::addBar(LLViewerFetchedTexture *imagep, S32 hilite) { llassert(imagep); diff --git a/indra/newview/lltextureview.h b/indra/newview/lltextureview.h index 99b6db9662..20be17aef4 100644 --- a/indra/newview/lltextureview.h +++ b/indra/newview/lltextureview.h @@ -35,7 +35,7 @@ #include "llcontainerview.h" -class LLViewerImage; +class LLViewerFetchedTexture; class LLTextureBar; class LLGLTexMemBar; @@ -54,12 +54,12 @@ public: /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent); - static void addDebugImage(LLViewerImage* image) { sDebugImages.insert(image); } - static void removeDebugImage(LLViewerImage* image) { sDebugImages.insert(image); } + static void addDebugImage(LLViewerFetchedTexture* image) { sDebugImages.insert(image); } + static void removeDebugImage(LLViewerFetchedTexture* image) { sDebugImages.insert(image); } static void clearDebugImages() { sDebugImages.clear(); } private: - BOOL addBar(LLViewerImage *image, BOOL hilight = FALSE); + BOOL addBar(LLViewerFetchedTexture *image, BOOL hilight = FALSE); void removeAllBars(); private: @@ -75,7 +75,7 @@ private: LLGLTexMemBar* mGLTexMemBar; public: - static std::set sDebugImages; + static std::set sDebugImages; }; extern LLTextureView *gTextureView; diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 72ed8f8108..3a7ef4dfc9 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -59,7 +59,7 @@ #include "lltoolmgr.h" #include "lltrans.h" #include "llui.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerinventory.h" #include "llviewerobject.h" #include "llviewerobjectlist.h" @@ -1146,7 +1146,7 @@ void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj, { return; } - LLViewerImage* image = gImageList.getImage(asset_id); + LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id); LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT ); S32 num_faces = hit_obj->getNumTEs(); for( S32 face = 0; face < num_faces; face++ ) @@ -1164,7 +1164,7 @@ void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj, void LLToolDragAndDrop::dropTextureOneFaceAvatar(LLVOAvatar* avatar, S32 hit_face, LLInventoryItem* item) { if (hit_face == -1) return; - LLViewerImage* image = gImageList.getImage(item->getAssetUUID()); + LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(item->getAssetUUID()); avatar->userSetOptionalTE( hit_face, image); } @@ -1189,7 +1189,7 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj, return; } // update viewer side image in anticipation of update from simulator - LLViewerImage* image = gImageList.getImage(asset_id); + LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id); LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT ); hit_obj->setTEImage(hit_face, image); dialog_refresh_all(); diff --git a/indra/newview/lltoolgun.cpp b/indra/newview/lltoolgun.cpp index 3dc0ea646a..b70cff3869 100644 --- a/indra/newview/lltoolgun.cpp +++ b/indra/newview/lltoolgun.cpp @@ -42,7 +42,7 @@ #include "llresmgr.h" #include "llfontgl.h" #include "llui.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewercamera.h" #include "llhudmanager.h" #include "lltoolmgr.h" diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp index af0d784a3e..ae3f2f55de 100644 --- a/indra/newview/lltoolmorph.cpp +++ b/indra/newview/lltoolmorph.cpp @@ -58,7 +58,7 @@ #include "lltoolmgr.h" #include "llui.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerobject.h" #include "llviewerwindow.h" #include "llvoavatarself.h" @@ -81,7 +81,7 @@ LLVisualParamHint::LLVisualParamHint( LLViewerVisualParam *param, F32 param_weight) : - LLDynamicTexture(width, height, 3, LLDynamicTexture::ORDER_MIDDLE, TRUE ), + LLViewerDynamicTexture(width, height, 3, LLViewerDynamicTexture::ORDER_MIDDLE, TRUE ), mNeedsUpdate( TRUE ), mIsVisible( FALSE ), mJointMesh( mesh ), @@ -155,7 +155,7 @@ void LLVisualParamHint::preRender(BOOL clear_depth) avatarp->updateGeometry(avatarp->mDrawable); avatarp->updateLOD(); - LLDynamicTexture::preRender(clear_depth); + LLViewerDynamicTexture::preRender(clear_depth); } //----------------------------------------------------------------------------- @@ -169,7 +169,7 @@ BOOL LLVisualParamHint::render() glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); - glOrtho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f); + glOrtho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f); glMatrixMode(GL_MODELVIEW); glPushMatrix(); @@ -177,7 +177,7 @@ BOOL LLVisualParamHint::render() LLGLSUIDefault gls_ui; //LLGLState::verify(TRUE); - mBackgroundp->draw(0, 0, mWidth, mHeight); + mBackgroundp->draw(0, 0, mFullWidth, mFullHeight); glMatrixMode(GL_PROJECTION); glPopMatrix(); @@ -224,13 +224,13 @@ BOOL LLVisualParamHint::render() gGL.flush(); - LLViewerCamera::getInstance()->setAspect((F32)mWidth / (F32)mHeight); + LLViewerCamera::getInstance()->setAspect((F32)mFullWidth / (F32)mFullHeight); LLViewerCamera::getInstance()->setOriginAndLookAt( camera_pos, // camera LLVector3(0.f, 0.f, 1.f), // up target_pos ); // point of interest - LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mWidth, mHeight, FALSE); + LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE); if (avatarp->mDrawable.notNull()) { @@ -244,7 +244,7 @@ BOOL LLVisualParamHint::render() } avatarp->setVisualParamWeight(mVisualParam, mLastParamWeight); gGL.color4f(1,1,1,1); - mTexture->setGLTextureCreated(true); + mGLTexturep->setGLTextureCreated(true); return TRUE; } @@ -256,7 +256,7 @@ void LLVisualParamHint::draw() { if (!mIsVisible) return; - gGL.getTexUnit(0)->bind(getTexture()); + gGL.getTexUnit(0)->bind(this); gGL.color4f(1.f, 1.f, 1.f, 1.f); @@ -264,13 +264,13 @@ void LLVisualParamHint::draw() gGL.begin(LLRender::QUADS); { gGL.texCoord2i(0, 1); - gGL.vertex2i(0, mHeight); + gGL.vertex2i(0, mFullHeight); gGL.texCoord2i(0, 0); gGL.vertex2i(0, 0); gGL.texCoord2i(1, 0); - gGL.vertex2i(mWidth, 0); + gGL.vertex2i(mFullWidth, 0); gGL.texCoord2i(1, 1); - gGL.vertex2i(mWidth, mHeight); + gGL.vertex2i(mFullWidth, mFullHeight); } gGL.end(); @@ -280,7 +280,7 @@ void LLVisualParamHint::draw() //----------------------------------------------------------------------------- // LLVisualParamReset() //----------------------------------------------------------------------------- -LLVisualParamReset::LLVisualParamReset() : LLDynamicTexture(1, 1, 1, ORDER_RESET, FALSE) +LLVisualParamReset::LLVisualParamReset() : LLViewerDynamicTexture(1, 1, 1, ORDER_RESET, FALSE) { } diff --git a/indra/newview/lltoolmorph.h b/indra/newview/lltoolmorph.h index 11de8160eb..b7df718ba2 100644 --- a/indra/newview/lltoolmorph.h +++ b/indra/newview/lltoolmorph.h @@ -42,7 +42,7 @@ #include "llstrider.h" #include "llviewervisualparam.h" #include "llframetimer.h" -#include "llviewerimage.h" +#include "llviewertexture.h" class LLViewerJointMesh; class LLPolyMesh; @@ -51,17 +51,18 @@ class LLViewerObject; //----------------------------------------------------------------------------- // LLVisualParamHint //----------------------------------------------------------------------------- -class LLVisualParamHint -: public LLDynamicTexture +class LLVisualParamHint : public LLViewerDynamicTexture { +protected: + virtual ~LLVisualParamHint(); + public: LLVisualParamHint( S32 pos_x, S32 pos_y, S32 width, S32 height, LLViewerJointMesh *mesh, LLViewerVisualParam *param, - F32 param_weight); - virtual ~LLVisualParamHint(); + F32 param_weight); BOOL needsRender(); void preRender(BOOL clear_depth); @@ -94,13 +95,15 @@ protected: LLUIImagePtr mBackgroundp; - typedef std::set instance_list_t; + typedef std::set< LLVisualParamHint* > instance_list_t; static instance_list_t sInstances; }; // this class resets avatar data at the end of an update cycle -class LLVisualParamReset : public LLDynamicTexture +class LLVisualParamReset : public LLViewerDynamicTexture { +protected: + /*virtual */ ~LLVisualParamReset(){} public: LLVisualParamReset(); /*virtual */ BOOL render(); diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 0a71c14120..30c97cdfa3 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -49,7 +49,7 @@ #include "llsky.h" #include "llvieweraudio.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerthrottle.h" #include "llviewerwindow.h" #include "llvoavatarself.h" @@ -212,7 +212,7 @@ static bool handleMaxPartCountChanged(const LLSD& newvalue) static bool handleVideoMemoryChanged(const LLSD& newvalue) { - gImageList.updateMaxResidentTexMem(newvalue.asInteger()); + gTextureList.updateMaxResidentTexMem(newvalue.asInteger()); return true; } diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index a340514e3b..c4ed4db3e2 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -48,7 +48,6 @@ #include "llfirstuse.h" #include "llhudmanager.h" #include "llimagebmp.h" -#include "llimagegl.h" #include "llmemory.h" #include "llselectmgr.h" #include "llsky.h" @@ -74,7 +73,7 @@ #include "llviewershadermgr.h" #include "llfasttimer.h" #include "llfloatertools.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llfocusmgr.h" #include "llcubemap.h" #include "llviewerregion.h" @@ -84,9 +83,9 @@ #include "llwaterparammanager.h" #include "llpostprocess.h" -extern LLPointer gStartImageGL; +extern LLPointer gStartTexture; -LLPointer gDisconnectedImagep = NULL; +LLPointer gDisconnectedImagep = NULL; // used to toggle renderer back on after teleport const F32 TELEPORT_RENDER_DELAY = 20.f; // Max time a teleport is allowed to take before we raise the curtain @@ -136,7 +135,7 @@ void display_startup() if (frame_count++ > 1) // make sure we have rendered a frame first { - LLDynamicTexture::updateAllInstances(); + LLViewerDynamicTexture::updateAllInstances(); } LLGLState::checkStates(); @@ -383,7 +382,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) gAgent.setTeleportState( LLAgent::TELEPORT_ARRIVING ); gAgent.setTeleportMessage( LLAgent::sTeleportProgressMessages["arriving"]); - gImageList.mForceResetTextureStats = TRUE; + gTextureList.mForceResetTextureStats = TRUE; gAgent.resetView(TRUE, TRUE); break; @@ -506,7 +505,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) { LLAppViewer::instance()->pingMainloopTimeout("Display:DynamicTextures"); LLFastTimer t(LLFastTimer::FTM_UPDATE_TEXTURES); - if (LLDynamicTexture::updateAllInstances()) + if (LLViewerDynamicTexture::updateAllInstances()) { gGL.setColorMask(true, true); glClear(GL_DEPTH_BUFFER_BIT); @@ -690,13 +689,13 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) LLMemType mt_iu(LLMemType::MTYPE_DISPLAY_IMAGE_UPDATE); LLFastTimer t(LLFastTimer::FTM_IMAGE_UPDATE); - LLViewerImage::updateClass(LLViewerCamera::getInstance()->getVelocityStat()->getMean(), + LLViewerTexture::updateClass(LLViewerCamera::getInstance()->getVelocityStat()->getMean(), LLViewerCamera::getInstance()->getAngularVelocityStat()->getMean()); - gBumpImageList.updateImages(); // must be called before gImageList version so that it's textures are thrown out first. + gBumpImageList.updateImages(); // must be called before gTextureList version so that it's textures are thrown out first. const F32 max_image_decode_time = llmin(0.005f, 0.005f*10.f*gFrameIntervalSeconds); // 50 ms/second decode time (no more than 5ms/frame) - gImageList.updateImages(max_image_decode_time); + gTextureList.updateImages(max_image_decode_time); stop_glerror(); } llpushcallstacks ; @@ -1279,8 +1278,7 @@ void render_disconnected_background() //llinfos << "Bitmap load failed" << llendl; return; } - - gDisconnectedImagep = new LLImageGL( FALSE ); + LLPointer raw = new LLImageRaw; if (!image_bmp->decode(raw, 0.0f)) { @@ -1306,8 +1304,8 @@ void render_disconnected_background() raw->expandToPowerOfTwo(); - gDisconnectedImagep->createGLTexture(0, raw); - gStartImageGL = gDisconnectedImagep; + gDisconnectedImagep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE ); + gStartTexture = gDisconnectedImagep; gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index b6f0dafae6..8fbb59bc74 100644 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp @@ -52,7 +52,7 @@ #include "lltexlayer.h" #include "llviewercamera.h" #include "llviewercontrol.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerjointmesh.h" #include "llvoavatar.h" #include "llsky.h" @@ -230,7 +230,7 @@ void LLViewerJointMesh::setColor( F32 red, F32 green, F32 blue, F32 alpha ) //-------------------------------------------------------------------- // LLViewerJointMesh::getTexture() //-------------------------------------------------------------------- -//LLViewerImage *LLViewerJointMesh::getTexture() +//LLViewerTexture *LLViewerJointMesh::getTexture() //{ // return mTexture; //} @@ -238,7 +238,7 @@ void LLViewerJointMesh::setColor( F32 red, F32 green, F32 blue, F32 alpha ) //-------------------------------------------------------------------- // LLViewerJointMesh::setTexture() //-------------------------------------------------------------------- -void LLViewerJointMesh::setTexture( LLViewerImage *texture ) +void LLViewerJointMesh::setTexture( LLViewerTexture *texture ) { mTexture = texture; @@ -557,7 +557,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) { if( mLayerSet->hasComposite() ) { - gGL.getTexUnit(0)->bind(mLayerSet->getComposite()->getTexture()); + gGL.getTexUnit(0)->bind(mLayerSet->getComposite()); } else { @@ -567,19 +567,22 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) { llwarns << "Layerset without composite" << llendl; } - gGL.getTexUnit(0)->bind(gImageList.getImage(IMG_DEFAULT)); + gGL.getTexUnit(0)->bind(LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT)); } } else if ( !is_dummy && mTexture.notNull() ) { - old_mode = mTexture->getAddressMode(); - gGL.getTexUnit(0)->bind(mTexture.get()); + if(mTexture->hasGLTexture()) + { + old_mode = mTexture->getAddressMode(); + } + gGL.getTexUnit(0)->bind(mTexture); gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); } else { - gGL.getTexUnit(0)->bind(gImageList.getImage(IMG_DEFAULT_AVATAR)); + gGL.getTexUnit(0)->bind(LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR)); } if (gRenderForSelect) @@ -633,7 +636,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) if (mTexture.notNull() && !is_dummy) { - gGL.getTexUnit(0)->bind(mTexture.get()); + gGL.getTexUnit(0)->bind(mTexture); gGL.getTexUnit(0)->setTextureAddressMode(old_mode); } diff --git a/indra/newview/llviewerjointmesh.h b/indra/newview/llviewerjointmesh.h index 0cae48df93..0248502789 100644 --- a/indra/newview/llviewerjointmesh.h +++ b/indra/newview/llviewerjointmesh.h @@ -34,7 +34,7 @@ #define LL_LLVIEWERJOINTMESH_H #include "llviewerjoint.h" -#include "llviewerimage.h" +#include "llviewertexture.h" #include "llpolymesh.h" #include "v4color.h" #include "llapr.h" @@ -72,7 +72,7 @@ protected: LLColor4 mColor; // color value // LLColor4 mSpecular; // specular color (always white for now) F32 mShiny; // shiny value - LLPointer mTexture; // ptr to a global texture + LLPointer mTexture; // ptr to a global texture LLTexLayerSet* mLayerSet; // ptr to a layer set owned by the avatar U32 mTestImageName; // handle to a temporary texture for previewing uploads LLPolyMesh* mMesh; // ptr to a global polymesh @@ -110,7 +110,7 @@ public: void setSpecular( const LLColor4& color, F32 shiny ) { /*mSpecular = color;*/ mShiny = shiny; }; // Sets the shape texture - void setTexture( LLViewerImage *texture ); + void setTexture( LLViewerTexture *texture ); void setTestTexture( U32 name ) { mTestImageName = name; } diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 5d1cb824a2..bfc258506f 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -40,12 +40,12 @@ #include "llmimetypes.h" #include "llviewercontrol.h" -#include "llviewerimage.h" +#include "llviewertexture.h" #include "llviewerparcelmedia.h" #include "llviewerparcelmgr.h" #include "llviewerwindow.h" #include "llversionviewer.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llevent.h" // LLSimpleListener #include "llmediamanager.h" @@ -59,58 +59,58 @@ class LLViewerMediaImpl : public LLMediaObserver { - public: - LLViewerMediaImpl() - : mMediaSource( NULL ), - mMovieImageID(), - mMovieImageHasMips(false) - { } - - void destroyMediaSource(); - - void play(const std::string& media_url, - const std::string& mime_type, - const LLUUID& placeholder_texture_id, - S32 media_width, S32 media_height, U8 media_auto_scale, - U8 media_loop); - - void stop(); - void pause(); - void start(); - void seek(F32 time); - void setVolume(F32 volume); - LLMediaBase::EStatus getStatus(); - - /*virtual*/ void onMediaSizeChange(const EventType& event_in); - /*virtual*/ void onMediaContentsChange(const EventType& event_in); - - void updateMovieImage(const LLUUID& image_id, BOOL active); - void updateImagesMediaStreams(); - LLUUID getMediaTextureID(); - - // Internally set our desired browser user agent string, including - // the Second Life version and skin name. Used because we can - // switch skins without restarting the app. - static void updateBrowserUserAgent(); - - // Callback for when the SkinCurrent control is changed to - // switch the user agent string to indicate the new skin. - static bool handleSkinCurrentChanged(const LLSD& newvalue); - - public: - - // a single media url with some data and an impl. - LLMediaBase* mMediaSource; - LLUUID mMovieImageID; - bool mMovieImageHasMips; - std::string mMediaURL; - std::string mMimeType; - private: - void initializePlaceholderImage(LLViewerImage *placeholder_image, LLMediaBase *media_source); +public: + LLViewerMediaImpl() + : mMediaSource( NULL ), + mMovieImageID(), + mMovieImageHasMips(false) + { } + + void destroyMediaSource(); + + void play(const std::string& media_url, + const std::string& mime_type, + const LLUUID& placeholder_texture_id, + S32 media_width, S32 media_height, U8 media_auto_scale, + U8 media_loop); + + void stop(); + void pause(); + void start(); + void seek(F32 time); + void setVolume(F32 volume); + LLMediaBase::EStatus getStatus(); + + /*virtual*/ void onMediaSizeChange(const EventType& event_in); + /*virtual*/ void onMediaContentsChange(const EventType& event_in); + + void restoreMovieImage(); + void updateImagesMediaStreams(); + LLUUID getMediaTextureID(); + + // Internally set our desired browser user agent string, including + // the Second Life version and skin name. Used because we can + // switch skins without restarting the app. + static void updateBrowserUserAgent(); + + // Callback for when the SkinCurrent control is changed to + // switch the user agent string to indicate the new skin. + static bool handleSkinCurrentChanged(const LLSD& newvalue); + +public: + + // a single media url with some data and an impl. + LLMediaBase* mMediaSource; + LLUUID mMovieImageID; + bool mMovieImageHasMips; + std::string mMediaURL; + std::string mMimeType; + +private: + void initializePlaceholderImage(LLViewerMediaTexture *placeholder_image, LLMediaBase *media_source); }; static LLViewerMediaImpl sViewerMediaImpl; - ////////////////////////////////////////////////////////////////////////////////////////// void LLViewerMediaImpl::destroyMediaSource() @@ -118,12 +118,11 @@ void LLViewerMediaImpl::destroyMediaSource() LLMediaManager* mgr = LLMediaManager::getInstance(); if ( mMediaSource ) { - bool was_playing = LLViewerMedia::isMediaPlaying(); mMediaSource->remObserver(this); mgr->destroySource( mMediaSource ); // Restore the texture - updateMovieImage(LLUUID::null, was_playing); + restoreMovieImage(); } mMediaSource = NULL; @@ -229,49 +228,36 @@ LLMediaBase::EStatus LLViewerMediaImpl::getStatus() } ////////////////////////////////////////////////////////////////////////////////////////// -// static -void LLViewerMediaImpl::updateMovieImage(const LLUUID& uuid, BOOL active) +void LLViewerMediaImpl::restoreMovieImage() { // IF the media image hasn't changed, do nothing - if (mMovieImageID == uuid) + if (mMovieImageID.isNull()) { return; } - // If we have changed media uuid, restore the old one - if (!mMovieImageID.isNull()) - { - LLViewerImage* oldImage = LLViewerImage::getImage( mMovieImageID ); - if (oldImage) - { - oldImage->reinit(mMovieImageHasMips); - oldImage->mIsMediaTexture = FALSE; - } - mMovieImageID.setNull(); - } - // If the movie is playing, set the new media image - if (active && !uuid.isNull()) + + //restore the movie image to the old one + LLViewerMediaTexture* media = LLViewerTextureManager::findMediaTexture( mMovieImageID ) ; + if (media) { - LLViewerImage* viewerImage = LLViewerImage::getImage( uuid ); - if( viewerImage ) + if(media->getOldTexture())//set back to the old texture if it exists { - mMovieImageID = uuid; - // Can't use mipmaps for movies because they don't update the full image - mMovieImageHasMips = viewerImage->getUseMipMaps(); - viewerImage->reinit(FALSE); - viewerImage->mIsMediaTexture = TRUE; + media->switchToTexture(media->getOldTexture()) ; + media->setPlaying(FALSE) ; } + media->reinit(mMovieImageHasMips); } + mMovieImageID.setNull(); } ////////////////////////////////////////////////////////////////////////////////////////// -// static void LLViewerMediaImpl::updateImagesMediaStreams() { LLMediaManager::updateClass(); } -void LLViewerMediaImpl::initializePlaceholderImage(LLViewerImage *placeholder_image, LLMediaBase *media_source) +void LLViewerMediaImpl::initializePlaceholderImage(LLViewerMediaTexture *placeholder_image, LLMediaBase *media_source) { int media_width = media_source->getMediaWidth(); int media_height = media_source->getMediaHeight(); @@ -308,19 +294,14 @@ void LLViewerMediaImpl::initializePlaceholderImage(LLViewerImage *placeholder_im // placeholder_image->setExplicitFormat() placeholder_image->setUseMipMaps(FALSE); - - // MEDIAOPT: set this dynamically on play/stop - placeholder_image->mIsMediaTexture = true; } - - // virtual void LLViewerMediaImpl::onMediaContentsChange(const EventType& event_in) { LLMediaBase* media_source = event_in.getSubject(); - LLViewerImage* placeholder_image = gImageList.getImage( mMovieImageID ); - if ((placeholder_image) && (placeholder_image->getHasGLTexture())) + LLViewerMediaTexture* placeholder_image = LLViewerTextureManager::getMediaTexture( mMovieImageID ) ; + if (placeholder_image && placeholder_image->hasValidGLTexture()) { if (placeholder_image->getUseMipMaps()) { @@ -345,7 +326,7 @@ void LLViewerMediaImpl::onMediaContentsChange(const EventType& event_in) void LLViewerMediaImpl::onMediaSizeChange(const EventType& event_in) { LLMediaBase* media_source = event_in.getSubject(); - LLViewerImage* placeholder_image = gImageList.getImage( mMovieImageID ); + LLViewerMediaTexture* placeholder_image = LLViewerTextureManager::getMediaTexture( mMovieImageID ) ; if (placeholder_image) { initializePlaceholderImage(placeholder_image, media_source); @@ -356,75 +337,6 @@ void LLViewerMediaImpl::onMediaSizeChange(const EventType& event_in) } } - - // Get the image we're using - - /* - // update media stream if required - LLMediaEngine* media_engine = LLMediaEngine::getInstance(); - if (media_engine) - { - if ( media_engine->update() ) - { - LLUUID media_uuid = media_engine->getImageUUID(); - updateMovieImage(media_uuid, TRUE); - if (!media_uuid.isNull()) - { - LLViewerImage* viewerImage = getImage( media_uuid ); - if( viewerImage ) - { - LLMediaBase* renderer = media_engine->getMediaRenderer(); - if ((renderer->getTextureWidth() != viewerImage->getWidth()) || - (renderer->getTextureHeight() != viewerImage->getHeight()) || - (renderer->getTextureDepth() != viewerImage->getComponents()) || - (viewerImage->getHasGLTexture() == FALSE)) - { - // destroy existing GL image - viewerImage->destroyGLTexture(); - - // set new size - viewerImage->setSize( renderer->getTextureWidth(), - renderer->getTextureHeight(), - renderer->getTextureDepth() ); - - LLPointer raw = new LLImageRaw(renderer->getTextureWidth(), - renderer->getTextureHeight(), - renderer->getTextureDepth()); - raw->clear(0x7f,0x7f,0x7f,0xff); - viewerImage->createGLTexture(0, raw); - } - - // Set the explicit format the instance wants - viewerImage->setExplicitFormat(renderer->getTextureFormatInternal(), - renderer->getTextureFormatPrimary(), - renderer->getTextureFormatType(), - renderer->getTextureFormatSwapBytes()); - // This should be redundant, but just in case: - viewerImage->setUseMipMaps(FALSE); - - LLImageRaw* rawImage = media_engine->getImageRaw(); - if ( rawImage ) - { - viewerImage->setSubImage(rawImage, 0, 0, - renderer->getMediaWidth(), - renderer->getMediaHeight()); - } - } - else - { - llwarns << "MediaEngine update unable to get viewer image for GL texture" << llendl; - } - } - } - else - { - LLUUID media_uuid = media_engine->getImageUUID(); - updateMovieImage(media_uuid, FALSE); - } - } - */ - - LLUUID LLViewerMediaImpl::getMediaTextureID() { return mMovieImageID; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index da3c94225b..0bb1bd7857 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -183,7 +183,7 @@ #include "llviewercamera.h" #include "llviewergenericmessage.h" #include "llviewergesture.h" -#include "llviewerimagelist.h" // gImageList +#include "llviewertexturelist.h" // gTextureList #include "llviewerinventory.h" #include "llviewermenufile.h" // init_menu_file() #include "llviewermessage.h" @@ -1155,7 +1155,7 @@ class LLAdvancedToggleDisableTextures : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLViewerImage::sDontLoadVolumeTextures = !LLViewerImage::sDontLoadVolumeTextures; + LLViewerTexture::sDontLoadVolumeTextures = !LLViewerTexture::sDontLoadVolumeTextures; return true; } }; @@ -1164,7 +1164,7 @@ class LLAdvancedCheckDisableTextures : public view_listener_t { bool handleEvent(const LLSD& userdata) { - bool new_value = LLViewerImage::sDontLoadVolumeTextures; // <-- make this using LLCacheControl + bool new_value = LLViewerTexture::sDontLoadVolumeTextures; // <-- make this using LLCacheControl return new_value; } }; @@ -6345,7 +6345,7 @@ void handle_selected_texture_info(void*) { if (!node->isTESelected(i)) continue; - LLViewerImage* img = node->getObject()->getTEImage(i); + LLViewerTexture* img = node->getObject()->getTEImage(i); LLUUID image_id = img->getID(); faces_per_texture[image_id].push_back(i); } @@ -6355,7 +6355,7 @@ void handle_selected_texture_info(void*) { LLUUID image_id = it->first; U8 te = it->second[0]; - LLViewerImage* img = node->getObject()->getTEImage(te); + LLViewerTexture* img = node->getObject()->getTEImage(te); S32 height = img->getHeight(); S32 width = img->getWidth(); S32 components = img->getComponents(); diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 6576ea81ed..e34c47368c 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -47,7 +47,7 @@ #include "llfloaterperms.h" #include "llstatusbar.h" #include "llviewercontrol.h" // gSavedSettings -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "lluictrlfactory.h" #include "llviewerinventory.h" #include "llviewermenu.h" // gMenuHolder @@ -481,7 +481,7 @@ void handle_compress_image(void*) BOOL success; - success = LLViewerImageList::createUploadFile(infile, outfile, IMG_CODEC_TGA); + success = LLViewerTextureList::createUploadFile(infile, outfile, IMG_CODEC_TGA); if (success) { @@ -537,7 +537,7 @@ void upload_new_resource(const std::string& src_filename, std::string name, else if( exten == "bmp") { asset_type = LLAssetType::AT_TEXTURE; - if (!LLViewerImageList::createUploadFile(src_filename, + if (!LLViewerTextureList::createUploadFile(src_filename, filename, IMG_CODEC_BMP )) { @@ -552,7 +552,7 @@ void upload_new_resource(const std::string& src_filename, std::string name, else if( exten == "tga") { asset_type = LLAssetType::AT_TEXTURE; - if (!LLViewerImageList::createUploadFile(src_filename, + if (!LLViewerTextureList::createUploadFile(src_filename, filename, IMG_CODEC_TGA )) { @@ -567,7 +567,7 @@ void upload_new_resource(const std::string& src_filename, std::string name, else if( exten == "jpg" || exten == "jpeg") { asset_type = LLAssetType::AT_TEXTURE; - if (!LLViewerImageList::createUploadFile(src_filename, + if (!LLViewerTextureList::createUploadFile(src_filename, filename, IMG_CODEC_JPEG )) { @@ -582,7 +582,7 @@ void upload_new_resource(const std::string& src_filename, std::string name, else if( exten == "png") { asset_type = LLAssetType::AT_TEXTURE; - if (!LLViewerImageList::createUploadFile(src_filename, + if (!LLViewerTextureList::createUploadFile(src_filename, filename, IMG_CODEC_PNG )) { diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index a96ccfd848..cf3491ef03 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -70,7 +70,7 @@ #include "llrendersphere.h" #include "lltooldraganddrop.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerinventory.h" #include "llviewerobjectlist.h" #include "llviewerparceloverlay.h" @@ -2919,14 +2919,14 @@ void LLViewerObject::boostTexturePriority(BOOL boost_children /* = TRUE */) S32 tex_count = getNumTEs(); for (i = 0; i < tex_count; i++) { - getTEImage(i)->setBoostLevel(LLViewerImage::BOOST_SELECTED); + getTEImage(i)->setBoostLevel(LLViewerTexture::BOOST_SELECTED); } if (isSculpted()) { LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); LLUUID sculpt_id = sculpt_params->getSculptTexture(); - gImageList.getImage(sculpt_id)->setBoostLevel(LLViewerImage::BOOST_SELECTED); + LLViewerTextureManager::getFetchedTexture(sculpt_id, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE)->setBoostLevel(LLViewerTexture::BOOST_SELECTED); } if (boost_children) @@ -3554,8 +3554,8 @@ void LLViewerObject::setNumTEs(const U8 num_tes) { if (num_tes) { - LLPointer *new_images; - new_images = new LLPointer[num_tes]; + LLPointer *new_images; + new_images = new LLPointer[num_tes]; for (i = 0; i < num_tes; i++) { if (i < getNumTEs()) @@ -3689,11 +3689,11 @@ void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry) // if (mDrawable.notNull() && mDrawable->isVisible()) // { const LLUUID& image_id = getTE(te)->getID(); - mTEImages[te] = gImageList.getImage(image_id); + mTEImages[te] = LLViewerTextureManager::getFetchedTexture(image_id, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE); // } } -void LLViewerObject::setTEImage(const U8 te, LLViewerImage *imagep) +void LLViewerObject::setTEImage(const U8 te, LLViewerTexture *imagep) { if (mTEImages[te] != imagep) { @@ -3715,7 +3715,7 @@ S32 LLViewerObject::setTETextureCore(const U8 te, const LLUUID& uuid, LLHost hos uuid == LLUUID::null) { retval = LLPrimitive::setTETexture(te, uuid); - mTEImages[te] = gImageList.getImageFromHost(uuid, host); + mTEImages[te] = LLViewerTextureManager::getFetchedTexture(uuid, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE, 0, 0, host); setChanged(TEXTURE); if (mDrawable.notNull()) { @@ -3726,6 +3726,18 @@ S32 LLViewerObject::setTETextureCore(const U8 te, const LLUUID& uuid, LLHost hos } +void LLViewerObject::changeTEImage(const LLViewerTexture* old_image, LLViewerTexture* new_image) +{ + U32 end = getNumTEs() ; + for (U32 face = 0 ; face < end ; face++) + { + if(old_image == mTEImages[face]) + { + mTEImages[face] = new_image ; + } + } +} + S32 LLViewerObject::setTETexture(const U8 te, const LLUUID& uuid) { // Invalid host == get from the agent's sim @@ -3970,20 +3982,20 @@ S32 LLViewerObject::setTERotation(const U8 te, const F32 r) } -LLViewerImage *LLViewerObject::getTEImage(const U8 face) const +LLViewerTexture *LLViewerObject::getTEImage(const U8 face) const { // llassert(mTEImages); if (face < getNumTEs()) { - LLViewerImage* image = mTEImages[face]; + LLViewerTexture* image = mTEImages[face]; if (image) { return image; } else { - return (LLViewerImage*)((LLImageGL*)LLViewerImage::sDefaultImagep); + return (LLViewerTexture*)(LLViewerFetchedTexture::sDefaultImagep); } } @@ -4104,7 +4116,7 @@ void LLViewerObject::setDebugText(const std::string &utf8text) updateText(); } -void LLViewerObject::setIcon(LLViewerImage* icon_image) +void LLViewerObject::setIcon(LLViewerTexture* icon_image) { if (!mIcon) { @@ -4194,14 +4206,14 @@ void LLViewerObject::setParticleSource(const LLPartSysData& particle_parameters, if (mPartSourcep->getImage()->getID() != mPartSourcep->mPartSysData.mPartImageID) { - LLViewerImage* image; + LLViewerTexture* image; if (mPartSourcep->mPartSysData.mPartImageID == LLUUID::null) { - image = gImageList.getImageFromFile("pixiesmall.tga"); + image = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.tga"); } else { - image = gImageList.getImage(mPartSourcep->mPartSysData.mPartImageID); + image = LLViewerTextureManager::getFetchedTexture(mPartSourcep->mPartSysData.mPartImageID); } mPartSourcep->setImage(image); } @@ -4243,14 +4255,14 @@ void LLViewerObject::unpackParticleSource(const S32 block_num, const LLUUID& own { if (mPartSourcep->getImage()->getID() != mPartSourcep->mPartSysData.mPartImageID) { - LLViewerImage* image; + LLViewerTexture* image; if (mPartSourcep->mPartSysData.mPartImageID == LLUUID::null) { - image = gImageList.getImageFromFile("pixiesmall.j2c"); + image = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c"); } else { - image = gImageList.getImage(mPartSourcep->mPartSysData.mPartImageID); + image = LLViewerTextureManager::getFetchedTexture(mPartSourcep->mPartSysData.mPartImageID); } mPartSourcep->setImage(image); } @@ -4290,14 +4302,14 @@ void LLViewerObject::unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_ { if (mPartSourcep->getImage()->getID() != mPartSourcep->mPartSysData.mPartImageID) { - LLViewerImage* image; + LLViewerTexture* image; if (mPartSourcep->mPartSysData.mPartImageID == LLUUID::null) { - image = gImageList.getImageFromFile("pixiesmall.j2c"); + image = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c"); } else { - image = gImageList.getImage(mPartSourcep->mPartSysData.mPartImageID); + image = LLViewerTextureManager::getFetchedTexture(mPartSourcep->mPartSysData.mPartImageID); } mPartSourcep->setImage(image); } diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 2b2c2d5a95..cda2c5114f 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -68,7 +68,7 @@ class LLPartSysData; class LLPrimitive; class LLPipeline; class LLTextureEntry; -class LLViewerImage; +class LLViewerTexture; class LLViewerInventoryItem; class LLViewerObject; class LLViewerPartSourceScript; @@ -312,8 +312,9 @@ public: /*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags ); /*virtual*/ S32 setTEGlow(const U8 te, const F32 glow); /*virtual*/ BOOL setMaterial(const U8 material); - virtual void setTEImage(const U8 te, LLViewerImage *imagep); // Not derived from LLPrimitive - LLViewerImage *getTEImage(const U8 te) const; + virtual void setTEImage(const U8 te, LLViewerTexture *imagep); // Not derived from LLPrimitive + void changeTEImage(const LLViewerTexture* old_image, LLViewerTexture* new_image) ; + LLViewerTexture *getTEImage(const U8 te) const; void fitFaceTexture(const U8 face); void sendTEUpdate() const; // Sends packed representation of all texture entry information @@ -354,7 +355,7 @@ public: void setCanSelect(BOOL canSelect); void setDebugText(const std::string &utf8text); - void setIcon(LLViewerImage* icon_image); + void setIcon(LLViewerTexture* icon_image); void clearIcon(); void markForUpdate(BOOL priority); @@ -527,7 +528,7 @@ public: // Last total CRC received from sim, used for caching U32 mTotalCRC; - LLPointer *mTEImages; + LLPointer *mTEImages; // Selection, picking and rendering variables U32 mGLName; // GL "name" used by selection code diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 468c9fbb66..8939faeb91 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -66,7 +66,7 @@ #include "lltoolpie.h" #include "llkeyboard.h" #include "u64.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "lldatapacker.h" #ifdef LL_STANDALONE #include @@ -558,7 +558,7 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent) { num_updates = mObjects.count() - mCurLazyUpdateIndex; max_value = mObjects.count(); - gImageList.setUpdateStats(TRUE); + gTextureList.setUpdateStats(TRUE); } else { diff --git a/indra/newview/llviewerparcelmediaautoplay.cpp b/indra/newview/llviewerparcelmediaautoplay.cpp index dbb9c32008..7ba2172c3f 100644 --- a/indra/newview/llviewerparcelmediaautoplay.cpp +++ b/indra/newview/llviewerparcelmediaautoplay.cpp @@ -39,7 +39,7 @@ #include "llviewerparcelmgr.h" #include "lluuid.h" #include "message.h" -#include "llviewerimagelist.h" // for texture stats +#include "llviewertexturelist.h" // for texture stats #include "llagent.h" const F32 AUTOPLAY_TIME = 5; // how many seconds before we autoplay @@ -113,13 +113,13 @@ BOOL LLViewerParcelMediaAutoPlay::tick() { if (this_media_texture_id.notNull()) // and if the media texture is good { - LLViewerImage *image = gImageList.getImage(this_media_texture_id, FALSE); + LLViewerMediaTexture *image = LLViewerTextureManager::getMediaTexture(this_media_texture_id, FALSE) ; F32 image_size = 0; if (image) { - image_size = image->mMaxVirtualSize; + image_size = image->getMaxVirtualSize() ; } if (gAgent.getVelocity().magVec() < AUTOPLAY_SPEED) // and if the agent is stopped (slow enough) diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index dc9b26eedc..a702d3a85d 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -60,8 +60,8 @@ #include "llsdutil.h" #include "llstatusbar.h" #include "llui.h" -#include "llviewerimage.h" -#include "llviewerimagelist.h" +#include "llviewertexture.h" +#include "llviewertexturelist.h" #include "llviewermenu.h" #include "llviewerparcelmedia.h" #include "llviewerparceloverlay.h" @@ -80,8 +80,8 @@ U8* LLViewerParcelMgr::sPackedOverlay = NULL; LLUUID gCurrentMovieID = LLUUID::null; -LLPointer sBlockedImage; -LLPointer sPassImage; +LLPointer sBlockedImage; +LLPointer sPassImage; // Local functions void optionally_start_music(const std::string& music_url); @@ -143,8 +143,8 @@ LLViewerParcelMgr::LLViewerParcelMgr() mCollisionSegments = new U8[(mParcelsPerEdge+1)*(mParcelsPerEdge+1)]; resetSegments(mCollisionSegments); - mBlockedImage = gImageList.getImageFromFile("noentrylines.j2c"); - mPassImage = gImageList.getImageFromFile("noentrypasslines.j2c"); + mBlockedImage = LLViewerTextureManager::getFetchedTextureFromFile("noentrylines.j2c"); + mPassImage = LLViewerTextureManager::getFetchedTextureFromFile("noentrypasslines.j2c"); S32 overlay_size = mParcelsPerEdge * mParcelsPerEdge / PARCEL_OVERLAY_CHUNKS; sPackedOverlay = new U8[overlay_size]; @@ -2382,12 +2382,12 @@ void LLViewerParcelMgr::cleanupGlobals() LLParcelSelection::sNullSelection = NULL; } -LLViewerImage* LLViewerParcelMgr::getBlockedImage() const +LLViewerTexture* LLViewerParcelMgr::getBlockedImage() const { return sBlockedImage; } -LLViewerImage* LLViewerParcelMgr::getPassImage() const +LLViewerTexture* LLViewerParcelMgr::getPassImage() const { return sPassImage; } diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h index dc6c2a6287..427ed4a6f2 100644 --- a/indra/newview/llviewerparcelmgr.h +++ b/indra/newview/llviewerparcelmgr.h @@ -46,7 +46,7 @@ class LLUUID; class LLMessageSystem; class LLParcel; -class LLViewerImage; +class LLViewerTexture; class LLViewerRegion; // Constants for sendLandOwner @@ -291,8 +291,8 @@ private: static bool callbackJoinLand(const LLSD& notification, const LLSD& response); //void finishClaim(BOOL user_to_user_sale, U32 join); - LLViewerImage* getBlockedImage() const; - LLViewerImage* getPassImage() const; + LLViewerTexture* getBlockedImage() const; + LLViewerTexture* getPassImage() const; private: BOOL mSelected; @@ -341,8 +341,8 @@ private: BOOL mRenderSelection; S32 mCollisionBanned; LLFrameTimer mCollisionTimer; - LLImageGL* mBlockedImage; - LLImageGL* mPassImage; + LLViewerTexture* mBlockedImage; + LLViewerTexture* mPassImage; // Media S32 mMediaParcelId; diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp index 2056a4be1b..1a91240abb 100644 --- a/indra/newview/llviewerparceloverlay.cpp +++ b/indra/newview/llviewerparceloverlay.cpp @@ -43,13 +43,13 @@ #include "v2math.h" // newview includes -#include "llviewerimage.h" +#include "llviewertexture.h" #include "llviewercontrol.h" #include "llsurface.h" #include "llviewerregion.h" #include "llagent.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llselectmgr.h" #include "llfloatertools.h" #include "llglheaders.h" @@ -69,10 +69,9 @@ LLViewerParcelOverlay::LLViewerParcelOverlay(LLViewerRegion* region, F32 region_ { // Create a texture to hold color information. // 4 components - // Use mipmaps = FALSE, clamped, NEAREST filter, for sharp edges - mTexture = new LLImageGL(FALSE); + // Use mipmaps = FALSE, clamped, NEAREST filter, for sharp edges mImageRaw = new LLImageRaw(mParcelGridsPerEdge, mParcelGridsPerEdge, OVERLAY_IMG_COMPONENTS); - mTexture->createGLTexture(0, mImageRaw); + mTexture = LLViewerTextureManager::getLocalTexture(mImageRaw.get(), FALSE); gGL.getTexUnit(0)->activate(); gGL.getTexUnit(0)->bind(mTexture); mTexture->setAddressMode(LLTexUnit::TAM_CLAMP); diff --git a/indra/newview/llviewerparceloverlay.h b/indra/newview/llviewerparceloverlay.h index 9bed1dde34..e673b811ed 100644 --- a/indra/newview/llviewerparceloverlay.h +++ b/indra/newview/llviewerparceloverlay.h @@ -39,7 +39,7 @@ #include "lldarray.h" #include "llframetimer.h" #include "lluuid.h" -#include "llviewerimage.h" +#include "llviewertexture.h" class LLViewerRegion; class LLVector3; @@ -53,7 +53,7 @@ public: ~LLViewerParcelOverlay(); // ACCESS - LLImageGL* getTexture() const { return mTexture; } + LLViewerTexture* getTexture() const { return mTexture; } BOOL isOwned(const LLVector3& pos) const; BOOL isOwnedSelf(const LLVector3& pos) const; @@ -99,7 +99,7 @@ private: S32 mParcelGridsPerEdge; - LLPointer mTexture; + LLPointer mTexture; LLPointer mImageRaw; // Size: mParcelGridsPerEdge * mParcelGridsPerEdge diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp index b74f9e9f2c..ec39819bc8 100644 --- a/indra/newview/llviewerpartsim.cpp +++ b/indra/newview/llviewerpartsim.cpp @@ -98,7 +98,7 @@ LLViewerPart::~LLViewerPart() --LLViewerPartSim::sParticleCount2 ; } -void LLViewerPart::init(LLPointer sourcep, LLViewerImage *imagep, LLVPCallback cb) +void LLViewerPart::init(LLPointer sourcep, LLViewerTexture *imagep, LLVPCallback cb) { LLMemType mt(LLMemType::MTYPE_PARTICLES); mPartID = LLViewerPart::sNextPartID; diff --git a/indra/newview/llviewerpartsim.h b/indra/newview/llviewerpartsim.h index 208675e7bf..8f1f72518a 100644 --- a/indra/newview/llviewerpartsim.h +++ b/indra/newview/llviewerpartsim.h @@ -39,10 +39,10 @@ #include "llpartdata.h" #include "llviewerpartsource.h" -class LLViewerImage; +class LLViewerTexture; class LLViewerPart; class LLViewerRegion; -class LLViewerImage; +class LLViewerTexture; class LLVOPartGroup; typedef void (*LLVPCallback)(LLViewerPart &part, const F32 dt); @@ -60,7 +60,7 @@ public: public: LLViewerPart(); - void init(LLPointer sourcep, LLViewerImage *imagep, LLVPCallback cb); + void init(LLPointer sourcep, LLViewerTexture *imagep, LLVPCallback cb); U32 mPartID; // Particle ID used primarily for moving between groups @@ -72,7 +72,7 @@ public: // Current particle state (possibly used for rendering) - LLPointer mImagep; + LLPointer mImagep; LLVector3 mPosAgent; LLVector3 mVelocity; LLVector3 mAccel; diff --git a/indra/newview/llviewerpartsource.cpp b/indra/newview/llviewerpartsource.cpp index 38c75a84d1..a8cbcd86c6 100644 --- a/indra/newview/llviewerpartsource.cpp +++ b/indra/newview/llviewerpartsource.cpp @@ -39,7 +39,7 @@ #include "llagent.h" #include "lldrawable.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerobject.h" #include "llviewerobjectlist.h" #include "llvoavatar.h" @@ -78,7 +78,7 @@ void LLViewerPartSource::update(const F32 dt) LLUUID LLViewerPartSource::getImageUUID() const { - LLViewerImage* imagep = mImagep; + LLViewerTexture* imagep = mImagep; if(imagep) { return imagep->getID(); @@ -100,8 +100,8 @@ LLViewerPartSourceScript::LLViewerPartSourceScript(LLViewerObject *source_objp) llassert(source_objp); mSourceObjectp = source_objp; mPosAgent = mSourceObjectp->getPositionAgent(); - mImagep = gImageList.getImageFromFile("pixiesmall.j2c"); - gGL.getTexUnit(0)->bind(mImagep.get()); + mImagep = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c"); + gGL.getTexUnit(0)->bind(mImagep); mImagep->setAddressMode(LLTexUnit::TAM_CLAMP); } @@ -491,7 +491,7 @@ LLPointer LLViewerPartSourceScript::createPSS(LLViewer } -void LLViewerPartSourceScript::setImage(LLViewerImage *imagep) +void LLViewerPartSourceScript::setImage(LLViewerTexture *imagep) { LLMemType mt(LLMemType::MTYPE_PARTICLES); mImagep = imagep; @@ -551,7 +551,7 @@ void LLViewerPartSourceSpiral::update(const F32 dt) LLMemType mt(LLMemType::MTYPE_PARTICLES); if (!mImagep) { - mImagep = gImageList.getImageFromFile("pixiesmall.j2c"); + mImagep = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c"); } const F32 RATE = 0.025f; @@ -720,7 +720,7 @@ void LLViewerPartSourceBeam::update(const F32 dt) if (!mImagep) { - mImagep = gImageList.getImageFromFile("pixiesmall.j2c"); + mImagep = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c"); } LLViewerPart* part = new LLViewerPart(); @@ -806,7 +806,7 @@ void LLViewerPartSourceChat::update(const F32 dt) LLMemType mt(LLMemType::MTYPE_PARTICLES); if (!mImagep) { - mImagep = gImageList.getImageFromFile("pixiesmall.j2c"); + mImagep = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c"); } diff --git a/indra/newview/llviewerpartsource.h b/indra/newview/llviewerpartsource.h index 31e671af3a..540e30eb19 100644 --- a/indra/newview/llviewerpartsource.h +++ b/indra/newview/llviewerpartsource.h @@ -45,7 +45,7 @@ // // -class LLViewerImage; +class LLViewerTexture; class LLViewerObject; class LLViewerPart; @@ -90,7 +90,7 @@ protected: F32 mLastUpdateTime; F32 mLastPartTime; LLUUID mOwnerUUID; - LLPointer mImagep; + LLPointer mImagep; // Particle information U32 mPartFlags; // Flags for the particle @@ -123,8 +123,8 @@ public: static LLPointer unpackPSS(LLViewerObject *source_objp, LLPointer pssp, LLDataPacker &dp); static LLPointer createPSS(LLViewerObject *source_objp, const LLPartSysData& particle_parameters); - LLViewerImage *getImage() const { return mImagep; } - void setImage(LLViewerImage *imagep); + LLViewerTexture *getImage() const { return mImagep; } + void setImage(LLViewerTexture *imagep); LLPartSysData mPartSysData; void setTargetObject(LLViewerObject *objp); diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index c79ded1dce..709fcdcf01 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -45,7 +45,7 @@ #include "pipeline.h" #include "lltexturefetch.h" #include "llviewerobjectlist.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "lltexlayer.h" #include "lltexlayerparams.h" #include "llsurface.h" @@ -424,7 +424,7 @@ void output_statistics(void*) { llinfos << "Number of orphans: " << gObjectList.getOrphanCount() << llendl; llinfos << "Number of dead objects: " << gObjectList.mNumDeadObjects << llendl; - llinfos << "Num images: " << gImageList.getNumImages() << llendl; + llinfos << "Num images: " << gTextureList.getNumImages() << llendl; llinfos << "Texture usage: " << LLImageGL::sGlobalTextureMemoryInBytes << llendl; llinfos << "Texture working set: " << LLImageGL::sBoundTextureMemoryInBytes << llendl; llinfos << "Raw usage: " << LLImageRaw::sGlobalRawMemory << llendl; @@ -567,7 +567,7 @@ void update_statistics(U32 frame_count) { gTotalWorldBytes += gVLManager.getTotalBytes(); gTotalObjectBytes += gObjectBits / 8; - gTotalTextureBytes += gImageList.mTextureBits / 8; + gTotalTextureBytes += gTextureList.mTextureBits / 8; // make sure we have a valid time delta for this frame if (gFrameIntervalSeconds > 0.f) @@ -619,7 +619,7 @@ void update_statistics(U32 frame_count) F32 layer_bits = (F32)(gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits()); LLViewerStats::getInstance()->mLayersKBitStat.addValue(layer_bits/1024.f); LLViewerStats::getInstance()->mObjectKBitStat.addValue(gObjectBits/1024.f); - LLViewerStats::getInstance()->mTextureKBitStat.addValue(gImageList.mTextureBits/1024.f); + LLViewerStats::getInstance()->mTextureKBitStat.addValue(gTextureList.mTextureBits/1024.f); LLViewerStats::getInstance()->mVFSPendingOperations.addValue(LLVFile::getVFSThread()->getPending()); LLViewerStats::getInstance()->mAssetKBitStat.addValue(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f); gTransferManager.resetTransferBitsIn(LLTCT_ASSET); @@ -633,7 +633,7 @@ void update_statistics(U32 frame_count) gDebugTimers[0].unpause(); } - LLViewerStats::getInstance()->mTexturePacketsStat.addValue(gImageList.mTexturePackets); + LLViewerStats::getInstance()->mTexturePacketsStat.addValue(gTextureList.mTexturePackets); { static F32 visible_avatar_frames = 0.f; @@ -654,8 +654,8 @@ void update_statistics(U32 frame_count) gObjectBits = 0; // gDecodedBits = 0; - gImageList.mTextureBits = 0; - gImageList.mTexturePackets = 0; + gTextureList.mTextureBits = 0; + gTextureList.mTexturePackets = 0; } diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index 399b7c6bc1..23f3f46570 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -54,7 +54,7 @@ #include "lltooldraganddrop.h" #include "lltrans.h" #include "llviewercontrol.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerwindow.h" #include "llviewerinventory.h" #include "lluictrlfactory.h" diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp new file mode 100644 index 0000000000..92e00e0cae --- /dev/null +++ b/indra/newview/llviewertexture.cpp @@ -0,0 +1,2375 @@ +/** + * @file llviewertexture.cpp + * @brief Object which handles a received image (and associated texture(s)) + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2009, 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" +/////////////////////////////////////////////////////////////////////////////// + +// statics +LLPointer LLViewerTexture::sNullImagep = NULL; +LLPointer LLViewerFetchedTexture::sMissingAssetImagep = NULL; +LLPointer LLViewerFetchedTexture::sWhiteImagep = NULL; +LLPointer LLViewerFetchedTexture::sDefaultImagep = NULL; +LLPointer 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 ; +BOOL LLViewerTexture::sDontLoadVolumeTextures = 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 + +//---------------------------------------------------------------------------------------------- +//namespace: LLViewerTextureAccess +//---------------------------------------------------------------------------------------------- +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) +{ + LLViewerMediaTexture::media_map_t::iterator iter = LLViewerMediaTexture::sMediaMap.find(media_id); + if(iter == LLViewerMediaTexture::sMediaMap.end()) + return NULL; + + ((LLViewerMediaTexture*)(iter->second))->getLastReferencedTimer()->reset() ; + return iter->second; +} + +LLViewerMediaTexture* LLViewerTextureManager::getMediaTexture(const LLUUID& id, BOOL usemipmaps, LLImageGL* gl_image) +{ + LLViewerMediaTexture* tex = LLViewerTextureManager::findMediaTexture(id) ; + if(!tex) + { + tex = LLViewerTextureManager::createMediaTexture(id, usemipmaps, gl_image) ; + } + + LLViewerTexture* old_tex = tex->getOldTexture() ; + if(!old_tex) + { + //if there is a fetched texture with the same id, replace it by this media texture + old_tex = gTextureList.findImage(id) ; + if(old_tex) + { + tex->setOldTexture(old_tex) ; + } + } + + if (gSavedSettings.getBOOL("ParcelMediaAutoPlayEnable") && gSavedSettings.getBOOL("AudioStreamingVideo")) + { + if(!tex->isPlaying()) + { + if(old_tex) + { + old_tex->switchToTexture(tex) ; + } + tex->setPlaying(TRUE) ; + } + } + tex->getLastReferencedTimer()->reset() ; + + return tex ; +} + +LLViewerFetchedTexture* LLViewerTextureManager::staticCastToFetchedTexture(LLViewerTexture* tex, BOOL report_error) +{ + S8 type = tex->getType() ; + if(type == LLViewerTexture::FETCHED_TEXTURE || type == LLViewerTexture::LOD_TEXTURE) + { + return static_cast(tex) ; + } + + if(report_error) + { + llerrs << "not a fetched texture type: " << type << llendl ; + } + + return NULL ; +} + +LLPointer LLViewerTextureManager::getLocalTexture(BOOL usemipmaps, BOOL generate_gl_tex) +{ + LLPointer tex = new LLViewerTexture(usemipmaps) ; + if(generate_gl_tex) + { + tex->generateGLTexture() ; + } + return tex ; +} +LLPointer LLViewerTextureManager::getLocalTexture(const LLUUID& id, BOOL usemipmaps, BOOL generate_gl_tex) +{ + LLPointer tex = new LLViewerTexture(id, usemipmaps) ; + if(generate_gl_tex) + { + tex->generateGLTexture() ; + } + return tex ; +} +LLPointer LLViewerTextureManager::getLocalTexture(const LLImageRaw* raw, BOOL usemipmaps) +{ + LLPointer tex = new LLViewerTexture(raw, usemipmaps) ; + return tex ; +} +LLPointer LLViewerTextureManager::getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex) +{ + LLPointer tex = new LLViewerTexture(width, height, components, usemipmaps) ; + if(generate_gl_tex) + { + tex->generateGLTexture() ; + } + return tex ; +} + +LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture( + const LLUUID &image_id, + BOOL usemipmaps, + BOOL level_immediate, + S8 texture_type, + LLGLint internal_format, + LLGLenum primary_format, + LLHost request_from_host) +{ + return gTextureList.getImage(image_id, usemipmaps, level_immediate, texture_type, internal_format, primary_format, request_from_host) ; +} + +LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromFile( + const std::string& filename, + BOOL usemipmaps, + BOOL level_immediate, + S8 texture_type, + LLGLint internal_format, + LLGLenum primary_format, + const LLUUID& force_id) +{ + return gTextureList.getImageFromFile(filename, usemipmaps, level_immediate, 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 raw = new LLImageRaw(1,1,3); + raw->clear(0x77, 0x77, 0x77, 0xFF); + LLViewerTexture::sNullImagep = LLViewerTextureManager::getLocalTexture(raw.get(), TRUE) ; + +#if 1 + LLPointer imagep = new LLViewerFetchedTexture(IMG_DEFAULT, TRUE); + LLViewerFetchedTexture::sDefaultImagep = imagep; + + const S32 dim = 128; + LLPointer image_raw = new LLImageRaw(dim,dim,3); + U8* data = image_raw->getData(); + for (S32 i = 0; 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; + gTextureList.addImage(imagep); + LLViewerFetchedTexture::sDefaultImagep->dontDiscard(); +#else + LLViewerFetchedTexture::sDefaultImagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, TRUE); +#endif + + LLViewerFetchedTexture::sSmokeImagep = LLViewerTextureManager::getFetchedTexture(IMG_SMOKE, TRUE, TRUE); + 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::sMediaMap.clear() ; +} + +//---------------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------------- +//start of LLViewerTexture +//---------------------------------------------------------------------------------------------- +// static +void LLViewerTexture::initClass() +{ + LLImageGL::sDefaultGLTexture = LLViewerFetchedTexture::sDefaultImagep->getGLTexture() ; +} + +// static +void LLViewerTexture::cleanupClass() +{ +} + +// 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) +{ + 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); +} + +//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; +} + +//virtual +S8 LLViewerTexture::getType() const +{ + return LLViewerTexture::LOCAL_TEXTURE ; +} + +void LLViewerTexture::cleanup() +{ + mFaceList.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() ; + } + } +} + + +bool LLViewerTexture::bindDefaultImage(S32 stage) const +{ + 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(); + 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) const +{ + if (virtual_size > mMaxVirtualSize) + { + mMaxVirtualSize = virtual_size; + } +} + +void LLViewerTexture::resetTextureStats(BOOL zero) +{ + if (zero) + { + mMaxVirtualSize = 0.0f; + } + else + { + mMaxVirtualSize -= mMaxVirtualSize * .10f; // decay by 5%/update + } +} + +void LLViewerTexture::addFace(LLFace* facep) +{ + mFaceList.push_back(facep) ; +} +void LLViewerTexture::removeFace(LLFace* facep) +{ + mFaceList.remove(facep) ; +} + +void LLViewerTexture::switchToTexture(LLViewerTexture* new_texture) +{ + if(this == new_texture) + { + return ; + } + + new_texture->addTextureStats(getMaxVirtualSize()) ; + + for(ll_face_list_t::iterator iter = mFaceList.begin(); iter != mFaceList.end(); ) + { + LLFace* facep = *iter++ ; + facep->setTexture(new_texture) ; + facep->getViewerObject()->changeTEImage(this, new_texture) ; + gPipeline.markTextured(facep->getDrawable()); + } +} + +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_always(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) +{ + llassert_always(mGLTexturep.notNull()) ; + + return mGLTexturep->createGLTexture(discard_level, imageraw, usename) ; +} + +void LLViewerTexture::setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes) +{ + llassert_always(mGLTexturep.notNull()) ; + + mGLTexturep->setExplicitFormat(internal_format, primary_format, type_format, swap_bytes) ; +} +void LLViewerTexture::setAddressMode(LLTexUnit::eTextureAddressMode mode) +{ + llassert_always(mGLTexturep.notNull()) ; + mGLTexturep->setAddressMode(mode) ; +} +void LLViewerTexture::setFilteringOption(LLTexUnit::eTextureFilterOptions option) +{ + llassert_always(mGLTexturep.notNull()) ; + mGLTexturep->setFilteringOption(option) ; +} + +//virtual +S32 LLViewerTexture::getWidth(S32 discard_level) const +{ + llassert_always(mGLTexturep.notNull()) ; + return mGLTexturep->getWidth(discard_level) ; +} + +//virtual +S32 LLViewerTexture::getHeight(S32 discard_level) const +{ + llassert_always(mGLTexturep.notNull()) ; + return mGLTexturep->getHeight(discard_level) ; +} + +S32 LLViewerTexture::getMaxDiscardLevel() const +{ + llassert_always(mGLTexturep.notNull()) ; + return mGLTexturep->getMaxDiscardLevel() ; +} +S32 LLViewerTexture::getDiscardLevel() const +{ + llassert_always(mGLTexturep.notNull()) ; + return mGLTexturep->getDiscardLevel() ; +} +S8 LLViewerTexture::getComponents() const +{ + llassert_always(mGLTexturep.notNull()) ; + + return mGLTexturep->getComponents() ; +} + +LLGLuint LLViewerTexture::getTexName() const +{ + llassert_always(mGLTexturep.notNull()) ; + + return mGLTexturep->getTexName() ; +} + +BOOL LLViewerTexture::hasValidGLTexture() const +{ + if(mGLTexturep.notNull()) + { + return mGLTexturep->getHasGLTexture() ; + } + return FALSE ; +} + +BOOL LLViewerTexture::hasGLTexture() const +{ + return mGLTexturep.notNull() ; +} + +BOOL LLViewerTexture::getBoundRecently() const +{ + if(mGLTexturep.notNull()) + { + return mGLTexturep->getBoundRecently() ; + } + return FALSE ; +} + +LLTexUnit::eTextureType LLViewerTexture::getTarget(void) const +{ + llassert_always(mGLTexturep.notNull()) ; + return mGLTexturep->getTarget() ; +} + +BOOL LLViewerTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height) +{ + llassert_always(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_always(mGLTexturep.notNull()) ; + + return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height) ; +} + +void LLViewerTexture::setGLTextureCreated (bool initialized) +{ + llassert_always(mGLTexturep.notNull()) ; + + mGLTexturep->setGLTextureCreated (initialized) ; +} + +LLTexUnit::eTextureAddressMode LLViewerTexture::getAddressMode(void) const +{ + llassert_always(mGLTexturep.notNull()) ; + + return mGLTexturep->getAddressMode() ; +} + +S32 LLViewerTexture::getTextureMemory() const +{ + llassert_always(mGLTexturep.notNull()) ; + + return mGLTexturep->mTextureMemory ; +} + +LLGLenum LLViewerTexture::getPrimaryFormat() const +{ + llassert_always(mGLTexturep.notNull()) ; + + return mGLTexturep->getPrimaryFormat() ; +} + +BOOL LLViewerTexture::getIsAlphaMask() const +{ + llassert_always(mGLTexturep.notNull()) ; + + return mGLTexturep->getIsAlphaMask() ; +} + +BOOL LLViewerTexture::getMask(const LLVector2 &tc) +{ + llassert_always(mGLTexturep.notNull()) ; + + return mGLTexturep->getMask(tc) ; +} + +F32 LLViewerTexture::getTimePassedSinceLastBound() +{ + llassert_always(mGLTexturep.notNull()) ; + + return mGLTexturep->getTimePassedSinceLastBound() ; +} +BOOL LLViewerTexture::getMissed() const +{ + llassert_always(mGLTexturep.notNull()) ; + + return mGLTexturep->getMissed() ; +} + +BOOL LLViewerTexture::isValidForSculpt(S32 discard_level, S32 image_width, S32 image_height, S32 ncomponents) +{ + llassert_always(mGLTexturep.notNull()) ; + + return mGLTexturep->isValidForSculpt(discard_level, image_width, image_height, ncomponents) ; +} + +BOOL LLViewerTexture::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const +{ + llassert_always(mGLTexturep.notNull()) ; + + return mGLTexturep->readBackRaw(discard_level, imageraw, compressed_ok) ; +} + +void LLViewerTexture::destroyGLTexture() +{ + if(mGLTexturep.notNull() && mGLTexturep->getHasGLTexture()) + { + mGLTexturep->destroyGLTexture() ; + mTextureState = DELETED ; + } +} + +//virtual +void LLViewerTexture::updateBindStatsForTester() +{ + if(LLViewerTextureManager::sTesterp) + { + LLViewerTextureManager::sTesterp->updateTextureBindingStats(this) ; + } +} +//---------------------------------------------------------------------------------------------- +//end of LLViewerTexture +//---------------------------------------------------------------------------------------------- + +//---------------------------------------------------------------------------------------------- +//start of LLViewerFetchedTexture +//---------------------------------------------------------------------------------------------- + +//static +F32 LLViewerFetchedTexture::maxDecodePriority() +{ + return 2000000.f; +} + +LLViewerFetchedTexture::LLViewerFetchedTexture(const LLUUID& id, BOOL usemipmaps) + : LLViewerTexture(id, usemipmaps) +{ + init(TRUE) ; + generateGLTexture() ; +} + +LLViewerFetchedTexture::LLViewerFetchedTexture(const LLImageRaw* raw, BOOL usemipmaps) + : LLViewerTexture(raw, usemipmaps) +{ + init(TRUE) ; +} + +LLViewerFetchedTexture::LLViewerFetchedTexture(const std::string& full_path, const LLUUID& id, BOOL usemipmaps) + : LLViewerTexture(id, usemipmaps), + mLocalFileName(full_path) +{ + 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; + + 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; + + mNeedsCreateTexture = FALSE; + + mIsRawImageValid = FALSE; + mRawDiscardLevel = INVALID_DISCARD_LEVEL; + mMinDiscardLevel = 0; + + mHasFetcher = FALSE; + mIsFetching = FALSE; + mFetchState = 0; + mFetchPriority = 0; + mDownloadProgress = 0.f; + mFetchDeltaTime = 999999.f; + mDecodeFrame = 0; + mVisibleFrame = 0; + mForSculpt = FALSE ; + mIsFetched = FALSE ; +} + +LLViewerFetchedTexture::~LLViewerFetchedTexture() +{ + if (mHasFetcher) + { + 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(); +} + +void LLViewerFetchedTexture::setForSculpt() +{ + mForSculpt = TRUE ; +} + +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 ; + } +} + +// virtual +void LLViewerFetchedTexture::dump() +{ + LLViewerTexture::dump(); + + llinfos << "LLViewerFetchedTexture" + << " mIsMissingAsset " << (S32)mIsMissingAsset + << " mFullWidth " << mFullWidth + << " mFullHeight " << mFullHeight + << " mOrigWidth" << mOrigWidth + << " mOrigHeight" << mOrigHeight + << 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 ; +} + +// 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 (!mLocalFileName.empty()) + { + 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; + } + + res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename); + 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. +void LLViewerFetchedTexture::setKnownDrawSize(S32 width, S32 height) +{ + mKnownDrawWidth = width; + mKnownDrawHeight = height; + addTextureStats((F32)(width * height)); +} + +//virtual +void LLViewerFetchedTexture::processTextureStats() +{ + if(mFullyLoaded)//already loaded + { + return ; + } + + if(!mFullWidth || !mFullHeight) + { + mDesiredDiscardLevel = getMaxDiscardLevel() ; + } + else + { + 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 + } + + if(getDiscardLevel() >= 0 && (getDiscardLevel() <= mDesiredDiscardLevel)) + { + mFullyLoaded = TRUE ; + } + } +} + +//texture does not have any data, so we don't know the size of the image, treat it like 32 * 32. +F32 LLViewerFetchedTexture::calcDecodePriorityForUnknownTexture(F32 pixel_priority) +{ + 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 + 1; + ddiscard = llclamp(ddiscard, 1, 9); + + return ddiscard*100000.f; +} + +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 + } + + F32 priority; + S32 cur_discard = getDiscardLevel(); + bool have_all_data = (cur_discard >= 0 && (cur_discard <= mDesiredDiscardLevel)); + F32 pixel_priority = fsqrtf(mMaxVirtualSize); + const S32 MIN_NOT_VISIBLE_FRAMES = 30; // NOTE: this function is not called every frame + mDecodeFrame++; + if (pixel_priority > 0.f) + { + mVisibleFrame = mDecodeFrame; + } + + if (mIsMissingAsset) + { + priority = 0.0f; + } + else if (mDesiredDiscardLevel > getMaxDiscardLevel()) + { + // Don't decode anything we don't need + priority = -1.0f; + } + else if (mBoostLevel == LLViewerTexture::BOOST_UI && !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 if (mVisibleFrame == 0 || (mDecodeFrame - mVisibleFrame > MIN_NOT_VISIBLE_FRAMES)) + { + // Don't decode anything that isn't visible unless it's important + priority = -2.0f; + } + else + { + // Leave the priority as-is + return mDecodePriority; + } + } + else if (cur_discard < 0) + { + priority = calcDecodePriorityForUnknownTexture(pixel_priority) ; + } + 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 = 100000-400000 + S32 ddiscard = cur_discard - mDesiredDiscardLevel; + if (getDontDiscard()) + { + ddiscard+=2; + } + else if (mGLTexturep.notNull() && !mGLTexturep->getBoundRecently() && mBoostLevel == 0) + { + ddiscard-=2; + } + ddiscard = llclamp(ddiscard, 0, 4); + priority = ddiscard*100000.f; + } + if (priority > 0.0f) + { + pixel_priority = llclamp(pixel_priority, 0.0f, priority-1.f); // priority range = 100000-900000 + if ( mBoostLevel > BOOST_HIGH) + { + priority = 1000000.f + pixel_priority + 1000.f * mBoostLevel; + } + else + { + priority += 0.f + pixel_priority + 1000.f * mBoostLevel; + } + } + return priority; +} +//============================================================================ + +void LLViewerFetchedTexture::setDecodePriority(F32 priority) +{ + llassert(!mInImageList); + mDecodePriority = priority; +} + +bool LLViewerFetchedTexture::updateFetch() +{ + 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 (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) ; + + gTextureList.dirtyImage(this); + } + mIsRawImageValid = TRUE; + gTextureList.mCreateTextureList.insert(this); + mNeedsCreateTexture = TRUE; + mFullWidth = mRawImage->getWidth() << mRawDiscardLevel; + mFullHeight = mRawImage->getHeight() << mRawDiscardLevel; + } + 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.isNull()) + { + // We have data, but our fetch failed to return raw data + // *TODO: FIgure out why this is happening and fix it + destroyRawImage(); + } + } + else + { + LLAppViewer::getTextureFetch()->updateRequestPriority(mID, decode_priority); + } + } + + 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 (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; + } + if (!mDontDiscard) + { + if (mBoostLevel == 0) + { + desired_discard = llmax(desired_discard, current_discard-1); + } + else + { + desired_discard = llmax(desired_discard, current_discard-2); + } + } + + // bypass texturefetch directly by pulling from LLTextureCache + bool fetch_request_created = false; + if (mLocalFileName.empty()) + { + fetch_request_created = LLAppViewer::getTextureFetch()->createRequest(getID(), getTargetHost(), decode_priority, + w, h, c, desired_discard, + needsAux()); + } + else + { + fetch_request_created = LLAppViewer::getTextureFetch()->createRequest(mLocalFileName, 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; +} + +void LLViewerFetchedTexture::setIsMissingAsset() +{ + llwarns << mLocalFileName << " " << mID << ": 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); + } + 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(); + readBackRawImage(gl_discard); + 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 ; +} + +// Was in LLImageGL +LLImageRaw* LLViewerFetchedTexture::readBackRawImage(S8 discard_level) +{ + llassert_always(mGLTexturep.notNull()) ; + llassert_always(discard_level >= 0); + llassert_always(mComponents > 0); + if (mRawImage.notNull()) + { + llerrs << "called with existing mRawImage" << llendl; + mRawImage = NULL; + } + mRawImage = new LLImageRaw(mGLTexturep->getWidth(discard_level), mGLTexturep->getHeight(discard_level), mComponents); + sRawCount++; + mRawDiscardLevel = discard_level; + mGLTexturep->readBackRaw(mRawDiscardLevel, mRawImage, false); + mIsRawImageValid = TRUE; + + return mRawImage; +} + +void LLViewerFetchedTexture::destroyRawImage() +{ + if (mRawImage.notNull()) sRawCount--; + if (mAuxRawImage.notNull()) sAuxCount--; + mRawImage = NULL; + mAuxRawImage = NULL; + mIsRawImageValid = FALSE; + mRawDiscardLevel = INVALID_DISCARD_LEVEL; +} +//---------------------------------------------------------------------------------------------- +//end of LLViewerFetchedTexture +//---------------------------------------------------------------------------------------------- + +//---------------------------------------------------------------------------------------------- +//start of LLViewerLODTexture +//---------------------------------------------------------------------------------------------- +LLViewerLODTexture::LLViewerLODTexture(const LLUUID& id, BOOL usemipmaps) + : LLViewerFetchedTexture(id, usemipmaps) +{ + init(TRUE) ; +} + +LLViewerLODTexture::LLViewerLODTexture(const std::string& full_path, const LLUUID& id, BOOL usemipmaps) + : LLViewerFetchedTexture(full_path, 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 ; +} + +// This is gauranteed to get called periodically for every texture +//virtual +void LLViewerLODTexture::processTextureStats() +{ + // Generate the request priority and render priority + 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 (mBoostLevel == LLViewerTexture::BOOST_UI || + mBoostLevel == LLViewerTexture::BOOST_PREVIEW || + mBoostLevel == LLViewerTexture::BOOST_AVATAR_SELF) // JAMESDEBUG what about AVATAR_BAKED_SELF? + { + discard_level = 0; // full res + } + else*/ 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 ((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) + { + static const F32 discard_bias = -.5f; // Must be < 1 or highest discard will never load! + discard_level += discard_bias; + discard_level += sDesiredDiscardBias; + discard_level *= sDesiredDiscardScale; // scale + } + discard_level = floorf(discard_level); +// discard_level -= (gTextureList.mVideoMemorySetting>>1); // more video ram = higher detail + + 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. + // + + BOOL increase_discard = FALSE; + S32 current_discard = getDiscardLevel(); + if ((sDesiredDiscardBias > 0.0f) && + (current_discard >= 0 && mDesiredDiscardLevel >= current_discard)) + { + if ( BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) > sMaxBoundTextureMemInMegaBytes * texmem_middle_bound_scale) + { + // Limit the amount of GL memory bound each frame + if (mDesiredDiscardLevel > current_discard) + { + increase_discard = TRUE; + } + } + if ( BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) > sMaxTotalTextureMemInMegaBytes*texmem_middle_bound_scale) + { + // Only allow GL to have 2x the video card memory + if (!mGLTexturep->getBoundRecently()) + { + increase_discard = TRUE; + } + } + if (increase_discard) + { + // llinfos << "DISCARDED: " << mID << " Discard: " << current_discard << llendl; + sBoundTextureMemoryInBytes -= mGLTexturep->mTextureMemory; + sTotalTextureMemoryInBytes -= mGLTexturep->mTextureMemory; + // Increase the discard level (reduce the texture res) + S32 new_discard = current_discard+1; + mGLTexturep->setDiscardLevel(new_discard); + sBoundTextureMemoryInBytes += mGLTexturep->mTextureMemory; + sTotalTextureMemoryInBytes += mGLTexturep->mTextureMemory; + if(LLViewerTextureManager::sTesterp) + { + LLViewerTextureManager::sTesterp->setStablizingTime() ; + } + } + } + } +} + +//---------------------------------------------------------------------------------------------- +//end of LLViewerLODTexture +//---------------------------------------------------------------------------------------------- + +//---------------------------------------------------------------------------------------------- +//start of LLViewerMediaTexture +//---------------------------------------------------------------------------------------------- +//static +void LLViewerMediaTexture::updateClass() +{ + static const F32 MAX_INACTIVE_TIME = 30.f ; + + for(media_map_t::iterator iter = sMediaMap.begin() ; iter != sMediaMap.end(); ) + { + LLViewerMediaTexture* mediap = iter->second; + ++iter ; + + if(mediap->getNumRefs() == 1 && mediap->getLastReferencedTimer()->getElapsedTimeF32() > MAX_INACTIVE_TIME) //one by sMediaMap + { + sMediaMap.erase(mediap->getID()) ; + } + } +} + +LLViewerMediaTexture::LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps, LLImageGL* gl_image) + : LLViewerTexture(id, usemipmaps) +{ + sMediaMap.insert(std::make_pair(id, this)); + + mGLTexturep = gl_image ; + if(mGLTexturep.isNull()) + { + generateGLTexture() ; + } + mIsPlaying = FALSE ; +} + +void LLViewerMediaTexture::reinit(BOOL usemipmaps /* = TRUE */) +{ + mGLTexturep = NULL ; + init(false); + mUseMipMaps = usemipmaps ; + mIsPlaying = FALSE ; + getLastReferencedTimer()->reset() ; + + generateGLTexture() ; +} + +void LLViewerMediaTexture::setUseMipMaps(BOOL mipmap) +{ + mUseMipMaps = mipmap; + + if(mGLTexturep.notNull()) + { + mGLTexturep->setUseMipMaps(mipmap) ; + } +} + +//virtual +S8 LLViewerMediaTexture::getType() const +{ + return LLViewerTexture::MEDIA_TEXTURE ; +} + +void LLViewerMediaTexture::setOldTexture(LLViewerTexture* tex) +{ + mOldTexturep = tex ; +} + +LLViewerTexture* LLViewerMediaTexture::getOldTexture() const +{ + return mOldTexturep ; +} +//---------------------------------------------------------------------------------------------- +//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->isForSculpt()) + { + 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(mBaseSessionp) ; + LLTexturePipelineTester::LLTextureTestSession* current_sessionp = dynamic_cast(mCurrentSessionp) ; + if(!base_sessionp || !current_sessionp) + { + llerrs << "type of test session does not match!" << llendl ; + } + + //compare and output the comparison + *os << llformat("%s\n", mName.c_str()) ; + *os << llformat("AggregateResults\n") ; + + compareTestResults(os, "TotalFetchingTime", base_sessionp->mTotalFetchingTime, current_sessionp->mTotalFetchingTime) ; + compareTestResults(os, "TotalGrayTime", base_sessionp->mTotalGrayTime, current_sessionp->mTotalGrayTime) ; + compareTestResults(os, "TotalStablizingTime", base_sessionp->mTotalStablizingTime, current_sessionp->mTotalStablizingTime); + compareTestResults(os, "StartTimeLoadingSculpties", base_sessionp->mStartTimeLoadingSculpties, current_sessionp->mStartTimeLoadingSculpties) ; + 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("InstantResults\n") ; + S32 size = llmin(base_sessionp->mInstantPerformanceListCounter, current_sessionp->mInstantPerformanceListCounter) ; + for(S32 i = 0 ; i < size ; i++) + { + *os << llformat("Time(B-T)-%.4f-%.4f\n", 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)- -%.4f\n", current_sessionp->mInstantPerformanceList[i].mTime) ; + + *os << llformat(", AverageBytesUsedPerSecond, N/A, %d\n", current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedPerSecond) ; + *os << llformat(", AverageBytesUsedForLargeImagePerSecond, N/A, %d\n", current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedForLargeImagePerSecond) ; + *os << llformat(", AveragePercentageBytesUsedPerSecond, N/A, %.4f\n", 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 +//---------------------------------------------------------------------------------------------- + diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h new file mode 100644 index 0000000000..142c212435 --- /dev/null +++ b/indra/newview/llviewertexture.h @@ -0,0 +1,672 @@ +/** + * @file llviewertexture.h + * @brief Object for managing images and their textures + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2009, 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$ + */ + +#ifndef LL_LLVIEWERTEXTURE_H +#define LL_LLVIEWERTEXTURE_H + +#include "lltexture.h" +#include "lltimer.h" +#include "llframetimer.h" +#include "llhost.h" +#include "llgltypes.h" +#include "llrender.h" +#include "llmetricperformancetester.h" + +#include +#include + +#define MIN_VIDEO_RAM_IN_MEGA_BYTES 32 +#define MAX_VIDEO_RAM_IN_MEGA_BYTES 512 // 512MB max for performance reasons. + +class LLFace; +class LLImageGL ; +class LLViewerTexture; +class LLViewerFetchedTexture ; +class LLViewerMediaTexture ; +class LLTexturePipelineTester ; + +typedef void (*loaded_callback_func)( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata ); + +class LLVFile; +class LLMessageSystem; + +class LLLoadedCallbackEntry +{ +public: + 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) + { + } + + loaded_callback_func mCallback; + S32 mLastUsedDiscard; + S32 mDesiredDiscard; + BOOL mNeedsImageRaw; + void* mUserData; +}; + +class LLTextureBar; + +class LLViewerTexture : public LLTexture +{ +public: + enum + { + MAX_IMAGE_SIZE_DEFAULT = 1024, + INVALID_DISCARD_LEVEL = 0x7fff + }; + enum + { + LOCAL_TEXTURE, + MEDIA_TEXTURE, + DYNAMIC_TEXTURE, + FETCHED_TEXTURE, + LOD_TEXTURE, + INVALID_TEXTURE_TYPE + }; + + enum EBoostLevel + { + BOOST_NONE = 0, + BOOST_AVATAR_BAKED = 1, + BOOST_AVATAR = 2, + BOOST_CLOUDS = 3, + BOOST_SCULPTED = 4, + + BOOST_HIGH = 10, + BOOST_TERRAIN = 11, // has to be high priority for minimap / low detail + BOOST_SELECTED = 12, + BOOST_HUD = 13, + BOOST_AVATAR_BAKED_SELF = 14, + BOOST_UI = 15, + BOOST_PREVIEW = 16, + BOOST_MAP = 17, + BOOST_MAP_LAYER = 18, + BOOST_AVATAR_SELF = 19, // needed for baking avatar + BOOST_MAX_LEVEL + }; + +protected: + virtual ~LLViewerTexture(); + LOG_CLASS(LLViewerTexture); + +public: + static void initClass(); + static void cleanupClass(); + static void updateClass(const F32 velocity, const F32 angular_velocity) ; + + LLViewerTexture(BOOL usemipmaps = TRUE); + LLViewerTexture(const LLUUID& id, BOOL usemipmaps) ; + LLViewerTexture(const LLImageRaw* raw, BOOL usemipmaps) ; + LLViewerTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) ; + + virtual S8 getType() const; + virtual BOOL isMissingAsset()const ; + virtual void dump(); // debug info to llinfos + + /*virtual*/ bool bindDefaultImage(const S32 stage = 0) const ; + /*virtual*/ void forceImmediateUpdate() ; + + const LLUUID& getID() const { return mID; } + + void setBoostLevel(S32 level); + S32 getBoostLevel() { return mBoostLevel; } + + //maxVirtualSize of the texture + void addTextureStats(F32 virtual_size) const ; + void resetTextureStats(BOOL zero = FALSE); + F32 getMaxVirtualSize()const {return mMaxVirtualSize ;} + + LLFrameTimer* getLastReferencedTimer() {return &mLastReferencedTimer ;} + + S32 getFullWidth() const { return mFullWidth; } + S32 getFullHeight() const { return mFullHeight; } + + void addFace(LLFace* facep) ; + void removeFace(LLFace* facep) ; + + void generateGLTexture() ; + void destroyGLTexture() ; + + //--------------------------------------------------------------------------------------------- + //functions to access LLImageGL + //--------------------------------------------------------------------------------------------- + /*virtual*/S32 getWidth(S32 discard_level = -1) const; + /*virtual*/S32 getHeight(S32 discard_level = -1) const; + + BOOL hasGLTexture() const ; + BOOL hasValidGLTexture() const ; + LLGLuint getTexName() const ; + BOOL createGLTexture() ; + BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0); + + void setFilteringOption(LLTexUnit::eTextureFilterOptions option); + void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE); + void setAddressMode(LLTexUnit::eTextureAddressMode mode); + BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height); + BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height); + void setGLTextureCreated (bool initialized); + + LLTexUnit::eTextureAddressMode getAddressMode(void) const ; + S32 getMaxDiscardLevel() const; + S32 getDiscardLevel() const; + S8 getComponents() const ; + BOOL getBoundRecently() const; + S32 getTextureMemory() const ; + LLGLenum getPrimaryFormat() const; + BOOL getIsAlphaMask() const ; + LLTexUnit::eTextureType getTarget(void) const ; + BOOL getMask(const LLVector2 &tc); + F32 getTimePassedSinceLastBound(); + BOOL getMissed() const ; + BOOL isValidForSculpt(S32 discard_level, S32 image_width, S32 image_height, S32 ncomponents) ; + BOOL readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const; + //--------------------------------------------------------------------------------------------- + //end of functions to access LLImageGL + //--------------------------------------------------------------------------------------------- + + void switchToTexture(LLViewerTexture* new_texture) ; //make all faces pointing to this texture to point to new_texture. + + //----------------- + /*virtual*/ void setActive() ; + void forceActive() ; + void setNoDelete() ; + void dontDiscard() { mDontDiscard = 1; mTextureState = NO_DELETE; } + BOOL getDontDiscard() const { return mDontDiscard; } + //----------------- + + /*virtual*/ void updateBindStatsForTester() ; +protected: + void cleanup() ; + void init(bool firstinit) ; + +private: + //note: do not make this function public. + /*virtual*/ LLImageGL* getGLTexture() const ; + +protected: + LLUUID mID; + S32 mBoostLevel; // enum describing priority level + S32 mFullWidth; + S32 mFullHeight; + BOOL mUseMipMaps ; + S8 mComponents; + mutable F32 mMaxVirtualSize; // The largest virtual size of the image, in pixels - how much data to we need? + + LLFrameTimer mLastReferencedTimer; + + typedef std::list ll_face_list_t ; + ll_face_list_t mFaceList ; //reverse pointer pointing to the faces using this image as texture + + //GL texture + LLPointer mGLTexturep ; + S8 mDontDiscard; // Keep full res version of this image (for UI, etc) + +protected: + typedef enum + { + DELETED = 0, //removed from memory + DELETION_CANDIDATE, //ready to be removed from memory + INACTIVE, //not be used for the last certain period (i.e., 30 seconds). + ACTIVE, //just being used, can become inactive if not being used for a certain time (10 seconds). + NO_DELETE = 99 //stay in memory, can not be removed. + } LLGLTexureState; + LLGLTexureState mTextureState ; + +public: + static const U32 sCurrentFileVersion; + static S32 sImageCount; + static S32 sRawCount; + static S32 sAuxCount; + static LLTimer sEvaluationTimer; + static F32 sDesiredDiscardBias; + static F32 sDesiredDiscardScale; + static S32 sBoundTextureMemoryInBytes; + static S32 sTotalTextureMemoryInBytes; + static S32 sMaxBoundTextureMemInMegaBytes; + static S32 sMaxTotalTextureMemInMegaBytes; + static S32 sMaxDesiredTextureMemInBytes ; + static BOOL sDontLoadVolumeTextures; + + static LLPointer sNullImagep; // Null texture for non-textured objects. +}; + + +// +//textures are managed in gTextureList. +//raw image data is fetched from remote or local cache +//but the raw image this texture pointing to is fixed. +// +class LLViewerFetchedTexture : public LLViewerTexture +{ + friend class LLTextureBar; // debug info only + friend class LLTextureView; // debug info only + +protected: + /*virtual*/ ~LLViewerFetchedTexture(); +public: + LLViewerFetchedTexture(const LLUUID& id, BOOL usemipmaps = TRUE); + LLViewerFetchedTexture(const LLImageRaw* raw, BOOL usemipmaps); + LLViewerFetchedTexture(const std::string& full_path, const LLUUID& id, BOOL usemipmaps = TRUE); + +public: + static F32 maxDecodePriority(); + + struct Compare + { + // lhs < rhs + bool operator()(const LLPointer &lhs, const LLPointer &rhs) const + { + const LLViewerFetchedTexture* lhsp = (const LLViewerFetchedTexture*)lhs; + const LLViewerFetchedTexture* rhsp = (const LLViewerFetchedTexture*)rhs; + // greater priority is "less" + const F32 lpriority = lhsp->getDecodePriority(); + const F32 rpriority = rhsp->getDecodePriority(); + if (lpriority > rpriority) // higher priority + return true; + if (lpriority < rpriority) + return false; + return lhsp < rhsp; + } + }; + +public: + /*virtual*/ S8 getType() const ; + /*virtual*/ void forceImmediateUpdate() ; + /*virtual*/ void dump() ; + + // Set callbacks to get called when the image gets updated with higher + // resolution versions. + void setLoadedCallback(loaded_callback_func cb, + S32 discard_level, BOOL keep_imageraw, BOOL needs_aux, + void* userdata); + bool hasCallbacks() { return mLoadedCallbackList.empty() ? false : true; } + bool doLoadedCallbacks(); + + // ONLY call from LLViewerTextureList + BOOL createTexture(S32 usename = 0); + void destroyTexture() ; + + virtual void processTextureStats() ; + F32 calcDecodePriority() ; + + BOOL needsAux() const { return mNeedsAux; } + + // Host we think might have this image, used for baked av textures. + void setTargetHost(LLHost host) { mTargetHost = host; } + LLHost getTargetHost() const { return mTargetHost; } + + // Set the decode priority for this image... + // DON'T CALL THIS UNLESS YOU KNOW WHAT YOU'RE DOING, it can mess up + // the priority list, and cause horrible things to happen. + void setDecodePriority(F32 priority = -1.0f); + F32 getDecodePriority() const { return mDecodePriority; }; + + // setDesiredDiscardLevel is only used by LLViewerTextureList + void setDesiredDiscardLevel(S32 discard) { mDesiredDiscardLevel = discard; } + S32 getDesiredDiscardLevel() { return mDesiredDiscardLevel; } + void setMinDiscardLevel(S32 discard) { mMinDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel,(S8)discard); } + + bool updateFetch(); + + // Override the computation of discard levels if we know the exact output + // size of the image. Used for UI textures to not decode, even if we have + // more data. + void setKnownDrawSize(S32 width, S32 height); + + void setIsMissingAsset(); + /*virtual*/ BOOL isMissingAsset() const { return mIsMissingAsset; } + + // returns dimensions of original image for local files (before power of two scaling) + // and returns 0 for all asset system images + S32 getOriginalWidth() { return mOrigWidth; } + S32 getOriginalHeight() { return mOrigHeight; } + + BOOL isInImageList() const {return mInImageList ;} + void setInImageList(BOOL flag) {mInImageList = flag ;} + + const std::string& getLocalFileName() const {return mLocalFileName ;} + LLFrameTimer* getLastPacketTimer() {return &mLastPacketTimer;} + + U32 getFetchPriority() const { return mFetchPriority ;} + F32 getDownloadProgress() const {return mDownloadProgress ;} + + LLImageRaw* readBackRawImage(S8 discard_level) ; + void destroyRawImage(); + + //--------------- + BOOL isDeleted() ; + BOOL isInactive() ; + BOOL isDeletionCandidate(); + void setDeletionCandidate() ; + void setInactive() ; + BOOL getUseDiscard() const { return mUseMipMaps && !mDontDiscard; } + //--------------- + + void setForSculpt(); + BOOL isForSculpt() const {return mForSculpt;} + +private: + void init(bool firstinit) ; + void cleanup() ; + + F32 calcDecodePriorityForUnknownTexture(F32 pixel_priority) ; + +private: + BOOL mFullyLoaded; + +protected: + S32 mOrigWidth; + S32 mOrigHeight; + + // Override the computation of discard levels if we know the exact output size of the image. + // Used for UI textures to not decode, even if we have more data. + S32 mKnownDrawWidth; + S32 mKnownDrawHeight; + + std::string mLocalFileName; + + S8 mDesiredDiscardLevel; // The discard level we'd LIKE to have - if we have it and there's space + S8 mMinDesiredDiscardLevel; // The minimum discard level we'd like to have + S32 mMinDiscardLevel; + + S32 mRequestedDiscardLevel; + F32 mRequestedDownloadPriority; + S32 mFetchState; + U32 mFetchPriority; + F32 mDownloadProgress; + F32 mFetchDeltaTime; + F32 mRequestDeltaTime; + S32 mDecodeFrame; + S32 mVisibleFrame; // decode frame where image was last visible + + S8 mNeedsAux; // We need to decode the auxiliary channels + S8 mDecodingAux; // Are we decoding high components + S8 mIsRawImageValid; + S8 mHasFetcher; // We've made a fecth request + S8 mIsFetching; // Fetch request is active + + mutable S8 mIsMissingAsset; // True if we know that there is no image asset with this image id in the database. + + F32 mDecodePriority; // The priority for decoding this image. + typedef std::list callback_list_t; + callback_list_t mLoadedCallbackList; + + LLPointer mRawImage; + S32 mRawDiscardLevel; + + // Used ONLY for cloth meshes right now. Make SURE you know what you're + // doing if you use it for anything else! - djs + LLPointer mAuxRawImage; + + LLHost mTargetHost; // if LLHost::invalid, just request from agent's simulator + + // Timers + LLFrameTimer mLastPacketTimer; // Time since last packet. + + BOOL mInImageList; // TRUE if image is in list (in which case don't reset priority!) + BOOL mNeedsCreateTexture; + + BOOL mForSculpt ; //a flag if the texture is used as sculpt data. + BOOL mIsFetched ; //is loaded from remote or from cache, not generated locally. + +public: + static LLPointer sMissingAssetImagep; // Texture to show for an image asset that is not in the database + static LLPointer sWhiteImagep; // Texture to show NOTHING (whiteness) + static LLPointer sDefaultImagep; // "Default" texture for error cases, the only case of fetched texture which is generated in local. + static LLPointer sSmokeImagep; // Old "Default" translucent texture +}; + +// +//the image data is fetched from remote or from local cache +//the resolution of the texture is adjustable: depends on the view-dependent parameters. +// +class LLViewerLODTexture : public LLViewerFetchedTexture +{ +protected: + /*virtual*/ ~LLViewerLODTexture(){} + +public: + LLViewerLODTexture(const LLUUID& id, BOOL usemipmaps = TRUE); + LLViewerLODTexture(const std::string& full_path, const LLUUID& id, BOOL usemipmaps = TRUE); + + /*virtual*/ S8 getType() const; + // Process image stats to determine priority/quality requirements. + /*virtual*/ void processTextureStats(); + +private: + void init(bool firstinit) ; + +private: + + F32 mTexelsPerImage; // Texels per image. + F32 mDiscardVirtualSize; // Virtual size used to calculate desired discard + F32 mCalculatedDiscardLevel; // Last calculated discard level +}; + +// +//the image data is fetched from the media pipeline periodically +//the resolution of the texture is also adjusted by the media pipeline +// +class LLViewerMediaTexture : public LLViewerTexture +{ +protected: + /*virtual*/ ~LLViewerMediaTexture() {} + +public: + LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ; + + /*virtual*/ S8 getType() const; + + void reinit(BOOL usemipmaps = TRUE); + + BOOL getUseMipMaps() {return mUseMipMaps ; } + void setUseMipMaps(BOOL mipmap) ; + + void setOldTexture(LLViewerTexture* tex) ; + LLViewerTexture* getOldTexture() const ; + + void setPlaying(BOOL playing) {mIsPlaying = playing ;} + BOOL isPlaying() const {return mIsPlaying;} + +private: + LLPointer mOldTexturep ; //the texture this media texture replaces. + BOOL mIsPlaying ; + +public: + static void updateClass() ; + +public: + typedef std::map< LLUUID, LLPointer > media_map_t ; + static media_map_t sMediaMap ; +}; + +//just an interface class, do not create instance from this class. +class LLViewerTextureManager +{ +private: + //make the constructor private to preclude creating instances from this class. + LLViewerTextureManager(){} + +public: + //texture pipeline tester + static LLTexturePipelineTester* sTesterp ; + + //returns NULL if tex is not a LLViewerFetchedTexture nor derived from LLViewerFetchedTexture. + static LLViewerFetchedTexture* staticCastToFetchedTexture(LLViewerTexture* tex, BOOL report_error = FALSE) ; + + // + //"find-texture" just check if the texture exists, if yes, return it, otherwise return null. + // + static LLViewerTexture* findTexture(const LLUUID& id) ; + static LLViewerMediaTexture* findMediaTexture(const LLUUID& id) ; + + static LLViewerMediaTexture* createMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ; + + // + //"get-texture" will create a new texture if the texture does not exist. + // + static LLViewerMediaTexture* getMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ; + + static LLPointer getLocalTexture(BOOL usemipmaps = TRUE, BOOL generate_gl_tex = TRUE); + static LLPointer getLocalTexture(const LLUUID& id, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) ; + static LLPointer getLocalTexture(const LLImageRaw* raw, BOOL usemipmaps) ; + static LLPointer getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) ; + + static LLViewerFetchedTexture* getFetchedTexture(const LLUUID &image_id, + BOOL usemipmap = TRUE, + BOOL level_immediate = FALSE, // Get the requested level immediately upon creation. + S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, + LLGLint internal_format = 0, + LLGLenum primary_format = 0, + LLHost request_from_host = LLHost() + ); + + static LLViewerFetchedTexture* getFetchedTextureFromFile(const std::string& filename, + BOOL usemipmap = TRUE, + BOOL level_immediate = FALSE, // Get the requested level immediately upon creation. + S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, + LLGLint internal_format = 0, + LLGLenum primary_format = 0, + const LLUUID& force_id = LLUUID::null + ); + + static LLViewerFetchedTexture* getFetchedTextureFromHost(const LLUUID& image_id, LLHost host) ; + + static void init() ; + static void cleanup() ; +}; +// +//this class is used for test/debug only +//it tracks the activities of the texture pipeline +//records them, and outputs them to log files +// +class LLTexturePipelineTester : public LLMetricPerformanceTester +{ + enum + { + MIN_LARGE_IMAGE_AREA = 262144 //512 * 512 + }; +public: + LLTexturePipelineTester() ; + ~LLTexturePipelineTester() ; + + void update(); + void updateTextureBindingStats(const LLViewerTexture* imagep) ; + void updateTextureLoadingStats(const LLViewerFetchedTexture* imagep, const LLImageRaw* raw_imagep, BOOL from_cache) ; + void updateGrayTextureBinding() ; + void setStablizingTime() ; + + /*virtual*/ void analyzePerformance(std::ofstream* os, LLSD* base, LLSD* current) ; + +private: + void reset() ; + void updateStablizingTime() ; + + /*virtual*/ void outputTestRecord(LLSD* sd) ; + +private: + BOOL mPause ; +private: + BOOL mUsingDefaultTexture; //if set, some textures are still gray. + + U32 mTotalBytesUsed ; //total bytes of textures bound/used for the current frame. + U32 mTotalBytesUsedForLargeImage ; //total bytes of textures bound/used for the current frame for images larger than 256 * 256. + U32 mLastTotalBytesUsed ; //total bytes of textures bound/used for the previous frame. + U32 mLastTotalBytesUsedForLargeImage ; //total bytes of textures bound/used for the previous frame for images larger than 256 * 256. + + // + //data size + // + U32 mTotalBytesLoaded ; //total bytes fetched by texture pipeline + U32 mTotalBytesLoadedFromCache ; //total bytes fetched by texture pipeline from local cache + U32 mTotalBytesLoadedForLargeImage ; //total bytes fetched by texture pipeline for images larger than 256 * 256. + U32 mTotalBytesLoadedForSculpties ; //total bytes fetched by texture pipeline for sculpties + + // + //time + //NOTE: the error tolerances of the following timers is one frame time. + // + F32 mStartFetchingTime ; + F32 mTotalGrayTime ; //total loading time when no gray textures. + F32 mTotalStablizingTime ; //total stablizing time when texture memory overflows + F32 mStartTimeLoadingSculpties ; //the start moment of loading sculpty images. + F32 mEndTimeLoadingSculpties ; //the end moment of loading sculpty images. + F32 mStartStablizingTime ; + F32 mEndStablizingTime ; + +private: + // + //The following members are used for performance analyzing + // + class LLTextureTestSession : public LLTestSession + { + public: + LLTextureTestSession() ; + /*virtual*/ ~LLTextureTestSession() ; + + void reset() ; + + F32 mTotalFetchingTime ; + F32 mTotalGrayTime ; + F32 mTotalStablizingTime ; + F32 mStartTimeLoadingSculpties ; + F32 mTotalTimeLoadingSculpties ; + + S32 mTotalBytesLoaded ; + S32 mTotalBytesLoadedFromCache ; + S32 mTotalBytesLoadedForLargeImage ; + S32 mTotalBytesLoadedForSculpties ; + + typedef struct _texture_instant_preformance_t + { + S32 mAverageBytesUsedPerSecond ; + S32 mAverageBytesUsedForLargeImagePerSecond ; + F32 mAveragePercentageBytesUsedPerSecond ; + F32 mTime ; + }texture_instant_preformance_t ; + std::vector mInstantPerformanceList ; + S32 mInstantPerformanceListCounter ; + }; + + /*virtual*/ LLMetricPerformanceTester::LLTestSession* loadTestSession(LLSD* log) ; + /*virtual*/ void compareTestSessions(std::ofstream* os) ; +}; + +#endif diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp new file mode 100644 index 0000000000..c96914975b --- /dev/null +++ b/indra/newview/llviewertexturelist.cpp @@ -0,0 +1,1510 @@ +/** + * @file llviewertexturelist.cpp + * @brief Object for managing the list of images within a region + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2009, 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 "llviewertexturelist.h" + +#include "imageids.h" +#include "llgl.h" // fot gathering stats from GL +#include "llimagegl.h" +#include "llimagebmp.h" +#include "llimagej2c.h" +#include "llimagetga.h" +#include "llimagejpeg.h" +#include "llimagepng.h" + +#include "llsdserialize.h" +#include "llsys.h" +#include "llvfs.h" +#include "llvfile.h" +#include "llvfsthread.h" +#include "llxmltree.h" +#include "message.h" + +#include "llagent.h" +#include "lltexturecache.h" +#include "lltexturefetch.h" +#include "llviewercontrol.h" +#include "llviewertexture.h" +#include "llviewermedia.h" +#include "llviewerregion.h" +#include "llviewerstats.h" +#include "pipeline.h" +#include "llappviewer.h" +#include "lluictrlfactory.h" // for LLXUIParser +#include + +//////////////////////////////////////////////////////////////////////////// + +void (*LLViewerTextureList::sUUIDCallback)(void **, const LLUUID&) = NULL; + +const S32 IMAGES_PER_REQUEST = 42; +const S32 IMAGES_MIN_UPDATES = 4; // Always update the highest N images each frame +const S32 IMAGES_MAX_PACKET_UPDATES = 1; // Only send N packets of IMAGES_PER_REQUEST in a frame +const F32 RESEND_IMAGE_REQUEST_TIME = 15.f; // seconds + +LLViewerTextureList gTextureList; + +/////////////////////////////////////////////////////////////////////////////// + +LLViewerTextureList::LLViewerTextureList() + : mForceResetTextureStats(FALSE), + mUpdateStats(FALSE), + mMaxResidentTexMemInMegaBytes(0), + mMaxTotalTextureMemInMegaBytes(0) +{ +} + +void LLViewerTextureList::init() +{ + mNumImages = 0; + mMaxResidentTexMemInMegaBytes = 0; + mMaxTotalTextureMemInMegaBytes = 0 ; + if (gNoRender) + { + // Don't initialize GL stuff if we're not rendering. + return; + } + + mUpdateStats = TRUE; + + // Update how much texture RAM we're allowed to use. + updateMaxResidentTexMem(0); // 0 = use current + + doPreloadImages(); +} + + +void LLViewerTextureList::doPreloadImages() +{ + LL_DEBUGS("ViewerImages") << "Preloading images..." << LL_ENDL; + + // Set the "missing asset" image + LLViewerFetchedTexture::sMissingAssetImagep = LLViewerTextureManager::getFetchedTextureFromFile("missing_asset.tga", MIPMAP_NO, IMMEDIATE_YES); + + // Set the "white" image + LLViewerFetchedTexture::sWhiteImagep = LLViewerTextureManager::getFetchedTextureFromFile("white.tga", MIPMAP_NO, IMMEDIATE_YES); + + LLUIImageList* image_list = LLUIImageList::getInstance(); + + image_list->initFromFile(); + + // turn off clamping and bilinear filtering for uv picking images + //LLViewerFetchedTexture* uv_test = preloadUIImage("uv_test1.tga", LLUUID::null, FALSE); + //uv_test->setClamp(FALSE, FALSE); + //uv_test->setMipFilterNearest(TRUE, TRUE); + //uv_test = preloadUIImage("uv_test2.tga", LLUUID::null, FALSE); + //uv_test->setClamp(FALSE, FALSE); + //uv_test->setMipFilterNearest(TRUE, TRUE); + + // prefetch specific UUIDs + LLViewerTextureManager::getFetchedTexture(IMG_SHOT, TRUE); + LLViewerTextureManager::getFetchedTexture(IMG_SMOKE_POOF, TRUE); + LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", MIPMAP_YES, IMMEDIATE_YES); + if (image) + { + image->setAddressMode(LLTexUnit::TAM_WRAP); + mImagePreloads.insert(image); + } + image = LLViewerTextureManager::getFetchedTextureFromFile("noentrylines.j2c", MIPMAP_YES, IMMEDIATE_YES); + if (image) + { + image->setAddressMode(LLTexUnit::TAM_WRAP); + mImagePreloads.insert(image); + } + image = LLViewerTextureManager::getFetchedTextureFromFile("noentrypasslines.j2c", MIPMAP_YES, IMMEDIATE_YES); + if (image) + { + image->setAddressMode(LLTexUnit::TAM_WRAP); + mImagePreloads.insert(image); + } + image = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL, MIPMAP_YES, IMMEDIATE_YES); + if (image) + { + image->setAddressMode(LLTexUnit::TAM_WRAP); + mImagePreloads.insert(image); + } + image = LLViewerTextureManager::getFetchedTextureFromFile("transparent.j2c", MIPMAP_YES, IMMEDIATE_YES, LLViewerTexture::FETCHED_TEXTURE, + 0,0,LLUUID("8dcd4a48-2d37-4909-9f78-f7a9eb4ef903")); + if (image) + { + image->setAddressMode(LLTexUnit::TAM_WRAP); + mImagePreloads.insert(image); + } + +} + +static std::string get_texture_list_name() +{ + return std::string("texture_list_") + gSavedSettings.getString("LoginLocation") + ".xml"; +} + +void LLViewerTextureList::doPrefetchImages() +{ + if (LLAppViewer::instance()->getPurgeCache()) + { + // cache was purged, no point + return; + } + + // Pre-fetch textures from last logout + LLSD imagelist; + std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, get_texture_list_name()); + llifstream file; + file.open(filename); + if (file.is_open()) + { + LLSDSerialize::fromXML(imagelist, file); + } + for (LLSD::array_iterator iter = imagelist.beginArray(); + iter != imagelist.endArray(); ++iter) + { + LLSD imagesd = *iter; + LLUUID uuid = imagesd["uuid"]; + S32 pixel_area = imagesd["area"]; + S32 texture_type = imagesd["type"]; + + if(LLViewerTexture::FETCHED_TEXTURE == texture_type || LLViewerTexture::LOD_TEXTURE == texture_type) + { + LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(uuid, MIPMAP_TRUE, FALSE, texture_type); + if (image) + { + image->addTextureStats((F32)pixel_area); + } + } + } +} + +/////////////////////////////////////////////////////////////////////////////// + +LLViewerTextureList::~LLViewerTextureList() +{ +} + +void LLViewerTextureList::shutdown() +{ + // clear out preloads + mImagePreloads.clear(); + + // Write out list of currently loaded textures for precaching on startup + typedef std::set > image_area_list_t; + image_area_list_t image_area_list; + for (image_priority_list_t::iterator iter = mImageList.begin(); + iter != mImageList.end(); ++iter) + { + LLViewerFetchedTexture* image = *iter; + if (!image->hasGLTexture() || + !image->getUseDiscard() || + image->needsAux() || + image->getTargetHost() != LLHost::invalid) + { + continue; // avoid UI, baked, and other special images + } + S32 desired = image->getDesiredDiscardLevel(); + if (desired >= 0 && desired < MAX_DISCARD_LEVEL) + { + S32 pixel_area = image->getWidth(desired) * image->getHeight(desired); + image_area_list.insert(std::make_pair(pixel_area, image)); + } + } + + LLSD imagelist; + const S32 max_count = 1000; + S32 count = 0; + S32 image_type ; + for (image_area_list_t::reverse_iterator riter = image_area_list.rbegin(); + riter != image_area_list.rend(); ++riter) + { + LLViewerFetchedTexture* image = riter->second; + image_type = (S32)image->getType() ; + imagelist[count]["area"] = riter->first; + imagelist[count]["uuid"] = image->getID(); + imagelist[count]["type"] = image_type; + if (++count >= max_count) + break; + } + + if (count > 0 && !gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "").empty()) + { + std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, get_texture_list_name()); + llofstream file; + file.open(filename); + LLSDSerialize::toPrettyXML(imagelist, file); + } + + // + // Clean up "loaded" callbacks. + // + mCallbackList.clear(); + + // Flush all of the references + mLoadingStreamList.clear(); + mCreateTextureList.clear(); + + mUUIDMap.clear(); + + mImageList.clear(); +} + +void LLViewerTextureList::dump() +{ + llinfos << "LLViewerTextureList::dump()" << llendl; + for (image_priority_list_t::iterator it = mImageList.begin(); it != mImageList.end(); ++it) + { + LLViewerFetchedTexture* image = *it; + + llinfos << "priority " << image->getDecodePriority() + << " boost " << image->getBoostLevel() + << " size " << image->getWidth() << "x" << image->getHeight() + << " discard " << image->getDiscardLevel() + << " desired " << image->getDesiredDiscardLevel() + << " http://asset.siva.lindenlab.com/" << image->getID() << ".texture" + << llendl; + } +} + +void LLViewerTextureList::destroyGL(BOOL save_state) +{ + LLImageGL::destroyGL(save_state); +} + +void LLViewerTextureList::restoreGL() +{ + LLImageGL::restoreGL(); +} + +/* Vertical tab container button image IDs + Seem to not decode when running app in debug. + + const LLUUID BAD_IMG_ONE("1097dcb3-aef9-8152-f471-431d840ea89e"); + const LLUUID BAD_IMG_TWO("bea77041-5835-1661-f298-47e2d32b7a70"); + */ + +/////////////////////////////////////////////////////////////////////////////// + +LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string& filename, + BOOL usemipmaps, + BOOL level_immediate, + S8 texture_type, + LLGLint internal_format, + LLGLenum primary_format, + const LLUUID& force_id) +{ + if (gNoRender) + { + // Never mind that this ignores image_set_id; + // getImage() will handle that later. + return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, TRUE); + } + + std::string full_path = gDirUtilp->findSkinnedFilename("textures", filename); + if (full_path.empty()) + { + llwarns << "Failed to find local image file: " << filename << llendl; + return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, TRUE); + } + + // generate UUID based on hash of filename + LLUUID new_id; + if (force_id.notNull()) + { + new_id = force_id; + } + else + { + new_id.generate(full_path); + } + + LLPointer imagep = findImage(new_id); + + if (imagep.isNull()) + { + switch(texture_type) + { + case LLViewerTexture::FETCHED_TEXTURE: + imagep = new LLViewerFetchedTexture(full_path, new_id, usemipmaps); + break ; + case LLViewerTexture::LOD_TEXTURE: + imagep = new LLViewerLODTexture(full_path, new_id, usemipmaps); + break ; + default: + llerrs << "Invalid texture type " << texture_type << llendl ; + } + + if (internal_format && primary_format) + { + imagep->setExplicitFormat(internal_format, primary_format); + } + + addImage(imagep); + + if (level_immediate) + { + imagep->dontDiscard(); + imagep->setBoostLevel(LLViewerFetchedTexture::BOOST_UI); + } + } + + imagep->setGLTextureCreated(true); + + return imagep; +} + + +LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id, + BOOL usemipmaps, + BOOL level_immediate, + S8 texture_type, + LLGLint internal_format, + LLGLenum primary_format, + LLHost request_from_host) +{ + // Return the image with ID image_id + // If the image is not found, creates new image and + // enqueues a request for transmission + + if ((&image_id == NULL) || image_id.isNull()) + { + return (LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, TRUE)); + } + + LLPointer imagep = findImage(image_id); + + if (imagep.isNull()) + { + imagep = createImage(image_id, usemipmaps, level_immediate, texture_type, internal_format, primary_format, request_from_host) ; + } + + imagep->setGLTextureCreated(true); + + return imagep; +} + +//when this function is called, there is no such texture in the gTextureList with image_id. +LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id, + BOOL usemipmaps, + BOOL level_immediate, + S8 texture_type, + LLGLint internal_format, + LLGLenum primary_format, + LLHost request_from_host) +{ + LLPointer imagep ; + switch(texture_type) + { + case LLViewerTexture::FETCHED_TEXTURE: + imagep = new LLViewerFetchedTexture(image_id, usemipmaps); + break ; + case LLViewerTexture::LOD_TEXTURE: + imagep = new LLViewerLODTexture(image_id, usemipmaps); + break ; + default: + llerrs << "Invalid texture type " << texture_type << llendl ; + } + + // Might want to request from host other than where the agent is. JC + imagep->setTargetHost(request_from_host); + + if (internal_format && primary_format) + { + imagep->setExplicitFormat(internal_format, primary_format); + } + + addImage(imagep); + + if (level_immediate) + { + imagep->dontDiscard(); + imagep->setBoostLevel(LLViewerFetchedTexture::BOOST_UI); + } + else + { + //by default, the texure can not be removed from memory even if it is not used. + //here turn this off + //if this texture should be set to NO_DELETE, either pass level_immediate == TRUE here, or call setNoDelete() afterwards. + imagep->forceActive() ; + } + + return imagep ; +} + +LLViewerFetchedTexture *LLViewerTextureList::findImage(const LLUUID &image_id) +{ + uuid_map_t::iterator iter = mUUIDMap.find(image_id); + if(iter == mUUIDMap.end()) + return NULL; + return iter->second; +} + +void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image) +{ + llassert(image); + if (image->isInImageList()) + { + llerrs << "LLViewerTextureList::addImageToList - Image already in list" << llendl; + } + llverify((mImageList.insert(image)).second == true); + image->setInImageList(TRUE) ; +} + +void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image) +{ + llassert(image); + if (!image->isInImageList()) + { + llinfos << "RefCount: " << image->getNumRefs() << llendl ; + uuid_map_t::iterator iter = mUUIDMap.find(image->getID()); + if(iter == mUUIDMap.end() || iter->second != image) + { + llinfos << "Image is not in mUUIDMap!" << llendl ; + } + llerrs << "LLViewerTextureList::removeImageFromList - Image not in list" << llendl; + } + llverify(mImageList.erase(image) == 1); + image->setInImageList(FALSE) ; +} + +void LLViewerTextureList::addImage(LLViewerFetchedTexture *new_image) +{ + if (!new_image) + { + llwarning("No image to add to image list", 0); + return; + } + LLUUID image_id = new_image->getID(); + + LLViewerFetchedTexture *image = findImage(image_id); + if (image) + { + llwarns << "Image with ID " << image_id << " already in list" << llendl; + } + mNumImages++; + + addImageToList(new_image); + mUUIDMap[image_id] = new_image; +} + + +void LLViewerTextureList::deleteImage(LLViewerFetchedTexture *image) +{ + if( image) + { + if (image->hasCallbacks()) + { + mCallbackList.erase(image); + } + + llverify(mUUIDMap.erase(image->getID()) == 1); + mNumImages--; + removeImageFromList(image); + } +} + +/////////////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////// + +void LLViewerTextureList::dirtyImage(LLViewerFetchedTexture *image) +{ + mDirtyTextureList.insert(image); +} + +//////////////////////////////////////////////////////////////////////////// + +void LLViewerTextureList::updateImages(F32 max_time) +{ + LLViewerStats::getInstance()->mNumImagesStat.addValue(mNumImages); + LLViewerStats::getInstance()->mNumRawImagesStat.addValue(LLImageRaw::sRawImageCount); + LLViewerStats::getInstance()->mGLTexMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageGL::sGlobalTextureMemoryInBytes)); + LLViewerStats::getInstance()->mGLBoundMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageGL::sBoundTextureMemoryInBytes)); + LLViewerStats::getInstance()->mRawMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageRaw::sGlobalRawMemory)); + LLViewerStats::getInstance()->mFormattedMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageFormatted::sGlobalFormattedMemory)); + + updateImagesDecodePriorities(); + max_time -= updateImagesFetchTextures(max_time); + max_time = llmin(llmax(max_time, 0.001f*10.f*gFrameIntervalSeconds), 0.001f); + max_time -= updateImagesCreateTextures(max_time); + max_time = llmin(llmax(max_time, 0.001f*10.f*gFrameIntervalSeconds), 0.001f); + if (!mDirtyTextureList.empty()) + { + LLFastTimer t(LLFastTimer::FTM_IMAGE_MARK_DIRTY); + gPipeline.dirtyPoolObjectTextures(mDirtyTextureList); + mDirtyTextureList.clear(); + } + bool didone = false; + for (image_list_t::iterator iter = mCallbackList.begin(); + iter != mCallbackList.end(); ) + { + //trigger loaded callbacks on local textures immediately + LLViewerFetchedTexture* image = *iter++; + if (!image->getLocalFileName().empty()) + { + // Do stuff to handle callbacks, update priorities, etc. + didone = image->doLoadedCallbacks(); + } + else if (!didone) + { + // Do stuff to handle callbacks, update priorities, etc. + didone = image->doLoadedCallbacks(); + } + } + if (!gNoRender && !gGLManager.mIsDisabled) + { + LLViewerMedia::updateImagesMediaStreams(); + } + updateImagesUpdateStats(); +} + +void LLViewerTextureList::updateImagesDecodePriorities() +{ + // Update the decode priority for N images each frame + { + const size_t max_update_count = llmin((S32) (1024*gFrameIntervalSeconds) + 1, 32); //target 1024 textures per second + S32 update_counter = llmin(max_update_count, mUUIDMap.size()/10); + uuid_map_t::iterator iter = mUUIDMap.upper_bound(mLastUpdateUUID); + while(update_counter > 0 && !mUUIDMap.empty()) + { + if (iter == mUUIDMap.end()) + { + iter = mUUIDMap.begin(); + } + mLastUpdateUUID = iter->first; + LLPointer imagep = iter->second; + ++iter; // safe to incrament now + + // + // Flush formatted images using a lazy flush + // + const F32 LAZY_FLUSH_TIMEOUT = 30.f; // stop decoding + const F32 MAX_INACTIVE_TIME = 50.f; // actually delete + S32 min_refs = 3; // 1 for mImageList, 1 for mUUIDMap, 1 for local reference + if (imagep->hasCallbacks()) + { + min_refs++; // Add an extra reference if we're on the loaded callback list + } + S32 num_refs = imagep->getNumRefs(); + if (num_refs == min_refs) + { + if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > LAZY_FLUSH_TIMEOUT) + { + // Remove the unused image from the image list + deleteImage(imagep); + imagep = NULL; // should destroy the image + } + continue; + } + else + { + if(imagep->isDeleted()) + { + continue ; + } + else if(imagep->isDeletionCandidate()) + { + imagep->destroyTexture() ; + continue ; + } + else if(imagep->isInactive()) + { + if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > MAX_INACTIVE_TIME) + { + imagep->setDeletionCandidate() ; + } + continue ; + } + else + { + imagep->getLastReferencedTimer()->reset(); + + //reset texture state. + imagep->setInactive() ; + } + } + + imagep->processTextureStats(); + F32 old_priority = imagep->getDecodePriority(); + F32 old_priority_test = llmax(old_priority, 0.0f); + F32 decode_priority = imagep->calcDecodePriority(); + F32 decode_priority_test = llmax(decode_priority, 0.0f); + // Ignore < 20% difference + if ((decode_priority_test < old_priority_test * .8f) || + (decode_priority_test > old_priority_test * 1.25f)) + { + removeImageFromList(imagep); + imagep->setDecodePriority(decode_priority); + addImageToList(imagep); + } + update_counter--; + } + } +} + +/* + static U8 get_image_type(LLViewerFetchedTexture* imagep, LLHost target_host) + { + // Having a target host implies this is a baked image. I don't + // believe that boost level has been set at this point. JC + U8 type_from_host = (target_host.isOk() + ? LLImageBase::TYPE_AVATAR_BAKE + : LLImageBase::TYPE_NORMAL); + S32 boost_level = imagep->getBoostLevel(); + U8 type_from_boost = ( (boost_level == LLViewerFetchedTexture::BOOST_AVATAR_BAKED + || boost_level == LLViewerFetchedTexture::BOOST_AVATAR_BAKED_SELF) + ? LLImageBase::TYPE_AVATAR_BAKE + : LLImageBase::TYPE_NORMAL); + if (type_from_host == LLImageBase::TYPE_NORMAL + && type_from_boost == LLImageBase::TYPE_AVATAR_BAKE) + { + llwarns << "TAT: get_image_type() type_from_host doesn't match type_from_boost" + << " host " << target_host + << " boost " << imagep->getBoostLevel() + << " imageid " << imagep->getID() + << llendl; + imagep->dump(); + } + return type_from_host; + } + */ + +F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time) +{ + if (gNoRender || gGLManager.mIsDisabled) return 0.0f; + + // + // Create GL textures for all textures that need them (images which have been + // decoded, but haven't been pushed into GL). + // + LLFastTimer t(LLFastTimer::FTM_IMAGE_CREATE); + + LLTimer create_timer; + image_list_t::iterator enditer = mCreateTextureList.begin(); + for (image_list_t::iterator iter = mCreateTextureList.begin(); + iter != mCreateTextureList.end();) + { + image_list_t::iterator curiter = iter++; + enditer = iter; + LLViewerFetchedTexture *imagep = *curiter; + imagep->createTexture(); + if (create_timer.getElapsedTimeF32() > max_time) + { + break; + } + } + mCreateTextureList.erase(mCreateTextureList.begin(), enditer); + return create_timer.getElapsedTimeF32(); +} + +void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep) +{ + if(!imagep) + { + return ; + } + if(imagep->isInImageList()) + { + removeImageFromList(imagep); + } + + imagep->processTextureStats(); + F32 decode_priority = LLViewerFetchedTexture::maxDecodePriority() ; + imagep->setDecodePriority(decode_priority); + mImageList.insert(imagep); + imagep->setInImageList(TRUE) ; + + return ; +} + +F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) +{ + LLTimer image_op_timer; + + // Update the decode priority for N images each frame + // Make a list with 32 high priority entries + 256 cycled entries + const size_t max_priority_count = llmin((S32) (256*10.f*gFrameIntervalSeconds)+1, 32); + const size_t max_update_count = llmin((S32) (1024*10.f*gFrameIntervalSeconds)+1, 256); + + // 32 high priority entries + std::set entries; + size_t update_counter = llmin(max_priority_count, mImageList.size()); + image_priority_list_t::iterator iter1 = mImageList.begin(); + while(update_counter > 0) + { + // added extra granularity and verbosity for crash logging during 1.19.1 RC. -Brad + if(iter1 == mImageList.end()) + { + llerrs << "DEV-12002: update_counter not calculated correctly!" << llendl; + return 0.f; + } + + LLPointer const & ptr = *iter1; + + LLViewerFetchedTexture * img = ptr.get(); + + // added extra granularity and verbosity for crash logging during 1.19.1 RC. -Brad + if(img == NULL) + { + llwarns << "DEV-12002: image is NULL!" << llendl; + } + + entries.insert(img); + + ++iter1; + update_counter--; + } + + // 256 cycled entries + update_counter = llmin(max_update_count, mUUIDMap.size()); + uuid_map_t::iterator iter2 = mUUIDMap.upper_bound(mLastFetchUUID); + while(update_counter > 0) + { + if (iter2 == mUUIDMap.end()) + { + iter2 = mUUIDMap.begin(); + } + mLastFetchUUID = iter2->first; + entries.insert(iter2->second); + ++iter2; + update_counter--; + } + + S32 min_count = max_priority_count + max_update_count/4; + for (std::set::iterator iter3 = entries.begin(); + iter3 != entries.end(); ) + { + LLPointer imagep = *iter3++; + + imagep->updateFetch(); + if (min_count <= 0 && image_op_timer.getElapsedTimeF32() > max_time) + { + break; + } + min_count--; + } + return image_op_timer.getElapsedTimeF32(); +} + +void LLViewerTextureList::updateImagesUpdateStats() +{ + if (mUpdateStats) + { + for (image_priority_list_t::iterator iter = mImageList.begin(); + iter != mImageList.end(); ) + { + LLViewerFetchedTexture* imagep = *iter++; + imagep->resetTextureStats(mForceResetTextureStats); + } + mUpdateStats = FALSE; + mForceResetTextureStats = FALSE; + } +} + +void LLViewerTextureList::decodeAllImages(F32 max_time) +{ + LLTimer timer; + if(gNoRender) return; + + // Update texture stats and priorities + std::vector > image_list; + for (image_priority_list_t::iterator iter = mImageList.begin(); + iter != mImageList.end(); ) + { + LLViewerFetchedTexture* imagep = *iter++; + image_list.push_back(imagep); + imagep->setInImageList(FALSE) ; + } + mImageList.clear(); + for (std::vector >::iterator iter = image_list.begin(); + iter != image_list.end(); ++iter) + { + LLViewerFetchedTexture* imagep = *iter; + imagep->processTextureStats(); + F32 decode_priority = imagep->calcDecodePriority(); + imagep->setDecodePriority(decode_priority); + mImageList.insert(imagep); + imagep->setInImageList(TRUE) ; + } + image_list.clear(); + + // Update fetch (decode) + for (image_priority_list_t::iterator iter = mImageList.begin(); + iter != mImageList.end(); ) + { + LLViewerFetchedTexture* imagep = *iter++; + imagep->updateFetch(); + } + // Run threads + S32 fetch_pending = 0; + while (1) + { + LLAppViewer::instance()->getTextureCache()->update(1); // unpauses the texture cache thread + LLAppViewer::instance()->getImageDecodeThread()->update(1); // unpauses the image thread + fetch_pending = LLAppViewer::instance()->getTextureFetch()->update(1); // unpauses the texture fetch thread + if (fetch_pending == 0 || timer.getElapsedTimeF32() > max_time) + { + break; + } + } + // Update fetch again + for (image_priority_list_t::iterator iter = mImageList.begin(); + iter != mImageList.end(); ) + { + LLViewerFetchedTexture* imagep = *iter++; + imagep->updateFetch(); + } + max_time -= timer.getElapsedTimeF32(); + max_time = llmax(max_time, .001f); + F32 create_time = updateImagesCreateTextures(max_time); + + LL_DEBUGS("ViewerImages") << "decodeAllImages() took " << timer.getElapsedTimeF32() << " seconds. " + << " fetch_pending " << fetch_pending + << " create_time " << create_time + << LL_ENDL; +} + + +BOOL LLViewerTextureList::createUploadFile(const std::string& filename, + const std::string& out_filename, + const U8 codec) +{ + // First, load the image. + LLPointer raw_image = new LLImageRaw; + + switch (codec) + { + case IMG_CODEC_BMP: + { + LLPointer bmp_image = new LLImageBMP; + + if (!bmp_image->load(filename)) + { + return FALSE; + } + + if (!bmp_image->decode(raw_image, 0.0f)) + { + return FALSE; + } + } + break; + case IMG_CODEC_TGA: + { + LLPointer tga_image = new LLImageTGA; + + if (!tga_image->load(filename)) + { + return FALSE; + } + + if (!tga_image->decode(raw_image)) + { + return FALSE; + } + + if( (tga_image->getComponents() != 3) && + (tga_image->getComponents() != 4) ) + { + tga_image->setLastError( "Image files with less than 3 or more than 4 components are not supported." ); + return FALSE; + } + } + break; + case IMG_CODEC_JPEG: + { + LLPointer jpeg_image = new LLImageJPEG; + + if (!jpeg_image->load(filename)) + { + return FALSE; + } + + if (!jpeg_image->decode(raw_image, 0.0f)) + { + return FALSE; + } + } + break; + case IMG_CODEC_PNG: + { + LLPointer png_image = new LLImagePNG; + + if (!png_image->load(filename)) + { + return FALSE; + } + + if (!png_image->decode(raw_image, 0.0f)) + { + return FALSE; + } + } + break; + default: + return FALSE; + } + + LLPointer compressedImage = convertToUploadFile(raw_image); + + if( !compressedImage->save(out_filename) ) + { + llinfos << "Couldn't create output file " << out_filename << llendl; + return FALSE; + } + + // test to see if the encode and save worked. + LLPointer integrity_test = new LLImageJ2C; + if( !integrity_test->loadAndValidate( out_filename ) ) + { + llinfos << "Image: " << out_filename << " is corrupt." << llendl; + return FALSE; + } + + return TRUE; +} + +// note: modifies the argument raw_image!!!! +LLPointer LLViewerTextureList::convertToUploadFile(LLPointer raw_image) +{ + raw_image->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); + LLPointer compressedImage = new LLImageJ2C(); + compressedImage->setRate(0.f); + + if (gSavedSettings.getBOOL("LosslessJ2CUpload") && + (raw_image->getWidth() * raw_image->getHeight() <= LL_IMAGE_REZ_LOSSLESS_CUTOFF * LL_IMAGE_REZ_LOSSLESS_CUTOFF)) + compressedImage->setReversible(TRUE); + + compressedImage->encode(raw_image, 0.0f); + + return compressedImage; +} + +// Returns min setting for TextureMemory (in MB) +S32 LLViewerTextureList::getMinVideoRamSetting() +{ + S32 system_ram = (S32)BYTES_TO_MEGA_BYTES(gSysMemory.getPhysicalMemoryClamped()); + //min texture mem sets to 64M if total physical mem is more than 1.5GB + return (system_ram > 1500) ? 64 : MIN_VIDEO_RAM_IN_MEGA_BYTES ; +} + +//static +// Returns max setting for TextureMemory (in MB) +S32 LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended) +{ + S32 max_texmem; + if (gGLManager.mVRAM != 0) + { + // Treat any card with < 32 MB (shudder) as having 32 MB + // - it's going to be swapping constantly regardless + S32 max_vram = gGLManager.mVRAM; + max_vram = llmax(max_vram, getMinVideoRamSetting()); + max_texmem = max_vram; + if (!get_recommended) + max_texmem *= 2; + } + else + { + if (get_recommended) + max_texmem = 128; + else + max_texmem = 512; + llwarns << "VRAM amount not detected, defaulting to " << max_texmem << " MB" << llendl; + } + + S32 system_ram = (S32)BYTES_TO_MEGA_BYTES(gSysMemory.getPhysicalMemoryClamped()); // In MB + //llinfos << "*** DETECTED " << system_ram << " MB of system memory." << llendl; + if (get_recommended) + max_texmem = llmin(max_texmem, (S32)(system_ram/2)); + else + max_texmem = llmin(max_texmem, (S32)(system_ram)); + + max_texmem = llclamp(max_texmem, getMinVideoRamSetting(), MAX_VIDEO_RAM_IN_MEGA_BYTES); + + return max_texmem; +} + +const S32 VIDEO_CARD_FRAMEBUFFER_MEM = 12; // MB +const S32 MIN_MEM_FOR_NON_TEXTURE = 512 ; //MB +void LLViewerTextureList::updateMaxResidentTexMem(S32 mem) +{ + // Initialize the image pipeline VRAM settings + S32 cur_mem = gSavedSettings.getS32("TextureMemory"); + F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple"); + S32 default_mem = getMaxVideoRamSetting(true); // recommended default + if (mem == 0) + { + mem = cur_mem > 0 ? cur_mem : default_mem; + } + else if (mem < 0) + { + mem = default_mem; + } + + // limit the texture memory to a multiple of the default if we've found some cards to behave poorly otherwise + mem = llmin(mem, (S32) (mem_multiplier * (F32) default_mem)); + + mem = llclamp(mem, getMinVideoRamSetting(), getMaxVideoRamSetting()); + if (mem != cur_mem) + { + gSavedSettings.setS32("TextureMemory", mem); + return; //listener will re-enter this function + } + + // TODO: set available resident texture mem based on use by other subsystems + // currently max(12MB, VRAM/4) assumed... + + S32 vb_mem = mem; + S32 fb_mem = llmax(VIDEO_CARD_FRAMEBUFFER_MEM, vb_mem/4); + mMaxResidentTexMemInMegaBytes = (vb_mem - fb_mem) ; //in MB + + mMaxTotalTextureMemInMegaBytes = mMaxResidentTexMemInMegaBytes * 2; + if (mMaxResidentTexMemInMegaBytes > 640) + { + mMaxTotalTextureMemInMegaBytes -= (mMaxResidentTexMemInMegaBytes >> 2); + } + + //system mem + S32 system_ram = (S32)BYTES_TO_MEGA_BYTES(gSysMemory.getPhysicalMemoryClamped()); // In MB + + //minimum memory reserved for non-texture use. + //if system_raw >= 1GB, reserve at least 512MB for non-texture use; + //otherwise reserve half of the system_ram for non-texture use. + S32 min_non_texture_mem = llmin(system_ram / 2, MIN_MEM_FOR_NON_TEXTURE) ; + + if (mMaxTotalTextureMemInMegaBytes > system_ram - min_non_texture_mem) + { + mMaxTotalTextureMemInMegaBytes = system_ram - min_non_texture_mem ; + } + + llinfos << "Total Video Memory set to: " << vb_mem << " MB" << llendl; + llinfos << "Available Texture Memory set to: " << (vb_mem - fb_mem) << " MB" << llendl; +} + +/////////////////////////////////////////////////////////////////////////////// + +// static +void LLViewerTextureList::receiveImageHeader(LLMessageSystem *msg, void **user_data) +{ + LLFastTimer t(LLFastTimer::FTM_PROCESS_IMAGES); + + // Receive image header, copy into image object and decompresses + // if this is a one-packet image. + + LLUUID id; + + char ip_string[256]; + u32_to_ip_string(msg->getSenderIP(),ip_string); + + if (msg->getReceiveCompressedSize()) + { + gTextureList.mTextureBits += msg->getReceiveCompressedSize() * 8; + } + else + { + gTextureList.mTextureBits += msg->getReceiveSize() * 8; + } + gTextureList.mTexturePackets++; + + U8 codec; + U16 packets; + U32 totalbytes; + msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, id); + msg->getU8Fast(_PREHASH_ImageID, _PREHASH_Codec, codec); + msg->getU16Fast(_PREHASH_ImageID, _PREHASH_Packets, packets); + msg->getU32Fast(_PREHASH_ImageID, _PREHASH_Size, totalbytes); + + S32 data_size = msg->getSizeFast(_PREHASH_ImageData, _PREHASH_Data); + if (!data_size) + { + return; + } + if (data_size < 0) + { + // msg->getSizeFast() is probably trying to tell us there + // was an error. + llerrs << "image header chunk size was negative: " + << data_size << llendl; + return; + } + + // this buffer gets saved off in the packet list + U8 *data = new U8[data_size]; + msg->getBinaryDataFast(_PREHASH_ImageData, _PREHASH_Data, data, data_size); + + LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE); + if (!image) + { + delete [] data; + return; + } + image->getLastPacketTimer()->reset(); + bool res = LLAppViewer::getTextureFetch()->receiveImageHeader(msg->getSender(), id, codec, packets, totalbytes, data_size, data); + if (!res) + { + delete[] data; + } +} + +// static +void LLViewerTextureList::receiveImagePacket(LLMessageSystem *msg, void **user_data) +{ + LLMemType mt1(LLMemType::MTYPE_APPFMTIMAGE); + LLFastTimer t(LLFastTimer::FTM_PROCESS_IMAGES); + + // Receives image packet, copy into image object, + // checks if all packets received, decompresses if so. + + LLUUID id; + U16 packet_num; + + char ip_string[256]; + u32_to_ip_string(msg->getSenderIP(),ip_string); + + if (msg->getReceiveCompressedSize()) + { + gTextureList.mTextureBits += msg->getReceiveCompressedSize() * 8; + } + else + { + gTextureList.mTextureBits += msg->getReceiveSize() * 8; + } + gTextureList.mTexturePackets++; + + //llprintline("Start decode, image header..."); + msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, id); + msg->getU16Fast(_PREHASH_ImageID, _PREHASH_Packet, packet_num); + S32 data_size = msg->getSizeFast(_PREHASH_ImageData, _PREHASH_Data); + + if (!data_size) + { + return; + } + if (data_size < 0) + { + // msg->getSizeFast() is probably trying to tell us there + // was an error. + llerrs << "image data chunk size was negative: " + << data_size << llendl; + return; + } + if (data_size > MTUBYTES) + { + llerrs << "image data chunk too large: " << data_size << " bytes" << llendl; + return; + } + U8 *data = new U8[data_size]; + msg->getBinaryDataFast(_PREHASH_ImageData, _PREHASH_Data, data, data_size); + + LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE); + if (!image) + { + delete [] data; + return; + } + image->getLastPacketTimer()->reset(); + bool res = LLAppViewer::getTextureFetch()->receiveImagePacket(msg->getSender(), id, packet_num, data_size, data); + if (!res) + { + delete[] data; + } +} + + +// We've been that the asset server does not contain the requested image id. +// static +void LLViewerTextureList::processImageNotInDatabase(LLMessageSystem *msg,void **user_data) +{ + LLFastTimer t(LLFastTimer::FTM_PROCESS_IMAGES); + LLUUID image_id; + msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, image_id); + + LLViewerFetchedTexture* image = gTextureList.findImage( image_id ); + if( image ) + { + image->setIsMissingAsset(); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +//static +const U32 SIXTEEN_MEG = 0x1000000; +S32 LLViewerTextureList::calcMaxTextureRAM() +{ + // Decide the maximum amount of RAM we should allow the user to allocate to texture cache + LLMemoryInfo memory_info; + U32 available_memory = memory_info.getPhysicalMemoryClamped(); + + clamp_rescale((F32)available_memory, + (F32)(SIXTEEN_MEG * 16), + (F32)U32_MAX, + (F32)(SIXTEEN_MEG * 4), + (F32)(U32_MAX >> 1)); + return available_memory; +} + +/////////////////////////////////////////////////////////////////////////////// + +// explicitly cleanup resources, as this is a singleton class with process +// lifetime so ability to perform std::map operations in destructor is not +// guaranteed. +void LLUIImageList::cleanUp() +{ + mUIImages.clear(); + mUITextureList.clear() ; +} + +LLUIImagePtr LLUIImageList::getUIImageByID(const LLUUID& image_id) +{ + // use id as image name + std::string image_name = image_id.asString(); + + // look for existing image + uuid_ui_image_map_t::iterator found_it = mUIImages.find(image_name); + if (found_it != mUIImages.end()) + { + return found_it->second; + } + + return loadUIImageByID(image_id); +} + +LLUIImagePtr LLUIImageList::getUIImage(const std::string& image_name) +{ + // look for existing image + uuid_ui_image_map_t::iterator found_it = mUIImages.find(image_name); + if (found_it != mUIImages.end()) + { + return found_it->second; + } + + return loadUIImageByName(image_name, image_name); +} + +LLUIImagePtr LLUIImageList::loadUIImageByName(const std::string& name, const std::string& filename, BOOL use_mips, const LLRect& scale_rect) +{ + LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTextureFromFile(filename, MIPMAP_NO, IMMEDIATE_YES); + return loadUIImage(imagep, name, use_mips, scale_rect); +} + +LLUIImagePtr LLUIImageList::loadUIImageByID(const LLUUID& id, BOOL use_mips, const LLRect& scale_rect) +{ + LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(id, MIPMAP_NO, IMMEDIATE_YES); + return loadUIImage(imagep, id.asString(), use_mips, scale_rect); +} + +LLUIImagePtr LLUIImageList::loadUIImage(LLViewerFetchedTexture* imagep, const std::string& name, BOOL use_mips, const LLRect& scale_rect) +{ + if (!imagep) return NULL; + + imagep->setAddressMode(LLTexUnit::TAM_CLAMP); + + //all UI images are non-deletable + imagep->setNoDelete() ; + + LLUIImagePtr new_imagep = new LLUIImage(name, imagep); + mUIImages.insert(std::make_pair(name, new_imagep)); + mUITextureList.push_back(imagep) ; + + LLUIImageLoadData* datap = new LLUIImageLoadData; + datap->mImageName = name; + datap->mImageScaleRegion = scale_rect; + + imagep->setLoadedCallback(onUIImageLoaded, 0, FALSE, FALSE, datap); + + return new_imagep; +} + +LLUIImagePtr LLUIImageList::preloadUIImage(const std::string& name, const std::string& filename, BOOL use_mips, const LLRect& scale_rect) +{ + // look for existing image + uuid_ui_image_map_t::iterator found_it = mUIImages.find(name); + if (found_it != mUIImages.end()) + { + // image already loaded! + llerrs << "UI Image " << name << " already loaded." << llendl; + } + + return loadUIImageByName(name, filename, use_mips, scale_rect); +} + +//static +void LLUIImageList::onUIImageLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* user_data ) +{ + if(!success || !user_data) + { + return; + } + + LLUIImageLoadData* image_datap = (LLUIImageLoadData*)user_data; + std::string ui_image_name = image_datap->mImageName; + LLRect scale_rect = image_datap->mImageScaleRegion; + if (final) + { + delete image_datap; + } + + LLUIImageList* instance = getInstance(); + + uuid_ui_image_map_t::iterator found_it = instance->mUIImages.find(ui_image_name); + if (found_it != instance->mUIImages.end()) + { + LLUIImagePtr imagep = found_it->second; + + // for images grabbed from local files, apply clipping rectangle to restore original dimensions + // from power-of-2 gl image + if (success && imagep.notNull() && src_vi && !src_vi->getLocalFileName().empty()) + { + F32 clip_x = (F32)src_vi->getOriginalWidth() / (F32)src_vi->getFullWidth(); + F32 clip_y = (F32)src_vi->getOriginalHeight() / (F32)src_vi->getFullHeight(); + imagep->setClipRegion(LLRectf(0.f, clip_y, clip_x, 0.f)); + if (scale_rect != LLRect::null) + { + imagep->setScaleRegion( + LLRectf(llclamp((F32)scale_rect.mLeft / (F32)imagep->getWidth(), 0.f, 1.f), + llclamp((F32)scale_rect.mTop / (F32)imagep->getHeight(), 0.f, 1.f), + llclamp((F32)scale_rect.mRight / (F32)imagep->getWidth(), 0.f, 1.f), + llclamp((F32)scale_rect.mBottom / (F32)imagep->getHeight(), 0.f, 1.f))); + } + } + } +} + +struct UIImageDeclaration : public LLInitParam::Block +{ + Mandatory name; + Optional file_name; + Optional preload; + Optional scale_rect; + Optional use_mips; + + UIImageDeclaration() + : name("name"), + file_name("file_name"), + preload("preload", false), + scale_rect("scale"), + use_mips("use_mips", false) + {} +}; + +struct UIImageDeclarations : public LLInitParam::Block +{ + Mandatory version; + Multiple textures; + + UIImageDeclarations() + : version("version"), + textures("texture") + {} +}; + +bool LLUIImageList::initFromFile() +{ + // construct path to canonical textures.xml in default skin dir + std::string base_file_path = gDirUtilp->getExpandedFilename(LL_PATH_SKINS, "default", "textures", "textures.xml"); + + LLXMLNodePtr root; + + if (!LLXMLNode::parseFile(base_file_path, root, NULL)) + { + llwarns << "Unable to parse UI image list file " << base_file_path << llendl; + return false; + } + + std::vector paths; + // path to current selected skin + paths.push_back(gDirUtilp->getSkinDir() + + gDirUtilp->getDirDelimiter() + + "textures" + + gDirUtilp->getDirDelimiter() + + "textures.xml"); + // path to user overrides on current skin + paths.push_back(gDirUtilp->getUserSkinDir() + + gDirUtilp->getDirDelimiter() + + "textures" + + gDirUtilp->getDirDelimiter() + + "textures.xml"); + + // apply skinned xml files incrementally + for(std::vector::iterator path_it = paths.begin(); + path_it != paths.end(); + ++path_it) + { + // don't reapply base file to itself + if (!path_it->empty() && (*path_it) != base_file_path) + { + LLXMLNodePtr update_root; + if (LLXMLNode::parseFile(*path_it, update_root, NULL)) + { + LLXMLNode::updateNode(root, update_root); + } + } + } + + UIImageDeclarations images; + LLXUIParser::instance().readXUI(root, images); + + if (!images.validateBlock()) return false; + + enum e_decode_pass + { + PASS_DECODE_NOW, + PASS_DECODE_LATER, + NUM_PASSES + }; + + for (S32 cur_pass = PASS_DECODE_NOW; cur_pass < NUM_PASSES; cur_pass++) + { + for (LLInitParam::ParamIterator::const_iterator image_it = images.textures().begin(); + image_it != images.textures().end(); + ++image_it) + { + std::string file_name = image_it->file_name.isProvided() ? image_it->file_name() : image_it->name(); + + // load high priority textures on first pass (to kick off decode) + enum e_decode_pass decode_pass = image_it->preload ? PASS_DECODE_NOW : PASS_DECODE_LATER; + if (decode_pass != cur_pass) + { + continue; + } + preloadUIImage(image_it->name, file_name, image_it->use_mips, image_it->scale_rect); + } + + if (cur_pass == PASS_DECODE_NOW && !gSavedSettings.getBOOL("NoPreload")) + { + gTextureList.decodeAllImages(10.f); // decode preloaded images + } + } + return true; +} + + diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h new file mode 100644 index 0000000000..11d1dd855f --- /dev/null +++ b/indra/newview/llviewertexturelist.h @@ -0,0 +1,243 @@ +/** + * @file llviewertexturelist.h + * @brief Object for managing the list of images within a region + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2009, 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$ + */ + +#ifndef LL_LLVIEWERTEXTURELIST_H +#define LL_LLVIEWERTEXTURELIST_H + +#include "lluuid.h" +//#include "message.h" +#include "llgl.h" +#include "llstat.h" +#include "llviewertexture.h" +#include "llui.h" +#include +#include + +const U32 LL_IMAGE_REZ_LOSSLESS_CUTOFF = 128; + +const BOOL MIPMAP_YES = TRUE; +const BOOL MIPMAP_NO = FALSE; + +const BOOL GL_TEXTURE_YES = TRUE; +const BOOL GL_TEXTURE_NO = FALSE; + +const BOOL IMMEDIATE_YES = TRUE; +const BOOL IMMEDIATE_NO = FALSE; + +class LLImageJ2C; +class LLMessageSystem; +class LLTextureView; + +typedef void (*LLImageCallback)(BOOL success, + LLViewerFetchedTexture *src_vi, + LLImageRaw* src, + LLImageRaw* src_aux, + S32 discard_level, + BOOL final, + void* userdata); + +class LLViewerTextureList +{ + LOG_CLASS(LLViewerTextureList); + + friend class LLTextureView; + friend class LLViewerTextureManager; + +public: + static BOOL createUploadFile(const std::string& filename, const std::string& out_filename, const U8 codec); + static LLPointer convertToUploadFile(LLPointer raw_image); + static void processImageNotInDatabase( LLMessageSystem *msg, void **user_data ); + static S32 calcMaxTextureRAM(); + static void receiveImageHeader(LLMessageSystem *msg, void **user_data); + static void receiveImagePacket(LLMessageSystem *msg, void **user_data); + +public: + LLViewerTextureList(); + ~LLViewerTextureList(); + + void init(); + void shutdown(); + void dump(); + void destroyGL(BOOL save_state = TRUE); + void restoreGL(); + + LLViewerFetchedTexture *findImage(const LLUUID &image_id); + + void dirtyImage(LLViewerFetchedTexture *image); + + // Using image stats, determine what images are necessary, and perform image updates. + void updateImages(F32 max_time); + void forceImmediateUpdate(LLViewerFetchedTexture* imagep) ; + + // Decode and create textures for all images currently in list. + void decodeAllImages(F32 max_decode_time); + + void handleIRCallback(void **data, const S32 number); + + void setUpdateStats(BOOL b) { mUpdateStats = b; } + + S32 getMaxResidentTexMem() const { return mMaxResidentTexMemInMegaBytes; } + S32 getMaxTotalTextureMem() const { return mMaxTotalTextureMemInMegaBytes;} + S32 getNumImages() { return mImageList.size(); } + + void updateMaxResidentTexMem(S32 mem); + + void doPreloadImages(); + void doPrefetchImages(); + + static S32 getMinVideoRamSetting(); + static S32 getMaxVideoRamSetting(bool get_recommended = false); + +private: + void updateImagesDecodePriorities(); + F32 updateImagesCreateTextures(F32 max_time); + F32 updateImagesFetchTextures(F32 max_time); + void updateImagesUpdateStats(); + + void addImage(LLViewerFetchedTexture *image); + void deleteImage(LLViewerFetchedTexture *image); + + void addImageToList(LLViewerFetchedTexture *image); + void removeImageFromList(LLViewerFetchedTexture *image); + + LLViewerFetchedTexture * getImage(const LLUUID &image_id, + BOOL usemipmap = TRUE, + BOOL level_immediate = FALSE, // Get the requested level immediately upon creation. + S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, + LLGLint internal_format = 0, + LLGLenum primary_format = 0, + LLHost request_from_host = LLHost() + ); + + LLViewerFetchedTexture * getImageFromFile(const std::string& filename, + BOOL usemipmap = TRUE, + BOOL level_immediate = FALSE, // Get the requested level immediately upon creation. + S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, + LLGLint internal_format = 0, + LLGLenum primary_format = 0, + const LLUUID& force_id = LLUUID::null + ); + + LLViewerFetchedTexture* createImage(const LLUUID &image_id, + BOOL usemipmap = TRUE, + BOOL level_immediate = FALSE, // Get the requested level immediately upon creation. + S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, + LLGLint internal_format = 0, + LLGLenum primary_format = 0, + LLHost request_from_host = LLHost() + ); + + // Request image from a specific host, used for baked avatar textures. + // Implemented in header in case someone changes default params above. JC + LLViewerFetchedTexture* getImageFromHost(const LLUUID& image_id, LLHost host) + { return getImage(image_id, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE, 0, 0, host); } + +public: + typedef std::set > image_list_t; + image_list_t mLoadingStreamList; + image_list_t mCreateTextureList; + image_list_t mCallbackList; + + // Note: just raw pointers because they are never referenced, just compared against + std::set mDirtyTextureList; + + BOOL mForceResetTextureStats; + +private: + typedef std::map< LLUUID, LLPointer > uuid_map_t; + uuid_map_t mUUIDMap; + LLUUID mLastUpdateUUID; + LLUUID mLastFetchUUID; + + typedef std::set, LLViewerFetchedTexture::Compare> image_priority_list_t; + image_priority_list_t mImageList; + + // simply holds on to LLViewerFetchedTexture references to stop them from being purged too soon + std::set > mImagePreloads; + + BOOL mUpdateStats; + S32 mMaxResidentTexMemInMegaBytes; + S32 mMaxTotalTextureMemInMegaBytes; + LLFrameTimer mForceDecodeTimer; + +public: + U32 mTextureBits; + U32 mTexturePackets; + +private: + S32 mNumImages; + static void (*sUUIDCallback)(void**, const LLUUID &); +}; + +class LLUIImageList : public LLImageProviderInterface, public LLSingleton +{ +public: + // LLImageProviderInterface + LLUIImagePtr getUIImageByID(const LLUUID& id); + LLUIImagePtr getUIImage(const std::string& name); + void cleanUp(); + + bool initFromFile(); + + LLUIImagePtr preloadUIImage(const std::string& name, const std::string& filename, BOOL use_mips, const LLRect& scale_rect); + + static void onUIImageLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata ); +private: + LLUIImagePtr loadUIImageByName(const std::string& name, const std::string& filename, BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null); + LLUIImagePtr loadUIImageByID(const LLUUID& id, BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null); + + LLUIImagePtr loadUIImage(LLViewerFetchedTexture* imagep, const std::string& name, BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null); + + + struct LLUIImageLoadData + { + std::string mImageName; + LLRect mImageScaleRegion; + }; + + typedef std::map< std::string, LLPointer > uuid_ui_image_map_t; + uuid_ui_image_map_t mUIImages; + + // + //keep a copy of UI textures to prevent them to be deleted. + //mGLTexturep of each UI texture equals to some LLUIImage.mImage. + std::list< LLPointer > mUITextureList ; +}; + +const BOOL GLTEXTURE_TRUE = TRUE; +const BOOL GLTEXTURE_FALSE = FALSE; +const BOOL MIPMAP_TRUE = TRUE; +const BOOL MIPMAP_FALSE = FALSE; + +extern LLViewerTextureList gTextureList; + +#endif diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 2caa8f2309..637d072cf4 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -161,7 +161,7 @@ #include "llvieweraudio.h" #include "llviewercamera.h" #include "llviewergesture.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerinventory.h" #include "llviewerkeyboard.h" #include "llviewermenu.h" @@ -1356,8 +1356,8 @@ LLViewerWindow::LLViewerWindow( // Init the image list. Must happen after GL is initialized and before the images that // LLViewerWindow needs are requested. - gImageList.init(); - LLViewerImage::initClass(); + gTextureList.init(); + LLViewerTextureManager::init() ; gBumpImageList.init(); // Init font system, but don't actually load the fonts yet @@ -1687,7 +1687,7 @@ void LLViewerWindow::shutdownGL() gSky.cleanup(); stop_glerror(); - gImageList.shutdown(); + gTextureList.shutdown(); stop_glerror(); gBumpImageList.shutdown(); @@ -1699,7 +1699,7 @@ void LLViewerWindow::shutdownGL() gPipeline.cleanup(); stop_glerror(); - LLViewerImage::cleanupClass(); + LLViewerTextureManager::cleanup() ; llinfos << "Cleaning up select manager" << llendl; LLSelectMgr::getInstance()->cleanup(); @@ -4439,7 +4439,7 @@ void LLViewerWindow::stopGL(BOOL save_state) //Note: --bao //if not necessary, do not change the order of the function calls in this function. //if change something, make sure it will not break anything. - //especially be careful to put anything behind gImageList.destroyGL(save_state); + //especially be careful to put anything behind gTextureList.destroyGL(save_state); if (!gGLManager.mIsDisabled) { llinfos << "Shutting down GL..." << llendl; @@ -4464,7 +4464,7 @@ void LLViewerWindow::stopGL(BOOL save_state) LLVOAvatar::destroyGL(); stop_glerror(); - LLDynamicTexture::destroyGL(); + LLViewerDynamicTexture::destroyGL(); stop_glerror(); if (gPipeline.isInit()) @@ -4482,9 +4482,9 @@ void LLViewerWindow::stopGL(BOOL save_state) gPostProcess->invalidate(); } - gImageList.destroyGL(save_state); + gTextureList.destroyGL(save_state); stop_glerror(); - + gGLManager.mIsDisabled = TRUE; stop_glerror(); @@ -4497,7 +4497,7 @@ void LLViewerWindow::restoreGL(const std::string& progress_message) //Note: --bao //if not necessary, do not change the order of the function calls in this function. //if change something, make sure it will not break anything. - //especially, be careful to put something before gImageList.restoreGL(); + //especially, be careful to put something before gTextureList.restoreGL(); if (gGLManager.mIsDisabled) { llinfos << "Restoring GL..." << llendl; @@ -4505,8 +4505,9 @@ void LLViewerWindow::restoreGL(const std::string& progress_message) initGLDefaults(); LLGLState::restoreGL(); - gImageList.restoreGL(); - + + gTextureList.restoreGL(); + // for future support of non-square pixels, and fonts that are properly stretched //LLFontGL::destroyDefaultFonts(); initFonts(); @@ -4517,7 +4518,7 @@ void LLViewerWindow::restoreGL(const std::string& progress_message) LLManipTranslate::restoreGL(); gBumpImageList.restoreGL(); - LLDynamicTexture::restoreGL(); + LLViewerDynamicTexture::restoreGL(); LLVOAvatar::restoreGL(); gResizeScreenTexture = TRUE; @@ -5104,7 +5105,7 @@ void LLPickInfo::updateXYCoords() if (mObjectFace > -1) { const LLTextureEntry* tep = getObject()->getTE(mObjectFace); - LLPointer imagep = gImageList.getImage(tep->getID()); + LLPointer imagep = LLViewerTextureManager::getFetchedTexture(tep->getID()); if(mUVCoords.mV[VX] >= 0.f && mUVCoords.mV[VY] >= 0.f && imagep.notNull()) { LLCoordGL coords; diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index e52fec7909..f26ba6f46e 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -39,8 +39,8 @@ #include "v3math.h" #include "llsurface.h" #include "lltextureview.h" -#include "llviewerimage.h" -#include "llviewerimagelist.h" +#include "llviewertexture.h" +#include "llviewertexturelist.h" #include "llviewerregion.h" #include "noise.h" #include "llregionhandle.h" // for from_region_handle @@ -106,7 +106,7 @@ void LLVLComposition::setDetailTextureID(S32 corner, const LLUUID& id) { return; } - mDetailTextures[corner] = gImageList.getImage(id); + mDetailTextures[corner] = LLViewerTextureManager::getFetchedTexture(id); mDetailTextures[corner]->setNoDelete() ; mRawImages[corner] = NULL; } @@ -229,7 +229,7 @@ BOOL LLVLComposition::generateComposition() { if (mDetailTextures[i]->getDiscardLevel() < 0) { - mDetailTextures[i]->setBoostLevel(LLViewerImage::BOOST_TERRAIN); // in case we are at low detail + mDetailTextures[i]->setBoostLevel(LLViewerTexture::BOOST_TERRAIN); // in case we are at low detail mDetailTextures[i]->addTextureStats(BASE_SIZE*BASE_SIZE); return FALSE; } @@ -237,8 +237,8 @@ BOOL LLVLComposition::generateComposition() (mDetailTextures[i]->getWidth() < BASE_SIZE || mDetailTextures[i]->getHeight() < BASE_SIZE))) { - S32 width = mDetailTextures[i]->getWidth(0); - S32 height = mDetailTextures[i]->getHeight(0); + S32 width = mDetailTextures[i]->getFullWidth(); + S32 height = mDetailTextures[i]->getFullHeight(); S32 min_dim = llmin(width, height); S32 ddiscard = 0; while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL) @@ -246,7 +246,7 @@ BOOL LLVLComposition::generateComposition() ddiscard++; min_dim /= 2; } - mDetailTextures[i]->setBoostLevel(LLViewerImage::BOOST_TERRAIN); // in case we are at low detail + mDetailTextures[i]->setBoostLevel(LLViewerTexture::BOOST_TERRAIN); // in case we are at low detail mDetailTextures[i]->setMinDiscardLevel(ddiscard); return FALSE; } @@ -280,7 +280,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, { // Read back a raw image for this discard level, if it exists mRawImages[i] = new LLImageRaw; - S32 min_dim = llmin(mDetailTextures[i]->getWidth(0), mDetailTextures[i]->getHeight(0)); + S32 min_dim = llmin(mDetailTextures[i]->getFullWidth(), mDetailTextures[i]->getFullHeight()); S32 ddiscard = 0; while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL) { @@ -336,7 +336,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, // // - LLViewerImage *texturep; + LLViewerTexture *texturep; U32 tex_width, tex_height, tex_comps; U32 tex_stride; F32 tex_x_scalef, tex_y_scalef; @@ -455,7 +455,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, for (S32 i = 0; i < 4; i++) { // Un-boost detatil textures (will get re-boosted if rendering in high detail) - mDetailTextures[i]->setBoostLevel(LLViewerImage::BOOST_NONE); + mDetailTextures[i]->setBoostLevel(LLViewerTexture::BOOST_NONE); mDetailTextures[i]->setMinDiscardLevel(MAX_DISCARD_LEVEL + 1); } @@ -467,7 +467,7 @@ LLUUID LLVLComposition::getDetailTextureID(S32 corner) return mDetailTextures[corner]->getID(); } -LLViewerImage* LLVLComposition::getDetailTexture(S32 corner) +LLViewerFetchedTexture* LLVLComposition::getDetailTexture(S32 corner) { return mDetailTextures[corner]; } diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h index 6d5db3c050..d1b3dc4495 100644 --- a/indra/newview/llvlcomposition.h +++ b/indra/newview/llvlcomposition.h @@ -34,7 +34,7 @@ #define LL_LLVLCOMPOSITION_H #include "llviewerlayer.h" -#include "llviewerimage.h" +#include "llviewertexture.h" class LLSurface; @@ -62,7 +62,7 @@ public: CORNER_COUNT = 4 }; LLUUID getDetailTextureID(S32 corner); - LLViewerImage* getDetailTexture(S32 corner); + LLViewerFetchedTexture* getDetailTexture(S32 corner); F32 getStartHeight(S32 corner); F32 getHeightRange(S32 corner); @@ -79,7 +79,7 @@ protected: LLSurface *mSurfacep; BOOL mTexturesLoaded; - LLPointer mDetailTextures[CORNER_COUNT]; + LLPointer mDetailTextures[CORNER_COUNT]; LLPointer mRawImages[CORNER_COUNT]; F32 mStartHeight[CORNER_COUNT]; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index e351c904e6..258061190b 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -67,7 +67,7 @@ #include "lltexlayer.h" #include "lltoolmorph.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewermenu.h" #include "llviewerobjectlist.h" #include "llviewerparcelmgr.h" @@ -717,8 +717,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mRippleTimeLast = 0.f; - mShadowImagep = gImageList.getImageFromFile("foot_shadow.j2c"); - gGL.getTexUnit(0)->bind(mShadowImagep.get()); + mShadowImagep = LLViewerTextureManager::getFetchedTextureFromFile("foot_shadow.j2c"); + gGL.getTexUnit(0)->bind(mShadowImagep); mShadowImagep->setAddressMode(LLTexUnit::TAM_CLAMP); mInAir = FALSE; @@ -2499,7 +2499,7 @@ void LLVOAvatar::idleUpdateLoadingEffect() particle_parameters.mPartData.mStartColor = LLColor4(1, 1, 1, 0.5f); particle_parameters.mPartData.mEndColor = LLColor4(1, 1, 1, 0.0f); particle_parameters.mPartData.mStartScale.mV[VX] = 0.8f; - LLViewerImage* cloud = gImageList.getImageFromFile("cloud-particle.j2c"); + LLViewerTexture* cloud = LLViewerTextureManager::getFetchedTextureFromFile("cloud-particle.j2c"); particle_parameters.mPartImageID = cloud->getID(); particle_parameters.mMaxAge = 0.f; particle_parameters.mPattern = LLPartSysData::LL_PART_SRC_PATTERN_ANGLE_CONE; @@ -3869,7 +3869,7 @@ U32 LLVOAvatar::renderFootShadows() LLGLDepthTest test(GL_TRUE, GL_FALSE); //render foot shadows LLGLEnable blend(GL_BLEND); - gGL.getTexUnit(0)->bind(mShadowImagep.get()); + gGL.getTexUnit(0)->bind(mShadowImagep); glColor4fv(mShadow0Facep->getRenderColor().mV); mShadow0Facep->renderIndexed(foot_mask); glColor4fv(mShadow1Facep->getRenderColor().mV); @@ -3945,7 +3945,7 @@ void LLVOAvatar::updateTextures(LLAgent &agent) { if (layer_baked[i] && !mBakedTextureDatas[i].mIsLoaded) { - gGL.getTexUnit(0)->bind(getImage(mBakedTextureDatas[i].mTextureIndex)); + gGL.getTexUnit(0)->bind(getImage( mBakedTextureDatas[i].mTextureIndex )); } } } @@ -3955,7 +3955,7 @@ void LLVOAvatar::updateTextures(LLAgent &agent) mHasGrey = FALSE; // debug for (U32 index = 0; index < getNumTEs(); index++) { - LLViewerImage *imagep = getImage(index); + LLViewerFetchedTexture *imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(index), TRUE); if (imagep) { const LLTextureEntry *te = getTE(index); @@ -4007,15 +4007,15 @@ void LLVOAvatar::updateTextures(LLAgent &agent) } -void LLVOAvatar::addLocalTextureStats(ETextureIndex idx, LLViewerImage* imagep, - F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked, U32 index) +void LLVOAvatar::addLocalTextureStats( ETextureIndex idx, LLViewerFetchedTexture* imagep, + F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked, U32 index ) { // No local texture stats for non-self avatars return; } -void LLVOAvatar::addBakedTextureStats( LLViewerImage* imagep, F32 pixel_area, F32 texel_area_ratio, S32 boost_level) +void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel_area, F32 texel_area_ratio, S32 boost_level) { mMaxPixelArea = llmax(pixel_area, mMaxPixelArea); mMinPixelArea = llmin(pixel_area, mMinPixelArea); @@ -4024,13 +4024,13 @@ void LLVOAvatar::addBakedTextureStats( LLViewerImage* imagep, F32 pixel_area, F3 } //virtual -void LLVOAvatar::setImage(const U8 te, LLViewerImage *imagep) +void LLVOAvatar::setImage(const U8 te, LLViewerTexture *imagep) { setTEImage(te, imagep); } //virtual -LLViewerImage* LLVOAvatar::getImage(const U8 te) const +LLViewerTexture* LLVOAvatar::getImage(const U8 te) const { return getTEImage(te); } @@ -5213,7 +5213,7 @@ void LLVOAvatar::updateShadowFaces() sprite.setSize(0.4f + cos_elev * 0.8f, 0.3f); LLVector3 sun_vec = gSky.mVOSkyp ? gSky.mVOSkyp->getToSun() : LLVector3(0.f, 0.f, 0.f); - if (mShadowImagep->getHasGLTexture()) + if (mShadowImagep->hasValidGLTexture()) { LLVector3 normal; LLVector3d shadow_pos; @@ -5772,10 +5772,10 @@ void LLVOAvatar::updateMeshTextures() // if user has never specified a texture, assign the default for (U32 i=0; i < getNumTEs(); i++) { - const LLViewerImage* te_image = getImage(i); + const LLViewerTexture* te_image = getImage(i); if(!te_image || te_image->getID().isNull() || (te_image->getID() == IMG_DEFAULT)) { - setImage(i, gImageList.getImage(i == TEX_HAIR ? IMG_DEFAULT : IMG_DEFAULT_AVATAR)); // IMG_DEFAULT_AVATAR = a special texture that's never rendered. + setImage(i, LLViewerTextureManager::getFetchedTexture(i == TEX_HAIR ? IMG_DEFAULT : IMG_DEFAULT_AVATAR)); // IMG_DEFAULT_AVATAR = a special texture that's never rendered. } } @@ -5829,7 +5829,7 @@ void LLVOAvatar::updateMeshTextures() { if (use_lkg_baked_layer[i] && !self_customizing ) { - LLViewerImage* baked_img = gImageList.getImageFromHost( mBakedTextureDatas[i].mLastTextureIndex, target_host ); + LLViewerFetchedTexture* baked_img = LLViewerTextureManager::getFetchedTextureFromHost( mBakedTextureDatas[i].mLastTextureIndex, target_host ); mBakedTextureDatas[i].mIsUsed = TRUE; for (U32 k=0; k < mBakedTextureDatas[i].mMeshes.size(); k++) { @@ -5838,7 +5838,7 @@ void LLVOAvatar::updateMeshTextures() } else if (!self_customizing && is_layer_baked[i]) { - LLViewerImage* baked_img = getImage( mBakedTextureDatas[i].mTextureIndex ); + LLViewerFetchedTexture* baked_img = LLViewerTextureManager::staticCastToFetchedTexture(getImage( mBakedTextureDatas[i].mTextureIndex ), TRUE) ; if( baked_img->getID() == mBakedTextureDatas[i].mLastTextureIndex ) { // Even though the file may not be finished loading, we'll consider it loaded and use it (rather than doing compositing). @@ -5873,7 +5873,7 @@ void LLVOAvatar::updateMeshTextures() if (!is_layer_baked[BAKED_HAIR] || self_customizing) { const LLColor4 color = mTexHairColor ? mTexHairColor->getColor() : LLColor4(1,1,1,1); - LLViewerImage* hair_img = getImage( TEX_HAIR ); + LLViewerTexture* hair_img = getImage( TEX_HAIR ); for (U32 i = 0; i < mBakedTextureDatas[BAKED_HAIR].mMeshes.size(); i++) { mBakedTextureDatas[BAKED_HAIR].mMeshes[i]->setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] ); @@ -5907,7 +5907,7 @@ void LLVOAvatar::updateMeshTextures() //----------------------------------------------------------------------------- // setLocalTexture() //----------------------------------------------------------------------------- -void LLVOAvatar::setLocalTexture(ETextureIndex type, LLViewerImage* tex, BOOL baked_version_exists, U32 index) +void LLVOAvatar::setLocalTexture( ETextureIndex type, LLViewerTexture* in_tex, BOOL baked_version_ready, U32 index ) { // invalid for anyone but self llassert(0); @@ -6153,7 +6153,7 @@ void LLVOAvatar::dumpAvatarTEs( const std::string& context ) iter++) { const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second; - const LLViewerImage* te_image = getImage(iter->first); + const LLViewerTexture* te_image = getImage(iter->first); if( !te_image ) { llinfos << " " << texture_dict->mName << ": null ptr" << llendl; @@ -6319,7 +6319,7 @@ void LLVOAvatar::onFirstTEMessageReceived() // (That is, don't do a transition from unbaked to baked.) if (layer_baked) { - LLViewerImage* image = getImage( mBakedTextureDatas[i].mTextureIndex ); + LLViewerFetchedTexture* image = LLViewerTextureManager::staticCastToFetchedTexture(getImage( mBakedTextureDatas[i].mTextureIndex ), TRUE) ; mBakedTextureDatas[i].mLastTextureIndex = image->getID(); // If we have more than one texture for the other baked layers, we'll want to call this for them too. if ( (i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER) ) @@ -6381,7 +6381,8 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) && mBakedTextureDatas[baked_index].mLastTextureIndex != IMG_DEFAULT && baked_index != BAKED_SKIRT) { - setTEImage(mBakedTextureDatas[baked_index].mTextureIndex, gImageList.getImage(mBakedTextureDatas[baked_index].mLastTextureIndex)); + setTEImage(mBakedTextureDatas[baked_index].mTextureIndex, + LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[baked_index].mLastTextureIndex, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE)); } } @@ -6518,7 +6519,7 @@ void LLVOAvatar::getAnimNames( LLDynamicArray* names ) names->put( "enter_away_from_keyboard_state" ); } -void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) +void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) { if (!userdata) return; @@ -6571,7 +6572,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerImage *src_vi, if (texture_dict->mIsUsedByBakedTexture) { const ETextureIndex texture_index = iter->first; - const LLViewerImage *baked_img = self->getImage(texture_index); + const LLViewerTexture *baked_img = self->getImage(texture_index); if (id == baked_img->getID()) { const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; @@ -6609,7 +6610,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerImage *src_vi, } // static -void LLVOAvatar::onInitialBakedTextureLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) +void LLVOAvatar::onInitialBakedTextureLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) { LLUUID *avatar_idp = (LLUUID *)userdata; LLVOAvatar *selfp = (LLVOAvatar *)gObjectList.findObject(*avatar_idp); @@ -6624,7 +6625,7 @@ void LLVOAvatar::onInitialBakedTextureLoaded( BOOL success, LLViewerImage *src_v } } -void LLVOAvatar::onBakedTextureLoaded(BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) +void LLVOAvatar::onBakedTextureLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) { //llinfos << "onBakedTextureLoaded: " << src_vi->getID() << llendl; @@ -6659,7 +6660,7 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id ) mHeadMesh1.setTexture( head_baked ); */ for (U32 i = 0; i < mBakedTextureDatas.size(); i++) { - LLViewerImage* image_baked = getImage( mBakedTextureDatas[i].mTextureIndex ); + LLViewerTexture* image_baked = getImage( mBakedTextureDatas[i].mTextureIndex ); if (id == image_baked->getID()) { mBakedTextureDatas[i].mIsLoaded = true; @@ -6734,7 +6735,7 @@ void LLVOAvatar::dumpArchetypeXML( void* ) { if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex)te) == type) { - LLViewerImage* te_image = avatar->getImage((ETextureIndex)te); + LLViewerTexture* te_image = avatar->getImage((ETextureIndex)te); if( te_image ) { std::string uuid_str; @@ -7623,7 +7624,7 @@ U32 calc_shame(LLVOVolume* volume, std::set &textures) { LLFace* face = drawablep->getFace(i); const LLTextureEntry* te = face->getTextureEntry(); - LLViewerImage* img = face->getTexture(); + LLViewerTexture* img = face->getTexture(); textures.insert(img->getID()); diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 283b9ea156..f36d64aa8e 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -370,7 +370,7 @@ public: private: LLFace* mShadow0Facep; LLFace* mShadow1Facep; - LLPointer mShadowImagep; + LLPointer mShadowImagep; //-------------------------------------------------------------------- // Impostors @@ -432,8 +432,8 @@ private: // Constants //-------------------------------------------------------------------- public: - virtual LLViewerImage::EBoostLevel getAvatarBoostLevel() const { return LLViewerImage::BOOST_AVATAR; } - virtual LLViewerImage::EBoostLevel getAvatarBakedBoostLevel() const { return LLViewerImage::BOOST_AVATAR_BAKED; } + virtual LLViewerTexture::EBoostLevel getAvatarBoostLevel() const { return LLViewerTexture::BOOST_AVATAR; } + virtual LLViewerTexture::EBoostLevel getAvatarBakedBoostLevel() const { return LLViewerTexture::BOOST_AVATAR_BAKED; } virtual S32 getTexImageSize() const; virtual S32 getTexImageArea() const { return getTexImageSize()*getTexImageSize(); } @@ -450,7 +450,7 @@ public: // Loading status //-------------------------------------------------------------------- public: - virtual BOOL isTextureDefined(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const; + virtual BOOL isTextureDefined(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const; BOOL isTextureVisible(LLVOAvatarDefines::ETextureIndex index) const; protected: BOOL isFullyBaked(); @@ -462,9 +462,9 @@ protected: public: void releaseComponentTextures(); // ! BACKWARDS COMPATIBILITY ! protected: - static void onBakedTextureMasksLoaded(BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); - static void onInitialBakedTextureLoaded(BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); - static void onBakedTextureLoaded(BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); + static void onBakedTextureMasksLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); + static void onInitialBakedTextureLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); + static void onBakedTextureLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); virtual void removeMissingBakedTextures(); void useBakedTexture(const LLUUID& id); @@ -489,15 +489,15 @@ protected: // Local Textures //-------------------------------------------------------------------- protected: - virtual void setLocalTexture(LLVOAvatarDefines::ETextureIndex type, LLViewerImage* tex, BOOL baked_version_exits, U32 index = 0); - virtual void addLocalTextureStats(LLVOAvatarDefines::ETextureIndex type, LLViewerImage* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked, U32 index = 0); + virtual void setLocalTexture(LLVOAvatarDefines::ETextureIndex type, LLViewerTexture* tex, BOOL baked_version_exits, U32 index = 0); + virtual void addLocalTextureStats(LLVOAvatarDefines::ETextureIndex type, LLViewerFetchedTexture* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked, U32 index = 0); //-------------------------------------------------------------------- // Texture accessors //-------------------------------------------------------------------- private: - virtual void setImage(const U8 te, LLViewerImage *imagep); - virtual LLViewerImage* getImage(const U8 te) const; + virtual void setImage(const U8 te, LLViewerTexture *imagep); + virtual LLViewerTexture* getImage(const U8 te) const; virtual const LLTextureEntry* getTexEntry(const U8 te_num) const; virtual void setTexEntry(const U8 index, const LLTextureEntry &te); @@ -508,7 +508,7 @@ private: //-------------------------------------------------------------------- protected: void deleteLayerSetCaches(bool clearAll = true); - void addBakedTextureStats(LLViewerImage* imagep, F32 pixel_area, F32 texel_area_ratio, S32 boost_level); + void addBakedTextureStats(LLViewerFetchedTexture* imagep, F32 pixel_area, F32 texel_area_ratio, S32 boost_level); //-------------------------------------------------------------------- // Composites diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 55e72cc437..4a80882c89 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -69,7 +69,7 @@ #include "lltoolmorph.h" #include "lltrans.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewermenu.h" #include "llviewerobjectlist.h" #include "llviewerparcelmgr.h" @@ -103,7 +103,7 @@ struct LocalTextureData mWearableID(IMG_DEFAULT_AVATAR), mTexEntry(NULL) {} - LLPointer mImage; + LLPointer mImage; BOOL mIsBakedReady; S32 mDiscard; LLUUID mWearableID; // UUID of the wearable that this texture belongs to, not of the image itself @@ -675,7 +675,7 @@ void LLVOAvatarSelf::stopMotionFromSource(const LLUUID& source_id) } // virtual -void LLVOAvatarSelf::setLocalTextureTE(U8 te, LLViewerImage* image, BOOL set_by_user, U32 index) +void LLVOAvatarSelf::setLocalTextureTE(U8 te, LLViewerTexture* image, BOOL set_by_user, U32 index) { if (te >= TEX_NUM_INDICES) { @@ -716,9 +716,10 @@ void LLVOAvatarSelf::removeMissingBakedTextures() for (U32 i = 0; i < mBakedTextureDatas.size(); i++) { const S32 te = mBakedTextureDatas[i].mTextureIndex; - if (getTEImage(te)->isMissingAsset()) + LLViewerTexture* tex = getTEImage(te) ; + if (!tex || tex->isMissingAsset()) { - setTEImage(te, gImageList.getImage(IMG_DEFAULT_AVATAR)); + setTEImage(te, LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR)); removed = TRUE; } } @@ -1008,7 +1009,7 @@ LLViewerJointAttachment *LLVOAvatarSelf::attachObject(LLViewerObject *viewer_obj } // virtual -void LLVOAvatarSelf::localTextureLoaded(BOOL success, LLViewerImage *src_vi, LLImageRaw* src_raw, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) +void LLVOAvatarSelf::localTextureLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src_raw, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) { //llinfos << "onLocalTextureLoaded: " << src_vi->getID() << llendl; @@ -1074,9 +1075,9 @@ BOOL LLVOAvatarSelf::getLocalTextureRaw(ETextureIndex index, LLImageRaw* image_r */ // virtual -BOOL LLVOAvatarSelf::getLocalTextureGL(ETextureIndex type, LLImageGL** image_gl_pp, U32 index) const +BOOL LLVOAvatarSelf::getLocalTextureGL(ETextureIndex type, LLViewerTexture** tex_pp, U32 index) const { - *image_gl_pp = NULL; + *tex_pp = NULL; if (!isIndexLocalTexture(type)) return FALSE; if (getLocalTextureID(type, index) == IMG_DEFAULT_AVATAR) return TRUE; @@ -1086,7 +1087,7 @@ BOOL LLVOAvatarSelf::getLocalTextureGL(ETextureIndex type, LLImageGL** image_gl_ { return FALSE; } - *image_gl_pp = local_tex_data->mImage; + *tex_pp = local_tex_data->mImage; return TRUE; } @@ -1230,7 +1231,7 @@ void LLVOAvatarSelf::invalidateComposite( LLTexLayerSet* layerset, BOOL set_by_u llassert(isSelf()); ETextureIndex baked_te = getBakedTE( layerset ); - setTEImage( baked_te, gImageList.getImage(IMG_DEFAULT_AVATAR) ); + setTEImage( baked_te, LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR) ); layerset->requestUpload(); } } @@ -1319,12 +1320,12 @@ void LLVOAvatarSelf::getLocalTextureByteCount(S32* gl_bytes) const const LocalTextureData *local_tex_data = local_tex_vec[num]; if (local_tex_data) { - const LLViewerImage* image_gl = local_tex_data->mImage; + const LLViewerFetchedTexture* image_gl = local_tex_data->mImage; if (image_gl) { S32 bytes = (S32)image_gl->getWidth() * image_gl->getHeight() * image_gl->getComponents(); - if (image_gl->getHasGLTexture()) + if (image_gl->hasValidGLTexture()) { *gl_bytes += bytes; } @@ -1335,10 +1336,16 @@ void LLVOAvatarSelf::getLocalTextureByteCount(S32* gl_bytes) const } // virtual -void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerImage* tex, BOOL baked_version_ready, U32 index) +void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_tex, BOOL baked_version_ready, U32 index) { if (!isIndexLocalTexture(type)) return; + LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(src_tex, TRUE) ; + if(!tex) + { + return ; + } + S32 desired_discard = isSelf() ? 0 : 2; LocalTextureData *local_tex_data = getLocalTextureData(type,index); if (!baked_version_ready) @@ -1415,7 +1422,7 @@ void LLVOAvatarSelf::dumpLocalTextures() const } else { - const LLViewerImage* image = local_tex_data->mImage; + const LLViewerFetchedTexture* image = local_tex_data->mImage; llinfos << "LocTex " << name << ": " << "Discard " << image->getDiscardLevel() << ", " @@ -1431,7 +1438,7 @@ void LLVOAvatarSelf::dumpLocalTextures() const } else { - llinfos << "LocTex " << name << ": No LLViewerImage" << llendl; + llinfos << "LocTex " << name << ": No LLViewerTexture" << llendl; } } } @@ -1441,7 +1448,7 @@ void LLVOAvatarSelf::dumpLocalTextures() const // onLocalTextureLoaded() //----------------------------------------------------------------------------- -void LLVOAvatarSelf::onLocalTextureLoaded(BOOL success, LLViewerImage *src_vi, LLImageRaw* src_raw, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) +void LLVOAvatarSelf::onLocalTextureLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src_raw, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) { LLAvatarTexData *data = (LLAvatarTexData *)userdata; LLVOAvatarSelf *self = (LLVOAvatarSelf *)gObjectList.findObject(data->mAvatarID); @@ -1555,8 +1562,8 @@ BOOL LLVOAvatarSelf::updateIsFullyLoaded() continue; // Check for the case that texture is defined but not sufficiently loaded to display anything. - LLViewerImage* baked_img = getImage( texture_data.mTextureIndex ); - if (!baked_img || !baked_img->getHasGLTexture()) + LLViewerTexture* baked_img = getImage( texture_data.mTextureIndex ); + if (!baked_img || !baked_img->hasValidGLTexture()) { loading = TRUE; } @@ -1646,7 +1653,7 @@ BOOL LLVOAvatarSelf::canGrabLocalTexture(ETextureIndex type, U32 index) const return TRUE; } -void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerImage* imagep, +void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTexture* imagep, F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked, U32 index ) { if (!isIndexLocalTexture(type)) return; @@ -1698,7 +1705,7 @@ void LLVOAvatarSelf::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid ) { // Baked textures live on other sims. LLHost target_host = getObjectHost(); - setTEImage( te, gImageList.getImageFromHost( uuid, target_host ) ); + setTEImage( te, LLViewerTextureManager::getFetchedTextureFromHost( uuid, target_host ) ); updateMeshTextures(); dirtyMesh(); diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index 588e3e67d8..7e8a36427d 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -34,6 +34,7 @@ #ifndef LL_LLVOAVATARSELF_H #define LL_LLVOAVATARSELF_H +#include "llviewertexture.h" #include "llvoavatar.h" struct LocalTextureData; @@ -141,8 +142,8 @@ private: // LLVOAvatar Constants //-------------------------------------------------------------------- public: - /*virtual*/ LLViewerImage::EBoostLevel getAvatarBoostLevel() const { return LLViewerImage::BOOST_AVATAR_SELF; } - /*virtual*/ LLViewerImage::EBoostLevel getAvatarBakedBoostLevel() const { return LLViewerImage::BOOST_AVATAR_BAKED_SELF; } + /*virtual*/ LLViewerTexture::EBoostLevel getAvatarBoostLevel() const { return LLViewerTexture::BOOST_AVATAR_SELF; } + /*virtual*/ LLViewerTexture::EBoostLevel getAvatarBakedBoostLevel() const { return LLViewerTexture::BOOST_AVATAR_BAKED_SELF; } /*virtual*/ S32 getTexImageSize() const { return LLVOAvatar::getTexImageSize()*4; } /** Rendering @@ -169,18 +170,18 @@ public: // Local Textures //-------------------------------------------------------------------- public: - BOOL getLocalTextureGL(LLVOAvatarDefines::ETextureIndex type, LLImageGL** image_gl_pp, U32 index = 0) const; + BOOL getLocalTextureGL(LLVOAvatarDefines::ETextureIndex type, LLViewerTexture** image_gl_pp, U32 index = 0) const; const LLUUID& getLocalTextureID(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const; - void setLocalTextureTE(U8 te, LLViewerImage* image, BOOL set_by_user, U32 index = 0); + void setLocalTextureTE(U8 te, LLViewerTexture* image, BOOL set_by_user, U32 index = 0); const LLUUID& grabLocalTexture(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const; BOOL canGrabLocalTexture(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const; protected: - /*virtual*/ void setLocalTexture(LLVOAvatarDefines::ETextureIndex type, LLViewerImage* tex, BOOL baked_version_exits, U32 index = 0); - void localTextureLoaded(BOOL succcess, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); + /*virtual*/ void setLocalTexture(LLVOAvatarDefines::ETextureIndex type, LLViewerTexture* tex, BOOL baked_version_exits, U32 index = 0); + void localTextureLoaded(BOOL succcess, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); void getLocalTextureByteCount(S32* gl_byte_count) const; - /*virtual*/ void addLocalTextureStats(LLVOAvatarDefines::ETextureIndex i, LLViewerImage* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked, U32 index = 0); + /*virtual*/ void addLocalTextureStats(LLVOAvatarDefines::ETextureIndex i, LLViewerFetchedTexture* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked, U32 index = 0); private: - static void onLocalTextureLoaded(BOOL succcess, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); + static void onLocalTextureLoaded(BOOL succcess, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); //-------------------------------------------------------------------- // Baked textures diff --git a/indra/newview/llvoclouds.cpp b/indra/newview/llvoclouds.cpp index 9095ee43c8..fbc4e2e609 100644 --- a/indra/newview/llvoclouds.cpp +++ b/indra/newview/llvoclouds.cpp @@ -44,7 +44,7 @@ #include "llprimitive.h" #include "llsky.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerobjectlist.h" #include "llviewerregion.h" #include "llvosky.h" @@ -61,8 +61,8 @@ LLVOClouds::LLVOClouds(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re mCloudGroupp = NULL; mbCanSelect = FALSE; setNumTEs(1); - LLViewerImage* image = gImageList.getImage(gCloudTextureID); - image->setBoostLevel(LLViewerImage::BOOST_CLOUDS); + LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(gCloudTextureID); + image->setBoostLevel(LLViewerTexture::BOOST_CLOUDS); setTEImage(0, image); } diff --git a/indra/newview/llvoclouds.h b/indra/newview/llvoclouds.h index f70ea5b9e7..95e6b96e4e 100644 --- a/indra/newview/llvoclouds.h +++ b/indra/newview/llvoclouds.h @@ -37,7 +37,7 @@ #include "lltable.h" #include "v4coloru.h" -class LLViewerImage; +class LLViewerTexture; class LLViewerCloudGroup; class LLCloudGroup; diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index a956ec8ab3..cf6eb8e9fd 100644 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -46,7 +46,7 @@ #include "llsurfacepatch.h" #include "llvosky.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerregion.h" #include "pipeline.h" #include "llspatialpartition.h" @@ -106,7 +106,7 @@ void LLVOGrass::updateSpecies() SpeciesMap::const_iterator it = sSpeciesTable.begin(); mSpecies = (*it).first; } - setTEImage(0, gImageList.getImage(sSpeciesTable[mSpecies]->mTextureID)); + setTEImage(0, LLViewerTextureManager::getFetchedTexture(sSpeciesTable[mSpecies]->mTextureID, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE)); } diff --git a/indra/newview/llvograss.h b/indra/newview/llvograss.h index 11b79d519c..124400d356 100644 --- a/indra/newview/llvograss.h +++ b/indra/newview/llvograss.h @@ -38,7 +38,7 @@ #include class LLSurfacePatch; -class LLViewerImage; +class LLViewerTexture; class LLVOGrass : public LLAlphaObject diff --git a/indra/newview/llvoground.h b/indra/newview/llvoground.h index f485bd0aa4..af3fcd65d4 100644 --- a/indra/newview/llvoground.h +++ b/indra/newview/llvoground.h @@ -36,7 +36,7 @@ #include "stdtypes.h" #include "v3color.h" #include "v4coloru.h" -#include "llviewerimage.h" +#include "llviewertexture.h" #include "llviewerobject.h" class LLVOGround : public LLStaticViewerObject diff --git a/indra/newview/llvoicevisualizer.cpp b/indra/newview/llvoicevisualizer.cpp index a361a1160c..9bafc03a6d 100644 --- a/indra/newview/llvoicevisualizer.cpp +++ b/indra/newview/llvoicevisualizer.cpp @@ -42,9 +42,8 @@ #include "llvoicevisualizer.h" #include "llviewercamera.h" #include "llviewerobject.h" -#include "llimagegl.h" -#include "llviewerimage.h" -#include "llviewerimagelist.h" +#include "llviewertexture.h" +#include "llviewertexturelist.h" #include "llvoiceclient.h" #include "llrender.h" @@ -143,7 +142,7 @@ LLVoiceVisualizer::LLVoiceVisualizer( const U8 type ) for (int i=0; i mTexture [ NUM_VOICE_SYMBOL_WAVES ]; + LLPointer mTexture [ NUM_VOICE_SYMBOL_WAVES ]; bool mActive; LLVector3 mPosition; }; diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index d4df141477..993cf522e9 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -49,7 +49,7 @@ #include "llglheaders.h" #include "llsky.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerobjectlist.h" #include "llviewerregion.h" #include "llworld.h" @@ -212,8 +212,8 @@ void LLSkyTex::init() for (S32 i = 0; i < 2; ++i) { - mImageGL[i] = new LLImageGL(FALSE); - mImageGL[i]->setAddressMode(LLTexUnit::TAM_CLAMP); + mTexture[i] = LLViewerTextureManager::getLocalTexture(FALSE); + mTexture[i]->setAddressMode(LLTexUnit::TAM_CLAMP); mImageRaw[i] = new LLImageRaw(sResolution, sResolution, sComponents); initEmpty(i); @@ -222,16 +222,16 @@ void LLSkyTex::init() void LLSkyTex::cleanupGL() { - mImageGL[0] = NULL; - mImageGL[1] = NULL; + mTexture[0] = NULL; + mTexture[1] = NULL; } void LLSkyTex::restoreGL() { for (S32 i = 0; i < 2; i++) { - mImageGL[i] = new LLImageGL(FALSE); - mImageGL[i]->setAddressMode(LLTexUnit::TAM_CLAMP); + mTexture[i] = LLViewerTextureManager::getLocalTexture(FALSE); + mTexture[i]->setAddressMode(LLTexUnit::TAM_CLAMP); } } @@ -289,13 +289,13 @@ void LLSkyTex::create(const F32 brightness) void LLSkyTex::createGLImage(S32 which) { - mImageGL[which]->createGLTexture(0, mImageRaw[which]); - mImageGL[which]->setAddressMode(LLTexUnit::TAM_CLAMP); + mTexture[which]->createGLTexture(0, mImageRaw[which]); + mTexture[which]->setAddressMode(LLTexUnit::TAM_CLAMP); } void LLSkyTex::bindTexture(BOOL curr) { - gGL.getTexUnit(0)->bind(mImageGL[getWhich(curr)]); + gGL.getTexUnit(0)->bind(mTexture[getWhich(curr)]); } /*************************************** @@ -376,11 +376,11 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) mSun.setIntensity(SUN_INTENSITY); mMoon.setIntensity(0.1f * SUN_INTENSITY); - mSunTexturep = gImageList.getImage(gSunTextureID, TRUE, TRUE); + mSunTexturep = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, TRUE); mSunTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); - mMoonTexturep = gImageList.getImage(gMoonTextureID, TRUE, TRUE); + mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, TRUE); mMoonTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); - mBloomTexturep = gImageList.getImage(IMG_BLOOM1); + mBloomTexturep = LLViewerTextureManager::getFetchedTexture(IMG_BLOOM1); mBloomTexturep->setNoDelete() ; mBloomTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); @@ -390,7 +390,7 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) LLVOSky::~LLVOSky() { - // Don't delete images - it'll get deleted by gImageList on shutdown + // Don't delete images - it'll get deleted by gTextureList on shutdown // This needs to be done for each texture mCubeMap = NULL; @@ -472,11 +472,11 @@ void LLVOSky::restoreGL() { mSkyTex[i].restoreGL(); } - mSunTexturep = gImageList.getImage(gSunTextureID, TRUE, TRUE); + mSunTexturep = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, TRUE); mSunTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); - mMoonTexturep = gImageList.getImage(gMoonTextureID, TRUE, TRUE); + mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, TRUE); mMoonTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); - mBloomTexturep = gImageList.getImage(IMG_BLOOM1); + mBloomTexturep = LLViewerTextureManager::getFetchedTexture(IMG_BLOOM1); mBloomTexturep->setNoDelete() ; mBloomTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); diff --git a/indra/newview/llvosky.h b/indra/newview/llvosky.h index 5e23065153..466cdfdcd0 100644 --- a/indra/newview/llvosky.h +++ b/indra/newview/llvosky.h @@ -36,7 +36,7 @@ #include "stdtypes.h" #include "v3color.h" #include "v4coloru.h" -#include "llviewerimage.h" +#include "llviewertexture.h" #include "llviewerobject.h" #include "llframetimer.h" @@ -122,7 +122,7 @@ class LLSkyTex private: static S32 sResolution; static S32 sComponents; - LLPointer mImageGL[2]; + LLPointer mTexture[2]; LLPointer mImageRaw[2]; LLColor4 *mSkyData; LLVector3 *mSkyDirs; // Cache of sky direction vectors @@ -567,9 +567,9 @@ public: BOOL isReflFace(const LLFace* face) const { return face == mFace[FACE_REFLECTION]; } LLFace* getReflFace() const { return mFace[FACE_REFLECTION]; } - LLViewerImage* getSunTex() const { return mSunTexturep; } - LLViewerImage* getMoonTex() const { return mMoonTexturep; } - LLViewerImage* getBloomTex() const { return mBloomTexturep; } + LLViewerTexture* getSunTex() const { return mSunTexturep; } + LLViewerTexture* getMoonTex() const { return mMoonTexturep; } + LLViewerTexture* getBloomTex() const { return mBloomTexturep; } void forceSkyUpdate(void) { mForceUpdate = TRUE; } public: @@ -579,9 +579,9 @@ public: protected: ~LLVOSky(); - LLPointer mSunTexturep; - LLPointer mMoonTexturep; - LLPointer mBloomTexturep; + LLPointer mSunTexturep; + LLPointer mMoonTexturep; + LLPointer mBloomTexturep; static S32 sResolution; static S32 sTileResX; diff --git a/indra/newview/llvotextbubble.cpp b/indra/newview/llvotextbubble.cpp index de69aac037..9871965458 100644 --- a/indra/newview/llvotextbubble.cpp +++ b/indra/newview/llvotextbubble.cpp @@ -43,7 +43,7 @@ #include "llbox.h" #include "lldrawable.h" #include "llface.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llvolume.h" #include "pipeline.h" #include "llviewerregion.h" @@ -125,7 +125,7 @@ void LLVOTextBubble::updateTextures(LLAgent &agent) const LLTextureEntry *te = getTE(i); F32 texel_area_ratio = fabs(te->mScaleS * te->mScaleT); texel_area_ratio = llclamp(texel_area_ratio, .125f, 16.f); - LLViewerImage *imagep = getTEImage(i); + LLViewerTexture *imagep = getTEImage(i); if (imagep) { imagep->addTextureStats(mPixelArea / texel_area_ratio); @@ -142,9 +142,9 @@ LLDrawable *LLVOTextBubble::createDrawable(LLPipeline *pipeline) for (U32 i = 0; i < getNumTEs(); i++) { - LLViewerImage *imagep; + LLViewerTexture *imagep; const LLTextureEntry *texture_entry = getTE(i); - imagep = gImageList.getImage(texture_entry->getID()); + imagep = LLViewerTextureManager::getFetchedTexture(texture_entry->getID()); mDrawable->addFace((LLFacePool*) NULL, imagep); } @@ -194,7 +194,7 @@ BOOL LLVOTextBubble::updateGeometry(LLDrawable *drawable) { LLFace *face = drawable->getFace(i); face->setTEOffset(i); - face->setTexture(LLViewerImage::sSmokeImagep); + face->setTexture(LLViewerFetchedTexture::sSmokeImagep); face->setState(LLFace::FULLBRIGHT); } diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index b602b93025..d1cac4c77e 100644 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -48,7 +48,7 @@ #include "lldrawable.h" #include "llface.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerobjectlist.h" #include "llviewerregion.h" #include "llworld.h" @@ -311,10 +311,10 @@ U32 LLVOTree::processUpdateMessage(LLMessageSystem *mesgsys, // // Load Species-Specific data // - mTreeImagep = gImageList.getImage(sSpeciesTable[mSpecies]->mTextureID); + mTreeImagep = LLViewerTextureManager::getFetchedTexture(sSpeciesTable[mSpecies]->mTextureID, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE); if (mTreeImagep) { - gGL.getTexUnit(0)->bind(mTreeImagep.get()); + gGL.getTexUnit(0)->bind(mTreeImagep); } mBranchLength = sSpeciesTable[mSpecies]->mBranchLength; mTrunkLength = sSpeciesTable[mSpecies]->mTrunkLength; diff --git a/indra/newview/llvotree.h b/indra/newview/llvotree.h index 42a6d54f62..13817fa111 100644 --- a/indra/newview/llvotree.h +++ b/indra/newview/llvotree.h @@ -39,7 +39,7 @@ class LLFace; class LLDrawPool; - +class LLViewerFetchedTexture; class LLVOTree : public LLViewerObject { @@ -160,7 +160,7 @@ protected: LLVector3 mWind; LLPointer mReferenceBuffer; //reference geometry for generating tree mesh - LLPointer mTreeImagep; // Pointer to proper tree image + LLPointer mTreeImagep; // Pointer to proper tree image U8 mSpecies; // Species of tree F32 mBranchLength; // Scale (length) of tree branches @@ -184,7 +184,7 @@ protected: // complete rebuild when not animating LLVector3 mLastPosition; LLQuaternion mLastRotation; - + U32 mFrameCount; typedef std::map SpeciesMap; diff --git a/indra/newview/llvotreenew.h b/indra/newview/llvotreenew.h index 02f6d3a056..3fec5855ef 100644 --- a/indra/newview/llvotreenew.h +++ b/indra/newview/llvotreenew.h @@ -41,7 +41,7 @@ #include "llstrider.h" #include "v2math.h" #include "v3math.h" -#include "llviewerimage.h" +#include "llviewertexture.h" class LLFace; class LLDrawPool; @@ -187,7 +187,7 @@ public: //LLTreeParams mParams; U8 mSpecies; - LLPointer mTreeImagep; + LLPointer mTreeImagep; LLMatrix4 mTrunkFlareFrames[MAX_FLARE]; F32 mSegSplitsError[3]; U32 mRandOffset[MAX_LEVELS]; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index f31f09f60e..bef38bb669 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -59,7 +59,7 @@ #include "llsky.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerregion.h" #include "llviewertextureanim.h" #include "llworld.h" @@ -427,7 +427,7 @@ void LLVOVolume::updateTextures() return; } - if (LLViewerImage::sDontLoadVolumeTextures || mDrawable.isNull()) // || !mDrawable->isVisible()) + if (LLViewerTexture::sDontLoadVolumeTextures || mDrawable.isNull()) // || !mDrawable->isVisible()) { return; } @@ -443,7 +443,7 @@ void LLVOVolume::updateTextures() { LLFace* face = mDrawable->getFace(i); const LLTextureEntry *te = face->getTextureEntry(); - LLViewerImage *imagep = face->getTexture(); + LLViewerTexture *imagep = face->getTexture(); if (!imagep || !te || face->mExtents[0] == face->mExtents[1]) { @@ -456,7 +456,7 @@ void LLVOVolume::updateTextures() { F32 area = (F32) LLViewerCamera::getInstance()->getScreenPixelArea(); vsize = area; - imagep->setBoostLevel(LLViewerImage::BOOST_HUD); + imagep->setBoostLevel(LLViewerTexture::BOOST_HUD); face->setPixelArea(area); // treat as full screen } else @@ -486,10 +486,14 @@ void LLVOVolume::updateTextures() } else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)) { - F32 pri = imagep->getDecodePriority(); - pri = llmax(pri, 0.0f); - if (pri < min_vsize) min_vsize = pri; - if (pri > max_vsize) max_vsize = pri; + LLViewerFetchedTexture* img = LLViewerTextureManager::staticCastToFetchedTexture(imagep) ; + if(img) + { + F32 pri = img->getDecodePriority(); + pri = llmax(pri, 0.0f); + if (pri < min_vsize) min_vsize = pri; + if (pri > max_vsize) max_vsize = pri; + } } else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_AREA)) { @@ -503,7 +507,7 @@ void LLVOVolume::updateTextures() { LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); LLUUID id = sculpt_params->getSculptTexture(); - mSculptTexture = gImageList.getImage(id); + mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE); if (mSculptTexture.notNull()) { S32 lod = llmin(mLOD, 3); @@ -511,7 +515,7 @@ void LLVOVolume::updateTextures() F32 tex_size = lodf * MAX_SCULPT_REZ; mSculptTexture->addTextureStats(2.f * tex_size * tex_size); mSculptTexture->setBoostLevel(llmax((S32)mSculptTexture->getBoostLevel(), - (S32)LLViewerImage::BOOST_SCULPTED)); + (S32)LLViewerTexture::BOOST_SCULPTED)); mSculptTexture->setForSculpt() ; } @@ -625,7 +629,7 @@ void LLVOVolume::setScale(const LLVector3 &scale, BOOL damped) LLFace* LLVOVolume::addFace(S32 f) { const LLTextureEntry* te = getTE(f); - LLViewerImage* imagep = getTEImage(f); + LLViewerTexture* imagep = getTEImage(f); return mDrawable->addFace(te, imagep); } @@ -701,7 +705,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &volume_params, const S32 detail if (isSculpted()) { - mSculptTexture = gImageList.getImage(volume_params.getSculptID()); + mSculptTexture = LLViewerTextureManager::getFetchedTexture(volume_params.getSculptID(), TRUE, FALSE, LLViewerTexture::LOD_TEXTURE); if (mSculptTexture.notNull()) { sculpt(); @@ -783,9 +787,9 @@ void LLVOVolume::sculpt() sculpt_height = 0; sculpt_data = NULL ; - if(LLViewerImage::sTesterp) + if(LLViewerTextureManager::sTesterp) { - LLViewerImage::sTesterp->updateGrayTextureBinding(); + LLViewerTextureManager::sTesterp->updateGrayTextureBinding(); } } else @@ -796,9 +800,9 @@ void LLVOVolume::sculpt() sculpt_data = raw_image->getData(); - if(LLViewerImage::sTesterp) + if(LLViewerTextureManager::sTesterp) { - mSculptTexture->updateBindStats() ; + mSculptTexture->updateBindStatsForTester() ; } } getVolume()->sculpt(sculpt_width, sculpt_height, sculpt_components, sculpt_data, discard_level); @@ -1257,7 +1261,7 @@ BOOL LLVOVolume::isRootEdit() const return TRUE; } -void LLVOVolume::setTEImage(const U8 te, LLViewerImage *imagep) +void LLVOVolume::setTEImage(const U8 te, LLViewerTexture *imagep) { BOOL changed = (mTEImages[te] != imagep); LLViewerObject::setTEImage(te, imagep); @@ -2056,7 +2060,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e { LLFace* face = mDrawable->getFace(face_hit); - if (pick_transparent || !face->getTexture() || face->getTexture()->getMask(face->surfaceToTexture(tc, p, n))) + if (pick_transparent || !face->getTexture() || !face->getTexture()->hasGLTexture() || face->getTexture()->getMask(face->surfaceToTexture(tc, p, n))) { v_end = p; if (face_hitp != NULL) @@ -2167,7 +2171,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U8 bump = (type == LLRenderPass::PASS_BUMP ? facep->getTextureEntry()->getBumpmap() : 0); - LLViewerImage* tex = facep->getTexture(); + LLViewerTexture* tex = facep->getTexture(); U8 glow = 0; @@ -2318,7 +2322,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (facep->hasGeometry() && facep->mPixelArea > FORCE_CULL_AREA) { const LLTextureEntry* te = facep->getTextureEntry(); - LLViewerImage* tex = facep->getTexture(); + LLViewerTexture* tex = facep->getTexture(); if (facep->isState(LLFace::TEXTURE_ANIM)) { @@ -2566,7 +2570,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: LLSpatialGroup::buffer_map_t buffer_map; - LLViewerImage* last_tex = NULL; + LLViewerTexture* last_tex = NULL; S32 buffer_index = 0; if (distance_sort) @@ -2578,7 +2582,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: { //pull off next face LLFace* facep = *face_iter; - LLViewerImage* tex = facep->getTexture(); + LLViewerTexture* tex = facep->getTexture(); if (distance_sort) { diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 5d7b373b3c..d343d4db74 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -34,7 +34,7 @@ #define LL_LLVOVOLUME_H #include "llviewerobject.h" -#include "llviewerimage.h" +#include "llviewertexture.h" #include "llframetimer.h" #include "llapr.h" #include "m3math.h" // LLMatrix3 @@ -153,7 +153,7 @@ public: /*virtual*/ void setScale(const LLVector3 &scale, BOOL damped); - /*virtual*/ void setTEImage(const U8 te, LLViewerImage *imagep); + /*virtual*/ void setTEImage(const U8 te, LLViewerTexture *imagep); /*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid); /*virtual*/ S32 setTEColor(const U8 te, const LLColor3 &color); /*virtual*/ S32 setTEColor(const U8 te, const LLColor4 &color); @@ -237,7 +237,7 @@ private: BOOL mVolumeChanged; F32 mVObjRadius; LLVolumeInterface *mVolumeImpl; - LLPointer mSculptTexture; + LLPointer mSculptTexture; // statics public: diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp index d23c746b75..427119285b 100644 --- a/indra/newview/llvowater.cpp +++ b/indra/newview/llvowater.cpp @@ -45,7 +45,7 @@ #include "llsurface.h" #include "llvosky.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerregion.h" #include "llworld.h" #include "pipeline.h" diff --git a/indra/newview/llvowater.h b/indra/newview/llvowater.h index cdda48f6f2..28a5633c58 100644 --- a/indra/newview/llvowater.h +++ b/indra/newview/llvowater.h @@ -34,7 +34,7 @@ #define LL_VOWATER_H #include "llviewerobject.h" -#include "llviewerimage.h" +#include "llviewertexture.h" #include "v2math.h" const U32 N_RES = 16; //32 // number of subdivisions of wave tile diff --git a/indra/newview/llwaterparamset.cpp b/indra/newview/llwaterparamset.cpp index a26ccedfb2..3e97f9dbef 100644 --- a/indra/newview/llwaterparamset.cpp +++ b/indra/newview/llwaterparamset.cpp @@ -39,7 +39,7 @@ #include "llwaterparammanager.h" #include "lluictrlfactory.h" #include "llsliderctrl.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewercontrol.h" #include "lluuid.h" diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp index 1e35a31cb6..e8c4046660 100644 --- a/indra/newview/llwearable.cpp +++ b/indra/newview/llwearable.cpp @@ -35,7 +35,7 @@ #include "llagent.h" #include "llagentwearables.h" #include "llfloatercustomize.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llinventorymodel.h" #include "llviewerregion.h" #include "llvoavatar.h" @@ -459,7 +459,7 @@ BOOL LLWearable::isDirty() const { if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType) { - LLViewerImage* avatar_image = avatar->getTEImage( te ); + LLViewerTexture* avatar_image = avatar->getTEImage( te ); if( !avatar_image ) { llassert( 0 ); @@ -559,7 +559,7 @@ void LLWearable::writeToAvatar( BOOL set_by_user ) if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType) { const LLUUID& image_id = get_if_there(mTEMap, te, LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te)); - LLViewerImage* image = gImageList.getImage( image_id ); + LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture( image_id, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE ); avatar->setLocalTextureTE(te, image, set_by_user); } } @@ -631,7 +631,7 @@ void LLWearable::removeFromAvatar( EWearableType type, BOOL set_by_user ) } // Pull textures - LLViewerImage* image = gImageList.getImage( IMG_DEFAULT_AVATAR ); + LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture( IMG_DEFAULT_AVATAR ); for( S32 te = 0; te < TEX_NUM_INDICES; te++ ) { if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == type) @@ -682,7 +682,7 @@ void LLWearable::readFromAvatar() { if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType) { - LLViewerImage* image = avatar->getTEImage( te ); + LLViewerTexture* image = avatar->getTEImage( te ); if( image ) { mTEMap[te] = image->getID(); diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 692efd2b7a..5c6fc2cf21 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -46,8 +46,8 @@ #include "llregionhandle.h" #include "llsurface.h" #include "llviewercamera.h" -#include "llviewerimage.h" -#include "llviewerimagelist.h" +#include "llviewertexture.h" +#include "llviewertexturelist.h" #include "llviewernetwork.h" #include "llviewerobjectlist.h" #include "llviewerparceloverlay.h" @@ -109,8 +109,8 @@ LLWorld::LLWorld() : *(default_texture++) = MAX_WATER_COLOR.mV[2]; *(default_texture++) = MAX_WATER_COLOR.mV[3]; - mDefaultWaterTexturep = new LLViewerImage(raw, FALSE); - gGL.getTexUnit(0)->bind(mDefaultWaterTexturep.get()); + mDefaultWaterTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE); + gGL.getTexUnit(0)->bind(mDefaultWaterTexturep); mDefaultWaterTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); } @@ -962,7 +962,7 @@ void LLWorld::shiftRegions(const LLVector3& offset) LLViewerPartSim::getInstance()->shift(offset); } -LLViewerImage* LLWorld::getDefaultWaterTexture() +LLViewerTexture* LLWorld::getDefaultWaterTexture() { return mDefaultWaterTexturep; } diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h index b5380a6f6c..48025c700b 100644 --- a/indra/newview/llworld.h +++ b/indra/newview/llworld.h @@ -45,7 +45,7 @@ #include "llsingleton.h" #include "llstring.h" #include "llviewerpartsim.h" -#include "llviewerimage.h" +#include "llviewertexture.h" #include "llvowater.h" class LLViewerRegion; @@ -141,7 +141,7 @@ public: F32 getLandFarClip() const; void setLandFarClip(const F32 far_clip); - LLViewerImage *getDefaultWaterTexture(); + LLViewerTexture *getDefaultWaterTexture(); void updateWaterObjects(); void shiftRegions(const LLVector3& offset); @@ -192,7 +192,7 @@ private: std::list mHoleWaterObjects; LLPointer mEdgeWaterObjects[8]; - LLPointer mDefaultWaterTexturep; + LLPointer mDefaultWaterTexturep; }; diff --git a/indra/newview/llworldmap.cpp b/indra/newview/llworldmap.cpp index 827f12d19e..700971dcc4 100644 --- a/indra/newview/llworldmap.cpp +++ b/indra/newview/llworldmap.cpp @@ -43,7 +43,7 @@ #include "llviewercontrol.h" #include "llfloaterworldmap.h" #include "lltracker.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerregion.h" #include "llregionflags.h" #include "lltrans.h" @@ -519,9 +519,9 @@ void LLWorldMap::processMapLayerReply(LLMessageSystem* msg, void**) LLWorldMapLayer new_layer; new_layer.LayerDefined = TRUE; msg->getUUIDFast(_PREHASH_LayerData, _PREHASH_ImageID, new_layer.LayerImageID, block); - new_layer.LayerImage = gImageList.getImage(new_layer.LayerImageID, MIPMAP_TRUE, FALSE); + new_layer.LayerImage = LLViewerTextureManager::getFetchedTexture(new_layer.LayerImageID, MIPMAP_TRUE, FALSE, LLViewerTexture::LOD_TEXTURE); - gGL.getTexUnit(0)->bind(new_layer.LayerImage.get()); + gGL.getTexUnit(0)->bind(new_layer.LayerImage); new_layer.LayerImage->setAddressMode(LLTexUnit::TAM_CLAMP); U32 left, right, top, bottom; @@ -634,15 +634,15 @@ void LLWorldMap::processMapBlockReply(LLMessageSystem* msg, void**) siminfo->mMapImageID[agent_flags] = image_id; #ifdef IMMEDIATE_IMAGE_LOAD - siminfo->mCurrentImage = gImageList.getImage(siminfo->mMapImageID[LLWorldMap::getInstance()->mCurrentMap], MIPMAP_TRUE, FALSE); - gGL.getTexUnit(0)->bind(siminfo->mCurrentImage.get()); + siminfo->mCurrentImage = LLViewerTextureManager::getFetchedTexture(siminfo->mMapImageID[LLWorldMap::getInstance()->mCurrentMap], MIPMAP_TRUE, FALSE, LLViewerTexture::LOD_TEXTURE); + gGL.getTexUnit(0)->bind(siminfo->mCurrentImage); siminfo->mCurrentImage->setAddressMode(LLTexUnit::TAM_CLAMP); #endif if (siminfo->mMapImageID[2].notNull()) { #ifdef IMMEDIATE_IMAGE_LOAD - siminfo->mOverlayImage = gImageList.getImage(siminfo->mMapImageID[2], MIPMAP_TRUE, FALSE); + siminfo->mOverlayImage = LLViewerTextureManager::getFetchedTexture(siminfo->mMapImageID[2], MIPMAP_TRUE, FALSE, LLViewerTexture::LOD_TEXTURE); #endif } else @@ -862,10 +862,10 @@ void LLWorldMap::dump() if (info->mCurrentImage) { llinfos << "image discard " << (S32)info->mCurrentImage->getDiscardLevel() - << " fullwidth " << info->mCurrentImage->getWidth(0) - << " fullheight " << info->mCurrentImage->getHeight(0) - << " maxvirt " << info->mCurrentImage->mMaxVirtualSize - << " maxdisc " << (S32)info->mCurrentImage->getMaxDiscardLevel() + << " fullwidth " << info->mCurrentImage->getFullWidth() + << " fullheight " << info->mCurrentImage->getFullHeight() + << " maxvirt " << info->mCurrentImage->getMaxVirtualSize() + //<< " maxdisc " << (S32)info->mCurrentImage->getMaxDiscardLevel() << llendl; } } diff --git a/indra/newview/llworldmap.h b/indra/newview/llworldmap.h index 1db081c74a..9daee38752 100644 --- a/indra/newview/llworldmap.h +++ b/indra/newview/llworldmap.h @@ -45,7 +45,7 @@ #include "lluuid.h" #include "llpointer.h" #include "llsingleton.h" -#include "llviewerimage.h" +#include "llviewertexture.h" #include "lleventinfo.h" #include "v3color.h" @@ -96,8 +96,8 @@ public: LLUUID mMapImageID[MAP_SIM_IMAGE_TYPES]; // Hold a reference to the currently displayed image. - LLPointer mCurrentImage; - LLPointer mOverlayImage; + LLPointer mCurrentImage; + LLPointer mOverlayImage; }; #define MAP_BLOCK_RES 256 @@ -105,7 +105,7 @@ public: struct LLWorldMapLayer { BOOL LayerDefined; - LLPointer LayerImage; + LLPointer LayerImage; LLUUID LayerImageID; LLRect LayerExtents; diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index 3deddf40ac..67bc205f62 100644 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -54,8 +54,8 @@ #include "lltextureview.h" #include "lltracker.h" #include "llviewercamera.h" -#include "llviewerimage.h" -#include "llviewerimagelist.h" +#include "llviewertexture.h" +#include "llviewertexturelist.h" #include "llviewermenu.h" #include "llviewerparceloverlay.h" #include "llviewerregion.h" @@ -332,7 +332,7 @@ void LLWorldMapView::draw() continue; } LLWorldMapLayer *layer = &LLWorldMap::getInstance()->mMapLayers[LLWorldMap::getInstance()->mCurrentMap][layer_idx]; - LLViewerImage *current_image = layer->LayerImage; + LLViewerFetchedTexture *current_image = layer->LayerImage; if (current_image->isMissingAsset()) { @@ -367,10 +367,10 @@ void LLWorldMapView::draw() continue; } - current_image->setBoostLevel(LLViewerImage::BOOST_MAP_LAYER); + current_image->setBoostLevel(LLViewerTexture::BOOST_MAP_LAYER); current_image->setKnownDrawSize(llround(pix_width * LLUI::sGLScaleFactor.mV[VX]), llround(pix_height * LLUI::sGLScaleFactor.mV[VY])); - if (!current_image->getHasGLTexture()) + if (!current_image->hasValidGLTexture()) { continue; // better to draw nothing than the default image } @@ -434,8 +434,8 @@ void LLWorldMapView::draw() U64 handle = (*it).first; LLSimInfo* info = (*it).second; - LLViewerImage* simimage = info->mCurrentImage; - LLViewerImage* overlayimage = info->mOverlayImage; + LLViewerFetchedTexture* simimage = info->mCurrentImage; + LLViewerFetchedTexture* overlayimage = info->mOverlayImage; if (gMapScale < SIM_MAP_SCALE) { @@ -472,7 +472,7 @@ void LLWorldMapView::draw() bool sim_visible = (gMapScale >= map_scale_cutoff) && (simimage != NULL) && - (simimage->getHasGLTexture()); + (simimage->hasValidGLTexture()); if (sim_visible) { @@ -510,7 +510,7 @@ void LLWorldMapView::draw() (textures_requested_this_tick < MAX_REQUEST_PER_TICK))) { textures_requested_this_tick++; - info->mCurrentImage = gImageList.getImage(info->mMapImageID[LLWorldMap::getInstance()->mCurrentMap], MIPMAP_TRUE, FALSE); + info->mCurrentImage = LLViewerTextureManager::getFetchedTexture(info->mMapImageID[LLWorldMap::getInstance()->mCurrentMap], MIPMAP_TRUE, FALSE, LLViewerTexture::LOD_TEXTURE); info->mCurrentImage->setAddressMode(LLTexUnit::TAM_CLAMP); simimage = info->mCurrentImage; gGL.getTexUnit(0)->bind(simimage); @@ -523,7 +523,7 @@ void LLWorldMapView::draw() (textures_requested_this_tick < MAX_REQUEST_PER_TICK))) { textures_requested_this_tick++; - info->mOverlayImage = gImageList.getImage(info->mMapImageID[2], MIPMAP_TRUE, FALSE); + info->mOverlayImage = LLViewerTextureManager::getFetchedTexture(info->mMapImageID[2], MIPMAP_TRUE, FALSE, LLViewerTexture::LOD_TEXTURE); info->mOverlayImage->setAddressMode(LLTexUnit::TAM_CLAMP); overlayimage = info->mOverlayImage; gGL.getTexUnit(0)->bind(overlayimage); @@ -546,13 +546,13 @@ void LLWorldMapView::draw() S32 draw_size = llround(gMapScale); if (simimage != NULL) { - simimage->setBoostLevel(LLViewerImage::BOOST_MAP); + simimage->setBoostLevel(LLViewerTexture::BOOST_MAP); simimage->setKnownDrawSize(llround(draw_size * LLUI::sGLScaleFactor.mV[VX]), llround(draw_size * LLUI::sGLScaleFactor.mV[VY])); } if (overlayimage != NULL) { - overlayimage->setBoostLevel(LLViewerImage::BOOST_MAP); + overlayimage->setBoostLevel(LLViewerTexture::BOOST_MAP); overlayimage->setKnownDrawSize(llround(draw_size * LLUI::sGLScaleFactor.mV[VX]), llround(draw_size * LLUI::sGLScaleFactor.mV[VY])); } @@ -581,7 +581,7 @@ void LLWorldMapView::draw() gGL.vertex3f(right, top, 0.f); gGL.end(); - if (gSavedSettings.getBOOL("MapShowLandForSale") && overlayimage && overlayimage->getHasGLTexture()) + if (gSavedSettings.getBOOL("MapShowLandForSale") && overlayimage && overlayimage->hasValidGLTexture()) { gGL.getTexUnit(0)->bind(overlayimage); gGL.color4f(1.f, 1.f, 1.f, alpha); diff --git a/indra/newview/llworldmapview.h b/indra/newview/llworldmapview.h index dd64da1371..41c9772694 100644 --- a/indra/newview/llworldmapview.h +++ b/indra/newview/llworldmapview.h @@ -39,7 +39,7 @@ #include "v3math.h" #include "v3dmath.h" #include "v4color.h" -#include "llviewerimage.h" +#include "llviewertexture.h" #include "llmapimagetype.h" #include "llworldmap.h" @@ -50,7 +50,7 @@ const S32 DEFAULT_TRACKING_ARROW_SIZE = 16; class LLColor4; class LLColor4U; class LLCoordGL; -class LLViewerImage; +class LLViewerTexture; class LLTextBox; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 88d2eab66d..38c81bf027 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -76,7 +76,7 @@ #include "lltool.h" #include "lltoolmgr.h" #include "llviewercamera.h" -#include "llviewerimagelist.h" +#include "llviewertexturelist.h" #include "llviewerobject.h" #include "llviewerobjectlist.h" #include "llviewerparcelmgr.h" @@ -751,9 +751,9 @@ S32 LLPipeline::setLightingDetail(S32 level) class LLOctreeDirtyTexture : public LLOctreeTraveler { public: - const std::set& mTextures; + const std::set& mTextures; - LLOctreeDirtyTexture(const std::set& textures) : mTextures(textures) { } + LLOctreeDirtyTexture(const std::set& textures) : mTextures(textures) { } virtual void visit(const LLOctreeNode* node) { @@ -766,7 +766,8 @@ public: for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j) { LLDrawInfo* params = *j; - if (mTextures.find(params->mTexture) != mTextures.end()) + LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(params->mTexture); + if (tex && mTextures.find(tex) != mTextures.end()) { group->setState(LLSpatialGroup::GEOM_DIRTY); } @@ -783,7 +784,7 @@ public: }; // Called when a texture changes # of channels (causes faces to move to alpha pool) -void LLPipeline::dirtyPoolObjectTextures(const std::set& textures) +void LLPipeline::dirtyPoolObjectTextures(const std::set& textures) { assertInitialized(); @@ -815,7 +816,7 @@ void LLPipeline::dirtyPoolObjectTextures(const std::set& texture } } -LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerImage *tex0) +LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0) { assertInitialized(); @@ -887,7 +888,7 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerImage *tex0) } -LLDrawPool *LLPipeline::getPool(const U32 type, LLViewerImage *tex0) +LLDrawPool *LLPipeline::getPool(const U32 type, LLViewerTexture *tex0) { LLMemType mt(LLMemType::MTYPE_PIPELINE); LLDrawPool *poolp = findPool(type, tex0); @@ -904,7 +905,7 @@ LLDrawPool *LLPipeline::getPool(const U32 type, LLViewerImage *tex0) // static -LLDrawPool* LLPipeline::getPoolFromTE(const LLTextureEntry* te, LLViewerImage* imagep) +LLDrawPool* LLPipeline::getPoolFromTE(const LLTextureEntry* te, LLViewerTexture* imagep) { LLMemType mt(LLMemType::MTYPE_PIPELINE); U32 type = getPoolTypeFromTE(te, imagep); @@ -912,7 +913,7 @@ LLDrawPool* LLPipeline::getPoolFromTE(const LLTextureEntry* te, LLViewerImage* i } //static -U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerImage* imagep) +U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* imagep) { LLMemType mt_gpt(LLMemType::MTYPE_PIPELINE_GET_POOL_TYPE); @@ -924,7 +925,7 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerImage* image bool alpha = te->getColor().mV[3] < 0.999f; if (imagep) { - alpha = alpha || (imagep->getComponents() == 4 && ! imagep->mIsMediaTexture) || (imagep->getComponents() == 2); + alpha = alpha || (imagep->getComponents() == 4 && imagep->getType() != LLViewerTexture::MEDIA_TEXTURE) || (imagep->getComponents() == 2); } if (alpha) @@ -2446,7 +2447,7 @@ void LLPipeline::renderHighlights() // Make sure the selection image gets downloaded and decoded if (!mFaceSelectImagep) { - mFaceSelectImagep = gImageList.getImage(IMG_FACE_SELECT); + mFaceSelectImagep = LLViewerTextureManager::getFetchedTexture(IMG_FACE_SELECT); } mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA); @@ -2476,7 +2477,7 @@ void LLPipeline::renderHighlights() for (S32 i = 0; i < count; i++) { LLFace* facep = mHighlightFaces[i]; - facep->renderSelected(LLViewerImage::sNullImagep, color); + facep->renderSelected(LLViewerTexture::sNullImagep, color); } } @@ -2565,8 +2566,8 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) sUnderWaterRender = FALSE; } - gGL.getTexUnit(0)->bind(LLViewerImage::sDefaultImagep); - LLViewerImage::sDefaultImagep->setAddressMode(LLTexUnit::TAM_WRAP); + gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sDefaultImagep); + LLViewerFetchedTexture::sDefaultImagep->setAddressMode(LLTexUnit::TAM_WRAP); ////////////////////////////////////////////// // diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 5358fce766..fc02e7dd88 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -46,7 +46,7 @@ #include "lldrawable.h" #include "llrendertarget.h" -class LLViewerImage; +class LLViewerTexture; class LLEdge; class LLFace; class LLViewerObject; @@ -104,15 +104,15 @@ public: /// @brief Get a draw pool from pool type (POOL_SIMPLE, POOL_MEDIA) and texture. /// @return Draw pool, or NULL if not found. - LLDrawPool *findPool(const U32 pool_type, LLViewerImage *tex0 = NULL); + LLDrawPool *findPool(const U32 pool_type, LLViewerTexture *tex0 = NULL); /// @brief Get a draw pool for faces of the appropriate type and texture. Create if necessary. /// @return Always returns a draw pool. - LLDrawPool *getPool(const U32 pool_type, LLViewerImage *tex0 = NULL); + LLDrawPool *getPool(const U32 pool_type, LLViewerTexture *tex0 = NULL); /// @brief Figures out draw pool type from texture entry. Creates pool if necessary. - static LLDrawPool* getPoolFromTE(const LLTextureEntry* te, LLViewerImage* te_image); - static U32 getPoolTypeFromTE(const LLTextureEntry* te, LLViewerImage* imagep); + static LLDrawPool* getPoolFromTE(const LLTextureEntry* te, LLViewerTexture* te_image); + static U32 getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* imagep); void addPool(LLDrawPool *poolp); // Only to be used by LLDrawPool classes for splitting pools! void removePool( LLDrawPool* poolp ); @@ -150,7 +150,7 @@ public: ); // Something about these textures has changed. Dirty them. - void dirtyPoolObjectTextures(const std::set& textures); + void dirtyPoolObjectTextures(const std::set& textures); void resetDrawOrders(); @@ -561,9 +561,9 @@ public: protected: std::vector mSelectedFaces; - LLPointer mFaceSelectImagep; - LLPointer mBloomImagep; - LLPointer mBloomImage2p; + LLPointer mFaceSelectImagep; + LLPointer mBloomImagep; + LLPointer mBloomImage2p; U32 mLightMask; U32 mLightMovingMask; -- cgit v1.3 From 104f32750e6ac3349e85d2c9b00a8b26c78c017a Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Sat, 11 Jul 2009 02:09:37 +0000 Subject: add LLImageGL::create(...) back for server side use. --- indra/llrender/llimagegl.cpp | 25 +++++++++++++++++++++++++ indra/llrender/llimagegl.h | 9 ++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) (limited to 'indra/llrender') diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index c4d91209e6..a86a0aac23 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -262,6 +262,31 @@ void LLImageGL::restoreGL() } //---------------------------------------------------------------------------- + +//for server side use only. +//static +BOOL LLImageGL::create(LLPointer& dest, BOOL usemipmaps) +{ + dest = new LLImageGL(usemipmaps); + return TRUE; +} + +//for server side use only. +BOOL LLImageGL::create(LLPointer& dest, U32 width, U32 height, U8 components, BOOL usemipmaps) +{ + dest = new LLImageGL(width, height, components, usemipmaps); + return TRUE; +} + +//for server side use only. +BOOL LLImageGL::create(LLPointer& dest, const LLImageRaw* imageraw, BOOL usemipmaps) +{ + dest = new LLImageGL(imageraw, usemipmaps); + return TRUE; +} + +//---------------------------------------------------------------------------- + LLImageGL::LLImageGL(BOOL usemipmaps) : mSaveData(0) { diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 84c0f8746e..09210b1ef1 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -71,7 +71,14 @@ public: static S32 updateBoundTexMem(const S32 delta); static bool checkSize(S32 width, S32 height); - + + //for server side use only. + // Not currently necessary for LLImageGL, but required in some derived classes, + // so include for compatability + static BOOL create(LLPointer& dest, BOOL usemipmaps = TRUE); + static BOOL create(LLPointer& dest, U32 width, U32 height, U8 components, BOOL usemipmaps = TRUE); + static BOOL create(LLPointer& dest, const LLImageRaw* imageraw, BOOL usemipmaps = TRUE); + public: LLImageGL(BOOL usemipmaps = TRUE); LLImageGL(U32 width, U32 height, U8 components, BOOL usemipmaps = TRUE); -- cgit v1.3 From 6a198eed3b784a0495e9710288bddcf73b44ae15 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Thu, 16 Jul 2009 23:51:22 +0000 Subject: add a flag in LLImageGL to turn off calling LLImageGL::analyzeAlpha() and LLImageGL::updatePickMask(). --- indra/llrender/llimagegl.cpp | 11 +++++++++++ indra/llrender/llimagegl.h | 2 ++ 2 files changed, 13 insertions(+) (limited to 'indra/llrender') diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index a86a0aac23..311009064f 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -362,6 +362,7 @@ void LLImageGL::init(BOOL usemipmaps) mGLTextureCreated = FALSE ; mIsMask = FALSE; + mNeedsAlpahAndPickMask = TRUE ; } void LLImageGL::cleanup() @@ -1356,6 +1357,11 @@ void LLImageGL::setTarget(const LLGLenum target, const LLTexUnit::eTextureType b void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h) { + if(!mNeedsAlpahAndPickMask) + { + return ; + } + if (mFormatType != GL_UNSIGNED_BYTE) { llwarns << "Cannot analyze alpha for image with format type " << std::hex << mFormatType << std::dec << llendl; @@ -1416,6 +1422,11 @@ void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h) //---------------------------------------------------------------------------- void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in) { + if(!mNeedsAlpahAndPickMask) + { + return ; + } + if (mFormatType != GL_UNSIGNED_BYTE || mFormatPrimary != GL_RGBA) { diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 09210b1ef1..b58472d398 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -167,6 +167,7 @@ public: void init(BOOL usemipmaps); virtual void cleanup(); // Clean up the LLImageGL so it can be reinitialized. Be careful when using this in derived class destructors + void setNeedsAlpahAndPickMask(BOOL need_mask) {mNeedsAlpahAndPickMask = need_mask;} public: // Various GL/Rendering options S32 mTextureMemory; @@ -180,6 +181,7 @@ private: S8 mAutoGenMips; BOOL mIsMask; + BOOL mNeedsAlpahAndPickMask; bool mGLTextureCreated ; LLGLuint mTexName; -- cgit v1.3 From 9ffb8addf7db0a512fcd2931ff13c8400cd2227b Mon Sep 17 00:00:00 2001 From: Adam Moss Date: Fri, 17 Jul 2009 07:32:06 +0000 Subject: six instances of Alpah -> Alpha --- indra/llrender/llimagegl.cpp | 6 +++--- indra/llrender/llimagegl.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'indra/llrender') diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 311009064f..c3d1d9e894 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -362,7 +362,7 @@ void LLImageGL::init(BOOL usemipmaps) mGLTextureCreated = FALSE ; mIsMask = FALSE; - mNeedsAlpahAndPickMask = TRUE ; + mNeedsAlphaAndPickMask = TRUE ; } void LLImageGL::cleanup() @@ -1357,7 +1357,7 @@ void LLImageGL::setTarget(const LLGLenum target, const LLTexUnit::eTextureType b void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h) { - if(!mNeedsAlpahAndPickMask) + if(!mNeedsAlphaAndPickMask) { return ; } @@ -1422,7 +1422,7 @@ void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h) //---------------------------------------------------------------------------- void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in) { - if(!mNeedsAlpahAndPickMask) + if(!mNeedsAlphaAndPickMask) { return ; } diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index b58472d398..5f32b23356 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -167,7 +167,7 @@ public: void init(BOOL usemipmaps); virtual void cleanup(); // Clean up the LLImageGL so it can be reinitialized. Be careful when using this in derived class destructors - void setNeedsAlpahAndPickMask(BOOL need_mask) {mNeedsAlpahAndPickMask = need_mask;} + void setNeedsAlphaAndPickMask(BOOL need_mask) {mNeedsAlphaAndPickMask = need_mask;} public: // Various GL/Rendering options S32 mTextureMemory; @@ -181,7 +181,7 @@ private: S8 mAutoGenMips; BOOL mIsMask; - BOOL mNeedsAlpahAndPickMask; + BOOL mNeedsAlphaAndPickMask; bool mGLTextureCreated ; LLGLuint mTexName; -- cgit v1.3 From 8f7ec64899c54dcee6caa0307510cc4003ba7bdd Mon Sep 17 00:00:00 2001 From: James Cook Date: Mon, 27 Jul 2009 17:56:26 +0000 Subject: Merged skinning-17 into viewer-2 for bug fixes. Commented out new IM window for now, not complete. Merging revisions 127913-128319 of svn+ssh://svn.lindenlab.com/svn/linden/branches/skinning/skinning-17 into D:\viewer-2.0.0-3, respecting ancestry --- .../llui_libtest/llui_libtest.cpp | 1 + .../integration_tests/llui_libtest/llwidgetreg.cpp | 6 +- indra/llrender/CMakeLists.txt | 4 +- indra/llrender/llfontbitmapcache.h | 2 +- indra/llrender/llfontfreetype.cpp | 630 +++++++++++++++ indra/llrender/llfontfreetype.h | 380 +++++++++ indra/llrender/llfontgl.cpp | 868 ++++++++++----------- indra/llrender/llfontgl.h | 217 ++---- indra/llrender/llfontregistry.cpp | 57 +- indra/llrender/llfontregistry.h | 2 +- indra/llui/CMakeLists.txt | 7 +- indra/llui/llbutton.cpp | 4 +- indra/llui/llbutton.h | 8 +- indra/llui/llcombobox.cpp | 2 +- indra/llui/llconsole.h | 3 +- indra/llui/lldraghandle.cpp | 17 + indra/llui/lldraghandle.h | 3 +- indra/llui/llfiltereditor.cpp | 110 +++ indra/llui/llfiltereditor.h | 86 ++ indra/llui/llfloater.cpp | 89 ++- indra/llui/llfloater.h | 39 +- indra/llui/llhandle.h | 171 ++++ indra/llui/lllayoutstack.cpp | 8 +- indra/llui/lllayoutstack.h | 4 +- indra/llui/lllineeditor.cpp | 133 ++-- indra/llui/lllineeditor.h | 40 +- indra/llui/llmenugl.cpp | 13 +- indra/llui/llmenugl.h | 1 + indra/llui/llnotifications.cpp | 2 +- indra/llui/llnotifications.h | 18 +- indra/llui/llpanel.cpp | 5 +- indra/llui/llpanel.h | 7 +- indra/llui/llprogressbar.cpp | 10 +- indra/llui/llprogressbar.h | 8 +- indra/llui/llresizehandle.cpp | 4 +- indra/llui/llrngwriter.cpp | 315 ++++++++ indra/llui/llrngwriter.h | 69 ++ indra/llui/llscrolllistcell.cpp | 10 +- indra/llui/llscrolllistcell.h | 3 +- indra/llui/llscrolllistcolumn.h | 2 +- indra/llui/llscrolllistctrl.cpp | 37 +- indra/llui/llscrolllistctrl.h | 2 +- indra/llui/llscrolllistitem.h | 6 +- indra/llui/llsearcheditor.cpp | 82 +- indra/llui/llsearcheditor.h | 33 +- indra/llui/llstyle.h | 1 - indra/llui/lltabcontainer.cpp | 1 + indra/llui/lltabcontainer.h | 4 + indra/llui/lltextbox.cpp | 7 +- indra/llui/lltextbox.h | 1 - indra/llui/lltexteditor.cpp | 37 +- indra/llui/lltexteditor.h | 28 +- indra/llui/llui.cpp | 19 +- indra/llui/llui.h | 137 +--- indra/llui/lluictrl.cpp | 6 +- indra/llui/lluictrl.h | 2 +- indra/llui/lluictrlfactory.cpp | 420 +++------- indra/llui/lluictrlfactory.h | 39 +- indra/llxml/llxmlnode.cpp | 150 ++-- indra/llxml/llxmlnode.h | 4 +- indra/newview/CMakeLists.txt | 2 + indra/newview/app_settings/settings.xml | 6 +- indra/newview/llavatariconctrl.h | 3 +- indra/newview/llavatarlistitem.h | 4 +- indra/newview/llbottomtray.cpp | 9 + indra/newview/llbottomtray.h | 1 + indra/newview/llchatitemscontainerctrl.cpp | 2 +- indra/newview/llchiclet.cpp | 25 +- indra/newview/llchiclet.h | 4 + indra/newview/llfloaterinventory.cpp | 22 +- indra/newview/llfloaterinventory.h | 6 +- indra/newview/llfloaterland.cpp | 18 +- indra/newview/llfloateruipreview.cpp | 15 +- indra/newview/llfloateruipreview.h | 1 + indra/newview/llfloaterworldmap.h | 1 + indra/newview/llfolderviewitem.cpp | 5 +- indra/newview/llimpanel.cpp | 235 +++++- indra/newview/llimpanel.h | 44 +- indra/newview/llimview.cpp | 12 +- indra/newview/llimview.h | 6 +- indra/newview/llmenucommands.cpp | 1 + indra/newview/llnameeditor.h | 5 + indra/newview/llnamelistctrl.cpp | 2 +- indra/newview/llnamelistctrl.h | 4 +- indra/newview/llnavigationbar.cpp | 10 +- indra/newview/llnavigationbar.h | 4 +- indra/newview/lloutputmonitorctrl.cpp | 3 +- indra/newview/llpanelavatar.cpp | 1 + indra/newview/llpanelimcontrolpanel.cpp | 87 +++ indra/newview/llpanelimcontrolpanel.h | 55 ++ indra/newview/llpanellandmarks.cpp | 1 + indra/newview/llpanellogin.h | 1 + indra/newview/llpanelpeople.cpp | 12 +- indra/newview/llpanelpeople.h | 6 +- indra/newview/llpanelpick.cpp | 1 + indra/newview/llpanelplaces.cpp | 18 +- indra/newview/llpanelplaces.h | 6 +- indra/newview/llpanelplacestab.cpp | 4 +- indra/newview/llsidetray.cpp | 2 +- indra/newview/llsidetray.h | 25 +- indra/newview/lltexturectrl.cpp | 22 +- indra/newview/lltexturectrl.h | 2 +- indra/newview/lltoast.cpp | 4 +- indra/newview/lltoastnotifypanel.cpp | 2 +- indra/newview/llviewermessage.cpp | 2 +- indra/newview/llviewerwindow.cpp | 1 + indra/newview/skins/default/textures/textures.xml | 3 +- .../skins/default/xui/en/floater_about_land.xml | 2 +- .../skins/default/xui/en/floater_im_session.xml | 73 +- .../skins/default/xui/en/floater_inspect.xml | 6 +- .../skins/default/xui/en/floater_inventory.xml | 2 +- .../skins/default/xui/en/floater_test_widgets.xml | 8 +- .../skins/default/xui/en/floater_texture_ctrl.xml | 2 +- .../skins/default/xui/en/floater_ui_preview.xml | 11 +- .../skins/default/xui/en/panel_bottomtray.xml | 1 + .../newview/skins/default/xui/en/panel_friends.xml | 2 +- .../default/xui/en/panel_im_control_panel.xml | 32 + .../skins/default/xui/en/panel_navigation_bar.xml | 24 +- .../newview/skins/default/xui/en/panel_people.xml | 3 +- .../newview/skins/default/xui/en/panel_places.xml | 2 +- .../default/xui/en/panel_teleport_history.xml | 2 +- indra/newview/skins/default/xui/en/strings.xml | 2 + .../skins/default/xui/en/widgets/filter_editor.xml | 7 + .../skins/default/xui/en/widgets/line_editor.xml | 10 +- .../skins/default/xui/en/widgets/scroll_list.xml | 2 +- .../skins/default/xui/en/widgets/search_editor.xml | 13 +- .../default/xui/en/widgets/simple_text_editor.xml | 32 +- .../skins/default/xui/en/widgets/text_editor.xml | 21 +- 128 files changed, 3647 insertions(+), 1689 deletions(-) create mode 100644 indra/llrender/llfontfreetype.cpp create mode 100644 indra/llrender/llfontfreetype.h create mode 100644 indra/llui/llfiltereditor.cpp create mode 100644 indra/llui/llfiltereditor.h create mode 100644 indra/llui/llhandle.h create mode 100644 indra/llui/llrngwriter.cpp create mode 100644 indra/llui/llrngwriter.h create mode 100644 indra/newview/llpanelimcontrolpanel.cpp create mode 100644 indra/newview/llpanelimcontrolpanel.h create mode 100644 indra/newview/skins/default/xui/en/panel_im_control_panel.xml create mode 100644 indra/newview/skins/default/xui/en/widgets/filter_editor.xml (limited to 'indra/llrender') diff --git a/indra/integration_tests/llui_libtest/llui_libtest.cpp b/indra/integration_tests/llui_libtest/llui_libtest.cpp index e0117eca06..54fc167adf 100644 --- a/indra/integration_tests/llui_libtest/llui_libtest.cpp +++ b/indra/integration_tests/llui_libtest/llui_libtest.cpp @@ -41,6 +41,7 @@ #include "lldir.h" #include "llerrorcontrol.h" #include "llfloater.h" +#include "llfontfreetype.h" #include "llfontgl.h" #include "lltrans.h" #include "llui.h" diff --git a/indra/integration_tests/llui_libtest/llwidgetreg.cpp b/indra/integration_tests/llui_libtest/llwidgetreg.cpp index 4e59971f29..5a97f2aefd 100644 --- a/indra/integration_tests/llui_libtest/llwidgetreg.cpp +++ b/indra/integration_tests/llui_libtest/llwidgetreg.cpp @@ -42,6 +42,7 @@ #include "llmultisliderctrl.h" #include "llprogressbar.h" #include "llradiogroup.h" +#include "llsearcheditor.h" #include "llscrollcontainer.h" #include "llscrollingpanellist.h" #include "llscrolllistctrl.h" @@ -53,7 +54,7 @@ #include "lltextbox.h" #include "lltexteditor.h" #include "llflyoutbutton.h" -#include "llsearcheditor.h" +#include "llfiltereditor.h" #include "lllayoutstack.h" void LLWidgetReg::initClass(bool register_widgets) @@ -65,11 +66,11 @@ void LLWidgetReg::initClass(bool register_widgets) LLDefaultChildRegistry::Register button("button"); LLDefaultChildRegistry::Register check_box("check_box"); LLDefaultChildRegistry::Register combo_box("combo_box"); + LLDefaultChildRegistry::Register filter_editor("filter_editor"); LLDefaultChildRegistry::Register flyout_button("flyout_button"); LLDefaultChildRegistry::Register container_view("container_view"); LLDefaultChildRegistry::Register icon("icon"); LLDefaultChildRegistry::Register line_editor("line_editor"); - LLDefaultChildRegistry::Register search_editor("search_editor"); LLDefaultChildRegistry::Register menu_item_separator("menu_item_separator"); LLDefaultChildRegistry::Register menu_item_call_gl("menu_item_call"); LLDefaultChildRegistry::Register menu_item_check_gl("menu_item_check"); @@ -83,6 +84,7 @@ void LLWidgetReg::initClass(bool register_widgets) LLDefaultChildRegistry::Register progress_bar("progress_bar"); LLDefaultChildRegistry::Register radio_group("radio_group"); LLDefaultChildRegistry::Register radio_item("radio_item"); + LLDefaultChildRegistry::Register search_editor("search_editor"); LLDefaultChildRegistry::Register scroll_container("scroll_container"); LLDefaultChildRegistry::Register scrolling_panel_list("scrolling_panel_list"); LLDefaultChildRegistry::Register scroll_list("scroll_list"); diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt index 0e0fc6ce6c..aac650bec9 100644 --- a/indra/llrender/CMakeLists.txt +++ b/indra/llrender/CMakeLists.txt @@ -26,7 +26,7 @@ include_directories( set(llrender_SOURCE_FILES llcubemap.cpp - llfont.cpp + llfontfreetype.cpp llfontgl.cpp llfontbitmapcache.cpp llfontregistry.cpp @@ -45,7 +45,7 @@ set(llrender_HEADER_FILES llcubemap.h llfontgl.h - llfont.h + llfontfreetype.h llfontbitmapcache.h llfontregistry.h llgl.h diff --git a/indra/llrender/llfontbitmapcache.h b/indra/llrender/llfontbitmapcache.h index 4beea0d026..4a57052b91 100644 --- a/indra/llrender/llfontbitmapcache.h +++ b/indra/llrender/llfontbitmapcache.h @@ -36,7 +36,7 @@ #include // Maintain a collection of bitmaps containing rendered glyphs. -// Generalizes the single-bitmap logic from LLFont and LLFontGL. +// Generalizes the single-bitmap logic from LLFontFreetype and LLFontGL. class LLFontBitmapCache: public LLRefCount { public: diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp new file mode 100644 index 0000000000..91a95cdd25 --- /dev/null +++ b/indra/llrender/llfontfreetype.cpp @@ -0,0 +1,630 @@ +/** + * @file llfontfreetype.cpp + * @brief Freetype font library wrapper + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2009, 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 "linden_common.h" + +#include "llfontfreetype.h" + +// Freetype stuff +#include + +// For some reason, this won't work if it's not wrapped in the ifdef +#ifdef FT_FREETYPE_H +#include FT_FREETYPE_H +#endif + +#include "llerror.h" +#include "llimage.h" +//#include "llimagej2c.h" +#include "llmath.h" // Linden math +#include "llstring.h" +//#include "imdebug.h" +#include "llfontbitmapcache.h" +#include "llgl.h" + +FT_Render_Mode gFontRenderMode = FT_RENDER_MODE_NORMAL; + +LLFontManager *gFontManagerp = NULL; + +FT_Library gFTLibrary = NULL; + +//static +void LLFontManager::initClass() +{ + gFontManagerp = new LLFontManager; +} + +//static +void LLFontManager::cleanupClass() +{ + delete gFontManagerp; + gFontManagerp = NULL; +} + +LLFontManager::LLFontManager() +{ + int error; + error = FT_Init_FreeType(&gFTLibrary); + if (error) + { + // Clean up freetype libs. + llerrs << "Freetype initialization failure!" << llendl; + FT_Done_FreeType(gFTLibrary); + } +} + +LLFontManager::~LLFontManager() +{ + FT_Done_FreeType(gFTLibrary); +} + + +LLFontGlyphInfo::LLFontGlyphInfo(U32 index) +: mGlyphIndex(index), + mXBitmapOffset(0), // Offset to the origin in the bitmap + mYBitmapOffset(0), // Offset to the origin in the bitmap + mXBearing(0), // Distance from baseline to left in pixels + mYBearing(0), // Distance from baseline to top in pixels + mWidth(0), // In pixels + mHeight(0), // In pixels + mXAdvance(0.f), // In pixels + mYAdvance(0.f), // In pixels + mIsRendered(FALSE), + mMetricsValid(FALSE) +{ +} + +LLFontFreetype::LLFontFreetype() +: mFontBitmapCachep(new LLFontBitmapCache), + mValid(FALSE), + mAscender(0.f), + mDescender(0.f), + mLineHeight(0.f), + mIsFallback(FALSE), + mFTFace(NULL), + mRenderGlyphCount(0), + mAddGlyphCount(0), + mPointSize(0) +{ +} + + +LLFontFreetype::~LLFontFreetype() +{ + // Clean up freetype libs. + if (mFTFace) + FT_Done_Face(mFTFace); + mFTFace = NULL; + + // Delete glyph info + std::for_each(mCharGlyphInfoMap.begin(), mCharGlyphInfoMap.end(), DeletePairedPointer()); + + // mFontBitmapCachep will be cleaned up by LLPointer destructor. + // mFallbackFonts cleaned up by LLPointer destructor +} + +BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback) +{ + // Don't leak face objects. This is also needed to deal with + // changed font file names. + if (mFTFace) + { + FT_Done_Face(mFTFace); + mFTFace = NULL; + } + + int error; + + error = FT_New_Face( gFTLibrary, + filename.c_str(), + 0, + &mFTFace ); + + if (error) + { + return FALSE; + } + + mIsFallback = is_fallback; + F32 pixels_per_em = (point_size / 72.f)*vert_dpi; // Size in inches * dpi + + error = FT_Set_Char_Size(mFTFace, /* handle to face object */ + 0, /* char_width in 1/64th of points */ + (S32)(point_size*64), /* char_height in 1/64th of points */ + (U32)horz_dpi, /* horizontal device resolution */ + (U32)vert_dpi); /* vertical device resolution */ + + if (error) + { + // Clean up freetype libs. + FT_Done_Face(mFTFace); + mFTFace = NULL; + return FALSE; + } + + F32 y_max, y_min, x_max, x_min; + F32 ems_per_unit = 1.f/ mFTFace->units_per_EM; + F32 pixels_per_unit = pixels_per_em * ems_per_unit; + + // Get size of bbox in pixels + y_max = mFTFace->bbox.yMax * pixels_per_unit; + y_min = mFTFace->bbox.yMin * pixels_per_unit; + x_max = mFTFace->bbox.xMax * pixels_per_unit; + x_min = mFTFace->bbox.xMin * pixels_per_unit; + mAscender = mFTFace->ascender * pixels_per_unit; + mDescender = -mFTFace->descender * pixels_per_unit; + mLineHeight = mFTFace->height * pixels_per_unit; + + S32 max_char_width = llround(0.5f + (x_max - x_min)); + S32 max_char_height = llround(0.5f + (y_max - y_min)); + + mFontBitmapCachep->init(components, max_char_width, max_char_height); + + if (!mFTFace->charmap) + { + //llinfos << " no unicode encoding, set whatever encoding there is..." << llendl; + FT_Set_Charmap(mFTFace, mFTFace->charmaps[0]); + } + + if (!mIsFallback) + { + // Add the default glyph + addGlyph(0, 0); + } + + mName = filename; + mPointSize = point_size; + + return TRUE; +} + +void LLFontFreetype::setFallbackFonts(const font_vector_t &font) +{ + mFallbackFonts = font; +} + +const LLFontFreetype::font_vector_t &LLFontFreetype::getFallbackFonts() const +{ + return mFallbackFonts; +} + +F32 LLFontFreetype::getLineHeight() const +{ + return mLineHeight; +} + +F32 LLFontFreetype::getAscenderHeight() const +{ + return mAscender; +} + +F32 LLFontFreetype::getDescenderHeight() const +{ + return mDescender; +} + +F32 LLFontFreetype::getXAdvance(llwchar wch) const +{ + if (mFTFace == NULL) + return 0.0; + + llassert(!mIsFallback); + U32 glyph_index; + + // Return existing info only if it is current + LLFontGlyphInfo* gi = getGlyphInfo(wch); + if (gi && gi->mMetricsValid) + { + return gi->mXAdvance; + } + + const LLFontFreetype* fontp = this; + + // Initialize char to glyph map + glyph_index = FT_Get_Char_Index(mFTFace, wch); + if (glyph_index == 0) + { + font_vector_t::const_iterator iter; + for(iter = mFallbackFonts.begin(); (iter != mFallbackFonts.end()) && (glyph_index == 0); iter++) + { + glyph_index = FT_Get_Char_Index((*iter)->mFTFace, wch); + if(glyph_index) + { + fontp = *iter; + } + } + } + + if (glyph_index) + { + // This font has this glyph + fontp->renderGlyph(glyph_index); + + // Create the entry if it's not there + char_glyph_info_map_t::iterator iter2 = mCharGlyphInfoMap.find(wch); + if (iter2 == mCharGlyphInfoMap.end()) + { + gi = new LLFontGlyphInfo(glyph_index); + insertGlyphInfo(wch, gi); + } + else + { + gi = iter2->second; + } + + gi->mWidth = fontp->mFTFace->glyph->bitmap.width; + gi->mHeight = fontp->mFTFace->glyph->bitmap.rows; + + // Convert these from 26.6 units to float pixels. + gi->mXAdvance = fontp->mFTFace->glyph->advance.x / 64.f; + gi->mYAdvance = fontp->mFTFace->glyph->advance.y / 64.f; + gi->mMetricsValid = TRUE; + return gi->mXAdvance; + } + else + { + gi = get_if_there(mCharGlyphInfoMap, (llwchar)0, (LLFontGlyphInfo*)NULL); + if (gi) + { + return gi->mXAdvance; + } + } + + // Last ditch fallback - no glyphs defined at all. + return (F32)mFontBitmapCachep->getMaxCharWidth(); +} + +F32 LLFontFreetype::getXKerning(llwchar char_left, llwchar char_right) const +{ + if (mFTFace == NULL) + return 0.0; + + llassert(!mIsFallback); + LLFontGlyphInfo* left_glyph_info = get_if_there(mCharGlyphInfoMap, char_left, (LLFontGlyphInfo*)NULL); + U32 left_glyph = left_glyph_info ? left_glyph_info->mGlyphIndex : 0; + // Kern this puppy. + LLFontGlyphInfo* right_glyph_info = get_if_there(mCharGlyphInfoMap, char_right, (LLFontGlyphInfo*)NULL); + U32 right_glyph = right_glyph_info ? right_glyph_info->mGlyphIndex : 0; + + FT_Vector delta; + + llverify(!FT_Get_Kerning(mFTFace, left_glyph, right_glyph, ft_kerning_unfitted, &delta)); + + return delta.x*(1.f/64.f); +} + +BOOL LLFontFreetype::hasGlyph(llwchar wch) const +{ + llassert(!mIsFallback); + const LLFontGlyphInfo* gi = getGlyphInfo(wch); + if (gi && gi->mIsRendered) + { + return TRUE; + } + else + { + return FALSE; + } +} + +BOOL LLFontFreetype::addChar(llwchar wch) const +{ + if (mFTFace == NULL) + return FALSE; + + llassert(!mIsFallback); + //lldebugs << "Adding new glyph for " << wch << " to font" << llendl; + + FT_UInt glyph_index; + + // Initialize char to glyph map + glyph_index = FT_Get_Char_Index(mFTFace, wch); + if (glyph_index == 0) + { + //llinfos << "Trying to add glyph from fallback font!" << llendl + font_vector_t::const_iterator iter; + for(iter = mFallbackFonts.begin(); iter != mFallbackFonts.end(); iter++) + { + glyph_index = FT_Get_Char_Index((*iter)->mFTFace, wch); + if (glyph_index) + { + addGlyphFromFont(*iter, wch, glyph_index); + return TRUE; + } + } + } + + char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.find(wch); + if (iter == mCharGlyphInfoMap.end() || !(iter->second->mIsRendered)) + { + BOOL result = addGlyph(wch, glyph_index); + return result; + } + return FALSE; +} + +BOOL LLFontFreetype::addGlyph(llwchar wch, U32 glyph_index) const +{ + return addGlyphFromFont(this, wch, glyph_index); +} + +BOOL LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index) const +{ + if (mFTFace == NULL) + return FALSE; + + llassert(!mIsFallback); + fontp->renderGlyph(glyph_index); + S32 width = fontp->mFTFace->glyph->bitmap.width; + S32 height = fontp->mFTFace->glyph->bitmap.rows; + + S32 pos_x, pos_y; + S32 bitmap_num; + mFontBitmapCachep->nextOpenPos(width, pos_x, pos_y, bitmap_num); + mAddGlyphCount++; + + LLFontGlyphInfo* gi = new LLFontGlyphInfo(glyph_index); + gi->mXBitmapOffset = pos_x; + gi->mYBitmapOffset = pos_y; + gi->mBitmapNum = bitmap_num; + gi->mWidth = width; + gi->mHeight = height; + gi->mXBearing = fontp->mFTFace->glyph->bitmap_left; + gi->mYBearing = fontp->mFTFace->glyph->bitmap_top; + // Convert these from 26.6 units to float pixels. + gi->mXAdvance = fontp->mFTFace->glyph->advance.x / 64.f; + gi->mYAdvance = fontp->mFTFace->glyph->advance.y / 64.f; + gi->mIsRendered = TRUE; + gi->mMetricsValid = TRUE; + + insertGlyphInfo(wch, gi); + + llassert(fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO + || fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY); + + if (fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO + || fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY) + { + U8 *buffer_data = fontp->mFTFace->glyph->bitmap.buffer; + S32 buffer_row_stride = fontp->mFTFace->glyph->bitmap.pitch; + U8 *tmp_graydata = NULL; + + if (fontp->mFTFace->glyph->bitmap.pixel_mode + == FT_PIXEL_MODE_MONO) + { + // need to expand 1-bit bitmap to 8-bit graymap. + tmp_graydata = new U8[width * height]; + S32 xpos, ypos; + for (ypos = 0; ypos < height; ++ypos) + { + S32 bm_row_offset = buffer_row_stride * ypos; + for (xpos = 0; xpos < width; ++xpos) + { + U32 bm_col_offsetbyte = xpos / 8; + U32 bm_col_offsetbit = 7 - (xpos % 8); + U32 bit = + !!(buffer_data[bm_row_offset + + bm_col_offsetbyte + ] & (1 << bm_col_offsetbit) ); + tmp_graydata[width*ypos + xpos] = + 255 * bit; + } + } + // use newly-built graymap. + buffer_data = tmp_graydata; + buffer_row_stride = width; + } + + switch (mFontBitmapCachep->getNumComponents()) + { + case 1: + mFontBitmapCachep->getImageRaw(bitmap_num)->setSubImage(pos_x, + pos_y, + width, + height, + buffer_data, + buffer_row_stride, + TRUE); + break; + case 2: + setSubImageLuminanceAlpha(pos_x, + pos_y, + bitmap_num, + width, + height, + buffer_data, + buffer_row_stride); + break; + default: + break; + } + + if (tmp_graydata) + delete[] tmp_graydata; + } else { + // we don't know how to handle this pixel format from FreeType; + // omit it from the font-image. + } + + return TRUE; +} + +LLFontGlyphInfo* LLFontFreetype::getGlyphInfo(llwchar wch) const +{ + char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.find(wch); + if (iter != mCharGlyphInfoMap.end()) + { + return iter->second; + } + return NULL; +} + +void LLFontFreetype::insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const +{ + char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.find(wch); + if (iter != mCharGlyphInfoMap.end()) + { + delete iter->second; + iter->second = gi; + } + else + { + mCharGlyphInfoMap[wch] = gi; + } +} + +void LLFontFreetype::renderGlyph(U32 glyph_index) const +{ + if (mFTFace == NULL) + return; + + int error = FT_Load_Glyph(mFTFace, glyph_index, FT_LOAD_DEFAULT ); + llassert(!error); + + error = FT_Render_Glyph(mFTFace->glyph, gFontRenderMode); + + mRenderGlyphCount++; + + llassert(!error); +} + +void LLFontFreetype::reset(F32 vert_dpi, F32 horz_dpi) +{ + if (!mIsFallback) + { + // This is the head of the list - need to rebuild ourself and all fallbacks. + loadFace(mName, mPointSize, vert_dpi ,horz_dpi, mFontBitmapCachep->getNumComponents(), mIsFallback); + + if (mFallbackFonts.empty()) + { + llwarns << "LLFontGL::reset(), no fallback fonts present" << llendl; + } + else + { + for(font_vector_t::iterator it = mFallbackFonts.begin(); + it != mFallbackFonts.end(); + ++it) + { + (*it)->reset(vert_dpi, horz_dpi); + } + } + } + resetBitmapCache(); +} + +void LLFontFreetype::resetBitmapCache() +{ + // Iterate through glyphs and clear the mIsRendered flag + for (char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.begin(); + iter != mCharGlyphInfoMap.end(); ++iter) + { + iter->second->mIsRendered = FALSE; + //FIXME: this is only strictly necessary when resetting the entire font, + //not just flushing the bitmap + iter->second->mMetricsValid = FALSE; + } + mFontBitmapCachep->reset(); + + // Add the empty glyph`5 + addGlyph(0, 0); +} + +void LLFontFreetype::destroyGL() +{ + mFontBitmapCachep->destroyGL(); +} + +BOOL LLFontFreetype::getIsFallback() const +{ + return mIsFallback; +} + +const std::string &LLFontFreetype::getName() const +{ + return mName; +} + +F32 LLFontFreetype::getPointSize() const +{ + return mPointSize; +} + +const LLPointer LLFontFreetype::getFontBitmapCache() const +{ + return mFontBitmapCachep; +} + +void LLFontFreetype::setStyle(U8 style) +{ + mStyle = style; +} + +U8 LLFontFreetype::getStyle() const +{ + return mStyle; +} + +void LLFontFreetype::setSubImageLuminanceAlpha(U32 x, U32 y, U32 bitmap_num, U32 width, U32 height, U8 *data, S32 stride) const +{ + LLImageRaw *image_raw = mFontBitmapCachep->getImageRaw(bitmap_num); + + llassert(!mIsFallback); + llassert(image_raw && (image_raw->getComponents() == 2)); + + + U8 *target = image_raw->getData(); + + if (!data) + { + return; + } + + if (0 == stride) + stride = width; + + U32 i, j; + U32 to_offset; + U32 from_offset; + U32 target_width = image_raw->getWidth(); + for (i = 0; i < height; i++) + { + to_offset = (y + i)*target_width + x; + from_offset = (height - 1 - i)*stride; + for (j = 0; j < width; j++) + { + *(target + to_offset*2 + 1) = *(data + from_offset); + to_offset++; + from_offset++; + } + } +} + diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h new file mode 100644 index 0000000000..0520ef2cd6 --- /dev/null +++ b/indra/llrender/llfontfreetype.h @@ -0,0 +1,380 @@ +/** + * @file llfontfreetype.h + * @brief Font library wrapper + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2009, 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$ + */ + +#ifndef LL_LLFONTFREETYPE_H +#define LL_LLFONTFREETYPE_H + +#include +#include "llpointer.h" +#include "llstl.h" + +#include "llimagegl.h" +#include "llfontbitmapcache.h" + +// Hack. FT_Face is just a typedef for a pointer to a struct, +// but there's no simple forward declarations file for FreeType, +// and the main include file is 200K. +// We'll forward declare the struct here. JC +struct FT_FaceRec_; +typedef struct FT_FaceRec_* LLFT_Face; + +class LLFontManager +{ +public: + static void initClass(); + static void cleanupClass(); + +private: + LLFontManager(); + ~LLFontManager(); +}; + +class LLFontGlyphInfo +{ +public: + LLFontGlyphInfo(U32 index); + + U32 mGlyphIndex; + + // Metrics + S32 mWidth; // In pixels + S32 mHeight; // In pixels + F32 mXAdvance; // In pixels + F32 mYAdvance; // In pixels + BOOL mMetricsValid; // We have up-to-date metrics for this glyph + + // Information for actually rendering + BOOL mIsRendered; // We actually have rendered this glyph + S32 mXBitmapOffset; // Offset to the origin in the bitmap + S32 mYBitmapOffset; // Offset to the origin in the bitmap + S32 mXBearing; // Distance from baseline to left in pixels + S32 mYBearing; // Distance from baseline to top in pixels + S32 mBitmapNum; // Which bitmap in the bitmap cache contains this glyph +}; + +extern LLFontManager *gFontManagerp; + +class LLFontFreetype : public LLRefCount +{ +public: + LLFontFreetype(); + ~LLFontFreetype(); + + // is_fallback should be true for fallback fonts that aren't used + // to render directly (Unicode backup, primarily) + BOOL loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback); + + typedef std::vector > font_vector_t; + + void setFallbackFonts(const font_vector_t &font); + const font_vector_t &getFallbackFonts() const; + + // Global font metrics - in units of pixels + F32 getLineHeight() const; + F32 getAscenderHeight() const; + F32 getDescenderHeight() const; + + +// For a lowercase "g": +// +// ------------------------------ +// ^ ^ +// | | +// xxx x |Ascender +// x x v | +// --------- xxxx-------------- Baseline +// ^ x | +// | Descender x | +// v xxxx |LineHeight +// ----------------------- | +// v +// ------------------------------ + + enum + { + FIRST_CHAR = 32, + NUM_CHARS = 127 - 32, + LAST_CHAR_BASIC = 127, + + // Need full 8-bit ascii range for spanish + NUM_CHARS_FULL = 255 - 32, + LAST_CHAR_FULL = 255 + }; + + F32 getXAdvance(llwchar wc) const; + F32 getXKerning(llwchar char_left, llwchar char_right) const; // Get the kerning between the two characters + + BOOL hasGlyph(llwchar wch) const; // Has a glyph for this character + BOOL addChar(llwchar wch) const; // Add a new character to the font if necessary + BOOL addGlyph(llwchar wch, U32 glyph_index) const; // Add a new glyph to the existing font + BOOL addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index) const; // Add a glyph from this font to the other (returns the glyph_index, 0 if not found) + + LLFontGlyphInfo* getGlyphInfo(llwchar wch) const; + + void insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const; + void renderGlyph(U32 glyph_index) const; + + void reset(F32 vert_dpi, F32 horz_dpi); + void resetBitmapCache(); + + void destroyGL(); + + BOOL getIsFallback() const; + + const std::string& getName() const; + + F32 getPointSize() const; + + const LLPointer getFontBitmapCache() const; + + void setStyle(U8 style); + U8 getStyle() const; + +private: + void setSubImageLuminanceAlpha(U32 x, U32 y, U32 bitmap_num, U32 width, U32 height, U8 *data, S32 stride = 0) const; + + std::string mName; + + U8 mStyle; + + F32 mPointSize; + F32 mAscender; + F32 mDescender; + F32 mLineHeight; + + LLFT_Face mFTFace; + + BOOL mIsFallback; + font_vector_t mFallbackFonts; // A list of fallback fonts to look for glyphs in (for Unicode chars) + + BOOL mValid; + + typedef std::map char_glyph_info_map_t; + mutable char_glyph_info_map_t mCharGlyphInfoMap; // Information about glyph location in bitmap + + mutable LLPointer mFontBitmapCachep; + + mutable S32 mRenderGlyphCount; + mutable S32 mAddGlyphCount; +}; + +#endif // LL_FONTFREETYPE_H +/** + * @file llfontfreetype.h + * @brief Font library wrapper + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2009, 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$ + */ + +#ifndef LL_LLFONTFREETYPE_H +#define LL_LLFONTFREETYPE_H + +#include +#include "llpointer.h" +#include "llstl.h" + +#include "llimagegl.h" +#include "llfontbitmapcache.h" + +// Hack. FT_Face is just a typedef for a pointer to a struct, +// but there's no simple forward declarations file for FreeType, +// and the main include file is 200K. +// We'll forward declare the struct here. JC +struct FT_FaceRec_; +typedef struct FT_FaceRec_* LLFT_Face; + +class LLFontManager +{ +public: + static void initClass(); + static void cleanupClass(); + +private: + LLFontManager(); + ~LLFontManager(); +}; + +class LLFontGlyphInfo +{ +public: + LLFontGlyphInfo(U32 index); + + U32 mGlyphIndex; + + // Metrics + S32 mWidth; // In pixels + S32 mHeight; // In pixels + F32 mXAdvance; // In pixels + F32 mYAdvance; // In pixels + BOOL mMetricsValid; // We have up-to-date metrics for this glyph + + // Information for actually rendering + BOOL mIsRendered; // We actually have rendered this glyph + S32 mXBitmapOffset; // Offset to the origin in the bitmap + S32 mYBitmapOffset; // Offset to the origin in the bitmap + S32 mXBearing; // Distance from baseline to left in pixels + S32 mYBearing; // Distance from baseline to top in pixels + S32 mBitmapNum; // Which bitmap in the bitmap cache contains this glyph +}; + +extern LLFontManager *gFontManagerp; + +class LLFontFreetype : public LLRefCount +{ +public: + LLFontFreetype(); + ~LLFontFreetype(); + + // is_fallback should be true for fallback fonts that aren't used + // to render directly (Unicode backup, primarily) + BOOL loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback); + + typedef std::vector > font_vector_t; + + void setFallbackFonts(const font_vector_t &font); + const font_vector_t &getFallbackFonts() const; + + // Global font metrics - in units of pixels + F32 getLineHeight() const; + F32 getAscenderHeight() const; + F32 getDescenderHeight() const; + + +// For a lowercase "g": +// +// ------------------------------ +// ^ ^ +// | | +// xxx x |Ascender +// x x v | +// --------- xxxx-------------- Baseline +// ^ x | +// | Descender x | +// v xxxx |LineHeight +// ----------------------- | +// v +// ------------------------------ + + enum + { + FIRST_CHAR = 32, + NUM_CHARS = 127 - 32, + LAST_CHAR_BASIC = 127, + + // Need full 8-bit ascii range for spanish + NUM_CHARS_FULL = 255 - 32, + LAST_CHAR_FULL = 255 + }; + + F32 getXAdvance(llwchar wc) const; + F32 getXKerning(llwchar char_left, llwchar char_right) const; // Get the kerning between the two characters + + BOOL hasGlyph(llwchar wch) const; // Has a glyph for this character + BOOL addChar(llwchar wch) const; // Add a new character to the font if necessary + BOOL addGlyph(llwchar wch, U32 glyph_index) const; // Add a new glyph to the existing font + BOOL addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index) const; // Add a glyph from this font to the other (returns the glyph_index, 0 if not found) + + LLFontGlyphInfo* getGlyphInfo(llwchar wch) const; + + void insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const; + void renderGlyph(U32 glyph_index) const; + + void reset(F32 vert_dpi, F32 horz_dpi); + void resetBitmapCache(); + + void destroyGL(); + + BOOL getIsFallback() const; + + const std::string& getName() const; + + F32 getPointSize() const; + + const LLPointer getFontBitmapCache() const; + + void setStyle(U8 style); + U8 getStyle() const; + +private: + void setSubImageLuminanceAlpha(U32 x, U32 y, U32 bitmap_num, U32 width, U32 height, U8 *data, S32 stride = 0) const; + + std::string mName; + + U8 mStyle; + + F32 mPointSize; + F32 mAscender; + F32 mDescender; + F32 mLineHeight; + + LLFT_Face mFTFace; + + BOOL mIsFallback; + font_vector_t mFallbackFonts; // A list of fallback fonts to look for glyphs in (for Unicode chars) + + BOOL mValid; + + typedef std::map char_glyph_info_map_t; + mutable char_glyph_info_map_t mCharGlyphInfoMap; // Information about glyph location in bitmap + + mutable LLPointer mFontBitmapCachep; + + mutable S32 mRenderGlyphCount; + mutable S32 mAddGlyphCount; +}; + +#endif // LL_FONTFREETYPE_H diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 0b57d86c78..32a008047c 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -35,7 +35,7 @@ #include "llfontgl.h" // Linden library includes -#include "llfont.h" +#include "llfontfreetype.h" #include "llfontbitmapcache.h" #include "llfontregistry.h" #include "llgl.h" @@ -73,54 +73,25 @@ const F32 PIXEL_CORRECTION_DISTANCE = 0.01f; const F32 PAD_UVY = 0.5f; // half of vertical padding between glyphs in the glyph texture const F32 DROP_SHADOW_SOFT_STRENGTH = 0.3f; -F32 llfont_round_x(F32 x) +static F32 llfont_round_x(F32 x) { //return llfloor((x-LLFontGL::sCurOrigin.mX)/LLFontGL::sScaleX+0.5f)*LLFontGL::sScaleX+LLFontGL::sCurOrigin.mX; //return llfloor(x/LLFontGL::sScaleX+0.5f)*LLFontGL::sScaleY; return x; } -F32 llfont_round_y(F32 y) +static F32 llfont_round_y(F32 y) { //return llfloor((y-LLFontGL::sCurOrigin.mY)/LLFontGL::sScaleY+0.5f)*LLFontGL::sScaleY+LLFontGL::sCurOrigin.mY; //return llfloor(y+0.5f); return y; } -// static -U8 LLFontGL::getStyleFromString(const std::string &style) -{ - S32 ret = 0; - if (style.find("NORMAL") != style.npos) - { - ret |= NORMAL; - } - if (style.find("BOLD") != style.npos) - { - ret |= BOLD; - } - if (style.find("ITALIC") != style.npos) - { - ret |= ITALIC; - } - if (style.find("UNDERLINE") != style.npos) - { - ret |= UNDERLINE; - } - return ret; -} - LLFontGL::LLFontGL() - : LLFont() { clearEmbeddedChars(); } -LLFontGL::LLFontGL(const LLFontGL &source) -{ - llerrs << "Not implemented!" << llendl; -} - LLFontGL::~LLFontGL() { clearEmbeddedChars(); @@ -128,293 +99,26 @@ LLFontGL::~LLFontGL() void LLFontGL::reset() { - if (!mIsFallback) - { - // This is the head of the list - need to rebuild ourself and all fallbacks. - loadFace(mName,mPointSize,sVertDPI,sHorizDPI,mFontBitmapCachep->getNumComponents(),mIsFallback); - if (mFallbackFontp==NULL) - { - llwarns << "LLFontGL::reset(), no fallback fonts present" << llendl; - } - else - { - for (LLFontList::iterator it = mFallbackFontp->begin(); - it != mFallbackFontp->end(); - ++it) - { - (*it)->reset(); - } - } - } - resetBitmapCache(); -} - -// static -std::string LLFontGL::getFontPathSystem() -{ - std::string system_path; - - // Try to figure out where the system's font files are stored. - char *system_root = NULL; -#if LL_WINDOWS - system_root = getenv("SystemRoot"); /* Flawfinder: ignore */ - if (!system_root) - { - llwarns << "SystemRoot not found, attempting to load fonts from default path." << llendl; - } -#endif - - if (system_root) - { - system_path = llformat("%s/fonts/", system_root); - } - else - { -#if LL_WINDOWS - // HACK for windows 98/Me - system_path = "/WINDOWS/FONTS/"; -#elif LL_DARWIN - // HACK for Mac OS X - system_path = "/System/Library/Fonts/"; -#endif - } - return system_path; -} - - -// static -std::string LLFontGL::getFontPathLocal() -{ - std::string local_path; - - // Backup files if we can't load from system fonts directory. - // We could store this in an end-user writable directory to allow - // end users to switch fonts. - if (LLFontGL::sAppDir.length()) - { - // use specified application dir to look for fonts - local_path = LLFontGL::sAppDir + "/fonts/"; - } - else - { - // assume working directory is executable directory - local_path = "./fonts/"; - } - return local_path; -} - -bool findOrCreateFont(LLFontGL*& fontp, const LLFontDescriptor& desc) -{ - // Don't delete existing fonts, if any, here, because they've - // already been deleted by LLFontRegistry::clear() - fontp = LLFontGL::getFont(desc); - return (fontp != NULL); -} - -// static -void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, - const std::string& app_dir, - const std::vector& xui_paths, - bool create_gl_textures) -{ - sVertDPI = (F32)llfloor(screen_dpi * y_scale); - sHorizDPI = (F32)llfloor(screen_dpi * x_scale); - sScaleX = x_scale; - sScaleY = y_scale; - sAppDir = app_dir; - - // Font registry init - if (!sFontRegistry) - { - sFontRegistry = new LLFontRegistry(xui_paths, create_gl_textures); - sFontRegistry->parseFontInfo("fonts.xml"); - } - else - { - sFontRegistry->reset(); - } -} - -// Force standard fonts to get generated up front. -// This is primarily for error detection purposes. -// Don't do this during initClass because it can be slow and we want to get -// the viewer window on screen first. JC -// static -bool LLFontGL::loadDefaultFonts() -{ - bool succ = true; - succ &= (NULL != getFontSansSerifSmall()); - succ &= (NULL != getFontSansSerif()); - succ &= (NULL != getFontSansSerifBig()); - succ &= (NULL != getFontSansSerifHuge()); - succ &= (NULL != getFontSansSerifBold()); - succ &= (NULL != getFontMonospace()); - succ &= (NULL != getFontExtChar()); - return succ; -} - - - -// static -void LLFontGL::destroyDefaultFonts() -{ - // Remove the actual fonts. - delete sFontRegistry; - sFontRegistry = NULL; -} - -//static -void LLFontGL::destroyAllGL() -{ - if (sFontRegistry) - { - sFontRegistry->destroyGL(); - } + mFontFreetype->reset(sVertDPI, sHorizDPI); } void LLFontGL::destroyGL() { - mFontBitmapCachep->destroyGL(); -} - - - -LLFontGL &LLFontGL::operator=(const LLFontGL &source) -{ - llerrs << "Not implemented" << llendl; - return *this; -} - -BOOL LLFontGL::loadFace(const std::string& filename, - const F32 point_size, const F32 vert_dpi, const F32 horz_dpi, - const S32 components, BOOL is_fallback) -{ - if (!LLFont::loadFace(filename, point_size, vert_dpi, horz_dpi, components, is_fallback)) - { - return FALSE; - } - return TRUE; -} - -//static -LLFontGL* LLFontGL::getFontMonospace() -{ - return getFont(LLFontDescriptor("Monospace","Monospace",0)); -} - -//static -LLFontGL* LLFontGL::getFontSansSerifSmall() -{ - return getFont(LLFontDescriptor("SansSerif","Small",0)); -} - -//static -LLFontGL* LLFontGL::getFontSansSerif() -{ - return getFont(LLFontDescriptor("SansSerif","Medium",0)); -} - -//static -LLFontGL* LLFontGL::getFontSansSerifBig() -{ - return getFont(LLFontDescriptor("SansSerif","Large",0)); -} - -//static -LLFontGL* LLFontGL::getFontSansSerifHuge() -{ - return getFont(LLFontDescriptor("SansSerif","Huge",0)); -} - -//static -LLFontGL* LLFontGL::getFontSansSerifBold() -{ - return getFont(LLFontDescriptor("SansSerif","Medium",BOLD)); -} - -//static -LLFontGL* LLFontGL::getFontExtChar() -{ - return getFontSansSerif(); -} - -//static -LLFontGL* LLFontGL::getFont(const LLFontDescriptor& desc) -{ - return sFontRegistry->getFont(desc); -} - -//static -LLFontGL* LLFontGL::getFontByName(const std::string& name) -{ - // check for most common fonts first - if (name == "SANSSERIF") - { - return getFontSansSerif(); - } - else if (name == "SANSSERIF_SMALL") - { - return getFontSansSerifSmall(); - } - else if (name == "SANSSERIF_BIG") - { - return getFontSansSerifBig(); - } - else if (name == "SMALL" || name == "OCRA") - { - // *BUG: Should this be "MONOSPACE"? Do we use "OCRA" anymore? - // Does "SMALL" mean "SERIF"? - return getFontMonospace(); - } - else - { - return NULL; - } + mFontFreetype->destroyGL(); } -BOOL LLFontGL::addChar(const llwchar wch) const +BOOL LLFontGL::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback) { - if (!LLFont::addChar(wch)) + if(mFontFreetype == reinterpret_cast(NULL)) { - return FALSE; + mFontFreetype = new LLFontFreetype; } - stop_glerror(); - - LLFontGlyphInfo *glyph_info = getGlyphInfo(wch); - U32 bitmap_num = glyph_info->mBitmapNum; - LLImageGL *image_gl = mFontBitmapCachep->getImageGL(bitmap_num); - LLImageRaw *image_raw = mFontBitmapCachep->getImageRaw(bitmap_num); - image_gl->setSubImage(image_raw, 0, 0, image_gl->getWidth(), image_gl->getHeight()); - return TRUE; -} - - -S32 LLFontGL::renderUTF8(const std::string &text, const S32 offset, - const F32 x, const F32 y, - const LLColor4 &color, - const HAlign halign, const VAlign valign, - U8 style, - ShadowType shadow, - const S32 max_chars, const S32 max_pixels, - F32* right_x, - BOOL use_ellipses) const -{ - LLWString wstr = utf8str_to_wstring(text); - return render(wstr, offset, x, y, color, halign, valign, style, shadow, max_chars, max_pixels, right_x, FALSE, use_ellipses); + return mFontFreetype->loadFace(filename, point_size, vert_dpi, horz_dpi, components, is_fallback); } -S32 LLFontGL::render(const LLWString &wstr, - const S32 begin_offset, - const F32 x, const F32 y, - const LLColor4 &color, - const HAlign halign, const VAlign valign, - U8 style, - ShadowType shadow, - const S32 max_chars, S32 max_pixels, - F32* right_x, - BOOL use_embedded, - BOOL use_ellipses) const +S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, + ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, BOOL use_embedded, BOOL use_ellipses) const { if(!sDisplayFont) //do not display texts { @@ -430,8 +134,9 @@ S32 LLFontGL::render(const LLWString &wstr, S32 scaled_max_pixels = max_pixels == S32_MAX ? S32_MAX : llceil((F32)max_pixels * sScaleX); - // Strip off any style bits that are already accounted for by the font. - style = style & (~getFontDesc().getStyle()); + // determine which style flags need to be added programmatically by striping off the + // style bits that are drawn by the underlying Freetype font + U8 style_to_add = (style | mFontDescriptor.getStyle()) & ~mFontFreetype->getStyle(); F32 drop_shadow_strength = 0.f; if (shadow != NO_SHADOW) @@ -483,13 +188,13 @@ S32 LLFontGL::render(const LLWString &wstr, switch (valign) { case TOP: - cur_y -= mAscender; + cur_y -= mFontFreetype->getAscenderHeight(); break; case BOTTOM: - cur_y += mDescender; + cur_y += mFontFreetype->getDescenderHeight(); break; case VCENTER: - cur_y -= ((mAscender - mDescender)/2.f); + cur_y -= ((mFontFreetype->getAscenderHeight() - mFontFreetype->getDescenderHeight())/2.f); break; case BASELINE: // Baseline, do nothing. @@ -517,10 +222,12 @@ S32 LLFontGL::render(const LLWString &wstr, F32 start_x = cur_x; - F32 inv_width = 1.f / mFontBitmapCachep->getBitmapWidth(); - F32 inv_height = 1.f / mFontBitmapCachep->getBitmapHeight(); + const LLFontBitmapCache* font_bitmap_cache = mFontFreetype->getFontBitmapCache(); - const S32 LAST_CHARACTER = LLFont::LAST_CHAR_FULL; + F32 inv_width = 1.f / font_bitmap_cache->getBitmapWidth(); + F32 inv_height = 1.f / font_bitmap_cache->getBitmapHeight(); + + const S32 LAST_CHARACTER = LLFontFreetype::LAST_CHAR_FULL; BOOL draw_ellipses = FALSE; @@ -576,11 +283,11 @@ S32 LLFontGL::render(const LLWString &wstr, // snap origin to whole screen pixel const F32 ext_x = (F32)llround(cur_render_x + (EXT_X_BEARING * sScaleX)); - const F32 ext_y = (F32)llround(cur_render_y + (EXT_Y_BEARING * sScaleY + mAscender - mLineHeight)); + const F32 ext_y = (F32)llround(cur_render_y + (EXT_Y_BEARING * sScaleY + mFontFreetype->getAscenderHeight() - mFontFreetype->getLineHeight())); LLRectf uv_rect(0.f, 1.f, 1.f, 0.f); LLRectf screen_rect(ext_x, ext_y + ext_height, ext_x + ext_width, ext_y); - drawGlyph(screen_rect, uv_rect, LLColor4::white, style, shadow, drop_shadow_strength); + drawGlyph(screen_rect, uv_rect, LLColor4::white, style_to_add, shadow, drop_shadow_strength); if (!label.empty()) { @@ -609,19 +316,19 @@ S32 LLFontGL::render(const LLWString &wstr, } else { - if (!hasGlyph(wch)) + if (!mFontFreetype->hasGlyph(wch)) { addChar(wch); } - const LLFontGlyphInfo* fgi= getGlyphInfo(wch); + const LLFontGlyphInfo* fgi= mFontFreetype->getGlyphInfo(wch); if (!fgi) { llerrs << "Missing Glyph Info" << llendl; break; } // Per-glyph bitmap texture. - LLImageGL *image_gl = mFontBitmapCachep->getImageGL(fgi->mBitmapNum); + LLImageGL *image_gl = mFontFreetype->getFontBitmapCache()->getImageGL(fgi->mBitmapNum); if (last_bound_texture != image_gl) { gGL.getTexUnit(0)->bind(image_gl); @@ -646,7 +353,7 @@ S32 LLFontGL::render(const LLWString &wstr, llround(cur_render_x + (F32)fgi->mXBearing) + (F32)fgi->mWidth, llround(cur_render_y + (F32)fgi->mYBearing) - (F32)fgi->mHeight); - drawGlyph(screen_rect, uv_rect, color, style, shadow, drop_shadow_strength); + drawGlyph(screen_rect, uv_rect, color, style_to_add, shadow, drop_shadow_strength); chars_drawn++; cur_x += fgi->mXAdvance; @@ -656,11 +363,11 @@ S32 LLFontGL::render(const LLWString &wstr, if (next_char && (next_char < LAST_CHARACTER)) { // Kern this puppy. - if (!hasGlyph(next_char)) + if (!mFontFreetype->hasGlyph(next_char)) { addChar(next_char); } - cur_x += getXKerning(wch, next_char); + cur_x += mFontFreetype->getXKerning(wch, next_char); } // Round after kerning. @@ -680,12 +387,14 @@ S32 LLFontGL::render(const LLWString &wstr, *right_x = cur_x / sScaleX; } - if (style & UNDERLINE) + if (style_to_add & UNDERLINE) { + F32 descender = mFontFreetype->getDescenderHeight(); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.begin(LLRender::LINES); - gGL.vertex2f(start_x, cur_y - (mDescender)); - gGL.vertex2f(cur_x, cur_y - (mDescender)); + gGL.vertex2f(start_x, cur_y - (descender)); + gGL.vertex2f(cur_x, cur_y - (descender)); gGL.end(); } @@ -703,7 +412,7 @@ S32 LLFontGL::render(const LLWString &wstr, cur_x / sScaleX, (F32)y, color, LEFT, valign, - style, + style_to_add, shadow, S32_MAX, max_pixels, right_x, @@ -716,8 +425,43 @@ S32 LLFontGL::render(const LLWString &wstr, return chars_drawn; } - -S32 LLFontGL::getWidth(const std::string& utf8text) const +S32 LLFontGL::render(const LLWString &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color) const +{ + return render(text, begin_offset, x, y, color, LEFT, BASELINE, NORMAL, NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE, FALSE); +} + +S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, BOOL use_ellipses) const +{ + return render(utf8str_to_wstring(text), begin_offset, x, y, color, halign, valign, style, shadow, max_chars, max_pixels, right_x, FALSE, use_ellipses); +} + +S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color) const +{ + return renderUTF8(text, begin_offset, (F32)x, (F32)y, color, LEFT, BASELINE, NORMAL, NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE); +} + +S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow) const +{ + return renderUTF8(text, begin_offset, (F32)x, (F32)y, color, halign, valign, style, shadow, S32_MAX, S32_MAX, NULL, FALSE); +} + +// font metrics - override for LLFontFreetype that returns units of virtual pixels +F32 LLFontGL::getLineHeight() const +{ + return (F32)llround(mFontFreetype->getLineHeight() / sScaleY); +} + +F32 LLFontGL::getAscenderHeight() const +{ + return (F32)llround(mFontFreetype->getAscenderHeight() / sScaleY); +} + +F32 LLFontGL::getDescenderHeight() const +{ + return (F32)llround(mFontFreetype->getDescenderHeight() / sScaleY); +} + +S32 LLFontGL::getWidth(const std::string& utf8text) const { LLWString wtext = utf8str_to_wstring(utf8text); return getWidth(wtext.c_str(), 0, S32_MAX); @@ -728,13 +472,13 @@ S32 LLFontGL::getWidth(const llwchar* wchars) const return getWidth(wchars, 0, S32_MAX); } -S32 LLFontGL::getWidth(const std::string& utf8text, const S32 begin_offset, const S32 max_chars) const +S32 LLFontGL::getWidth(const std::string& utf8text, S32 begin_offset, S32 max_chars) const { LLWString wtext = utf8str_to_wstring(utf8text); return getWidth(wtext.c_str(), begin_offset, max_chars); } -S32 LLFontGL::getWidth(const llwchar* wchars, const S32 begin_offset, const S32 max_chars, BOOL use_embedded) const +S32 LLFontGL::getWidth(const llwchar* wchars, S32 begin_offset, S32 max_chars, BOOL use_embedded) const { F32 width = getWidthF32(wchars, begin_offset, max_chars, use_embedded); return llround(width); @@ -751,15 +495,15 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars) const return getWidthF32(wchars, 0, S32_MAX); } -F32 LLFontGL::getWidthF32(const std::string& utf8text, const S32 begin_offset, const S32 max_chars ) const +F32 LLFontGL::getWidthF32(const std::string& utf8text, S32 begin_offset, S32 max_chars ) const { LLWString wtext = utf8str_to_wstring(utf8text); return getWidthF32(wtext.c_str(), begin_offset, max_chars); } -F32 LLFontGL::getWidthF32(const llwchar* wchars, const S32 begin_offset, const S32 max_chars, BOOL use_embedded) const +F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars, BOOL use_embedded) const { - const S32 LAST_CHARACTER = LLFont::LAST_CHAR_FULL; + const S32 LAST_CHARACTER = LLFontFreetype::LAST_CHAR_FULL; F32 cur_x = 0; const S32 max_index = begin_offset + max_chars; @@ -783,7 +527,7 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, const S32 begin_offset, const S } else { - cur_x += getXAdvance(wch); + cur_x += mFontFreetype->getXAdvance(wch); llwchar next_char = wchars[i+1]; if (((i + 1) < max_chars) @@ -791,7 +535,7 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, const S32 begin_offset, const S && (next_char < LAST_CHARACTER)) { // Kern this puppy. - cur_x += getXKerning(wch, next_char); + cur_x += mFontFreetype->getXKerning(wch, next_char); } } // Round after kerning. @@ -801,12 +545,8 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, const S32 begin_offset, const S return cur_x / sScaleX; } - - // Returns the max number of complete characters from text (up to max_chars) that can be drawn in max_pixels -S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars, - BOOL end_on_word_boundary, const BOOL use_embedded, - F32* drawn_pixels) const +S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars, BOOL end_on_word_boundary, BOOL use_embedded, F32* drawn_pixels) const { if (!wchars || !wchars[0] || max_chars == 0) { @@ -899,7 +639,7 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch } } - cur_x += getXAdvance(wch); + cur_x += mFontFreetype->getXAdvance(wch); if (scaled_max_pixels < cur_x) { @@ -910,7 +650,7 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch if (((i+1) < max_chars) && wchars[i+1]) { // Kern this puppy. - cur_x += getXKerning(wch, wchars[i+1]); + cur_x += mFontFreetype->getXKerning(wch, wchars[i+1]); } } // Round after kerning. @@ -929,7 +669,6 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch return i; } - S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_len, S32 start_pos, S32 max_chars) const { if (!wchars || !wchars[0] || max_chars == 0) @@ -948,7 +687,7 @@ S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_ llwchar wch = wchars[i]; const embedded_data_t* ext_data = getEmbeddedCharData(wch); - F32 char_width = ext_data ? getEmbeddedCharAdvance(ext_data) : getXAdvance(wch); + F32 char_width = ext_data ? getEmbeddedCharAdvance(ext_data) : mFontFreetype->getXAdvance(wch); if( scaled_max_pixels < (total_width + char_width) ) { @@ -966,7 +705,7 @@ S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_ if ( i > 0 ) { // kerning - total_width += ext_data ? (EXT_KERNING * sScaleX) : getXKerning(wchars[i-1], wch); + total_width += ext_data ? (EXT_KERNING * sScaleX) : mFontFreetype->getXKerning(wchars[i-1], wch); } // Round after kerning. @@ -976,8 +715,7 @@ S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_ return start_pos - drawable_chars; } - -S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, const S32 begin_offset, F32 target_x, F32 max_pixels, S32 max_chars, BOOL round, BOOL use_embedded) const +S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 target_x, F32 max_pixels, S32 max_chars, BOOL round, BOOL use_embedded) const { if (!wchars || !wchars[0] || max_chars == 0) { @@ -1041,7 +779,7 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, const S32 begin_offset, } else { - F32 char_width = getXAdvance(wch); + F32 char_width = mFontFreetype->getXAdvance(wch); if (round) { @@ -1070,7 +808,7 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, const S32 begin_offset, { llwchar next_char = wchars[i + 1]; // Kern this puppy. - cur_x += getXKerning(wch, next_char); + cur_x += mFontFreetype->getXKerning(wch, next_char); } // Round after kerning. @@ -1081,60 +819,370 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, const S32 begin_offset, return pos; } +void LLFontGL::addEmbeddedChar( llwchar wc, LLTexture* image, const std::string& label ) const +{ + LLWString wlabel = utf8str_to_wstring(label); + addEmbeddedChar(wc, image, wlabel); +} -const LLFontGL::embedded_data_t* LLFontGL::getEmbeddedCharData(const llwchar wch) const +void LLFontGL::addEmbeddedChar( llwchar wc, LLTexture* image, const LLWString& wlabel ) const { - // Handle crappy embedded hack - embedded_map_t::const_iterator iter = mEmbeddedChars.find(wch); + embedded_data_t* ext_data = new embedded_data_t(image->getGLTexture(), wlabel); + mEmbeddedChars[wc] = ext_data; +} + +void LLFontGL::removeEmbeddedChar(llwchar wc) const +{ + embedded_map_t::iterator iter = mEmbeddedChars.find(wc); if (iter != mEmbeddedChars.end()) { - return iter->second; + delete iter->second; + mEmbeddedChars.erase(wc); } - return NULL; } +BOOL LLFontGL::addChar(llwchar wch) const +{ + if (!mFontFreetype->addChar(wch)) + { + return FALSE; + } -F32 LLFontGL::getEmbeddedCharAdvance(const embedded_data_t* ext_data) const + stop_glerror(); + + LLFontGlyphInfo *glyph_info = mFontFreetype->getGlyphInfo(wch); + U32 bitmap_num = glyph_info->mBitmapNum; + + const LLFontBitmapCache* font_bitmap_cache = mFontFreetype->getFontBitmapCache(); + LLImageGL *image_gl = font_bitmap_cache->getImageGL(bitmap_num); + LLImageRaw *image_raw = font_bitmap_cache->getImageRaw(bitmap_num); + image_gl->setSubImage(image_raw, 0, 0, image_gl->getWidth(), image_gl->getHeight()); + return TRUE; +} + +const LLFontDescriptor& LLFontGL::getFontDesc() const { - const LLWString& label = ext_data->mLabel; - LLImageGL* ext_image = ext_data->mImage; + return mFontDescriptor; +} - F32 ext_width = (F32)ext_image->getWidth(); - if( !label.empty() ) +// static +void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, const std::vector& xui_paths, bool create_gl_textures) +{ + sVertDPI = (F32)llfloor(screen_dpi * y_scale); + sHorizDPI = (F32)llfloor(screen_dpi * x_scale); + sScaleX = x_scale; + sScaleY = y_scale; + sAppDir = app_dir; + + // Font registry init + if (!sFontRegistry) { - ext_width += (EXT_X_BEARING + getFontExtChar()->getWidthF32(label.c_str())) * sScaleX; + sFontRegistry = new LLFontRegistry(xui_paths, create_gl_textures); + sFontRegistry->parseFontInfo("fonts.xml"); + } + else + { + sFontRegistry->reset(); } +} - return (EXT_X_BEARING * sScaleX) + ext_width; +// Force standard fonts to get generated up front. +// This is primarily for error detection purposes. +// Don't do this during initClass because it can be slow and we want to get +// the viewer window on screen first. JC +// static +bool LLFontGL::loadDefaultFonts() +{ + bool succ = true; + succ &= (NULL != getFontSansSerifSmall()); + succ &= (NULL != getFontSansSerif()); + succ &= (NULL != getFontSansSerifBig()); + succ &= (NULL != getFontSansSerifHuge()); + succ &= (NULL != getFontSansSerifBold()); + succ &= (NULL != getFontMonospace()); + succ &= (NULL != getFontExtChar()); + return succ; } +// static +void LLFontGL::destroyDefaultFonts() +{ + // Remove the actual fonts. + delete sFontRegistry; + sFontRegistry = NULL; +} -void LLFontGL::clearEmbeddedChars() +//static +void LLFontGL::destroyAllGL() { - for_each(mEmbeddedChars.begin(), mEmbeddedChars.end(), DeletePairedPointer()); - mEmbeddedChars.clear(); + if (sFontRegistry) + { + sFontRegistry->destroyGL(); + } } -void LLFontGL::addEmbeddedChar( llwchar wc, LLTexture* image, const std::string& label ) const +// static +U8 LLFontGL::getStyleFromString(const std::string &style) { - LLWString wlabel = utf8str_to_wstring(label); - addEmbeddedChar(wc, image, wlabel); + S32 ret = 0; + if (style.find("NORMAL") != style.npos) + { + ret |= NORMAL; + } + if (style.find("BOLD") != style.npos) + { + ret |= BOLD; + } + if (style.find("ITALIC") != style.npos) + { + ret |= ITALIC; + } + if (style.find("UNDERLINE") != style.npos) + { + ret |= UNDERLINE; + } + return ret; } -void LLFontGL::addEmbeddedChar( llwchar wc, LLTexture* image, const LLWString& wlabel ) const +// static +std::string LLFontGL::nameFromFont(const LLFontGL* fontp) { - embedded_data_t* ext_data = new embedded_data_t(image->getGLTexture(), wlabel); - mEmbeddedChars[wc] = ext_data; + return fontp->mFontDescriptor.getName(); } -void LLFontGL::removeEmbeddedChar( llwchar wc ) const +// static +std::string LLFontGL::nameFromHAlign(LLFontGL::HAlign align) { - embedded_map_t::iterator iter = mEmbeddedChars.find(wc); + if (align == LEFT) return std::string("left"); + else if (align == RIGHT) return std::string("right"); + else if (align == HCENTER) return std::string("center"); + else return std::string(); +} + +// static +LLFontGL::HAlign LLFontGL::hAlignFromName(const std::string& name) +{ + LLFontGL::HAlign gl_hfont_align = LLFontGL::LEFT; + if (name == "left") + { + gl_hfont_align = LLFontGL::LEFT; + } + else if (name == "right") + { + gl_hfont_align = LLFontGL::RIGHT; + } + else if (name == "center") + { + gl_hfont_align = LLFontGL::HCENTER; + } + //else leave left + return gl_hfont_align; +} + +// static +std::string LLFontGL::nameFromVAlign(LLFontGL::VAlign align) +{ + if (align == TOP) return std::string("top"); + else if (align == VCENTER) return std::string("center"); + else if (align == BASELINE) return std::string("baseline"); + else if (align == BOTTOM) return std::string("bottom"); + else return std::string(); +} + +// static +LLFontGL::VAlign LLFontGL::vAlignFromName(const std::string& name) +{ + LLFontGL::VAlign gl_vfont_align = LLFontGL::BASELINE; + if (name == "top") + { + gl_vfont_align = LLFontGL::TOP; + } + else if (name == "center") + { + gl_vfont_align = LLFontGL::VCENTER; + } + else if (name == "baseline") + { + gl_vfont_align = LLFontGL::BASELINE; + } + else if (name == "bottom") + { + gl_vfont_align = LLFontGL::BOTTOM; + } + //else leave baseline + return gl_vfont_align; +} + +//static +LLFontGL* LLFontGL::getFontMonospace() +{ + return getFont(LLFontDescriptor("Monospace","Monospace",0)); +} + +//static +LLFontGL* LLFontGL::getFontSansSerifSmall() +{ + return getFont(LLFontDescriptor("SansSerif","Small",0)); +} + +//static +LLFontGL* LLFontGL::getFontSansSerif() +{ + return getFont(LLFontDescriptor("SansSerif","Medium",0)); +} + +//static +LLFontGL* LLFontGL::getFontSansSerifBig() +{ + return getFont(LLFontDescriptor("SansSerif","Large",0)); +} + +//static +LLFontGL* LLFontGL::getFontSansSerifHuge() +{ + return getFont(LLFontDescriptor("SansSerif","Huge",0)); +} + +//static +LLFontGL* LLFontGL::getFontSansSerifBold() +{ + return getFont(LLFontDescriptor("SansSerif","Medium",BOLD)); +} + +//static +LLFontGL* LLFontGL::getFontExtChar() +{ + return getFontSansSerif(); +} + +//static +LLFontGL* LLFontGL::getFont(const LLFontDescriptor& desc) +{ + return sFontRegistry->getFont(desc); +} + +//static +LLFontGL* LLFontGL::getFontByName(const std::string& name) +{ + // check for most common fonts first + if (name == "SANSSERIF") + { + return getFontSansSerif(); + } + else if (name == "SANSSERIF_SMALL") + { + return getFontSansSerifSmall(); + } + else if (name == "SANSSERIF_BIG") + { + return getFontSansSerifBig(); + } + else if (name == "SMALL" || name == "OCRA") + { + // *BUG: Should this be "MONOSPACE"? Do we use "OCRA" anymore? + // Does "SMALL" mean "SERIF"? + return getFontMonospace(); + } + else + { + return NULL; + } +} + +// static +std::string LLFontGL::getFontPathSystem() +{ + std::string system_path; + + // Try to figure out where the system's font files are stored. + char *system_root = NULL; +#if LL_WINDOWS + system_root = getenv("SystemRoot"); /* Flawfinder: ignore */ + if (!system_root) + { + llwarns << "SystemRoot not found, attempting to load fonts from default path." << llendl; + } +#endif + + if (system_root) + { + system_path = llformat("%s/fonts/", system_root); + } + else + { +#if LL_WINDOWS + // HACK for windows 98/Me + system_path = "/WINDOWS/FONTS/"; +#elif LL_DARWIN + // HACK for Mac OS X + system_path = "/System/Library/Fonts/"; +#endif + } + return system_path; +} + + +// static +std::string LLFontGL::getFontPathLocal() +{ + std::string local_path; + + // Backup files if we can't load from system fonts directory. + // We could store this in an end-user writable directory to allow + // end users to switch fonts. + if (LLFontGL::sAppDir.length()) + { + // use specified application dir to look for fonts + local_path = LLFontGL::sAppDir + "/fonts/"; + } + else + { + // assume working directory is executable directory + local_path = "./fonts/"; + } + return local_path; +} + +LLFontGL::LLFontGL(const LLFontGL &source) +{ + llerrs << "Not implemented!" << llendl; +} + +LLFontGL &LLFontGL::operator=(const LLFontGL &source) +{ + llerrs << "Not implemented" << llendl; + return *this; +} + +const LLFontGL::embedded_data_t* LLFontGL::getEmbeddedCharData(llwchar wch) const +{ + // Handle crappy embedded hack + embedded_map_t::const_iterator iter = mEmbeddedChars.find(wch); if (iter != mEmbeddedChars.end()) { - delete iter->second; - mEmbeddedChars.erase(wc); + return iter->second; } + return NULL; +} + +F32 LLFontGL::getEmbeddedCharAdvance(const embedded_data_t* ext_data) const +{ + const LLWString& label = ext_data->mLabel; + LLImageGL* ext_image = ext_data->mImage; + + F32 ext_width = (F32)ext_image->getWidth(); + if( !label.empty() ) + { + ext_width += (EXT_X_BEARING + getFontExtChar()->getWidthF32(label.c_str())) * sScaleX; + } + + return (EXT_X_BEARING * sScaleX) + ext_width; +} + +void LLFontGL::clearEmbeddedChars() +{ + for_each(mEmbeddedChars.begin(), mEmbeddedChars.end(), DeletePairedPointer()); + mEmbeddedChars.clear(); } @@ -1160,7 +1208,7 @@ void LLFontGL::renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F3 void LLFontGL::drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4& color, U8 style, ShadowType shadow, F32 drop_shadow_strength) const { F32 slant_offset; - slant_offset = ((style & ITALIC) ? ( -mAscender * 0.2f) : 0.f); + slant_offset = ((style & ITALIC) ? ( -mFontFreetype->getAscenderHeight() * 0.2f) : 0.f); gGL.begin(LLRender::QUADS); { @@ -1230,71 +1278,3 @@ void LLFontGL::drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, con } gGL.end(); } - -std::string LLFontGL::nameFromFont(const LLFontGL* fontp) -{ - return fontp->getFontDesc().getName(); -} - -// static -std::string LLFontGL::nameFromHAlign(LLFontGL::HAlign align) -{ - if (align == LEFT) return std::string("left"); - else if (align == RIGHT) return std::string("right"); - else if (align == HCENTER) return std::string("center"); - else return std::string(); -} - -// static -LLFontGL::HAlign LLFontGL::hAlignFromName(const std::string& name) -{ - LLFontGL::HAlign gl_hfont_align = LLFontGL::LEFT; - if (name == "left") - { - gl_hfont_align = LLFontGL::LEFT; - } - else if (name == "right") - { - gl_hfont_align = LLFontGL::RIGHT; - } - else if (name == "center") - { - gl_hfont_align = LLFontGL::HCENTER; - } - //else leave left - return gl_hfont_align; -} - -// static -std::string LLFontGL::nameFromVAlign(LLFontGL::VAlign align) -{ - if (align == TOP) return std::string("top"); - else if (align == VCENTER) return std::string("center"); - else if (align == BASELINE) return std::string("baseline"); - else if (align == BOTTOM) return std::string("bottom"); - else return std::string(); -} - -// static -LLFontGL::VAlign LLFontGL::vAlignFromName(const std::string& name) -{ - LLFontGL::VAlign gl_vfont_align = LLFontGL::BASELINE; - if (name == "top") - { - gl_vfont_align = LLFontGL::TOP; - } - else if (name == "center") - { - gl_vfont_align = LLFontGL::VCENTER; - } - else if (name == "baseline") - { - gl_vfont_align = LLFontGL::BASELINE; - } - else if (name == "bottom") - { - gl_vfont_align = LLFontGL::BOTTOM; - } - //else leave baseline - return gl_vfont_align; -} diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h index 2298db0ef3..42ed7a381f 100644 --- a/indra/llrender/llfontgl.h +++ b/indra/llrender/llfontgl.h @@ -35,21 +35,21 @@ #define LL_LLFONTGL_H #include "llcoord.h" -#include "llfont.h" #include "llfontregistry.h" +#include "llimagegl.h" #include "llpointer.h" #include "llrect.h" #include "v2math.h" class LLColor4; -class LLImageGL; // Key used to request a font. class LLFontDescriptor; +class LLFontFreetype; // Structure used to store previously requested fonts. class LLFontRegistry; -class LLFontGL : public LLFont +class LLFontGL { public: enum HAlign @@ -85,130 +85,72 @@ public: DROP_SHADOW, DROP_SHADOW_SOFT }; - - // Takes a string with potentially several flags, i.e. "NORMAL|BOLD|ITALIC" - static U8 getStyleFromString(const std::string &style); LLFontGL(); - LLFontGL(const LLFontGL &source); ~LLFontGL(); - void init(); // Internal init, or reinitialization - void reset(); // Reset a font after GL cleanup. ONLY works on an already loaded font. - LLFontGL &operator=(const LLFontGL &source); - - static void initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, - const std::string& app_dir, - const std::vector& xui_paths, - bool create_gl_textures = true); + void reset(); // Reset a font after GL cleanup. ONLY works on an already loaded font. - // Load sans-serif, sans-serif-small, etc. - // Slow, requires multiple seconds to load fonts. - static bool loadDefaultFonts(); - static void destroyDefaultFonts(); - static void destroyAllGL(); void destroyGL(); - /* virtual*/ BOOL loadFace(const std::string& filename, - const F32 point_size, const F32 vert_dpi, const F32 horz_dpi, - const S32 components, BOOL is_fallback); + BOOL loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, const S32 components, BOOL is_fallback); + S32 render(const LLWString &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign = LEFT, VAlign valign = BASELINE, U8 style = NORMAL, + ShadowType shadow = NO_SHADOW, S32 max_chars = S32_MAX, S32 max_pixels = S32_MAX, F32* right_x=NULL, BOOL use_embedded = FALSE, BOOL use_ellipses = FALSE) const; + S32 render(const LLWString &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color) const; - S32 renderUTF8(const std::string &text, const S32 begin_offset, - S32 x, S32 y, - const LLColor4 &color) const - { - return renderUTF8(text, begin_offset, (F32)x, (F32)y, color, - LEFT, BASELINE, NORMAL, NO_SHADOW, - S32_MAX, S32_MAX, NULL, FALSE); - } - - S32 renderUTF8(const std::string &text, const S32 begin_offset, - S32 x, S32 y, - const LLColor4 &color, - HAlign halign, VAlign valign, U8 style = NORMAL, ShadowType shadow = NO_SHADOW) const - { - return renderUTF8(text, begin_offset, (F32)x, (F32)y, color, - halign, valign, style, shadow, - S32_MAX, S32_MAX, NULL, FALSE); - } - // renderUTF8 does a conversion, so is slower! - S32 renderUTF8(const std::string &text, - S32 begin_offset, - F32 x, F32 y, - const LLColor4 &color, - HAlign halign, - VAlign valign, - U8 style, - ShadowType shadow, - S32 max_chars, - S32 max_pixels, - F32* right_x, - BOOL use_ellipses) const; - - S32 render(const LLWString &text, const S32 begin_offset, - F32 x, F32 y, - const LLColor4 &color) const - { - return render(text, begin_offset, x, y, color, - LEFT, BASELINE, NORMAL, NO_SHADOW, - S32_MAX, S32_MAX, NULL, FALSE, FALSE); - } - + S32 renderUTF8(const std::string &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, BOOL use_ellipses) const; + S32 renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color) const; + S32 renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style = NORMAL, ShadowType shadow = NO_SHADOW) const; - S32 render(const LLWString &text, - S32 begin_offset, - F32 x, F32 y, - const LLColor4 &color, - HAlign halign = LEFT, - VAlign valign = BASELINE, - U8 style = NORMAL, - ShadowType shadow = NO_SHADOW, - S32 max_chars = S32_MAX, - S32 max_pixels = S32_MAX, - F32* right_x=NULL, - BOOL use_embedded = FALSE, - BOOL use_ellipses = FALSE) const; - - // font metrics - override for LLFont that returns units of virtual pixels - /*virtual*/ F32 getLineHeight() const { return (F32)llround(mLineHeight / sScaleY); } - /*virtual*/ F32 getAscenderHeight() const { return (F32)llround(mAscender / sScaleY); } - /*virtual*/ F32 getDescenderHeight() const { return (F32)llround(mDescender / sScaleY); } - - virtual S32 getWidth(const std::string& utf8text) const; - virtual S32 getWidth(const llwchar* wchars) const; - virtual S32 getWidth(const std::string& utf8text, const S32 offset, const S32 max_chars ) const; - virtual S32 getWidth(const llwchar* wchars, const S32 offset, const S32 max_chars, BOOL use_embedded = FALSE) const; + // font metrics - override for LLFontFreetype that returns units of virtual pixels + F32 getLineHeight() const; + F32 getAscenderHeight() const; + F32 getDescenderHeight() const; - virtual F32 getWidthF32(const std::string& utf8text) const; - virtual F32 getWidthF32(const llwchar* wchars) const; - virtual F32 getWidthF32(const std::string& text, const S32 offset, const S32 max_chars ) const; - virtual F32 getWidthF32(const llwchar* wchars, const S32 offset, const S32 max_chars, BOOL use_embedded = FALSE ) const; + S32 getWidth(const std::string& utf8text) const; + S32 getWidth(const llwchar* wchars) const; + S32 getWidth(const std::string& utf8text, S32 offset, S32 max_chars ) const; + S32 getWidth(const llwchar* wchars, S32 offset, S32 max_chars, BOOL use_embedded = FALSE) const; + + F32 getWidthF32(const std::string& utf8text) const; + F32 getWidthF32(const llwchar* wchars) const; + F32 getWidthF32(const std::string& text, S32 offset, S32 max_chars ) const; + F32 getWidthF32(const llwchar* wchars, S32 offset, S32 max_chars, BOOL use_embedded = FALSE ) const; // The following are called often, frequently with large buffers, so do not use a string interface // Returns the max number of complete characters from text (up to max_chars) that can be drawn in max_pixels - virtual S32 maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars = S32_MAX, - BOOL end_on_word_boundary = FALSE, const BOOL use_embedded = FALSE, - F32* drawn_pixels = NULL) const; + S32 maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars = S32_MAX, BOOL end_on_word_boundary = FALSE, BOOL use_embedded = FALSE, F32* drawn_pixels = NULL) const; // Returns the index of the first complete characters from text that can be drawn in max_pixels // given that the character at start_pos should be the last character (or as close to last as possible). - virtual S32 firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_len, S32 start_pos=S32_MAX, S32 max_chars = S32_MAX) const; + S32 firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_len, S32 start_pos=S32_MAX, S32 max_chars = S32_MAX) const; // Returns the index of the character closest to pixel position x (ignoring text to the right of max_pixels and max_chars) - virtual S32 charFromPixelOffset(const llwchar* wchars, const S32 char_offset, - F32 x, F32 max_pixels=F32_MAX, S32 max_chars = S32_MAX, - BOOL round = TRUE, BOOL use_embedded = FALSE) const; + S32 charFromPixelOffset(const llwchar* wchars, S32 char_offset, F32 x, F32 max_pixels=F32_MAX, S32 max_chars = S32_MAX, BOOL round = TRUE, BOOL use_embedded = FALSE) const; + + void addEmbeddedChar( llwchar wc, LLTexture* image, const std::string& label) const; + void addEmbeddedChar( llwchar wc, LLTexture* image, const LLWString& label) const; + void removeEmbeddedChar( llwchar wc ) const; + BOOL addChar(const llwchar wch) const; - LLImageGL *getImageGL() const; + const LLFontDescriptor& getFontDesc() const; - void addEmbeddedChar( llwchar wc, LLTexture* image, const std::string& label) const; - void addEmbeddedChar( llwchar wc, LLTexture* image, const LLWString& label) const; - void removeEmbeddedChar( llwchar wc ) const; + + static void initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, const std::vector& xui_paths, bool create_gl_textures = true); + + // Load sans-serif, sans-serif-small, etc. + // Slow, requires multiple seconds to load fonts. + static bool loadDefaultFonts(); + static void destroyDefaultFonts(); + static void destroyAllGL(); + + // Takes a string with potentially several flags, i.e. "NORMAL|BOLD|ITALIC" + static U8 getStyleFromString(const std::string &style); static std::string nameFromFont(const LLFontGL* fontp); @@ -218,28 +160,7 @@ public: static std::string nameFromVAlign(LLFontGL::VAlign align); static LLFontGL::VAlign vAlignFromName(const std::string& name); - static void setFontDisplay(BOOL flag) { sDisplayFont = flag ; } - -protected: - struct embedded_data_t - { - embedded_data_t(LLImageGL* image, const LLWString& label) : mImage(image), mLabel(label) {} - LLPointer mImage; - LLWString mLabel; - }; - const embedded_data_t* getEmbeddedCharData(const llwchar wch) const; - F32 getEmbeddedCharAdvance(const embedded_data_t* ext_data) const; - void clearEmbeddedChars(); - void renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F32 slant_amt) const; - void drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4& color, U8 style, ShadowType shadow, F32 drop_shadow_fade) const; - -public: - static F32 sVertDPI; - static F32 sHorizDPI; - static F32 sScaleX; - static F32 sScaleY; - static BOOL sDisplayFont ; - static std::string sAppDir; // For loading fonts + static void setFontDisplay(BOOL flag) { sDisplayFont = flag; } static LLFontGL* getFontMonospace(); static LLFontGL* getFontSansSerifSmall(); @@ -252,32 +173,50 @@ public: // Use with legacy names like "SANSSERIF_SMALL" or "OCRA" static LLFontGL* getFontByName(const std::string& name); + static std::string getFontPathLocal(); + static std::string getFontPathSystem(); + + static LLCoordFont sCurOrigin; + static std::vector sOriginStack; + static LLColor4 sShadowColor; + static F32 sVertDPI; + static F32 sHorizDPI; + static F32 sScaleX; + static F32 sScaleY; + static BOOL sDisplayFont ; + static std::string sAppDir; // For loading fonts + +private: + friend class LLFontRegistry; friend class LLTextBillboard; friend class LLHUDText; -protected: - /*virtual*/ BOOL addChar(const llwchar wch) const; + LLFontGL(const LLFontGL &source); + LLFontGL &operator=(const LLFontGL &source); -protected: - typedef std::map embedded_map_t; - mutable embedded_map_t mEmbeddedChars; - LLFontDescriptor mFontDescriptor; + LLPointer mFontFreetype; - // Registry holds all instantiated fonts. - static LLFontRegistry* sFontRegistry; + struct embedded_data_t + { + embedded_data_t(LLImageGL* image, const LLWString& label) : mImage(image), mLabel(label) {} + LLPointer mImage; + LLWString mLabel; + }; -public: - static std::string getFontPathLocal(); - static std::string getFontPathSystem(); + typedef std::map embedded_map_t; + mutable embedded_map_t mEmbeddedChars; - static LLCoordFont sCurOrigin; - static std::vector sOriginStack; + const embedded_data_t* getEmbeddedCharData(llwchar wch) const; + F32 getEmbeddedCharAdvance(const embedded_data_t* ext_data) const; + void clearEmbeddedChars(); + void renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F32 slant_amt) const; + void drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4& color, U8 style, ShadowType shadow, F32 drop_shadow_fade) const; - const LLFontDescriptor &getFontDesc() const { return mFontDescriptor; } - void setFontDesc(const LLFontDescriptor& font_desc) { mFontDescriptor = font_desc; } + // Registry holds all instantiated fonts. + static LLFontRegistry* sFontRegistry; }; #endif diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp index 3b5c62a5ea..553e7b8f9d 100644 --- a/indra/llrender/llfontregistry.cpp +++ b/indra/llrender/llfontregistry.cpp @@ -33,8 +33,9 @@ #include "linden_common.h" #include "llgl.h" -#include "llfontregistry.h" +#include "llfontfreetype.h" #include "llfontgl.h" +#include "llfontregistry.h" #include #include "llcontrol.h" #include "lldir.h" @@ -382,7 +383,14 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc) if (it != mFontMap.end()) { llinfos << "-- matching font exists: " << nearest_exact_desc.getName() << " size " << nearest_exact_desc.getSize() << " style " << ((S32) nearest_exact_desc.getStyle()) << llendl; - return it->second; + + // copying underlying Freetype font, and storing in LLFontGL with requested font descriptor + LLFontGL *font = new LLFontGL; + font->mFontDescriptor = desc; + font->mFontFreetype = it->second->mFontFreetype; + mFontMap[desc] = font; + + return font; } // Build list of font names to look for. @@ -410,10 +418,11 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc) llwarns << "createFont failed, no file names specified" << llendl; return NULL; } - LLFontList *fontlistp = new LLFontList; + + LLFontFreetype::font_vector_t fontlist; LLFontGL *result = NULL; - // Snarf all fonts we can into fontlistp. First will get pulled + // Snarf all fonts we can into fontlist. First will get pulled // off the list and become the "head" font, set to non-fallback. // Rest will consitute the fallback list. BOOL is_first_found = TRUE; @@ -455,23 +464,28 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc) is_first_found = false; } else - fontlistp->addAtEnd(fontp); + { + fontlist.push_back(fontp->mFontFreetype); + } } } - if (result && !fontlistp->empty()) + + if (result && !fontlist.empty()) { - result->setFallbackFont(fontlistp); + result->mFontFreetype->setFallbackFonts(fontlist); } - norm_desc.setStyle(match_desc->getStyle()); if (result) - result->setFontDesc(norm_desc); - - if (!result) + { + result->mFontFreetype->setStyle(match_desc->getStyle()); + result->mFontDescriptor = desc; + } + else { llwarns << "createFont failed in some way" << llendl; } - mFontMap[norm_desc] = result; + + mFontMap[desc] = result; return result; } @@ -511,21 +525,19 @@ void LLFontRegistry::destroyGL() } } -LLFontGL *LLFontRegistry::getFont(const LLFontDescriptor& orig_desc) +LLFontGL *LLFontRegistry::getFont(const LLFontDescriptor& desc) { - LLFontDescriptor norm_desc = orig_desc.normalize(); - - font_reg_map_t::iterator it = mFontMap.find(norm_desc); + font_reg_map_t::iterator it = mFontMap.find(desc); if (it != mFontMap.end()) return it->second; else { - LLFontGL *fontp = createFont(orig_desc); + LLFontGL *fontp = createFont(desc); if (!fontp) { - llwarns << "getFont failed, name " << orig_desc.getName() - <<" style=[" << ((S32) orig_desc.getStyle()) << "]" - << " size=[" << orig_desc.getSize() << "]" << llendl; + llwarns << "getFont failed, name " << desc.getName() + <<" style=[" << ((S32) desc.getStyle()) << "]" + << " size=[" << desc.getSize() << "]" << llendl; } return fontp; } @@ -653,3 +665,8 @@ void LLFontRegistry::dump() } } } + +const string_vec_t& LLFontRegistry::getUltimateFallbackList() const +{ + return mUltimateFallbackList; +} diff --git a/indra/llrender/llfontregistry.h b/indra/llrender/llfontregistry.h index 198ca0b920..4da4ca48bb 100644 --- a/indra/llrender/llfontregistry.h +++ b/indra/llrender/llfontregistry.h @@ -98,7 +98,7 @@ public: void dump(); - const string_vec_t& getUltimateFallbackList() const { return mUltimateFallbackList; } + const string_vec_t& getUltimateFallbackList() const; private: LLFontGL *createFont(const LLFontDescriptor& desc); diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index e62d875a01..edd3fe2beb 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -37,6 +37,7 @@ set(llui_SOURCE_FILES lldraghandle.cpp lleditmenuhandler.cpp llf32uictrl.cpp + llfiltereditor.cpp llfloater.cpp llfloaterreg.cpp llflyoutbutton.cpp @@ -59,6 +60,7 @@ set(llui_SOURCE_FILES llresizebar.cpp llresizehandle.cpp llresmgr.cpp + llrngwriter.cpp llscrollbar.cpp llscrollcontainer.cpp llscrollingpanellist.cpp @@ -67,7 +69,7 @@ set(llui_SOURCE_FILES llscrolllistctrl.cpp llscrolllistitem.cpp llsdparam.cpp - llsearcheditor.cpp + llsearcheditor.cpp llslider.cpp llsliderctrl.cpp llspinctrl.cpp @@ -109,11 +111,13 @@ set(llui_HEADER_FILES lldraghandle.h lleditmenuhandler.h llf32uictrl.h + llfiltereditor.h llfloater.h llfloaterreg.h llflyoutbutton.h llfocusmgr.h llfunctorregistry.h + llhandle.h llhtmlhelp.h lliconctrl.h llinitparam.h @@ -134,6 +138,7 @@ set(llui_HEADER_FILES llresizebar.h llresizehandle.h llresmgr.h + llrngwriter.h llsearcheditor.h llscrollbar.h llscrollcontainer.h diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index 9ad27e7c41..fc3af34951 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -62,7 +62,7 @@ S32 BTN_HEIGHT = 0; LLButton::Params::Params() : label_selected("label_selected"), // requires is_toggle true - label_dropshadow("label_shadow", true), + label_shadow("label_shadow", true), auto_resize("auto_resize", false), image_unselected("image_unselected"), image_selected("image_selected"), @@ -133,7 +133,7 @@ LLButton::LLButton(const LLButton::Params& p) mImageOverlayAlignment(LLFontGL::hAlignFromName(p.image_overlay_alignment)), mIsToggle(p.is_toggle), mScaleImage(p.scale_image), - mDropShadowedText(p.label_dropshadow), + mDropShadowedText(p.label_shadow), mAutoResize(p.auto_resize), mHAlign(p.font_halign), mLeftHPad(p.pad_left), diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index 3fa62cc351..e387c91a17 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -74,7 +74,7 @@ public: { // text label Optional label_selected; - Optional label_dropshadow; + Optional label_shadow; Optional auto_resize; // images @@ -105,9 +105,9 @@ public: // callbacks Optional click_callback, // alias -> commit_callback - mouse_down_callback, - mouse_up_callback, - mouse_held_callback; + mouse_down_callback, + mouse_up_callback, + mouse_held_callback; // misc Optional is_toggle, diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index 5caad1919a..51f9d6bd18 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -141,7 +141,7 @@ LLComboBox::LLComboBox(const LLComboBox::Params& p) LLScrollListItem::Params item_params = *it; if (it->label.isProvided()) { - item_params.cells.add().value(it->label()); + item_params.columns.add().value(it->label()); } mList->addRow(item_params); diff --git a/indra/llui/llconsole.h b/indra/llui/llconsole.h index 65149b217f..56e1614948 100644 --- a/indra/llui/llconsole.h +++ b/indra/llui/llconsole.h @@ -58,7 +58,8 @@ public: Optional font_size_index; Params() : max_lines("max_lines", LLUI::sSettingGroups["config"]->getS32("ConsoleMaxLines")), - persist_time("persist_time", 0.f) // forever + persist_time("persist_time", 0.f), // forever + font_size_index("font_size_index") { mouse_opaque(false); } diff --git a/indra/llui/lldraghandle.cpp b/indra/llui/lldraghandle.cpp index 8ecbdb98e1..6e8e37ded3 100644 --- a/indra/llui/lldraghandle.cpp +++ b/indra/llui/lldraghandle.cpp @@ -317,6 +317,23 @@ BOOL LLDragHandle::handleHover(S32 x, S32 y, MASK mask) S32 delta_x = screen_x - mDragLastScreenX; S32 delta_y = screen_y - mDragLastScreenY; + // if dragging a docked floater we want to undock + if (((LLFloater*)getParent())->isDocked()) + { + const S32 SLOP = 12; + + if (delta_y <= -SLOP || + delta_y >= SLOP) + { + ((LLFloater*)getParent())->setDocked(false, false); + return TRUE; + } + else + { + return FALSE; + } + } + LLRect original_rect = getParent()->getRect(); LLRect translated_rect = getParent()->getRect(); translated_rect.translate(delta_x, delta_y); diff --git a/indra/llui/lldraghandle.h b/indra/llui/lldraghandle.h index 86eef7c42c..88ec1d21f8 100644 --- a/indra/llui/lldraghandle.h +++ b/indra/llui/lldraghandle.h @@ -53,7 +53,8 @@ public: Optional drag_shadow_color; Params() - : drag_highlight_color("drag_highlight_color", LLUIColorTable::instance().getColor("DefaultHighlightLight")), + : label("label"), + drag_highlight_color("drag_highlight_color", LLUIColorTable::instance().getColor("DefaultHighlightLight")), drag_shadow_color("drag_shadow_color", LLUIColorTable::instance().getColor("DefaultShadowDark")) { mouse_opaque(true); diff --git a/indra/llui/llfiltereditor.cpp b/indra/llui/llfiltereditor.cpp new file mode 100644 index 0000000000..0f36483fc2 --- /dev/null +++ b/indra/llui/llfiltereditor.cpp @@ -0,0 +1,110 @@ +/** + * @file llfiltereditor.cpp + * @brief LLFilterEditor implementation + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, 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$ + */ + +// Text editor widget to let users enter a single line. + +#include "linden_common.h" + +#include "llfiltereditor.h" + +LLFilterEditor::LLFilterEditor(const LLFilterEditor::Params& p) +: LLUICtrl(p) +{ + LLLineEditor::Params line_editor_p(p); + line_editor_p.name("filter edit box"); + line_editor_p.rect(getLocalRect()); + line_editor_p.follows.flags(FOLLOWS_ALL); + line_editor_p.text_pad_right(getRect().getHeight()); + line_editor_p.keystroke_callback(boost::bind(&LLUICtrl::onCommit, this)); + + mFilterEditor = LLUICtrlFactory::create(line_editor_p); + addChild(mFilterEditor); + + S32 btn_width = getRect().getHeight(); // button is square, and as tall as search editor + LLRect clear_btn_rect(getRect().getWidth() - btn_width, getRect().getHeight(), getRect().getWidth(), 0); + LLButton::Params button_params(p.clear_filter_button); + button_params.name(std::string("clear filter")); + button_params.rect(clear_btn_rect) ; + button_params.follows.flags(FOLLOWS_RIGHT|FOLLOWS_TOP); + button_params.tab_stop(false); + button_params.click_callback.function(boost::bind(&LLFilterEditor::onClearFilter, this, _2)); + + mClearFilterButton = LLUICtrlFactory::create(button_params); + mFilterEditor->addChild(mClearFilterButton); +} + +//virtual +void LLFilterEditor::setValue(const LLSD& value ) +{ + mFilterEditor->setValue(value); +} + +//virtual +LLSD LLFilterEditor::getValue() const +{ + return mFilterEditor->getValue(); +} + +//virtual +BOOL LLFilterEditor::setTextArg( const std::string& key, const LLStringExplicit& text ) +{ + return mFilterEditor->setTextArg(key, text); +} + +//virtual +BOOL LLFilterEditor::setLabelArg( const std::string& key, const LLStringExplicit& text ) +{ + return mFilterEditor->setLabelArg(key, text); +} + +//virtual +void LLFilterEditor::clear() +{ + if (mFilterEditor) + { + mFilterEditor->clear(); + } +} + +void LLFilterEditor::draw() +{ + mClearFilterButton->setVisible(!mFilterEditor->getWText().empty()); + + LLUICtrl::draw(); +} + +void LLFilterEditor::onClearFilter(const LLSD& data) +{ + setText(LLStringUtil::null); + onCommit(); +} + diff --git a/indra/llui/llfiltereditor.h b/indra/llui/llfiltereditor.h new file mode 100644 index 0000000000..4240fd770c --- /dev/null +++ b/indra/llui/llfiltereditor.h @@ -0,0 +1,86 @@ +/** + * @file llfiltereditor.h + * @brief Text editor widget that represents a filter operation + * + * Features: + * Text entry of a single line (text, delete, left and right arrow, insert, return). + * Callbacks either on every keystroke or just on the return key. + * Focus (allow multiple text entry widgets) + * Clipboard (cut, copy, and paste) + * Horizontal scrolling to allow strings longer than widget size allows + * Pre-validation (limit which keys can be used) + * Optional line history so previous entries can be recalled by CTRL UP/DOWN + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, 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$ + */ + +#ifndef LL_FILTEREDITOR_H +#define LL_FILTEREDITOR_H + +#include "lllineeditor.h" +#include "llbutton.h" + +class LLFilterEditor : public LLUICtrl +{ +public: + struct Params : public LLInitParam::Block + { + Optional clear_filter_button; + + Params() + : clear_filter_button("clear_filter_button") + { + name = "filter_editor"; + } + }; + +protected: + LLFilterEditor(const Params&); + friend class LLUICtrlFactory; +public: + virtual ~LLFilterEditor() {} + + /*virtual*/ void draw(); + + void setText(const LLStringExplicit &new_text) { mFilterEditor->setText(new_text); } + + // LLUICtrl interface + virtual void setValue(const LLSD& value ); + virtual LLSD getValue() const; + virtual BOOL setTextArg( const std::string& key, const LLStringExplicit& text ); + virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text ); + virtual void clear(); + +private: + void onClearFilter(const LLSD& data); + + LLLineEditor* mFilterEditor; + LLButton* mClearFilterButton; +}; + +#endif // LL_FILTEREDITOR_H diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 153e025385..a397278a2b 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -71,15 +71,8 @@ std::string LLFloater::sButtonActiveImageNames[BUTTON_COUNT] = "minimize.tga", //BUTTON_MINIMIZE "tearoffbox.tga", //BUTTON_TEAR_OFF "closebox.tga", //BUTTON_EDIT -}; - -std::string LLFloater::sButtonInactiveImageNames[BUTTON_COUNT] = -{ - "close_inactive_blue.tga", //BUTTON_CLOSE - "restore_inactive.tga", //BUTTON_RESTORE - "minimize_inactive.tga", //BUTTON_MINIMIZE - "tearoffbox.tga", //BUTTON_TEAR_OFF - "close_inactive_blue.tga", //BUTTON_EDIT + "Icon_Dock_Foreground", + "Icon_Undock_Foreground" }; std::string LLFloater::sButtonPressedImageNames[BUTTON_COUNT] = @@ -89,6 +82,8 @@ std::string LLFloater::sButtonPressedImageNames[BUTTON_COUNT] = "minimize_pressed.tga", //BUTTON_MINIMIZE "tearoff_pressed.tga", //BUTTON_TEAR_OFF "close_in_blue.tga", //BUTTON_EDIT + "Icon_Dock_Press", + "Icon_Undock_Press" }; std::string LLFloater::sButtonNames[BUTTON_COUNT] = @@ -98,6 +93,8 @@ std::string LLFloater::sButtonNames[BUTTON_COUNT] = "llfloater_minimize_btn", //BUTTON_MINIMIZE "llfloater_tear_off_btn", //BUTTON_TEAR_OFF "llfloater_edit_btn", //BUTTON_EDIT + "llfloater_dock_btn", + "llfloater_undock_btn" }; std::string LLFloater::sButtonToolTips[BUTTON_COUNT] = {}; @@ -114,6 +111,8 @@ std::string LLFloater::sButtonToolTipsIndex[BUTTON_COUNT]= "BUTTON_MINIMIZE",//LLTrans::getString("BUTTON_MINIMIZE"), //"Minimize", //BUTTON_MINIMIZE "BUTTON_TEAR_OFF",//LLTrans::getString("BUTTON_TEAR_OFF"), //"Tear Off", //BUTTON_TEAR_OFF "BUTTON_EDIT", //LLTrans::getString("BUTTON_EDIT"), // "Edit", //BUTTON_EDIT + "BUTTON_DOCK", + "BUTTON_UNDOCK" }; LLFloater::click_callback LLFloater::sButtonCallbacks[BUTTON_COUNT] = @@ -123,6 +122,8 @@ LLFloater::click_callback LLFloater::sButtonCallbacks[BUTTON_COUNT] = LLFloater::onClickMinimize, //BUTTON_MINIMIZE LLFloater::onClickTearOff, //BUTTON_TEAR_OFF LLFloater::onClickEdit, //BUTTON_EDIT + LLFloater::onClickDock, + LLFloater::onClickDock }; LLMultiFloater* LLFloater::sHostp = NULL; @@ -189,6 +190,29 @@ bool LLFloater::KeyCompare::equate(const LLSD& a, const LLSD& b) //************************************ +LLFloater::Params::Params() +: title("title"), + short_title("short_title"), + single_instance("single_instance", false), + auto_tile("auto_tile", false), + can_resize("can_resize", false), + can_minimize("can_minimize", true), + can_close("can_close", true), + can_drag_on_left("can_drag_on_left", false), + can_tear_off("can_tear_off", true), + save_rect("save_rect", false), + save_visibility("save_visibility", false), + open_callback("open_callback"), + close_callback("close_callback"), + can_dock("can_dock", false) +{ + name = "floater"; + // defaults that differ from LLPanel: + background_visible = true; + visible = false; +} + + //static const LLFloater::Params& LLFloater::getDefaultParams() { @@ -217,6 +241,8 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p) mEditing(FALSE), mButtonScale(1.0f), mAutoFocus(TRUE), // automatically take focus when opened + mCanDock(false), + mDocked(false), mHasBeenDraggedWhileMinimized(FALSE), mPreviousMinimizedBottom(0), mPreviousMinimizedLeft(0), @@ -289,6 +315,11 @@ void LLFloater::initFloater() mButtonsEnabled[BUTTON_MINIMIZE] = TRUE; } + if(mCanDock) + { + mButtonsEnabled[BUTTON_DOCK] = TRUE; + } + buildButtons(); // Floaters are created in the invisible state @@ -1305,6 +1336,36 @@ void LLFloater::setFrontmost(BOOL take_focus) } } +void LLFloater::setCanDock(bool b) +{ + if(b != mCanDock) + { + mCanDock = b; + if(mCanDock) + { + mButtonsEnabled[BUTTON_DOCK] = !mDocked; + mButtonsEnabled[BUTTON_UNDOCK] = mDocked; + } + else + { + mButtonsEnabled[BUTTON_DOCK] = FALSE; + mButtonsEnabled[BUTTON_UNDOCK] = FALSE; + } + } + updateButtons(); +} + +void LLFloater::setDocked(bool docked, bool pop_on_undock) +{ + if(docked != mDocked && mCanDock) + { + mDocked = docked; + mButtonsEnabled[BUTTON_DOCK] = !mDocked; + mButtonsEnabled[BUTTON_UNDOCK] = mDocked; + updateButtons(); + } +} + //static void LLFloater::setEditModeEnabled(BOOL enable) { @@ -1381,6 +1442,15 @@ void LLFloater::onClickEdit(LLFloater* self) self->mEditing = self->mEditing ? FALSE : TRUE; } +// static +void LLFloater::onClickDock(LLFloater* self) +{ + if(self && self->mCanDock) + { + self->setDocked(!self->mDocked, true); + } +} + // static LLFloater* LLFloater::getClosableFloaterFromFocus() { @@ -2522,6 +2592,7 @@ void LLFloater::initFromParams(const LLFloater::Params& p) setCanTearOff(p.can_tear_off); setCanMinimize(p.can_minimize); setCanClose(p.can_close); + setCanDock(p.can_dock); mDragOnLeft = p.can_drag_on_left; mResizable = p.can_resize; diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index b1d33f48e9..f6c6dcf277 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -102,6 +102,8 @@ public: BUTTON_MINIMIZE, BUTTON_TEAR_OFF, BUTTON_EDIT, + BUTTON_DOCK, + BUTTON_UNDOCK, BUTTON_COUNT }; @@ -120,7 +122,7 @@ public: { Optional function; }; - + struct Params : public LLInitParam::Block { @@ -135,31 +137,13 @@ public: can_drag_on_left, can_tear_off, save_rect, - save_visibility; + save_visibility, + can_dock; Optional open_callback; Optional close_callback; - Params() : - title("title"), - short_title("short_title"), - single_instance("single_instance", false), - auto_tile("auto_tile", false), - can_resize("can_resize", false), - can_minimize("can_minimize", true), - can_close("can_close", true), - can_drag_on_left("can_drag_on_left", false), - can_tear_off("can_tear_off", true), - save_rect("save_rect", false), - save_visibility("save_visibility", false), - open_callback("open_callback"), - close_callback("close_callback") - { - name = "floater"; - // defaults that differ from LLPanel: - background_visible = true; - visible = false; - } + Params(); }; // use this to avoid creating your own default LLFloater::Param instance @@ -267,6 +251,12 @@ public: const LLSD& getKey() { return mKey; } BOOL matchesKey(const LLSD& key) { return mSingleInstance || KeyCompare::equate(key, mKey); } + bool isDockable() const { return mCanDock; } + void setCanDock(bool b); + + bool isDocked() const { return mDocked; } + virtual void setDocked(bool docked, bool pop_on_undock = true); + // Return a closeable floater, if any, given the current focus. static LLFloater* getClosableFloaterFromFocus(); @@ -283,6 +273,7 @@ public: static void onClickMinimize(LLFloater* floater); static void onClickTearOff(LLFloater* floater); static void onClickEdit(LLFloater* floater); + static void onClickDock(LLFloater* floater); static void setFloaterHost(LLMultiFloater* hostp) {sHostp = hostp; } static void setEditModeEnabled(BOOL enable); @@ -378,11 +369,13 @@ private: LLHandle mHostHandle; LLHandle mLastHostHandle; + bool mCanDock; + bool mDocked; + static LLMultiFloater* sHostp; static BOOL sEditModeEnabled; static BOOL sQuitting; static std::string sButtonActiveImageNames[BUTTON_COUNT]; - static std::string sButtonInactiveImageNames[BUTTON_COUNT]; static std::string sButtonPressedImageNames[BUTTON_COUNT]; static std::string sButtonNames[BUTTON_COUNT]; static std::string sButtonToolTips[BUTTON_COUNT]; diff --git a/indra/llui/llhandle.h b/indra/llui/llhandle.h new file mode 100644 index 0000000000..10a7fd4544 --- /dev/null +++ b/indra/llui/llhandle.h @@ -0,0 +1,171 @@ +/** +* @file llhandle.h +* @brief "Handle" to an object (usually a floater) whose lifetime you don't +* control. +* +* $LicenseInfo:firstyear=2001&license=viewergpl$ +* +* Copyright (c) 2001-2009, 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$ +*/ +#ifndef LLHANDLE_H +#define LLHANDLE_H + +#include "llpointer.h" + +template +class LLTombStone : public LLRefCount +{ +public: + LLTombStone(T* target = NULL) : mTarget(target) {} + + void setTarget(T* target) { mTarget = target; } + T* getTarget() const { return mTarget; } +private: + T* mTarget; +}; + +// LLHandles are used to refer to objects whose lifetime you do not control or influence. +// Calling get() on a handle will return a pointer to the referenced object or NULL, +// if the object no longer exists. Note that during the lifetime of the returned pointer, +// you are assuming that the object will not be deleted by any action you perform, +// or any other thread, as normal when using pointers, so avoid using that pointer outside of +// the local code block. +// +// https://wiki.lindenlab.com/mediawiki/index.php?title=LLHandle&oldid=79669 + +template +class LLHandle +{ +public: + LLHandle() : mTombStone(sDefaultTombStone) {} + const LLHandle& operator =(const LLHandle& other) + { + mTombStone = other.mTombStone; + return *this; + } + + bool isDead() const + { + return mTombStone->getTarget() == NULL; + } + + void markDead() + { + mTombStone = sDefaultTombStone; + } + + T* get() const + { + return mTombStone->getTarget(); + } + + friend bool operator== (const LLHandle& lhs, const LLHandle& rhs) + { + return lhs.mTombStone == rhs.mTombStone; + } + friend bool operator!= (const LLHandle& lhs, const LLHandle& rhs) + { + return !(lhs == rhs); + } + friend bool operator< (const LLHandle& lhs, const LLHandle& rhs) + { + return lhs.mTombStone < rhs.mTombStone; + } + friend bool operator> (const LLHandle& lhs, const LLHandle& rhs) + { + return lhs.mTombStone > rhs.mTombStone; + } +protected: + +protected: + LLPointer > mTombStone; + +private: + static LLPointer > sDefaultTombStone; +}; + +// initialize static "empty" tombstone pointer +template LLPointer > LLHandle::sDefaultTombStone = new LLTombStone(); + + +template +class LLRootHandle : public LLHandle +{ +public: + LLRootHandle(T* object) { bind(object); } + LLRootHandle() {}; + ~LLRootHandle() { unbind(); } + + // this is redundant, since a LLRootHandle *is* an LLHandle + LLHandle getHandle() { return LLHandle(*this); } + + void bind(T* object) + { + // unbind existing tombstone + if (LLHandle::mTombStone.notNull()) + { + if (LLHandle::mTombStone->getTarget() == object) return; + LLHandle::mTombStone->setTarget(NULL); + } + // tombstone reference counted, so no paired delete + LLHandle::mTombStone = new LLTombStone(object); + } + + void unbind() + { + LLHandle::mTombStone->setTarget(NULL); + } + + //don't allow copying of root handles, since there should only be one +private: + LLRootHandle(const LLRootHandle& other) {}; +}; + +// Use this as a mixin for simple classes that need handles and when you don't +// want handles at multiple points of the inheritance hierarchy +template +class LLHandleProvider +{ +protected: + typedef LLHandle handle_type_t; + LLHandleProvider() + { + // provided here to enforce T deriving from LLHandleProvider + } + + LLHandle getHandle() + { + // perform lazy binding to avoid small tombstone allocations for handle + // providers whose handles are never referenced + mHandle.bind(static_cast(this)); + return mHandle; + } + +private: + LLRootHandle mHandle; +}; + +#endif diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index f1e7d791d4..702d8e4a39 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -120,7 +120,8 @@ struct LLLayoutStack::LayoutPanel LLLayoutStack::Params::Params() : orientation("orientation", std::string("vertical")), - animate("animate", TRUE), + animate("animate", true), + clip("clip", true), border_size("border_size", LLCachedControl(*LLUI::sSettingGroups["config"], "UIResizeBarHeight", 0)) { name="stack"; @@ -132,7 +133,8 @@ LLLayoutStack::LLLayoutStack(const LLLayoutStack::Params& p) mMinHeight(0), mPanelSpacing(p.border_size), mOrientation((p.orientation() == "vertical") ? VERTICAL : HORIZONTAL), - mAnimate(p.animate) + mAnimate(p.animate), + mClip(p.clip) {} LLLayoutStack::~LLLayoutStack() @@ -163,7 +165,7 @@ void LLLayoutStack::draw() LLPanel* panelp = (*panel_it)->mPanel; - LLLocalClipRect clip(clip_rect); + LLLocalClipRect clip(clip_rect, mClip); // only force drawing invisible children if visible amount is non-zero drawChild(panelp, 0, 0, !clip_rect.isNull()); } diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h index 480bdb5c17..9459b9990c 100644 --- a/indra/llui/lllayoutstack.h +++ b/indra/llui/lllayoutstack.h @@ -43,7 +43,8 @@ public: { Optional orientation; Optional border_size; - Optional animate; + Optional animate; + Optional clip; // mMinWidth and mMinHeight are calculated, not set in XML Params(); @@ -100,6 +101,7 @@ private: S32 mPanelSpacing; bool mAnimate; + bool mClip; }; // end class LLLayoutStack #endif diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 43c22cbf5d..f94eb7fcc3 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -91,7 +91,11 @@ void LLLineEditor::PrevalidateNamedFuncs::declareValues() LLLineEditor::Params::Params() : max_length_bytes("max_length", 254), + keystroke_callback("keystroke_callback"), + prevalidate_callback("prevalidate_callback"), background_image("background_image"), + background_image_disabled("background_image_disabled"), + background_image_focused("background_image_focused"), select_on_focus("select_on_focus", false), handle_edit_keys_directly("handle_edit_keys_directly", false), commit_on_focus_lost("commit_on_focus_lost", true), @@ -100,9 +104,8 @@ LLLineEditor::Params::Params() text_color("text_color"), text_readonly_color("text_readonly_color"), text_tentative_color("text_tentative_color"), - bg_readonly_color("bg_readonly_color"), - bg_writeable_color("bg_writeable_color"), - bg_focus_color("bg_focus_color"), + highlight_color("highlight_color"), + preedit_bg_color("preedit_bg_color"), border(""), is_unicode("is_unicode"), drop_shadow_visible("drop_shadow_visible"), @@ -145,18 +148,18 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p) mSelectAllonFocusReceived( p.select_on_focus ), mPassDelete(FALSE), mReadOnly(FALSE), - mImage( NULL ), + mBgImage( p.background_image ), + mBgImageDisabled( p.background_image_disabled ), + mBgImageFocused( p.background_image_focused ), mReplaceNewlinesWithSpaces( TRUE ), mLabel(p.label), mCursorColor(p.cursor_color()), mFgColor(p.text_color()), mReadOnlyFgColor(p.text_readonly_color()), mTentativeFgColor(p.text_tentative_color()), - mWriteableBgColor(p.bg_writeable_color()), - mReadOnlyBgColor(p.bg_readonly_color()), - mFocusBgColor(p.bg_focus_color()), - mGLFont(p.font), - mGLFontStyle(LLFontGL::getStyleFromString(p.font.style)) + mHighlightColor(p.highlight_color()), + mPreeditBgColor(p.preedit_bg_color()), + mGLFont(p.font) { llassert( mMaxLengthBytes > 0 ); @@ -183,11 +186,6 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p) mBorder = LLUICtrlFactory::create(border_p); addChild( mBorder ); - if(p.background_image.isProvided()) - { - mImage = p.background_image; - } - // clamp text padding to current editor size updateTextPadding(); setCursor(mText.length()); @@ -237,6 +235,7 @@ void LLLineEditor::onFocusLost() LLUICtrl::onFocusLost(); } +// virtual void LLLineEditor::onCommit() { // put current line into the line history @@ -247,6 +246,33 @@ void LLLineEditor::onCommit() selectAll(); } +// Returns TRUE if user changed value at all +// virtual +BOOL LLLineEditor::isDirty() const +{ + return mText.getString() != mPrevText; +} + +// Clear dirty state +// virtual +void LLLineEditor::resetDirty() +{ + mPrevText = mText.getString(); +} + +// assumes UTF8 text +// virtual +void LLLineEditor::setValue(const LLSD& value ) +{ + setText(value.asString()); +} + +//virtual +LLSD LLLineEditor::getValue() const +{ + return LLSD(getText()); +} + // line history support void LLLineEditor::updateHistory() @@ -1497,6 +1523,33 @@ void LLLineEditor::doDelete() } +void LLLineEditor::drawBackground() +{ + bool has_focus = hasFocus(); + LLUIImage* image; + if ( mReadOnly ) + { + image = mBgImageDisabled; + } + else if ( has_focus ) + { + image = mBgImageFocused; + } + else + { + image = mBgImage; + } + + // optionally draw programmatic border + if (has_focus) + { + image->drawBorder(0, 0, getRect().getWidth(), getRect().getHeight(), + gFocusMgr.getFocusColor(), + gFocusMgr.getFocusFlashWidth()); + } + image->draw(getLocalRect()); +} + void LLLineEditor::draw() { S32 text_len = mText.length(); @@ -1527,34 +1580,8 @@ void LLLineEditor::draw() LLRect background( 0, getRect().getHeight(), getRect().getWidth(), 0 ); background.stretch( -mBorderThickness ); - LLColor4 bg_color = mReadOnlyBgColor.get(); - -#if 1 // for when we're ready for image art. - if( hasFocus()) - { - mImage->drawBorder(0, 0, getRect().getWidth(), getRect().getHeight(), gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth()); - } - mImage->draw(getLocalRect()); -#else // the old programmer art. - // drawing solids requires texturing be disabled - { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - // draw background for text - if( !mReadOnly ) - { - if( gFocusMgr.getKeyboardFocus() == this ) - { - bg_color = mFocusBgColor.get(); - } - else - { - bg_color = mWriteableBgColor.get(); - } - } - gl_rect_2d(background, bg_color); - } -#endif - + drawBackground(); + // draw text // With viewer-2 art files, input region is 2 pixels up @@ -1600,7 +1627,8 @@ void LLLineEditor::draw() background.mBottom + preedit_standout_position, preedit_pixels_right - preedit_standout_gap - 1, background.mBottom + preedit_standout_position - preedit_standout_thickness, - (text_color * preedit_standout_brightness + bg_color * (1 - preedit_standout_brightness)).setAlpha(1.0f)); + (text_color * preedit_standout_brightness + + mPreeditBgColor * (1 - preedit_standout_brightness)).setAlpha(1.0f)); } else { @@ -1608,7 +1636,8 @@ void LLLineEditor::draw() background.mBottom + preedit_marker_position, preedit_pixels_right - preedit_marker_gap - 1, background.mBottom + preedit_marker_position - preedit_marker_thickness, - (text_color * preedit_marker_brightness + bg_color * (1 - preedit_marker_brightness)).setAlpha(1.0f)); + (text_color * preedit_marker_brightness + + mPreeditBgColor * (1 - preedit_marker_brightness)).setAlpha(1.0f)); } } } @@ -1641,7 +1670,7 @@ void LLLineEditor::draw() rendered_pixels_right, text_bottom, text_color, LLFontGL::LEFT, LLFontGL::BOTTOM, - mGLFontStyle, + 0, LLFontGL::NO_SHADOW, select_left - mScrollHPos, mMaxHPixels - llround(rendered_pixels_right), @@ -1650,7 +1679,7 @@ void LLLineEditor::draw() if( (rendered_pixels_right < (F32)mMaxHPixels) && (rendered_text < text_len) ) { - LLColor4 color(1.f - bg_color.mV[0], 1.f - bg_color.mV[1], 1.f - bg_color.mV[2], 1.f); + LLColor4 color = mHighlightColor; // selected middle S32 width = mGLFont->getWidth(mText.getWString().c_str(), mScrollHPos + rendered_text, select_right - mScrollHPos - rendered_text); width = llmin(width, mMaxHPixels - llround(rendered_pixels_right)); @@ -1661,7 +1690,7 @@ void LLLineEditor::draw() rendered_pixels_right, text_bottom, LLColor4( 1.f - text_color.mV[0], 1.f - text_color.mV[1], 1.f - text_color.mV[2], 1 ), LLFontGL::LEFT, LLFontGL::BOTTOM, - mGLFontStyle, + 0, LLFontGL::NO_SHADOW, select_right - mScrollHPos - rendered_text, mMaxHPixels - llround(rendered_pixels_right), @@ -1676,7 +1705,7 @@ void LLLineEditor::draw() rendered_pixels_right, text_bottom, text_color, LLFontGL::LEFT, LLFontGL::BOTTOM, - mGLFontStyle, + 0, LLFontGL::NO_SHADOW, S32_MAX, mMaxHPixels - llround(rendered_pixels_right), @@ -1690,7 +1719,7 @@ void LLLineEditor::draw() rendered_pixels_right, text_bottom, text_color, LLFontGL::LEFT, LLFontGL::BOTTOM, - mGLFontStyle, + 0, LLFontGL::NO_SHADOW, S32_MAX, mMaxHPixels - llround(rendered_pixels_right), @@ -1728,7 +1757,7 @@ void LLLineEditor::draw() mGLFont->render(mText, getCursor(), (F32)(cursor_left + lineeditor_cursor_thickness / 2), text_bottom, LLColor4( 1.f - text_color.mV[0], 1.f - text_color.mV[1], 1.f - text_color.mV[2], 1 ), LLFontGL::LEFT, LLFontGL::BOTTOM, - mGLFontStyle, + 0, LLFontGL::NO_SHADOW, 1); } @@ -1754,7 +1783,7 @@ void LLLineEditor::draw() label_color, LLFontGL::LEFT, LLFontGL::BOTTOM, - mGLFontStyle, + 0, LLFontGL::NO_SHADOW, S32_MAX, mMaxHPixels - llround(rendered_pixels_right), @@ -1779,7 +1808,7 @@ void LLLineEditor::draw() label_color, LLFontGL::LEFT, LLFontGL::BOTTOM, - mGLFontStyle, + 0, LLFontGL::NO_SHADOW, S32_MAX, mMaxHPixels - llround(rendered_pixels_right), diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index 4362cff2fe..0986ce5a87 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -84,7 +84,9 @@ public: Optional border; - Optional background_image; + Optional background_image, + background_image_disabled, + background_image_focused; Optional select_on_focus, handle_edit_keys_directly, @@ -96,10 +98,9 @@ public: text_color, text_readonly_color, text_tentative_color, - bg_readonly_color, - bg_writeable_color, - bg_focus_color; - + highlight_color, + preedit_bg_color; + Optional text_pad_left, text_pad_right; @@ -107,7 +108,7 @@ public: drop_shadow_visible, border_drop_shadow_visible, bg_visible; - + Params(); }; protected: @@ -163,12 +164,12 @@ public: virtual void setRect(const LLRect& rect); virtual BOOL acceptsTextInput() const; virtual void onCommit(); - virtual BOOL isDirty() const { return mText.getString() != mPrevText; } // Returns TRUE if user changed value at all - virtual void resetDirty() { mPrevText = mText.getString(); } // Clear dirty state + virtual BOOL isDirty() const; // Returns TRUE if user changed value at all + virtual void resetDirty(); // Clear dirty state // assumes UTF8 text - virtual void setValue(const LLSD& value ) { setText(value.asString()); } - virtual LLSD getValue() const { return LLSD(getText()); } + virtual void setValue(const LLSD& value ); + virtual LLSD getValue() const; virtual BOOL setTextArg( const std::string& key, const LLStringExplicit& text ); virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text ); @@ -197,16 +198,10 @@ public: void setFgColor( const LLColor4& c ) { mFgColor = c; } void setReadOnlyFgColor( const LLColor4& c ) { mReadOnlyFgColor = c; } void setTentativeFgColor(const LLColor4& c) { mTentativeFgColor = c; } - void setWriteableBgColor( const LLColor4& c ) { mWriteableBgColor = c; } - void setReadOnlyBgColor( const LLColor4& c ) { mReadOnlyBgColor = c; } - void setFocusBgColor(const LLColor4& c) { mFocusBgColor = c; } const LLColor4& getFgColor() const { return mFgColor.get(); } const LLColor4& getReadOnlyFgColor() const { return mReadOnlyFgColor.get(); } const LLColor4& getTentativeFgColor() const { return mTentativeFgColor.get(); } - const LLColor4& getWriteableBgColor() const { return mWriteableBgColor.get(); } - const LLColor4& getReadOnlyBgColor() const { return mReadOnlyBgColor.get(); } - const LLColor4& getFocusBgColor() const { return mFocusBgColor.get(); } void setIgnoreArrowKeys(BOOL b) { mIgnoreArrowKeys = b; } void setIgnoreTab(BOOL b) { mIgnoreTab = b; } @@ -266,6 +261,9 @@ private: BOOL handleControlKey(KEY key, MASK mask); S32 handleCommitKey(KEY key, MASK mask); void updateTextPadding(); + + // Draw the background image depending on enabled/focused state. + void drawBackground(); // // private data members @@ -294,7 +292,6 @@ protected: LLViewBorder* mBorder; const LLFontGL* mGLFont; - U8 mGLFontStyle; S32 mMaxLengthBytes; // Max length of the UTF8 string in bytes S32 mCursorPos; // I-beam is just after the mCursorPos-th character. S32 mScrollHPos; // Horizontal offset from the start of mText. Used for scrolling. @@ -326,9 +323,8 @@ protected: LLUIColor mFgColor; LLUIColor mReadOnlyFgColor; LLUIColor mTentativeFgColor; - LLUIColor mWriteableBgColor; - LLUIColor mReadOnlyBgColor; - LLUIColor mFocusBgColor; + LLUIColor mHighlightColor; // background for selected text + LLUIColor mPreeditBgColor; // preedit marker background color S32 mBorderThickness; @@ -349,7 +345,9 @@ protected: private: // Instances that by default point to the statics but can be overidden in XML. - LLPointer mImage; + LLPointer mBgImage; + LLPointer mBgImageDisabled; + LLPointer mBgImageFocused; BOOL mReplaceNewlinesWithSpaces; // if false, will replace pasted newlines with paragraph symbol. diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index ade88d2714..fdb4bdd5c1 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -49,12 +49,12 @@ #include "llmath.h" #include "llrender.h" #include "llfocusmgr.h" -#include "llfont.h" #include "llcoord.h" #include "llwindow.h" #include "llcriticaldamp.h" #include "lluictrlfactory.h" +#include "llbutton.h" #include "llfontgl.h" #include "llresmgr.h" #include "llui.h" @@ -1453,6 +1453,7 @@ void LLMenuItemBranchDownGL::draw( void ) setHover(FALSE); } + class LLMenuScrollItem : public LLMenuItemCallGL { public: @@ -1461,10 +1462,18 @@ public: ARROW_DOWN, ARROW_UP }; + struct ArrowTypes : public LLInitParam::TypeValuesHelper + { + static void declareValues() + { + declare("up", ARROW_UP); + declare("down", ARROW_DOWN); + } + }; struct Params : public LLInitParam::Block { - Optional arrow_type; + Optional arrow_type; Optional scroll_callback; }; diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 7d5cc25e1e..262f75f1e1 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -380,6 +380,7 @@ public: Params() : jump_key("jump_key", KEY_NONE), + horizontal_layout("horizontal_layout"), can_tear_off("tear_off", false), drop_shadow("drop_shadow", true), bg_visible("bg_visible", true), diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 50fee41029..2b6ae1f67e 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -384,7 +384,7 @@ LLNotificationTemplate::LLNotificationTemplate() : } LLNotification::LLNotification(const LLNotification::Params& p) : - mTimestamp(p.timestamp), + mTimestamp(p.time_stamp), mSubstitutions(p.substitutions), mPayload(p.payload), mExpiresAt(0), diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 512886790c..63eae7278f 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -294,7 +294,7 @@ public: Optional payload; Optional priority; Optional form_elements; - Optional timestamp; + Optional time_stamp; Optional context; struct Functor : public LLInitParam::Choice @@ -312,19 +312,23 @@ public: Params() : name("name"), priority("priority", NOTIFICATION_PRIORITY_UNSPECIFIED), - timestamp("time_stamp") + time_stamp("time_stamp"), + payload("payload"), + form_elements("form_elements") { - timestamp = LLDate::now(); + time_stamp = LLDate::now(); } Params(const std::string& _name) - : name("name"), - priority("priority", NOTIFICATION_PRIORITY_UNSPECIFIED), - timestamp("time_stamp") + : name("name"), + priority("priority", NOTIFICATION_PRIORITY_UNSPECIFIED), + time_stamp("time_stamp"), + payload("payload"), + form_elements("form_elements") { functor.name = _name; name = _name; - timestamp = LLDate::now(); + time_stamp = LLDate::now(); } }; diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp index 116096b7b3..9fb38bc316 100644 --- a/indra/llui/llpanel.cpp +++ b/indra/llui/llpanel.cpp @@ -43,6 +43,7 @@ #include "llerror.h" #include "lltimer.h" +#include "llbutton.h" #include "llmenugl.h" //#include "llstatusbar.h" #include "llui.h" @@ -53,7 +54,6 @@ #include "lluictrl.h" #include "lluictrlfactory.h" #include "llviewborder.h" -#include "llbutton.h" #include "lltabcontainer.h" static LLDefaultChildRegistry::Register r1("panel", &LLPanel::fromXML); @@ -65,6 +65,7 @@ const LLPanel::Params& LLPanel::getDefaultParams() LLPanel::Params::Params() : has_border("border", false), + border(""), bg_opaque_color("bg_opaque_color"), bg_alpha_color("bg_alpha_color"), background_visible("background_visible", false), @@ -430,7 +431,7 @@ void LLPanel::initFromParams(const LLPanel::Params& p) it != p.strings().end(); ++it) { - mUIStrings[it->name] = it->text; + mUIStrings[it->name] = it->value; } setLabel(p.label()); diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index 381cba2db3..4140e3aa93 100644 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -37,8 +37,6 @@ #include "llcallbackmap.h" #include "lluictrl.h" -#include "llbutton.h" -#include "lllineeditor.h" #include "llviewborder.h" #include "lluistring.h" #include "v4color.h" @@ -49,6 +47,7 @@ const S32 LLPANEL_BORDER_WIDTH = 1; const BOOL BORDER_YES = TRUE; const BOOL BORDER_NO = FALSE; +class LLButton; /* * General purpose concrete view base class. @@ -62,11 +61,11 @@ public: struct LocalizedString : public LLInitParam::Block { Mandatory name; - Mandatory text; + Mandatory value; LocalizedString() : name("name"), - text("value") + value("value") {} }; diff --git a/indra/llui/llprogressbar.cpp b/indra/llui/llprogressbar.cpp index 7a34cc6792..c8b6e814e1 100644 --- a/indra/llui/llprogressbar.cpp +++ b/indra/llui/llprogressbar.cpp @@ -50,10 +50,7 @@ static LLDefaultChildRegistry::Register r("progress_bar"); LLProgressBar::Params::Params() : image_bar("image_bar"), image_fill("image_fill"), - image_shadow("image_shadow"), color_bar("color_bar"), - color_bar2("color_bar2"), - color_shadow("color_shadow"), color_bg("color_bg") {} @@ -61,12 +58,9 @@ LLProgressBar::Params::Params() LLProgressBar::LLProgressBar(const LLProgressBar::Params& p) : LLView(p), mImageBar(p.image_bar), - mImageShadow(p.image_shadow), mImageFill(p.image_fill), mColorBackground(p.color_bg()), mColorBar(p.color_bar()), - mColorBar2(p.color_bar2()), - mColorShadow(p.color_shadow()), mPercentDone(0.f) {} @@ -85,10 +79,10 @@ void LLProgressBar::draw() F32 alpha = 0.5f + 0.5f*0.5f*(1.f + (F32)sin(3.f*timer.getElapsedTimeF32())); LLColor4 bar_color = mColorBar.get(); - bar_color.mV[3] = alpha; + bar_color.mV[VALPHA] *= alpha; // modulate alpha LLRect progress_rect = getLocalRect(); progress_rect.mRight = llround(getRect().getWidth() * (mPercentDone / 100.f)); - mImageFill->draw(progress_rect); + mImageFill->draw(progress_rect, bar_color); } void LLProgressBar::setPercent(const F32 percent) diff --git a/indra/llui/llprogressbar.h b/indra/llui/llprogressbar.h index 5c2f73ef9e..b6a5b0400d 100644 --- a/indra/llui/llprogressbar.h +++ b/indra/llui/llprogressbar.h @@ -43,12 +43,9 @@ public: struct Params : public LLInitParam::Block { Optional image_bar, - image_fill, - image_shadow; + image_fill; Optional color_bar, - color_bar2, - color_shadow, color_bg; Params(); @@ -65,10 +62,7 @@ private: LLPointer mImageBar; LLUIColor mColorBar; - LLUIColor mColorBar2; - LLPointer mImageShadow; - LLUIColor mColorShadow; LLUIColor mColorBackground; LLPointer mImageFill; diff --git a/indra/llui/llresizehandle.cpp b/indra/llui/llresizehandle.cpp index 90f51b9919..7449c339a0 100644 --- a/indra/llui/llresizehandle.cpp +++ b/indra/llui/llresizehandle.cpp @@ -45,7 +45,9 @@ const S32 RESIZE_BORDER_WIDTH = 3; LLResizeHandle::Params::Params() -: corner("corner") +: corner("corner"), + min_width("min_width"), + min_height("min_height") { name = "resize_handle"; } diff --git a/indra/llui/llrngwriter.cpp b/indra/llui/llrngwriter.cpp new file mode 100644 index 0000000000..cf23e3af15 --- /dev/null +++ b/indra/llui/llrngwriter.cpp @@ -0,0 +1,315 @@ +/** + * @file llrngwriter.cpp + * @brief Generates Relax NG schema from param blocks + * + * $LicenseInfo:firstyear=2003&license=viewergpl$ + * + * Copyright (c) 2003-2009, 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 "linden_common.h" + +#include "llrngwriter.h" +#include "lluicolor.h" +#include "lluictrlfactory.h" + +// +// LLRNGWriter - writes Relax NG schema files based on a param block +// +LLRNGWriter::LLRNGWriter() +{ + // register various callbacks for inspecting the contents of a param block + registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "boolean", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "unsignedByte", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "signedByte", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "unsignedShort", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "signedShort", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "unsignedInt", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "integer", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "float", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "double", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4)); + registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4)); +} + +void LLRNGWriter::writeRNG(const std::string& type_name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace) +{ + mGrammarNode = node; + mGrammarNode->setName("grammar"); + mGrammarNode->createChild("xmlns", true)->setStringValue("http://relaxng.org/ns/structure/1.0"); + mGrammarNode->createChild("datatypeLibrary", true)->setStringValue("http://www.w3.org/2001/XMLSchema-datatypes"); + mGrammarNode->createChild("ns", true)->setStringValue(xml_namespace); + + node = mGrammarNode->createChild("start", false); + node = node->createChild("ref", false); + node->createChild("name", true)->setStringValue(type_name); + + addDefinition(type_name, block); +} + +void LLRNGWriter::addDefinition(const std::string& type_name, const LLInitParam::BaseBlock& block) +{ + if (mDefinedElements.find(type_name) != mDefinedElements.end()) return; + mDefinedElements.insert(type_name); + + LLXMLNodePtr node = mGrammarNode->createChild("define", false); + node->createChild("name", true)->setStringValue(type_name); + + mElementNode = node->createChild("element", false); + mElementNode->createChild("name", true)->setStringValue(type_name); + mChildrenNode = mElementNode->createChild("zeroOrMore", false)->createChild("choice", false); + + mAttributesWritten.first = mElementNode; + mAttributesWritten.second.clear(); + mElementsWritten.clear(); + + block.inspectBlock(*this); + + // add includes for all possible children + const std::type_info* type = *LLWidgetTypeRegistry::instance().getValue(type_name); + const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instance().getValue(type); + + // add include declarations for all valid children + for (widget_registry_t::Registrar::registry_map_t::const_iterator it = widget_registryp->currentRegistrar().beginItems(); + it != widget_registryp->currentRegistrar().endItems(); + ++it) + { + std::string child_name = it->first; + if (child_name == type_name) + { + continue; + } + + LLXMLNodePtr old_element_node = mElementNode; + LLXMLNodePtr old_child_node = mChildrenNode; + addDefinition(child_name, (*LLDefaultParamBlockRegistry::instance().getValue(type))()); + mElementNode = old_element_node; + mChildrenNode = old_child_node; + + mChildrenNode->createChild("ref", false)->createChild("name", true)->setStringValue(child_name); + } + + if (mChildrenNode->mChildren.isNull()) + { + // remove unused children node + mChildrenNode->mParent->mParent->deleteChild(mChildrenNode->mParent); + } +} + +void LLRNGWriter::writeAttribute(const std::string& type, const Parser::name_stack_t& stack, S32 min_count, S32 max_count, const std::vector* possible_values) +{ + if (max_count == 0) return; + + name_stack_t non_empty_names; + std::string attribute_name; + for (name_stack_t::const_iterator it = stack.begin(); + it != stack.end(); + ++it) + { + const std::string& name = it->first; + if (!name.empty()) + { + non_empty_names.push_back(*it); + } + } + + if (non_empty_names.empty()) return; + + for (name_stack_t::const_iterator it = non_empty_names.begin(); + it != non_empty_names.end(); + ++it) + { + if (!attribute_name.empty()) + { + attribute_name += "."; + } + attribute_name += it->first; + } + + // singular attribute, e.g. + if (non_empty_names.size() == 1 && max_count == 1) + { + if (mAttributesWritten.second.find(attribute_name) == mAttributesWritten.second.end()) + { + LLXMLNodePtr node = createCardinalityNode(mElementNode, min_count, max_count)->createChild("attribute", false); + node->createChild("name", true)->setStringValue(attribute_name); + node->createChild("data", false)->createChild("type", true)->setStringValue(type); + + mAttributesWritten.second.insert(attribute_name); + } + } + // compound attribute + else + { + std::string element_name; + + // traverse all but last element, leaving that as an attribute name + name_stack_t::const_iterator end_it = non_empty_names.end(); + end_it--; + + for (name_stack_t::const_iterator it = non_empty_names.begin(); + it != end_it; + ++it) + { + if (it != non_empty_names.begin()) + { + element_name += "."; + } + element_name += it->first; + } + + elements_map_t::iterator found_it = mElementsWritten.find(element_name); + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + + if (found_it != mElementsWritten.end()) + { + // reuse existing element + LLXMLNodePtr choice_node = found_it->second.first; + + // attribute with this name not already written? + if (found_it->second.second.find(attribute_name) == found_it->second.second.end()) + { + // append to + LLXMLNodePtr node = choice_node->mChildren->head; + node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false); + node->createChild("name", true)->setStringValue(attribute_name); + addTypeNode(node, type, possible_values); + + // append to + node = choice_node->mChildren->head->mNext->mChildren->head; + node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false); + node->createChild("name", true)->setStringValue(non_empty_names.back().first); + addTypeNode(node, type, possible_values); + + // append to + //node = choice_node->mChildren->head->mNext->mNext->mChildren->head; + //node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false); + //node->createChild("name", true)->setStringValue(non_empty_names.back().first); + //addTypeNode(node, type, possible_values); + + found_it->second.second.insert(attribute_name); + } + } + else + { + LLXMLNodePtr choice_node = mElementNode->createChild("choice", false); + + LLXMLNodePtr node = choice_node->createChild("group", false); + node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false); + node->createChild("name", true)->setStringValue(attribute_name); + addTypeNode(node, type, possible_values); + + node = choice_node->createChild("optional", false); + node = node->createChild("element", false); + node->createChild("name", true)->setStringValue(element_name); + node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false); + node->createChild("name", true)->setStringValue(non_empty_names.back().first); + addTypeNode(node, type, possible_values); + + //node = choice_node->createChild("optional", false); + //node = node->createChild("element", false); + //node->createChild("name", true)->setStringValue(mDefinitionName + "." + element_name); + //node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false); + //node->createChild("name", true)->setStringValue(non_empty_names.back().first); + //addTypeNode(node, type, possible_values); + + attribute_data_t& attribute_data = mElementsWritten[element_name]; + attribute_data.first = choice_node; + attribute_data.second.insert(attribute_name); + } + } +} + +void LLRNGWriter::addTypeNode(LLXMLNodePtr parent_node, const std::string& type, const std::vector* possible_values) +{ + if (possible_values) + { + LLXMLNodePtr enum_node = parent_node->createChild("choice", false); + for (std::vector::const_iterator it = possible_values->begin(); + it != possible_values->end(); + ++it) + { + enum_node->createChild("value", false)->setStringValue(*it); + } + } + else + { + parent_node->createChild("data", false)->createChild("type", true)->setStringValue(type); + } +} + +LLXMLNodePtr LLRNGWriter::createCardinalityNode(LLXMLNodePtr parent_node, S32 min_count, S32 max_count) +{ + // unlinked by default, meaning this attribute is forbidden + LLXMLNodePtr count_node = new LLXMLNode(); + if (min_count == 0) + { + if (max_count == 1) + { + count_node = parent_node->createChild("optional", false); + } + else if (max_count > 1) + { + count_node = parent_node->createChild("zeroOrMore", false); + } + } + else if (min_count >= 1) + { + if (max_count == 1 && min_count == 1) + { + // just add raw element, will count as 1 and only 1 + count_node = parent_node; + } + else + { + count_node = parent_node->createChild("oneOrMore", false); + } + } + return count_node; +} diff --git a/indra/llui/llrngwriter.h b/indra/llui/llrngwriter.h new file mode 100644 index 0000000000..66807577b5 --- /dev/null +++ b/indra/llui/llrngwriter.h @@ -0,0 +1,69 @@ +/** + * @file llrngwriter.h + * @brief Generates Relax NG schema files from a param block + * + * $LicenseInfo:firstyear=2003&license=viewergpl$ + * + * Copyright (c) 2003-2009, 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$ + */ + +#ifndef LLRNGWRITER_H +#define LLRNGWRITER_H + +#include "llinitparam.h" +#include "llxmlnode.h" + +class LLRNGWriter : public LLInitParam::Parser +{ + LOG_CLASS(LLRNGWriter); +public: + void writeRNG(const std::string& name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace); + void addDefinition(const std::string& type_name, const LLInitParam::BaseBlock& block); + + /*virtual*/ std::string getCurrentElementName() { return LLStringUtil::null; } + + LLRNGWriter(); + +private: + LLXMLNodePtr createCardinalityNode(LLXMLNodePtr parent_node, S32 min_count, S32 max_count); + void addTypeNode(LLXMLNodePtr parent_node, const std::string& type, const std::vector* possible_values); + + void writeAttribute(const std::string& type, const Parser::name_stack_t&, S32 min_count, S32 max_count, const std::vector* possible_values); + LLXMLNodePtr mElementNode; + LLXMLNodePtr mChildrenNode; + LLXMLNodePtr mGrammarNode; + std::string mDefinitionName; + + typedef std::pair > attribute_data_t; + typedef std::map elements_map_t; + typedef std::set defined_elements_t; + + defined_elements_t mDefinedElements; + attribute_data_t mAttributesWritten; + elements_map_t mElementsWritten; +}; + +#endif //LLRNGWRITER_H diff --git a/indra/llui/llscrolllistcell.cpp b/indra/llui/llscrolllistcell.cpp index 4e6de24160..cd43e194d2 100644 --- a/indra/llui/llscrolllistcell.cpp +++ b/indra/llui/llscrolllistcell.cpp @@ -177,7 +177,6 @@ LLScrollListText::LLScrollListText(const LLScrollListCell::Params& p) mFont(p.font), mColor(p.color), mUseColor(p.color.isProvided()), - mFontStyle(LLFontGL::NORMAL), mFontAlignment(p.font_halign), mVisible(p.visible), mHighlightCount( 0 ), @@ -240,6 +239,13 @@ void LLScrollListText::setText(const LLStringExplicit& text) mText = text; } +void LLScrollListText::setFontStyle(const U8 font_style) +{ + LLFontDescriptor new_desc(mFont->getFontDesc()); + new_desc.setStyle(font_style); + mFont = LLFontGL::getFont(new_desc); +} + //virtual void LLScrollListText::setValue(const LLSD& text) { @@ -308,7 +314,7 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col display_color, mFontAlignment, LLFontGL::BOTTOM, - mFontStyle, + 0, LLFontGL::NO_SHADOW, string_chars, getWidth(), diff --git a/indra/llui/llscrolllistcell.h b/indra/llui/llscrolllistcell.h index 2ab13f7618..9d3fa65f64 100644 --- a/indra/llui/llscrolllistcell.h +++ b/indra/llui/llscrolllistcell.h @@ -145,14 +145,13 @@ public: /*virtual*/ BOOL isText() const; void setText(const LLStringExplicit& text); - void setFontStyle(const U8 font_style) { mFontStyle = font_style; } + void setFontStyle(const U8 font_style); private: LLUIString mText; const LLFontGL* mFont; LLColor4 mColor; U8 mUseColor; - U8 mFontStyle; LLFontGL::HAlign mFontAlignment; BOOL mVisible; S32 mHighlightCount; diff --git a/indra/llui/llscrolllistcolumn.h b/indra/llui/llscrolllistcolumn.h index 712ea56454..23318fd7c4 100644 --- a/indra/llui/llscrolllistcolumn.h +++ b/indra/llui/llscrolllistcolumn.h @@ -121,7 +121,7 @@ public: Alternative relative_width; Width() - : dynamic_width("dynamicwidth", false), + : dynamic_width("dynamic_width", false), pixel_width("width"), relative_width("relative_width", -1.f) { diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 84a725ce02..e8627586ea 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -102,11 +102,11 @@ struct SortScrollListItem //--------------------------------------------------------------------------- LLScrollListCtrl::Contents::Contents() -: columns("columns"), - rows("rows") +: columns("column"), + rows("row") { - addSynonym(columns, "column"); - addSynonym(rows, "row"); + addSynonym(columns, "columns"); + addSynonym(rows, "rows"); } LLScrollListCtrl::Params::Params() @@ -126,10 +126,11 @@ LLScrollListCtrl::Params::Params() bg_selected_color("bg_selected_color"), fg_disable_color("fg_disable_color"), bg_writeable_color("bg_writeable_color"), - bg_read_only_color("bg_read_only_color"), + bg_readonly_color("bg_readonly_color"), bg_stripe_color("bg_stripe_color"), hovered_color("hovered_color"), - highlighted_color("highlighted_color") + highlighted_color("highlighted_color"), + contents("") { name = "scroll_list"; mouse_opaque = true; @@ -170,7 +171,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p) mBackgroundVisible(p.background_visible), mDrawStripes(p.draw_stripes), mBgWriteableColor(p.bg_writeable_color()), - mBgReadOnlyColor(p.bg_read_only_color()), + mBgReadOnlyColor(p.bg_readonly_color()), mBgSelectedColor(p.bg_selected_color()), mBgStripeColor(p.bg_stripe_color()), mFgSelectedColor(p.fg_selected_color()), @@ -1082,12 +1083,12 @@ LLScrollListItem* LLScrollListCtrl::addSeparator(EAddPosition pos) { LLScrollListItem::Params separator_params; separator_params.enabled(false); - LLScrollListCell::Params cell_params; - cell_params.type = "icon"; - cell_params.value = "menu_separator"; - cell_params.color = LLColor4(0.f, 0.f, 0.f, 0.7f); - cell_params.font_halign = LLFontGL::HCENTER; - separator_params.cells.add(cell_params); + LLScrollListCell::Params column_params; + column_params.type = "icon"; + column_params.value = "menu_separator"; + column_params.color = LLColor4(0.f, 0.f, 0.f, 0.7f); + column_params.font_halign = LLFontGL::HCENTER; + separator_params.columns.add(column_params); return addRow( separator_params, pos ); } @@ -1249,7 +1250,7 @@ LLScrollListItem* LLScrollListCtrl::addStringUUIDItem(const std::string& item_te LLScrollListItem::Params item_p; item_p.enabled(enabled); item_p.value(id); - item_p.cells.add().value(item_text).type("text"); + item_p.columns.add().value(item_text).type("text"); return addRow( item_p, pos ); } @@ -2635,8 +2636,8 @@ LLScrollListItem* LLScrollListCtrl::addRow(const LLScrollListItem::Params& item_ // Add any columns we don't already have S32 col_index = 0; - for(LLInitParam::ParamIterator::const_iterator itor = item_p.cells().begin(); - itor != item_p.cells().end(); + for(LLInitParam::ParamIterator::const_iterator itor = item_p.columns().begin(); + itor != item_p.columns().end(); ++itor) { LLScrollListCell::Params cell_p = *itor; @@ -2687,7 +2688,7 @@ LLScrollListItem* LLScrollListCtrl::addRow(const LLScrollListItem::Params& item_ col_index++; } - if (item_p.cells().empty()) + if (item_p.columns().empty()) { if (mColumns.empty()) { @@ -2742,7 +2743,7 @@ LLScrollListItem* LLScrollListCtrl::addSimpleElement(const std::string& value, E LLScrollListItem::Params item_params; item_params.value(entry_id); - item_params.cells.add() + item_params.columns.add() .value(value) .font(LLFontGL::getFontSansSerifSmall()); diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 60cd9239e2..c1800419be 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -99,7 +99,7 @@ public: bg_selected_color, fg_disable_color, bg_writeable_color, - bg_read_only_color, + bg_readonly_color, bg_stripe_color, hovered_color, highlighted_color; diff --git a/indra/llui/llscrolllistitem.h b/indra/llui/llscrolllistitem.h index 4237d5b304..c2b7effbc7 100644 --- a/indra/llui/llscrolllistitem.h +++ b/indra/llui/llscrolllistitem.h @@ -68,7 +68,7 @@ public: Ignored type; Ignored length; - Multiple cells; + Multiple columns; Params() : enabled("enabled", true), @@ -76,9 +76,9 @@ public: name("name"), type("type"), length("length"), - cells("columns") + columns("columns") { - addSynonym(cells, "column"); + addSynonym(columns, "column"); addSynonym(value, "id"); } }; diff --git a/indra/llui/llsearcheditor.cpp b/indra/llui/llsearcheditor.cpp index 64583071a6..3516712dc9 100644 --- a/indra/llui/llsearcheditor.cpp +++ b/indra/llui/llsearcheditor.cpp @@ -1,6 +1,6 @@ /** - * @file lllineeditor.cpp - * @brief LLLineEditor base class + * @file llsearcheditor.cpp + * @brief LLSearchEditor implementation * * $LicenseInfo:firstyear=2001&license=viewergpl$ * @@ -36,89 +36,63 @@ #include "llsearcheditor.h" -//static LLDefaultChildRegistry::Register r2("search_editor"); - LLSearchEditor::LLSearchEditor(const LLSearchEditor::Params& p) : LLUICtrl(p) { - LLLineEditor::Params line_editor_p(p); - line_editor_p.name("search edit box"); - line_editor_p.rect(getLocalRect()); - line_editor_p.follows.flags(FOLLOWS_ALL); - line_editor_p.text_pad_right(getRect().getHeight()); - line_editor_p.keystroke_callback(boost::bind(&LLSearchEditor::onSearchEdit, this, _1)); - - mSearchEdit = LLUICtrlFactory::create(line_editor_p); - addChild(mSearchEdit); - - S32 btn_width = getRect().getHeight(); // button is square, and as tall as search editor - LLRect clear_btn_rect(getRect().getWidth() - btn_width, getRect().getHeight(), getRect().getWidth(), 0); - LLButton::Params button_params(p.clear_search_button); - button_params.name(std::string("clear search")); - button_params.rect(clear_btn_rect) ; + const S32 fudge = 2; + S32 btn_height = getRect().getHeight() - (fudge * 2); + + LLLineEditor::Params line_editor_params(p); + line_editor_params.name("filter edit box"); + line_editor_params.rect(getLocalRect()); + line_editor_params.follows.flags(FOLLOWS_ALL); + line_editor_params.text_pad_left(btn_height + fudge); + line_editor_params.commit_callback.function(boost::bind(&LLUICtrl::onCommit, this)); + + mSearchEditor = LLUICtrlFactory::create(line_editor_params); + addChild(mSearchEditor); + + LLRect search_btn_rect(fudge, fudge + btn_height, fudge + btn_height, fudge); + LLButton::Params button_params(p.search_button); + button_params.name(std::string("clear filter")); + button_params.rect(search_btn_rect) ; button_params.follows.flags(FOLLOWS_RIGHT|FOLLOWS_TOP); button_params.tab_stop(false); - button_params.click_callback.function(boost::bind(&LLSearchEditor::onClearSearch, this, _2)); + button_params.click_callback.function(boost::bind(&LLUICtrl::onCommit, this)); - mClearSearchButton = LLUICtrlFactory::create(button_params); - mSearchEdit->addChild(mClearSearchButton); + mSearchButton = LLUICtrlFactory::create(button_params); + mSearchEditor->addChild(mSearchButton); } //virtual void LLSearchEditor::setValue(const LLSD& value ) { - mSearchEdit->setValue(value); + mSearchEditor->setValue(value); } //virtual LLSD LLSearchEditor::getValue() const { - return mSearchEdit->getValue(); + return mSearchEditor->getValue(); } //virtual BOOL LLSearchEditor::setTextArg( const std::string& key, const LLStringExplicit& text ) { - return mSearchEdit->setTextArg(key, text); + return mSearchEditor->setTextArg(key, text); } //virtual BOOL LLSearchEditor::setLabelArg( const std::string& key, const LLStringExplicit& text ) { - return mSearchEdit->setLabelArg(key, text); + return mSearchEditor->setLabelArg(key, text); } //virtual void LLSearchEditor::clear() { - if (mSearchEdit) + if (mSearchEditor) { - mSearchEdit->clear(); + mSearchEditor->clear(); } } - -void LLSearchEditor::draw() -{ - mClearSearchButton->setVisible(!mSearchEdit->getWText().empty()); - - LLUICtrl::draw(); -} - - -void LLSearchEditor::onSearchEdit(LLLineEditor* caller ) -{ - if (mSearchCallback) - { - mSearchCallback(caller->getText()); - } -} - -void LLSearchEditor::onClearSearch(const LLSD& data) -{ - setText(LLStringUtil::null); - if (mSearchCallback) - { - mSearchCallback(LLStringUtil::null); - } -} - diff --git a/indra/llui/llsearcheditor.h b/indra/llui/llsearcheditor.h index d8c5093fbf..368b68baa3 100644 --- a/indra/llui/llsearcheditor.h +++ b/indra/llui/llsearcheditor.h @@ -39,28 +39,21 @@ * $/LicenseInfo$ */ -#ifndef LL_LLSEARCHEDITOR_H -#define LL_LLSEARCHEDITOR_H +#ifndef LL_SEARCHEDITOR_H +#define LL_SEARCHEDITOR_H #include "lllineeditor.h" #include "llbutton.h" -#include - -/* - * @brief A line editor with a button to clear it and a callback to call on every edit event. - */ class LLSearchEditor : public LLUICtrl { public: struct Params : public LLInitParam::Block { - Optional > search_callback; - - Optional clear_search_button; + Optional search_button; Params() - : clear_search_button("clear_search_button") + : search_button("search_button") { name = "search_editor"; } @@ -69,15 +62,11 @@ public: protected: LLSearchEditor(const Params&); friend class LLUICtrlFactory; + public: virtual ~LLSearchEditor() {} - /*virtual*/ void draw(); - - void setText(const LLStringExplicit &new_text) { mSearchEdit->setText(new_text); } - - typedef boost::function search_callback_t; - void setSearchCallback(search_callback_t cb) { mSearchCallback = cb; } + void setText(const LLStringExplicit &new_text) { mSearchEditor->setText(new_text); } // LLUICtrl interface virtual void setValue(const LLSD& value ); @@ -87,12 +76,8 @@ public: virtual void clear(); private: - void onSearchEdit(LLLineEditor* caller ); - void onClearSearch(const LLSD& data); - - LLLineEditor* mSearchEdit; - LLButton* mClearSearchButton; - search_callback_t mSearchCallback; + LLLineEditor* mSearchEditor; + LLButton* mSearchButton; }; -#endif // LL_LLSEARCHEDITOR_H +#endif // LL_SEARCHEDITOR_H diff --git a/indra/llui/llstyle.h b/indra/llui/llstyle.h index 1a94fcf2c6..32ddded2c8 100644 --- a/indra/llui/llstyle.h +++ b/indra/llui/llstyle.h @@ -34,7 +34,6 @@ #define LL_LLSTYLE_H #include "v4color.h" -#include "llfont.h" #include "llui.h" class LLFontGL; diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index 3d5b5caead..29c30004ef 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -108,6 +108,7 @@ LLTabContainer::Params::Params() tab_min_width("tab_min_width"), tab_max_width("tab_max_width"), hide_tabs("hide_tabs", false), + tab_padding_right("tab_padding_right"), tab_top_image_unselected("tab_top_image_unselected"), tab_top_image_selected("tab_top_image_selected"), tab_bottom_image_unselected("tab_bottom_image_unselected"), diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h index ac8232bbb1..78592a0f9a 100644 --- a/indra/llui/lltabcontainer.h +++ b/indra/llui/lltabcontainer.h @@ -122,6 +122,10 @@ public: TabPanelParams() : panel("panel", NULL), + label("label"), + select_tab("select_tab"), + is_placeholder("is_placeholder"), + indent("indent"), insert_at("insert_at", END) {} }; diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp index 56019171e1..3dd8d21f6b 100644 --- a/indra/llui/lltextbox.cpp +++ b/indra/llui/lltextbox.cpp @@ -82,8 +82,7 @@ LLTextBox::LLTextBox(const LLTextBox::Params& p) mHAlign(p.font_halign), mLineSpacing(p.line_spacing), mWordWrap( p.word_wrap ), - mDidWordWrap(FALSE), - mFontStyle(LLFontGL::getStyleFromString(p.font.style)) + mDidWordWrap(FALSE) { setText( p.text() ); } @@ -382,7 +381,7 @@ void LLTextBox::drawText( S32 x, S32 y, const LLColor4& color ) { mFontGL->render(mText.getWString(), 0, (F32)x, (F32)y, color, mHAlign, mVAlign, - mFontStyle, + 0, mShadowType, S32_MAX, getRect().getWidth(), NULL, TRUE, mUseEllipses); } @@ -395,7 +394,7 @@ void LLTextBox::drawText( S32 x, S32 y, const LLColor4& color ) S32 line_length = *iter; mFontGL->render(mText.getWString(), cur_pos, (F32)x, (F32)y, color, mHAlign, mVAlign, - mFontStyle, + 0, mShadowType, line_length, getRect().getWidth(), NULL, TRUE, mUseEllipses ); cur_pos += line_length + 1; diff --git a/indra/llui/lltextbox.h b/indra/llui/lltextbox.h index 53d57ff785..d807fe7639 100644 --- a/indra/llui/lltextbox.h +++ b/indra/llui/lltextbox.h @@ -143,7 +143,6 @@ private: BOOL mWordWrap; BOOL mDidWordWrap; - U8 mFontStyle; // style bit flags for font LLFontGL::ShadowType mShadowType; BOOL mBorderDropShadowVisible; BOOL mUseEllipses; diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 421ba32168..adeaf0a279 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -36,6 +36,7 @@ #include "lltexteditor.h" +#include "llfontfreetype.h" // for LLFontFreetype::FIRST_CHAR #include "llfontgl.h" #include "llrender.h" #include "llui.h" @@ -227,6 +228,29 @@ private: /////////////////////////////////////////////////////////////////// +LLTextEditor::Params::Params() +: default_text("default_text"), + max_text_length("max_length", 255), + read_only("read_only", false), + embedded_items("embedded_items", false), + hide_scrollbar("hide_scrollbar", false), + hide_border("hide_border", false), + word_wrap("word_wrap", false), + ignore_tab("ignore_tab", true), + track_bottom("track_bottom", false), + takes_non_scroll_clicks("takes_non_scroll_clicks", true), + cursor_color("cursor_color"), + default_color("default_color"), + text_color("text_color"), + text_readonly_color("text_readonly_color"), + bg_readonly_color("bg_readonly_color"), + bg_writeable_color("bg_writeable_color"), + bg_focus_color("bg_focus_color"), + length("length"), // ignored + type("type"), // ignored + is_unicode("is_unicode")// ignored +{} + LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) : LLUICtrl(p, LLTextViewModelPtr(new LLTextViewModel)), mMaxTextByteLength( p.max_text_length ), @@ -254,7 +278,7 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) mHideScrollbarForShortDocs( FALSE ), mTakesNonScrollClicks( p.takes_non_scroll_clicks ), mTrackBottom( p.track_bottom ), - mAllowEmbeddedItems( p.allow_embedded_items ), + mAllowEmbeddedItems( p.embedded_items ), mHandleEditKeysDirectly( FALSE ), mMouseDownX(0), mMouseDownY(0), @@ -263,8 +287,7 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) mScrollNeeded(FALSE), mLastSelectionY(-1), mTabsToNextField(p.ignore_tab), - mGLFont(p.font), - mGLFontStyle(LLFontGL::getStyleFromString(p.font.style)) + mGLFont(p.font) { static LLUICachedControl scrollbar_size ("UIScrollbarSize", 0); @@ -1930,7 +1953,7 @@ void LLTextEditor::pasteHelper(bool is_primary) for( S32 i = 0; i < len; i++ ) { llwchar wc = clean_string[i]; - if( (wc < LLFont::FIRST_CHAR) && (wc != LF) ) + if( (wc < LLFontFreetype::FIRST_CHAR) && (wc != LF) ) { clean_string[i] = LL_UNKNOWN_CHAR; } @@ -3101,7 +3124,7 @@ void LLTextEditor::drawClippedSegment(const LLWString &text, S32 seg_start, S32 S32 start = seg_start; S32 end = llmin( selection_left, seg_end ); S32 length = end - start; - font->render(text, start, x, y_top, color, LLFontGL::LEFT, LLFontGL::TOP, mGLFontStyle, LLFontGL::NO_SHADOW, length, S32_MAX, right_x, mAllowEmbeddedItems); + font->render(text, start, x, y_top, color, LLFontGL::LEFT, LLFontGL::TOP, 0, LLFontGL::NO_SHADOW, length, S32_MAX, right_x, mAllowEmbeddedItems); } x = *right_x; @@ -3114,7 +3137,7 @@ void LLTextEditor::drawClippedSegment(const LLWString &text, S32 seg_start, S32 font->render(text, start, x, y_top, LLColor4( 1.f - color.mV[0], 1.f - color.mV[1], 1.f - color.mV[2], 1.f ), - LLFontGL::LEFT, LLFontGL::TOP, mGLFontStyle, LLFontGL::NO_SHADOW, length, S32_MAX, right_x, mAllowEmbeddedItems); + LLFontGL::LEFT, LLFontGL::TOP, 0, LLFontGL::NO_SHADOW, length, S32_MAX, right_x, mAllowEmbeddedItems); } x = *right_x; if( selection_right < seg_end ) @@ -3123,7 +3146,7 @@ void LLTextEditor::drawClippedSegment(const LLWString &text, S32 seg_start, S32 S32 start = llmax( selection_right, seg_start ); S32 end = seg_end; S32 length = end - start; - font->render(text, start, x, y_top, color, LLFontGL::LEFT, LLFontGL::TOP, mGLFontStyle, LLFontGL::NO_SHADOW, length, S32_MAX, right_x, mAllowEmbeddedItems); + font->render(text, start, x, y_top, color, LLFontGL::LEFT, LLFontGL::TOP, 0, LLFontGL::NO_SHADOW, length, S32_MAX, right_x, mAllowEmbeddedItems); } } diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index 5e423f8548..4da91cc1d7 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -63,7 +63,7 @@ public: Optional max_text_length; Optional read_only, - allow_embedded_items, + embedded_items, hide_scrollbar, word_wrap, ignore_tab, @@ -86,30 +86,7 @@ public: length, is_unicode; - - Params() - : max_text_length("max_length", 255), - read_only("read_only", false), - allow_embedded_items("embedded_items", false), - hide_scrollbar("hide_scrollbar", false), - hide_border("hide_border", false), - word_wrap("word_wrap", false), - ignore_tab("ignore_tab", true), - track_bottom("track_bottom", false), - takes_non_scroll_clicks("takes_non_scroll_clicks", true), - cursor_color("cursor_color"), - default_color("default_color"), - text_color("text_color"), - text_readonly_color("text_readonly_color"), - bg_readonly_color("bg_readonly_color"), - bg_writeable_color("bg_writeable_color"), - bg_focus_color("bg_focus_color"), - length("length"), - type("type"), - is_unicode("is_unicode") - {} - - + Params(); }; void initFromParams(const Params&); @@ -524,7 +501,6 @@ private: S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes const LLFontGL* mGLFont; - U8 mGLFontStyle; // the font style from xml class LLViewBorder* mBorder; diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index 7eaa118222..6906f0befb 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -58,8 +58,9 @@ #include "llwindow.h" // for registration -#include "llsearcheditor.h" +#include "llfiltereditor.h" #include "llflyoutbutton.h" +#include "llsearcheditor.h" // for XUIParse #include "llquaternion.h" @@ -88,9 +89,10 @@ std::list gUntranslated; /*static*/ std::vector LLUI::sXUIPaths; -// register searcheditor here -static LLDefaultChildRegistry::Register register_search_editor("search_editor"); +// register filtereditor here +static LLDefaultChildRegistry::Register register_filter_editor("filter_editor"); static LLDefaultChildRegistry::Register register_flyout_button("flyout_button"); +static LLDefaultChildRegistry::Register register_search_editor("search_editor"); // @@ -1963,6 +1965,17 @@ namespace LLInitParam declare("blue", LLColor4::blue); } + template<> + class ParamCompare + { + public: + static bool equals(const LLFontGL* a, const LLFontGL* b) + { + return !(a->getFontDesc() < b->getFontDesc()) + && !(b->getFontDesc() < a->getFontDesc()); + } + }; + TypedParam::TypedParam(BlockDescriptor& descriptor, const char* name, const LLFontGL*const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) : super_t(descriptor, name, value, func, min_count, max_count), name(""), diff --git a/indra/llui/llui.h b/indra/llui/llui.h index 9399eff2ab..413733a50b 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -39,7 +39,6 @@ #include "llrect.h" #include "llcontrol.h" #include "llcoord.h" -//#include "llhtmlhelp.h" #include "llgl.h" // *TODO: break this dependency #include #include "lluiimage.h" // *TODO: break this dependency, need to add #include "lluiimage.h" to all widgets that hold an Optional in their paramblocks @@ -49,6 +48,8 @@ #include "lluicolortable.h" #include #include "lllazyvalue.h" +#include "llhandle.h" // *TODO: remove this dependency, added as a + // convenience when LLHandle moved to llhandle.h // LLUIFactory #include "llsd.h" @@ -433,139 +434,7 @@ public: LLLocalClipRect(const LLRect& rect, BOOL enabled = TRUE); }; -template -class LLTombStone : public LLRefCount -{ -public: - LLTombStone(T* target = NULL) : mTarget(target) {} - - void setTarget(T* target) { mTarget = target; } - T* getTarget() const { return mTarget; } -private: - T* mTarget; -}; - -// LLHandles are used to refer to objects whose lifetime you do not control or influence. -// Calling get() on a handle will return a pointer to the referenced object or NULL, -// if the object no longer exists. Note that during the lifetime of the returned pointer, -// you are assuming that the object will not be deleted by any action you perform, -// or any other thread, as normal when using pointers, so avoid using that pointer outside of -// the local code block. -// -// https://wiki.lindenlab.com/mediawiki/index.php?title=LLHandle&oldid=79669 - -template -class LLHandle -{ -public: - LLHandle() : mTombStone(sDefaultTombStone) {} - const LLHandle& operator =(const LLHandle& other) - { - mTombStone = other.mTombStone; - return *this; - } - - bool isDead() const - { - return mTombStone->getTarget() == NULL; - } - - void markDead() - { - mTombStone = sDefaultTombStone; - } - - T* get() const - { - return mTombStone->getTarget(); - } - - friend bool operator== (const LLHandle& lhs, const LLHandle& rhs) - { - return lhs.mTombStone == rhs.mTombStone; - } - friend bool operator!= (const LLHandle& lhs, const LLHandle& rhs) - { - return !(lhs == rhs); - } - friend bool operator< (const LLHandle& lhs, const LLHandle& rhs) - { - return lhs.mTombStone < rhs.mTombStone; - } - friend bool operator> (const LLHandle& lhs, const LLHandle& rhs) - { - return lhs.mTombStone > rhs.mTombStone; - } -protected: - -protected: - LLPointer > mTombStone; - -private: - static LLPointer > sDefaultTombStone; -}; - -// initialize static "empty" tombstone pointer -template LLPointer > LLHandle::sDefaultTombStone = new LLTombStone(); - - -template -class LLRootHandle : public LLHandle -{ -public: - LLRootHandle(T* object) { bind(object); } - LLRootHandle() {}; - ~LLRootHandle() { unbind(); } - - // this is redundant, since a LLRootHandle *is* an LLHandle - LLHandle getHandle() { return LLHandle(*this); } - - void bind(T* object) - { - // unbind existing tombstone - if (LLHandle::mTombStone.notNull()) - { - if (LLHandle::mTombStone->getTarget() == object) return; - LLHandle::mTombStone->setTarget(NULL); - } - // tombstone reference counted, so no paired delete - LLHandle::mTombStone = new LLTombStone(object); - } - - void unbind() - { - LLHandle::mTombStone->setTarget(NULL); - } - - //don't allow copying of root handles, since there should only be one -private: - LLRootHandle(const LLRootHandle& other) {}; -}; - -// Use this as a mixin for simple classes that need handles and when you don't -// want handles at multiple points of the inheritance hierarchy -template -class LLHandleProvider -{ -protected: - typedef LLHandle handle_type_t; - LLHandleProvider() - { - // provided here to enforce T deriving from LLHandleProvider - } - - LLHandle getHandle() - { - // perform lazy binding to avoid small tombstone allocations for handle - // providers whose handles are never referenced - mHandle.bind(static_cast(this)); - return mHandle; - } - -private: - LLRootHandle mHandle; -}; - +// Moved all LLHandle-related code to llhandle.h //RN: maybe this needs to moved elsewhere? class LLImageProviderInterface diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index ebf594ff66..aae4a86d87 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -43,7 +43,7 @@ static LLDefaultChildRegistry::Register r("ui_ctrl"); LLUICtrl::Params::Params() : tab_stop("tab_stop", true), label("label"), - initial_value("initial_value"), + initial_value("value"), init_callback("init_callback"), commit_callback("commit_callback"), validate_callback("validate_callback"), @@ -52,9 +52,7 @@ LLUICtrl::Params::Params() mouseleave_callback("mouseleave_callback"), control_name("control_name") { - addSynonym(initial_value, "initial_val"); - // this is the canonical name for text contents of an xml node - addSynonym(initial_value, "value"); + addSynonym(initial_value, "initial_value"); } LLFocusableElement::LLFocusableElement() diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index 16fbbf79ea..cf6634f370 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -108,7 +108,7 @@ public: { Optional function; }; - + struct EnableCallbackParam : public LLInitParam::Block { Optional function; diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp index 9df22e39b4..3b2b56d48e 100644 --- a/indra/llui/lluictrlfactory.cpp +++ b/indra/llui/lluictrlfactory.cpp @@ -77,6 +77,7 @@ const S32 HPAD = 4; const S32 VPAD = 4; const S32 FLOATER_H_MARGIN = 15; const S32 MIN_WIDGET_HEIGHT = 10; +const S32 MAX_STRING_ATTRIBUTE_SIZE = 40; LLFastTimer::DeclareTimer FTM_WIDGET_CONSTRUCTION("Widget Construction"); LLFastTimer::DeclareTimer FTM_INIT_FROM_PARAMS("Widget InitFromParams"); @@ -449,177 +450,6 @@ void LLUICtrlFactory::popFactoryFunctions() } } - -// -// LLRNGWriter - writes Relax NG schema files based on a param block -// -LLRNGWriter::LLRNGWriter() -{ - // register various callbacks for inspecting the contents of a param block - registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "boolean", _1, _2, _3, _4)); - registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4)); - registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "unsignedByte", _1, _2, _3, _4)); - registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "signedByte", _1, _2, _3, _4)); - registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "unsignedShort", _1, _2, _3, _4)); - registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "signedShort", _1, _2, _3, _4)); - registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "unsignedInt", _1, _2, _3, _4)); - registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "integer", _1, _2, _3, _4)); - registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "float", _1, _2, _3, _4)); - registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "double", _1, _2, _3, _4)); - registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4)); - registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4)); - registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4)); - registerInspectFunc(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4)); -} - -void LLRNGWriter::writeRNG(const std::string& type_name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace) -{ - mGrammarNode = node; - mGrammarNode->setName("grammar"); - mGrammarNode->createChild("xmlns", true)->setStringValue("http://relaxng/ns/structure/1.0"); - mGrammarNode->createChild("datatypeLibrary", true)->setStringValue("http://www.w3.org/2001/XMLSchema-datatypes"); - mGrammarNode->createChild("ns", true)->setStringValue(xml_namespace); - - node = mGrammarNode->createChild("start", false); - node = node->createChild("ref", false); - node->createChild("name", true)->setStringValue(type_name); - - node = mGrammarNode->createChild("define", false); - node->createChild("name", true)->setStringValue(type_name); - - mElementNode = node->createChild("element", false); - mElementNode->createChild("name", true)->setStringValue(type_name); - - block.inspectBlock(*this); -} - -void LLRNGWriter::writeAttribute(const std::string& type, const Parser::name_stack_t& stack, S32 min_count, S32 max_count, const std::vector* possible_values) -{ - name_stack_t non_empty_names; - std::string attribute_name; - for (name_stack_t::const_iterator it = stack.begin(); - it != stack.end(); - ++it) - { - const std::string& name = it->first; - if (!name.empty()) - { - non_empty_names.push_back(*it); - } - } - - if (non_empty_names.empty()) return; - - for (name_stack_t::const_iterator it = non_empty_names.begin(); - it != non_empty_names.end(); - ++it) - { - if (!attribute_name.empty()) - { - attribute_name += "."; - } - attribute_name += it->first; - } - - // singular attribute - if (non_empty_names.size() == 1) - { - if (max_count == 1) - { - LLXMLNodePtr node = getCardinalityNode(mElementNode, min_count, max_count)->createChild("attribute", false); - node->createChild("name", true)->setStringValue(attribute_name); - node->createChild("data", false)->createChild("type", true)->setStringValue(type); - } - } - // compound attribute - else - { - std::string element_name; - - // traverse all but last element, leaving that as an attribute name - name_stack_t::const_iterator end_it = non_empty_names.end(); - end_it--; - - for (name_stack_t::const_iterator it = non_empty_names.begin(); - it != end_it; - ++it) - { - if (it != non_empty_names.begin()) - { - element_name += "."; - } - element_name += it->first; - } - - elements_map_t::iterator found_it = mElementsWritten.find(element_name); - if (found_it != mElementsWritten.end()) - { - // reuse existing element - LLXMLNodePtr choice_node = found_it->second; - - LLXMLNodePtr node = choice_node->mChildren->head; - node = getCardinalityNode(node, min_count, max_count)->createChild("attribute", false); - node->createChild("name", true)->setStringValue(attribute_name); - node->createChild("data", false)->createChild("type", true)->setStringValue(type); - - node = choice_node->mChildren->head->mNext->mChildren->head; - node = getCardinalityNode(node, min_count, max_count)->createChild("attribute", false); - node->createChild("name", true)->setStringValue(non_empty_names.back().first); - node->createChild("data", false)->createChild("type", true)->setStringValue(type); - } - else - { - LLXMLNodePtr choice_node = mElementNode->createChild("choice", false); - - LLXMLNodePtr node = choice_node->createChild("group", false); - node = getCardinalityNode(node, min_count, max_count)->createChild("attribute", false); - node->createChild("name", true)->setStringValue(attribute_name); - node->createChild("data", false)->createChild("type", true)->setStringValue(type); - - node = choice_node->createChild("element", false); - node->createChild("name", true)->setStringValue(element_name); - node = getCardinalityNode(node, min_count, max_count)->createChild("attribute", false); - node->createChild("name", true)->setStringValue(non_empty_names.back().first); - node->createChild("data", false)->createChild("type", true)->setStringValue(type); - - node = choice_node->createChild("element", false); - node->createChild("name", true)->setStringValue(type + "." + element_name); - node->createChild("ref", true)->createChild("name", true)->setStringValue(element_name); - - mElementsWritten[element_name] = choice_node; - } - } -} - -LLXMLNodePtr LLRNGWriter::getCardinalityNode(LLXMLNodePtr parent_node, S32 min_count, S32 max_count) -{ - // unlinked by default, meaning this attribute is forbidden - LLXMLNodePtr count_node = new LLXMLNode(); - if (min_count >= 1) - { - if (max_count == 1 && min_count == 1) - { - // just add raw element, will count as 1 and only 1 - count_node = mElementNode; - } - else - { - count_node = mElementNode->createChild("oneOrMore", false); - } - } - else - { - if (max_count == 1) - { - count_node = mElementNode->createChild("optional", false); - } - else if (max_count > 1) - { - count_node = mElementNode->createChild("zeroOrMore", false); - } - } - return count_node; -} // // LLXSDWriter // @@ -811,7 +641,7 @@ void LLXSDWriter::addAttributeToSchema(LLXMLNodePtr type_declaration_node, const string_set_t& attributes_written = mAttributesWritten[type_declaration_node]; - string_set_t::iterator found_it = std::lower_bound(attributes_written.begin(), attributes_written.end(), attribute_name); + string_set_t::iterator found_it = attributes_written.lower_bound(attribute_name); // attribute not yet declared if (found_it == attributes_written.end() || attributes_written.key_comp()(attribute_name, *found_it)) @@ -997,142 +827,6 @@ void LLXUIParser::readXUI(LLXMLNodePtr node, LLInitParam::BaseBlock& block, bool } } -void LLXUIParser::writeXUI(LLXMLNodePtr node, const LLInitParam::BaseBlock &block, const LLInitParam::BaseBlock* diff_block) -{ - mLastWriteGeneration = -1; - mWriteRootNode = node; - block.serializeBlock(*this, Parser::name_stack_t(), diff_block); -} - -// go from a stack of names to a specific XML node -LLXMLNodePtr LLXUIParser::getNode(const name_stack_t& stack) -{ - name_stack_t name_stack; - - for (name_stack_t::const_iterator it = stack.begin(); - it != stack.end(); - ++it) - { - if (!it->first.empty()) - { - name_stack.push_back(*it); - } - } - - if (name_stack.empty() || mWriteRootNode.isNull()) return NULL; - - std::string attribute_name = name_stack.front().first; - - // heuristic to make font always attribute of parent node - bool is_font = (attribute_name == "font"); - // XML spec says that attributes have their whitespace normalized - // on parse: http://www.w3.org/TR/REC-xml/#AVNormalize - // Therefore text-oriented widgets that might have carriage returns - // have their values serialized as text contents, not the - // initial_value attribute. JC - if (attribute_name == "initial_value") - { - const char* root_node_name = mWriteRootNode->getName()->mString; - if (!strcmp(root_node_name, "text") // LLTextBox - || !strcmp(root_node_name, "text_editor") - || !strcmp(root_node_name, "line_editor")) // for consistency - { - // writeStringValue will write to this node - return mWriteRootNode; - } - } - - for (name_stack_t::const_iterator it = ++name_stack.begin(); - it != name_stack.end(); - ++it) - { - attribute_name += "."; - attribute_name += it->first; - } - - // *NOTE: elements for translation need to have whitespace - // preserved like "initial_value" above, however, the node - // becomes an attribute of the containing floater or panel. - // Because all elements must have a "name" attribute, and - // "name" is parsed first, just put the value into the last written - // child. - if (attribute_name == "string.value") - { - // The caller of will shortly call writeStringValue(), which sets - // this node's type to string, but we don't want to export type="string". - // Set the default for this node to suppress the export. - static LLXMLNodePtr default_node; - if (default_node.isNull()) - { - default_node = new LLXMLNode(); - // Force the node to have a string type - default_node->setStringValue( std::string() ); - } - mLastWrittenChild->setDefault(default_node); - // mLastWrittenChild is the "string" node part of "string.value", - // so the caller will call writeStringValue() into that node, - // setting the node text contents. - return mLastWrittenChild; - } - - LLXMLNodePtr attribute_node; - - const char* attribute_cstr = attribute_name.c_str(); - if (name_stack.size() != 1 - && !is_font) - { - std::string child_node_name(mWriteRootNode->getName()->mString); - child_node_name += "."; - child_node_name += name_stack.front().first; - - LLXMLNodePtr child_node; - - if (mLastWriteGeneration == name_stack.front().second) - { - child_node = mLastWrittenChild; - } - else - { - mLastWriteGeneration = name_stack.front().second; - child_node = mWriteRootNode->createChild(child_node_name.c_str(), false); - } - - mLastWrittenChild = child_node; - - name_stack_t::const_iterator it = ++name_stack.begin(); - std::string short_attribute_name(it->first); - - for (++it; - it != name_stack.end(); - ++it) - { - short_attribute_name += "."; - short_attribute_name += it->first; - } - - if (child_node->hasAttribute(short_attribute_name.c_str())) - { - llerrs << "Attribute " << short_attribute_name << " already exists!" << llendl; - } - - attribute_node = child_node->createChild(short_attribute_name.c_str(), true); - } - else - { - if (mWriteRootNode->hasAttribute(attribute_cstr)) - { - mWriteRootNode->getAttribute(attribute_cstr, attribute_node); - } - else - { - attribute_node = mWriteRootNode->createChild(attribute_name.c_str(), true); - } - } - - return attribute_node; -} - - bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, const std::string& scope, LLInitParam::BaseBlock& block) { typedef boost::tokenizer > tokenizer; @@ -1152,8 +846,15 @@ bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, const std::string& scope, LLIn // child nodes are not necessarily valid parameters (could be a child widget) // so don't complain once we've recursed bool silent = mCurReadDepth > 0; - block.submitValue(mNameStack, *this, silent); - mNameStack.pop_back(); + if (!block.submitValue(mNameStack, *this, true)) + { + mNameStack.pop_back(); + block.submitValue(mNameStack, *this, silent); + } + else + { + mNameStack.pop_back(); + } } // then traverse children @@ -1271,6 +972,62 @@ bool LLXUIParser::readAttributes(LLXMLNodePtr nodep, LLInitParam::BaseBlock& blo return any_parsed; } +void LLXUIParser::writeXUI(LLXMLNodePtr node, const LLInitParam::BaseBlock &block, const LLInitParam::BaseBlock* diff_block) +{ + mWriteRootNode = node; + block.serializeBlock(*this, Parser::name_stack_t(), diff_block); + mOutNodes.clear(); +} + +// go from a stack of names to a specific XML node +LLXMLNodePtr LLXUIParser::getNode(const name_stack_t& stack) +{ + name_stack_t name_stack; + for (name_stack_t::const_iterator it = stack.begin(); + it != stack.end(); + ++it) + { + if (!it->first.empty()) + { + name_stack.push_back(*it); + } + } + + LLXMLNodePtr out_node = mWriteRootNode; + + name_stack_t::const_iterator next_it = name_stack.begin(); + for (name_stack_t::const_iterator it = name_stack.begin(); + it != name_stack.end(); + it = next_it) + { + ++next_it; + if (it->first.empty()) + { + continue; + } + + out_nodes_t::iterator found_it = mOutNodes.lower_bound(it->second); + + // node with this name not yet written + if (found_it == mOutNodes.end() || mOutNodes.key_comp()(found_it->first, it->second)) + { + // make an attribute if we are the last element on the name stack + bool is_attribute = next_it == name_stack.end(); + LLXMLNodePtr new_node = new LLXMLNode(it->first.c_str(), is_attribute); + out_node->addChild(new_node); + mOutNodes.insert(found_it, std::make_pair(it->second, new_node)); + out_node = new_node; + } + else + { + out_node = found_it->second; + } + } + + return (out_node == mWriteRootNode ? LLXMLNodePtr(NULL) : out_node); +} + + bool LLXUIParser::readBoolValue(void* val_ptr) { S32 value; @@ -1301,7 +1058,27 @@ bool LLXUIParser::writeStringValue(const void* val_ptr, const name_stack_t& stac LLXMLNodePtr node = getNode(stack); if (node.notNull()) { - node->setStringValue(*((std::string*)val_ptr)); + const std::string* string_val = reinterpret_cast(val_ptr); + if (string_val->find('\n') != std::string::npos + || string_val->size() > MAX_STRING_ATTRIBUTE_SIZE) + { + // don't write strings with newlines into attributes + std::string attribute_name = node->getName()->mString; + LLXMLNodePtr parent_node = node->mParent; + parent_node->deleteChild(node); + // write results in text contents of node + if (attribute_name == "value") + { + // "value" is implicit, just write to parent + node = parent_node; + } + else + { + // create a child that is not an attribute, but with same name + node = parent_node->createChild(attribute_name.c_str(), false); + } + } + node->setStringValue(*string_val); return true; } return false; @@ -1538,7 +1315,26 @@ bool LLXUIParser::writeSDValue(const void* val_ptr, const name_stack_t& stack) LLXMLNodePtr node = getNode(stack); if (node.notNull()) { - node->setStringValue(((LLSD*)val_ptr)->asString()); + std::string string_val = ((LLSD*)val_ptr)->asString(); + if (string_val.find('\n') != std::string::npos || string_val.size() > MAX_STRING_ATTRIBUTE_SIZE) + { + // don't write strings with newlines into attributes + std::string attribute_name = node->getName()->mString; + LLXMLNodePtr parent_node = node->mParent; + parent_node->deleteChild(node); + // write results in text contents of node + if (attribute_name == "value") + { + // "value" is implicit, just write to parent + node = parent_node; + } + else + { + node = parent_node->createChild(attribute_name.c_str(), false); + } + } + + node->setStringValue(string_val); return true; } return false; diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index 894c77888c..6374018ca6 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -47,28 +47,6 @@ class LLPanel; class LLFloater; class LLView; -class LLRNGWriter : public LLInitParam::Parser -{ - LOG_CLASS(LLRNGWriter); -public: - void writeRNG(const std::string& name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace); - - /*virtual*/ std::string getCurrentElementName() { return LLStringUtil::null; } - - LLRNGWriter(); - -private: - LLXMLNodePtr getCardinalityNode(LLXMLNodePtr parent_node, S32 min_count, S32 max_count); - - void writeAttribute(const std::string& type, const Parser::name_stack_t&, S32 min_count, S32 max_count, const std::vector* possible_values); - LLXMLNodePtr mElementNode; - LLXMLNodePtr mGrammarNode; - - typedef std::map elements_map_t; - elements_map_t mElementsWritten; -}; - - class LLXSDWriter : public LLInitParam::Parser { LOG_CLASS(LLXSDWriter); @@ -161,6 +139,9 @@ private: LLXMLNodePtr mCurReadNode; // Root of the widget XML sub-tree, for example, "line_editor" LLXMLNodePtr mWriteRootNode; + + typedef std::map out_nodes_t; + out_nodes_t mOutNodes; S32 mLastWriteGeneration; LLXMLNodePtr mLastWrittenChild; S32 mCurReadDepth; @@ -489,7 +470,7 @@ LLChildRegistry::Register::Register(const char* tag, LLWidgetCreator } -typedef boost::function LLPannelClassCreatorFunc; +typedef boost::function LLPanelClassCreatorFunc; // local static instance for registering a particular panel class @@ -498,15 +479,15 @@ class LLRegisterPanelClass { public: // reigister with either the provided builder, or the generic templated builder - void addPanelClass(const std::string& tag,LLPannelClassCreatorFunc func) + void addPanelClass(const std::string& tag,LLPanelClassCreatorFunc func) { - mPannelClassesNames[tag] = func; + mPanelClassesNames[tag] = func; } LLPanel* createPanelClass(const std::string& tag) { - param_name_map_t::iterator iT = mPannelClassesNames.find(tag); - if(iT == mPannelClassesNames.end()) + param_name_map_t::iterator iT = mPanelClassesNames.find(tag); + if(iT == mPanelClassesNames.end()) return 0; return iT->second(); } @@ -518,9 +499,9 @@ public: } private: - typedef std::map< std::string, LLPannelClassCreatorFunc> param_name_map_t; + typedef std::map< std::string, LLPanelClassCreatorFunc> param_name_map_t; - param_name_map_t mPannelClassesNames; + param_name_map_t mPanelClassesNames; }; diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp index 5d43ac11e4..07cc612a0a 100644 --- a/indra/llxml/llxmlnode.cpp +++ b/indra/llxml/llxmlnode.cpp @@ -922,7 +922,7 @@ void LLXMLNode::writeHeaderToFile(LLFILE *out_file) fprintf(out_file, "\n"); } -void LLXMLNode::writeToFile(LLFILE *out_file, const std::string& indent) +void LLXMLNode::writeToFile(LLFILE *out_file, const std::string& indent, bool use_type_decorations) { if (isFullyDefault()) { @@ -931,7 +931,7 @@ void LLXMLNode::writeToFile(LLFILE *out_file, const std::string& indent) } std::ostringstream ostream; - writeToOstream(ostream, indent); + writeToOstream(ostream, indent, use_type_decorations); std::string outstring = ostream.str(); size_t written = fwrite(outstring.c_str(), 1, outstring.length(), out_file); if (written != outstring.length()) @@ -940,7 +940,7 @@ void LLXMLNode::writeToFile(LLFILE *out_file, const std::string& indent) } } -void LLXMLNode::writeToOstream(std::ostream& output_stream, const std::string& indent) +void LLXMLNode::writeToOstream(std::ostream& output_stream, const std::string& indent, bool use_type_decorations) { if (isFullyDefault()) { @@ -956,77 +956,80 @@ void LLXMLNode::writeToOstream(std::ostream& output_stream, const std::string& i // stream the name output_stream << indent << "<" << mName->mString << "\n"; - // ID - if (mID != "") + if (use_type_decorations) { - output_stream << indent << " id=\"" << mID << "\"\n"; - } + // ID + if (mID != "") + { + output_stream << indent << " id=\"" << mID << "\"\n"; + } - // Type - if (!has_default_type) - { - switch (mType) + // Type + if (!has_default_type) { - case TYPE_BOOLEAN: - output_stream << indent << " type=\"boolean\"\n"; - break; - case TYPE_INTEGER: - output_stream << indent << " type=\"integer\"\n"; - break; - case TYPE_FLOAT: - output_stream << indent << " type=\"float\"\n"; - break; - case TYPE_STRING: - output_stream << indent << " type=\"string\"\n"; - break; - case TYPE_UUID: - output_stream << indent << " type=\"uuid\"\n"; - break; - case TYPE_NODEREF: - output_stream << indent << " type=\"noderef\"\n"; - break; - default: - // default on switch(enum) eliminates a warning on linux - break; - }; - } + switch (mType) + { + case TYPE_BOOLEAN: + output_stream << indent << " type=\"boolean\"\n"; + break; + case TYPE_INTEGER: + output_stream << indent << " type=\"integer\"\n"; + break; + case TYPE_FLOAT: + output_stream << indent << " type=\"float\"\n"; + break; + case TYPE_STRING: + output_stream << indent << " type=\"string\"\n"; + break; + case TYPE_UUID: + output_stream << indent << " type=\"uuid\"\n"; + break; + case TYPE_NODEREF: + output_stream << indent << " type=\"noderef\"\n"; + break; + default: + // default on switch(enum) eliminates a warning on linux + break; + }; + } - // Encoding - if (!has_default_encoding) - { - switch (mEncoding) + // Encoding + if (!has_default_encoding) { - case ENCODING_DECIMAL: - output_stream << indent << " encoding=\"decimal\"\n"; - break; - case ENCODING_HEX: - output_stream << indent << " encoding=\"hex\"\n"; - break; - /*case ENCODING_BASE32: - output_stream << indent << " encoding=\"base32\"\n"; - break;*/ - default: - // default on switch(enum) eliminates a warning on linux - break; - }; - } + switch (mEncoding) + { + case ENCODING_DECIMAL: + output_stream << indent << " encoding=\"decimal\"\n"; + break; + case ENCODING_HEX: + output_stream << indent << " encoding=\"hex\"\n"; + break; + /*case ENCODING_BASE32: + output_stream << indent << " encoding=\"base32\"\n"; + break;*/ + default: + // default on switch(enum) eliminates a warning on linux + break; + }; + } - // Precision - if (!has_default_precision && (mType == TYPE_INTEGER || mType == TYPE_FLOAT)) - { - output_stream << indent << " precision=\"" << mPrecision << "\"\n"; - } + // Precision + if (!has_default_precision && (mType == TYPE_INTEGER || mType == TYPE_FLOAT)) + { + output_stream << indent << " precision=\"" << mPrecision << "\"\n"; + } - // Version - if (mVersionMajor > 0 || mVersionMinor > 0) - { - output_stream << indent << " version=\"" << mVersionMajor << "." << mVersionMinor << "\"\n"; - } + // Version + if (mVersionMajor > 0 || mVersionMinor > 0) + { + output_stream << indent << " version=\"" << mVersionMajor << "." << mVersionMinor << "\"\n"; + } - // Array length - if (!has_default_length && mLength > 0) - { - output_stream << indent << " length=\"" << mLength << "\"\n"; + // Array length + if (!has_default_length && mLength > 0) + { + output_stream << indent << " length=\"" << mLength << "\"\n"; + } } { @@ -1039,12 +1042,13 @@ void LLXMLNode::writeToOstream(std::ostream& output_stream, const std::string& i if (child->mDefault.isNull() || child->mDefault->mValue != child->mValue) { std::string attr = child->mName->mString; - if (attr == "id" || - attr == "type" || - attr == "encoding" || - attr == "precision" || - attr == "version" || - attr == "length") + if (use_type_decorations + && (attr == "id" || + attr == "type" || + attr == "encoding" || + attr == "precision" || + attr == "version" || + attr == "length")) { continue; // skip built-in attributes } @@ -1074,7 +1078,7 @@ void LLXMLNode::writeToOstream(std::ostream& output_stream, const std::string& i std::string next_indent = indent + " "; for (LLXMLNode* child = getFirstChild(); child; child = child->getNextSibling()) { - child->writeToOstream(output_stream, next_indent); + child->writeToOstream(output_stream, next_indent, use_type_decorations); } } if (!mValue.empty()) diff --git a/indra/llxml/llxmlnode.h b/indra/llxml/llxmlnode.h index cc9e5cb351..818d774f73 100644 --- a/indra/llxml/llxmlnode.h +++ b/indra/llxml/llxmlnode.h @@ -165,8 +165,8 @@ public: // Write XML to file with one attribute per line. // XML escapes values as they are written. - void writeToFile(LLFILE *out_file, const std::string& indent = std::string()); - void writeToOstream(std::ostream& output_stream, const std::string& indent = std::string()); + void writeToFile(LLFILE *out_file, const std::string& indent = std::string(), bool use_type_decorations=true); + void writeToOstream(std::ostream& output_stream, const std::string& indent = std::string(), bool use_type_decorations=true); // Utility void findName(const std::string& name, LLXMLNodeList &results); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index d06571fb7a..2e29a56e79 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -299,6 +299,7 @@ set(viewer_SOURCE_FILES llpanelgroupnotices.cpp llpanelgrouproles.cpp llpanelinventory.cpp + llpanelimcontrolpanel.cpp llpanelland.cpp llpanellandmarks.cpp llpanellandmedia.cpp @@ -734,6 +735,7 @@ set(viewer_HEADER_FILES llpanelgroupnotices.h llpanelgrouproles.h llpanelinventory.h + llpanelimcontrolpanel.h llpanelland.h llpanellandmarks.h llpanellandmedia.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index cb30cada70..ab9b018150 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -8091,7 +8091,7 @@ Type S32 Value - 1 + 4 UIPreeditMarkerThickness @@ -8135,7 +8135,7 @@ Type S32 Value - 2 + 4 UIPreeditStandoutThickness @@ -8146,7 +8146,7 @@ Type S32 Value - 2 + 2 UIResizeBarHeight diff --git a/indra/newview/llavatariconctrl.h b/indra/newview/llavatariconctrl.h index cb1e9584ba..e34f2ff474 100644 --- a/indra/newview/llavatariconctrl.h +++ b/indra/newview/llavatariconctrl.h @@ -46,9 +46,10 @@ public: Optional avatar_id; Optional draw_tooltip; Params() + : avatar_id("avatar_id"), + draw_tooltip("draw_tooltip", true) { name = "avatar_icon"; - draw_tooltip = TRUE; } }; protected: diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h index 5835a4c6b4..dc73f187a7 100644 --- a/indra/newview/llavatarlistitem.h +++ b/indra/newview/llavatarlistitem.h @@ -57,7 +57,9 @@ public: {}; } buttons; - Params() : avatar_icon("avatar_icon",LLUUID()), user_name("user_name","") + Params() + : avatar_icon("avatar_icon"), + user_name("user_name") {}; }; diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp index d84dd09812..963946e888 100644 --- a/indra/newview/llbottomtray.cpp +++ b/indra/newview/llbottomtray.cpp @@ -32,11 +32,14 @@ #include "llviewerprecompiledheaders.h" // must be first include #include "llbottomtray.h" + #include "llagent.h" #include "llchiclet.h" #include "llfloaterreg.h" #include "llflyoutbutton.h" +#include "llimpanel.h" #include "llkeyboard.h" +#include "lllineeditor.h" #include "llgesturemgr.h" #include "llanimationstates.h" #include "llmultigesture.h" @@ -233,7 +236,13 @@ void LLBottomTray::onChicletClick(LLUICtrl* ctrl) LLIMChiclet* chiclet = dynamic_cast(ctrl); if (chiclet) { + // Until you can type into an IM Window and have a conversation, + // still show the old communicate window LLFloaterReg::showInstance("communicate", chiclet->getSessionId()); + // DISABLED IN VIEWER-2 BRANCH UNTIL FEATURE IS DONE -- James + //// Show after comm window so it is frontmost (and hence will not + //// auto-hide) + //LLIMFloater::show(chiclet->getSessionId()); } } diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h index 330afeb647..08f5cb91d8 100644 --- a/indra/newview/llbottomtray.h +++ b/indra/newview/llbottomtray.h @@ -40,6 +40,7 @@ #include "llcombobox.h" class LLChicletPanel; +class LLLineEditor; class LLNotificationChiclet; class LLTalkButton; diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp index 27ebccfe25..bb31b7f2e8 100644 --- a/indra/newview/llchatitemscontainerctrl.cpp +++ b/indra/newview/llchatitemscontainerctrl.cpp @@ -367,7 +367,7 @@ void LLChatItemsContainerCtrl::updateLayout (S32 width, S32 height) } - //set sizes for first pannels and dragbars + //set sizes for first panels and dragbars for(size_t i=0;igetRect(); diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index 38a7494b5b..bfa4e06d2e 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -37,7 +37,7 @@ #include "llbottomtray.h" #include "llgroupactions.h" #include "lliconctrl.h" -#include "llimpanel.h" +#include "llimpanel.h" // LLFloaterIMPanel #include "llimview.h" #include "llfloatergroupinfo.h" #include "llmenugl.h" @@ -203,6 +203,7 @@ LLIMChiclet::LLIMChiclet(const Params& p) , mSpeakerCtrl(NULL) , mShowSpeaker(p.show_speaker) , mPopupMenu(NULL) +, mDockTongueVisible(false) { LLChicletAvatarIconCtrl::Params avatar_params = p.avatar_icon; mAvatarCtrl = LLUICtrlFactory::create(avatar_params); @@ -227,6 +228,11 @@ LLIMChiclet::~LLIMChiclet() } +void LLIMChiclet::setDockTongueVisible(bool visible) +{ + mDockTongueVisible = visible; +} + void LLIMChiclet::setCounter(S32 counter) { mCounterCtrl->setCounter(counter); @@ -321,6 +327,13 @@ void LLIMChiclet::draw() { LLUICtrl::draw(); gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.0f,0.0f,0.0f,1.f), FALSE); + + if (mDockTongueVisible) + { + LLUIImagePtr flyout_tongue = LLUI::getUIImage("windows/Flyout_Pointer.png"); + // was previously AVATAR_WIDTH-16 and CHICLET_HEIGHT-6 + flyout_tongue->draw( getRect().getWidth()-31, getRect().getHeight()-5); + } } BOOL LLIMChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask) @@ -552,14 +565,6 @@ void LLChicletPanel::onChicletSizeChanged(LLChiclet* ctrl, const LLSD& param) void LLChicletPanel::onChicletClick(LLUICtrl*ctrl,const LLSD¶m) { - LLIMChiclet* chiclet = dynamic_cast(ctrl); - if (chiclet) - { - S32 x, y; - LLRect rect = getRect(); - localPointToScreen(rect.getCenterX(), 0, &x, &y); - LLIMFloater::show(chiclet->getSessionId(), x); - } mCommitSignal(ctrl,param); } @@ -653,7 +658,7 @@ void LLChicletPanel::reshape(S32 width, S32 height, BOOL called_from_parent ) width, height - scroll_button_rect.getHeight())); mScrollArea->setRect(LLRect(scroll_button_rect.getWidth() + SCROLL_BUTTON_PAD, - height + 1, width - scroll_button_rect.getWidth() - SCROLL_BUTTON_PAD, 0)); + height + 7, width - scroll_button_rect.getWidth() - SCROLL_BUTTON_PAD, 0)); trimChiclets(); diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h index e467ec012a..415ae59ca2 100644 --- a/indra/newview/llchiclet.h +++ b/indra/newview/llchiclet.h @@ -34,6 +34,7 @@ #define LL_LLCHICLET_H #include "llavatariconctrl.h" +#include "llbutton.h" #include "llpanel.h" #include "lltextbox.h" #include "lloutputmonitorctrl.h" @@ -266,6 +267,8 @@ public: */ virtual void setShowSpeaker(bool show); + void setDockTongueVisible(bool visible); + /* * Returns voice chat status control visibility. */ @@ -332,6 +335,7 @@ protected: LLMenuGL* mPopupMenu; bool mShowSpeaker; + bool mDockTongueVisible; }; /* diff --git a/indra/newview/llfloaterinventory.cpp b/indra/newview/llfloaterinventory.cpp index d05a32dc88..cf78d7d34f 100644 --- a/indra/newview/llfloaterinventory.cpp +++ b/indra/newview/llfloaterinventory.cpp @@ -42,7 +42,7 @@ #include "llcallingcard.h" #include "llfloaterreg.h" #include "llsdserialize.h" -#include "llsearcheditor.h" +#include "llfiltereditor.h" #include "llspinctrl.h" #include "llui.h" #include "message.h" @@ -530,10 +530,10 @@ BOOL LLFloaterInventory::postBuild() } - mSearchEditor = getChild("inventory search editor"); - if (mSearchEditor) + mFilterEditor = getChild("inventory search editor"); + if (mFilterEditor) { - mSearchEditor->setSearchCallback(boost::bind(&LLFloaterInventory::onSearchEdit, this, _1)); + mFilterEditor->setCommitCallback(boost::bind(&LLFloaterInventory::onFilterEdit, this, _2)); } // *TODO:Get the cost info from the server @@ -598,9 +598,9 @@ void LLFloaterInventory::draw() title << mFilterText; setTitle(title.str()); } - if (mActivePanel && mSearchEditor) + if (mActivePanel && mFilterEditor) { - mSearchEditor->setText(mActivePanel->getFilterSubString()); + mFilterEditor->setText(mActivePanel->getFilterSubString()); } LLFloater::draw(); } @@ -673,9 +673,9 @@ void LLOpenFoldersWithSelection::doFolder(LLFolderViewFolder* folder) void LLFloaterInventory::startSearch() { // this forces focus to line editor portion of search editor - if (mSearchEditor) + if (mFilterEditor) { - mSearchEditor->focusFirstItem(TRUE); + mFilterEditor->focusFirstItem(TRUE); } } @@ -715,8 +715,8 @@ BOOL LLFloaterInventory::handleKeyHere(KEY key, MASK mask) if (root_folder) { // first check for user accepting current search results - if (mSearchEditor - && mSearchEditor->hasFocus() + if (mFilterEditor + && mFilterEditor->hasFocus() && (key == KEY_RETURN || key == KEY_DOWN) && mask == MASK_NONE) @@ -966,7 +966,7 @@ void LLFloaterInventory::onClearSearch() } } -void LLFloaterInventory::onSearchEdit(const std::string& search_string ) +void LLFloaterInventory::onFilterEdit(const std::string& search_string ) { if (search_string == "") { diff --git a/indra/newview/llfloaterinventory.h b/indra/newview/llfloaterinventory.h index cd60407507..35ac1ab380 100644 --- a/indra/newview/llfloaterinventory.h +++ b/indra/newview/llfloaterinventory.h @@ -64,7 +64,7 @@ class LLScrollContainer; class LLTextBox; class LLIconCtrl; class LLSaveFolderState; -class LLSearchEditor; +class LLFilterEditor; class LLTabContainer; class LLInventoryPanel : public LLPanel @@ -267,7 +267,7 @@ public: void onClearSearch(); static void onFoldersByName(void *user_data); static BOOL checkFoldersByName(void *user_data); - void onSearchEdit(const std::string& search_string ); + void onFilterEdit(const std::string& search_string ); static BOOL incrementalFind(LLFolderViewItem* first_item, const char *find_text, BOOL backward); void onFilterSelected(); @@ -291,7 +291,7 @@ public: LLFloaterInventoryFinder* getFinder() { return (LLFloaterInventoryFinder*)mFinderHandle.get(); } protected: - LLSearchEditor* mSearchEditor; + LLFilterEditor* mFilterEditor; LLTabContainer* mFilterTabs; LLHandle mFinderHandle; LLInventoryPanel* mActivePanel; diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 08a042707d..149df61b35 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -1490,26 +1490,26 @@ void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, vo if (is_group_owned) { - item_params.cells.add().type("icon").value(self->mIconGroup->getName()).column("type"); - item_params.cells.add().value(OWNER_GROUP).font(FONT).column("online_status"); + item_params.columns.add().type("icon").value(self->mIconGroup->getName()).column("type"); + item_params.columns.add().value(OWNER_GROUP).font(FONT).column("online_status"); } else if (is_online) { - item_params.cells.add().type("icon").value(self->mIconAvatarOnline->getName()).column("type"); - item_params.cells.add().value(OWNER_ONLINE).font(FONT).column("online_status"); + item_params.columns.add().type("icon").value(self->mIconAvatarOnline->getName()).column("type"); + item_params.columns.add().value(OWNER_ONLINE).font(FONT).column("online_status"); } else // offline { - item_params.cells.add().type("icon").value(self->mIconAvatarOffline->getName()).column("type"); - item_params.cells.add().value(OWNER_OFFLINE).font(FONT).column("online_status"); + item_params.columns.add().type("icon").value(self->mIconAvatarOffline->getName()).column("type"); + item_params.columns.add().value(OWNER_OFFLINE).font(FONT).column("online_status"); } // Placeholder for name. - item_params.cells.add().font(FONT).column("name"); + item_params.columns.add().font(FONT).column("name"); object_count_str = llformat("%d", object_count); - item_params.cells.add().value(object_count_str).font(FONT).column("count"); - item_params.cells.add().value(formatted_time((time_t)most_recent_time)).font(FONT).column("mostrecent"); + item_params.columns.add().value(object_count_str).font(FONT).column("count"); + item_params.columns.add().value(formatted_time((time_t)most_recent_time)).font(FONT).column("mostrecent"); self->mOwnerList->addRow(item_params); diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp index 41e9ee3ccd..4870494b20 100644 --- a/indra/newview/llfloateruipreview.cpp +++ b/indra/newview/llfloateruipreview.cpp @@ -57,6 +57,7 @@ #include "lldraghandle.h" #include "lllayoutstack.h" #include "llviewermenu.h" +#include "llrngwriter.h" // Boost (for linux/unix command-line execv) #include @@ -354,6 +355,7 @@ void LLFloaterUIPreview::onLanguageComboSelect(LLUICtrl* ctrl) void LLFloaterUIPreview::onClickExportSchema() { + gViewerWindow->setCursor(UI_CURSOR_WAIT); std::string template_path = gDirUtilp->getExpandedFilename(LL_PATH_DEFAULT_SKIN, "xui", "schema"); typedef LLWidgetTypeRegistry::Registrar::registry_map_t::const_iterator registry_it; @@ -373,10 +375,12 @@ void LLFloaterUIPreview::onClickExportSchema() LLFILE* rng_file = LLFile::fopen(file_name.c_str(), "w"); { LLXMLNode::writeHeaderToFile(rng_file); - root_nodep->writeToFile(rng_file); + const bool use_type_decorations = false; + root_nodep->writeToFile(rng_file, std::string(), use_type_decorations); } fclose(rng_file); } + gViewerWindow->setCursor(UI_CURSOR_ARROW); } @@ -625,7 +629,8 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save) std::string full_filename = append_new_to_xml_filename(path); LLFILE* floater_temp = LLFile::fopen(full_filename.c_str(), "w"); LLXMLNode::writeHeaderToFile(floater_temp); - floater_write->writeToFile(floater_temp); + const bool use_type_decorations = false; + floater_write->writeToFile(floater_temp, std::string(), use_type_decorations); fclose(floater_temp); } } @@ -647,7 +652,8 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save) std::string full_filename = append_new_to_xml_filename(path); LLFILE* menu_temp = LLFile::fopen(full_filename.c_str(), "w"); LLXMLNode::writeHeaderToFile(menu_temp); - menu_write->writeToFile(menu_temp); + const bool use_type_decorations = false; + menu_write->writeToFile(menu_temp, std::string(), use_type_decorations); fclose(menu_temp); } @@ -671,7 +677,8 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save) std::string full_filename = append_new_to_xml_filename(path); LLFILE* panel_temp = LLFile::fopen(full_filename.c_str(), "w"); LLXMLNode::writeHeaderToFile(panel_temp); - panel_write->writeToFile(panel_temp); + const bool use_type_decorations = false; + panel_write->writeToFile(panel_temp, std::string(), use_type_decorations); fclose(panel_temp); } } diff --git a/indra/newview/llfloateruipreview.h b/indra/newview/llfloateruipreview.h index 1307d60689..eca8c0a141 100644 --- a/indra/newview/llfloateruipreview.h +++ b/indra/newview/llfloateruipreview.h @@ -49,6 +49,7 @@ class LLColor; class LLScrollListCtrl; class LLComboBox; class LLButton; +class LLLineEditor; class LLXmlTreeNode; class LLFloaterUIPreview; class LLFadeEventTimer; diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h index 5c1760ce22..d52079fc06 100644 --- a/indra/newview/llfloaterworldmap.h +++ b/indra/newview/llfloaterworldmap.h @@ -49,6 +49,7 @@ class LLFriendObserver; class LLInventoryModel; class LLInventoryObserver; class LLItemInfo; +class LLLineEditor; class LLTabContainer; class LLFloaterWorldMap : public LLFloater diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp index 43f3ea8d8f..a6a8da2a76 100644 --- a/indra/newview/llfolderviewitem.cpp +++ b/indra/newview/llfolderviewitem.cpp @@ -81,8 +81,9 @@ void LLFolderViewItem::cleanupClass() // NOTE: Optimize this, we call it a *lot* when opening a large inventory LLFolderViewItem::Params::Params() -: folder_arrow_image("", LLUI::getUIImage("folder_arrow.tga")), - selection_image("", LLUI::getUIImage("rounded_square.tga")) +: icon("icon"), + folder_arrow_image("folder_arrow_image", LLUI::getUIImage("folder_arrow.tga")), + selection_image("selection_image", LLUI::getUIImage("rounded_square.tga")) { mouse_opaque(true); follows.flags(FOLLOWS_LEFT|FOLLOWS_TOP|FOLLOWS_RIGHT); diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index 5b4f711099..248a8dbc4c 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -45,8 +45,10 @@ #include "llagent.h" #include "llbutton.h" +#include "llbottomtray.h" #include "llcallingcard.h" #include "llchat.h" +#include "llchiclet.h" #include "llconsole.h" #include "llfloater.h" #include "llfloatercall.h" @@ -57,9 +59,12 @@ #include "llinventorymodel.h" #include "llfloaterinventory.h" #include "llfloaterchat.h" +#include "lliconctrl.h" +#include "llimview.h" // for LLIMModel to get other avatar id in chat #include "llkeyboard.h" #include "lllineeditor.h" #include "llnotify.h" +#include "llpanelimcontrolpanel.h" #include "llrecentpeople.h" #include "llresmgr.h" #include "lltrans.h" @@ -2040,7 +2045,7 @@ bool LLFloaterIMPanel::onConfirmForceCloseError(const LLSD& notification, const } return false; } - + std::map LLIMFloater::sIMFloaterMap; @@ -2048,23 +2053,183 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id, const std::string title, EInstantMessage dialog) : mSessionID(session_id), - mIndex(0) + mLastMessageIndex(-1), + mDialog(dialog) { LLUICtrlFactory::getInstance()->buildFloater(this, "floater_im_session.xml"); sIMFloaterMap[mSessionID] = this; + LLPanelIMControlPanel* im_control_panel = getChild("panel_im_control_panel"); + + LLIMModel::LLIMSession* session = get_if_there(LLIMModel::instance().sSessionsMap, session_id, (LLIMModel::LLIMSession*)NULL); + if(session) + { + mOtherParticipantUUID = session->mOtherParticipantID; + im_control_panel->setAvatarId(session->mOtherParticipantID); + } + + LLButton* slide_left = getChild("slide_left_btn"); + slide_left->setVisible(im_control_panel->getVisible()); + slide_left->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this)); + + LLButton* slide_right = getChild("slide_right_btn"); + slide_right->setVisible(!im_control_panel->getVisible()); + slide_right->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this)); + setTitle(title); + setDocked(true); + + mInputEditor = getChild("chat_editor"); + + + mInputEditor->setMaxTextLength(1023); + // enable line history support for instant message bar + mInputEditor->setEnableLineHistory(TRUE); + + mInputEditor->setFocusReceivedCallback( onInputEditorFocusReceived, this ); + mInputEditor->setFocusLostCallback( onInputEditorFocusLost, this ); + mInputEditor->setKeystrokeCallback( onInputEditorKeystroke, this ); + mInputEditor->setCommitOnFocusLost( FALSE ); + mInputEditor->setRevertOnEsc( FALSE ); + mInputEditor->setReplaceNewlinesWithSpaces( FALSE ); + + childSetCommitCallback("chat_editor", onSendMsg, this); +} + +/* static */ +void LLIMFloater::newIMCallback(const LLSD& data){ + + if (data["num_unread"].asInteger() > 0) + { + LLUUID session_id = data["session_id"].asUUID(); + + LLIMFloater* floater = get_if_there(sIMFloaterMap, session_id, (LLIMFloater*)NULL); + + if (floater == NULL) + { + llwarns << "new_im_callback for non-existent session_id " << session_id << llendl; + return; + } + + // update if visible, otherwise will be updated when opened + if (floater->getVisible()) + { + floater->updateMessages(); + } + } +} + +void LLIMFloater::onSendMsg( LLUICtrl* ctrl, void* userdata ) +{ + LLIMFloater* self = (LLIMFloater*) userdata; + self->sendMsg(); } +void LLIMFloater::sendMsg() +{ + if (!gAgent.isGodlike() + && (mDialog == IM_NOTHING_SPECIAL) + && mOtherParticipantUUID.isNull()) + { + llinfos << "Cannot send IM to everyone unless you're a god." << llendl; + return; + } + + if (mInputEditor) + { + LLWString text = mInputEditor->getConvertedText(); + if(!text.empty()) + { + // Truncate and convert to UTF8 for transport + std::string utf8_text = wstring_to_utf8str(text); + utf8_text = utf8str_truncate(utf8_text, MAX_MSG_BUF_SIZE - 1); + + LLIMModel::sendMessage(utf8_text, + mSessionID, + mOtherParticipantUUID, + mDialog); + + mInputEditor->setText(LLStringUtil::null); + + updateMessages(); + } + } +} + + + LLIMFloater::~LLIMFloater() { sIMFloaterMap.erase(mSessionID); } +//virtual +BOOL LLIMFloater::postBuild() +{ + mHistoryEditor = getChild("im_text", true, false); + mChiclet = LLBottomTray::getInstance()->getChicletPanel()->findChiclet(mSessionID); + + if (!mChiclet) + { + llwarns << "No chiclet found for the IMFloter" << llendl; + } + setDocked(false); + return TRUE; +} + +const U32 UNDOCK_LEAP_HEIGHT = 12; +const U32 DOCK_ICON_HEIGHT = 6; -void LLIMFloater::show(const LLUUID& session_id, S32 center_x) +//virtual +void LLIMFloater::onFocusLost() { + // spec says close if docked to bottom tray and user has clicked away + // (hence we are no longer focused) + if (isDocked()) + { + // app not quitting + closeFloater(false); + } +} + +//virtual +void LLIMFloater::setDocked(bool docked, bool pop_on_undock) +{ + LLFloater::setDocked(docked); + mChiclet->setDockTongueVisible(docked); + if (docked) + { + S32 x, y; + mChiclet->localPointToScreen((mChiclet->getRect().getWidth())/2, 0, &x, &y); + translate(x - getRect().getCenterX(), DOCK_ICON_HEIGHT - getRect().mBottom); + } + else if (pop_on_undock) + { + // visually pop up a little bit to emphasize the undocking + translate(0, UNDOCK_LEAP_HEIGHT); + } +} + + +void LLIMFloater::onClose(bool app_quitting) +{ + mChiclet->setDockTongueVisible(false); + LLFloater::onClose(app_quitting); +} + +void LLIMFloater::onSlide() +{ + LLPanel* im_control_panel = getChild("panel_im_control_panel"); + im_control_panel->setVisible(!im_control_panel->getVisible()); + + getChild("slide_left_btn")->setVisible(im_control_panel->getVisible()); + getChild("slide_right_btn")->setVisible(!im_control_panel->getVisible()); +} + +//static +LLIMFloater* LLIMFloater::show(const LLUUID& session_id) +{ LLIMFloater* floater = get_if_there(sIMFloaterMap, session_id, (LLIMFloater*)NULL); if (floater == NULL) @@ -2078,28 +2243,25 @@ void LLIMFloater::show(const LLUUID& session_id, S32 center_x) { LLIMFloater* floater = (*iter).second; floater->setVisible(false); + floater->mChiclet->setDockTongueVisible(false); + } - //floater->setVisibleAndFrontmost(true); + floater->setVisibleAndFrontmost(true); - floater->updateMessages(session_id); - - floater->translate(center_x - floater->getRect().getCenterX(), gFloaterView->getRect().mBottom - floater->getRect().mBottom); + if (floater->isDocked()) + { + floater->mChiclet->setDockTongueVisible(true); + } + floater->updateMessages(); + return floater; } -void LLIMFloater::updateMessages(const LLUUID& session_id) +void LLIMFloater::updateMessages() { - LLTextEditor* text_editor = getChild("im_text", true, false); - - if (!text_editor) - { - llwarns << "Text editor not found! " << llendl; - return; - } - - std::list messages = LLIMModel::instance().getMessages(mSessionID, mIndex); + std::list messages = LLIMModel::instance().getMessages(mSessionID, mLastMessageIndex+1); if (messages.size()) { @@ -2112,10 +2274,45 @@ void LLIMFloater::updateMessages(const LLUUID& session_id) message << msg["from"].asString() << " : " << msg["time"].asString() << "\n " << msg["message"].asString() << "\n"; - mIndex = msg["index"].asInteger(); + mLastMessageIndex = msg["index"].asInteger(); } - text_editor->setText(message.str()); + mHistoryEditor->appendText(message.str(), false, false); + mHistoryEditor->setCursorAndScrollToEnd(); } } +// static +void LLIMFloater::onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata ) +{ + LLIMFloater* self= (LLIMFloater*) userdata; + self->mHistoryEditor->setCursorAndScrollToEnd(); +} + +// static +void LLIMFloater::onInputEditorFocusLost(LLFocusableElement* caller, void* userdata) +{ + LLIMFloater* self = (LLIMFloater*) userdata; + self->setTyping(FALSE); +} + +// static +void LLIMFloater::onInputEditorKeystroke(LLLineEditor* caller, void* userdata) +{ + LLIMFloater* self = (LLIMFloater*)userdata; + std::string text = self->mInputEditor->getText(); + if (!text.empty()) + { + self->setTyping(TRUE); + } + else + { + // Deleting all text counts as stopping typing. + self->setTyping(FALSE); + } +} + +//just a stub for now +void LLIMFloater::setTyping(BOOL typing) +{ +} diff --git a/indra/newview/llimpanel.h b/indra/newview/llimpanel.h index 88f21864b5..e6bde5c93a 100644 --- a/indra/newview/llimpanel.h +++ b/indra/newview/llimpanel.h @@ -47,6 +47,7 @@ class LLInventoryItem; class LLInventoryCategory; class LLIMSpeakerMgr; class LLPanelActiveSpeakers; +class LLIMChiclet; class LLVoiceChannel : public LLVoiceClientStatusObserver { @@ -359,6 +360,8 @@ private: }; +// Individual IM window that appears at the bottom of the screen, +// optionally "docked" to the bottom tray. class LLIMFloater : public LLFloater { public: @@ -367,14 +370,49 @@ public: EInstantMessage dialog); virtual ~LLIMFloater(); + + // LLView overrides + /*virtual*/ BOOL postBuild(); + + // Floater should close when user clicks away to other UI area, + // hence causing focus loss. + /*virtual*/ void onFocusLost(); + + // LLFloater overrides + /*virtual*/ void setDocked(bool docked, bool pop_on_undock = true); + + static LLIMFloater* show(const LLUUID& session_id); + void onClose(bool app_quitting); - static void show(const LLUUID& session_id, S32 center_x); - void updateMessages(const LLUUID& session_id); + // get new messages from LLIMModel + void updateMessages(); + static void onSendMsg( LLUICtrl*, void*); + void sendMsg(); + // callback for LLIMModel on new messages + // route to specific floater if it is visible + static void newIMCallback(const LLSD& data); + static std::map sIMFloaterMap; + + +private: + + static void onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata ); + static void onInputEditorFocusLost(LLFocusableElement* caller, void* userdata); + static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata); + void setTyping(BOOL typing); + void onSlide(); + LLUUID mSessionID; - U32 mIndex; + S32 mLastMessageIndex; + EInstantMessage mDialog; + LLIMChiclet* mChiclet; + LLUUID mOtherParticipantUUID; + LLViewerTextEditor* mHistoryEditor; + LLLineEditor* mInputEditor; + }; diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 38335fe68f..0505baac41 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -113,14 +113,16 @@ void toast_callback(const LLSD& msg){ LLIMModel::LLIMModel() { addChangedCallback(toast_callback); + addChangedCallback(LLIMFloater::newIMCallback); } void LLIMModel::testMessages() { - static LLUUID bot1_id, bot1_session_id; - if (bot1_id.isNull()) bot1_id.generate(); - std::string from = "Bot1 TestLinden"; + LLUUID bot1_id("d0426ec6-6535-4c11-a5d9-526bb0c654d9"); + LLUUID bot1_session_id; + std::string from = "IM Tester"; + bot1_session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, bot1_id); newSession(bot1_session_id, from, IM_NOTHING_SPECIAL, bot1_id); addMessage(bot1_session_id, from, "Test Message: Hi from testerbot land!"); @@ -158,7 +160,7 @@ bool LLIMModel::newSession(LLUUID session_id, std::string name, EInstantMessage } -std::list LLIMModel::getMessages(LLUUID session_id, int index) +std::list LLIMModel::getMessages(LLUUID session_id, int start_index) { std::list return_list; @@ -170,7 +172,7 @@ std::list LLIMModel::getMessages(LLUUID session_id, int index) return return_list; } - int i = session->mMsgs.size() - index; + int i = session->mMsgs.size() - start_index; for (std::list::iterator iter = session->mMsgs.begin(); iter != session->mMsgs.end() && i > 0; diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index 6a354dfe92..b3b821f2ac 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -53,11 +53,11 @@ public: struct LLIMSession { LLIMSession(std::string name, EInstantMessage type, LLUUID other_participant_id) - :mName(name), mType(type), mNumUnread(0), mOtherPraticipantID(other_participant_id) {} + :mName(name), mType(type), mNumUnread(0), mOtherParticipantID(other_participant_id) {} std::string mName; EInstantMessage mType; - LLUUID mOtherPraticipantID; + LLUUID mOtherParticipantID; S32 mNumUnread; std::list mMsgs; }; @@ -70,7 +70,7 @@ public: boost::signals2::connection addChangedCallback( boost::function cb ); bool newSession(LLUUID session_id, std::string name, EInstantMessage type, LLUUID other_participant_id); - std::list getMessages(LLUUID session_id, int index = 0); + std::list getMessages(LLUUID session_id, int start_index = 0); bool addMessage(LLUUID session_id, std::string from, std::string utf8_text); bool addToHistory(LLUUID session_id, std::string from, std::string utf8_text); //used to get the name of the session, for use as the title diff --git a/indra/newview/llmenucommands.cpp b/indra/newview/llmenucommands.cpp index 0c652621f4..cfcb331912 100644 --- a/indra/newview/llmenucommands.cpp +++ b/indra/newview/llmenucommands.cpp @@ -51,6 +51,7 @@ #include "llfloaterworldmap.h" #include "llgivemoney.h" #include "llfloaterinventory.h" +#include "lllineeditor.h" #include "llnotify.h" #include "llstatusbar.h" #include "llimview.h" diff --git a/indra/newview/llnameeditor.h b/indra/newview/llnameeditor.h index f9cabb5831..99e03a1166 100644 --- a/indra/newview/llnameeditor.h +++ b/indra/newview/llnameeditor.h @@ -50,6 +50,11 @@ public: { Optional is_group; Optional name_id; + + Params() + : is_group("is_group"), + name_id("name_id") + {} }; protected: diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp index d7066cb140..ffc3b2f37a 100644 --- a/indra/newview/llnamelistctrl.cpp +++ b/indra/newview/llnamelistctrl.cpp @@ -169,7 +169,7 @@ LLScrollListItem* LLNameListCtrl::addRow(const LLNameListCtrl::NameItem& name_it if (!item) return NULL; // use supplied name by default - std::string fullname = name_item.display_name; + std::string fullname = name_item.name; switch(name_item.target) { case GROUP: diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h index 6692d4cff9..80feaea881 100644 --- a/indra/newview/llnamelistctrl.h +++ b/indra/newview/llnamelistctrl.h @@ -57,11 +57,11 @@ public: struct NameItem : public LLInitParam::Block { - Optional display_name; + Optional name; Optional target; NameItem() - : display_name("name"), + : name("name"), target("target", INDIVIDUAL) {} }; diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index fbeff2d628..c0bddd101e 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -45,6 +45,7 @@ #include "lllocationhistory.h" #include "lllocationinputctrl.h" #include "llteleporthistory.h" +#include "llsearcheditor.h" #include "llslurl.h" #include "llurlsimstring.h" #include "llviewerinventory.h" @@ -204,12 +205,10 @@ BOOL LLNavigationBar::postBuild() mBtnHelp = getChild("help_btn"); mCmbLocation= getChild("location_combo"); - mLeSearch = getChild("search_input"); - - LLButton* search_btn = getChild("search_btn"); + mLeSearch = getChild("search_input"); if (!mBtnBack || !mBtnForward || !mBtnHome || !mBtnHelp || - !mCmbLocation || !mLeSearch || !search_btn) + !mCmbLocation || !mLeSearch) { llwarns << "Malformed navigation bar" << llendl; return FALSE; @@ -229,7 +228,6 @@ BOOL LLNavigationBar::postBuild() mCmbLocation->setSelectionCallback(boost::bind(&LLNavigationBar::onLocationSelection, this)); mLeSearch->setCommitCallback(boost::bind(&LLNavigationBar::onSearchCommit, this)); - search_btn->setClickedCallback(boost::bind(&LLNavigationBar::onSearchCommit, this)); // Load the location field context menu mLocationContextMenu = LLUICtrlFactory::getInstance()->createFromFile("menu_navbar.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); @@ -306,7 +304,7 @@ void LLNavigationBar::onHelpButtonClicked() void LLNavigationBar::onSearchCommit() { - invokeSearch(mLeSearch->getText()); + invokeSearch(mLeSearch->getValue().asString()); } void LLNavigationBar::onTeleportHistoryMenuItemClicked(const LLSD& userdata) diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h index 846040e506..a82dfc73ff 100644 --- a/indra/newview/llnavigationbar.h +++ b/indra/newview/llnavigationbar.h @@ -40,7 +40,7 @@ extern S32 NAVIGATION_BAR_HEIGHT; class LLButton; class LLLocationInputCtrl; class LLMenuGL; -class LLLineEditor; +class LLSearchEditor; /** * Web browser-like navigation bar. @@ -97,7 +97,7 @@ private: LLButton* mBtnForward; LLButton* mBtnHome; LLButton* mBtnHelp; - LLLineEditor* mLeSearch; + LLSearchEditor* mLeSearch; LLLocationInputCtrl* mCmbLocation; bool mPurgeTPHistoryItems; }; diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp index 340cb8187d..955f50caf5 100644 --- a/indra/newview/lloutputmonitorctrl.cpp +++ b/indra/newview/lloutputmonitorctrl.cpp @@ -52,7 +52,8 @@ LLColor4 LLOutputMonitorCtrl::sColorBound; //F32 LLOutputMonitorCtrl::sRectHeightRatio = 0.f; LLOutputMonitorCtrl::Params::Params() -: image_mute("image_mute"), +: draw_border("draw_border"), + image_mute("image_mute"), image_off("image_off"), image_on("image_on"), image_level_1("image_level_1"), diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index 868d4d9200..bf6ecd6bf4 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -61,6 +61,7 @@ public: { Optional agent_id; Params() + : agent_id("agent_id") { mouse_opaque(false); follows.flags(FOLLOWS_ALL); diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp new file mode 100644 index 0000000000..45fe625a13 --- /dev/null +++ b/indra/newview/llpanelimcontrolpanel.cpp @@ -0,0 +1,87 @@ +/** + * @file llpanelavatar.cpp + * @brief LLPanelAvatar and related class implementations + * + * $LicenseInfo:firstyear=2004&license=viewergpl$ + * + * Copyright (c) 2004-2009, 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 "llpanelimcontrolpanel.h" + +#include "llavataractions.h" +#include "llavatariconctrl.h" +#include "llbutton.h" + +static LLRegisterPanelClassWrapper t_im_control_panel("panel_im_control_panel"); + +LLPanelIMControlPanel::LLPanelIMControlPanel() +: LLPanel() +{ +} + +LLPanelIMControlPanel::~LLPanelIMControlPanel() +{ +} + +BOOL LLPanelIMControlPanel::postBuild() +{ + childSetAction("view_profile_btn", boost::bind(&LLPanelIMControlPanel::onViewProfileButtonClicked, this)); + childSetAction("add_friend_btn", boost::bind(&LLPanelIMControlPanel::onAddFriendButtonClicked, this)); + childSetAction("call_btn", boost::bind(&LLPanelIMControlPanel::onCallButtonClicked, this)); + childSetAction("share_btn", boost::bind(&LLPanelIMControlPanel::onShareButtonClicked, this)); + + return TRUE; +} + +void LLPanelIMControlPanel::onViewProfileButtonClicked() +{ + LLAvatarActions::showProfile(getChild("avatar_icon")->getAvatarId()); +} + +void LLPanelIMControlPanel::onAddFriendButtonClicked() +{ + LLAvatarIconCtrl* avatar_icon = getChild("avatar_icon"); + std::string full_name = avatar_icon->getFirstName() + " " + avatar_icon->getLastName(); + LLAvatarActions::requestFriendshipDialog(avatar_icon->getAvatarId(), full_name); +} + +void LLPanelIMControlPanel::onCallButtonClicked() +{ + // *TODO: Implement +} + +void LLPanelIMControlPanel::onShareButtonClicked() +{ + // *TODO: Implement +} + +void LLPanelIMControlPanel::setAvatarId(const LLUUID& avatar_id) +{ + getChild("avatar_icon")->setValue(avatar_id); +} diff --git a/indra/newview/llpanelimcontrolpanel.h b/indra/newview/llpanelimcontrolpanel.h new file mode 100644 index 0000000000..be3b2d3130 --- /dev/null +++ b/indra/newview/llpanelimcontrolpanel.h @@ -0,0 +1,55 @@ +/** + * @file llpanelimcontrolpanel.h + * @brief LLPanelIMControlPanel and related class definitions + * + * $LicenseInfo:firstyear=2004&license=viewergpl$ + * + * Copyright (c) 2004-2009, 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$ + */ + +#ifndef LL_LLPANELIMCONTROLPANEL_H +#define LL_LLPANELIMCONTROLPANEL_H + +#include "llpanel.h" + +class LLPanelIMControlPanel : public LLPanel +{ +public: + LLPanelIMControlPanel(); + ~LLPanelIMControlPanel(); + + BOOL postBuild(); + + void setAvatarId(const LLUUID& avatar_id); + +private: + void onViewProfileButtonClicked(); + void onAddFriendButtonClicked(); + void onCallButtonClicked(); + void onShareButtonClicked(); +}; + +#endif // LL_LLPANELIMCONTROLPANEL_H diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index 453183ad74..0cbf10f7c2 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -33,6 +33,7 @@ #include "llpanellandmarks.h" +#include "llbutton.h" #include "llfloaterreg.h" #include "lllandmark.h" diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h index 540f938053..83a31eecda 100644 --- a/indra/newview/llpanellogin.h +++ b/indra/newview/llpanellogin.h @@ -37,6 +37,7 @@ #include "llpointer.h" // LLPointer<> #include "llwebbrowserctrl.h" // LLWebBrowserCtrlObserver +class LLLineEditor; class LLUIImage; diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index d2879a675f..d947003109 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -35,7 +35,7 @@ // libs #include "llfloaterreg.h" #include "llmenugl.h" -#include "llsearcheditor.h" +#include "llfiltereditor.h" #include "lltabcontainer.h" #include "lluictrlfactory.h" @@ -306,7 +306,7 @@ public: LLPanelPeople::LLPanelPeople() : LLPanel(), mFilterSubString(LLStringUtil::null), - mSearchEditor(NULL), + mFilterEditor(NULL), mTabContainer(NULL), mFriendList(NULL), mNearbyList(NULL), @@ -330,8 +330,8 @@ LLPanelPeople::~LLPanelPeople() BOOL LLPanelPeople::postBuild() { - mSearchEditor = getChild("filter_input"); - mSearchEditor->setSearchCallback(boost::bind(&LLPanelPeople::onSearchEdit, this, _1)); + mFilterEditor = getChild("filter_input"); + mFilterEditor->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2)); mTabContainer = getChild("tabs"); mTabContainer->setCommitCallback(boost::bind(&LLPanelPeople::onTabSelected, this, _2)); @@ -609,7 +609,7 @@ void LLPanelPeople::reSelectedCurrentTab() mTabContainer->selectTab(mTabContainer->getCurrentPanelIndex()); } -void LLPanelPeople::onSearchEdit(const std::string& search_string) +void LLPanelPeople::onFilterEdit(const std::string& search_string) { if (mFilterSubString == search_string) return; @@ -618,7 +618,7 @@ void LLPanelPeople::onSearchEdit(const std::string& search_string) LLStringUtil::toUpper(mFilterSubString); LLStringUtil::trimHead(mFilterSubString); - mSearchEditor->setText(mFilterSubString); + mFilterEditor->setText(mFilterSubString); // Apply new filter to all tabs. filterNearbyList(); diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h index 1131790106..6c3b5e0664 100644 --- a/indra/newview/llpanelpeople.h +++ b/indra/newview/llpanelpeople.h @@ -37,7 +37,7 @@ #include "llcallingcard.h" // for avatar tracker -class LLSearchEditor; +class LLFilterEditor; class LLTabContainer; class LLAvatarList; class LLGroupList; @@ -77,7 +77,7 @@ private: void reSelectedCurrentTab(); // UI callbacks - void onSearchEdit(const std::string& search_string); + void onFilterEdit(const std::string& search_string); void onTabSelected(const LLSD& param); void onViewProfileButtonClicked(); void onAddFriendButtonClicked(); @@ -104,7 +104,7 @@ private: const std::vector& ids, void*); - LLSearchEditor* mSearchEditor; + LLFilterEditor* mFilterEditor; LLTabContainer* mTabContainer; LLAvatarList* mFriendList; LLAvatarList* mNearbyList; diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp index 961c54d667..cda1a9e7e7 100644 --- a/indra/newview/llpanelpick.cpp +++ b/indra/newview/llpanelpick.cpp @@ -38,6 +38,7 @@ #include "llpanel.h" #include "message.h" #include "llagent.h" +#include "llbutton.h" #include "llparcel.h" #include "llviewerparcelmgr.h" #include "lltexturectrl.h" diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index c162a9ba33..57c633dd74 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -32,7 +32,7 @@ #include "llviewerprecompiledheaders.h" #include "llfloaterreg.h" -#include "llsearcheditor.h" +#include "llfiltereditor.h" #include "lltabcontainer.h" #include "lluictrlfactory.h" @@ -67,7 +67,7 @@ LLPanelPlaces::LLPanelPlaces() : LLPanel(), mFilterSubString(LLStringUtil::null), mActivePanel(NULL), - mSearchEditor(NULL), + mFilterEditor(NULL), mPlaceInfo(NULL) { gInventory.addObserver(this); @@ -92,10 +92,10 @@ BOOL LLPanelPlaces::postBuild() mTabContainer->setCommitCallback(boost::bind(&LLPanelPlaces::onTabSelected, this)); } - mSearchEditor = getChild("Filter"); - if (mSearchEditor) + mFilterEditor = getChild("Filter"); + if (mFilterEditor) { - mSearchEditor->setSearchCallback(boost::bind(&LLPanelPlaces::onSearchEdit, this, _1)); + mFilterEditor->setCommitCallback(boost::bind(&LLPanelPlaces::onFilterEdit, this, _2)); } mPlaceInfo = getChild("panel_place_info", TRUE, FALSE); @@ -187,7 +187,7 @@ void LLPanelPlaces::onOpen(const LLSD& key) } } -void LLPanelPlaces::onSearchEdit(const std::string& search_string) +void LLPanelPlaces::onFilterEdit(const std::string& search_string) { if (mFilterSubString != search_string) { @@ -196,7 +196,7 @@ void LLPanelPlaces::onSearchEdit(const std::string& search_string) LLStringUtil::toUpper(mFilterSubString); LLStringUtil::trimHead(mFilterSubString); - mSearchEditor->setText(mFilterSubString); + mFilterEditor->setText(mFilterSubString); mActivePanel->onSearchEdit(mFilterSubString); } @@ -208,7 +208,7 @@ void LLPanelPlaces::onTabSelected() if (!mActivePanel) return; - onSearchEdit(mFilterSubString); + onFilterEdit(mFilterSubString); mActivePanel->updateVerbs(); } @@ -274,7 +274,7 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible) return; mPlaceInfo->setVisible(visible); - mSearchEditor->setVisible(!visible); + mFilterEditor->setVisible(!visible); mTabContainer->setVisible(!visible); // Enable overflow button only for the information about agent's current location. diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h index 6fbb7562c9..e2ba4f39cd 100644 --- a/indra/newview/llpanelplaces.h +++ b/indra/newview/llpanelplaces.h @@ -42,7 +42,7 @@ #include "llpanelplaceinfo.h" class LLPanelPlacesTab; -class LLSearchEditor; +class LLFilterEditor; class LLTabContainer; class LLPanelPlaces : public LLPanel, LLInventoryObserver @@ -55,7 +55,7 @@ public: /*virtual*/ void changed(U32 mask); /*virtual*/ void onOpen(const LLSD& key); - void onSearchEdit(const std::string& search_string); + void onFilterEdit(const std::string& search_string); void onTabSelected(); //void onAddLandmarkButtonClicked(); //void onCopySLURLButtonClicked(); @@ -68,7 +68,7 @@ public: void onAgentParcelChange(); private: - LLSearchEditor* mSearchEditor; + LLFilterEditor* mFilterEditor; LLPanelPlacesTab* mActivePanel; LLTabContainer* mTabContainer; LLPanelPlaceInfo* mPlaceInfo; diff --git a/indra/newview/llpanelplacestab.cpp b/indra/newview/llpanelplacestab.cpp index dc9119d2e3..e5b1f04064 100644 --- a/indra/newview/llpanelplacestab.cpp +++ b/indra/newview/llpanelplacestab.cpp @@ -31,12 +31,14 @@ #include "llviewerprecompiledheaders.h" +#include "llpanelplacestab.h" + #include "llwindow.h" #include "llnotifications.h" +#include "llbutton.h" #include "llslurl.h" -#include "llpanelplacestab.h" #include "llworldmap.h" void LLPanelPlacesTab::setPanelPlacesButtons(LLPanelPlaces* panel) diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp index 37262b736e..abcff7cfb1 100644 --- a/indra/newview/llsidetray.cpp +++ b/indra/newview/llsidetray.cpp @@ -118,7 +118,7 @@ LLSideTrayTab::LLSideTrayTab(const Params& params):mAccordionCtrl(0) { mImagePath = params.image_path; mTabTitle = params.tab_title; - mDescription = params.tab_description; + mDescription = params.description; } LLSideTrayTab::~LLSideTrayTab() { diff --git a/indra/newview/llsidetray.h b/indra/newview/llsidetray.h index 7487c71bfc..7b1f4aee04 100644 --- a/indra/newview/llsidetray.h +++ b/indra/newview/llsidetray.h @@ -51,10 +51,11 @@ public: // image name Optional image_path; Optional tab_title; - Optional tab_description; - Params():image_path("image","") - ,tab_title("tab_title","no title") - ,tab_description("description","no description") + Optional description; + Params() + : image_path("image"), + tab_title("tab_title","no title"), + description("description","no description") {}; }; protected: @@ -109,14 +110,14 @@ public: Optional default_button_height; Optional default_button_margin; - Params(): - collapsed("collapsed",false) - ,tab_btn_image_normal("tab_btn_image","sidebar_tab_left.tga") - ,tab_btn_image_selected("tab_btn_image_selected","button_enabled_selected_32x128.tga") - ,default_button_width("tab_btn_width",32) - ,default_button_height("tab_btn_height",32) - ,default_button_margin("tab_btn_margin",0) - {}; + Params() + : collapsed("collapsed",false), + tab_btn_image_normal("tab_btn_image","sidebar_tab_left.tga"), + tab_btn_image_selected("tab_btn_image_selected","button_enabled_selected_32x128.tga"), + default_button_width("tab_btn_width",32), + default_button_height("tab_btn_height",32), + default_button_margin("tab_btn_margin",0) + {}; }; static LLSideTray* getInstance (); diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 211a441d64..d792b972bb 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -60,7 +60,7 @@ #include "llscrollcontainer.h" #include "lltoolmgr.h" #include "lltoolpipette.h" -#include "llsearcheditor.h" +#include "llfiltereditor.h" #include "lltool.h" #include "llviewerwindow.h" @@ -130,7 +130,7 @@ public: void updateFilterPermMask(); void commitIfImmediateSet(); - void onSearchEdit(const std::string& search_string ); + void onFilterEdit(const std::string& search_string ); static void onBtnSetToDefault( void* userdata ); static void onBtnSelect( void* userdata ); @@ -164,7 +164,7 @@ protected: std::string mPendingName; BOOL mActive; - LLSearchEditor* mSearchEdit; + LLFilterEditor* mFilterEdit; LLInventoryPanel* mInventoryPanel; PermissionMask mImmediateFilterPermMask; PermissionMask mNonImmediateFilterPermMask; @@ -191,7 +191,7 @@ LLFloaterTexturePicker::LLFloaterTexturePicker( mTentativeLabel(NULL), mResolutionLabel(NULL), mActive( TRUE ), - mSearchEdit(NULL), + mFilterEdit(NULL), mImmediateFilterPermMask(immediate_filter_perm_mask), mNonImmediateFilterPermMask(non_immediate_filter_perm_mask), mContextConeOpacity(0.f) @@ -335,9 +335,9 @@ BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask) { LLFolderView* root_folder = mInventoryPanel->getRootFolder(); - if (root_folder && mSearchEdit) + if (root_folder && mFilterEdit) { - if (mSearchEdit->hasFocus() + if (mFilterEdit->hasFocus() && (key == KEY_RETURN || key == KEY_DOWN) && mask == MASK_NONE) { @@ -362,7 +362,7 @@ BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask) if (mInventoryPanel->hasFocus() && key == KEY_UP) { - mSearchEdit->focusFirstItem(TRUE); + mFilterEdit->focusFirstItem(TRUE); } } @@ -404,8 +404,8 @@ BOOL LLFloaterTexturePicker::postBuild() childSetCommitCallback("show_folders_check", onShowFolders, this); childSetVisible("show_folders_check", FALSE); - mSearchEdit = getChild("inventory search editor"); - mSearchEdit->setSearchCallback(boost::bind(&LLFloaterTexturePicker::onSearchEdit, this, _1)); + mFilterEdit = getChild("inventory search editor"); + mFilterEdit->setCommitCallback(boost::bind(&LLFloaterTexturePicker::onFilterEdit, this, _2)); mInventoryPanel = getChild("inventory panel"); @@ -524,7 +524,7 @@ void LLFloaterTexturePicker::draw() childSetValue("Pipette", LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance()); //RN: reset search bar to reflect actual search query (all caps, for example) - mSearchEdit->setText(mInventoryPanel->getFilterSubString()); + mFilterEdit->setText(mInventoryPanel->getFilterSubString()); //BOOL allow_copy = FALSE; if( mOwner ) @@ -797,7 +797,7 @@ void LLFloaterTexturePicker::updateFilterPermMask() //mInventoryPanel->setFilterPermMask( getFilterPermMask() ); Commented out due to no-copy texture loss. } -void LLFloaterTexturePicker::onSearchEdit(const std::string& search_string ) +void LLFloaterTexturePicker::onFilterEdit(const std::string& search_string ) { std::string upper_case_search_string = search_string; LLStringUtil::toUpper(upper_case_search_string); diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index e30cdb2e97..0b232da62b 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -84,7 +84,7 @@ public: Params() : image_id("image"), - default_image_id("default_image"), + default_image_id("default_image_id"), default_image_name("default_image_name"), allow_no_texture("allow_no_texture"), can_apply_immediately("can_apply_immediately"), diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp index 954418f7fb..9144f9c3e0 100644 --- a/indra/newview/lltoast.cpp +++ b/indra/newview/lltoast.cpp @@ -32,9 +32,11 @@ #include "llviewerprecompiledheaders.h" // must be first include -#include "llfocusmgr.h" #include "lltoast.h" +#include "llbutton.h" +#include "llfocusmgr.h" + using namespace LLNotificationsUI; //-------------------------------------------------------------------------- diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp index c43618d330..a7b57802c1 100644 --- a/indra/newview/lltoastnotifypanel.cpp +++ b/indra/newview/lltoastnotifypanel.cpp @@ -174,7 +174,7 @@ LLToastNotifyPanel::LLToastNotifyPanel(LLNotificationPtr& notification) : LLToas params.max_text_length(MAX_LENGTH); params.default_text(mMessage); params.font(sFont); - params.allow_embedded_items(false); + params.embedded_items(false); params.word_wrap(true); params.tab_stop(false); params.mouse_opaque(false); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 8f1b105ba6..74ded99124 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1719,7 +1719,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) LLSD args; args["SUBJECT"] = subj; args["MESSAGE"] = mes; - LLNotifications::instance().add(LLNotification::Params("GroupNotice").substitutions(args).payload(payload).timestamp(timestamp)); + LLNotifications::instance().add(LLNotification::Params("GroupNotice").substitutions(args).payload(payload).time_stamp(timestamp)); } // Also send down the old path for now. diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 24479485ef..3e86f48cc5 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -107,6 +107,7 @@ #include "llfloatertools.h" #include "llfloaterworldmap.h" #include "llfocusmgr.h" +#include "llfontfreetype.h" #include "llgesturemgr.h" #include "llglheaders.h" #include "llhoverview.h" diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 7703211c3d..dc5936a435 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -1,4 +1,5 @@ + @@ -469,7 +470,6 @@ - @@ -477,4 +477,5 @@ + diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml index 1fb0942461..cb3388ccbc 100644 --- a/indra/newview/skins/default/xui/en/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en/floater_about_land.xml @@ -1147,7 +1147,7 @@ Go to World menu > About Land or select another parcel to show its details. name="online_status" width="-1" /> - - + width="315"> + + + + + width="115" />