diff options
Diffstat (limited to 'indra/newview/llfeaturemanager.cpp')
-rwxr-xr-x | indra/newview/llfeaturemanager.cpp | 234 |
1 files changed, 153 insertions, 81 deletions
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index ddb9d3bc43..c47618e1ec 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,6 +53,8 @@ #include "llboost.h" #include "llweb.h" #include "llviewershadermgr.h" +#include "llstring.h" +#include "stringize.h" #if LL_WINDOWS #include "lldxhardware.h" @@ -187,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)) @@ -209,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 @@ -250,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) @@ -286,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*/ @@ -305,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) + { + S32 available; + F32 recommended; + file >> available >> recommended; + flp->addFeature(name, available, recommended); + } + else { - LL_ERRS("RenderInit") << "Specified parameter before <list> keyword!" << LL_ENDL; - return FALSE; + 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; @@ -355,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(); @@ -504,6 +604,7 @@ void LLFeatureManager::parseGPUTable(std::string filename) #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 @@ -620,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_5)); + U32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_5)); llinfos << "Applying Recommended Features" << llendl; @@ -696,62 +797,33 @@ 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) + + // if we're passed an invalid level, default to "Low" + std::string features(isValidGraphicsLevel(level)? getNameForGraphicsLevel(level) : "Low"); + if (features == "Low") { - case 0: #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) - { - maskFeatures("LowFixedFunction"); - } - else - { //same as low, but with "Basic Shaders" enabled - maskFeatures("Low"); - } + // 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 - 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"); - } + // 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 - break; - case 1: - maskFeatures("LowMid"); - break; - case 2: - maskFeatures("Mid"); - break; - case 3: - maskFeatures("MidHigh"); - break; - case 4: - maskFeatures("High"); - break; - case 5: - maskFeatures("HighUltra"); - break; - case 6: - maskFeatures("Ultra"); - break; - default: - maskFeatures("Low"); - break; + { + // same as Low, but with "Basic Shaders" disabled + features = "LowFixedFunction"; + } } + maskFeatures(features); + applyFeatures(skipFeatures); LLViewerShaderMgr::sSkipReload = false; |