Scott Lawrence avatar Scott Lawrence committed ff6f7a5 Merge

merge changes for DRTVWR-148

Comments (0)

Files changed (73)

 3d75c836d178c7c7e788f256afe195f6cab764a2 3.2.7-beta1
 89980333c99dbaf1787fe20784f1d8849e9b5d4f 3.2.8-start
 16f8e2915f3f2e4d732fb3125daf229cb0fd1875 DRTVWR-114_3.2.8-beta1
+37dd400ad721e2a89ee820ffc1e7e433c68f3ca2 3.2.9-start
 16f8e2915f3f2e4d732fb3125daf229cb0fd1875 3.2.8-beta1
 987425b1acf4752379b2e1eb20944b4b35d67a85 DRTVWR-115_3.2.8-beta2
 987425b1acf4752379b2e1eb20944b4b35d67a85 3.2.8-beta2
 51b2fd52e36aab8f670e0874e7e1472434ec4b4a DRTVWR-113_3.2.8-release
 51b2fd52e36aab8f670e0874e7e1472434ec4b4a 3.2.8-release
-37dd400ad721e2a89ee820ffc1e7e433c68f3ca2 3.2.9-start
 e9c82fca5ae6fb8a8af29012d78fb194a29323f3 DRTVWR-117_3.2.9-beta1
 e9c82fca5ae6fb8a8af29012d78fb194a29323f3 3.2.9-beta1
 a01ef9bed28627f4ca543fbc1d70c79cc297a90f DRTVWR-118_3.2.9-beta2
 675668bd24d3bea570814f71762a2a806f7e1b8d 3.3.2-release
 675668bd24d3bea570814f71762a2a806f7e1b8d viewer-release-candidate
 15e90b52dc0297921b022b90d10d797436b8a1bd viewer-release-candidate
+6414ecdabc5d89515b08d1f872cf923ed3a5523a DRTVWR-148

indra/linux_updater/linux_updater.cpp

 		else if ((!strcmp(argv[i], "--image-dir")) && (++i < argc))
 		{
 			app_state->image_dir = argv[i];
-			app_state->image_dir_iter = new LLDirIterator(argv[i], "/*.jpg");
+			app_state->image_dir_iter = new LLDirIterator(argv[i], "*.jpg");
 		}
 		else if ((!strcmp(argv[i], "--dest")) && (++i < argc))
 		{

indra/llmessage/llcurl.cpp

 	  mErrorCount(0),
 	  mState(STATE_READY),
 	  mDead(FALSE),
+	  mValid(TRUE),
 	  mMutexp(NULL),
 	  mDeletionMutexp(NULL),
 	  mEasyMutexp(NULL)
 
 LLCurl::Multi::~Multi()
 {
-	cleanup() ;	
+	cleanup(true) ;	
+	
+	delete mDeletionMutexp ;
+	mDeletionMutexp = NULL ;	
 }
 
-void LLCurl::Multi::cleanup()
+void LLCurl::Multi::cleanup(bool deleted)
 {
 	if(!mCurlMultiHandle)
 	{
 		return ; //nothing to clean.
 	}
+	llassert_always(deleted || !mValid) ;
 
+	LLMutexLock lock(mDeletionMutexp);
+	
 	// Clean up active
 	for(easy_active_list_t::iterator iter = mEasyActiveList.begin();
 		iter != mEasyActiveList.end(); ++iter)
 	{
 		Easy* easy = *iter;
 		check_curl_multi_code(curl_multi_remove_handle(mCurlMultiHandle, easy->getCurlHandle()));
+
+		if(deleted)
+		{
+			easy->mResponder = NULL ; //avoid triggering mResponder.
+		}
 		delete easy;
 	}
 	mEasyActiveList.clear();
 
 	check_curl_multi_code(LLCurl::deleteMultiHandle(mCurlMultiHandle));
 	mCurlMultiHandle = NULL ;
-
+	
 	delete mMutexp ;
 	mMutexp = NULL ;
-	delete mDeletionMutexp ;
-	mDeletionMutexp = NULL ;
 	delete mEasyMutexp ;
 	mEasyMutexp = NULL ;
 
 
 void LLCurl::Multi::markDead()
 {
-	LLMutexLock lock(mDeletionMutexp) ;
+	{
+		LLMutexLock lock(mDeletionMutexp) ;
 	
-	mDead = TRUE ;
-	LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_URGENT) ; 
+		if(mCurlMultiHandle != NULL)
+		{
+			mDead = TRUE ;
+			LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_URGENT) ; 
+
+			return;
+		}
+	}
+	
+	//not valid, delete it.
+	delete this;	
 }
 
 void LLCurl::Multi::setState(LLCurl::Multi::ePerformState state)
 		setState(STATE_COMPLETED) ;
 		mIdleTimer.reset() ;
 	}
-	else if(mIdleTimer.getElapsedTimeF32() > mIdleTimeOut) //idle for too long, remove it.
+	else if(!mValid && mIdleTimer.getElapsedTimeF32() > mIdleTimeOut) //idle for too long, remove it.
 	{
 		dead = true ;
 	}
+	else if(mValid && mIdleTimer.getElapsedTimeF32() > mIdleTimeOut - 1.f) //idle for too long, mark it invalid.
+	{
+		mValid = FALSE ;
+	}
 
 	return dead ;
 }
 		return ;
 	}
 
-	if(multi->isValid())
-	{
 	multi->markDead() ;
 }
-	else
-	{
-		deleteMulti(multi) ;
-	}
-}
 
 //private
 bool LLCurlThread::doMultiPerform(LLCurl::Multi* multi) 
 void LLCurlThread::cleanupMulti(LLCurl::Multi* multi) 
 {
 	multi->cleanup() ;
+	if(multi->isDead()) //check if marked dead during cleaning up.
+	{
+		deleteMulti(multi) ;
+	}
 }
 
 //------------------------------------------------------------

indra/llmessage/llcurl.h

 	ePerformState getState() ;
 	
 	bool isCompleted() ;
-	bool isValid() {return mCurlMultiHandle != NULL ;}
+	bool isValid() {return mCurlMultiHandle != NULL && mValid;}
 	bool isDead() {return mDead;}
 
 	bool waitToComplete() ;
 	
 private:
 	void easyFree(LLCurl::Easy*);
-	void cleanup() ;
+	void cleanup(bool deleted = false) ;
 	
 	CURLM* mCurlMultiHandle;
 
 	ePerformState mState;
 
 	BOOL mDead ;
+	BOOL mValid ;
 	LLMutex* mMutexp ;
 	LLMutex* mDeletionMutexp ;
 	LLMutex* mEasyMutexp ;

indra/llrender/llgl.cpp

 	llwarns << "Severity: " << std::hex << severity << llendl;
 	llwarns << "Message: " << message << llendl;
 	llwarns << "-----------------------" << llendl;
+	if (severity == GL_DEBUG_SEVERITY_HIGH_ARB)
+	{
+		llerrs << "Halting on GL Error" << llendl;
+	}
 }
 #endif
 
 #endif
 	}
 
+	if (mGLVersion >= 2.1f && LLImageGL::sCompressTextures)
+	{ //use texture compression
+		glHint(GL_TEXTURE_COMPRESSION_HINT, GL_NICEST);
+	}
+	else
+	{ //GL version is < 3.0, always disable texture compression
+		LLImageGL::sCompressTextures = false;
+	}
+	
 	// Trailing space necessary to keep "nVidia Corpor_ati_on" cards
 	// from being recognized as ATI.
 	if (mGLVendor.substr(0,4) == "ATI ")
 #endif // LL_WINDOWS
 
 #if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS
-		// release 7277 is a point at which we verify that ATI OpenGL
-		// drivers get pretty stable with SL, ~Catalyst 8.2,
-		// for both Win32 and Linux.
-		if (mDriverVersionRelease < 7277 &&
-		    mDriverVersionRelease != 0) // 0 == Undetectable driver version - these get to pretend to be new ATI drivers, though that decision may be revisited.
+		// count any pre OpenGL 3.0 implementation as an old driver
+		if (mGLVersion < 3.f) 
 		{
 			mATIOldDriver = TRUE;
 		}
 	}
 #endif
 
+	if (mIsIntel && mGLVersion <= 3.f)
+	{ //never try to use framebuffer objects on older intel drivers (crashy)
+		mHasFramebufferObject = FALSE;
+	}
+
 	if (mHasFramebufferObject)
 	{
 		glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples);
 	glClientActiveTextureARB(GL_TEXTURE0_ARB);
 	gGL.getTexUnit(0)->activate();
 
-	if (gGLManager.mHasVertexShader)
+	if (gGLManager.mHasVertexShader && LLGLSLShader::sNoFixedFunction)
 	{	//make sure vertex attribs are all disabled
 		GLint count;
 		glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &count);

indra/llrender/llimagegl.cpp

 F32 LLImageGL::sLastFrameTime			= 0.f;
 BOOL LLImageGL::sAllowReadBackRaw       = FALSE ;
 LLImageGL* LLImageGL::sDefaultGLTexture = NULL ;
+bool LLImageGL::sCompressTextures = false;
 
 std::set<LLImageGL*> LLImageGL::sImageList;
 
 	mDiscardLevelInAtlas = -1 ;
 	mTexelsInAtlas = 0 ;
 	mTexelsInGLTexture = 0 ;
+
+	mAllowCompression = true;
 	
 	mTarget = GL_TEXTURE_2D;
 	mBindTarget = LLTexUnit::TT_TEXTURE;
 						stop_glerror();
 					}
 						
-					LLImageGL::setManualImage(mTarget, gl_level, mFormatInternal, w, h, mFormatPrimary, GL_UNSIGNED_BYTE, (GLvoid*)data_in);
+					LLImageGL::setManualImage(mTarget, gl_level, mFormatInternal, w, h, mFormatPrimary, GL_UNSIGNED_BYTE, (GLvoid*)data_in, mAllowCompression);
 					if (gl_level == 0)
 					{
 						analyzeAlpha(data_in, w, h);
 					LLImageGL::setManualImage(mTarget, 0, mFormatInternal,
 								 w, h, 
 								 mFormatPrimary, mFormatType,
-								 data_in);
+								 data_in, mAllowCompression);
 					analyzeAlpha(data_in, w, h);
 					stop_glerror();
 
 							stop_glerror();
 						}
 
-						LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data);
+						LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data, mAllowCompression);
 						if (m == 0)
 						{
 							analyzeAlpha(data_in, w, h);
 			}
 
 			LLImageGL::setManualImage(mTarget, 0, mFormatInternal, w, h,
-						 mFormatPrimary, mFormatType, (GLvoid *)data_in);
+						 mFormatPrimary, mFormatType, (GLvoid *)data_in, mAllowCompression);
 			analyzeAlpha(data_in, w, h);
 			
 			updatePickMask(w, h, data_in);
 }
 
 // static
-void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels)
+void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels, bool allow_compression)
 {
 	bool use_scratch = false;
 	U32* scratch = NULL;
 		}
 	}
 
+	if (LLImageGL::sCompressTextures && allow_compression)
+	{
+		switch (intformat)
+		{
+			case GL_RGB: 
+			case GL_RGB8:
+				intformat = GL_COMPRESSED_RGB; 
+				break;
+			case GL_RGBA:
+			case GL_RGBA8:
+				intformat = GL_COMPRESSED_RGBA; 
+				break;
+			case GL_LUMINANCE:
+			case GL_LUMINANCE8:
+				intformat = GL_COMPRESSED_LUMINANCE;
+				break;
+			case GL_LUMINANCE_ALPHA:
+			case GL_LUMINANCE8_ALPHA8:
+				intformat = GL_COMPRESSED_LUMINANCE_ALPHA;
+				break;
+			case GL_ALPHA:
+			case GL_ALPHA8:
+				intformat = GL_COMPRESSED_ALPHA;
+				break;
+			default:
+				llwarns << "Could not compress format: " << std::hex << intformat << llendl;
+				break;
+		}
+	}
+
 	stop_glerror();
 	glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, use_scratch ? scratch : pixels);
 	stop_glerror();

indra/llrender/llimagegl.h

 	
 	void setSize(S32 width, S32 height, S32 ncomponents);
 	void setComponents(S32 ncomponents) { mComponents = (S8)ncomponents ;}
+	void setAllowCompression(bool allow) { mAllowCompression = allow; }
 
 	// These 3 functions currently wrap glGenTextures(), glDeleteTextures(), and glTexImage2D() 
 	// for tracking purposes and will be deprecated in the future
 	static void generateTextures(S32 numTextures, U32 *textures);
 	static void deleteTextures(S32 numTextures, U32 *textures, bool immediate = false);
-	static void setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels);
+	static void setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels, bool allow_compression = true);
 
 	BOOL createGLTexture() ;
 	BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE,
 	U32      mTexelsInAtlas ;
 	U32      mTexelsInGLTexture;
 
+	bool mAllowCompression;
+
 protected:
 	LLGLenum mTarget;		// Normally GL_TEXTURE2D, sometimes something else (ex. cube maps)
 	LLTexUnit::eTextureType mBindTarget;	// Normally TT_TEXTURE, sometimes something else (ex. cube maps)
 	static BOOL sGlobalUseAnisotropic;
 	static LLImageGL* sDefaultGLTexture ;	
 	static BOOL sAutomatedTest;
-
+	static bool sCompressTextures;			//use GL texture compression
 #if DEBUG_MISS
 	BOOL mMissed; // Missed on last bind?
 	BOOL getMissed() const { return mMissed; };

indra/llrender/llrendertarget.cpp

 
 	{
 		clear_glerror();
-		LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+		LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL, false);
 		if (glGetError() != GL_NO_ERROR)
 		{
 			llwarns << "Could not allocate color buffer for render target." << llendl;
 		U32 internal_type = LLTexUnit::getInternalType(mUsage);
 		stop_glerror();
 		clear_glerror();
-		LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT24, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
+		LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT24, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL, false);
 		gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
 	}
 

indra/llrender/llvertexbuffer.cpp

 #include "llglslshader.h"
 #include "llmemory.h"
 
+#define LL_VBO_POOLING 0
+
 //Next Highest Power Of Two
 //helper function, returns first number > v that is a power of 2, or v if v is already a power of 2
 U32 nhpo2(U32 v)
 	return r;
 }
 
+//which power of 2 is i?
+//assumes i is a power of 2 > 0
+U32 wpo2(U32 i)
+{
+	llassert(i > 0);
+	llassert(nhpo2(i) == i);
+
+	U32 r = 0;
+
+	while (i >>= 1) ++r;
+
+	return r;
+}
+
+
+const U32 LL_VBO_BLOCK_SIZE = 2048;
+
+U32 vbo_block_size(U32 size)
+{ //what block size will fit size?
+	U32 mod = size % LL_VBO_BLOCK_SIZE;
+	return mod == 0 ? size : size + (LL_VBO_BLOCK_SIZE-mod);
+}
+
+U32 vbo_block_index(U32 size)
+{
+	return vbo_block_size(size)/LL_VBO_BLOCK_SIZE;
+}
+
+
 
 //============================================================================
 
 LLVBOPool LLVertexBuffer::sDynamicVBOPool(GL_DYNAMIC_DRAW_ARB, GL_ARRAY_BUFFER_ARB);
 LLVBOPool LLVertexBuffer::sStreamIBOPool(GL_STREAM_DRAW_ARB, GL_ELEMENT_ARRAY_BUFFER_ARB);
 LLVBOPool LLVertexBuffer::sDynamicIBOPool(GL_DYNAMIC_DRAW_ARB, GL_ELEMENT_ARRAY_BUFFER_ARB);
+
 U32 LLVBOPool::sBytesPooled = 0;
+U32 LLVBOPool::sIndexBytesPooled = 0;
+U32 LLVertexBuffer::sAllocatedIndexBytes = 0;
+U32 LLVertexBuffer::sIndexCount = 0;
 
 LLPrivateMemoryPool* LLVertexBuffer::sPrivatePoolp = NULL;
 U32 LLVertexBuffer::sBindCount = 0;
 bool LLVertexBuffer::sVBOActive = false;
 bool LLVertexBuffer::sIBOActive = false;
 U32 LLVertexBuffer::sAllocatedBytes = 0;
+U32 LLVertexBuffer::sVertexCount = 0;
 bool LLVertexBuffer::sMapped = false;
 bool LLVertexBuffer::sUseStreamDraw = true;
 bool LLVertexBuffer::sUseVAO = false;
 };
 
 
-//which power of 2 is i?
-//assumes i is a power of 2 > 0
-U32 wpo2(U32 i)
-{
-	llassert(i > 0);
-	llassert(nhpo2(i) == i);
-
-	U32 r = 0;
-
-	while (i >>= 1) ++r;
-
-	return r;
-}
-
 volatile U8* LLVBOPool::allocate(U32& name, U32 size)
 {
-	llassert(nhpo2(size) == size);
+	llassert(vbo_block_size(size) == size);
+	
+	volatile U8* ret = NULL;
 
-	U32 i = wpo2(size);
+#if LL_VBO_POOLING
+
+	U32 i = vbo_block_index(size);
 
 	if (mFreeList.size() <= i)
 	{
 		mFreeList.resize(i+1);
 	}
 
-	volatile U8* ret = NULL;
-
 	if (mFreeList[i].empty())
 	{
 		//make a new buffer
 		glGenBuffersARB(1, &name);
 		glBindBufferARB(mType, name);
-		LLVertexBuffer::sAllocatedBytes += size;
+
+		if (mType == GL_ARRAY_BUFFER_ARB)
+		{
+			LLVertexBuffer::sAllocatedBytes += size;
+		}
+		else
+		{
+			LLVertexBuffer::sAllocatedIndexBytes += size;
+		}
 
 		if (LLVertexBuffer::sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB)
 		{
 		name = mFreeList[i].front().mGLName;
 		ret = mFreeList[i].front().mClientData;
 
-		sBytesPooled -= size;
+		if (mType == GL_ARRAY_BUFFER_ARB)
+		{
+			sBytesPooled -= size;
+		}
+		else
+		{
+			sIndexBytesPooled -= size;
+		}
 
 		mFreeList[i].pop_front();
 	}
+#else //no pooling
+
+	glGenBuffersARB(1, &name);
+	glBindBufferARB(mType, name);
+
+	if (mType == GL_ARRAY_BUFFER_ARB)
+	{
+		LLVertexBuffer::sAllocatedBytes += size;
+	}
+	else
+	{
+		LLVertexBuffer::sAllocatedIndexBytes += size;
+	}
+
+	if (LLVertexBuffer::sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB)
+	{
+		glBufferDataARB(mType, size, 0, mUsage);
+		ret = (U8*) ll_aligned_malloc_16(size);
+	}
+	else
+	{ //always use a true hint of static draw when allocating non-client-backed buffers
+		glBufferDataARB(mType, size, 0, GL_STATIC_DRAW_ARB);
+	}
+
+	glBindBufferARB(mType, 0);
+
+#endif
 
 	return ret;
 }
 
 void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)
 {
-	llassert(nhpo2(size) == size);
+	llassert(vbo_block_size(size) == size);
 
-	U32 i = wpo2(size);
+#if LL_VBO_POOLING
+
+	U32 i = vbo_block_index(size);
 
 	llassert(mFreeList.size() > i);
 
 	}
 	else
 	{
-		sBytesPooled += size;
+		if (mType == GL_ARRAY_BUFFER_ARB)
+		{
+			sBytesPooled += size;
+		}
+		else
+		{
+			sIndexBytesPooled += size;
+		}
 		mFreeList[i].push_back(rec);
 	}
+#else //no pooling
+	glDeleteBuffersARB(1, &name);
+	ll_aligned_free_16((U8*) buffer);
+
+	if (mType == GL_ARRAY_BUFFER_ARB)
+	{
+		LLVertexBuffer::sAllocatedBytes -= size;
+	}
+	else
+	{
+		LLVertexBuffer::sAllocatedIndexBytes -= size;
+	}
+#endif
 }
 
 void LLVBOPool::cleanup()
 
 			l.pop_front();
 
-			LLVertexBuffer::sAllocatedBytes -= size;
-			sBytesPooled -= size;
+			if (mType == GL_ARRAY_BUFFER_ARB)
+			{
+				sBytesPooled -= size;
+				LLVertexBuffer::sAllocatedBytes -= size;
+			}
+			else
+			{
+				sIndexBytesPooled -= size;
+				LLVertexBuffer::sAllocatedIndexBytes -= size;
+			}
 		}
 
 		size *= 2;
 	
 	mFence = NULL;
 
+	sVertexCount -= mNumVerts;
+	sIndexCount -= mNumIndices;
+
 	llassert_always(!mMappedData && !mMappedIndexData);
 };
 
 
 void LLVertexBuffer::genBuffer(U32 size)
 {
-	mSize = nhpo2(size);
+	mSize = vbo_block_size(size);
 
 	if (mUsage == GL_STREAM_DRAW_ARB)
 	{
 
 void LLVertexBuffer::genIndices(U32 size)
 {
-	mIndicesSize = nhpo2(size);
+	mIndicesSize = vbo_block_size(size);
 
 	if (mUsage == GL_STREAM_DRAW_ARB)
 	{
 		createGLBuffer(needed_size);
 	}
 
+	sVertexCount -= mNumVerts;
 	mNumVerts = nverts;
+	sVertexCount += mNumVerts;
 }
 
 void LLVertexBuffer::updateNumIndices(S32 nindices)
 		createGLIndices(needed_size);
 	}
 
+	sIndexCount -= mNumIndices;
 	mNumIndices = nindices;
+	sIndexCount += mNumIndices;
 }
 
 void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)

indra/llrender/llvertexbuffer.h

 {
 public:
 	static U32 sBytesPooled;
+	static U32 sIndexBytesPooled;
 	
 	LLVBOPool(U32 vboUsage, U32 vboType)
 		: mUsage(vboUsage)
 	static bool sIBOActive;
 	static U32 sLastMask;
 	static U32 sAllocatedBytes;
+	static U32 sAllocatedIndexBytes;
+	static U32 sVertexCount;
+	static U32 sIndexCount;
 	static U32 sBindCount;
 	static U32 sSetCount;
 };

indra/llui/llmultifloater.cpp

 
 BOOL LLMultiFloater::handleKeyHere(KEY key, MASK mask)
 {
-	if (key == 'W' && mask == (MASK_CONTROL|MASK_SHIFT))
+	if (key == 'W' && mask == MASK_CONTROL)
 	{
 		LLFloater* floater = getActiveFloater();
 		// is user closeable and is system closeable

indra/llvfs/lldir.cpp

 	std::string fullpath;
 	S32 result;
 
+	// File masks starting with "/" will match nothing, so we consider them invalid.
+	if (LLStringUtil::startsWith(mask, getDirDelimiter()))
+	{
+		llwarns << "Invalid file mask: " << mask << llendl;
+		llassert(!"Invalid file mask");
+	}
+
 	LLDirIterator iter(dirname, mask);
 	while (iter.next(filename))
 	{

indra/llwindow/llwindowwin32.cpp

 			}
 			else
 			{
-				llinfos << "Created OpenGL " << llformat("%d.%d", attribs[1], attribs[3]) << " context." << llendl;
+				llinfos << "Created OpenGL " << llformat("%d.%d", attribs[1], attribs[3]) << 
+					(LLRender::sGLCoreProfile ? " core" : " compatibility") << " context." << llendl;
 				done = true;
 
 				if (LLRender::sGLCoreProfile)

indra/mac_updater/mac_updater.cpp

 	
 			llinfos << "Clearing cache..." << llendl;
 			
-			char mask[LL_MAX_PATH];		/* Flawfinder: ignore */
-			snprintf(mask, LL_MAX_PATH, "%s*.*", gDirUtilp->getDirDelimiter().c_str());		
-			gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""),mask);
+			gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""), "*.*");
 			
 			llinfos << "Clear complete." << llendl;
 

indra/newview/app_settings/settings.xml

       <key>Value</key>
       <integer>1</integer>
     </map>
+  <key>RenderCompressTextures</key>
+  <map>
+    <key>Comment</key>
+    <string>Enable texture compression on OpenGL 3.0 and later implementations (EXPERIMENTAL, requires restart)</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>0</integer>
+  </map>
     <key>RenderPerformanceTest</key>
     <map>
       <key>Comment</key>
     <key>Value</key>
     <integer>0</integer>
   </map>
-    <key>RenderUseShaderLOD</key>
-    <map>
-      <key>Comment</key>
-      <string>Whether we want to have different shaders for LOD</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>Boolean</string>
-      <key>Value</key>
-      <integer>1</integer>
-    </map>
-    <key>RenderUseShaderNearParticles</key>
-    <map>
-      <key>Comment</key>
-      <string>Whether we want to use shaders on near particles</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>Boolean</string>
-      <key>Value</key>
-      <integer>0</integer>
-    </map>
+    
+  <key>RenderAutoHideSurfaceAreaLimit</key>
+  <map>
+    <key>Comment</key>
+    <string>Maximum surface area of a set of proximal objects inworld before automatically hiding geometry to prevent system overload.</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>F32</string>
+    <key>Value</key>
+    <integer>0</integer>
+  </map>
+
     <key>RenderVBOEnable</key>
     <map>
       <key>Comment</key>

indra/newview/featuretable.txt

 Disregard128DefaultDrawDistance	1	1
 Disregard96DefaultDrawDistance	1	1
 RenderTextureMemoryMultiple		1	1.0
+RenderCompressTextures		1	1
 RenderShaderLightingMaxLevel	1	3
 RenderDeferred				1	1
 RenderDeferredSSAO			1	1
 
 
 //
+// Low Graphics Settings (fixed function)
+//
+list LowFixedFunction
+RenderAnisotropic			1	0
+RenderAvatarCloth			1	0
+RenderAvatarLODFactor		1	0
+RenderAvatarPhysicsLODFactor 1	0
+RenderAvatarMaxVisible      1   3
+RenderAvatarVP				1	0
+RenderFarClip				1	64
+RenderFlexTimeFactor		1	0
+RenderGlowResolutionPow		1	8
+RenderMaxPartCount			1	0
+RenderObjectBump			1	0
+RenderLocalLights			1	0
+RenderReflectionDetail		1	0
+RenderTerrainDetail			1	0
+RenderTerrainLODFactor		1	1
+RenderTransparentWater		1	0
+RenderTreeLODFactor			1	0
+RenderUseImpostors			1	1
+RenderVolumeLODFactor		1	1.125
+VertexShaderEnable			1	0
+WindLightUseAtmosShaders	1	0
+WLSkyDetail					1	48
+RenderDeferred				1	0
+RenderDeferredSSAO			1	0
+RenderShadowDetail			1	0
+RenderFSAASamples			1	0
+
+
+//
 // Low Graphics Settings
 //
 list Low
 RenderTreeLODFactor			1	0
 RenderUseImpostors			1	1
 RenderVolumeLODFactor		1	1.125
-VertexShaderEnable			1	0
+VertexShaderEnable			1	1
 WindLightUseAtmosShaders	1	0
 WLSkyDetail					1	48
 RenderDeferred				1	0
 RenderVBOEnable				1	1
 
 //
+// VRAM > 512MB
+//
+list VRAMGT512
+RenderCompressTextures		1	0
+
+//
 // No Pixel Shaders available
 //
 list NoPixelShaders
 list Intel
 RenderAnisotropic			1	0
 RenderVBOEnable				1	0
+RenderFSAASamples			1	0
 
 list GeForce2
 RenderAnisotropic			1	0

indra/newview/featuretable_linux.txt

 Disregard128DefaultDrawDistance	1	1
 Disregard96DefaultDrawDistance	1	1
 RenderTextureMemoryMultiple		1	1.0
+RenderCompressTextures		1	1
 RenderShaderLightingMaxLevel		1	3
 RenderDeferred				1	1
 RenderDeferredSSAO			1	1
 RenderMaxTextureIndex		1	16
 
 //
+// Low Graphics Settings (fixed function)
+//
+list LowFixedFunction
+RenderAnisotropic			1	0
+RenderAvatarCloth			1	0
+RenderAvatarLODFactor		1	0
+RenderAvatarPhysicsLODFactor 1	0
+RenderAvatarMaxVisible      1   3
+RenderAvatarVP				1	0
+RenderFarClip				1	64
+RenderFlexTimeFactor		1	0
+RenderGlowResolutionPow		1	8
+RenderLocalLights			1	0
+RenderMaxPartCount			1	0
+RenderObjectBump			1	0
+RenderReflectionDetail		1	0
+RenderTerrainDetail			1	0
+RenderTerrainLODFactor		1	1
+RenderTransparentWater		1	0
+RenderTreeLODFactor			1	0
+RenderUseImpostors			1	1
+RenderVolumeLODFactor		1	0.5
+VertexShaderEnable			1	1
+WindLightUseAtmosShaders	1	0
+WLSkyDetail					1	48
+RenderDeferred				1	0
+RenderDeferredSSAO			1	0
+RenderShadowDetail			1	0
+RenderFSAASamples			1	0
+
+//
 // Low Graphics Settings
 //
 list Low
 RenderVBOEnable				1	1
 
 //
+// VRAM > 512MB
+//
+list VRAMGT512
+RenderCompressTextures		1	0
+
+//
 // No Pixel Shaders available
 //
 list NoPixelShaders
 list OpenGLPre15
 RenderVBOEnable				1	0
 
+list OpenGLPre30
+RenderDeferred				0	0
+RenderMaxTextureIndex		1	1
+
 list Intel
 RenderAnisotropic			1	0
 // Avoid some Intel crashes on Linux
 RenderCubeMap				0	0
+RenderFSAASamples			1	0
 
 list GeForce2
 RenderAnisotropic			1	0

indra/newview/featuretable_mac.txt

 Disregard128DefaultDrawDistance	1	1
 Disregard96DefaultDrawDistance	1	1
 RenderTextureMemoryMultiple		1	0.5
+RenderCompressTextures			1	1
 RenderShaderLightingMaxLevel	1	3
 RenderDeferred				1	1
 RenderDeferredSSAO			1	1
 RenderMaxTextureIndex		1	16
 
 //
+// Low Graphics Settings (fixed function)
+//
+list LowFixedFunction
+RenderAnisotropic			1	0
+RenderAvatarCloth			1	0
+RenderAvatarLODFactor		1	0
+RenderAvatarPhysicsLODFactor 1	0
+RenderAvatarMaxVisible      1   3
+RenderAvatarVP				1	0
+RenderFarClip				1	64
+RenderFlexTimeFactor		1	0
+RenderGlowResolutionPow		1	8
+RenderLocalLights			1	0
+RenderMaxPartCount			1	0
+RenderObjectBump			1	0
+RenderReflectionDetail		1	0
+RenderTerrainDetail			1	0
+RenderTerrainLODFactor		1	1
+RenderTransparentWater		1	0
+RenderTreeLODFactor			1	0
+RenderUseImpostors			1	1
+RenderVolumeLODFactor		1	0.5
+VertexShaderEnable			1	0
+WindLightUseAtmosShaders	1	0
+WLSkyDetail					1	48
+RenderDeferred				1	0
+RenderDeferredSSAO			1	0
+RenderShadowDetail			1	0
+RenderFSAASamples			1	0
+
+//
 // Low Graphics Settings
 //
 list Low
 RenderTreeLODFactor			1	0
 RenderUseImpostors			1	1
 RenderVolumeLODFactor		1	0.5
-VertexShaderEnable			1	0
+VertexShaderEnable			1	1
 WindLightUseAtmosShaders	1	0
 WLSkyDetail					1	48
 RenderDeferred				1	0
 RenderShadowDetail			0	0
 
 //
+// VRAM > 512MB
+//
+list VRAMGT512
+RenderCompressTextures		1	0
+
+//
 // "Default" setups for safe, low, medium, high
 //
 list safe
 list OpenGLPre15
 RenderVBOEnable				1	0
 
+
 list TexUnit8orLess
 RenderDeferredSSAO			0	0
 
 list Intel
 RenderAnisotropic			1	0
 RenderLocalLights			1	0
+RenderFSAASamples			1	0
 
 list GeForce2
 RenderAnisotropic			1	0

indra/newview/featuretable_xp.txt

 Disregard128DefaultDrawDistance	1	1
 Disregard96DefaultDrawDistance	1	1
 RenderTextureMemoryMultiple		1	1.0
+RenderCompressTextures		1	1
 RenderShaderLightingMaxLevel	1	3
 RenderDeferred				1	0
 RenderDeferredSSAO			1	0
 RenderMaxTextureIndex		1	16
 
 //
+// Low Graphics Settings (fixed function)
+//
+list LowFixedFunction
+RenderAnisotropic			1	0
+RenderAvatarCloth			1	0
+RenderAvatarLODFactor		1	0
+RenderAvatarPhysicsLODFactor 1	0
+RenderAvatarMaxVisible      1   3
+RenderAvatarVP				1	0
+RenderFarClip				1	64
+RenderFlexTimeFactor		1	0
+RenderGlowResolutionPow		1	8
+RenderLocalLights			1	0
+RenderMaxPartCount			1	0
+RenderObjectBump			1	0
+RenderReflectionDetail		1	0
+RenderTerrainDetail			1	0
+RenderTerrainLODFactor		1	1
+RenderTransparentWater		1	0
+RenderTreeLODFactor			1	0
+RenderUseImpostors			1	1
+RenderVolumeLODFactor		1	0.5
+VertexShaderEnable			1	0
+WindLightUseAtmosShaders	1	0
+WLSkyDetail					1	48
+RenderDeferred				1	0
+RenderDeferredSSAO			1	0
+RenderShadowDetail			1	0
+RenderFSAASamples			1	0
+
+//
 // Low Graphics Settings
 //
 list Low
 RenderTreeLODFactor			1	0
 RenderUseImpostors			1	1
 RenderVolumeLODFactor		1	0.5
-VertexShaderEnable			1	0
+VertexShaderEnable			1	1
 WindLightUseAtmosShaders	1	0
 WLSkyDetail					1	48
 RenderDeferred				1	0
 RenderVBOEnable				1	1
 
 //
+// VRAM > 512MB
+//
+list VRAMGT512
+RenderCompressTextures		1	0
+
+//
 // No Pixel Shaders available
 //
 list NoPixelShaders
 list Intel
 RenderAnisotropic			1	0
 RenderVBOEnable				1	0
+RenderFSAASamples			1	0
 
 list GeForce2
 RenderAnisotropic			1	0

indra/newview/gpu_table.txt

 ATI Radeon X900					.*ATI.*Radeon ?X9.*							2		1
 ATI Radeon Xpress				.*ATI.*Radeon Xpress.*						0		1
 ATI Rage 128					.*ATI.*Rage 128.*							0		1
+ATI R300 (9700)					.*R300.*									1		1
 ATI R350 (9800)					.*R350.*									1		1
 ATI R580 (X1900)				.*R580.*									3		1
 ATI RC410 (Xpress 200)			.*RC410.*									0		0

indra/newview/llappviewer.cpp

 	LLRender::sGLCoreProfile = gSavedSettings.getBOOL("RenderGLCoreProfile");
 
 	LLImageGL::sGlobalUseAnisotropic	= gSavedSettings.getBOOL("RenderAnisotropic");
+	LLImageGL::sCompressTextures		= gSavedSettings.getBOOL("RenderCompressTextures");
 	LLVOVolume::sLODFactor				= gSavedSettings.getF32("RenderVolumeLODFactor");
 	LLVOVolume::sDistanceFactor			= 1.f-LLVOVolume::sLODFactor * 0.1f;
 	LLVolumeImplFlexible::sUpdateFactor = gSavedSettings.getF32("RenderFlexTimeFactor");
 	gAgentPilot.setNumRuns(gSavedSettings.getS32("StatsNumRuns"));
 	gAgentPilot.setQuitAfterRuns(gSavedSettings.getBOOL("StatsQuitAfterRuns"));
 	gAgent.setHideGroupTitle(gSavedSettings.getBOOL("RenderHideGroupTitle"));
-
+		
 	gDebugWindowProc = gSavedSettings.getBOOL("DebugWindowProc");
 	gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates");
 	LLWorldMapView::sMapScale = gSavedSettings.getF32("MapScale");
 		}
 	}
 
+#if LL_WINDOWS
+	if (gGLManager.mIsIntel && 
+		LLFeatureManager::getInstance()->getGPUClass() > 0 &&
+		gGLManager.mGLVersion <= 3.f)
+	{
+		LLNotificationsUtil::add("IntelOldDriver");
+	}
+#endif
+
 
 	// save the graphics card
 	gDebugInfo["GraphicsCard"] = LLFeatureManager::getInstance()->getGPUString();
 	if (! isError())
 	{
 		std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "");
-		logdir += gDirUtilp->getDirDelimiter();
 		gDirUtilp->deleteFilesInDir(logdir, "*-*-*-*-*.dmp");
 	}
 
 	if (mPurgeOnExit)
 	{
 		llinfos << "Purging all cache files on exit" << llendflush;
-		std::string mask = gDirUtilp->getDirDelimiter() + "*.*";
-		gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""),mask);
+		gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""), "*.*");
 	}
 
 	removeMarkerFile(); // Any crashes from here on we'll just have to ignore
 
 void LLAppViewer::removeCacheFiles(const std::string& file_mask)
 {
-	std::string mask = gDirUtilp->getDirDelimiter() + file_mask;
-	gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), mask);
+	gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), file_mask);
 }
 
 void LLAppViewer::writeSystemInfo()
 	LL_INFOS("AppCache") << "Purging Cache and Texture Cache..." << LL_ENDL;
 	LLAppViewer::getTextureCache()->purgeCache(LL_PATH_CACHE);
 	LLVOCache::getInstance()->removeCache(LL_PATH_CACHE);
-	std::string mask = "*.*";
-	gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), mask);
+	gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), "*.*");
 }
 
 std::string LLAppViewer::getSecondLifeTitle() const

indra/newview/llavataractions.cpp

 		}
 
 		S32 count = LLShareInfo::instance().mAvatarNames.size();
-		bool shared = false;
+		bool shared = count && !inventory_selected_uuids.empty();
 
 		// iterate through avatars
 		for(S32 i = 0; i < count; ++i)
 				LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it);
 				if (inv_cat)
 				{
-					LLGiveInventory::doGiveInventoryCategory(avatar_uuid, inv_cat, session_id);
-					shared = true;
+					if (!LLGiveInventory::doGiveInventoryCategory(avatar_uuid, inv_cat, session_id, "ItemsShared"))
+					{
+						shared = false;
+					}
 					break;
 				}
 				LLViewerInventoryItem* inv_item = gInventory.getItem(*it);
 				}
 				else
 				{
-				LLGiveInventory::doGiveInventoryItem(avatar_uuid, inv_item, session_id);
-					shared = true;
+					if (!LLGiveInventory::doGiveInventoryItem(avatar_uuid, inv_item, session_id))
+					{
+						shared = false;
+					}
 				}
 			}
 			if (noncopy_items.beginArray() != noncopy_items.endArray())
 				LLSD payload;
 				payload["agent_id"] = avatar_uuid;
 				payload["items"] = noncopy_items;
+				payload["success_notification"] = "ItemsShared";
 				LLNotificationsUtil::add("CannotCopyWarning", substitutions, payload,
 					&LLGiveInventory::handleCopyProtectedItem);
+				shared = false;
 				break;
 			}
 		}

indra/newview/lldrawpoolbump.cpp

 			// immediately assign bump to a global smart pointer in case some local smart pointer
 			// accidentally releases it.
 			LLPointer<LLViewerTexture> bump = LLViewerTextureManager::getLocalTexture( TRUE );
-			
-			
+
 			if (!LLPipeline::sRenderDeferred)
 			{
 				LLFastTimer t(FTM_BUMP_SOURCE_CREATE);
 			}
 			else 
 			{ //convert to normal map
+				
+				//disable compression on normal maps to prevent errors below
+				bump->getGLTexture()->setAllowCompression(false);
+
 				{
 					LLFastTimer t(FTM_BUMP_SOURCE_CREATE);
 					bump->setExplicitFormat(GL_RGBA8, GL_ALPHA);

indra/newview/llfeaturemanager.cpp

 	switch (level)
 	{
 		case 0:
-			maskFeatures("Low");			
+			if (gGLManager.mGLVersion < 3.f || gGLManager.mIsIntel)
+			{ //only use fixed function by default if GL version < 3.0 or this is an intel graphics chip
+				maskFeatures("LowFixedFunction");			
+			}
+			else
+			{ //same as low, but with "Basic Shaders" enabled
+				maskFeatures("Low");
+			}
 			break;
 		case 1:
 			maskFeatures("Mid");
 	{
 		maskFeatures("MapBufferRange");
 	}
+	if (gGLManager.mVRAM > 512)
+	{
+		maskFeatures("VRAMGT512");
+	}
 
 	// now mask by gpu string
 	// Replaces ' ' with '_' in mGPUString to deal with inability for parser to handle spaces

indra/newview/llfloaterbvhpreview.cpp

 //-----------------------------------------------------------------------------
 void LLFloaterBvhPreview::resetMotion()
 {
+	if (!mAnimPreview)
+		return;
+
 	LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
 	BOOL paused = avatarp->areAnimationsPaused();
 
 //-----------------------------------------------------------------------------
 BOOL LLFloaterBvhPreview::handleScrollWheel(S32 x, S32 y, S32 clicks)
 {
+	if (!mAnimPreview)
+		return false;
+
 	mAnimPreview->zoom((F32)clicks * -0.2f);
 	mAnimPreview->requestUpdate();
 
 //-----------------------------------------------------------------------------
 void LLFloaterBvhPreview::onCommitLoop()
 {
-	if (!getEnabled())
+	if (!getEnabled() || !mAnimPreview)
 		return;
 	
 	LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
 //-----------------------------------------------------------------------------
 void LLFloaterBvhPreview::onCommitLoopIn()
 {
-	if (!getEnabled())
+	if (!getEnabled() || !mAnimPreview)
 		return;
 
 	LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
 //-----------------------------------------------------------------------------
 void LLFloaterBvhPreview::onCommitLoopOut()
 {
-	if (!getEnabled())
+	if (!getEnabled() || !mAnimPreview)
 		return;
 
 	LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
 //-----------------------------------------------------------------------------
 void LLFloaterBvhPreview::onCommitName()
 {
-	if (!getEnabled())
+	if (!getEnabled() || !mAnimPreview)
 		return;
 
 	LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
 //-----------------------------------------------------------------------------
 void LLFloaterBvhPreview::onCommitPriority()
 {
-	if (!getEnabled())
+	if (!getEnabled() || !mAnimPreview)
 		return;
 
 	LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
 //-----------------------------------------------------------------------------
 void LLFloaterBvhPreview::onCommitEaseIn()
 {
-	if (!getEnabled())
+	if (!getEnabled() || !mAnimPreview)
 		return;
 
 	LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
 //-----------------------------------------------------------------------------
 void LLFloaterBvhPreview::onCommitEaseOut()
 {
-	if (!getEnabled())
+	if (!getEnabled() || !mAnimPreview)
 		return;
 
 	LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
 //-----------------------------------------------------------------------------
 bool LLFloaterBvhPreview::validateEaseIn(const LLSD& data)
 {
-	if (!getEnabled())
+	if (!getEnabled() || !mAnimPreview)
 		return false;
 
 	LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
 //-----------------------------------------------------------------------------
 bool LLFloaterBvhPreview::validateEaseOut(const LLSD& data)
 {
-	if (!getEnabled())
+	if (!getEnabled() || !mAnimPreview)
 		return false;
 
 	LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();

indra/newview/llfloaterhardwaresettings.cpp

 #include "llspinctrl.h"
 #include "llstartup.h"
 #include "lltextbox.h"
+#include "llcombobox.h"
 #include "pipeline.h"
 
 // Linden library includes
 		getChildView("vbo")->setEnabled(FALSE);
 	}
 
+	if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderCompressTextures") ||
+		!gGLManager.mHasVertexBufferObject)
+	{
+		getChildView("texture compression")->setEnabled(FALSE);
+	}
+
 	// if no windlight shaders, turn off nighttime brightness, gamma, and fog distance
 	LLSpinCtrl* gamma_ctrl = getChild<LLSpinCtrl>("gamma");
 	gamma_ctrl->setEnabled(!gPipeline.canUseWindLightShaders());
 {
 	childSetAction("OK", onBtnOK, this);
 
+	if (gGLManager.mIsIntel || gGLManager.mGLVersion < 3.f)
+	{ //remove FSAA settings above "4x"
+		LLComboBox* combo = getChild<LLComboBox>("fsaa");
+		combo->remove("8x");
+		combo->remove("16x");
+	}
+
 	refresh();
 	center();
 
Add a comment to this file

indra/newview/llfolderview.cpp

File contents unchanged.

indra/newview/llfolderviewitem.cpp

 	
 	item->dirtyFilter();
 
-	// Update the folder creation date if the folder has no creation date
-	bool setting_date = false;
-	const time_t item_creation_date = item->getCreationDate();
-	if ((item_creation_date > 0) && (mCreationDate == 0))
-	{
-		setCreationDate(item_creation_date);
-		setting_date = true;
-	}
+	// Update the folder creation date if the child is newer than our current date
+	setCreationDate(llmax<time_t>(mCreationDate, item->getCreationDate()));
 
 	// Handle sorting
 	requestArrange();
 	LLFolderViewFolder* parentp = getParentFolder();
 	while (parentp)
 	{
-		// Update the parent folder creation date
-		if (setting_date && (parentp->mCreationDate == 0))
-		{
-			parentp->setCreationDate(item_creation_date);
-		}
+		// Update the folder creation date if the child is newer than our current date
+		parentp->setCreationDate(llmax<time_t>(parentp->mCreationDate, item->getCreationDate()));
 
 		if (parentp->mSortFunction.isByDate())
 		{

indra/newview/llgiveinventory.cpp

 	return res;
 }
 
-void LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent,
+bool LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent,
 											  const LLInventoryCategory* cat,
-											  const LLUUID& im_session_id)
+											  const LLUUID& im_session_id,
+											  const std::string& notification_name)
 
 {
-	if (!cat) return;
+	if (!cat)
+	{
+		return false;
+	}
 	llinfos << "LLGiveInventory::giveInventoryCategory() - "
 		<< cat->getUUID() << llendl;
 
-	if (!isAgentAvatarValid()) return;
+	if (!isAgentAvatarValid())
+	{
+		return false;
+	}
 
+	bool give_successful = true;
 	// Test out how many items are being given.
 	LLViewerInventoryCategory::cat_array_t cats;
 	LLViewerInventoryItem::item_array_t items;
 	if (!complete)
 	{
 		LLNotificationsUtil::add("IncompleteInventory");
-		return;
+		give_successful = false;
 	}
 	count = items.count() + cats.count();
 	if (count > MAX_ITEMS)
 	{
 		LLNotificationsUtil::add("TooManyItems");
-		return;
+		give_successful = false;
 	}
 	else if (count == 0)
 	{
 		LLNotificationsUtil::add("NoItems");
-		return;
+		give_successful = false;
 	}
-	else
+	else if (give_successful)
 	{
 		if (0 == giveable.countNoCopy())
 		{
-			LLGiveInventory::commitGiveInventoryCategory(to_agent, cat, im_session_id);
+			give_successful = LLGiveInventory::commitGiveInventoryCategory(to_agent, cat, im_session_id);
 		}
 		else
 		{
 			LLSD payload;
 			payload["agent_id"] = to_agent;
 			payload["folder_id"] = cat->getUUID();
+			if (!notification_name.empty())
+			{
+				payload["success_notification"] = notification_name;
+			}
 			LLNotificationsUtil::add("CannotCopyCountItems", args, payload, &LLGiveInventory::handleCopyProtectedCategory);
+			give_successful = false;
 		}
 	}
+
+	return give_successful;
 }
 
 //////////////////////////////////////////////////////////////////////////
 	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
 	LLSD itmes = notification["payload"]["items"];
 	LLInventoryItem* item = NULL;
+	bool give_successful = true;
 	switch(option)
 	{
 	case 0:  // "Yes"
 			else
 			{
 				LLNotificationsUtil::add("CannotGiveItem");
+				give_successful = false;
 			}
 		}
+		if (give_successful && notification["payload"]["success_notification"].isDefined())
+		{
+			LLNotificationsUtil::add(notification["payload"]["success_notification"].asString());
+		}
 		break;
 
 	default: // no, cancel, whatever, who cares, not yes.
 		LLNotificationsUtil::add("TransactionCancelled");
+		give_successful = false;
 		break;
 	}
-	return false;
+	return give_successful;
 }
 
 // static
 {
 	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
 	LLInventoryCategory* cat = NULL;
+	bool give_successful = true;
 	switch(option)
 	{
 	case 0:  // "Yes"
 		cat = gInventory.getCategory(notification["payload"]["folder_id"].asUUID());
 		if (cat)
 		{
-			LLGiveInventory::commitGiveInventoryCategory(notification["payload"]["agent_id"].asUUID(),
+			give_successful = LLGiveInventory::commitGiveInventoryCategory(notification["payload"]["agent_id"].asUUID(),
 				cat);
 			LLViewerInventoryCategory::cat_array_t cats;
 			LLViewerInventoryItem::item_array_t items;
 				gInventory.deleteObject(items.get(i)->getUUID());
 			}
 			gInventory.notifyObservers();
+
+			if (give_successful && notification["payload"]["success_notification"].isDefined())
+			{
+				LLNotificationsUtil::add(notification["payload"]["success_notification"].asString());
+			}
 		}
 		else
 		{
 			LLNotificationsUtil::add("CannotGiveCategory");
+			give_successful = false;
 		}
 		break;
 
 	default: // no, cancel, whatever, who cares, not yes.
 		LLNotificationsUtil::add("TransactionCancelled");
+		give_successful = false;
 		break;
 	}
-	return false;
+	return give_successful;
 }
 
 // static
-void LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,
+bool LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,
 													const LLInventoryCategory* cat,
 													const LLUUID& im_session_id)
 
 {
-	if (!cat) return;
+	if (!cat)
+	{
+		return false;
+	}
 	llinfos << "LLGiveInventory::commitGiveInventoryCategory() - "
 		<< cat->getUUID() << llendl;
 
 		LLInventoryModel::EXCLUDE_TRASH,
 		giveable);
 
+	bool give_successful = true;
 	// MAX ITEMS is based on (sizeof(uuid)+2) * count must be <
 	// MTUBYTES or 18 * count < 1200 => count < 1200/18 =>
 	// 66. I've cut it down a bit from there to give some pad.
 	if (count > MAX_ITEMS)
 	{
 		LLNotificationsUtil::add("TooManyItems");
-		return;
+		give_successful = false;
 	}
 	else if (count == 0)
 	{
 		LLNotificationsUtil::add("NoItems");
-		return;
+		give_successful = false;
 	}
 	else
 	{
 
 		logInventoryOffer(to_agent, im_session_id);
 	}
+
+	return give_successful;
 }
 
 // EOF

indra/newview/llgiveinventory.h

 	/**
 	 * Gives passed inventory category to specified avatar in specified session.
 	 */
-	static void doGiveInventoryCategory(const LLUUID& to_agent,
+	static bool doGiveInventoryCategory(const LLUUID& to_agent,
 									const LLInventoryCategory* item,
-									const LLUUID &session_id = LLUUID::null);
+									const LLUUID &session_id = LLUUID::null,
+									const std::string& notification = std::string());
 
 	// give inventory item functionality
 	static bool handleCopyProtectedItem(const LLSD& notification, const LLSD& response);
 
 	// give inventory category functionality
 	static bool handleCopyProtectedCategory(const LLSD& notification, const LLSD& response);
-	static void commitGiveInventoryCategory(const LLUUID& to_agent,
+	static bool commitGiveInventoryCategory(const LLUUID& to_agent,
 									const LLInventoryCategory* cat,
 									const LLUUID &im_session_id = LLUUID::null);
 

indra/newview/llimfloatercontainer.cpp

 void LLIMFloaterContainer::onCloseFloater(LLUUID& id)
 {
 	mSessions.erase(id);
+	setFocus(TRUE);
 }
 
 void LLIMFloaterContainer::onNewMessageReceived(const LLSD& data)

indra/newview/llimview.cpp

 			//just like a normal IM
 			//this is just replicated code from process_improved_im
 			//and should really go in it's own function -jwolk
-			LLChat chat;
 
 			std::string message = message_params["message"].asString();
 			std::string name = message_params["from_name"].asString();
 				name,
 				LLMute::flagTextChat);
 
-			BOOL is_linden = LLMuteList::getInstance()->isLinden(name);
-			std::string separator_string(": ");
-			
-			chat.mMuted = is_muted && !is_linden;
-			chat.mFromID = from_id;
-			chat.mFromName = name;
-
-			if (!is_linden && is_busy)
+			if (is_busy || is_muted)
 			{
 				return;
 			}

indra/newview/llinspectobject.cpp

 	
 private:
 	LLUUID				mObjectID;
+	LLUUID				mPreviousObjectID;
 	S32					mObjectFace;
 	viewer_media_t		mMediaImpl;
 	LLMediaEntry*       mMediaEntry;
 {
 	// Release selection to deselect
 	mObjectSelection = NULL;
+	mPreviousObjectID = mObjectID;
 
 	getChild<LLMenuButton>("gear_btn")->hideMenu();
 }
 	LLSelectNode* nodep = selection->getFirstRootNode();
 	if (!nodep) return;
 
+	// If we don't have fresh object info yet and it's the object we inspected last time,
+	// keep showing the previously retrieved data until we get the update.
+	if (!nodep->mValid && nodep->getObject()->getID() == mPreviousObjectID)
+	{
+		return;
+	}
+
 	updateButtons(nodep);
 	updateName(nodep);
 	updateDescription(nodep);

indra/newview/llinventoryfilter.cpp

 		bool are_date_limits_valid = mFilterOps.mMinDate == time_min() && mFilterOps.mMaxDate == time_max();
 
 		bool is_increasing = hours > mFilterOps.mHoursAgo;
-		bool is_increasing_from_zero = is_increasing && !mFilterOps.mHoursAgo;
+		bool is_increasing_from_zero = is_increasing && !mFilterOps.mHoursAgo && !isSinceLogoff();
 
 		// *NOTE: need to cache last filter time, in case filter goes stale
 		BOOL less_restrictive = (are_date_limits_valid && ((is_increasing && mFilterOps.mHoursAgo)) || !hours);

indra/newview/llmeshrepository.cpp

 			mCurlRequest->process();
 			//sleep for 10ms to prevent eating a whole core
 			apr_sleep(10000);
-		} while (mCurlRequest->getQueued() > 0);
+		} while (!LLAppViewer::isQuitting() && mCurlRequest->getQueued() > 0);
 	}
 
 	delete mCurlRequest;

indra/newview/llnavigationbar.cpp

 	mBtnForward(NULL),
 	mBtnHome(NULL),
 	mCmbLocation(NULL),
-	mPurgeTPHistoryItems(false),
 	mSaveToLocationHistory(false)
 {
 	buildFromFile( "panel_navigation_bar.xml");
 
 void LLNavigationBar::draw()
 {
-	if(mPurgeTPHistoryItems)
-	{
-		LLTeleportHistory::getInstance()->purgeItems();
-		mPurgeTPHistoryItems = false;
-	}
-
 	if (isBackgroundVisible())
 	{
 		static LLUICachedControl<S32> drop_shadow_floater ("DropShadowFloater", 0);
 	LLLocationHistory* lh = LLLocationHistory::getInstance();
 	lh->removeItems();
 	lh->save();	
-	mPurgeTPHistoryItems= true;
+	LLTeleportHistory::getInstance()->purgeItems();
 }
 
 int LLNavigationBar::getDefNavBarHeight()

indra/newview/llnavigationbar.h

 	boost::signals2::connection	mTeleportFailedConnection;
 	boost::signals2::connection	mTeleportFinishConnection;
 	boost::signals2::connection	mHistoryMenuConnection;
-	bool						mPurgeTPHistoryItems;
 	// if true, save location to location history when teleport finishes
 	bool						mSaveToLocationHistory;
 };

indra/newview/llnearbychatbar.cpp

 
 	mNearbyChat = getChildView("nearby_chat");
 
-	LLUICtrl* show_btn = getChild<LLUICtrl>("show_nearby_chat");
+	gSavedSettings.declareBOOL("nearbychat_history_visibility", mNearbyChat->getVisible(), "Visibility state of nearby chat history", TRUE);
+	BOOL show_nearby_chat = gSavedSettings.getBOOL("nearbychat_history_visibility");
+
+	LLButton* show_btn = getChild<LLButton>("show_nearby_chat");
 	show_btn->setCommitCallback(boost::bind(&LLNearbyChatBar::onToggleNearbyChatPanel, this));
+	show_btn->setToggleState(show_nearby_chat);
 
 	mOutputMonitor = getChild<LLOutputMonitorCtrl>("chat_zone_indicator");
 	mOutputMonitor->setVisible(FALSE);
 
-	gSavedSettings.declareBOOL("nearbychat_history_visibility", mNearbyChat->getVisible(), "Visibility state of nearby chat history", TRUE);
-
-	mNearbyChat->setVisible(gSavedSettings.getBOOL("nearbychat_history_visibility"));
+	showNearbyChatPanel(show_nearby_chat);
 
 	// Register for font change notifications
 	LLViewerChat::setFontChangedCallback(boost::bind(&LLNearbyChatBar::onChatFontChange, this, _1));
 	}
 }
 
-
-void LLNearbyChatBar::onToggleNearbyChatPanel()
+void LLNearbyChatBar::showNearbyChatPanel(bool show)
 {
-	LLView* nearby_chat = getChildView("nearby_chat");
-
-	if (nearby_chat->getVisible())
+	if (!show)
 	{
-		if (!isMinimized())
+		if (mNearbyChat->getVisible() && !isMinimized())
 		{
 			mExpandedHeight = getRect().getHeight();
 		}
 		setResizeLimits(getMinWidth(), COLLAPSED_HEIGHT);
-		nearby_chat->setVisible(FALSE);
+		mNearbyChat->setVisible(FALSE);
 		reshape(getRect().getWidth(), COLLAPSED_HEIGHT);
 		enableResizeCtrls(true, true, false);
 		storeRectControl();
 	}
 	else
 	{
-		nearby_chat->setVisible(TRUE);
+		mNearbyChat->setVisible(TRUE);
 		setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT);
 		reshape(getRect().getWidth(), mExpandedHeight);
 		enableResizeCtrls(true);
 	gSavedSettings.setBOOL("nearbychat_history_visibility", mNearbyChat->getVisible());
 }
 
+void LLNearbyChatBar::onToggleNearbyChatPanel()
+{
+	showNearbyChatPanel(!mNearbyChat->getVisible());
+}
+
 void LLNearbyChatBar::setMinimized(BOOL b)
 {
 	LLNearbyChat* nearby_chat = getChild<LLNearbyChat>("nearby_chat");

indra/newview/llnearbychatbar.h

 
 class LLNearbyChatBar :	public LLFloater
 {
+	LOG_CLASS(LLNearbyChatBar);
+
 public:
 	// constructor for inline chat-bars (e.g. hosted in chat history window)
 	LLNearbyChatBar(const LLSD& key);
 
 	/* virtual */ bool applyRectControl();
 
+	void showNearbyChatPanel(bool show);
 	void onToggleNearbyChatPanel();
 
 	static LLWString stripChannelNumber(const LLWString &mesg, S32* channel);

indra/newview/llprogressview.cpp

 
 #include "llagent.h"
 #include "llbutton.h"
+#include "llcallbacklist.h"
 #include "llfocusmgr.h"
 #include "llnotifications.h"
 #include "llprogressbar.h"
 	mStartupComplete(false)
 {
 	mUpdateEvents.listen("self", boost::bind(&LLProgressView::handleUpdate, this, _1));
+	mFadeToWorldTimer.stop();
+	mFadeFromLoginTimer.stop();
 }
 
 BOOL LLProgressView::postBuild()
 
 	mCancelBtn = getChild<LLButton>("cancel_btn");
 	mCancelBtn->setClickedCallback(  LLProgressView::onCancelButtonClicked, NULL );
-	mFadeToWorldTimer.stop();
-	mFadeFromLoginTimer.stop();
 
 	getChild<LLTextBox>("title_text")->setText(LLStringExplicit(LLAppViewer::instance()->getSecondLifeTitle()));
 
 
 LLProgressView::~LLProgressView()
 {
+	// Just in case something went wrong, make sure we deregister our idle callback.
+	gIdleCallbacks.deleteFunction(onIdle, this);
+
 	gFocusMgr.releaseFocusIfNeeded( this );
 
 	sInstance = NULL;
 	}
 
 	mFadeFromLoginTimer.start();
+	gIdleCallbacks.addFunction(onIdle, this);
 }
 
 void LLProgressView::setStartupComplete()
<