GPU-SD  1.1.2
glx/module.cpp
00001 
00002 /* Copyright (c) 2011-2012, Stefan Eilemann <eile@eyescale.ch> 
00003  *
00004  * This library is free software; you can redistribute it and/or modify it under
00005  * the terms of the GNU Lesser General Public License version 2.1 as published
00006  * by the Free Software Foundation.
00007  *  
00008  * This library is distributed in the hope that it will be useful, but WITHOUT
00009  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00010  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00011  * details.
00012  * 
00013  * You should have received a copy of the GNU Lesser General Public License
00014  * along with this library; if not, write to the Free Software Foundation, Inc.,
00015  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00016  */
00017 
00018 #include "module.h"
00019 
00020 #include <gpusd/gpuInfo.h>
00021 
00022 #include <X11/Xlib.h>
00023 #include <GL/glx.h>
00024 #include <cstdlib>
00025 #include <limits>
00026 #include <sstream>
00027 
00028 #define TRY_PORTS 10
00029 
00030 namespace gpusd
00031 {
00032 namespace glx
00033 {
00034 namespace
00035 {
00036 
00037 Module* instance = 0;
00038 
00039 static bool getGPUInfo_( Display* display, GPUInfo& info )
00040 {
00041     int major, event, error;
00042     if( !display || !XQueryExtension( display, "GLX", &major, &event, &error ))
00043         return false;
00044 
00045     std::string displayString = DisplayString( display );
00046     const size_t colonPos = displayString.find( ':' );
00047     if( colonPos != std::string::npos )
00048     {
00049         const std::string displayNumber = displayString.substr( colonPos+1 );
00050         info.port = atoi( displayNumber.c_str( ));
00051         info.device = DefaultScreen( display );
00052     }
00053 
00054     info.pvp[0] = 0;
00055     info.pvp[1] = 0;
00056     info.pvp[2] = DisplayWidth(  display, DefaultScreen( display ));
00057     info.pvp[3] = DisplayHeight( display, DefaultScreen( display ));
00058     
00059     const char* vendor = glXGetClientString( display, GLX_VENDOR );
00060     if( vendor && std::string( vendor ) == "VirtualGL" )
00061     {
00062         info.flags |= GPUInfo::FLAG_VIRTUALGL;
00063         const char* vglDisplay = getenv( "VGL_DISPLAY" );
00064         const std::string vglDisplayStr( vglDisplay ? vglDisplay : ":0.0" );
00065         std::stringstream xDisplay;
00066 
00067         xDisplay << DisplayString( display );
00068         if( xDisplay.str() == ":0" )
00069             xDisplay << "." << DefaultScreen( display );
00070 
00071         if( vglDisplayStr == xDisplay.str( ))
00072             info.flags |= GPUInfo::FLAG_VIRTUALGL_DISPLAY;
00073     }
00074 
00075     return true;
00076 }
00077 
00078 static bool queryDisplay_( const std::string display, GPUInfo& info )
00079 {
00080     ::Display* xDisplay = XOpenDisplay( display.c_str( ));
00081     if( !xDisplay )
00082         return false;
00083 
00084     int major, event, error;
00085     if( !XQueryExtension( xDisplay, "GLX", &major, &event, &error ))
00086     {
00087         XCloseDisplay( xDisplay );
00088         return false;
00089     }
00090 
00091     getGPUInfo_( xDisplay, info );
00092     XCloseDisplay( xDisplay );
00093     return true;
00094 }
00095 
00096 }
00097 
00098 void Module::use()
00099 {
00100     if( !instance )
00101         instance = new Module;
00102 }
00103 
00104 GPUInfos Module::discoverGPUs_() const
00105 {
00106     GPUInfos result;
00107     GPUInfo defaultInfo( "GLX" );
00108 
00109     const char* displayEnv = getenv( "DISPLAY" );
00110     if( displayEnv && displayEnv[0] != '\0' )
00111     {
00112         const std::string display( displayEnv );
00113         if( queryDisplay_( display, defaultInfo ))
00114         {
00115             if( display[0] != ':' && display[0] != '/' /* OS X launchd */ )
00116             {
00117                 defaultInfo.port = GPUInfo::defaultValue;
00118                 defaultInfo.device = GPUInfo::defaultValue;
00119             }
00120             result.push_back( defaultInfo );
00121         }
00122     }
00123 
00124     // try x servers :0 - :n
00125     for( unsigned i = 0; i < std::numeric_limits< unsigned >::max() ; ++i )
00126         // x screens :n.0 - :n.m
00127         for( unsigned j = 0; j < std::numeric_limits< unsigned >::max(); ++j )
00128         {
00129             std::stringstream stream;
00130             stream <<  ':' << i << '.' << j;
00131                 
00132             GPUInfo info( "GLX" );
00133             if( queryDisplay_( stream.str(), info ))
00134             {
00135                 if( info != defaultInfo )
00136                     result.push_back( info );
00137             }
00138             else if( j == 0 && i >= TRY_PORTS )
00139                 // X Server does not exist, stop query
00140                 return result;
00141             else // X Screen does not exist, try next server
00142                 break;
00143         }
00144     return result;
00145 }
00146 
00147 }
00148 }
Generated on Thu Jun 14 2012 07:53:07 for GPU-SD 1.1.2 by  doxygen 1.8.0