Commits

davep committed 636d19f Draft Merge

Comments (0)

Files changed (6)

           </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>

indra/cmake/NVAPI.cmake

+# -*- 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)
+

indra/newview/CMakeLists.txt

 include(LScript)
 include(Linking)
 include(NDOF)
+include(NVAPI)
 include(GooglePerfTools)
 include(TemplateCheck)
 include(UI)
     ${LLMATH_LIBRARIES}
     ${LLCOMMON_LIBRARIES}
     ${NDOF_LIBRARY}
+    ${NVAPI_LIBRARY}
     ${HUNSPELL_LIBRARY}
     ${viewer_LIBRARIES}
     ${BOOST_PROGRAM_OPTIONS_LIBRARY}

indra/newview/llappviewerwin32.cpp

 #include "llviewercontrol.h"
 #include "lldxhardware.h"
 
+#include "nvapi/nvapi.h"
+#include "nvapi/NvApiDriverSettings.h"
+
+#include <stdlib.h>
+
 #include "llweb.h"
 #include "llsecondlifeurls.h"
 
 #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
 
 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 
 	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
 		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)
 	{
 		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;
 }
 

indra/newview/llmeshrepository.cpp

 	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,
 	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,
 	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
-
+{ //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++;
 		}
 		}
 		else
 		{ //if no header request is pending, fetch header
-			LLMutexLock lock(mMutex);
 			mHeaderReqQ.push(req);
 			mPendingLOD[mesh_params].push_back(lod);
 		}
 	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)
 {

indra/newview/llmeshrepository.h

 
 	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);
 	//  (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();
 
 };