diff options
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llrender/llgl.cpp | 44 | ||||
| -rw-r--r-- | indra/llrender/llimagegl.cpp | 34 | ||||
| -rw-r--r-- | indra/llrender/llimagegl.h | 10 | ||||
| -rw-r--r-- | indra/llrender/llrender.cpp | 6 | ||||
| -rw-r--r-- | indra/newview/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl | 4 | ||||
| -rw-r--r-- | indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl | 3 | ||||
| -rw-r--r-- | indra/newview/lldrawable.h | 5 | ||||
| -rw-r--r-- | indra/newview/lldrawpooltree.cpp | 10 | ||||
| -rw-r--r-- | indra/newview/llface.h | 1 | ||||
| -rw-r--r-- | indra/newview/llglsandbox.cpp | 15 | ||||
| -rw-r--r-- | indra/newview/llspatialpartition.cpp | 130 | ||||
| -rw-r--r-- | indra/newview/llspatialpartition.h | 40 | ||||
| -rw-r--r-- | indra/newview/lltextureatlas.cpp | 416 | ||||
| -rw-r--r-- | indra/newview/lltextureatlas.h | 90 | ||||
| -rw-r--r-- | indra/newview/lltextureatlasmanager.cpp | 268 | ||||
| -rw-r--r-- | indra/newview/lltextureatlasmanager.h | 105 | ||||
| -rw-r--r-- | indra/newview/llviewertexture.cpp | 71 | ||||
| -rw-r--r-- | indra/newview/llvovolume.cpp | 11 | ||||
| -rw-r--r-- | indra/newview/pipeline.cpp | 28 | ||||
| -rw-r--r-- | indra/newview/pipeline.h | 3 | 
21 files changed, 166 insertions, 1132 deletions
| diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 58183adfce..f24bf6ec78 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -88,24 +88,32 @@ void APIENTRY gl_debug_callback(GLenum source,  {  	if (gGLDebugLoggingEnabled)  	{ -	if (severity == GL_DEBUG_SEVERITY_HIGH_ARB) -	{ -		LL_WARNS() << "----- GL ERROR --------" << LL_ENDL; -	} -	else -	{ -		LL_WARNS() << "----- GL WARNING -------" << LL_ENDL; -	} -	LL_WARNS() << "Type: " << std::hex << type << LL_ENDL; -	LL_WARNS() << "ID: " << std::hex << id << LL_ENDL; -	LL_WARNS() << "Severity: " << std::hex << severity << LL_ENDL; -	LL_WARNS() << "Message: " << message << LL_ENDL; -	LL_WARNS() << "-----------------------" << LL_ENDL; -	if (severity == GL_DEBUG_SEVERITY_HIGH_ARB) -	{ -		LL_ERRS() << "Halting on GL Error" << LL_ENDL; -	} -} + +        if (severity != GL_DEBUG_SEVERITY_HIGH_ARB && +            severity != GL_DEBUG_SEVERITY_MEDIUM_ARB && +            severity != GL_DEBUG_SEVERITY_LOW_ARB) +        { //suppress out-of-spec messages sent by nvidia driver (mostly vertexbuffer hints) +            return; +        } + +	    if (severity == GL_DEBUG_SEVERITY_HIGH_ARB) +	    { +		    LL_WARNS() << "----- GL ERROR --------" << LL_ENDL; +	    } +	    else +	    { +		    LL_WARNS() << "----- GL WARNING -------" << LL_ENDL; +	    } +	    LL_WARNS() << "Type: " << std::hex << type << LL_ENDL; +	    LL_WARNS() << "ID: " << std::hex << id << LL_ENDL; +	    LL_WARNS() << "Severity: " << std::hex << severity << LL_ENDL; +	    LL_WARNS() << "Message: " << message << LL_ENDL; +	    LL_WARNS() << "-----------------------" << LL_ENDL; +	    if (severity == GL_DEBUG_SEVERITY_HIGH_ARB) +	    { +		    LL_ERRS() << "Halting on GL Error" << LL_ENDL; +	    } +    }  }  #endif diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 894eb8c773..d3af27272b 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -41,6 +41,10 @@  #include "llrender.h"  #include "llwindow.h" +#if !LL_IMAGEGL_THREAD_CHECK +#define checkActiveThread() +#endif +  //----------------------------------------------------------------------------  const F32 MIN_TEXTURE_LIFETIME = 10.f; @@ -437,6 +441,10 @@ LLImageGL::~LLImageGL()  void LLImageGL::init(BOOL usemipmaps)  { +#if LL_IMAGEGL_THREAD_CHECK +    mActiveThread = LLThread::currentID(); +#endif +  	// keep these members in the same order as declared in llimagehl.h  	// so that it is obvious by visual inspection if we forgot to  	// init a field. @@ -1317,6 +1325,8 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt  BOOL LLImageGL::createGLTexture()  {      LL_PROFILE_ZONE_SCOPED; +    checkActiveThread(); +  	if (gGLManager.mIsDisabled)  	{  		LL_WARNS() << "Trying to create a texture while GL is disabled!" << LL_ENDL; @@ -1349,6 +1359,8 @@ BOOL LLImageGL::createGLTexture()  BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/, BOOL to_create, S32 category)  {      LL_PROFILE_ZONE_SCOPED; +    checkActiveThread(); +  	if (gGLManager.mIsDisabled)  	{  		LL_WARNS() << "Trying to create a texture while GL is disabled!" << LL_ENDL; @@ -1462,6 +1474,8 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S  BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename)  {      LL_PROFILE_ZONE_SCOPED; +    checkActiveThread(); +      llassert(data_in);      stop_glerror(); @@ -1576,6 +1590,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_      // mark this as bound at this point, so we don't throw it out immediately      mLastBindTime = sLastFrameTime; +    checkActiveThread();      return TRUE;  } @@ -1690,18 +1705,10 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre  	return TRUE ;  } -void LLImageGL::deleteDeadTextures() -{ -	bool reset = false; - -	if (reset) -	{ -		gGL.getTexUnit(0)->activate(); -	} -} -		  void LLImageGL::destroyGLTexture()  { +    checkActiveThread(); +  	if (mTexName != 0)  	{  		if(mTextureMemory != S32Bytes(0)) @@ -1720,6 +1727,7 @@ void LLImageGL::destroyGLTexture()  //force to invalidate the gl texture, most likely a sculpty texture  void LLImageGL::forceToInvalidateGLTexture()  { +    checkActiveThread();  	if (mTexName != 0)  	{  		destroyGLTexture(); @@ -2196,6 +2204,12 @@ void LLImageGL::resetCurTexSizebar()  	sCurTexPickSize = -1 ;  }  //---------------------------------------------------------------------------- +#if LL_IMAGEGL_THREAD_CHECK +void LLImageGL::checkActiveThread() +{ +    llassert(mActiveThread == LLThread::currentID()); +} +#endif  //---------------------------------------------------------------------------- diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index ae773bb362..28996a554a 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -40,7 +40,8 @@  #include "threadpool.h"  #include "workqueue.h" -class LLTextureAtlas ; +#define LL_IMAGEGL_THREAD_CHECK 0 //set to 1 to enable thread debugging for ImageGL +  class LLWindow;  #define BYTES_TO_MEGA_BYTES(x) ((x) >> 20) @@ -54,7 +55,6 @@ public:  	// These 2 functions replace glGenTextures() and glDeleteTextures()  	static void generateTextures(S32 numTextures, U32 *textures);  	static void deleteTextures(S32 numTextures, const U32 *textures); -	static void deleteDeadTextures();  	// Size calculation  	static S32 dataFormatBits(S32 dataformat); @@ -189,6 +189,12 @@ public:  	BOOL preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image);  	void postAddToAtlas() ;	 +#if LL_IMAGEGL_THREAD_CHECK +    // thread debugging +    std::thread::id mActiveThread; +    void checkActiveThread(); +#endif +  public:  	// Various GL/Rendering options  	S32Bytes mTextureMemory; diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 235f8a8eb0..8b4f250894 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -181,7 +181,11 @@ void LLTexUnit::bindFast(LLTexture* texture)      mCurrTexture = gl_tex->getTexName();      if (!mCurrTexture)      { -        mCurrTexture = LLImageGL::sDefaultGLTexture->getTexName(); +        LL_PROFILE_ZONE_NAMED("MISSING TEXTURE"); +        //if deleted, will re-generate it immediately +        texture->forceImmediateUpdate(); +        gl_tex->forceUpdateBindStats(); +        texture->bindDefaultImage(mIndex);      }      glBindTexture(sGLTextureType[gl_tex->getTarget()], mCurrTexture);      mHasMipMaps = gl_tex->mHasMipMaps; diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 4a7f17f15b..8157d1566a 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -590,8 +590,6 @@ set(viewer_SOURCE_FILES      llsyswellwindow.cpp      llteleporthistory.cpp      llteleporthistorystorage.cpp -    lltextureatlas.cpp -    lltextureatlasmanager.cpp      lltexturecache.cpp      lltexturectrl.cpp      lltexturefetch.cpp @@ -1219,8 +1217,6 @@ set(viewer_HEADER_FILES      lltable.h      llteleporthistory.h      llteleporthistorystorage.h -    lltextureatlas.h -    lltextureatlasmanager.h      lltexturecache.h      lltexturectrl.h      lltexturefetch.h diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl index ef49b6f4e8..1b16e4eb09 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl @@ -40,11 +40,11 @@ VARYING vec4 post_pos;  VARYING float pos_w;  VARYING float target_pos_x;  VARYING vec2 vary_texcoord0; -VARYING vec4 vertex_color; +uniform vec4 color;  void main()   { -	float alpha = texture2D(diffuseMap, vary_texcoord0.xy).a * vertex_color.a; +	float alpha = texture2D(diffuseMap, vary_texcoord0.xy).a * color.a;  	if (alpha < 0.05) // treat as totally transparent  	{ diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl index d1d7ece6fe..1c5b142ebd 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl @@ -30,7 +30,6 @@ uniform float shadow_target_width;  mat4 getSkinnedTransform();  void passTextureIndex(); -ATTRIBUTE vec4 diffuse_color;  ATTRIBUTE vec3 position;  ATTRIBUTE vec3 normal;  ATTRIBUTE vec2 texcoord0; @@ -41,7 +40,6 @@ VARYING vec4 post_pos;  VARYING float pos_w;  VARYING float target_pos_x;  VARYING vec2 vary_texcoord0; -VARYING vec4 vertex_color;  void main()  { @@ -68,7 +66,6 @@ void main()  	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; -	vertex_color = diffuse_color;  #if !DEPTH_CLAMP  	post_pos = pos; diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index 6002e3e0dd..9a9f6cf7c2 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -64,6 +64,8 @@ class LLDrawable  {      LL_ALIGN_NEW;  public: +    typedef std::vector<LLFace*> face_list_t; +  	LLDrawable(const LLDrawable& rhs)           : LLViewerOctreeEntryData(rhs)  	{ @@ -129,6 +131,7 @@ public:  	inline LLFace*      getFace(const S32 i) const;  	inline S32			getNumFaces()      	 const; +    face_list_t& getFaces() { return mFaces; }  	//void                removeFace(const S32 i); // SJB: Avoid using this, it's slow  	LLFace*				addFace(LLFacePool *poolp, LLViewerTexture *texturep); @@ -297,8 +300,6 @@ public:  	static F32 sCurPixelAngle; //current pixels per radian  private: -	typedef std::vector<LLFace*> face_list_t; -	  	U32				mState;  	S32				mRenderType;  	LLPointer<LLViewerObject> mVObjp; diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp index ac957f1cbd..facfb235c9 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -92,8 +92,9 @@ void LLDrawPoolTree::render(S32 pass)  	LLGLState test(GL_ALPHA_TEST, 0); -	gGL.getTexUnit(sDiffTex)->bind(mTexturep); -				 +	gGL.getTexUnit(sDiffTex)->bindFast(mTexturep); +    gPipeline.touchTexture(mTexturep, 1024.f * 1024.f); // <=== keep Linden tree textures at full res +  	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();  		 iter != mDrawFace.end(); iter++)  	{ @@ -116,9 +117,8 @@ void LLDrawPoolTree::render(S32 pass)  				gPipeline.mMatrixOpCount++;  			} -			buff->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); -			buff->drawRange(LLRender::TRIANGLES, 0, buff->getNumVerts()-1, buff->getNumIndices(), 0);  -			gPipeline.addTrianglesDrawn(buff->getNumIndices()); +			buff->setBufferFast(LLDrawPoolTree::VERTEX_DATA_MASK); +			buff->drawRangeFast(LLRender::TRIANGLES, 0, buff->getNumVerts()-1, buff->getNumIndices(), 0);   		}  	}  } diff --git a/indra/newview/llface.h b/indra/newview/llface.h index c533edede4..79f50f2273 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -47,7 +47,6 @@ class LLTextureEntry;  class LLVertexProgram;  class LLViewerTexture;  class LLGeometryManager; -class LLTextureAtlasSlot;  class LLDrawInfo;  class LLMeshSkinInfo; diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index a135ef0814..0b5064c77d 100644 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -1115,6 +1115,14 @@ F32 gpu_benchmark()  	// ensure matched pair of bind() and unbind() calls  	ShaderBinder binder(gBenchmarkProgram); +    U32 glarray = 0; + +    if (LLRender::sGLCoreProfile) +    { +        glGenVertexArrays(1, &glarray); +        glBindVertexArray(glarray); +    } +  	buff->setBuffer(LLVertexBuffer::MAP_VERTEX);  	glFinish(); @@ -1147,6 +1155,13 @@ F32 gpu_benchmark()  		}  	} +    if (LLRender::sGLCoreProfile) +    { +        glBindVertexArray(0); +        glDeleteVertexArrays(1, &glarray); +    } + +  	std::sort(results.begin(), results.end());  	F32 gbps = results[results.size()/2]; diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 25d6106361..48e9f3726f 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -51,7 +51,6 @@  #include "llphysicsshapebuilderutil.h"  #include "llvoavatar.h"  #include "llvolumemgr.h" -#include "lltextureatlas.h"  #include "llviewershadermgr.h"  #include "llcontrolavatar.h" @@ -128,129 +127,6 @@ LLSpatialGroup::~LLSpatialGroup()  	sNodeCount--;  	clearDrawMap(); -	clearAtlasList() ; -} - -BOOL LLSpatialGroup::hasAtlas(LLTextureAtlas* atlasp) -{ -	S8 type = atlasp->getComponents() - 1 ; -	for(std::list<LLTextureAtlas*>::iterator iter = mAtlasList[type].begin(); iter != mAtlasList[type].end() ; ++iter) -	{ -		if(atlasp == *iter) -		{ -			return TRUE ; -		} -	} -	return FALSE ; -} - -void LLSpatialGroup::addAtlas(LLTextureAtlas* atlasp, S8 recursive_level)  -{		 -	if(!hasAtlas(atlasp)) -	{ -		mAtlasList[atlasp->getComponents() - 1].push_back(atlasp) ; -		atlasp->addSpatialGroup(this) ; -	} -	 -	--recursive_level; -	if(recursive_level)//levels propagating up. -	{ -		LLSpatialGroup* parent = getParent() ; -		if(parent) -		{ -			parent->addAtlas(atlasp, recursive_level) ; -		} -	}	 -} - -void LLSpatialGroup::removeAtlas(LLTextureAtlas* atlasp, BOOL remove_group, S8 recursive_level)  -{ -	mAtlasList[atlasp->getComponents() - 1].remove(atlasp) ; -	if(remove_group) -	{ -		atlasp->removeSpatialGroup(this) ; -	} - -	--recursive_level; -	if(recursive_level)//levels propagating up. -	{ -		LLSpatialGroup* parent = getParent() ; -		if(parent) -		{ -			parent->removeAtlas(atlasp, recursive_level) ; -		} -	}	 -} - -void LLSpatialGroup::clearAtlasList()  -{ -	std::list<LLTextureAtlas*>::iterator iter ; -	for(S8 i = 0 ; i < 4 ; i++) -	{ -		if(mAtlasList[i].size() > 0) -		{ -			for(iter = mAtlasList[i].begin(); iter != mAtlasList[i].end() ; ++iter) -			{ -				((LLTextureAtlas*)*iter)->removeSpatialGroup(this) ;			 -			} -			mAtlasList[i].clear() ; -		} -	} -} - -LLTextureAtlas* LLSpatialGroup::getAtlas(S8 ncomponents, S8 to_be_reserved, S8 recursive_level) -{ -	S8 type = ncomponents - 1 ; -	if(mAtlasList[type].size() > 0) -	{ -		for(std::list<LLTextureAtlas*>::iterator iter = mAtlasList[type].begin(); iter != mAtlasList[type].end() ; ++iter) -		{ -			if(!((LLTextureAtlas*)*iter)->isFull(to_be_reserved)) -			{ -				return *iter ; -			} -		} -	} - -	--recursive_level; -	if(recursive_level) -	{ -		LLSpatialGroup* parent = getParent() ; -		if(parent) -		{ -			return parent->getAtlas(ncomponents, to_be_reserved, recursive_level) ; -		} -	} -	return NULL ; -} - -void LLSpatialGroup::setCurUpdatingSlot(LLTextureAtlasSlot* slotp)  -{  -	mCurUpdatingSlotp = slotp; - -	//if(!hasAtlas(mCurUpdatingSlotp->getAtlas())) -	//{ -	//	addAtlas(mCurUpdatingSlotp->getAtlas()) ; -	//} -} - -LLTextureAtlasSlot* LLSpatialGroup::getCurUpdatingSlot(LLViewerTexture* imagep, S8 recursive_level)  -{  -	if(gFrameCount && mCurUpdatingTime == gFrameCount && mCurUpdatingTexture == imagep) -	{ -		return mCurUpdatingSlotp ; -	} - -	//--recursive_level ; -	//if(recursive_level) -	//{ -	//	LLSpatialGroup* parent = getParent() ; -	//	if(parent) -	//	{ -	//		return parent->getCurUpdatingSlot(imagep, recursive_level) ; -	//	} -	//} -	return NULL ;  }  void LLSpatialGroup::clearDrawMap() @@ -665,11 +541,7 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : LLO  	mDistance(0.f),  	mDepth(0.f),  	mLastUpdateDistance(-1.f),  -	mLastUpdateTime(gFrameTimeSeconds), -	mAtlasList(4), -	mCurUpdatingTime(0), -	mCurUpdatingSlotp(NULL), -	mCurUpdatingTexture (NULL) +	mLastUpdateTime(gFrameTimeSeconds)  {  	ll_assert_aligned(this,16); diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 5fca516f19..58d821353a 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -50,8 +50,6 @@ class LLViewerOctreePartition;  class LLSpatialPartition;  class LLSpatialBridge;  class LLSpatialGroup; -class LLTextureAtlas; -class LLTextureAtlasSlot;  class LLViewerRegion;  void pushVerts(LLFace* face, U32 mask); @@ -91,6 +89,10 @@ public:  	LLPointer<LLViewerTexture>     mTexture;  	std::vector<LLPointer<LLViewerTexture> > mTextureList; +    // virtual size of mTexture and mTextureList textures +    // used to update the decode priority of textures in this DrawInfo +    std::vector<F32> mTextureListVSize; +  	S32 mDebugColor;  	const LLMatrix4* mTextureMatrix;  	const LLMatrix4* mModelMatrix; @@ -304,49 +306,15 @@ public:  	virtual void handleDestruction(const TreeNode* node);  	virtual void handleChildAddition(const OctreeNode* parent, OctreeNode* child); -//------------------- -//for atlas use -//------------------- -	//atlas	 -	void setCurUpdatingTime(U32 t) {mCurUpdatingTime = t ;} -	U32  getCurUpdatingTime() const { return mCurUpdatingTime ;} -	 -	void setCurUpdatingSlot(LLTextureAtlasSlot* slotp) ; -	LLTextureAtlasSlot* getCurUpdatingSlot(LLViewerTexture* imagep, S8 recursive_level = 3) ; - -	void setCurUpdatingTexture(LLViewerTexture* tex){ mCurUpdatingTexture = tex ;} -	LLViewerTexture* getCurUpdatingTexture() const { return mCurUpdatingTexture ;} -	 -	BOOL hasAtlas(LLTextureAtlas* atlasp) ; -	LLTextureAtlas* getAtlas(S8 ncomponents, S8 to_be_reserved, S8 recursive_level = 3) ; -	void addAtlas(LLTextureAtlas* atlasp, S8 recursive_level = 3) ; -	void removeAtlas(LLTextureAtlas* atlasp, BOOL remove_group = TRUE, S8 recursive_level = 3) ; -	void clearAtlasList() ; -  public: -  	LL_ALIGN_16(LLVector4a mViewAngle);  	LL_ALIGN_16(LLVector4a mLastUpdateViewAngle);  	F32 mObjectBoxSize; //cached mObjectBounds[1].getLength3() -		 -private: -	U32                     mCurUpdatingTime ; -	//do not make the below two to use LLPointer -	//because mCurUpdatingTime invalidates them automatically. -	LLTextureAtlasSlot* mCurUpdatingSlotp ; -	LLViewerTexture*          mCurUpdatingTexture ; - -	std::vector< std::list<LLTextureAtlas*> > mAtlasList ;  -//------------------- -//end for atlas use -//-------------------  protected:  	virtual ~LLSpatialGroup(); -	static S32 sLODSeed; -  public:  	bridge_list_t mBridgeList;  	buffer_map_t mBufferMap; //used by volume buffers to attempt to reuse vertex buffers diff --git a/indra/newview/lltextureatlas.cpp b/indra/newview/lltextureatlas.cpp deleted file mode 100644 index 1c8e4f796e..0000000000 --- a/indra/newview/lltextureatlas.cpp +++ /dev/null @@ -1,416 +0,0 @@ -/**  - * @file lltextureatlas.cpp - * @brief LLTextureAtlas class implementation. - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - *  - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - *  - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - *  - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA - * $/LicenseInfo$ - */ -#include "llviewerprecompiledheaders.h" -#include "linden_common.h" -#include "llerror.h" -#include "llimage.h" -#include "llmath.h" -#include "llgl.h" -#include "llrender.h" -#include "lltextureatlas.h" - -//------------------- -S16 LLTextureAtlas::sMaxSubTextureSize = 64 ; -S16 LLTextureAtlas::sSlotSize = 32 ; - -#ifndef DEBUG_ATLAS -#define DEBUG_ATLAS 0 -#endif - -#ifndef DEBUG_USAGE_BITS -#define DEBUG_USAGE_BITS 0 -#endif -//************************************************************************************************************** -LLTextureAtlas::LLTextureAtlas(U8 ncomponents, S16 atlas_dim) :  -    LLViewerTexture(atlas_dim * sSlotSize, atlas_dim * sSlotSize, ncomponents, TRUE), -	mAtlasDim(atlas_dim), -	mNumSlotsReserved(0), -	mMaxSlotsInAtlas(atlas_dim * atlas_dim) -{ -	generateEmptyUsageBits() ; - -	//generate an empty texture -	generateGLTexture() ; -	LLPointer<LLImageRaw> image_raw = new LLImageRaw(mFullWidth, mFullHeight, mComponents); -	createGLTexture(0, image_raw, 0); -	image_raw = NULL; -} - -LLTextureAtlas::~LLTextureAtlas()  -{ -	if(mSpatialGroupList.size() > 0) -	{ -		LL_ERRS() << "Not clean up the spatial groups!" << LL_ENDL ; -	} -	releaseUsageBits() ; -} - -//virtual  -S8 LLTextureAtlas::getType() const -{ -	return 0; //LLViewerTexture::ATLAS_TEXTURE ; -} - -void LLTextureAtlas::getTexCoordOffset(S16 col, S16 row, F32& xoffset, F32& yoffset) -{ -	xoffset = (F32)col / mAtlasDim ; -	yoffset = (F32)row / mAtlasDim ;	 -} - -void LLTextureAtlas::getTexCoordScale(S32 w, S32 h, F32& xscale, F32& yscale) -{ -	xscale = (F32)w / (mAtlasDim * sSlotSize) ; -	yscale = (F32)h / (mAtlasDim * sSlotSize) ;	 -} - -//insert a texture piece into the atlas -LLGLuint LLTextureAtlas::insertSubTexture(LLImageGL* source_gl_tex, S32 discard_level, const LLImageRaw* raw_image, S16 slot_col, S16 slot_row) -{ -	if(!getTexName()) -	{ -		return 0 ; -	} - -	S32 w = raw_image->getWidth() ; -	S32 h = raw_image->getHeight() ; -	if(w < 8 || w > sMaxSubTextureSize || h < 8 || h > sMaxSubTextureSize) -	{ -		//size overflow -		return 0 ; -	} - -	BOOL res = gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, getTexName()); -	if (!res)  -	{ -		LL_ERRS() << "bindTexture failed" << LL_ENDL; -	} -	 -	GLint xoffset = sSlotSize * slot_col ; -	GLint yoffset = sSlotSize * slot_row ; - -	if(!source_gl_tex->preAddToAtlas(discard_level, raw_image)) -	{ -		return 0 ; -	} - -	glTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, w, h, -						mGLTexturep->getPrimaryFormat(), mGLTexturep->getFormatType(), raw_image->getData()); -	 -	source_gl_tex->postAddToAtlas() ; -	return getTexName(); -} -	 -//release a sub-texture slot from the atlas -void LLTextureAtlas::releaseSlot(S16 slot_col, S16 slot_row, S8 slot_width) -{ -	unmarkUsageBits(slot_width, slot_col, slot_row) ; -	mNumSlotsReserved -= slot_width * slot_width ; -} - -BOOL LLTextureAtlas::isEmpty() const  -{ -	return !mNumSlotsReserved ; -} -	 -BOOL LLTextureAtlas::isFull(S8 to_be_reserved) const  -{ -	return mNumSlotsReserved + to_be_reserved > mMaxSlotsInAtlas ; -} -F32  LLTextureAtlas::getFullness() const  -{ -	return (F32)mNumSlotsReserved / mMaxSlotsInAtlas ; -} - -void LLTextureAtlas::addSpatialGroup(LLSpatialGroup* groupp)  -{ -	if(groupp && !hasSpatialGroup(groupp)) -	{ -		mSpatialGroupList.push_back(groupp); -	} -} - -void LLTextureAtlas::removeSpatialGroup(LLSpatialGroup* groupp)  -{ -	if(groupp) -	{ -		mSpatialGroupList.remove(groupp); -	} -} - -void LLTextureAtlas::clearSpatialGroup()  -{ -	mSpatialGroupList.clear(); -} -void LLTextureAtlas::removeLastSpatialGroup()  -{ -	mSpatialGroupList.pop_back() ; -} - -LLSpatialGroup* LLTextureAtlas::getLastSpatialGroup()  -{ -	if(mSpatialGroupList.size() > 0) -	{ -		return mSpatialGroupList.back() ; -	} -	return NULL ; -} - -BOOL LLTextureAtlas::hasSpatialGroup(LLSpatialGroup* groupp)  -{ -	for(std::list<LLSpatialGroup*>::iterator iter = mSpatialGroupList.begin(); iter != mSpatialGroupList.end() ; ++iter) -	{ -		if(*iter == groupp) -		{ -			return TRUE ; -		} -	} -	return FALSE ; -} - -//-------------------------------------------------------------------------------------- -//private -void LLTextureAtlas::generateEmptyUsageBits() -{ -	S32 col_len = (mAtlasDim + 7) >> 3 ; -	mUsageBits = new U8*[mAtlasDim] ; -	*mUsageBits = new U8[mAtlasDim * col_len] ; - -	mUsageBits[0] = *mUsageBits ; -	for(S32 i = 1 ; i < mAtlasDim ; i++) -	{ -	   mUsageBits[i] = mUsageBits[i-1] + col_len ; - -	   for(S32 j = 0 ; j < col_len ; j++) -	   { -		   //init by 0 for all bits. -		   mUsageBits[i][j] = 0 ; -	   } -	} - -	//do not forget mUsageBits[0]! -	for(S32 j = 0 ; j < col_len ; j++) -	{ -		//init by 0 for all bits. -		mUsageBits[0][j] = 0 ; -	} - -	mTestBits = NULL ; -#if DEBUG_USAGE_BITS -	//------------ -	//test -	mTestBits = new U8*[mAtlasDim] ; -	*mTestBits = new U8[mAtlasDim * mAtlasDim] ; -	mTestBits[0] = *mTestBits ; -	for(S32 i = 1 ; i < mAtlasDim ; i++) -	{ -	   mTestBits[i] = mTestBits[i-1] + mAtlasDim ; - -	   for(S32 j = 0 ; j < mAtlasDim ; j++) -	   { -		   //init by 0 for all bits. -		   mTestBits[i][j] = 0 ; -	   } -	} - -	for(S32 j = 0 ; j < mAtlasDim ; j++) -	{ -		//init by 0 for all bits. -		mTestBits[0][j] = 0 ; -	} -#endif -} - -void LLTextureAtlas::releaseUsageBits() -{ -   if(mUsageBits) -   { -       delete[] *mUsageBits ; -       delete[] mUsageBits ; -   } -   mUsageBits = NULL ; - -   //test -   if( mTestBits) -   { -	   delete[] *mTestBits; -	   delete[]  mTestBits; -   } -    mTestBits = NULL ; -} - -void LLTextureAtlas::markUsageBits(S8 bits_len, U8 mask, S16 col, S16 row) -{ -	S16 x = col >> 3 ; -	 -	for(S8 i = 0 ; i < bits_len ; i++) -	{ -		mUsageBits[row + i][x] |= mask ; -	} - -#if DEBUG_USAGE_BITS -	//test -	for(S8 i = row ; i < row + bits_len ; i++) -	{ -		for(S8 j = col ; j < col + bits_len ; j++) -		{ -			mTestBits[i][j] = 1 ; -		} -	} -#endif -} - -void LLTextureAtlas::unmarkUsageBits(S8 bits_len, S16 col, S16 row) -{ -	S16 x = col >> 3 ; -	U8  mask = 1 ; -	for(S8 i = 1 ; i < bits_len ; i++) -	{ -		mask |= (1 << i) ; -	} -	mask <<= (col & 7) ; -	mask = ~mask ; -	 -	for(S8 i = 0 ; i < bits_len ; i++) -	{ -		mUsageBits[row + i][x] &= mask ; -	} - -#if DEBUG_USAGE_BITS -	//test -	for(S8 i = row ; i < row + bits_len ; i++) -	{ -		for(S8 j = col ; j < col + bits_len ; j++) -		{ -			mTestBits[i][j] = 0 ; -		} -	} -#endif -} - -//return true if any of bits in the range marked. -BOOL LLTextureAtlas::areUsageBitsMarked(S8 bits_len, U8 mask, S16 col, S16 row) -{ -	BOOL ret = FALSE ;	 -	S16 x = col >> 3 ; -	 -	for(S8 i = 0 ; i < bits_len ; i++) -	{ -		if(mUsageBits[row + i][x] & mask) -		{ -			ret = TRUE ; -			break ; -			//return TRUE ; -		} -	} - -#if DEBUG_USAGE_BITS -	//test -	BOOL ret2 = FALSE ; -	for(S8 i = row ; i < row + bits_len ; i++) -	{ -		for(S8 j = col ; j < col + bits_len ; j++) -		{ -			if(mTestBits[i][j]) -			{ -				ret2 = TRUE ; -			} -		} -	} - -	if(ret != ret2) -	{ -		LL_ERRS() << "bits map corrupted." << LL_ENDL ; -	} -#endif -	return ret ;//FALSE ; -} - -//---------------------------------------------------------------------- -// -//index order: Z order, i.e.:  -// |-----|-----|-----|-----| -// |  10 |  11 | 14  | 15  | -// |-----|-----|-----|-----| -// |   8 |   9 | 12  | 13  | -// |-----|-----|-----|-----| -// |   2 |   3 |   6 |   7 | -// |-----|-----|-----|-----| -// |   0 |   1 |   4 |   5 | -// |-----|-----|-----|-----| -void LLTextureAtlas::getPositionFromIndex(S16 index, S16& col, S16& row) -{ -	col = 0 ; -	row = 0 ; - -	S16 index_copy = index ; -	for(S16 i = 0 ; index_copy && i < 16 ; i += 2) -	{ -		col |= ((index & (1 << i)) >> i) << (i >> 1) ; -		row |= ((index & (1 << (i + 1))) >> (i + 1)) << (i >> 1) ; -		index_copy >>= 2 ; -	} -} -void LLTextureAtlas::getIndexFromPosition(S16 col, S16 row, S16& index) -{ -	index = 0 ; -	S16 col_copy = col ; -	S16 row_copy = row ; -	for(S16 i = 0 ; (col_copy || row_copy) && i < 16 ; i++) -	{ -		index |= ((col & 1 << i) << i) | ((row & 1 << i) << ( i + 1)) ; -		col_copy >>= 1 ; -		row_copy >>= 1 ; -	} -} -//---------------------------------------------------------------------- -//return TRUE if succeeds. -BOOL LLTextureAtlas::getNextAvailableSlot(S8 bits_len, S16& col, S16& row) -{ -    S16 index_step = bits_len * bits_len ; - -    U8 mask = 1 ; -	for(S8 i = 1 ; i < bits_len ; i++) -	{ -		mask |= (1 << i) ; -	}	 -    -	U8 cur_mask ; -	for(S16 index = 0 ; index < mMaxSlotsInAtlas ; index += index_step) -    { -		getPositionFromIndex(index, col, row) ; -		 -		cur_mask = mask << (col & 7) ; -		if(!areUsageBitsMarked(bits_len, cur_mask, col, row)) -		{ -			markUsageBits(bits_len, cur_mask, col, row) ; -			mNumSlotsReserved += bits_len * bits_len ; -			 -			return TRUE ; -		} -    } - -   return FALSE ; -} diff --git a/indra/newview/lltextureatlas.h b/indra/newview/lltextureatlas.h deleted file mode 100644 index 6b36eb7fe4..0000000000 --- a/indra/newview/lltextureatlas.h +++ /dev/null @@ -1,90 +0,0 @@ -/**  - * @file lltextureatlas.h - * @brief LLTextureAtlas base class. - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - *  - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - *  - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - *  - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA - * $/LicenseInfo$ - */ - - -#ifndef LL_TEXTUREATLAS_H -#define LL_TEXTUREATLAS_H - -#include "llviewertexture.h" -class LLSpatialGroup ; - -class LLTextureAtlas : public LLViewerTexture -{ -protected: -	/*virtual*/ ~LLTextureAtlas() ; - -public: -	LLTextureAtlas(U8 ncomponents, S16 atlas_dim = 16) ;	 - -	/*virtual*/ S8 getType() const; - -	LLGLuint insertSubTexture(LLImageGL* source_gl_tex, S32 discard_level, const LLImageRaw* raw_image, S16 slot_col, S16 slot_row) ; -	void releaseSlot(S16 slot_col, S16 slot_row, S8 slot_width); - -	BOOL getNextAvailableSlot(S8 bits_len, S16& col, S16& row) ; -	void getTexCoordOffset(S16 col, S16 row, F32& xoffset, F32& yOffset) ; -	void getTexCoordScale(S32 w, S32 h, F32& xscale, F32& yscale) ; - -	BOOL isEmpty() const ; -	BOOL isFull(S8 to_be_reserved = 1) const ; -	F32  getFullness() const ; - -	void addSpatialGroup(LLSpatialGroup* groupp) ; -	void removeSpatialGroup(LLSpatialGroup* groupp) ; -	LLSpatialGroup* getLastSpatialGroup() ; -	void removeLastSpatialGroup() ; -	BOOL hasSpatialGroup(LLSpatialGroup* groupp) ; -	void clearSpatialGroup() ; -	std::list<LLSpatialGroup*>* getSpatialGroupList() {return &mSpatialGroupList;} -private: -	void generateEmptyUsageBits() ; -	void releaseUsageBits() ; - -	void markUsageBits(S8 bits_len, U8 mask, S16 col, S16 row) ; -	void unmarkUsageBits(S8 bits_len, S16 col, S16 row) ; - -	void getPositionFromIndex(S16 index, S16& col, S16& row) ; -	void getIndexFromPosition(S16 col, S16 row, S16& index) ; -	BOOL areUsageBitsMarked(S8 bits_len, U8 mask, S16 col, S16 row) ; - -private:	 -	S16 mAtlasDim ; //number of slots per edge, i.e, there are "mAtlasDim * mAtlasDim" total slots in the atlas.  -	S16 mNumSlotsReserved ; -	S16 mMaxSlotsInAtlas ; -	U8  **mUsageBits ;	 -	std::list<LLSpatialGroup*> mSpatialGroupList ; - -public: -	//debug use only -	U8  **mTestBits ; - -public: -	static S16 sMaxSubTextureSize ; -	static S16 sSlotSize ; -}; - -#endif - diff --git a/indra/newview/lltextureatlasmanager.cpp b/indra/newview/lltextureatlasmanager.cpp deleted file mode 100644 index ca9d6da4db..0000000000 --- a/indra/newview/lltextureatlasmanager.cpp +++ /dev/null @@ -1,268 +0,0 @@ -/**  - * @file lltextureatlasmanager.cpp - * @brief LLTextureAtlasManager class implementation. - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - *  - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - *  - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - *  - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA - * $/LicenseInfo$ - */ -#include "llviewerprecompiledheaders.h" -#include "linden_common.h" -#include "llerror.h" -#include "llmath.h" -#include "lltextureatlas.h" -#include "lltextureatlasmanager.h" -#include "llspatialpartition.h" - -const S8 MAX_NUM_EMPTY_ATLAS = 2 ; -const F32 MIN_ATLAS_FULLNESS = 0.6f ; - -//********************************************************************************************* -//implementation of class LLTextureAtlasInfo -//********************************************************************************************* -LLTextureAtlasSlot::LLTextureAtlasSlot(LLTextureAtlas* atlasp, LLSpatialGroup* groupp, S16 col, S16 row, F32 xoffset, F32 yoffset, S8 slot_width) :  -	mAtlasp(atlasp), -	mGroupp(groupp), -	mCol(col), -	mRow(row), -	mReservedSlotWidth(slot_width), -	mValid(FALSE), -	mUpdatedTime(0), -	mTexCoordOffset(xoffset, yoffset), -	mTexCoordScale(1.f, 1.f) -{ -	llassert_always(mAtlasp || mGroupp || mReservedSlotWidth) ; -} - -LLTextureAtlasSlot::~LLTextureAtlasSlot() -{ -	if(mAtlasp) -	{ -		mAtlasp->releaseSlot(mCol, mRow, mReservedSlotWidth) ; -		if(mAtlasp->isEmpty()) -		{ -			LLTextureAtlasManager::getInstance()->releaseAtlas(mAtlasp) ; -		} -		mAtlasp = NULL ; -	} -} - -//void LLTextureAtlasSlot::setAtlas(LLTextureAtlas* atlasp)  -//{ -//	mAtlasp = atlasp ; -//} -//void LLTextureAtlasSlot::setSlotPos(S16 col, S16 row)  -//{ -//	mCol = col ; -//	mRow = row ; -//} -//void LLTextureAtlasSlot::setSlotWidth(S8 width)  -//{ -//	//slot is a square with each edge length a power-of-two number -//	mReservedSlotWidth = width ; -//} -//void LLTextureAtlasSlot::setTexCoordOffset(F32 xoffset, F32 yoffset)  -//{ -//	mTexCoordOffset.mV[0] = xoffset ; -//	mTexCoordOffset.mV[1] = yoffset ; -//} - -void LLTextureAtlasSlot::setSpatialGroup(LLSpatialGroup* groupp)  -{ -	mGroupp = groupp ; -} -void LLTextureAtlasSlot::setTexCoordScale(F32 xscale, F32 yscale)  -{ -	mTexCoordScale.mV[0] = xscale ; -	mTexCoordScale.mV[1] = yscale ; -} -//********************************************************************************************* -//END of implementation of class LLTextureAtlasInfo -//********************************************************************************************* - -//********************************************************************************************* -//implementation of class LLTextureAtlasManager -//********************************************************************************************* -LLTextureAtlasManager::LLTextureAtlasManager() : -	mAtlasMap(4), -	mEmptyAtlasMap(4)  -{ -} - -LLTextureAtlasManager::~LLTextureAtlasManager() -{ -	for(S32 i = 0 ; i < 4 ; i++) -	{ -		for(ll_texture_atlas_list_t::iterator j = mAtlasMap[i].begin() ; j != mAtlasMap[i].end() ; ++j) -		{ -			*j = NULL ; -		} -		for(ll_texture_atlas_list_t::iterator j = mEmptyAtlasMap[i].begin() ; j != mEmptyAtlasMap[i].end() ; ++j) -		{ -			*j = NULL ; -		} - -		mAtlasMap[i].clear() ; -		mEmptyAtlasMap[i].clear() ; -	} -	mAtlasMap.clear() ; -	mEmptyAtlasMap.clear() ; -} - -//return TRUE if qualified -BOOL LLTextureAtlasManager::canAddToAtlas(S32 w, S32 h, S8 ncomponents, LLGLenum target)  -{ -	if(ncomponents < 1 || ncomponents > 4) -	{ -		return FALSE ; -	} -	//only support GL_TEXTURE_2D -	if(GL_TEXTURE_2D != target) -	{ -		return FALSE ; -	} -	//real image size overflows -	if(w < 8 || w > LLTextureAtlas::sMaxSubTextureSize || h < 8 || h > LLTextureAtlas::sMaxSubTextureSize) -	{ -		return FALSE ; -	} - -	//if non-power-of-two number -	if((w & (w - 1)) || (h & (h - 1))) -	{ -		return FALSE ; -	} - -	return TRUE ; -} - -void LLTextureAtlasManager::releaseAtlas(LLTextureAtlas* atlasp) -{	 -	LLSpatialGroup* groupp = atlasp->getLastSpatialGroup() ; -	while(groupp) -	{ -		groupp->removeAtlas(atlasp, FALSE) ; -		atlasp->removeLastSpatialGroup() ; - -		groupp = atlasp->getLastSpatialGroup() ; -	} - -	S8 type = atlasp->getComponents() - 1 ;	 -	//insert to the empty list -	if(mEmptyAtlasMap[type].size() < MAX_NUM_EMPTY_ATLAS) -	{					 -		mEmptyAtlasMap[type].push_back(atlasp) ; -	} -		 -	//delete the atlasp -	mAtlasMap[type].remove(atlasp) ; -} - -// -//this function reserves an appropriate slot from atlas pool for an image. -//return non-NULL if succeeds. -//Note: -//1, this function does not check if the image this slot assigned for qualifies for atlas or not,  -//       call LLTextureAtlasManager::canAddToAtlas(...) to do the check before calling this function. -//2, this function also dose not check if the image is already in atlas. It always assigns a new slot anyway. -//3, this function tries to group sub-textures from same spatial group into ONE atlas to improve render batching. -// -LLPointer<LLTextureAtlasSlot> LLTextureAtlasManager::reserveAtlasSlot(S32 sub_texture_size, S8 ncomponents,  -																		  LLSpatialGroup* groupp, LLViewerTexture* imagep) -{ -	if(!groupp) -	{ -		//do not insert to atlas if does not have a group. -		return NULL ; -	} - -	//bits_len must <= 8 and is a power of two number, i.e.: must be one of these numbers: 1, 2, 4, 8. -	if(sub_texture_size > LLTextureAtlas::sMaxSubTextureSize) -	{ -		sub_texture_size = LLTextureAtlas::sMaxSubTextureSize ; -	} -	S8 bits_len = sub_texture_size / LLTextureAtlas::sSlotSize ; -	if(bits_len < 1) -	{ -	   bits_len = 1 ; -	} -		 -	S16 col = -1, row = -1; -	S8 total_bits = bits_len * bits_len ; - -	//insert to the atlas reserved by the same spatial group -	LLPointer<LLTextureAtlas> atlasp = groupp->getAtlas(ncomponents, total_bits) ; -	if(atlasp.notNull()) -	{ -		if(!atlasp->getNextAvailableSlot(bits_len, col, row)) -		{ -			//failed -			atlasp = NULL ; -		}		 -	} - -   //search an atlas to fit for 'size' -	if(!atlasp) -	{ -		S8 atlas_index = ncomponents - 1 ; -		ll_texture_atlas_list_t::iterator iter = mAtlasMap[atlas_index].begin() ; -		for(; iter != mAtlasMap[atlas_index].end(); ++iter)  -		{ -			LLTextureAtlas* cur = (LLTextureAtlas*)*iter ; -			if(cur->getFullness() < MIN_ATLAS_FULLNESS)//this atlas is empty enough for this group to insert more sub-textures later if necessary. -			{ -				if(cur->getNextAvailableSlot(bits_len, col, row)) -				{ -					atlasp = cur ; -					groupp->addAtlas(atlasp) ;				 -					break ; -				} -			} -		} -	} - -	//create a new atlas if necessary -	if(!atlasp) -	{ -		if(mEmptyAtlasMap[ncomponents - 1].size() > 0) -		{ -			//there is an empty one -			atlasp = mEmptyAtlasMap[ncomponents - 1].back() ; -			mEmptyAtlasMap[ncomponents - 1].pop_back() ; -		} -		else -		{ -			atlasp = new LLTextureAtlas(ncomponents, 16) ; -		} -		mAtlasMap[ncomponents - 1].push_back(atlasp) ; -		atlasp->getNextAvailableSlot(bits_len, col, row) ;		 -		groupp->addAtlas(atlasp) ; -	} - -	F32 xoffset, yoffset ; -	atlasp->getTexCoordOffset(col, row, xoffset, yoffset) ; -	LLPointer<LLTextureAtlasSlot> slot_infop = new LLTextureAtlasSlot(atlasp, groupp, col, row, xoffset, yoffset, bits_len) ; -	 -	return slot_infop ; -} - -//********************************************************************************************* -//END of implementation of class LLTextureAtlasManager -//********************************************************************************************* diff --git a/indra/newview/lltextureatlasmanager.h b/indra/newview/lltextureatlasmanager.h deleted file mode 100644 index 1b8df708c6..0000000000 --- a/indra/newview/lltextureatlasmanager.h +++ /dev/null @@ -1,105 +0,0 @@ -/**  - * @file lltextureatlasmanager.h - * @brief LLTextureAtlasManager base class. - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - *  - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - *  - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - *  - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA - * $/LicenseInfo$ - */ - - -#ifndef LL_TEXTUREATLASMANAGER_H -#define LL_TEXTUREATLASMANAGER_H - -#include "llmemory.h" - -class LLSpatialGroup ; -class LLViewerTexture ; - -//just use it as a structure. -class LLTextureAtlasSlot : public LLRefCount -{ -public: -	LLTextureAtlasSlot(LLTextureAtlas* atlasp, LLSpatialGroup* groupp, S16 col, S16 row, F32 xoffset, F32 yoffset, S8 slot_width) ; - -protected: -	virtual ~LLTextureAtlasSlot(); -	 -public: - -	// -	//do not allow to change those values -	// -	//void setAtlas(LLTextureAtlas* atlasp) ;	 -	//void setSlotPos(S16 col, S16 row) ; -	//void setSlotWidth(S8 width) ; -	//void setTexCoordOffset(F32 xoffser, F32 yoffset) ; -	// - -	void setSpatialGroup(LLSpatialGroup* groupp) ; -	void setTexCoordScale(F32 xscale, F32 yscale) ; -	void setValid() {mValid = TRUE ;} - -	LLTextureAtlas* getAtlas()const {return mAtlasp;} -	LLSpatialGroup* getSpatialGroup() const {return mGroupp ;}  -	S16             getSlotCol()const {return mCol;} -	S16             getSlotRow()const {return mRow;} -	S8              getSlotWidth()const{return mReservedSlotWidth;} -	BOOL            isValid()const { return mValid;} -	const LLVector2*      getTexCoordOffset()const {return &mTexCoordOffset;} -	const LLVector2*      getTexCoordScale() const {return &mTexCoordScale;} - -	void setUpdatedTime(U32 t) {mUpdatedTime = t;} -	U32  getUpdatedTime()const {return mUpdatedTime;} - -private: -	LLTextureAtlas* mAtlasp; -	S16             mCol ;//col of the slot -	S16             mRow ;//row of the slot -	S8              mReservedSlotWidth ; //slot is a square with each edge length a power-of-two number	 -	LLSpatialGroup* mGroupp ; -	BOOL            mValid ; - -	LLVector2       mTexCoordOffset ; -	LLVector2       mTexCoordScale ; - -	U32             mUpdatedTime ;	 -} ; - -class LLTextureAtlasManager : public LLSingleton<LLTextureAtlasManager> -{ -	LLSINGLETON(LLTextureAtlasManager); -	~LLTextureAtlasManager(); -	typedef std::list<LLPointer<LLTextureAtlas> > ll_texture_atlas_list_t ; - -public: - -	LLPointer<LLTextureAtlasSlot> reserveAtlasSlot(S32 sub_texture_size, S8 ncomponents,  -		LLSpatialGroup* groupp, LLViewerTexture* imagep) ; -	void releaseAtlas(LLTextureAtlas* atlasp); - -	BOOL canAddToAtlas(S32 w, S32 h, S8 ncomponents, LLGLenum target) ; - -private:	 -	std::vector<ll_texture_atlas_list_t> mAtlasMap ; -	std::vector<ll_texture_atlas_list_t> mEmptyAtlasMap ; //delay some empty atlases deletion to avoid possible creation of new atlas immediately. -}; - -#endif diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index f932acd48c..37ed2e9f20 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -1476,6 +1476,10 @@ void LLViewerFetchedTexture::addToCreateTexture()  BOOL LLViewerFetchedTexture::preCreateTexture(S32 usename/*= 0*/)  {      LL_PROFILE_ZONE_SCOPED; +#if LL_IMAGEGL_THREAD_CHECK +    mGLTexturep->checkActiveThread(); +#endif +      if (!mNeedsCreateTexture)      {          destroyRawImage(); @@ -1603,6 +1607,9 @@ void LLViewerFetchedTexture::postCreateTexture()      {          return;      } +#if LL_IMAGEGL_THREAD_CHECK +    mGLTexturep->checkActiveThread(); +#endif      notifyAboutCreatingTexture(); @@ -1619,36 +1626,45 @@ void LLViewerFetchedTexture::postCreateTexture()  void LLViewerFetchedTexture::scheduleCreateTexture()  { -    ref(); -    mNeedsCreateTexture = TRUE; -    if (preCreateTexture()) +    if (!mNeedsCreateTexture)      { +        ref();          mNeedsCreateTexture = TRUE; -#if LL_WINDOWS //flip to 0 to revert to single-threaded OpenGL texture uploads -        auto mainq = mMainQueue.lock(); -        if (mainq) +        if (preCreateTexture())          { -            mainq->postTo( -                mImageQueue, -                // work to be done on LLImageGL worker thread -                [this]() -                { -                    //actually create the texture on a background thread -                    createTexture(); -                }, -                // callback to be run on main thread -                [this]() -                { -                    //finalize on main thread -                    postCreateTexture(); -                    unref(); -                }); -        } -        else +            mNeedsCreateTexture = TRUE; +#if LL_WINDOWS //flip to 0 to revert to single-threaded OpenGL texture uploads +            auto mainq = mMainQueue.lock(); +            if (mainq) +            { +                mainq->postTo( +                    mImageQueue, +                    // work to be done on LLImageGL worker thread +                    [this]() +                    { +#if LL_IMAGEGL_THREAD_CHECK +                        mGLTexturep->mActiveThread = LLThread::currentID();  #endif -        { -            gTextureList.mCreateTextureList.insert(this); -            unref(); +                        //actually create the texture on a background thread +                        createTexture(); +                    }, +                    // callback to be run on main thread +                        [this]() +                    { +#if LL_IMAGEGL_THREAD_CHECK +                        mGLTexturep->mActiveThread = LLThread::currentID(); +#endif +                        //finalize on main thread +                        postCreateTexture(); +                        unref(); +                    }); +            } +            else +#endif +            { +                gTextureList.mCreateTextureList.insert(this); +                unref(); +            }          }      }  } @@ -2967,7 +2983,8 @@ void LLViewerFetchedTexture::destroyRawImage()  void LLViewerFetchedTexture::switchToCachedImage()  {      LL_PROFILE_ZONE_SCOPED; -	if(mCachedRawImage.notNull()) +	if(mCachedRawImage.notNull() &&  +        !mNeedsCreateTexture) // <--- texture creation is pending, don't step on it  	{  		mRawImage = mCachedRawImage; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 2f554bc9b8..4e7eb4df5d 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5189,6 +5189,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  		}  	} +    F32 vsize = facep->getVirtualSize(); //TODO -- adjust by texture scale?  	if (index < FACE_DO_NOT_BATCH_TEXTURES && idx >= 0)  	{ @@ -5202,10 +5203,12 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  			{  				batchable = true;  				draw_vec[idx]->mTextureList[index] = tex; +                draw_vec[idx]->mTextureListVSize[index] = vsize;  			}  			else if (draw_vec[idx]->mTextureList[index] == tex)  			{ //this face's texture index can be used with this batch  				batchable = true; +                draw_vec[idx]->mTextureListVSize[index] = llmax(vsize, draw_vec[idx]->mTextureListVSize[index]);  			}  		}  		else @@ -5236,12 +5239,14 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  	{  		draw_vec[idx]->mCount += facep->getIndicesCount();  		draw_vec[idx]->mEnd += facep->getGeomCount(); -		draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, facep->getVirtualSize()); +		draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize);  		if (index < FACE_DO_NOT_BATCH_TEXTURES && index >= draw_vec[idx]->mTextureList.size())  		{  			draw_vec[idx]->mTextureList.resize(index+1);  			draw_vec[idx]->mTextureList[index] = tex; +            draw_vec[idx]->mTextureListVSize.resize(index + 1); +            draw_vec[idx]->mTextureListVSize[index] = vsize;  		}  		draw_vec[idx]->validate();  		update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[0]); @@ -5256,7 +5261,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  		LLPointer<LLDrawInfo> draw_info = new LLDrawInfo(start,end,count,offset, tex,   			facep->getVertexBuffer(), selected, fullbright, bump);  		draw_info->mGroup = group; -		draw_info->mVSize = facep->getVirtualSize(); +		draw_info->mVSize = vsize;  		draw_vec.push_back(draw_info);  		draw_info->mTextureMatrix = tex_mat;  		draw_info->mModelMatrix = model_mat; @@ -5331,6 +5336,8 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  		{ //initialize texture list for texture batching  			draw_info->mTextureList.resize(index+1);  			draw_info->mTextureList[index] = tex; +            draw_info->mTextureListVSize.resize(index + 1); +            draw_info->mTextureListVSize[index] = vsize;  		}  		draw_info->validate();  	} diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index c122b4f43e..df676b30fc 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -3711,25 +3711,31 @@ void renderSoundHighlights(LLDrawable* drawablep)  }  } -void LLPipeline::touchTextures(LLDrawInfo* info) +void LLPipeline::touchTexture(LLViewerTexture* tex, F32 vsize)  { -    LL_PROFILE_ZONE_SCOPED; -    for (auto& tex : info->mTextureList) +    if (tex)      { -        if (tex.notNull()) +        LLImageGL* gl_tex = tex->getGLTexture(); +        if (gl_tex && gl_tex->updateBindStats(gl_tex->mTextureMemory))          { -            LLImageGL* gl_tex = tex->getGLTexture(); -            if (gl_tex && gl_tex->updateBindStats(gl_tex->mTextureMemory)) -            { -                tex->setActive(); -            } +            tex->setActive(); +            tex->addTextureStats(vsize);          }      } -    if (info->mTexture.notNull()) + +} +void LLPipeline::touchTextures(LLDrawInfo* info) +{ +    LL_PROFILE_ZONE_SCOPED; +    for (int i = 0; i < info->mTextureList.size(); ++i)      { -        info->mTexture->addTextureStats(info->mVSize); +        touchTexture(info->mTextureList[i], info->mTextureListVSize[i]);      } + +    touchTexture(info->mTexture, info->mVSize); +    touchTexture(info->mSpecularMap, info->mVSize); +    touchTexture(info->mNormalMap, info->mVSize);  }  void LLPipeline::postSort(LLCamera& camera) diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 3ac3e3ce01..794d806d0c 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -260,8 +260,11 @@ public:  	void stateSort(LLSpatialBridge* bridge, LLCamera& camera, BOOL fov_changed = FALSE);  	void stateSort(LLDrawable* drawablep, LLCamera& camera);  	void postSort(LLCamera& camera); +          //update stats for textures in given DrawInfo      void touchTextures(LLDrawInfo* info); +    void touchTexture(LLViewerTexture* tex, F32 vsize); +  	void forAllVisibleDrawables(void (*func)(LLDrawable*));      void renderObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false, bool rigged = false); | 
