From f35d6cd35d92ad16a55bf49f61f19153949497c0 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Fri, 11 May 2012 21:55:28 +0300 Subject: Improve auto detection for best graphics mode. --- src/client.cpp | 122 +++++++++++++++++++++++++++------------------- src/graphicsmanager.cpp | 109 +++++++++++++++++++++++++++++++++++++++++ src/graphicsmanager.h | 10 ++++ src/test/testlauncher.cpp | 10 ++++ src/test/testlauncher.h | 2 + src/test/testmain.cpp | 20 ++++++-- 6 files changed, 219 insertions(+), 54 deletions(-) (limited to 'src') diff --git a/src/client.cpp b/src/client.cpp index 53fc071f9..18740cfd5 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -280,7 +280,7 @@ Client::Client(const Options &options): void Client::testsInit() { - if (!mOptions.test.empty()) + if (!mOptions.test.empty() && mOptions.test != "99") { gameInit(); } @@ -2004,48 +2004,59 @@ void Client::storeSafeParameters() if (isSafeMode) logger->log1("Run in safe mode"); - tmpHwaccel = config.getBoolValue("hwaccel"); - #if defined USE_OPENGL tmpOpengl = config.getIntValue("opengl"); #else tmpOpengl = 0; #endif - tmpFpslimit = config.getIntValue("fpslimit"); - tmpAltFpslimit = config.getIntValue("altfpslimit"); - tmpSound = config.getBoolValue("sound"); width = config.getIntValue("screenwidth"); height = config.getIntValue("screenheight"); - font = config.getStringValue("font"); - bFont = config.getStringValue("boldFont"); - particleFont = config.getStringValue("particleFont"); - helpFont = config.getStringValue("helpFont"); - secureFont = config.getStringValue("secureFont"); - japanFont = config.getStringValue("japanFont"); - - showBackground = config.getBoolValue("showBackground"); - enableMumble = config.getBoolValue("enableMumble"); - enableMapReduce = config.getBoolValue("enableMapReduce"); - - config.setValue("hwaccel", false); - config.setValue("opengl", 0); - config.setValue("fpslimit", 0); - config.setValue("altfpslimit", 0); - config.setValue("sound", false); - config.setValue("safemode", true); - config.setValue("screenwidth", 640); - config.setValue("screenheight", 480); - config.setValue("font", "fonts/dejavusans.ttf"); - config.setValue("boldFont", "fonts/dejavusans-bold.ttf"); - config.setValue("particleFont", "fonts/dejavusans.ttf"); - config.setValue("helpFont", "fonts/dejavusansmono.ttf"); - config.setValue("secureFont", "fonts/dejavusansmono.ttf"); - config.setValue("japanFont", "fonts/mplus-1p-regular.ttf"); - config.setValue("showBackground", false); - config.setValue("enableMumble", false); - config.setValue("enableMapReduce", false); + if (!mOptions.safeMode && !tmpOpengl) + { + tmpHwaccel = config.getBoolValue("hwaccel"); + + tmpFpslimit = config.getIntValue("fpslimit"); + tmpAltFpslimit = config.getIntValue("altfpslimit"); + tmpSound = config.getBoolValue("sound"); + + font = config.getStringValue("font"); + bFont = config.getStringValue("boldFont"); + particleFont = config.getStringValue("particleFont"); + helpFont = config.getStringValue("helpFont"); + secureFont = config.getStringValue("secureFont"); + japanFont = config.getStringValue("japanFont"); + + showBackground = config.getBoolValue("showBackground"); + enableMumble = config.getBoolValue("enableMumble"); + enableMapReduce = config.getBoolValue("enableMapReduce"); + + // if video mode configured reset most settings to safe + config.setValue("hwaccel", false); + config.setValue("opengl", 0); + config.setValue("altfpslimit", 3); + config.setValue("sound", false); + config.setValue("safemode", true); + config.setValue("screenwidth", 640); + config.setValue("screenheight", 480); + config.setValue("font", "fonts/dejavusans.ttf"); + config.setValue("boldFont", "fonts/dejavusans-bold.ttf"); + config.setValue("particleFont", "fonts/dejavusans.ttf"); + config.setValue("helpFont", "fonts/dejavusansmono.ttf"); + config.setValue("secureFont", "fonts/dejavusansmono.ttf"); + config.setValue("japanFont", "fonts/mplus-1p-regular.ttf"); + config.setValue("showBackground", false); + config.setValue("enableMumble", false); + config.setValue("enableMapReduce", false); + } + else + { + // if video mode not configured reset only video mode to safe + config.setValue("opengl", 0); + config.setValue("screenwidth", 640); + config.setValue("screenheight", 480); + } config.write(); @@ -2055,23 +2066,32 @@ void Client::storeSafeParameters() return; } - config.setValue("hwaccel", tmpHwaccel); - config.setValue("opengl", tmpOpengl); - config.setValue("fpslimit", tmpFpslimit); - config.setValue("altfpslimit", tmpAltFpslimit); - config.setValue("sound", tmpSound); - config.setValue("safemode", false); - config.setValue("screenwidth", width); - config.setValue("screenheight", height); - config.setValue("font", font); - config.setValue("boldFont", bFont); - config.setValue("particleFont", particleFont); - config.setValue("helpFont", helpFont); - config.setValue("secureFont", secureFont); - config.setValue("japanFont", japanFont); - config.setValue("showBackground", showBackground); - config.setValue("enableMumble", enableMumble); - config.setValue("enableMapReduce", enableMapReduce); + if (!tmpOpengl) + { + config.setValue("hwaccel", tmpHwaccel); + config.setValue("opengl", tmpOpengl); + config.setValue("fpslimit", tmpFpslimit); + config.setValue("altfpslimit", tmpAltFpslimit); + config.setValue("sound", tmpSound); + config.setValue("safemode", false); + config.setValue("screenwidth", width); + config.setValue("screenheight", height); + config.setValue("font", font); + config.setValue("boldFont", bFont); + config.setValue("particleFont", particleFont); + config.setValue("helpFont", helpFont); + config.setValue("secureFont", secureFont); + config.setValue("japanFont", japanFont); + config.setValue("showBackground", showBackground); + config.setValue("enableMumble", enableMumble); + config.setValue("enableMapReduce", enableMapReduce); + } + else + { + config.setValue("opengl", tmpOpengl); + config.setValue("screenwidth", width); + config.setValue("screenheight", height); + } } void Client::initTradeFilter() diff --git a/src/graphicsmanager.cpp b/src/graphicsmanager.cpp index fbe852588..68a2ac48d 100644 --- a/src/graphicsmanager.cpp +++ b/src/graphicsmanager.cpp @@ -27,6 +27,8 @@ #include "resources/image.h" +#include "utils/paths.h" +#include "utils/process.h" #include "utils/stringutils.h" #include "debug.h" @@ -41,6 +43,94 @@ GraphicsManager::~GraphicsManager() { } +bool GraphicsManager::detectGraphics() +{ +#ifdef USE_OPENGL + logger->log("start detecting best mode..."); + logger->log("enable opengl mode"); + SDL_SetVideoMode(100, 100, 0, SDL_ANYFORMAT | SDL_OPENGL); + + std::string vendor = getGLString(GL_VENDOR); + std::string renderer = getGLString(GL_RENDERER); + std::string version = getGLString(GL_VERSION); + logger->log("gl vendor: %s", vendor.c_str()); + logger->log("gl renderer: %s", renderer.c_str()); + logger->log("gl version: %s", version.c_str()); + sscanf(version.c_str(), "%d.%d", &mMajor, &mMinor); + + char const *glExtensions = reinterpret_cast( + glGetString(GL_EXTENSIONS)); + updateExtensions(glExtensions); + + bool mode = 1; + + // detecting features by known renderers or vendors + if (findI(renderer, "gdi generic") != std::string::npos) + { + // windows gdi OpenGL emulation + logger->log("detected gdi drawing"); + logger->log("disable OpenGL"); + mode = 0; + } + else if (findI(renderer, "Software Rasterizer") != std::string::npos) + { + // software OpenGL emulation + logger->log("detected software drawing"); + logger->log("disable OpenGL"); + mode = 0; + } + else if (findI(renderer, "Indirect") != std::string::npos) + { + // indirect OpenGL drawing + logger->log("detected indirect drawing"); + logger->log("disable OpenGL"); + mode = 0; + } + else if (findI(vendor, "VMWARE") != std::string::npos) + { + // vmware emulation + logger->log("detected VMWARE driver"); + logger->log("disable OpenGL"); + mode = 0; + } + else if (findI(renderer, "LLVM") != std::string::npos) + { + // llvm opengl emulation + logger->log("detected llvm driver"); + logger->log("disable OpenGL"); + mode = 0; + } + else if (findI(vendor, "NVIDIA") != std::string::npos) + { + // hope it can work well + logger->log("detected NVIDIA driver"); + mode = 1; + } + + // detecting feature based on OpenGL version + if (!checkGLVersion(1, 1)) + { + // very old OpenGL version + logger->log("OpenGL version too old"); + mode = 0; + } + + if (mode > 0 && findI(version, "Mesa") != std::string::npos) + { + // Mesa detected + config.setValue("compresstextures", true); + } + + config.setValue("opengl", mode); + config.setValue("videoconfigured", true); + + logger->log("detection complete"); + return true; +#else + return false; +#endif +} + void GraphicsManager::initGraphics(bool noOpenGL) { #ifdef USE_OPENGL @@ -158,6 +248,19 @@ void GraphicsManager::logString(const char *format, int num) #endif } +std::string GraphicsManager::getGLString(int num) const +{ +#ifdef USE_OPENGL + const char *str = reinterpret_cast(glGetString(num)); + if (str) + return str; + else + return ""; +#else + return ""; +#endif +} + void GraphicsManager::setVideoMode() { const int width = config.getIntValue("screenwidth"); @@ -197,3 +300,9 @@ void GraphicsManager::setVideoMode() } } } + + +bool GraphicsManager::checkGLVersion(int major, int minor) const +{ + return mMajor > major || (mMajor == major && mMinor >= minor); +} diff --git a/src/graphicsmanager.h b/src/graphicsmanager.h index cefbe81d2..9c892b80d 100644 --- a/src/graphicsmanager.h +++ b/src/graphicsmanager.h @@ -35,6 +35,8 @@ class GraphicsManager void initGraphics(bool noOpenGL); + bool detectGraphics(); + void updateExtensions(const char *extensions); bool supportExtension(const std::string &ext); @@ -43,10 +45,18 @@ class GraphicsManager void logString(const char *format, int num); + std::string getGLString(int num) const; + void setVideoMode(); + bool checkGLVersion(int major, int minor) const; + private: std::set mExtensions; + + int mMinor; + + int mMajor; }; extern GraphicsManager graphicsManager; diff --git a/src/test/testlauncher.cpp b/src/test/testlauncher.cpp index 6818c0b3c..b3fa729a0 100644 --- a/src/test/testlauncher.cpp +++ b/src/test/testlauncher.cpp @@ -23,6 +23,7 @@ #include "client.h" #include "configuration.h" #include "graphics.h" +#include "graphicsmanager.h" #include "localconsts.h" #include "logger.h" #include "sound.h" @@ -69,6 +70,8 @@ int TestLauncher::exec() return testRescale(); else if (mTest == "8" || mTest == "9" || mTest == "10") return testFps(); + else if (mTest == "99") + return testVideoDetection(); else if (mTest == "100") return testInternal(); @@ -207,6 +210,13 @@ int TestLauncher::testInternal() return 0; } +int TestLauncher::testVideoDetection() +{ + graphicsManager.detectGraphics(); + file << mTest << std::endl; + file << config.getIntValue("opengl") << std::endl; +} + int TestLauncher::calcFps(timeval *start, timeval *end, int calls) { long mtime; diff --git a/src/test/testlauncher.h b/src/test/testlauncher.h index 1f86dc396..5ca42eae7 100644 --- a/src/test/testlauncher.h +++ b/src/test/testlauncher.h @@ -47,6 +47,8 @@ class TestLauncher int testInternal(); + int testVideoDetection(); + private: std::string mTest; diff --git a/src/test/testmain.cpp b/src/test/testmain.cpp index eb24a2c75..8ec48e6e2 100644 --- a/src/test/testmain.cpp +++ b/src/test/testmain.cpp @@ -78,9 +78,10 @@ int TestMain::exec() { initConfig(); int softwareTest = invokeSoftwareRenderTest("1"); - int fastOpenGLTest = invokeFastOpenGLRenderTest("2"); - int safeOpenGLTest = invokeSafeOpenGLRenderTest("3"); - int soundTest = invokeTest4(); + int fastOpenGLTest = -1; + int safeOpenGLTest = -1; + int videoDetectTest = -1; + int soundTest = -1; int rescaleTest[3]; int softFps = 0; int fastOpenGLFps = 0; @@ -88,11 +89,20 @@ int TestMain::exec() int openGLMode = 0; int maxFps = 0; + int detectMode = 0; rescaleTest[0] = -1; rescaleTest[1] = -1; rescaleTest[2] = -1; std::string info; + videoDetectTest = invokeTest("99"); + if (!videoDetectTest) + detectMode = readValue(99); + + fastOpenGLTest = invokeFastOpenGLRenderTest("2"); + safeOpenGLTest = invokeSafeOpenGLRenderTest("3"); + soundTest = invokeTest4(); + info += strprintf("%d.%d,%d,%d.", soundTest, softwareTest, fastOpenGLTest, safeOpenGLTest); @@ -184,6 +194,10 @@ int TestMain::exec() maxFps = safeOpenGLFps; } + // if OpenGL implimentation is not good, disable it. + if (!detectMode) + openGLMode = 0; + writeConfig(openGLMode, rescaleTest[openGLMode], soundTest, info); return 0; } -- cgit v1.2.3-60-g2f50