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