From e3753ed8b2c52e98e282e82ea5169bda0b34a2a6 Mon Sep 17 00:00:00 2001
From: "Karl Stiefvater (qarl)" <qarl@lindenlab.com>
Date: Fri, 21 May 2010 16:11:21 -0500
Subject: S3 feature/gpu table implementation.  reviewed by palmer and davep.

---
 indra/newview/app_settings/settings.xml |  11 +++
 indra/newview/llfeaturemanager.cpp      | 144 ++++++++++++++++++++++++++++----
 indra/newview/llfeaturemanager.h        |   6 ++
 indra/newview/llstartup.cpp             |   9 ++
 indra/newview/llviewerwindow.cpp        |   1 +
 5 files changed, 156 insertions(+), 15 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 418032c554..a79e07bdb6 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -4150,6 +4150,17 @@
         <key>Value</key>
             <integer>1</integer>
         </map>
+    <key>LastGPUClass</key>
+    <map>
+      <key>Comment</key>
+      <string>[DO NOT MODIFY] previous GPU class for tracking hardware changes</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>S32</string>
+      <key>Value</key>
+      <integer>-1</integer>
+    </map>
     <key>LastFeatureVersion</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index 50b08f782a..4fdb010162 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -45,10 +45,13 @@
 #include "llsecondlifeurls.h"
 
 #include "llappviewer.h"
+#include "llhttpclient.h"
+#include "llnotificationsutil.h"
 #include "llviewercontrol.h"
 #include "llworld.h"
 #include "lldrawpoolterrain.h"
 #include "llviewertexturelist.h"
+#include "llversioninfo.h"
 #include "llwindow.h"
 #include "llui.h"
 #include "llcontrol.h"
@@ -62,15 +65,20 @@
 
 #if LL_DARWIN
 const char FEATURE_TABLE_FILENAME[] = "featuretable_mac.txt";
+const char FEATURE_TABLE_VER_FILENAME[] = "featuretable_mac.%s.txt";
 #elif LL_LINUX
 const char FEATURE_TABLE_FILENAME[] = "featuretable_linux.txt";
+const char FEATURE_TABLE_VER_FILENAME[] = "featuretable_linux.%s.txt";
 #elif LL_SOLARIS
 const char FEATURE_TABLE_FILENAME[] = "featuretable_solaris.txt";
+const char FEATURE_TABLE_VER_FILENAME[] = "featuretable_solaris.%s.txt";
 #else
 const char FEATURE_TABLE_FILENAME[] = "featuretable.txt";
+const char FEATURE_TABLE_VER_FILENAME[] = "featuretable.%s.txt";
 #endif
 
 const char GPU_TABLE_FILENAME[] = "gpu_table.txt";
+const char GPU_TABLE_VER_FILENAME[] = "gpu_table.%s.txt";
 
 LLFeatureInfo::LLFeatureInfo(const std::string& name, const BOOL available, const F32 level)
 	: mValid(TRUE), mName(name), mAvailable(available), mRecommendedLevel(level)
@@ -215,22 +223,44 @@ BOOL LLFeatureManager::loadFeatureTables()
 	mSkippedFeatures.insert("RenderVBOEnable");
 	mSkippedFeatures.insert("RenderFogRatio");
 
-	std::string data_path = gDirUtilp->getAppRODataDir();
+	// first table is install with app
+	std::string app_path = gDirUtilp->getAppRODataDir();
+	app_path += gDirUtilp->getDirDelimiter();
+	app_path += FEATURE_TABLE_FILENAME;
 
-	data_path += gDirUtilp->getDirDelimiter();
+	// second table is downloaded with HTTP
+	std::string http_filename = llformat(FEATURE_TABLE_VER_FILENAME, LLVersionInfo::getVersion().c_str());
+	std::string http_path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, http_filename);
 
-	data_path += FEATURE_TABLE_FILENAME;
-	lldebugs << "Looking for feature table in " << data_path << llendl;
+	// use HTTP table if it exists
+	std::string path;
+	if (gDirUtilp->fileExists(http_path))
+	{
+		path = http_path;
+	}
+	else
+	{
+		path = app_path;
+	}
+
+	
+	return parseFeatureTable(path);
+}
+
+
+BOOL LLFeatureManager::parseFeatureTable(std::string filename)
+{
+	llinfos << "Looking for feature table in " << filename << llendl;
 
 	llifstream file;
 	std::string name;
 	U32		version;
 	
-	file.open(data_path); 	 /*Flawfinder: ignore*/
+	file.open(filename); 	 /*Flawfinder: ignore*/
 
 	if (!file)
 	{
-		LL_WARNS("RenderInit") << "Unable to open feature table!" << LL_ENDL;
+		LL_WARNS("RenderInit") << "Unable to open feature table " << filename << LL_ENDL;
 		return FALSE;
 	}
 
@@ -239,7 +269,7 @@ BOOL LLFeatureManager::loadFeatureTables()
 	file >> version;
 	if (name != "version")
 	{
-		LL_WARNS("RenderInit") << data_path << " does not appear to be a valid feature table!" << LL_ENDL;
+		LL_WARNS("RenderInit") << filename << " does not appear to be a valid feature table!" << LL_ENDL;
 		return FALSE;
 	}
 
@@ -302,24 +332,44 @@ BOOL LLFeatureManager::loadFeatureTables()
 
 void LLFeatureManager::loadGPUClass()
 {
-	std::string data_path = gDirUtilp->getAppRODataDir();
-
-	data_path += gDirUtilp->getDirDelimiter();
-
-	data_path += GPU_TABLE_FILENAME;
-
 	// defaults
 	mGPUClass = GPU_CLASS_UNKNOWN;
 	mGPUString = gGLManager.getRawGLString();
 	mGPUSupported = FALSE;
 
+	// first table is in the app dir
+	std::string app_path = gDirUtilp->getAppRODataDir();
+	app_path += gDirUtilp->getDirDelimiter();
+	app_path += GPU_TABLE_FILENAME;
+	
+	// second table is downloaded with HTTP
+	std::string http_filename = llformat(GPU_TABLE_VER_FILENAME, LLVersionInfo::getVersion().c_str());
+	std::string http_path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, http_filename);
+
+	// use HTTP table if it exists
+	std::string path;
+	if (gDirUtilp->fileExists(http_path))
+	{
+		path = http_path;
+	}
+	else
+	{
+		path = app_path;
+	}
+
+	parseGPUTable(path);
+}
+
+	
+void LLFeatureManager::parseGPUTable(std::string filename)
+{
 	llifstream file;
 		
-	file.open(data_path); 		 /*Flawfinder: ignore*/
+	file.open(filename);
 
 	if (!file)
 	{
-		LL_WARNS("RenderInit") << "Unable to open GPU table: " << data_path << "!" << LL_ENDL;
+		LL_WARNS("RenderInit") << "Unable to open GPU table: " << filename << "!" << LL_ENDL;
 		return;
 	}
 
@@ -403,6 +453,70 @@ void LLFeatureManager::loadGPUClass()
 	LL_WARNS("RenderInit") << "Couldn't match GPU to a class: " << gGLManager.getRawGLString() << LL_ENDL;
 }
 
+// responder saves table into file
+class LLHTTPFeatureTableResponder : public LLHTTPClient::Responder
+{
+public:
+
+	LLHTTPFeatureTableResponder(std::string filename) :
+		mFilename(filename)
+	{
+	}
+
+	
+	virtual void completedRaw(U32 status, const std::string& reason,
+							  const LLChannelDescriptors& channels,
+							  const LLIOPipe::buffer_ptr_t& buffer)
+	{
+		if (isGoodStatus(status))
+		{
+			// write to file
+
+			llinfos << "writing feature table to " << mFilename << llendl;
+			
+			S32 file_size = buffer->countAfter(channels.in(), NULL);
+			if (file_size > 0)
+			{
+				// read from buffer
+				U8* copy_buffer = new U8[file_size];
+				buffer->readAfter(channels.in(), NULL, copy_buffer, file_size);
+
+				// write to file
+				LLAPRFile out(mFilename, LL_APR_WB);
+				out.write(copy_buffer, file_size);
+				out.close();
+			}
+		}
+		
+	}
+	
+private:
+	std::string mFilename;
+};
+
+void fetch_table(std::string table)
+{
+	const std::string base       = "http://viewer-settings.s3.amazonaws.com/";
+
+	const std::string filename   = llformat(table.c_str(), LLVersionInfo::getVersion().c_str());
+
+	const std::string url        = base + filename;
+
+	const std::string path       = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename);
+
+	llinfos << "LLFeatureManager fetching " << url << " into " << path << llendl;
+	
+	LLHTTPClient::get(url, new LLHTTPFeatureTableResponder(path));
+}
+
+// fetch table(s) from a website (S3)
+void LLFeatureManager::fetchHTTPTables()
+{
+	fetch_table(FEATURE_TABLE_VER_FILENAME);
+	fetch_table(GPU_TABLE_VER_FILENAME);
+}
+
+
 void LLFeatureManager::cleanupFeatureTables()
 {
 	std::for_each(mMaskList.begin(), mMaskList.end(), DeletePairedPointer());
diff --git a/indra/newview/llfeaturemanager.h b/indra/newview/llfeaturemanager.h
index dd218d428f..c2ecede2c5 100644
--- a/indra/newview/llfeaturemanager.h
+++ b/indra/newview/llfeaturemanager.h
@@ -48,6 +48,7 @@ typedef enum EGPUClass
 	GPU_CLASS_3 = 3
 } EGPUClass; 
 
+
 class LLFeatureInfo
 {
 public:
@@ -144,8 +145,13 @@ public:
 	// in the skip list if true
 	void applyFeatures(bool skipFeatures);
 
+	// load the dynamic GPU/feature table from a website
+	void fetchHTTPTables();
+	
 protected:
 	void loadGPUClass();
+	BOOL parseFeatureTable(std::string filename);
+	void parseGPUTable(std::string filename);
 	void initBaseMask();
 
 
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 0a464b3b6c..b28377e591 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -384,13 +384,22 @@ bool idle_startup()
 		{
 			LLNotificationsUtil::add("DisplaySetToRecommended");
 		}
+		else if ((gSavedSettings.getS32("LastGPUClass") != LLFeatureManager::getInstance()->getGPUClass()) &&
+				 (gSavedSettings.getS32("LastGPUClass") != -1))
+		{
+			LLNotificationsUtil::add("DisplaySetToRecommended");
+		}
 		else if (!gViewerWindow->getInitAlert().empty())
 		{
 			LLNotificationsUtil::add(gViewerWindow->getInitAlert());
 		}
 			
 		gSavedSettings.setS32("LastFeatureVersion", LLFeatureManager::getInstance()->getVersion());
+		gSavedSettings.setS32("LastGPUClass", LLFeatureManager::getInstance()->getGPUClass());
 
+		// load dynamic GPU/feature tables from website (S3)
+		LLFeatureManager::getInstance()->fetchHTTPTables();
+		
 		std::string xml_file = LLUI::locateSkin("xui_version.xml");
 		LLXMLNodePtr root;
 		bool xml_ok = false;
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index e0463e3c4a..9fc7d6a56d 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1433,6 +1433,7 @@ LLViewerWindow::LLViewerWindow(
 
 	if (LLFeatureManager::getInstance()->isSafe()
 		|| (gSavedSettings.getS32("LastFeatureVersion") != LLFeatureManager::getInstance()->getVersion())
+		|| (gSavedSettings.getS32("LastGPUClass") != LLFeatureManager::getInstance()->getGPUClass())
 		|| (gSavedSettings.getBOOL("ProbeHardwareOnStartup")))
 	{
 		LLFeatureManager::getInstance()->applyRecommendedSettings();
-- 
cgit v1.2.3


From 68ca9dc95729d9659b8318898dcbd1c813aca678 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Thu, 27 May 2010 18:26:06 -0700
Subject: VI-49 FIX "_external" links should work in shared media

monroe already did most of this, just moved dialog for confirming opening external browser to common code that calls out to external browser
so no way to skip notification unless the user opts out
---
 indra/newview/llviewermedia.cpp | 66 ++++++++++-------------------------------
 indra/newview/llviewermedia.h   |  2 --
 indra/newview/llweb.cpp         | 25 ++++++++++++++--
 3 files changed, 38 insertions(+), 55 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index e5c5a607dd..14e58f4167 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -2795,42 +2795,6 @@ bool LLViewerMediaImpl::isPlayable() const
 	return false;
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// static 
-bool LLViewerMediaImpl::onClickLinkExternalTarget(const LLSD& notification, const LLSD& response )
-{
-	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-	if ( 0 == option )
-	{
-		LLSD payload = notification["payload"];
-		std::string url = payload["url"].asString();
-		S32 target_type = payload["target_type"].asInteger();
-		clickLinkWithTarget(url, target_type);
-	}
-	return false;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-// static 
-void LLViewerMediaImpl::clickLinkWithTarget(const std::string& url, const S32& target_type )
-{
-	if (target_type == LLPluginClassMedia::TARGET_EXTERNAL)
-	{
-		// load target in an external browser
-		LLWeb::loadURLExternal(url);
-	}
-	else if (target_type == LLPluginClassMedia::TARGET_BLANK)
-	{
-		// load target in the user's preferred browser
-		LLWeb::loadURL(url);
-	}
-	else {
-		// unsupported link target - shouldn't happen
-		LL_WARNS("LinkTarget") << "Unsupported link target type" << LL_ENDL;
-	}
-}
-
 //////////////////////////////////////////////////////////////////////////////////////////
 void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginClassMediaOwner::EMediaEvent event)
 {
@@ -2851,21 +2815,23 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla
 			std::string url = plugin->getClickURL();
 			U32 target_type = plugin->getClickTargetType();
 			
-			// is there is a target specified for the link?
-			if (target_type == LLPluginClassMedia::TARGET_EXTERNAL ||
-				target_type == LLPluginClassMedia::TARGET_BLANK )
+			switch (target_type)
 			{
-				if (gSavedSettings.getBOOL("UseExternalBrowser"))
-				{
-					LLSD payload;
-					payload["url"] = url;
-					payload["target_type"] = LLSD::Integer(target_type);
-					LLNotificationsUtil::add( "WebLaunchExternalTarget", LLSD(), payload, onClickLinkExternalTarget);
-				}
-				else
-				{
-					clickLinkWithTarget(url, target_type);
-				}
+			case LLPluginClassMedia::TARGET_EXTERNAL:
+				// force url to external browser
+				LLWeb::loadURLExternal(url);
+				break;
+			case LLPluginClassMedia::TARGET_BLANK:
+				// open in SL media browser or external browser based on user pref
+				LLWeb::loadURL(url);
+				break;
+			case LLPluginClassMedia::TARGET_NONE:
+				// ignore this click and let media plugin handle it
+				break;
+			case LLPluginClassMedia::TARGET_OTHER:
+				LL_WARNS("LinkTarget") << "Unsupported link target type" << LL_ENDL;
+				break;
+			default: break;
 			}
 		};
 		break;
diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h
index 754d0851c3..8626f4469e 100644
--- a/indra/newview/llviewermedia.h
+++ b/indra/newview/llviewermedia.h
@@ -391,8 +391,6 @@ private:
 	bool shouldShowBasedOnClass() const;
 	static bool isObjectAttachedToAnotherAvatar(LLVOVolume *obj);
 	static bool isObjectInAgentParcel(LLVOVolume *obj);
-	static bool onClickLinkExternalTarget( const LLSD&, const LLSD& );
-	static void clickLinkWithTarget(const std::string& url, const S32& target_type );
 	
 private:
 	// a single media url with some data and an impl.
diff --git a/indra/newview/llweb.cpp b/indra/newview/llweb.cpp
index aa03b1afd1..5c9633c036 100644
--- a/indra/newview/llweb.cpp
+++ b/indra/newview/llweb.cpp
@@ -54,6 +54,10 @@
 #include "llviewerparcelmgr.h"
 #include "llviewerregion.h"
 #include "llviewerwindow.h"
+#include "llnotificationsutil.h"
+
+bool on_load_url_external_response(const LLSD& notification, const LLSD& response, bool async );
+
 
 class URLLoader : public LLToastAlertPanel::URLLoader
 {
@@ -110,11 +114,26 @@ void LLWeb::loadURLExternal(const std::string& url)
 // static
 void LLWeb::loadURLExternal(const std::string& url, bool async)
 {
-	std::string escaped_url = escapeURL(url);
-	if (gViewerWindow)
+	LLSD payload;
+	payload["url"] = url;
+	LLNotificationsUtil::add( "WebLaunchExternalTarget", LLSD(), payload, boost::bind(on_load_url_external_response, _1, _2, async));
+}
+
+// static 
+bool on_load_url_external_response(const LLSD& notification, const LLSD& response, bool async )
+{
+	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+	if ( 0 == option )
 	{
-		gViewerWindow->getWindow()->spawnWebBrowser(escaped_url, async);
+		LLSD payload = notification["payload"];
+		std::string url = payload["url"].asString();
+		std::string escaped_url = LLWeb::escapeURL(url);
+		if (gViewerWindow)
+		{
+			gViewerWindow->getWindow()->spawnWebBrowser(escaped_url, async);
+		}
 	}
+	return false;
 }
 
 
-- 
cgit v1.2.3