Package VisionEgg :: Module PlatformDependent
[frames] | no frames]

Source Code for Module VisionEgg.PlatformDependent

  1  # The Vision Egg: PlatformDependent 
  2  # 
  3  # Copyright (C) 2001-2003 Andrew Straw. 
  4  # Copyright (C) 2008 California Institute of Technology 
  5  # 
  6  # URL: <http://www.visionegg.org/> 
  7  # 
  8  # Distributed under the terms of the GNU Lesser General Public License 
  9  # (LGPL). See LICENSE.TXT that came with this file. 
 10   
 11  """ 
 12  Implementations of functions which vary by platform. 
 13   
 14  """ 
 15   
 16  #################################################################### 
 17  # 
 18  #        Import all the necessary packages 
 19  # 
 20  #################################################################### 
 21   
 22  import logging 
 23   
 24  import sys, os 
 25  import VisionEgg 
 26  import VisionEgg.Core 
 27   
 28  import VisionEgg.GL as gl # get all OpenGL stuff in one namespace 
 29   
30 -def set_priority(*args,**kw):
31 """Set the priority of the Vision Egg application. 32 33 Defaults to maximum priority, but can be changed via keyword 34 arguments. 35 36 Raises an exception on failure. 37 """ 38 39 # potential keywords 40 parse_me = ["darwin_realtime_period_denom", 41 "darwin_realtime_computation_denom", 42 "darwin_realtime_constraint_denom", 43 "darwin_realtime_preemptible", 44 "darwin_maxpriority_conventional_not_realtime", 45 "darwin_conventional_priority", 46 "darwin_pthread_priority"] 47 48 logger = logging.getLogger('VisionEgg.PlatformDependent') 49 params = {} 50 51 # set variable in local namespace 52 for word in parse_me: 53 # set the value from VisionEgg.config 54 config_name = "VISIONEGG_"+word.upper() 55 if hasattr(VisionEgg.config,config_name): 56 value = getattr(VisionEgg.config,config_name) 57 else: 58 value = None 59 # override default value if present in keyword arguments 60 if word in kw.keys(): 61 value = kw[word] 62 if value is not None: 63 params[word] = value 64 65 if sys.platform == 'darwin': 66 67 # Everything to support realtime in Apple Mac OS X is based on 68 # the following two things: 69 # 70 # 1) http://developer.apple.com/techpubs/macosx/Darwin/General/KernelProgramming/scheduler/Using_Mach__pplications.html 71 # 72 # 2) The Mac OS X port of the Esound daemon. 73 74 import darwin_maxpriority 75 76 if params['darwin_maxpriority_conventional_not_realtime']: 77 process = darwin_maxpriority.PRIO_PROCESS 78 policy = darwin_maxpriority.SCHED_RR 79 80 logger.info("Setting max priority mode for darwin platform " 81 "using conventional priority %d."%( 82 params['darwin_conventional_priority'],)) 83 84 # set the priority of the current process 85 darwin_maxpriority.setpriority(process,0,params['darwin_conventional_priority']) 86 87 # This sets the pthread priority, which only prioritizes 88 # threads in the process. Might as well do it, but it 89 # shouldn't matter unless we're running multi-threaded. 90 darwin_pthread_priority = params['darwin_pthread_priority'] 91 if darwin_pthread_priority == "max": # should otherwise be an int 92 darwin_pthread_priority = darwin_maxpriority.sched_get_priority_max(policy) 93 94 if darwin_maxpriority.set_self_pthread_priority(policy, 95 darwin_pthread_priority) == -1: 96 raise RuntimeError("set_self_pthread failed.") 97 98 else: 99 bus_speed = darwin_maxpriority.get_bus_speed() 100 logger.info("Setting max priority mode for darwin platform " 101 "using realtime threads. ( period = %d / %d, " 102 "computation = %d / %d, constraint = %d / %d, " 103 "preemptible = %d )" % ( 104 bus_speed, params['darwin_realtime_period_denom'], 105 bus_speed, params['darwin_realtime_computation_denom'], 106 bus_speed, params['darwin_realtime_constraint_denom'], 107 params['darwin_realtime_preemptible'] )) 108 period = bus_speed / params['darwin_realtime_period_denom'] 109 computation = bus_speed / params['darwin_realtime_computation_denom'] 110 constraint = bus_speed / params['darwin_realtime_constraint_denom'] 111 preemptible = params['darwin_realtime_preemptible'] 112 113 darwin_maxpriority.set_self_thread_time_constraint_policy( period, computation, constraint, preemptible ) 114 elif sys.platform == 'win32': 115 import win32_maxpriority 116 logger.info("Setting priority for win32 platform to " 117 "HIGH_PRIORITY_CLASS, THREAD_PRIORITY_HIGHEST. " 118 "(This is Microsoft's maximum recommended priority, " 119 "but you could still raise it higher.)") 120 win32_maxpriority.set_self_process_priority_class( 121 win32_maxpriority.HIGH_PRIORITY_CLASS ) 122 win32_maxpriority.set_self_thread_priority( 123 win32_maxpriority.THREAD_PRIORITY_HIGHEST) 124 125 elif sys.platform.startswith('irix') or sys.platform.startswith('linux') or sys.platform.startswith('posix'): 126 import posix_maxpriority 127 policy = posix_maxpriority.SCHED_FIFO 128 max_priority = posix_maxpriority.sched_get_priority_max( policy ) 129 logger.info("Setting priority for POSIX-compatible platform to " 130 "policy SCHED_FIFO and priority to " 131 "%d"%max_priority) 132 posix_maxpriority.set_self_policy_priority( policy, max_priority ) # Fails if you don't have permission (try running as root) 133 posix_maxpriority.stop_memory_paging() 134 else: 135 raise RuntimeError("Cannot change priority. Unknown platform '%s'"%sys.platform)
136
137 -def linux_but_unknown_drivers():
138 """Warn that platform is linux, but drivers not known.""" 139 # If you've added support for other drivers to sync with VBLANK under 140 # linux, please let me know how! 141 logger = logging.getLogger('VisionEgg.PlatformDependent') 142 logger.warning("Could not sync buffer swapping to vblank because " 143 "you are running linux but not known/supported " 144 "drivers (only nVidia and recent Mesa DRI Radeon " 145 "currently supported).")
146
147 -def sync_swap_with_vbl_pre_gl_init():
148 """Try to synchronize buffer swapping and vertical retrace before starting OpenGL.""" 149 success = 0 150 if sys.platform.startswith("linux"): 151 # Unfotunately, cannot check do glGetString(GL_VENDOR) to 152 # check if drivers are nVidia because we have to do that requires 153 # OpenGL context started, but this variable must be set 154 # before OpenGL context started! 155 156 # Assume drivers are nVidia or recent ATI 157 VisionEgg.Core.add_gl_assumption("__SPECIAL__","linux_nvidia_or_new_ATI",linux_but_unknown_drivers) 158 # Set for nVidia linux 159 os.environ["__GL_SYNC_TO_VBLANK"] = "1" 160 # Set for recent linux Mesa DRI Radeon 161 os.environ["LIBGL_SYNC_REFRESH"] = "1" 162 success = 1 163 elif sys.platform.startswith("irix"): 164 # I think this is set using the GLX swap_control SGI 165 # extension. A C extension could be to be written to change 166 # this value. (It probably cannot be set through an OpenGL 167 # extension or an SDL/pygame feature.) 168 logger = logging.getLogger('VisionEgg.PlatformDependent') 169 logger.info("IRIX platform detected, assuming retrace sync.") 170 return success
171
172 -def sync_swap_with_vbl_post_gl_init():
173 """Try to synchronize buffer swapping and vertical retrace after starting OpenGL.""" 174 success = 0 175 try: 176 if sys.platform == "win32": 177 import OpenGL.WGL.EXT.swap_control 178 if OpenGL.WGL.EXT.swap_control.wglInitSwapControlARB(): # Returns 1 if it's working 179 OpenGL.WGL.EXT.swap_control.wglSwapIntervalEXT(1) # Swap only at frame syncs 180 if OpenGL.WGL.EXT.swap_control.wglGetSwapIntervalEXT() == 1: 181 success = 1 182 elif sys.platform == "darwin": 183 try: 184 import _darwin_sync_swap 185 _darwin_sync_swap.sync_swap() 186 success = 1 187 except Exception,x: 188 logger = logging.getLogger('VisionEgg.PlatformDependent') 189 logger.warning("Failed trying to synchronize buffer " 190 "swapping on darwin: %s: %s"%(str(x.__class__),str(x))) 191 except: 192 pass 193 194 return success
195
196 -def query_refresh_rate(screen):
197 if sys.platform == 'win32': 198 import win32_getrefresh 199 return win32_getrefresh.getrefresh() 200 elif sys.platform == 'darwin': 201 import darwin_getrefresh 202 return darwin_getrefresh.getrefresh() 203 else: 204 raise NotImplementedError("Platform dependent code to query frame rate not implemented on this platform.")
205
206 -def attempt_to_load_multitexturing():
207 """Attempt to load multitexturing functions and constants. 208 209 Inserts the results into the gl module, which makes them globally 210 available.""" 211 logger = logging.getLogger('VisionEgg.PlatformDependent') 212 try: 213 import ctypes 214 if sys.platform.startswith('linux'): 215 libGL = ctypes.cdll.LoadLibrary('/usr/lib/libGL.so') 216 elif sys.platform == 'win32': 217 libGL = ctypes.cdll.LoadLibrary('opengl32.dll') 218 else: 219 raise NotImplementedError("ctypes support not added for this platform") 220 221 # make sure libGL has the appropriate functions 222 libGL.glGetString.restype = ctypes.c_char_p 223 vers = libGL.glGetString( ctypes.c_int( gl.GL_VERSION ) ) 224 logger.debug("ctypes loaded OpenGL %s"%vers) 225 226 gl.glActiveTexture = libGL.glActiveTexture 227 gl.glActiveTexture.argtypes = [ctypes.c_int] 228 229 gl.glMultiTexCoord2f = libGL.glMultiTexCoord2f 230 gl.glMultiTexCoord2f.argtypes = [ctypes.c_int, ctypes.c_float, ctypes.c_float] 231 232 # assign constants found by looking at gl.h 233 gl.GL_TEXTURE0 = 0x84C0 234 gl.GL_TEXTURE1 = 0x84C1 235 236 logger.debug("ctypes loaded OpenGL library and multitexture names " 237 "are present. Workaround appears successful. ") 238 except Exception, x: 239 logger.debug("ctypes loading of OpenGL library failed %s: " 240 "%s"%(x.__class__, str(x))) 241 242 if VisionEgg.Core.init_gl_extension('ARB','multitexture'): 243 # copy from extenstion 244 gl.glActiveTexture = gl.glActiveTextureARB 245 gl.glMultiTexCoord2f = gl.glMultiTexCoord2fARB 246 gl.GL_TEXTURE0 = gl.GL_TEXTURE0_ARB 247 gl.GL_TEXTURE1 = gl.GL_TEXTURE1_ARB 248 logger.debug("loaded multitexturing ARB extension") 249 else: 250 logger.warning("multitexturing not available after trying " 251 "ctypes and the OpenGL ARB extension. Some " 252 "features will not be available")
253