diff --git a/autobuild.xml b/autobuild.xml
index 05e0ac28aef6940f09acf2648eeb82d30a8b3111..1bfc540eb9f90973d381c2b4f0ee63746f935530 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -1463,6 +1463,30 @@
           </map>
         </map>
       </map>
+      <key>nvapi</key>
+      <map>
+        <key>license</key>
+        <string>NVAPI</string>
+        <key>license_file</key>
+        <string>LICENSES/NVAPI_SDK_License_Agreement.pdf</string>
+        <key>name</key>
+        <string>nvapi</string>
+        <key>platforms</key>
+        <map>
+          <key>windows</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>baf519d36dffe4e4a59471450e391d01</string>
+              <key>url</key>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-nvapi/rev/267102/arch/CYGWIN/installer/nvapi-304-windows-20121116.tar.bz2</string>
+            </map>
+            <key>name</key>
+            <string>windows</string>
+          </map>
+        </map>
+      </map>
       <key>ogg-vorbis</key>
       <map>
         <key>license</key>
diff --git a/indra/cmake/NVAPI.cmake b/indra/cmake/NVAPI.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..78989c408f94f3f100085e7568a64d8125840c83
--- /dev/null
+++ b/indra/cmake/NVAPI.cmake
@@ -0,0 +1,17 @@
+# -*- cmake -*-
+include(Prebuilt)
+
+set(NVAPI ON CACHE BOOL "Use NVAPI.")
+
+if (NVAPI)
+  use_prebuilt_binary(nvapi)
+  
+  if (WINDOWS)
+    set(NVAPI_LIBRARY nvapi)
+  else (WINDOWS)
+    set(NVAPI_LIBRARY "")
+  endif (WINDOWS)
+else (NVAPI)
+  set(NVAPI_LIBRARY "")
+endif (NVAPI)
+
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 767aaf7fd5961608d98ea73bb27a6da649190b64..b90d377c23588632d7f61dca9c0138c5a65aaa29 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -34,6 +34,7 @@ include(LLXML)
 include(LScript)
 include(Linking)
 include(NDOF)
+include(NVAPI)
 include(GooglePerfTools)
 include(TemplateCheck)
 include(UI)
@@ -1812,6 +1813,7 @@ target_link_libraries(${VIEWER_BINARY_NAME}
     ${LLMATH_LIBRARIES}
     ${LLCOMMON_LIBRARIES}
     ${NDOF_LIBRARY}
+    ${NVAPI_LIBRARY}
     ${HUNSPELL_LIBRARY}
     ${viewer_LIBRARIES}
     ${BOOST_PROGRAM_OPTIONS_LIBRARY}
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 510ec47a31e6b2873731e479d39619df88a05e7a..23eb55875575937b2cd87fd97d3425ba55057556 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -46,6 +46,11 @@
 #include "llviewercontrol.h"
 #include "lldxhardware.h"
 
+#include "nvapi/nvapi.h"
+#include "nvapi/NvApiDriverSettings.h"
+
+#include <stdlib.h>
+
 #include "llweb.h"
 #include "llsecondlifeurls.h"
 
@@ -60,6 +65,7 @@
 #include "llwindebug.h"
 #endif
 
+
 // *FIX:Mani - This hack is to fix a linker issue with libndofdev.lib
 // The lib was compiled under VS2005 - in VS2003 we need to remap assert
 #ifdef LL_DEBUG
@@ -75,6 +81,20 @@ extern "C" {
 
 const std::string LLAppViewerWin32::sWindowClass = "Second Life";
 
+/*
+    This function is used to print to the command line a text message 
+    describing the nvapi error and quits
+*/
+void nvapi_error(NvAPI_Status status)
+{
+    NvAPI_ShortString szDesc = {0};
+	NvAPI_GetErrorMessage(status, szDesc);
+	llwarns << szDesc << llendl;
+
+	//should always trigger when asserts are enabled
+	llassert(status == NVAPI_OK);
+}
+
 // Create app mutex creates a unique global windows object. 
 // If the object can be created it returns true, otherwise
 // it returns false. The false result can be used to determine 
@@ -96,6 +116,79 @@ bool create_app_mutex()
 	return result;
 }
 
+void ll_nvapi_init(NvDRSSessionHandle hSession)
+{
+	// (2) load all the system settings into the session
+	NvAPI_Status status = NvAPI_DRS_LoadSettings(hSession);
+	if (status != NVAPI_OK) 
+	{
+		nvapi_error(status);
+		return;
+	}
+
+	NvAPI_UnicodeString profile_name;
+	std::string app_name = LLTrans::getString("APP_NAME");
+	llutf16string w_app_name = utf8str_to_utf16str(app_name);
+	wsprintf(profile_name, L"%s", w_app_name.c_str());
+	status = NvAPI_DRS_SetCurrentGlobalProfile(hSession, profile_name);
+	if (status != NVAPI_OK)
+	{
+		nvapi_error(status);
+		return;
+	}
+
+	// (3) Obtain the current profile. 
+	NvDRSProfileHandle hProfile = 0;
+	status = NvAPI_DRS_GetCurrentGlobalProfile(hSession, &hProfile);
+	if (status != NVAPI_OK) 
+	{
+		nvapi_error(status);
+		return;
+	}
+
+	// load settings for querying 
+	status = NvAPI_DRS_LoadSettings(hSession);
+	if (status != NVAPI_OK)
+	{
+		nvapi_error(status);
+		return;
+	}
+
+	//get the preferred power management mode for Second Life
+	NVDRS_SETTING drsSetting = {0};
+	drsSetting.version = NVDRS_SETTING_VER;
+	status = NvAPI_DRS_GetSetting(hSession, hProfile, PREFERRED_PSTATE_ID, &drsSetting);
+	if (status == NVAPI_SETTING_NOT_FOUND)
+	{ //only override if the user hasn't specifically set this setting
+		// (4) Specify that we want the VSYNC disabled setting
+		// first we fill the NVDRS_SETTING struct, then we call the function
+		drsSetting.version = NVDRS_SETTING_VER;
+		drsSetting.settingId = PREFERRED_PSTATE_ID;
+		drsSetting.settingType = NVDRS_DWORD_TYPE;
+		drsSetting.u32CurrentValue = PREFERRED_PSTATE_PREFER_MAX;
+		status = NvAPI_DRS_SetSetting(hSession, hProfile, &drsSetting);
+		if (status != NVAPI_OK) 
+		{
+			nvapi_error(status);
+			return;
+		}
+	}
+	else if (status != NVAPI_OK)
+	{
+		nvapi_error(status);
+		return;
+	}
+
+	
+
+	// (5) Now we apply (or save) our changes to the system
+	status = NvAPI_DRS_SaveSettings(hSession);
+	if (status != NVAPI_OK) 
+	{
+		nvapi_error(status);
+	}
+}
+
 //#define DEBUGGING_SEH_FILTER 1
 #if DEBUGGING_SEH_FILTER
 #	define WINMAIN DebuggingWinMain
@@ -165,6 +258,27 @@ int APIENTRY WINMAIN(HINSTANCE hInstance,
 		return -1;
 	}
 	
+	NvAPI_Status status;
+    
+	// Initialize NVAPI
+	status = NvAPI_Initialize();
+	NvDRSSessionHandle hSession = 0;
+
+    if (status == NVAPI_OK) 
+	{
+		// Create the session handle to access driver settings
+		status = NvAPI_DRS_CreateSession(&hSession);
+		if (status != NVAPI_OK) 
+		{
+			nvapi_error(status);
+		}
+		else
+		{
+			//override driver setting as needed
+			ll_nvapi_init(hSession);
+		}
+	}
+
 	// Have to wait until after logging is initialized to display LFH info
 	if (num_heaps > 0)
 	{
@@ -232,6 +346,15 @@ int APIENTRY WINMAIN(HINSTANCE hInstance,
 		LLAppViewer::sUpdaterInfo = NULL ;
 	}
 
+
+
+	// (NVAPI) (6) We clean up. This is analogous to doing a free()
+	if (hSession)
+	{
+		NvAPI_DRS_DestroySession(hSession);
+		hSession = 0;
+	}
+	
 	return 0;
 }
 
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 4cd50ecd151964b0fbf9b75b3d68603470806f1c..5a29bb9e7b5ab813bb8234604daa224e457b4f5a 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -209,14 +209,23 @@ class LLMeshHeaderResponder : public LLCurl::Responder
 	LLMeshHeaderResponder(const LLVolumeParams& mesh_params)
 		: mMeshParams(mesh_params)
 	{
-		LLMeshRepoThread::sActiveHeaderRequests++;
+		LLMeshRepoThread::incActiveHeaderRequests();
 		mProcessed = false;
 	}
 
 	~LLMeshHeaderResponder()
 	{
-		llassert(mProcessed);
-		LLMeshRepoThread::sActiveHeaderRequests--;
+		if (!mProcessed && !LLApp::isQuitting())
+		{ //something went wrong, retry
+			llwarns << "Timeout or service unavailable, retrying." << llendl;
+			LLMeshRepository::sHTTPRetryCount++;
+			LLMeshRepoThread::HeaderRequest req(mMeshParams);
+			LLMutexLock lock(gMeshRepo.mThread->mMutex);
+			gMeshRepo.mThread->mHeaderReqQ.push(req);
+
+		}
+
+		LLMeshRepoThread::decActiveHeaderRequests();
 	}
 
 	virtual void completedRaw(U32 status, const std::string& reason,
@@ -237,14 +246,19 @@ class LLMeshLODResponder : public LLCurl::Responder
 	LLMeshLODResponder(const LLVolumeParams& mesh_params, S32 lod, U32 offset, U32 requested_bytes)
 		: mMeshParams(mesh_params), mLOD(lod), mOffset(offset), mRequestedBytes(requested_bytes)
 	{
-		LLMeshRepoThread::sActiveLODRequests++;
+		LLMeshRepoThread::incActiveLODRequests();
 		mProcessed = false;
 	}
 
 	~LLMeshLODResponder()
 	{
-		llassert(mProcessed);
-		LLMeshRepoThread::sActiveLODRequests--;
+		if (!mProcessed && !LLApp::isQuitting())
+		{
+			llwarns << "Killed without being processed, retrying." << llendl;
+			LLMeshRepository::sHTTPRetryCount++;
+			gMeshRepo.mThread->lockAndLoadMeshLOD(mMeshParams, mLOD);
+		}
+		LLMeshRepoThread::decActiveLODRequests();
 	}
 
 	virtual void completedRaw(U32 status, const std::string& reason,
@@ -665,16 +679,24 @@ void LLMeshRepoThread::loadMeshPhysicsShape(const LLUUID& mesh_id)
 	mPhysicsShapeRequests.insert(mesh_id);
 }
 
+void LLMeshRepoThread::lockAndLoadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
+{
+	if (!LLAppViewer::isQuitting())
+	{
+		loadMeshLOD(mesh_params, lod);
+	}
+}
+
 
-void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
-{ //protected by mSignal, no locking needed here
 
+void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
+{ //could be called from any thread
+	LLMutexLock lock(mMutex);
 	mesh_header_map::iterator iter = mMeshHeader.find(mesh_params.getSculptID());
 	if (iter != mMeshHeader.end())
 	{ //if we have the header, request LOD byte range
 		LODRequest req(mesh_params, lod);
 		{
-			LLMutexLock lock(mMutex);
 			mLODReqQ.push(req);
 			LLMeshRepository::sLODProcessing++;
 		}
@@ -692,7 +714,6 @@ void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
 		}
 		else
 		{ //if no header request is pending, fetch header
-			LLMutexLock lock(mMutex);
 			mHeaderReqQ.push(req);
 			mPendingLOD[mesh_params].push_back(lod);
 		}
@@ -972,6 +993,34 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
 	return ret;
 }
 
+//static
+void LLMeshRepoThread::incActiveLODRequests()
+{
+	LLMutexLock lock(gMeshRepo.mThread->mMutex);
+	++LLMeshRepoThread::sActiveLODRequests;
+}
+
+//static
+void LLMeshRepoThread::decActiveLODRequests()
+{
+	LLMutexLock lock(gMeshRepo.mThread->mMutex);
+	--LLMeshRepoThread::sActiveLODRequests;
+}
+
+//static
+void LLMeshRepoThread::incActiveHeaderRequests()
+{
+	LLMutexLock lock(gMeshRepo.mThread->mMutex);
+	++LLMeshRepoThread::sActiveHeaderRequests;
+}
+
+//static
+void LLMeshRepoThread::decActiveHeaderRequests()
+{
+	LLMutexLock lock(gMeshRepo.mThread->mMutex);
+	--LLMeshRepoThread::sActiveHeaderRequests;
+}
+
 //return false if failed to get header
 bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, U32& count)
 {
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 6e301c26a2ba78e226a8cd98234f3d522d19947a..8eaf691d6fbe2e9a7c6254a0693bb37caec397ad 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -322,7 +322,9 @@ class LLMeshRepoThread : public LLThread
 
 	virtual void run();
 
+	void lockAndLoadMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
 	void loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
+
 	bool fetchMeshHeader(const LLVolumeParams& mesh_params, U32& count);
 	bool fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, U32& count);
 	bool headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size);
@@ -351,6 +353,10 @@ class LLMeshRepoThread : public LLThread
 	//  (should hold onto mesh_id and try again later if header info does not exist)
 	bool fetchMeshPhysicsShape(const LLUUID& mesh_id);
 
+	static void incActiveLODRequests();
+	static void decActiveLODRequests();
+	static void incActiveHeaderRequests();
+	static void decActiveHeaderRequests();
 
 };