GPU-SD  1.0.2
glx/module.cpp
00001 
00002 /* Copyright (c) 2011, 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 namespace gpusd
00029 {
00030 namespace glx
00031 {
00032 namespace
00033 {
00034 
00035 Module* instance = 0;
00036 
00037 static bool getGPUInfo_( Display* display, GPUInfo& info )
00038 {
00039     if( !display )
00040         return false;
00041 
00042     std::string displayString = DisplayString( display );
00043     const size_t colonPos = displayString.find( ':' );
00044     if( colonPos != std::string::npos )
00045     {
00046         const std::string displayNumber = displayString.substr( colonPos+1 );
00047         info.port = atoi( displayNumber.c_str( ));
00048         info.device = DefaultScreen( display );
00049     }
00050 
00051     info.pvp[0] = 0;
00052     info.pvp[1] = 0;
00053     info.pvp[2] = DisplayWidth(  display, DefaultScreen( display ));
00054     info.pvp[3] = DisplayHeight( display, DefaultScreen( display ));
00055     
00056     return true;
00057 }
00058 
00059 static bool queryDisplay_( const std::string display, GPUInfo& info )
00060 {
00061     ::Display* xDisplay = XOpenDisplay( display.c_str( ));
00062     if( !xDisplay )
00063         return false;
00064 
00065     int major, event, error;
00066     if( !XQueryExtension( xDisplay, "GLX", &major, &event, &error ))
00067     {
00068         XCloseDisplay( xDisplay );
00069         return false;
00070     }
00071 
00072     getGPUInfo_( xDisplay, info );
00073     XCloseDisplay( xDisplay );
00074     return true;
00075 }
00076 
00077 }
00078 
00079 void Module::use()
00080 {
00081     if( !instance )
00082         instance = new Module;
00083 }
00084 
00085 GPUInfos Module::discoverGPUs_() const
00086 {
00087     GPUInfos result;
00088     GPUInfo defaultInfo( "GLX" );
00089 
00090     const char* displayEnv = getenv( "DISPLAY" );
00091     if( displayEnv && displayEnv[0] != '\0' )
00092     {
00093         const std::string display( displayEnv );
00094         if( queryDisplay_( display, defaultInfo ))
00095         {
00096             if( display[0] != ':' && 
00097                 display[0] != '/' /* OS X launchd DISPLAY */ )
00098             {
00099                 defaultInfo.port = GPUInfo::defaultValue;
00100                 defaultInfo.device = GPUInfo::defaultValue;
00101             }
00102             result.push_back( defaultInfo );
00103         }
00104     }
00105 
00106     // try x servers :0 - :n
00107     for( unsigned i = 0; i < std::numeric_limits< unsigned >::max() ; ++i )
00108         // x screens :n.0 - :n.m
00109         for( unsigned j = 0; j < std::numeric_limits< unsigned >::max(); ++j )
00110         {
00111             std::stringstream stream;
00112             stream <<  ':' << i << '.' << j;
00113                 
00114             GPUInfo info( "GLX" );
00115             if( queryDisplay_( stream.str(), info ))
00116             {
00117                 if( info != defaultInfo )
00118                     result.push_back( info );
00119             }
00120             else if( j == 0 ) // X Server does not exist, stop query
00121                 return result;
00122             else // X Screen does not exist, try next server
00123                 break;
00124         }
00125     return result;
00126 }
00127 
00128 }
00129 }
Generated on Tue Dec 13 2011 17:52:00 for GPU-SD 1.0.2 by  doxygen 1.7.5.1