diff options
author | Jacek Antonelli | 2008-08-15 23:45:34 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:45:34 -0500 |
commit | cd17687f01420952712a500107e0f93e7ab8d5f8 (patch) | |
tree | ce48c2b706f2c1176290e39fb555fbdf6648ce01 /linden/indra/newview/llfeaturemanager.cpp | |
parent | Second Life viewer sources 1.19.0.5 (diff) | |
download | meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.zip meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.gz meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.bz2 meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.xz |
Second Life viewer sources 1.19.1.0
Diffstat (limited to '')
-rw-r--r-- | linden/indra/newview/llfeaturemanager.cpp | 348 |
1 files changed, 207 insertions, 141 deletions
diff --git a/linden/indra/newview/llfeaturemanager.cpp b/linden/indra/newview/llfeaturemanager.cpp index 56e0469..f96b2db 100644 --- a/linden/indra/newview/llfeaturemanager.cpp +++ b/linden/indra/newview/llfeaturemanager.cpp | |||
@@ -34,6 +34,8 @@ | |||
34 | 34 | ||
35 | #include "llviewerprecompiledheaders.h" | 35 | #include "llviewerprecompiledheaders.h" |
36 | 36 | ||
37 | #include <boost/regex.hpp> | ||
38 | |||
37 | #include "llfeaturemanager.h" | 39 | #include "llfeaturemanager.h" |
38 | #include "lldir.h" | 40 | #include "lldir.h" |
39 | 41 | ||
@@ -43,11 +45,13 @@ | |||
43 | 45 | ||
44 | #include "llviewercontrol.h" | 46 | #include "llviewercontrol.h" |
45 | #include "llworld.h" | 47 | #include "llworld.h" |
46 | #include "pipeline.h" | ||
47 | #include "lldrawpoolterrain.h" | 48 | #include "lldrawpoolterrain.h" |
48 | #include "llviewerimagelist.h" | 49 | #include "llviewerimagelist.h" |
49 | #include "llwindow.h" | 50 | #include "llwindow.h" |
50 | #include "llui.h" | 51 | #include "llui.h" |
52 | #include "llcontrol.h" | ||
53 | #include "llboost.h" | ||
54 | #include "llweb.h" | ||
51 | 55 | ||
52 | #if LL_WINDOWS | 56 | #if LL_WINDOWS |
53 | #include "lldxhardware.h" | 57 | #include "lldxhardware.h" |
@@ -73,7 +77,7 @@ const char GPU_TABLE_FILENAME[] = "gpu_table.txt"; | |||
73 | 77 | ||
74 | LLFeatureManager *gFeatureManagerp = NULL; | 78 | LLFeatureManager *gFeatureManagerp = NULL; |
75 | 79 | ||
76 | LLFeatureInfo::LLFeatureInfo(const char *name, const BOOL available, const S32 level) : mValid(TRUE) | 80 | LLFeatureInfo::LLFeatureInfo(const char *name, const BOOL available, const F32 level) : mValid(TRUE) |
77 | { | 81 | { |
78 | mName = name; | 82 | mName = name; |
79 | mAvailable = available; | 83 | mAvailable = available; |
@@ -89,7 +93,7 @@ LLFeatureList::~LLFeatureList() | |||
89 | { | 93 | { |
90 | } | 94 | } |
91 | 95 | ||
92 | void LLFeatureList::addFeature(const char *name, const BOOL available, const S32 level) | 96 | void LLFeatureList::addFeature(const char *name, const BOOL available, const F32 level) |
93 | { | 97 | { |
94 | if (mFeatures.count(name)) | 98 | if (mFeatures.count(name)) |
95 | { | 99 | { |
@@ -108,18 +112,21 @@ BOOL LLFeatureList::isFeatureAvailable(const char *name) | |||
108 | } | 112 | } |
109 | 113 | ||
110 | llwarns << "Feature " << name << " not on feature list!" << llendl; | 114 | llwarns << "Feature " << name << " not on feature list!" << llendl; |
111 | return FALSE; | 115 | |
116 | // changing this to TRUE so you have to explicitly disable | ||
117 | // something for it to be disabled | ||
118 | return TRUE; | ||
112 | } | 119 | } |
113 | 120 | ||
114 | S32 LLFeatureList::getRecommendedLevel(const char *name) | 121 | F32 LLFeatureList::getRecommendedValue(const char *name) |
115 | { | 122 | { |
116 | if (mFeatures.count(name)) | 123 | if (mFeatures.count(name) && isFeatureAvailable(name)) |
117 | { | 124 | { |
118 | return mFeatures[name].mRecommendedLevel; | 125 | return mFeatures[name].mRecommendedLevel; |
119 | } | 126 | } |
120 | 127 | ||
121 | llwarns << "Feature " << name << " not on feature list!" << llendl; | 128 | llwarns << "Feature " << name << " not on feature list or not available!" << llendl; |
122 | return -1; | 129 | return 0; |
123 | } | 130 | } |
124 | 131 | ||
125 | BOOL LLFeatureList::maskList(LLFeatureList &mask) | 132 | BOOL LLFeatureList::maskList(LLFeatureList &mask) |
@@ -207,6 +214,14 @@ BOOL LLFeatureManager::maskFeatures(const char *name) | |||
207 | 214 | ||
208 | BOOL LLFeatureManager::loadFeatureTables() | 215 | BOOL LLFeatureManager::loadFeatureTables() |
209 | { | 216 | { |
217 | // *TODO - if I or anyone else adds something else to the skipped list | ||
218 | // make this data driven. Put it in the feature table and parse it | ||
219 | // correctly | ||
220 | mSkippedFeatures.insert("RenderAnisotropic"); | ||
221 | mSkippedFeatures.insert("RenderGamma"); | ||
222 | mSkippedFeatures.insert("RenderVBOEnable"); | ||
223 | mSkippedFeatures.insert("RenderFogRatio"); | ||
224 | |||
210 | std::string data_path = gDirUtilp->getAppRODataDir(); | 225 | std::string data_path = gDirUtilp->getAppRODataDir(); |
211 | 226 | ||
212 | data_path += gDirUtilp->getDirDelimiter(); | 227 | data_path += gDirUtilp->getDirDelimiter(); |
@@ -275,19 +290,8 @@ BOOL LLFeatureManager::loadFeatureTables() | |||
275 | llerrs << "Overriding mask " << name << ", this is invalid!" << llendl; | 290 | llerrs << "Overriding mask " << name << ", this is invalid!" << llendl; |
276 | } | 291 | } |
277 | 292 | ||
278 | if (!flp) | 293 | flp = new LLFeatureList(name); |
279 | { | 294 | mMaskList[name] = flp; |
280 | // | ||
281 | // The first one is always the default | ||
282 | // | ||
283 | flp = this; | ||
284 | } | ||
285 | else | ||
286 | { | ||
287 | flp = new LLFeatureList(name); | ||
288 | mMaskList[name] = flp; | ||
289 | } | ||
290 | |||
291 | } | 295 | } |
292 | else | 296 | else |
293 | { | 297 | { |
@@ -295,7 +299,8 @@ BOOL LLFeatureManager::loadFeatureTables() | |||
295 | { | 299 | { |
296 | llerrs << "Specified parameter before <list> keyword!" << llendl; | 300 | llerrs << "Specified parameter before <list> keyword!" << llendl; |
297 | } | 301 | } |
298 | S32 available, recommended; | 302 | S32 available; |
303 | F32 recommended; | ||
299 | file >> available >> recommended; | 304 | file >> available >> recommended; |
300 | flp->addFeature(name, available, recommended); | 305 | flp->addFeature(name, available, recommended); |
301 | } | 306 | } |
@@ -314,9 +319,10 @@ void LLFeatureManager::loadGPUClass() | |||
314 | data_path += GPU_TABLE_FILENAME; | 319 | data_path += GPU_TABLE_FILENAME; |
315 | 320 | ||
316 | // defaults | 321 | // defaults |
317 | mGPUClass = 0; | 322 | mGPUClass = GPU_CLASS_UNKNOWN; |
318 | mGPUString = gGLManager.getRawGLString(); | 323 | mGPUString = gGLManager.getRawGLString(); |
319 | 324 | mGPUSupported = FALSE; | |
325 | |||
320 | llifstream file; | 326 | llifstream file; |
321 | 327 | ||
322 | file.open(data_path.c_str()); /*Flawfinder: ignore*/ | 328 | file.open(data_path.c_str()); /*Flawfinder: ignore*/ |
@@ -354,41 +360,50 @@ void LLFeatureManager::loadGPUClass() | |||
354 | continue; | 360 | continue; |
355 | } | 361 | } |
356 | 362 | ||
357 | char* cls, *label, *expr; | 363 | // setup the tokenizer |
358 | 364 | std::string buf(buffer); | |
359 | label = strtok(buffer, "\t"); | 365 | std::string cls, label, expr, supported; |
360 | expr = strtok(NULL, "\t"); | 366 | boost_tokenizer tokens(buf, boost::char_separator<char>("\t\n")); |
361 | cls = strtok(NULL, "\t"); | 367 | boost_tokenizer::iterator token_iter = tokens.begin(); |
362 | 368 | ||
363 | if (label == NULL || expr == NULL || cls == NULL) | 369 | // grab the label, pseudo regular expression, and class |
370 | if(token_iter != tokens.end()) | ||
371 | { | ||
372 | label = *token_iter++; | ||
373 | } | ||
374 | if(token_iter != tokens.end()) | ||
375 | { | ||
376 | expr = *token_iter++; | ||
377 | } | ||
378 | if(token_iter != tokens.end()) | ||
379 | { | ||
380 | cls = *token_iter++; | ||
381 | } | ||
382 | if(token_iter != tokens.end()) | ||
383 | { | ||
384 | supported = *token_iter++; | ||
385 | } | ||
386 | |||
387 | if (label.empty() || expr.empty() || cls.empty() || supported.empty()) | ||
364 | { | 388 | { |
365 | continue; | 389 | continue; |
366 | } | 390 | } |
367 | 391 | ||
368 | for (U32 i = 0; i < strlen(expr); i++) /*Flawfinder: ignore*/ | 392 | for (U32 i = 0; i < expr.length(); i++) /*Flawfinder: ignore*/ |
369 | { | 393 | { |
370 | expr[i] = tolower(expr[i]); | 394 | expr[i] = tolower(expr[i]); |
371 | } | 395 | } |
372 | |||
373 | char* ex = strtok(expr, ".*"); | ||
374 | char* rnd = (char*) renderer.c_str(); | ||
375 | 396 | ||
376 | while (ex != NULL && rnd != NULL) | 397 | // run the regular expression against the renderer |
377 | { | 398 | boost::regex re(expr.c_str()); |
378 | rnd = strstr(rnd, ex); | 399 | if(boost::regex_search(renderer, re)) |
379 | if (rnd != NULL) | ||
380 | { | ||
381 | rnd += strlen(ex); | ||
382 | } | ||
383 | ex = strtok(NULL, ".*"); | ||
384 | } | ||
385 | |||
386 | if (rnd != NULL) | ||
387 | { | 400 | { |
401 | // if we found it, stop! | ||
388 | file.close(); | 402 | file.close(); |
389 | llinfos << "GPU is " << label << llendl; | 403 | llinfos << "GPU is " << label << llendl; |
390 | mGPUString = label; | 404 | mGPUString = label; |
391 | mGPUClass = (S32) strtol(cls, NULL, 10); | 405 | mGPUClass = (EGPUClass) strtol(cls.c_str(), NULL, 10); |
406 | mGPUSupported = (BOOL) strtol(supported.c_str(), NULL, 10); | ||
392 | file.close(); | 407 | file.close(); |
393 | return; | 408 | return; |
394 | } | 409 | } |
@@ -404,33 +419,142 @@ void LLFeatureManager::cleanupFeatureTables() | |||
404 | mMaskList.clear(); | 419 | mMaskList.clear(); |
405 | } | 420 | } |
406 | 421 | ||
422 | void LLFeatureManager::init() | ||
423 | { | ||
424 | // load the tables | ||
425 | loadFeatureTables(); | ||
426 | |||
427 | // get the gpu class | ||
428 | loadGPUClass(); | ||
429 | |||
430 | // apply the base masks, so we know if anything is disabled | ||
431 | applyBaseMasks(); | ||
432 | } | ||
407 | 433 | ||
408 | void LLFeatureManager::initCPUFeatureMasks() | 434 | void LLFeatureManager::applyRecommendedSettings() |
409 | { | 435 | { |
410 | if (gSysMemory.getPhysicalMemoryClamped() <= 256*1024*1024) | 436 | // apply saved settings |
437 | // cap the level at 2 (high) | ||
438 | S32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_2)); | ||
439 | |||
440 | llinfos << "Applying Recommended Features" << llendl; | ||
441 | |||
442 | setGraphicsLevel(level, false); | ||
443 | gSavedSettings.setU32("RenderQualityPerformance", level); | ||
444 | gSavedSettings.setBOOL("RenderCustomSettings", FALSE); | ||
445 | |||
446 | // now apply the tweaks to draw distance | ||
447 | // these are double negatives, because feature masks only work by | ||
448 | // downgrading values, so i needed to make a true value go to false | ||
449 | // for certain cards, thus the awkward name, "Disregard..." | ||
450 | if(!gSavedSettings.getBOOL("Disregard96DefaultDrawDistance")) | ||
411 | { | 451 | { |
412 | maskFeatures("RAM256MB"); | 452 | gSavedSettings.setF32("RenderFarClip", 96.0f); |
413 | } | 453 | } |
414 | 454 | else if(!gSavedSettings.getBOOL("Disregard128DefaultDrawDistance")) | |
415 | #if LL_SOLARIS && defined(__sparc) // even low MHz SPARCs are fast | 455 | { |
416 | #error The 800 is hinky. Would something like a LL_MIN_MHZ make more sense here? | 456 | gSavedSettings.setF32("RenderFarClip", 128.0f); |
417 | if (gSysCPU.getMhz() < 800) | 457 | } |
418 | #else | 458 | |
419 | if (gSysCPU.getMhz() < 1100) | 459 | |
460 | } | ||
461 | |||
462 | void LLFeatureManager::applyFeatures(bool skipFeatures) | ||
463 | { | ||
464 | // see featuretable.txt / featuretable_linux.txt / featuretable_mac.txt | ||
465 | |||
466 | #ifndef LL_RELEASE_FOR_DOWNLOAD | ||
467 | dump(); | ||
420 | #endif | 468 | #endif |
469 | |||
470 | // scroll through all of these and set their corresponding control value | ||
471 | for(feature_map_t::iterator mIt = mFeatures.begin(); | ||
472 | mIt != mFeatures.end(); | ||
473 | ++mIt) | ||
421 | { | 474 | { |
422 | maskFeatures("CPUSlow"); | 475 | // skip features you want to skip |
476 | // do this for when you don't want to change certain settings | ||
477 | if(skipFeatures) | ||
478 | { | ||
479 | if(mSkippedFeatures.find(mIt->first) != mSkippedFeatures.end()) | ||
480 | { | ||
481 | continue; | ||
482 | } | ||
483 | } | ||
484 | |||
485 | // get the control setting | ||
486 | LLControlBase* ctrl = gSavedSettings.getControl(mIt->first); | ||
487 | if(ctrl == NULL) | ||
488 | { | ||
489 | llwarns << "AHHH! Control setting " << mIt->first << " does not exist!" << llendl; | ||
490 | continue; | ||
491 | } | ||
492 | |||
493 | // handle all the different types | ||
494 | if(ctrl->isType(TYPE_BOOLEAN)) | ||
495 | { | ||
496 | gSavedSettings.setBOOL(mIt->first, (BOOL)getRecommendedValue(mIt->first.c_str())); | ||
497 | } | ||
498 | else if (ctrl->isType(TYPE_S32)) | ||
499 | { | ||
500 | gSavedSettings.setS32(mIt->first, (S32)getRecommendedValue(mIt->first.c_str())); | ||
501 | } | ||
502 | else if (ctrl->isType(TYPE_U32)) | ||
503 | { | ||
504 | gSavedSettings.setU32(mIt->first, (U32)getRecommendedValue(mIt->first.c_str())); | ||
505 | } | ||
506 | else if (ctrl->isType(TYPE_F32)) | ||
507 | { | ||
508 | gSavedSettings.setF32(mIt->first, (F32)getRecommendedValue(mIt->first.c_str())); | ||
509 | } | ||
510 | else | ||
511 | { | ||
512 | llwarns << "AHHH! Control variable is not a numeric type!" << llendl; | ||
513 | } | ||
423 | } | 514 | } |
424 | if (isSafe()) | 515 | } |
516 | |||
517 | void LLFeatureManager::setGraphicsLevel(S32 level, bool skipFeatures) | ||
518 | { | ||
519 | applyBaseMasks(); | ||
520 | |||
521 | switch (level) | ||
425 | { | 522 | { |
426 | maskFeatures("safe"); | 523 | case 0: |
524 | maskFeatures("Low"); | ||
525 | break; | ||
526 | case 1: | ||
527 | maskFeatures("Mid"); | ||
528 | break; | ||
529 | case 2: | ||
530 | maskFeatures("High"); | ||
531 | break; | ||
532 | case 3: | ||
533 | maskFeatures("Ultra"); | ||
534 | break; | ||
535 | default: | ||
536 | maskFeatures("Low"); | ||
537 | break; | ||
427 | } | 538 | } |
539 | |||
540 | applyFeatures(skipFeatures); | ||
428 | } | 541 | } |
429 | 542 | ||
430 | void LLFeatureManager::initGraphicsFeatureMasks() | 543 | void LLFeatureManager::applyBaseMasks() |
431 | { | 544 | { |
432 | loadGPUClass(); | 545 | // reapply masks |
433 | 546 | mFeatures.clear(); | |
547 | |||
548 | LLFeatureList* maskp = findMask("all"); | ||
549 | if(maskp == NULL) | ||
550 | { | ||
551 | llwarns << "AHH! No \"all\" in feature table!" << llendl; | ||
552 | return; | ||
553 | } | ||
554 | |||
555 | mFeatures = maskp->getFeatures(); | ||
556 | |||
557 | // mask class | ||
434 | if (mGPUClass >= 0 && mGPUClass < 4) | 558 | if (mGPUClass >= 0 && mGPUClass < 4) |
435 | { | 559 | { |
436 | const char* class_table[] = | 560 | const char* class_table[] = |
@@ -444,7 +568,13 @@ void LLFeatureManager::initGraphicsFeatureMasks() | |||
444 | llinfos << "Setting GPU Class to " << class_table[mGPUClass] << llendl; | 568 | llinfos << "Setting GPU Class to " << class_table[mGPUClass] << llendl; |
445 | maskFeatures(class_table[mGPUClass]); | 569 | maskFeatures(class_table[mGPUClass]); |
446 | } | 570 | } |
447 | 571 | else | |
572 | { | ||
573 | llinfos << "Setting GPU Class to Unknown" << llendl; | ||
574 | maskFeatures("Unknown"); | ||
575 | } | ||
576 | |||
577 | // now all those wacky ones | ||
448 | if (!gGLManager.mHasFragmentShader) | 578 | if (!gGLManager.mHasFragmentShader) |
449 | { | 579 | { |
450 | maskFeatures("NoPixelShaders"); | 580 | maskFeatures("NoPixelShaders"); |
@@ -477,6 +607,8 @@ void LLFeatureManager::initGraphicsFeatureMasks() | |||
477 | { | 607 | { |
478 | maskFeatures("OpenGLPre15"); | 608 | maskFeatures("OpenGLPre15"); |
479 | } | 609 | } |
610 | |||
611 | // now mask by gpu string | ||
480 | // Replaces ' ' with '_' in mGPUString to deal with inability for parser to handle spaces | 612 | // Replaces ' ' with '_' in mGPUString to deal with inability for parser to handle spaces |
481 | std::string gpustr = mGPUString; | 613 | std::string gpustr = mGPUString; |
482 | for (std::string::iterator iter = gpustr.begin(); iter != gpustr.end(); ++iter) | 614 | for (std::string::iterator iter = gpustr.begin(); iter != gpustr.end(); ++iter) |
@@ -486,94 +618,28 @@ void LLFeatureManager::initGraphicsFeatureMasks() | |||
486 | *iter = '_'; | 618 | *iter = '_'; |
487 | } | 619 | } |
488 | } | 620 | } |
489 | // llinfos << "Masking features from gpu table match: " << gpustr << llendl; | 621 | |
622 | //llinfos << "Masking features from gpu table match: " << gpustr << llendl; | ||
490 | maskFeatures(gpustr.c_str()); | 623 | maskFeatures(gpustr.c_str()); |
491 | 624 | ||
492 | if (isSafe()) | 625 | // now mask cpu type ones |
626 | if (gSysMemory.getPhysicalMemoryClamped() <= 256*1024*1024) | ||
493 | { | 627 | { |
494 | maskFeatures("safe"); | 628 | maskFeatures("RAM256MB"); |
495 | } | 629 | } |
496 | } | ||
497 | |||
498 | void LLFeatureManager::applyRecommendedFeatures() | ||
499 | { | ||
500 | // see featuretable.txt / featuretable_linux.txt / featuretable_mac.txt | ||
501 | |||
502 | llinfos << "Applying Recommended Features" << llendl; | ||
503 | #ifndef LL_RELEASE_FOR_DOWNLOAD | ||
504 | dump(); | ||
505 | #endif | ||
506 | 630 | ||
507 | // Enabling VBO | 631 | #if LL_SOLARIS && defined(__sparc) // even low MHz SPARCs are fast |
508 | if (getRecommendedLevel("RenderVBO")) | 632 | #error The 800 is hinky. Would something like a LL_MIN_MHZ make more sense here? |
509 | { | 633 | if (gSysCPU.getMhz() < 800) |
510 | gSavedSettings.setBOOL("RenderVBOEnable", TRUE); | 634 | #else |
511 | } | 635 | if (gSysCPU.getMhz() < 1100) |
512 | else | 636 | #endif |
513 | { | 637 | { |
514 | gSavedSettings.setBOOL("RenderVBOEnable", FALSE); | 638 | maskFeatures("CPUSlow"); |
515 | } | 639 | } |
516 | 640 | ||
517 | // Anisotropic rendering | ||
518 | BOOL aniso = getRecommendedLevel("RenderAniso"); | ||
519 | LLImageGL::sGlobalUseAnisotropic = aniso; | ||
520 | gSavedSettings.setBOOL("RenderAnisotropic", LLImageGL::sGlobalUseAnisotropic); | ||
521 | |||
522 | // Render Avatar Mode | ||
523 | BOOL avatar_vp = getRecommendedLevel("RenderAvatarVP"); | ||
524 | S32 avatar_mode = getRecommendedLevel("RenderAvatarMode"); | ||
525 | if (avatar_vp == FALSE) | ||
526 | avatar_mode = 0; | ||
527 | gSavedSettings.setBOOL("RenderAvatarVP", avatar_vp); | ||
528 | gSavedSettings.setS32("RenderAvatarMode", avatar_mode); | ||
529 | |||
530 | // Render Distance | ||
531 | S32 far_clip = getRecommendedLevel("RenderDistance"); | ||
532 | gSavedSettings.setF32("RenderFarClip", (F32)far_clip); | ||
533 | |||
534 | // Lighting | ||
535 | S32 lighting = getRecommendedLevel("RenderLighting"); | ||
536 | gSavedSettings.setS32("RenderLightingDetail", lighting); | ||
537 | |||
538 | // ObjectBump | ||
539 | BOOL bump = getRecommendedLevel("RenderObjectBump"); | ||
540 | gSavedSettings.setBOOL("RenderObjectBump", bump); | ||
541 | |||
542 | // Particle Count | ||
543 | S32 max_parts = getRecommendedLevel("RenderParticleCount"); | ||
544 | gSavedSettings.setS32("RenderMaxPartCount", max_parts); | ||
545 | LLViewerPartSim::setMaxPartCount(max_parts); | ||
546 | |||
547 | // RippleWater | ||
548 | BOOL ripple = getRecommendedLevel("RenderRippleWater"); | ||
549 | gSavedSettings.setBOOL("RenderRippleWater", ripple); | ||
550 | |||
551 | // Occlusion Culling | ||
552 | BOOL occlusion = getRecommendedLevel("UseOcclusion"); | ||
553 | gSavedSettings.setBOOL("UseOcclusion", occlusion); | ||
554 | |||
555 | // Vertex Shaders | ||
556 | S32 shaders = getRecommendedLevel("VertexShaderEnable"); | ||
557 | gSavedSettings.setBOOL("VertexShaderEnable", shaders); | ||
558 | |||
559 | // Terrain | ||
560 | S32 terrain = getRecommendedLevel("RenderTerrainDetail"); | ||
561 | gSavedSettings.setS32("RenderTerrainDetail", terrain); | ||
562 | LLDrawPoolTerrain::sDetailMode = terrain; | ||
563 | |||
564 | // Set the amount of VRAM we have available | ||
565 | if (isSafe()) | 641 | if (isSafe()) |
566 | { | 642 | { |
567 | gSavedSettings.setS32("GraphicsCardMemorySetting", 1); // 32 MB in 'safe' mode | 643 | maskFeatures("safe"); |
568 | } | ||
569 | else | ||
570 | { | ||
571 | S32 idx = gSavedSettings.getS32("GraphicsCardMemorySetting"); | ||
572 | // -1 indicates use default (max), don't change | ||
573 | if (idx != -1) | ||
574 | { | ||
575 | idx = LLViewerImageList::getMaxVideoRamSetting(-2); // get max recommended setting | ||
576 | gSavedSettings.setS32("GraphicsCardMemorySetting", idx); | ||
577 | } | ||
578 | } | 644 | } |
579 | } | 645 | } |