Team Ai
Apppublic

OpenMotionLab/MotionGPT

sourceHugging Facemitupdated 1y agoView on Hugging Face
118likes
egl.py220 linesDownload Raw Back to platforms
1import ctypes2import os3 4import OpenGL.platform5 6from .base import Platform7 8EGL_PLATFORM_DEVICE_EXT = 0x313F9EGL_DRM_DEVICE_FILE_EXT = 0x323310 11 12def _ensure_egl_loaded():13    plugin = OpenGL.platform.PlatformPlugin.by_name('egl')14    if plugin is None:15        raise RuntimeError("EGL platform plugin is not available.")16 17    plugin_class = plugin.load()18    plugin.loaded = True19    # create instance of this platform implementation20    plugin = plugin_class()21 22    plugin.install(vars(OpenGL.platform))23 24 25_ensure_egl_loaded()26from OpenGL import EGL as egl27 28 29def _get_egl_func(func_name, res_type, *arg_types):30    address = egl.eglGetProcAddress(func_name)31    if address is None:32        return None33 34    proto = ctypes.CFUNCTYPE(res_type)35    proto.argtypes = arg_types36    func = proto(address)37    return func38 39 40def _get_egl_struct(struct_name):41    from OpenGL._opaque import opaque_pointer_cls42    return opaque_pointer_cls(struct_name)43 44 45# These are not defined in PyOpenGL by default.46_EGLDeviceEXT = _get_egl_struct('EGLDeviceEXT')47_eglGetPlatformDisplayEXT = _get_egl_func('eglGetPlatformDisplayEXT', egl.EGLDisplay)48_eglQueryDevicesEXT = _get_egl_func('eglQueryDevicesEXT', egl.EGLBoolean)49_eglQueryDeviceStringEXT = _get_egl_func('eglQueryDeviceStringEXT', ctypes.c_char_p)50 51 52def query_devices():53    if _eglQueryDevicesEXT is None:54        raise RuntimeError("EGL query extension is not loaded or is not supported.")55 56    num_devices = egl.EGLint()57    success = _eglQueryDevicesEXT(0, None, ctypes.pointer(num_devices))58    if not success or num_devices.value < 1:59        return []60 61    devices = (_EGLDeviceEXT * num_devices.value)()  # array of size num_devices62    success = _eglQueryDevicesEXT(num_devices.value, devices, ctypes.pointer(num_devices))63    if not success or num_devices.value < 1:64        return []65 66    return [EGLDevice(devices[i]) for i in range(num_devices.value)]67 68 69def get_default_device():70    # Fall back to not using query extension.71    if _eglQueryDevicesEXT is None:72        return EGLDevice(None)73 74    return query_devices()[0]75 76 77def get_device_by_index(device_id):78    if _eglQueryDevicesEXT is None and device_id == 0:79        return get_default_device()80 81    devices = query_devices()82    if device_id >= len(devices):83        raise ValueError('Invalid device ID ({})'.format(device_id, len(devices)))84    return devices[device_id]85 86 87class EGLDevice:88 89    def __init__(self, display=None):90        self._display = display91 92    def get_display(self):93        if self._display is None:94            return egl.eglGetDisplay(egl.EGL_DEFAULT_DISPLAY)95 96        return _eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT, self._display, None)97 98    @property99    def name(self):100        if self._display is None:101            return 'default'102 103        name = _eglQueryDeviceStringEXT(self._display, EGL_DRM_DEVICE_FILE_EXT)104        if name is None:105            return None106 107        return name.decode('ascii')108 109    def __repr__(self):110        return "<EGLDevice(name={})>".format(self.name)111 112 113class EGLPlatform(Platform):114    """Renders using EGL.115    """116 117    def __init__(self, viewport_width, viewport_height, device: EGLDevice = None):118        super(EGLPlatform, self).__init__(viewport_width, viewport_height)119        if device is None:120            device = get_default_device()121 122        self._egl_device = device123        self._egl_display = None124        self._egl_context = None125 126    def init_context(self):127        _ensure_egl_loaded()128 129        from OpenGL.EGL import (130            EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, EGL_BLUE_SIZE,131            EGL_RED_SIZE, EGL_GREEN_SIZE, EGL_DEPTH_SIZE,132            EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER,133            EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, EGL_CONFORMANT,134            EGL_NONE, EGL_DEFAULT_DISPLAY, EGL_NO_CONTEXT,135            EGL_OPENGL_API, EGL_CONTEXT_MAJOR_VERSION,136            EGL_CONTEXT_MINOR_VERSION,137            EGL_CONTEXT_OPENGL_PROFILE_MASK,138            EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,139            eglGetDisplay, eglInitialize, eglChooseConfig,140            eglBindAPI, eglCreateContext, EGLConfig141        )142        from OpenGL import arrays143 144        config_attributes = arrays.GLintArray.asArray([145            EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,146            EGL_BLUE_SIZE, 8,147            EGL_RED_SIZE, 8,148            EGL_GREEN_SIZE, 8,149            EGL_DEPTH_SIZE, 24,150            EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER,151            EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,152            EGL_CONFORMANT, EGL_OPENGL_BIT,153            EGL_NONE154        ])155        context_attributes = arrays.GLintArray.asArray([156            EGL_CONTEXT_MAJOR_VERSION, 4,157            EGL_CONTEXT_MINOR_VERSION, 1,158            EGL_CONTEXT_OPENGL_PROFILE_MASK,159            EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,160            EGL_NONE161        ])162        major, minor = ctypes.c_long(), ctypes.c_long()163        num_configs = ctypes.c_long()164        configs = (EGLConfig * 1)()165 166        # Cache DISPLAY if necessary and get an off-screen EGL display167        orig_dpy = None168        if 'DISPLAY' in os.environ:169            orig_dpy = os.environ['DISPLAY']170            del os.environ['DISPLAY']171 172        self._egl_display = self._egl_device.get_display()173        if orig_dpy is not None:174            os.environ['DISPLAY'] = orig_dpy175 176        # Initialize EGL177        assert eglInitialize(self._egl_display, major, minor)178        assert eglChooseConfig(179            self._egl_display, config_attributes, configs, 1, num_configs180        )181 182        # Bind EGL to the OpenGL API183        assert eglBindAPI(EGL_OPENGL_API)184 185        # Create an EGL context186        self._egl_context = eglCreateContext(187            self._egl_display, configs[0],188            EGL_NO_CONTEXT, context_attributes189        )190 191        # Make it current192        self.make_current()193 194    def make_current(self):195        from OpenGL.EGL import eglMakeCurrent, EGL_NO_SURFACE196        assert eglMakeCurrent(197            self._egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,198            self._egl_context199        )200 201    def make_uncurrent(self):202        """Make the OpenGL context uncurrent.203        """204        pass205 206    def delete_context(self):207        from OpenGL.EGL import eglDestroyContext, eglTerminate208        if self._egl_display is not None:209            if self._egl_context is not None:210                eglDestroyContext(self._egl_display, self._egl_context)211                self._egl_context = None212            eglTerminate(self._egl_display)213            self._egl_display = None214 215    def supports_framebuffers(self):216        return True217 218 219__all__ = ['EGLPlatform']220