summaryrefslogtreecommitdiff
path: root/indra/newview/llfeaturemanager.cpp
diff options
context:
space:
mode:
authorOz Linden <oz@lindenlab.com>2013-11-19 17:59:55 -0500
committerOz Linden <oz@lindenlab.com>2013-11-19 17:59:55 -0500
commit0031e9a97be1bf6e9fe773c23506494d09ce91ae (patch)
tree220f195c82174b7cc8e94dceb2553e59fe5837a5 /indra/newview/llfeaturemanager.cpp
parentb7edc965bc77ab21e9a1e3f6b424299a50053529 (diff)
parentebc9bcbf69f7a519677a6522979a6bf6cbb04bb8 (diff)
merge up to 3.6.10-release; some of the storm-68 changes lost
Diffstat (limited to 'indra/newview/llfeaturemanager.cpp')
-rwxr-xr-x[-rw-r--r--]indra/newview/llfeaturemanager.cpp261
1 files changed, 203 insertions, 58 deletions
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index 08f9d26705..c47618e1ec 100644..100755
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -30,6 +30,7 @@
#include <fstream>
#include <boost/regex.hpp>
+#include <boost/assign/list_of.hpp>
#include "llfeaturemanager.h"
#include "lldir.h"
@@ -52,11 +53,14 @@
#include "llboost.h"
#include "llweb.h"
#include "llviewershadermgr.h"
+#include "llstring.h"
+#include "stringize.h"
#if LL_WINDOWS
#include "lldxhardware.h"
#endif
+#define LL_EXPORT_GPU_TABLE 0
#if LL_DARWIN
const char FEATURE_TABLE_FILENAME[] = "featuretable_mac.txt";
@@ -186,6 +190,55 @@ void LLFeatureList::dump()
LL_DEBUGS("RenderInit") << LL_ENDL;
}
+static const std::vector<std::string> sGraphicsLevelNames = boost::assign::list_of
+ ("Low")
+ ("LowMid")
+ ("Mid")
+ ("MidHigh")
+ ("High")
+ ("HighUltra")
+ ("Ultra")
+;
+
+U32 LLFeatureManager::getMaxGraphicsLevel() const
+{
+ return sGraphicsLevelNames.size() - 1;
+}
+
+bool LLFeatureManager::isValidGraphicsLevel(U32 level) const
+{
+ return (level <= getMaxGraphicsLevel());
+}
+
+std::string LLFeatureManager::getNameForGraphicsLevel(U32 level) const
+{
+ if (isValidGraphicsLevel(level))
+ {
+ return sGraphicsLevelNames[level];
+ }
+ return STRINGIZE("Invalid graphics level " << level << ", valid are 0 .. "
+ << getMaxGraphicsLevel());
+}
+
+S32 LLFeatureManager::getGraphicsLevelForName(const std::string& name) const
+{
+ const std::string FixedFunction("FixedFunction");
+ std::string rname(name);
+ if (LLStringUtil::endsWith(rname, FixedFunction))
+ {
+ // chop off any "FixedFunction" suffix
+ rname = rname.substr(0, rname.length() - FixedFunction.length());
+ }
+ for (S32 i(0), iend(getMaxGraphicsLevel()); i <= iend; ++i)
+ {
+ if (sGraphicsLevelNames[i] == rname)
+ {
+ return i;
+ }
+ }
+ return -1;
+}
+
LLFeatureList *LLFeatureManager::findMask(const std::string& name)
{
if (mMaskList.count(name))
@@ -208,7 +261,7 @@ BOOL LLFeatureManager::maskFeatures(const std::string& name)
return maskList(*maskp);
}
-BOOL LLFeatureManager::loadFeatureTables()
+bool LLFeatureManager::loadFeatureTables()
{
// *TODO - if I or anyone else adds something else to the skipped list
// make this data driven. Put it in the feature table and parse it
@@ -249,28 +302,36 @@ BOOL LLFeatureManager::loadFeatureTables()
// use HTTP table if it exists
std::string path;
+ bool parse_ok = false;
if (gDirUtilp->fileExists(http_path))
{
- path = http_path;
+ parse_ok = parseFeatureTable(http_path);
+ if (!parse_ok)
+ {
+ // the HTTP table failed to parse, so delete it
+ LLFile::remove(http_path);
+ LL_WARNS("RenderInit") << "Removed invalid feature table '" << http_path << "'" << LL_ENDL;
+ }
}
- else
+
+ if (!parse_ok)
{
- path = app_path;
+ parse_ok = parseFeatureTable(app_path);
}
-
- return parseFeatureTable(path);
+ return parse_ok;
}
-BOOL LLFeatureManager::parseFeatureTable(std::string filename)
+bool LLFeatureManager::parseFeatureTable(std::string filename)
{
- llinfos << "Looking for feature table in " << filename << llendl;
+ LL_INFOS("RenderInit") << "Attempting to parse feature table from " << filename << LL_ENDL;
llifstream file;
std::string name;
U32 version;
+ cleanupFeatureTables(); // in case an earlier attempt left partial results
file.open(filename); /*Flawfinder: ignore*/
if (!file)
@@ -285,13 +346,14 @@ BOOL LLFeatureManager::parseFeatureTable(std::string filename)
if (name != "version")
{
LL_WARNS("RenderInit") << filename << " does not appear to be a valid feature table!" << LL_ENDL;
- return FALSE;
+ return false;
}
mTableVersion = version;
-
+
LLFeatureList *flp = NULL;
- while (file >> name)
+ bool parse_ok = true;
+ while (file >> name && parse_ok)
{
char buffer[MAX_STRING]; /*Flawfinder: ignore*/
@@ -304,39 +366,58 @@ BOOL LLFeatureManager::parseFeatureTable(std::string filename)
if (name == "list")
{
+ LL_DEBUGS("RenderInit") << "Before new list" << std::endl;
if (flp)
{
- //flp->dump();
+ flp->dump();
+ }
+ else
+ {
+ LL_CONT << "No current list";
}
+ LL_CONT << LL_ENDL;
+
// It's a new mask, create it.
file >> name;
- if (mMaskList.count(name))
+ if (!mMaskList.count(name))
{
- LL_ERRS("RenderInit") << "Overriding mask " << name << ", this is invalid!" << LL_ENDL;
+ flp = new LLFeatureList(name);
+ mMaskList[name] = flp;
+ }
+ else
+ {
+ LL_WARNS("RenderInit") << "Overriding mask " << name << ", this is invalid!" << LL_ENDL;
+ parse_ok = false;
}
-
- flp = new LLFeatureList(name);
- mMaskList[name] = flp;
}
else
{
- if (!flp)
+ if (flp)
{
- LL_ERRS("RenderInit") << "Specified parameter before <list> keyword!" << LL_ENDL;
- return FALSE;
+ S32 available;
+ F32 recommended;
+ file >> available >> recommended;
+ flp->addFeature(name, available, recommended);
+ }
+ else
+ {
+ LL_WARNS("RenderInit") << "Specified parameter before <list> keyword!" << LL_ENDL;
+ parse_ok = false;
}
- S32 available;
- F32 recommended;
- file >> available >> recommended;
- flp->addFeature(name, available, recommended);
}
}
file.close();
- return TRUE;
+ if (!parse_ok)
+ {
+ LL_WARNS("RenderInit") << "Discarding feature table data from " << filename << LL_ENDL;
+ cleanupFeatureTables();
+ }
+
+ return parse_ok;
}
-void LLFeatureManager::loadGPUClass()
+bool LLFeatureManager::loadGPUClass()
{
// defaults
mGPUClass = GPU_CLASS_UNKNOWN;
@@ -354,29 +435,49 @@ void LLFeatureManager::loadGPUClass()
// use HTTP table if it exists
std::string path;
+ bool parse_ok = false;
if (gDirUtilp->fileExists(http_path))
{
- path = http_path;
+ parse_ok = parseGPUTable(http_path);
+ if (!parse_ok)
+ {
+ // the HTTP table failed to parse, so delete it
+ LLFile::remove(http_path);
+ LL_WARNS("RenderInit") << "Removed invalid gpu table '" << http_path << "'" << LL_ENDL;
+ }
}
- else
+
+ if (!parse_ok)
{
- path = app_path;
+ parse_ok = parseGPUTable(app_path);
}
- parseGPUTable(path);
+ return parse_ok; // indicates that the file parsed correctly, not that the gpu was recognized
}
-void LLFeatureManager::parseGPUTable(std::string filename)
+bool LLFeatureManager::parseGPUTable(std::string filename)
{
llifstream file;
-
+
+ LL_INFOS("RenderInit") << "Attempting to parse GPU table from " << filename << LL_ENDL;
file.open(filename);
- if (!file)
+ if (file)
+ {
+ const char recognizer[] = "//GPU_TABLE";
+ char first_line[MAX_STRING];
+ file.getline(first_line, MAX_STRING);
+ if (0 != strncmp(first_line, recognizer, strlen(recognizer)))
+ {
+ LL_WARNS("RenderInit") << "Invalid GPU table: " << filename << "!" << LL_ENDL;
+ return false;
+ }
+ }
+ else
{
LL_WARNS("RenderInit") << "Unable to open GPU table: " << filename << "!" << LL_ENDL;
- return;
+ return false;
}
std::string rawRenderer = gGLManager.getRawGLString();
@@ -386,6 +487,13 @@ void LLFeatureManager::parseGPUTable(std::string filename)
*i = tolower(*i);
}
+#if LL_EXPORT_GPU_TABLE
+ llofstream json;
+ json.open("gpu_table.json");
+
+ json << "var gpu_table = [" << std::endl;
+#endif
+
bool gpuFound;
U32 lineNumber;
for (gpuFound = false, lineNumber = 0; !gpuFound && !file.eof(); lineNumber++)
@@ -411,7 +519,7 @@ void LLFeatureManager::parseGPUTable(std::string filename)
// setup the tokenizer
std::string buf(buffer);
- std::string cls, label, expr, supported;
+ std::string cls, label, expr, supported, stats_based, expected_gl_version;
boost_tokenizer tokens(buf, boost::char_separator<char>("\t\n"));
boost_tokenizer::iterator token_iter = tokens.begin();
@@ -432,13 +540,29 @@ void LLFeatureManager::parseGPUTable(std::string filename)
{
supported = *token_iter++;
}
+ if (token_iter != tokens.end())
+ {
+ stats_based = *token_iter++;
+ }
+ if (token_iter != tokens.end())
+ {
+ expected_gl_version = *token_iter++;
+ }
if (label.empty() || expr.empty() || cls.empty() || supported.empty())
{
LL_WARNS("RenderInit") << "invald gpu_table.txt:" << lineNumber << ": '" << buffer << "'" << LL_ENDL;
continue;
}
-
+#if LL_EXPORT_GPU_TABLE
+ json << "{'label' : '" << label << "',\n" <<
+ "'regexp' : '" << expr << "',\n" <<
+ "'class' : '" << cls << "',\n" <<
+ "'supported' : '" << supported << "',\n" <<
+ "'stats_based' : " << stats_based << ",\n" <<
+ "'gl_version' : " << expected_gl_version << "\n},\n";
+#endif
+
for (U32 i = 0; i < expr.length(); i++) /*Flawfinder: ignore*/
{
expr[i] = tolower(expr[i]);
@@ -449,12 +573,19 @@ void LLFeatureManager::parseGPUTable(std::string filename)
if(boost::regex_search(renderer, re))
{
// if we found it, stop!
+#if !LL_EXPORT_GPU_TABLE
gpuFound = true;
+#endif
mGPUString = label;
mGPUClass = (EGPUClass) strtol(cls.c_str(), NULL, 10);
mGPUSupported = (BOOL) strtol(supported.c_str(), NULL, 10);
+ sscanf(expected_gl_version.c_str(), "%f", &mExpectedGLVersion);
}
}
+#if LL_EXPORT_GPU_TABLE
+ json << "];\n\n";
+ json.close();
+#endif
file.close();
if ( gpuFound )
@@ -469,6 +600,11 @@ void LLFeatureManager::parseGPUTable(std::string filename)
{
LL_WARNS("RenderInit") << "GPU '" << rawRenderer << "' not recognized" << LL_ENDL;
}
+
+#if LL_DARWIN // never go over "Mid" settings by default on OS X
+ mGPUClass = llmin(mGPUClass, GPU_CLASS_2);
+#endif
+ return true;
}
// responder saves table into file
@@ -585,7 +721,7 @@ void LLFeatureManager::applyRecommendedSettings()
{
// apply saved settings
// cap the level at 2 (high)
- S32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_2));
+ U32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_5));
llinfos << "Applying Recommended Features" << llendl;
@@ -661,35 +797,38 @@ void LLFeatureManager::applyFeatures(bool skipFeatures)
}
}
-void LLFeatureManager::setGraphicsLevel(S32 level, bool skipFeatures)
+void LLFeatureManager::setGraphicsLevel(U32 level, bool skipFeatures)
{
LLViewerShaderMgr::sSkipReload = true;
applyBaseMasks();
-
- switch (level)
- {
- case 0:
- maskFeatures("Low");
- break;
- case 1:
- maskFeatures("Mid");
- break;
- case 2:
- maskFeatures("High");
- break;
- case 3:
- maskFeatures("Ultra");
- break;
- default:
- maskFeatures("Low");
- break;
+
+ // if we're passed an invalid level, default to "Low"
+ std::string features(isValidGraphicsLevel(level)? getNameForGraphicsLevel(level) : "Low");
+ if (features == "Low")
+ {
+#if LL_DARWIN
+ // This Mac-specific change is to insure that we force 'Basic Shaders' for all Mac
+ // systems which support them instead of falling back to fixed-function unnecessarily
+ // MAINT-2157
+ if (gGLManager.mGLVersion < 2.1f)
+#else
+ // only use fixed function by default if GL version < 3.0 or this is an intel graphics chip
+ if (gGLManager.mGLVersion < 3.f || gGLManager.mIsIntel)
+#endif
+ {
+ // same as Low, but with "Basic Shaders" disabled
+ features = "LowFixedFunction";
+ }
}
+ maskFeatures(features);
+
applyFeatures(skipFeatures);
LLViewerShaderMgr::sSkipReload = false;
LLViewerShaderMgr::instance()->setShaders();
+ gPipeline.refreshCachedSettings();
}
void LLFeatureManager::applyBaseMasks()
@@ -707,14 +846,16 @@ void LLFeatureManager::applyBaseMasks()
mFeatures = maskp->getFeatures();
// mask class
- if (mGPUClass >= 0 && mGPUClass < 4)
+ if (mGPUClass >= 0 && mGPUClass < 6)
{
const char* class_table[] =
{
"Class0",
"Class1",
"Class2",
- "Class3"
+ "Class3",
+ "Class4",
+ "Class5",
};
LL_INFOS("RenderInit") << "Setting GPU Class to " << class_table[mGPUClass] << LL_ENDL;
@@ -779,6 +920,10 @@ void LLFeatureManager::applyBaseMasks()
{
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