LCOV - code coverage report
Current view: top level - source/ps/GameSetup - HWDetect.cpp (source / functions) Hit Total Coverage
Test: 0 A.D. test coverage report Lines: 1 113 0.9 %
Date: 2023-01-19 00:18:29 Functions: 2 7 28.6 %

          Line data    Source code
       1             : /* Copyright (C) 2022 Wildfire Games.
       2             :  * This file is part of 0 A.D.
       3             :  *
       4             :  * 0 A.D. is free software: you can redistribute it and/or modify
       5             :  * it under the terms of the GNU General Public License as published by
       6             :  * the Free Software Foundation, either version 2 of the License, or
       7             :  * (at your option) any later version.
       8             :  *
       9             :  * 0 A.D. is distributed in the hope that it will be useful,
      10             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12             :  * GNU General Public License for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU General Public License
      15             :  * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
      16             :  */
      17             : 
      18             : #include "precompiled.h"
      19             : 
      20             : #include "lib/svn_revision.h"
      21             : #include "lib/timer.h"
      22             : #include "lib/utf8.h"
      23             : #include "lib/external_libraries/libsdl.h"
      24             : #include "lib/posix/posix_utsname.h"
      25             : #include "lib/sysdep/cpu.h"
      26             : #include "lib/sysdep/numa.h"
      27             : #include "lib/sysdep/os_cpu.h"
      28             : #if CONFIG2_AUDIO
      29             : #include "soundmanager/SoundManager.h"
      30             : #endif
      31             : #include "ps/CLogger.h"
      32             : #include "ps/ConfigDB.h"
      33             : #include "ps/Filesystem.h"
      34             : #include "ps/GameSetup/Config.h"
      35             : #include "ps/Profile.h"
      36             : #include "ps/scripting/JSInterface_ConfigDB.h"
      37             : #include "ps/scripting/JSInterface_Debug.h"
      38             : #include "ps/UserReport.h"
      39             : #include "ps/VideoMode.h"
      40             : #include "renderer/backend/IDevice.h"
      41             : #include "scriptinterface/FunctionWrapper.h"
      42             : #include "scriptinterface/JSON.h"
      43             : #include "scriptinterface/Object.h"
      44             : #include "scriptinterface/ScriptInterface.h"
      45             : 
      46             : // FreeType headers might have an include order.
      47             : #include <ft2build.h>
      48             : #include <freetype/freetype.h>
      49             : 
      50             : #if OS_LINUX
      51             : #include <fstream>
      52             : #endif
      53             : 
      54             : #include <sstream>
      55             : #include <string>
      56             : #include <thread>
      57             : 
      58             : static void ReportSDL(const ScriptRequest& rq, JS::HandleValue settings);
      59             : static void ReportFreeType(const ScriptRequest& rq, JS::HandleValue settings);
      60             : 
      61           0 : void SetDisableAudio(bool disabled)
      62             : {
      63           0 :     g_DisableAudio = disabled;
      64           0 : }
      65             : 
      66           0 : void RunHardwareDetection()
      67             : {
      68           0 :     TIMER(L"RunHardwareDetection");
      69             : 
      70           0 :     ScriptInterface scriptInterface("Engine", "HWDetect", g_ScriptContext);
      71             : 
      72           0 :     ScriptRequest rq(scriptInterface);
      73             : 
      74           0 :     JSI_Debug::RegisterScriptFunctions(scriptInterface); // Engine.DisplayErrorDialog
      75           0 :     JSI_ConfigDB::RegisterScriptFunctions(scriptInterface);
      76             : 
      77           0 :     ScriptFunction::Register<SetDisableAudio>(rq, "SetDisableAudio");
      78             : 
      79             :     // Load the detection script:
      80             : 
      81           0 :     const wchar_t* scriptName = L"hwdetect/hwdetect.js";
      82           0 :     CVFSFile file;
      83           0 :     if (file.Load(g_VFS, scriptName) != PSRETURN_OK)
      84             :     {
      85           0 :         LOGERROR("Failed to load hardware detection script");
      86           0 :         return;
      87             :     }
      88             : 
      89           0 :     std::string code = file.DecodeUTF8(); // assume it's UTF-8
      90           0 :     scriptInterface.LoadScript(scriptName, code);
      91             : 
      92             :     // Collect all the settings we'll pass to the script:
      93             :     // (We'll use this same data for the opt-in online reporting system, so it
      94             :     // includes some fields that aren't directly useful for the hwdetect script)
      95             : 
      96           0 :     JS::RootedValue settings(rq.cx);
      97           0 :     Script::CreateObject(rq, &settings);
      98             : 
      99           0 :     Script::SetProperty(rq, settings, "os_unix", OS_UNIX);
     100           0 :     Script::SetProperty(rq, settings, "os_bsd", OS_BSD);
     101           0 :     Script::SetProperty(rq, settings, "os_linux", OS_LINUX);
     102           0 :     Script::SetProperty(rq, settings, "os_android", OS_ANDROID);
     103           0 :     Script::SetProperty(rq, settings, "os_macosx", OS_MACOSX);
     104           0 :     Script::SetProperty(rq, settings, "os_win", OS_WIN);
     105             : 
     106           0 :     Script::SetProperty(rq, settings, "arch_ia32", ARCH_IA32);
     107           0 :     Script::SetProperty(rq, settings, "arch_amd64", ARCH_AMD64);
     108           0 :     Script::SetProperty(rq, settings, "arch_arm", ARCH_ARM);
     109           0 :     Script::SetProperty(rq, settings, "arch_aarch64", ARCH_AARCH64);
     110           0 :     Script::SetProperty(rq, settings, "arch_e2k", ARCH_E2K);
     111           0 :     Script::SetProperty(rq, settings, "arch_ppc64", ARCH_PPC64);
     112             : 
     113             : #ifdef NDEBUG
     114             :     Script::SetProperty(rq, settings, "build_debug", 0);
     115             : #else
     116           0 :     Script::SetProperty(rq, settings, "build_debug", 1);
     117             : #endif
     118           0 :     Script::SetProperty(rq, settings, "build_opengles", CONFIG2_GLES);
     119             : 
     120           0 :     Script::SetProperty(rq, settings, "build_datetime", std::string(__DATE__ " " __TIME__));
     121           0 :     Script::SetProperty(rq, settings, "build_revision", std::wstring(svn_revision));
     122             : 
     123           0 :     Script::SetProperty(rq, settings, "build_msc", (int)MSC_VERSION);
     124           0 :     Script::SetProperty(rq, settings, "build_icc", (int)ICC_VERSION);
     125           0 :     Script::SetProperty(rq, settings, "build_gcc", (int)GCC_VERSION);
     126           0 :     Script::SetProperty(rq, settings, "build_clang", (int)CLANG_VERSION);
     127             : 
     128           0 :     Script::SetProperty(rq, settings, "gfx_card", g_VideoMode.GetBackendDevice()->GetName());
     129           0 :     Script::SetProperty(rq, settings, "gfx_drv_ver", g_VideoMode.GetBackendDevice()->GetDriverInformation());
     130             : #if CONFIG2_AUDIO
     131           0 :     if (g_SoundManager)
     132             :     {
     133           0 :         Script::SetProperty(rq, settings, "snd_card", g_SoundManager->GetSoundCardNames());
     134           0 :         Script::SetProperty(rq, settings, "snd_drv_ver", g_SoundManager->GetOpenALVersion());
     135             :     }
     136             : #endif
     137           0 :     ReportSDL(rq, settings);
     138             : 
     139           0 :     ReportFreeType(rq, settings);
     140             : 
     141           0 :     JS::RootedValue backendDeviceSettings(rq.cx);
     142           0 :     Script::CreateObject(rq, &backendDeviceSettings);
     143             : 
     144           0 :     g_VideoMode.GetBackendDevice()->Report(rq, backendDeviceSettings);
     145           0 :     Script::SetProperty(rq, settings, "renderer_backend", backendDeviceSettings);
     146             : 
     147           0 :     Script::SetProperty(rq, settings, "video_desktop_xres", g_VideoMode.GetDesktopXRes());
     148           0 :     Script::SetProperty(rq, settings, "video_desktop_yres", g_VideoMode.GetDesktopYRes());
     149           0 :     Script::SetProperty(rq, settings, "video_desktop_bpp", g_VideoMode.GetDesktopBPP());
     150           0 :     Script::SetProperty(rq, settings, "video_desktop_freq", g_VideoMode.GetDesktopFreq());
     151             : 
     152             :     struct utsname un;
     153           0 :     uname(&un);
     154           0 :     Script::SetProperty(rq, settings, "uname_sysname", std::string(un.sysname));
     155           0 :     Script::SetProperty(rq, settings, "uname_release", std::string(un.release));
     156           0 :     Script::SetProperty(rq, settings, "uname_version", std::string(un.version));
     157           0 :     Script::SetProperty(rq, settings, "uname_machine", std::string(un.machine));
     158             : 
     159             : #if OS_LINUX
     160             :     {
     161           0 :         std::ifstream ifs("/etc/lsb-release");
     162           0 :         if (ifs.good())
     163             :         {
     164           0 :             std::string str((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
     165           0 :             Script::SetProperty(rq, settings, "linux_release", str);
     166             :         }
     167             :     }
     168             : #endif
     169             : 
     170           0 :     Script::SetProperty(rq, settings, "cpu_identifier", std::string(cpu_IdentifierString()));
     171           0 :     Script::SetProperty(rq, settings, "cpu_frequency", os_cpu_ClockFrequency());
     172           0 :     Script::SetProperty(rq, settings, "cpu_pagesize", (u32)os_cpu_PageSize());
     173           0 :     Script::SetProperty(rq, settings, "cpu_largepagesize", (u32)os_cpu_LargePageSize());
     174           0 :     Script::SetProperty(rq, settings, "cpu_numprocs", (u32)os_cpu_NumProcessors());
     175             : 
     176           0 :     Script::SetProperty(rq, settings, "numa_numnodes", (u32)numa_NumNodes());
     177           0 :     Script::SetProperty(rq, settings, "numa_factor", numa_Factor());
     178           0 :     Script::SetProperty(rq, settings, "numa_interleaved", numa_IsMemoryInterleaved());
     179             : 
     180           0 :     Script::SetProperty(rq, settings, "ram_total", (u32)os_cpu_MemorySize());
     181           0 :     Script::SetProperty(rq, settings, "ram_total_os", (u32)os_cpu_QueryMemorySize());
     182             : 
     183             : #if ARCH_X86_X64
     184           0 :     Script::SetProperty(rq, settings, "x86_vendor", (u32)x86_x64::Vendor());
     185           0 :     Script::SetProperty(rq, settings, "x86_model", (u32)x86_x64::Model());
     186           0 :     Script::SetProperty(rq, settings, "x86_family", (u32)x86_x64::Family());
     187             : 
     188             :     u32 caps0, caps1, caps2, caps3;
     189           0 :     x86_x64::GetCapBits(&caps0, &caps1, &caps2, &caps3);
     190           0 :     Script::SetProperty(rq, settings, "x86_caps[0]", caps0);
     191           0 :     Script::SetProperty(rq, settings, "x86_caps[1]", caps1);
     192           0 :     Script::SetProperty(rq, settings, "x86_caps[2]", caps2);
     193           0 :     Script::SetProperty(rq, settings, "x86_caps[3]", caps3);
     194             : #endif
     195             : 
     196           0 :     Script::SetProperty(rq, settings, "timer_resolution", timer_Resolution());
     197             : 
     198           0 :     Script::SetProperty(rq, settings, "hardware_concurrency", std::thread::hardware_concurrency());
     199             : 
     200             :     // The version should be increased for every meaningful change.
     201           0 :     const int reportVersion = 20;
     202             : 
     203             :     // Send the same data to the reporting system
     204           0 :     g_UserReporter.SubmitReport(
     205             :         "hwdetect",
     206             :         reportVersion,
     207           0 :         Script::StringifyJSON(rq, &settings, false),
     208           0 :         Script::StringifyJSON(rq, &settings, true));
     209             : 
     210             :     // Run the detection script:
     211           0 :     JS::RootedValue global(rq.cx, rq.globalValue());
     212           0 :     ScriptFunction::CallVoid(rq, global, "RunHardwareDetection", settings);
     213             : }
     214             : 
     215           0 : static void ReportSDL(const ScriptRequest& rq, JS::HandleValue settings)
     216             : {
     217             :     SDL_version build, runtime;
     218           0 :     SDL_VERSION(&build);
     219             : 
     220             :     char version[16];
     221           0 :     snprintf(version, ARRAY_SIZE(version), "%d.%d.%d", build.major, build.minor, build.patch);
     222           0 :     Script::SetProperty(rq, settings, "sdl_build_version", version);
     223             : 
     224           0 :     SDL_GetVersion(&runtime);
     225           0 :     snprintf(version, ARRAY_SIZE(version), "%d.%d.%d", runtime.major, runtime.minor, runtime.patch);
     226           0 :     Script::SetProperty(rq, settings, "sdl_runtime_version", version);
     227             : 
     228             :     // This is null in atlas (and further the call triggers an assertion).
     229           0 :     const char* backend = g_VideoMode.GetWindow() ? GetSDLSubsystem(g_VideoMode.GetWindow()) : "none";
     230           0 :     Script::SetProperty(rq, settings, "sdl_video_backend", backend ? backend : "unknown");
     231             : 
     232           0 :     Script::SetProperty(rq, settings, "sdl_display_count", SDL_GetNumVideoDisplays());
     233             : 
     234           0 :     Script::SetProperty(rq, settings, "sdl_cpu_count", SDL_GetCPUCount());
     235           0 :     Script::SetProperty(rq, settings, "sdl_system_ram", SDL_GetSystemRAM());
     236           0 : }
     237             : 
     238           0 : static void ReportFreeType(const ScriptRequest& rq, JS::HandleValue settings)
     239             : {
     240             :     FT_Library FTLibrary;
     241           0 :     std::string FTSupport = "unsupported";
     242           0 :     if (!FT_Init_FreeType(&FTLibrary))
     243             :     {
     244             :         FT_Int major, minor, patch;
     245           0 :         FT_Library_Version(FTLibrary, &major, &minor, &patch);
     246           0 :         FT_Done_FreeType(FTLibrary);
     247           0 :         std::stringstream version;
     248           0 :         version << major << "." << minor << "." << patch;
     249           0 :         FTSupport = version.str();
     250             :     }
     251             :     else
     252             :     {
     253           0 :         FTSupport = "cantload";
     254             :     }
     255           0 :     Script::SetProperty(rq, settings, "freetype", FTSupport);
     256           3 : }
     257             : 

Generated by: LCOV version 1.13