Spaces:
Sleeping
Sleeping
File size: 6,615 Bytes
b4c8bc3 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
import ctypes
import os
import OpenGL.platform
from .base import Platform
EGL_PLATFORM_DEVICE_EXT = 0x313F
EGL_DRM_DEVICE_FILE_EXT = 0x3233
def _ensure_egl_loaded():
plugin = OpenGL.platform.PlatformPlugin.by_name('egl')
if plugin is None:
raise RuntimeError("EGL platform plugin is not available.")
plugin_class = plugin.load()
plugin.loaded = True
# create instance of this platform implementation
plugin = plugin_class()
plugin.install(vars(OpenGL.platform))
_ensure_egl_loaded()
from OpenGL import EGL as egl
def _get_egl_func(func_name, res_type, *arg_types):
address = egl.eglGetProcAddress(func_name)
if address is None:
return None
proto = ctypes.CFUNCTYPE(res_type)
proto.argtypes = arg_types
func = proto(address)
return func
def _get_egl_struct(struct_name):
from OpenGL._opaque import opaque_pointer_cls
return opaque_pointer_cls(struct_name)
# These are not defined in PyOpenGL by default.
_EGLDeviceEXT = _get_egl_struct('EGLDeviceEXT')
_eglGetPlatformDisplayEXT = _get_egl_func('eglGetPlatformDisplayEXT', egl.EGLDisplay)
_eglQueryDevicesEXT = _get_egl_func('eglQueryDevicesEXT', egl.EGLBoolean)
_eglQueryDeviceStringEXT = _get_egl_func('eglQueryDeviceStringEXT', ctypes.c_char_p)
def query_devices():
if _eglQueryDevicesEXT is None:
raise RuntimeError("EGL query extension is not loaded or is not supported.")
num_devices = egl.EGLint()
success = _eglQueryDevicesEXT(0, None, ctypes.pointer(num_devices))
if not success or num_devices.value < 1:
return []
devices = (_EGLDeviceEXT * num_devices.value)() # array of size num_devices
success = _eglQueryDevicesEXT(num_devices.value, devices, ctypes.pointer(num_devices))
if not success or num_devices.value < 1:
return []
return [EGLDevice(devices[i]) for i in range(num_devices.value)]
def get_default_device():
# Fall back to not using query extension.
if _eglQueryDevicesEXT is None:
return EGLDevice(None)
return query_devices()[0]
def get_device_by_index(device_id):
if _eglQueryDevicesEXT is None and device_id == 0:
return get_default_device()
devices = query_devices()
if device_id >= len(devices):
raise ValueError('Invalid device ID ({})'.format(device_id, len(devices)))
return devices[device_id]
class EGLDevice:
def __init__(self, display=None):
self._display = display
def get_display(self):
if self._display is None:
return egl.eglGetDisplay(egl.EGL_DEFAULT_DISPLAY)
return _eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT, self._display, None)
@property
def name(self):
if self._display is None:
return 'default'
name = _eglQueryDeviceStringEXT(self._display, EGL_DRM_DEVICE_FILE_EXT)
if name is None:
return None
return name.decode('ascii')
def __repr__(self):
return "<EGLDevice(name={})>".format(self.name)
class EGLPlatform(Platform):
"""Renders using EGL.
"""
def __init__(self, viewport_width, viewport_height, device: EGLDevice = None):
super(EGLPlatform, self).__init__(viewport_width, viewport_height)
if device is None:
device = get_default_device()
self._egl_device = device
self._egl_display = None
self._egl_context = None
def init_context(self):
_ensure_egl_loaded()
from OpenGL.EGL import (
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, EGL_BLUE_SIZE,
EGL_RED_SIZE, EGL_GREEN_SIZE, EGL_DEPTH_SIZE,
EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER,
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, EGL_CONFORMANT,
EGL_NONE, EGL_DEFAULT_DISPLAY, EGL_NO_CONTEXT,
EGL_OPENGL_API, EGL_CONTEXT_MAJOR_VERSION,
EGL_CONTEXT_MINOR_VERSION,
EGL_CONTEXT_OPENGL_PROFILE_MASK,
EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
eglGetDisplay, eglInitialize, eglChooseConfig,
eglBindAPI, eglCreateContext, EGLConfig
)
from OpenGL import arrays
config_attributes = arrays.GLintArray.asArray([
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
EGL_BLUE_SIZE, 8,
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_DEPTH_SIZE, 24,
EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER,
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
EGL_CONFORMANT, EGL_OPENGL_BIT,
EGL_NONE
])
context_attributes = arrays.GLintArray.asArray([
EGL_CONTEXT_MAJOR_VERSION, 4,
EGL_CONTEXT_MINOR_VERSION, 1,
EGL_CONTEXT_OPENGL_PROFILE_MASK,
EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
EGL_NONE
])
major, minor = ctypes.c_long(), ctypes.c_long()
num_configs = ctypes.c_long()
configs = (EGLConfig * 1)()
# Cache DISPLAY if necessary and get an off-screen EGL display
orig_dpy = None
if 'DISPLAY' in os.environ:
orig_dpy = os.environ['DISPLAY']
del os.environ['DISPLAY']
self._egl_display = self._egl_device.get_display()
if orig_dpy is not None:
os.environ['DISPLAY'] = orig_dpy
# Initialize EGL
assert eglInitialize(self._egl_display, major, minor)
assert eglChooseConfig(
self._egl_display, config_attributes, configs, 1, num_configs
)
# Bind EGL to the OpenGL API
assert eglBindAPI(EGL_OPENGL_API)
# Create an EGL context
self._egl_context = eglCreateContext(
self._egl_display, configs[0],
EGL_NO_CONTEXT, context_attributes
)
# Make it current
self.make_current()
def make_current(self):
from OpenGL.EGL import eglMakeCurrent, EGL_NO_SURFACE
assert eglMakeCurrent(
self._egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
self._egl_context
)
def make_uncurrent(self):
"""Make the OpenGL context uncurrent.
"""
pass
def delete_context(self):
from OpenGL.EGL import eglDestroyContext, eglTerminate
if self._egl_display is not None:
if self._egl_context is not None:
eglDestroyContext(self._egl_display, self._egl_context)
self._egl_context = None
eglTerminate(self._egl_display)
self._egl_display = None
def supports_framebuffers(self):
return True
__all__ = ['EGLPlatform']
|