public static function __pre_run_process()
 {
     self::$error_count = 0;
     self::$error_pointer = 0;
     self::$error_analysis = array();
     // Store the video resolution
     // Access the xrandr resolution directly to ensure it's not polling the FB size or one of the KMS modes
     self::$start_video_resolution = phodevi_gpu::gpu_xrandr_resolution();
     if (phodevi::is_linux() && phodevi::is_ati_graphics()) {
         $vsync_val = phodevi_linux_parser::read_amd_pcsdb('AMDPCSROOT/SYSTEM/BUSID-*/OpenGL,VSyncControl');
         // Check for vSync
         if ($vsync_val == '0x00000002' || $vsync_val == '0x00000003') {
             self::$driver_forced_vsync = true;
         }
         //$catalyst_ai_val = phodevi_linux_parser::read_amd_pcsdb('AMDPCSROOT/SYSTEM/BUSID-*/OpenGL,CatalystAI'); // Check for Catalyst AI
         //if($catalyst_ai_val == '0x00000001' || $catalyst_ai_val == '0x00000002')
         //	echo '\nCatalyst AI is enabled, which will use driver-specific optimizations in some tests that may offer extra performance enhancements.\n';
     } else {
         if (phodevi::is_nvidia_graphics()) {
             self::$error_pointer = self::nvidia_gpu_error_count();
             // Set the error pointer
             if (phodevi_parser::read_nvidia_extension('SyncToVBlank') == '1') {
                 shell_exec('nvidia-settings -a SyncToVBlank=0 2>&1');
                 self::$driver_forced_vsync = true;
             }
         }
     }
     if (self::$driver_forced_vsync == true) {
         //	echo '\nYour video driver is forcing vertical sync to be enabled. This will limit the system's frame-rate performance potential in any graphical tests!\n';
     }
     // vblank_mode=0 has long been set within pts-core, but put it here too just since there's these other checks here
     putenv('vblank_mode=0');
 }
 public static function sw_display_driver($with_version = true)
 {
     if (phodevi::is_windows()) {
         return null;
     }
     $display_driver = phodevi::read_property('system', 'dri-display-driver');
     if (empty($display_driver)) {
         if (phodevi::is_ati_graphics() && phodevi::is_linux()) {
             $display_driver = 'fglrx';
         } else {
             if (phodevi::is_nvidia_graphics() || is_file('/proc/driver/nvidia/version')) {
                 $display_driver = 'nvidia';
             } else {
                 if ((phodevi::is_mesa_graphics() || phodevi::is_bsd()) && stripos(phodevi::read_property('gpu', 'model'), 'NVIDIA') !== false) {
                     if (is_file('/sys/class/drm/version')) {
                         // If there's DRM loaded and NVIDIA, it should be Nouveau
                         $display_driver = 'nouveau';
                     } else {
                         // The dead xf86-video-nv doesn't use any DRM
                         $display_driver = 'nv';
                     }
                 } else {
                     // Fallback to hopefully detect the module, takes the first word off the GPU string and sees if it is the module
                     // This works in at least the case of the Cirrus driver
                     $display_driver = strtolower(pts_strings::first_in_string(phodevi::read_property('gpu', 'model')));
                 }
             }
         }
     }
     if (!empty($display_driver)) {
         $driver_version = phodevi_parser::read_xorg_module_version($display_driver . '_drv');
         if ($driver_version == false || $driver_version == '1.0.0') {
             switch ($display_driver) {
                 case 'amd':
                     // See if it's radeon driver
                     $driver_version = phodevi_parser::read_xorg_module_version('radeon_drv');
                     if ($driver_version != false) {
                         $display_driver = 'radeon';
                     }
                     break;
                 case 'vmwgfx':
                     // See if it's VMware driver
                     $driver_version = phodevi_parser::read_xorg_module_version('vmware_drv');
                     if ($driver_version != false) {
                         $display_driver = 'vmware';
                     }
                     break;
                 case 'radeon':
                     // RadeonHD driver also reports DRI driver as 'radeon', so try reading that instead
                     $driver_version = phodevi_parser::read_xorg_module_version('radeonhd_drv');
                     if ($driver_version != false) {
                         $display_driver = 'radeonhd';
                     }
                     break;
                 case 'nvidia':
                 case 'NVIDIA':
                 case 'nouveau':
                     // NVIDIA's binary driver usually ends up reporting 1.0.0
                     if ($nvs_value = phodevi_parser::read_nvidia_extension('NvidiaDriverVersion')) {
                         $display_driver = 'NVIDIA';
                         $driver_version = $nvs_value;
                     } else {
                         // NVIDIA's binary driver appends their driver version on the end of the OpenGL version string
                         $glxinfo = phodevi_parser::software_glxinfo_version();
                         if (($pos = strpos($glxinfo, 'NVIDIA ')) != false) {
                             $display_driver = 'NVIDIA';
                             $driver_version = substr($glxinfo, $pos + 7);
                         }
                     }
                     break;
                 default:
                     if (is_readable('/sys/class/graphics/fb0/name')) {
                         // This path works for at least finding NVIDIA Tegra 2 DDX (via tegra_fb)
                         $display_driver = file_get_contents('/sys/class/graphics/fb0/name');
                         $display_driver = str_replace(array('drm', '_fb'), null, $display_driver);
                         $driver_version = phodevi_parser::read_xorg_module_version($display_driver . '_drv');
                     }
                     break;
             }
         }
         if ($driver_version == false) {
             // If the version is empty, chances are the DDX driver string is incorrect
             $display_driver = null;
             // See if the VESA or fbdev driver is in use
             foreach (array('modesetting', 'fbdev', 'vesa') as $drv) {
                 $drv_version = phodevi_parser::read_xorg_module_version($drv . '_drv');
                 if ($drv_version) {
                     $display_driver = $drv;
                     $driver_version = $drv_version;
                     break;
                 }
             }
         }
         if (!empty($driver_version) && $with_version && $driver_version != '0.0.0') {
             $display_driver .= ' ' . $driver_version;
             // XXX: The below check is disabled since the Catalyst Version no longer seems reliably reported (circa Catalyst 13.x)
             if (false && phodevi::is_ati_graphics() && strpos($display_driver, 'fglrx') !== false) {
                 $catalyst_version = phodevi_linux_parser::read_amd_pcsdb('AMDPCSROOT/SYSTEM/LDC,Catalyst_Version');
                 if ($catalyst_version != null && $catalyst_version > 10.1 && $catalyst_version != 10.5 && $catalyst_version != 11.8) {
                     // This option was introduced around Catalyst 10.5 but seems to not be updated properly until Catalyst 10.11/10.12
                     $display_driver .= ' Catalyst ' . $catalyst_version . '';
                 }
             }
         }
     }
     return $display_driver;
 }
 public static function gpu_model()
 {
     // Report graphics processor string
     $info = phodevi_parser::read_glx_renderer();
     $video_ram = phodevi::read_property('gpu', 'memory-capacity');
     if (phodevi::is_ati_graphics() && phodevi::is_linux()) {
         $crossfire_status = phodevi_linux_parser::read_amd_pcsdb('SYSTEM/Crossfire/chain/*,Enable');
         $crossfire_status = pts_arrays::to_array($crossfire_status);
         $crossfire_card_count = 0;
         for ($i = 0; $i < count($crossfire_status); $i++) {
             if ($crossfire_status[$i] == '0x00000001') {
                 $crossfire_card_count += 2;
                 // For now assume each chain is 2 cards, but proper way would be NumSlaves + 1
             }
         }
         $adapters = phodevi_linux_parser::read_amd_graphics_adapters();
         if (count($adapters) > 0) {
             $video_ram = $video_ram > 64 ? ' ' . $video_ram . 'MB' : null;
             // assume more than 64MB of vRAM
             if ($crossfire_card_count > 1 && $crossfire_card_count <= count($adapters)) {
                 $unique_adapters = array_unique($adapters);
                 if (count($unique_adapters) == 1) {
                     if (strpos($adapters[0], 'X2') > 0 && $crossfire_card_count > 1) {
                         $crossfire_card_count -= 1;
                     }
                     $info = $crossfire_card_count . ' x ' . $adapters[0] . $video_ram . ' CrossFire';
                 } else {
                     $info = implode(', ', $unique_adapters) . ' CrossFire';
                 }
             } else {
                 $info = $adapters[0] . $video_ram;
             }
         }
     } else {
         if (phodevi::is_macosx()) {
             $system_profiler_info = implode(' + ', phodevi_osx_parser::read_osx_system_profiler('SPDisplaysDataType', 'ChipsetModel', true));
             if (!empty($system_profiler_info)) {
                 $info = $system_profiler_info;
             }
         } else {
             if (phodevi::is_nvidia_graphics()) {
                 if ($info == null) {
                     if (pts_client::executable_in_path('nvidia-settings')) {
                         $nv_gpus = shell_exec('nvidia-settings -q gpus 2>&1');
                         // TODO: search for more than one GPU
                         $nv_gpus = substr($nv_gpus, strpos($nv_gpus, '[0]'));
                         $nv_gpus = substr($nv_gpus, strpos($nv_gpus, '(') + 1);
                         $nv_gpus = substr($nv_gpus, 0, strpos($nv_gpus, ')'));
                         if (stripos($nv_gpus, 'GeForce') !== false || stripos($nv_gpus, 'Quadro') !== false) {
                             $info = $nv_gpus;
                         }
                     }
                 }
                 $sli_mode = phodevi_parser::read_nvidia_extension('SLIMode');
                 if (!empty($sli_mode) && $sli_mode != 'Off') {
                     $info .= ' SLI';
                 }
             } else {
                 if (phodevi::is_solaris()) {
                     if (($cut = strpos($info, 'DRI ')) !== false) {
                         $info = substr($info, $cut + 4);
                     }
                     if (($cut = strpos($info, ' Chipset')) !== false) {
                         $info = substr($info, 0, $cut);
                     }
                     if ($info == false && isset(phodevi::$vfs->xorg_log)) {
                         $xorg_log = phodevi::$vfs->xorg_log;
                         if (($x = strpos($xorg_log, '(0): Chipset: ')) !== false) {
                             $xorg_log = substr($xorg_log, $x + 14);
                             $xorg_log = str_replace(array('(R)', '"'), null, substr($xorg_log, 0, strpos($xorg_log, PHP_EOL)));
                             if (($c = strpos($xorg_log, '[')) || ($c = strpos($xorg_log, '('))) {
                                 $xorg_log = substr($xorg_log, 0, $c);
                             }
                             if (phodevi::is_product_string($xorg_log)) {
                                 $info = $xorg_log;
                             }
                         }
                     }
                 } else {
                     if (phodevi::is_bsd()) {
                         $drm_info = phodevi_bsd_parser::read_sysctl('dev.drm.0.%desc');
                         if (!$drm_info) {
                             $drm_info = phodevi_bsd_parser::read_sysctl('dev.nvidia.0.%desc');
                         }
                         if (!$drm_info) {
                             $agp_info = phodevi_bsd_parser::read_sysctl('dev.agp.0.%desc');
                             if ($agp_info != false) {
                                 $info = $agp_info;
                             }
                         } else {
                             $info = $drm_info;
                         }
                         if ($info == null && isset(phodevi::$vfs->xorg_log)) {
                             $xorg_log = phodevi::$vfs->xorg_log;
                             if (($e = strpos($xorg_log, ' at 01@00:00:0')) !== false) {
                                 $xorg_log = substr($xorg_log, 0, $e);
                                 $info = substr($xorg_log, strrpos($xorg_log, 'Found ') + 6);
                             }
                         }
                     } else {
                         if (phodevi::is_windows()) {
                             $info = phodevi_windows_parser::read_cpuz('Display Adapters', 'Name');
                         }
                     }
                 }
             }
         }
     }
     if (empty($info) || strpos($info, 'Mesa ') !== false || strpos($info, 'Gallium ') !== false) {
         if (phodevi::is_windows() == false) {
             $info_pci = phodevi_linux_parser::read_pci('VGA compatible controller', false);
             if (!empty($info_pci)) {
                 $info = $info_pci;
                 if (strpos($info, 'Intel 2nd Generation Core Family') !== false || strpos($info, 'Gen Core') !== false) {
                     // Try to come up with a better non-generic string
                     $was_reset = false;
                     if (isset(phodevi::$vfs->xorg_log)) {
                         /*
                         $ cat /var/log/Xorg.0.log | grep -i Chipset
                         [     8.421] (II) intel: Driver for Intel Integrated Graphics Chipsets: i810,
                         [     8.421] (II) VESA: driver for VESA chipsets: vesa
                         [     8.423] (II) intel(0): Integrated Graphics Chipset: Intel(R) Sandybridge Mobile (GT2+)
                         [     8.423] (--) intel(0): Chipset: "Sandybridge Mobile (GT2+)"
                         */
                         $xorg_log = phodevi::$vfs->xorg_log;
                         if (($x = strpos($xorg_log, 'Integrated Graphics Chipset: ')) !== false) {
                             $xorg_log = substr($xorg_log, $x + 29);
                             $xorg_log = str_replace(array('(R)', '"'), null, substr($xorg_log, 0, strpos($xorg_log, PHP_EOL)));
                             if (stripos($xorg_log, 'Intel') === false) {
                                 $xorg_log = 'Intel ' . $xorg_log;
                             }
                             // if string is too long, likely not product
                             if (!isset($xorg_log[45])) {
                                 $info = $xorg_log;
                                 $was_reset = true;
                             }
                         } else {
                             if (($x = strpos($xorg_log, '(0): Chipset: ')) !== false) {
                                 $xorg_log = substr($xorg_log, $x + 14);
                                 $xorg_log = str_replace(array('(R)', '"'), null, substr($xorg_log, 0, strpos($xorg_log, PHP_EOL)));
                                 if (stripos($xorg_log, 'Intel') === false) {
                                     $xorg_log = 'Intel ' . $xorg_log;
                                 }
                                 // if string is too long, likely not product
                                 if (!isset($xorg_log[45])) {
                                     $info = $xorg_log;
                                     $was_reset = true;
                                 }
                             }
                         }
                     }
                     if ($was_reset == false && isset(phodevi::$vfs->i915_capabilities)) {
                         $i915_caps = phodevi::$vfs->i915_capabilities;
                         if (($x = strpos($i915_caps, 'gen: ')) !== false) {
                             $gen = substr($i915_caps, $x + 5);
                             $gen = substr($gen, 0, strpos($gen, PHP_EOL));
                             if (is_numeric($gen)) {
                                 $info = 'Intel Gen' . $gen;
                                 if (strpos($i915_caps, 'is_mobile: yes') !== false) {
                                     $info .= ' Mobile';
                                 }
                             }
                         }
                     }
                 }
             }
         }
         if (($start_pos = strpos($info, ' DRI ')) > 0) {
             $info = substr($info, $start_pos + 5);
         }
         if (empty($info) && isset(phodevi::$vfs->xorg_log)) {
             $log_parse = phodevi::$vfs->xorg_log;
             $log_parse = substr($log_parse, strpos($log_parse, 'Chipset') + 8);
             $log_parse = substr($log_parse, 0, strpos($log_parse, 'found'));
             if (strpos($log_parse, '(--)') === false && strlen(str_ireplace(array('ATI', 'NVIDIA', 'VIA', 'Intel'), '', $log_parse)) != strlen($log_parse)) {
                 $info = $log_parse;
             }
         }
         if (empty($info) && is_readable('/sys/class/graphics/fb0/name')) {
             switch (pts_file_io::file_get_contents('/sys/class/graphics/fb0/name')) {
                 case 'omapdrm':
                     $info = 'Texas Instruments OMAP';
                     // The OMAP DRM driver currently is for OMAP2/3/4 hardware
                     break;
                 case 'exynos':
                     $info = 'Samsung EXYNOS';
                     // The Exynos DRM driver
                     break;
                 case 'tegra_fb':
                     $info = 'NVIDIA TEGRA';
                     // The Exynos DRM driver
                     break;
                 default:
                     if (is_file('/dev/mali')) {
                         $info = 'ARM Mali';
                         // One of the ARM Mali models
                     }
                     break;
             }
         }
         if (substr($info, -1) == ')' && ($open_p = strrpos($info, '(')) != false) {
             $end_check = strpos($info, ' ', $open_p);
             $to_check = substr($info, $open_p + 1, $end_check - $open_p - 1);
             // Don't report card revision from PCI info
             if ($to_check == 'rev') {
                 $info = substr($info, 0, $open_p - 1);
             }
         }
     }
     if (($bracket_open = strpos($info, '[')) !== false) {
         // Report only the information inside the brackets if it's more relevant...
         // Mainly with Linux systems where the PCI information is reported like 'nVidia GF104 [GeForce GTX 460]'
         if (($bracket_close = strpos($info, ']', $bracket_open + 1)) !== false) {
             $inside_bracket = substr($info, $bracket_open + 1, $bracket_close - $bracket_open - 1);
             if (stripos($inside_bracket, 'Quadro') !== false || stripos($inside_bracket, 'GeForce') !== false) {
                 $info = $inside_bracket . ' ' . substr($info, $bracket_close + 1);
             } else {
                 if (stripos($inside_bracket, 'Radeon') !== false || stripos($inside_bracket, 'Fire') !== false || stripos($inside_bracket, 'Fusion') !== false) {
                     $info = $inside_bracket . ' ' . substr($info, $bracket_close + 1);
                 }
             }
         }
     }
     if (stripos($info, 'NVIDIA') === false && (stripos($info, 'Quadro') !== false || stripos($info, 'GeForce') !== false)) {
         $info = 'NVIDIA' . ' ' . $info;
     } else {
         if (stripos($info, 'ATI') === false && stripos($info, 'AMD') === false && (stripos($info, 'Radeon') !== false || stripos($info, 'Fire') !== false || stripos($info, 'Fusion') !== false)) {
             // Fire would be for FireGL or FirePro hardware
             $info = 'AMD ' . $info;
         }
     }
     if (phodevi::is_linux() && ($vendor = phodevi_linux_parser::read_pci_subsystem_value('VGA compatible controller')) != null && stripos($info, $vendor) === false && (stripos($info, 'AMD') !== false || stripos($info, 'NVIDIA') !== false)) {
         $info = $vendor . ' ' . $info;
     }
     if ($video_ram > 64 && strpos($info, $video_ram) == false) {
         $info .= ' ' . $video_ram . 'MB';
     }
     $clean_phrases = array('OpenGL Engine');
     $info = str_replace($clean_phrases, null, $info);
     return $info;
 }
 public static function monitor_layout()
 {
     // Determine layout for multiple monitors
     $monitor_layout = array('CENTER');
     if (phodevi::read_property('monitor', 'count') > 1) {
         $xdpy_monitors = phodevi_parser::read_xdpy_monitor_info();
         $hit_0_0 = false;
         for ($i = 0; $i < count($xdpy_monitors); $i++) {
             $monitor_position = explode('@', $xdpy_monitors[$i]);
             $monitor_position = trim($monitor_position[1]);
             $monitor_position_x = substr($monitor_position, 0, strpos($monitor_position, ','));
             $monitor_position_y = substr($monitor_position, strpos($monitor_position, ',') + 1);
             if ($monitor_position == '0,0') {
                 $hit_0_0 = true;
             } else {
                 if ($monitor_position_x > 0 && $monitor_position_y == 0) {
                     array_push($monitor_layout, $hit_0_0 ? 'RIGHT' : 'LEFT');
                 } else {
                     if ($monitor_position_x == 0 && $monitor_position_y > 0) {
                         array_push($monitor_layout, $hit_0_0 ? 'LOWER' : 'UPPER');
                     }
                 }
             }
         }
         if (count($monitor_layout) == 1) {
             // Something went wrong with xdpy information, go to fallback support
             if (phodevi::is_ati_graphics() && phodevi::is_linux()) {
                 $amdpcsdb_monitor_layout = phodevi_linux_parser::read_amd_pcsdb('SYSTEM/BUSID-*/DDX,DesktopSetup');
                 $amdpcsdb_monitor_layout = pts_arrays::to_array($amdpcsdb_monitor_layout);
                 foreach ($amdpcsdb_monitor_layout as $card_monitor_configuration) {
                     switch ($card_monitor_configuration) {
                         case 'horizontal':
                             array_push($monitor_layout, 'RIGHT');
                             break;
                         case 'horizontal,reverse':
                             array_push($monitor_layout, 'LEFT');
                             break;
                         case 'vertical':
                             array_push($monitor_layout, 'ABOVE');
                             break;
                         case 'vertical,reverse':
                             array_push($monitor_layout, 'BELOW');
                             break;
                     }
                 }
             }
         }
     }
     return implode(',', $monitor_layout);
 }
 public static function __pre_run_process()
 {
     if (!(phodevi::is_nvidia_graphics() || phodevi::is_ati_graphics() && phodevi::is_linux())) {
         echo "\nNo supported driver found for graphics_override module!\n";
         return pts_module::MODULE_UNLOAD;
         // Not using a supported driver, quit the module
     }
     $force_aa = pts_module::read_variable("FORCE_AA");
     $force_af = pts_module::read_variable("FORCE_AF");
     if ($force_aa !== FALSE && in_array($force_aa, self::$supported_aa_levels)) {
         // First backup any existing override, then set the new value
         if (phodevi::is_nvidia_graphics()) {
             self::$preset_aa = phodevi_parser::read_nvidia_extension("FSAA");
             self::$preset_aa_control = phodevi_parser::read_nvidia_extension("FSAAAppControlled");
             switch ($force_aa) {
                 case 2:
                     $nvidia_aa = 2;
                     break;
                 case 4:
                     $nvidia_aa = 5;
                     break;
                 case 8:
                     $nvidia_aa = 7;
                     break;
                 case 16:
                     $nvidia_aa = 8;
                     break;
             }
             if (isset($nvidia_aa)) {
                 self::set_nvidia_extension("FSAA", $nvidia_aa);
                 self::set_nvidia_extension("FSAAAppControlled", 0);
             }
         } else {
             if (phodevi::is_ati_graphics()) {
                 self::$preset_aa = phodevi_linux_parser::read_amd_pcsdb("OpenGL,AntiAliasSamples");
                 self::$preset_aa_control = phodevi_linux_parser::read_amd_pcsdb("OpenGL,AAF");
                 switch ($force_aa) {
                     case 2:
                         $ati_aa = "0x00000002";
                         break;
                     case 4:
                         $ati_aa = "0x00000004";
                         break;
                     case 8:
                         $ati_aa = "0x00000008";
                         break;
                     case 16:
                         echo "\nThe ATI fglrx driver currently does not support 16x AA! Defaulting to 8x AA!\n";
                         $ati_aa = "0x00000008";
                         break;
                 }
                 if (isset($ati_aa)) {
                     self::set_amd_pcsdb("OpenGL,AntiAliasSamples", $ati_aa);
                     self::set_amd_pcsdb("OpenGL,AAF", "0x00000000");
                 }
             }
         }
     }
     if ($force_af !== FALSE && in_array($force_af, self::$supported_af_levels)) {
         // First backup any existing override, then set the new value
         if (phodevi::is_nvidia_graphics()) {
             self::$preset_af = phodevi_parser::read_nvidia_extension("LogAniso");
             self::$preset_af_control = phodevi_parser::read_nvidia_extension("LogAnisoAppControlled");
             switch ($force_af) {
                 case 2:
                     $nvidia_af = 1;
                     break;
                 case 4:
                     $nvidia_af = 2;
                     break;
                 case 8:
                     $nvidia_af = 3;
                     break;
                 case 16:
                     $nvidia_af = 4;
                     break;
             }
             if (isset($nvidia_af)) {
                 self::set_nvidia_extension("LogAniso", $nvidia_af);
                 self::set_nvidia_extension("LogAnisoAppControlled", 0);
             }
         } else {
             if (phodevi::is_ati_graphics()) {
                 self::$preset_af = phodevi_linux_parser::read_amd_pcsdb("OpenGL,AnisoDegree");
                 switch ($force_af) {
                     case 2:
                         $ati_af = "0x00000002";
                         break;
                     case 4:
                         $ati_af = "0x00000004";
                         break;
                     case 8:
                         $ati_af = "0x00000008";
                         break;
                     case 16:
                         $ati_af = "0x00000010";
                         break;
                 }
                 if (isset($ati_af)) {
                     self::set_amd_pcsdb("OpenGL,AnisoDegree", $ati_af);
                 }
             }
         }
     }
 }