From f6f9e5b802102a70b0804934b555b333f87453b1 Mon Sep 17 00:00:00 2001 From: Andros Baphomet Date: Wed, 2 Oct 2013 00:17:45 -0400 Subject: [PATCH 1/2] Rewrote X log parser in VRAM detection code --- indra/llwindow/llwindowsdl.cpp | 48 +++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index e1fa498fa..6e5922d7f 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -75,6 +75,9 @@ static bool ATIbug = false; #if LL_X11 # include +#include +#include +#include #endif //LL_X11 // TOFU HACK -- (*exactly* the same hack as LLWindowMacOSX for a similar @@ -323,6 +326,33 @@ static int x11_detect_VRAM_kb_fp(FILE *fp, const char *prefix_str) return 0; // 'could not detect' } +static int x11_detect_VRAM_kb_br(std::string filename) { + boost::regex pattern(".*?(VRAM|Memory|Video\\s?RAM)\\D*(\\d+)\\s?([kK]B?)"); + std::string line; + std::ifstream in(filename.c_str()); + int matched = -1; + if(in.is_open()) { + matched = 0; + while (getline(in, line)) + { + // lldebugs << "Processing line: " << line << llendl; + boost::cmatch match; + if(boost::regex_search(line.c_str(), match, pattern)) + { + matched = atoi(std::string(match[2]).c_str()); + lldebugs << "VRAM found: " << matched << llendl; + lldebugs << "Line matched: " << line << llendl; + } + } + in.close(); + } + else + { + lldebugs << "Couldn't open logfile " << filename << llendl; + } + return matched; // matched should be -1 if no file opened, 0 if file opened but no info found, or >0 if file opened and info found +} + static int x11_detect_VRAM_kb() { #if LL_SOLARIS && defined(__sparc) @@ -352,7 +382,8 @@ static int x11_detect_VRAM_kb() fname += "Xorg."; fname += ('0' + display_num); fname += ".log"; - fp = fopen(fname.c_str(), "r"); + rtn = x11_detect_VRAM_kb_br(fname); + /*fp = fopen(fname.c_str(), "r"); if (fp) { llinfos << "Looking in " << fname @@ -373,12 +404,13 @@ static int x11_detect_VRAM_kb() { rtn = x11_detect_VRAM_kb_fp(fp, ": Memory: "); fclose(fp); + } } } } } - } - else + }*/ + if(rtn == -1) // we couldn't read the Xorg file { llinfos << "Could not open " << fname << " - skipped." << llendl; @@ -387,7 +419,8 @@ static int x11_detect_VRAM_kb() fname += "XFree86."; fname += ('0' + display_num); fname += ".log"; - fp = fopen(fname.c_str(), "r"); + rtn = x11_detect_VRAM_kb_br(fname); + /*fp = fopen(fname.c_str(), "r"); if (fp) { llinfos << "Looking in " << fname @@ -403,13 +436,16 @@ static int x11_detect_VRAM_kb() fclose(fp); } } - } - else + }*/ + if(rtn == -1) // couldn't read old X log file either { llinfos << "Could not open " << fname << " - skipped." << llendl; + //stumped here, return 0 + rtn = 0; } } + return rtn; #endif // LL_SOLARIS } From c39d66b54721ed6d0a663f89d46d06321682c10d Mon Sep 17 00:00:00 2001 From: Andros Baphomet Date: Wed, 2 Oct 2013 21:35:17 -0400 Subject: [PATCH 2/2] Improved X log parser to handle VirtualGL systems, removed old X log parser --- indra/llwindow/llwindowsdl.cpp | 130 +++++++-------------------------- 1 file changed, 26 insertions(+), 104 deletions(-) diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index 6e5922d7f..10bcf816a 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -273,59 +273,16 @@ static SDL_Surface *Load_BMP_Resource(const char *basename) } #if LL_X11 -// This is an XFree86/XOrg-specific hack for detecting the amount of Video RAM -// on this machine. It works by searching /var/log/var/log/Xorg.?.log or -// /var/log/XFree86.?.log for a ': (VideoRAM ?|Memory): (%d+) kB' regex, where -// '?' is the X11 display number derived from $DISPLAY -static int x11_detect_VRAM_kb_fp(FILE *fp, const char *prefix_str) -{ - const int line_buf_size = 1000; - char line_buf[line_buf_size]; - while (fgets(line_buf, line_buf_size, fp)) - { - //lldebugs << "XLOG: " << line_buf << llendl; - - // Why the ad-hoc parser instead of using a regex? Our - // favourite regex implementation - libboost_regex - is - // quite a heavy and troublesome dependency for the client, so - // it seems a shame to introduce it for such a simple task. - // *FIXME: libboost_regex is a dependency now anyway, so we may - // as well use it instead of this hand-rolled nonsense. - const char *part1_template = prefix_str; - const char part2_template[] = " kB"; - char *part1 = strstr(line_buf, part1_template); - if (part1) // found start of matching line - { - part1 = &part1[strlen(part1_template)]; // -> after - char *part2 = strstr(part1, part2_template); - if (part2) // found end of matching line - { - // now everything between part1 and part2 is - // supposed to be numeric, describing the - // number of kB of Video RAM supported - int rtn = 0; - for (; part1 < part2; ++part1) - { - if (*part1 < '0' || *part1 > '9') - { - // unexpected char, abort parse - rtn = 0; - break; - } - rtn *= 10; - rtn += (*part1) - '0'; - } - if (rtn > 0) - { - // got the kB number. return it now. - return rtn; - } - } - } - } - return 0; // 'could not detect' -} - +// This function scrapes the Xorg log to determine the amount of VRAM available to the system. +// Believe it or not, this is the most reliable way at present to detect VRAM on Linux (until +// some angelic being ports the whole viewer to SDL 2.0 or something). +// +// Returns -1 if it couldn't open the file, +// 0 if it could open the file but couldn't detect the amount of VRAM, or +// >0 if it open the file and detect the amount of VRAM present. +// In that case, the number will be the amount of available VRAM in kilobytes. +// +// static int x11_detect_VRAM_kb_br(std::string filename) { boost::regex pattern(".*?(VRAM|Memory|Video\\s?RAM)\\D*(\\d+)\\s?([kK]B?)"); std::string line; @@ -346,11 +303,11 @@ static int x11_detect_VRAM_kb_br(std::string filename) { } in.close(); } - else + else // We couldn't open the file, so bow out. { lldebugs << "Couldn't open logfile " << filename << llendl; } - return matched; // matched should be -1 if no file opened, 0 if file opened but no info found, or >0 if file opened and info found + return matched; } static int x11_detect_VRAM_kb() @@ -365,9 +322,16 @@ static int x11_detect_VRAM_kb() std::string fname; int rtn = 0; // 'could not detect' int display_num = 0; - FILE *fp; - char *display_env = getenv("DISPLAY"); // e.g. :0 or :0.0 or :1.0 etc - // parse DISPLAY number so we can go grab the right log file + char *display_env = getenv("VGL_DISPLAY"); // e.g. :0 or :0.0 or :1.0 etc + // We parse $VGL_DISPLAY first so we can grab the right Xorg filename + // if we're using VirtualGL (like Optimus systems do). + + if (display_env == NULL) { + // if $VGL_DISPLAY doesn't exist, then we're in a single-card setup + display_env = getenv("DISPLAY"); + } + + // parse display number so we can go grab the right log file if (display_env[0] == ':' && display_env[1] >= '0' && display_env[1] <= '9') { @@ -375,41 +339,15 @@ static int x11_detect_VRAM_kb() } // *TODO: we could be smarter and see which of Xorg/XFree86 has the - // freshest time-stamp. + // freshest time-stamp. (...but would it work with VirtualGL?) // Try Xorg log first fname = x_log_location; fname += "Xorg."; fname += ('0' + display_num); fname += ".log"; + llinfos << "Looking in " << fname << " for VRAM info..." << llendl; rtn = x11_detect_VRAM_kb_br(fname); - /*fp = fopen(fname.c_str(), "r"); - if (fp) - { - llinfos << "Looking in " << fname - << " for VRAM info..." << llendl; - rtn = x11_detect_VRAM_kb_fp(fp, ": VideoRAM: "); - fclose(fp); - if (0 == rtn) - { - fp = fopen(fname.c_str(), "r"); - if (fp) - { - rtn = x11_detect_VRAM_kb_fp(fp, ": Video RAM: "); - fclose(fp); - if (0 == rtn) - { - fp = fopen(fname.c_str(), "r"); - if (fp) - { - rtn = x11_detect_VRAM_kb_fp(fp, ": Memory: "); - fclose(fp); - } - } - } - } - } - }*/ if(rtn == -1) // we couldn't read the Xorg file { llinfos << "Could not open " << fname @@ -419,24 +357,8 @@ static int x11_detect_VRAM_kb() fname += "XFree86."; fname += ('0' + display_num); fname += ".log"; + llinfos << "Looking in " << fname << " for VRAM info..." << llendl; rtn = x11_detect_VRAM_kb_br(fname); - /*fp = fopen(fname.c_str(), "r"); - if (fp) - { - llinfos << "Looking in " << fname - << " for VRAM info..." << llendl; - rtn = x11_detect_VRAM_kb_fp(fp, ": VideoRAM: "); - fclose(fp); - if (0 == rtn) - { - fp = fopen(fname.c_str(), "r"); - if (fp) - { - rtn = x11_detect_VRAM_kb_fp(fp, ": Memory: "); - fclose(fp); - } - } - }*/ if(rtn == -1) // couldn't read old X log file either { llinfos << "Could not open " << fname @@ -445,7 +367,7 @@ static int x11_detect_VRAM_kb() rtn = 0; } } - + llinfos << "Amount of VRAM detected: "<< rtn << " KB" << llendl; return rtn; #endif // LL_SOLARIS }