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 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382
|
# -*- coding: utf-8 -*-
# Copyright (c) Vispy Development Team. All Rights Reserved.
# Distributed under the (new) BSD License. See LICENSE.txt for more info.
""" A ctypes-based API to EGL.
"""
import os
import ctypes
from ctypes import c_int as _c_int, POINTER as _POINTER, c_void_p, c_char_p
_egl_file = None
if 'EGL_LIBRARY' in os.environ:
if os.path.exists(os.environ['EGL_LIBRARY']):
_egl_file = os.path.realpath(os.environ['EGL_LIBRARY'])
# Else, try to find it
if _egl_file is None:
_egl_file = ctypes.util.find_library('EGL')
# Else, we failed and exit
if _egl_file is None:
raise OSError('EGL library not found')
# Load it
_lib = ctypes.CDLL(_egl_file)
## Constants
EGL_FALSE = 0
EGL_TRUE = 1
# Out-of-band handle values
EGL_DEFAULT_DISPLAY = 0
EGL_NO_CONTEXT = 0
EGL_NO_DISPLAY = 0
EGL_NO_SURFACE = 0
# Out-of-band attribute value
EGL_DONT_CARE = -1
# Errors / GetError return values
EGL_SUCCESS = 0x3000
EGL_NOT_INITIALIZED = 0x3001
EGL_BAD_ACCESS = 0x3002
EGL_BAD_ALLOC = 0x3003
EGL_BAD_ATTRIBUTE = 0x3004
EGL_BAD_CONFIG = 0x3005
EGL_BAD_CONTEXT = 0x3006
EGL_BAD_CURRENT_SURFACE = 0x3007
EGL_BAD_DISPLAY = 0x3008
EGL_BAD_MATCH = 0x3009
EGL_BAD_NATIVE_PIXMAP = 0x300A
EGL_BAD_NATIVE_WINDOW = 0x300B
EGL_BAD_PARAMETER = 0x300C
EGL_BAD_SURFACE = 0x300D
EGL_CONTEXT_LOST = 0x300E # EGL 1.1 - IMG_power_management
# Reserved 0x300F-0x301F for additional errors
# Config attributes
EGL_BUFFER_SIZE = 0x3020
EGL_ALPHA_SIZE = 0x3021
EGL_BLUE_SIZE = 0x3022
EGL_GREEN_SIZE = 0x3023
EGL_RED_SIZE = 0x3024
EGL_DEPTH_SIZE = 0x3025
EGL_STENCIL_SIZE = 0x3026
EGL_CONFIG_CAVEAT = 0x3027
EGL_CONFIG_ID = 0x3028
EGL_LEVEL = 0x3029
EGL_MAX_PBUFFER_HEIGHT = 0x302A
EGL_MAX_PBUFFER_PIXELS = 0x302B
EGL_MAX_PBUFFER_WIDTH = 0x302C
EGL_NATIVE_RENDERABLE = 0x302D
EGL_NATIVE_VISUAL_ID = 0x302E
EGL_NATIVE_VISUAL_TYPE = 0x302F
EGL_SAMPLES = 0x3031
EGL_SAMPLE_BUFFERS = 0x3032
EGL_SURFACE_TYPE = 0x3033
EGL_TRANSPARENT_TYPE = 0x3034
EGL_TRANSPARENT_BLUE_VALUE = 0x3035
EGL_TRANSPARENT_GREEN_VALUE = 0x3036
EGL_TRANSPARENT_RED_VALUE = 0x3037
EGL_NONE = 0x3038 # Attrib list terminator
EGL_BIND_TO_TEXTURE_RGB = 0x3039
EGL_BIND_TO_TEXTURE_RGBA = 0x303A
EGL_MIN_SWAP_INTERVAL = 0x303B
EGL_MAX_SWAP_INTERVAL = 0x303C
EGL_LUMINANCE_SIZE = 0x303D
EGL_ALPHA_MASK_SIZE = 0x303E
EGL_COLOR_BUFFER_TYPE = 0x303F
EGL_RENDERABLE_TYPE = 0x3040
EGL_MATCH_NATIVE_PIXMAP = 0x3041 # Pseudo-attribute (not queryable)
EGL_CONFORMANT = 0x3042
# Reserved 0x3041-0x304F for additional config attributes
# Config attribute values
EGL_SLOW_CONFIG = 0x3050 # EGL_CONFIG_CAVEAT value
EGL_NON_CONFORMANT_CONFIG = 0x3051 # EGL_CONFIG_CAVEAT value
EGL_TRANSPARENT_RGB = 0x3052 # EGL_TRANSPARENT_TYPE value
EGL_RGB_BUFFER = 0x308E # EGL_COLOR_BUFFER_TYPE value
EGL_LUMINANCE_BUFFER = 0x308F # EGL_COLOR_BUFFER_TYPE value
# More config attribute values, for EGL_TEXTURE_FORMAT
EGL_NO_TEXTURE = 0x305C
EGL_TEXTURE_RGB = 0x305D
EGL_TEXTURE_RGBA = 0x305E
EGL_TEXTURE_2D = 0x305F
# Config attribute mask bits
EGL_PBUFFER_BIT = 0x0001 # EGL_SURFACE_TYPE mask bits
EGL_PIXMAP_BIT = 0x0002 # EGL_SURFACE_TYPE mask bits
EGL_WINDOW_BIT = 0x0004 # EGL_SURFACE_TYPE mask bits
EGL_VG_COLORSPACE_LINEAR_BIT = 0x0020 # EGL_SURFACE_TYPE mask bits
EGL_VG_ALPHA_FORMAT_PRE_BIT = 0x0040 # EGL_SURFACE_TYPE mask bits
EGL_MULTISAMPLE_RESOLVE_BOX_BIT = 0x0200 # EGL_SURFACE_TYPE mask bits
EGL_SWAP_BEHAVIOR_PRESERVED_BIT = 0x0400 # EGL_SURFACE_TYPE mask bits
EGL_OPENGL_ES_BIT = 0x0001 # EGL_RENDERABLE_TYPE mask bits
EGL_OPENVG_BIT = 0x0002 # EGL_RENDERABLE_TYPE mask bits
EGL_OPENGL_ES2_BIT = 0x0004 # EGL_RENDERABLE_TYPE mask bits
EGL_OPENGL_BIT = 0x0008 # EGL_RENDERABLE_TYPE mask bits
# QueryString targets
EGL_VENDOR = 0x3053
EGL_VERSION = 0x3054
EGL_EXTENSIONS = 0x3055
EGL_CLIENT_APIS = 0x308D
# QuerySurface / SurfaceAttrib / CreatePbufferSurface targets
EGL_HEIGHT = 0x3056
EGL_WIDTH = 0x3057
EGL_LARGEST_PBUFFER = 0x3058
EGL_TEXTURE_FORMAT = 0x3080
EGL_TEXTURE_TARGET = 0x3081
EGL_MIPMAP_TEXTURE = 0x3082
EGL_MIPMAP_LEVEL = 0x3083
EGL_RENDER_BUFFER = 0x3086
EGL_VG_COLORSPACE = 0x3087
EGL_VG_ALPHA_FORMAT = 0x3088
EGL_HORIZONTAL_RESOLUTION = 0x3090
EGL_VERTICAL_RESOLUTION = 0x3091
EGL_PIXEL_ASPECT_RATIO = 0x3092
EGL_SWAP_BEHAVIOR = 0x3093
EGL_MULTISAMPLE_RESOLVE = 0x3099
# EGL_RENDER_BUFFER values / BindTexImage / ReleaseTexImage buffer targets
EGL_BACK_BUFFER = 0x3084
EGL_SINGLE_BUFFER = 0x3085
# OpenVG color spaces
EGL_VG_COLORSPACE_sRGB = 0x3089 # EGL_VG_COLORSPACE value
EGL_VG_COLORSPACE_LINEAR = 0x308A # EGL_VG_COLORSPACE value
# OpenVG alpha formats
EGL_VG_ALPHA_FORMAT_NONPRE = 0x308B # EGL_ALPHA_FORMAT value
EGL_VG_ALPHA_FORMAT_PRE = 0x308C # EGL_ALPHA_FORMAT value
# Constant scale factor by which fractional display resolutions &
# * aspect ratio are scaled when queried as integer values.
EGL_DISPLAY_SCALING = 10000
# Unknown display resolution/aspect ratio
EGL_UNKNOWN = -1
# Back buffer swap behaviors
EGL_BUFFER_PRESERVED = 0x3094 # EGL_SWAP_BEHAVIOR value
EGL_BUFFER_DESTROYED = 0x3095 # EGL_SWAP_BEHAVIOR value
# CreatePbufferFromClientBuffer buffer types
EGL_OPENVG_IMAGE = 0x3096
# QueryContext targets
EGL_CONTEXT_CLIENT_TYPE = 0x3097
# CreateContext attributes
EGL_CONTEXT_CLIENT_VERSION = 0x3098
# Multisample resolution behaviors
EGL_MULTISAMPLE_RESOLVE_DEFAULT = 0x309A # EGL_MULTISAMPLE_RESOLVE value
EGL_MULTISAMPLE_RESOLVE_BOX = 0x309B # EGL_MULTISAMPLE_RESOLVE value
# BindAPI/QueryAPI targets
EGL_OPENGL_ES_API = 0x30A0
EGL_OPENVG_API = 0x30A1
EGL_OPENGL_API = 0x30A2
# GetCurrentSurface targets
EGL_DRAW = 0x3059
EGL_READ = 0x305A
# WaitNative engines
EGL_CORE_NATIVE_ENGINE = 0x305B
# EGL 1.2 tokens renamed for consistency in EGL 1.3
EGL_COLORSPACE = EGL_VG_COLORSPACE
EGL_ALPHA_FORMAT = EGL_VG_ALPHA_FORMAT
EGL_COLORSPACE_sRGB = EGL_VG_COLORSPACE_sRGB
EGL_COLORSPACE_LINEAR = EGL_VG_COLORSPACE_LINEAR
EGL_ALPHA_FORMAT_NONPRE = EGL_VG_ALPHA_FORMAT_NONPRE
EGL_ALPHA_FORMAT_PRE = EGL_VG_ALPHA_FORMAT_PRE
## The functions
_lib.eglGetDisplay.argtypes = _c_int,
_lib.eglGetDisplay.restype = c_void_p
_lib.eglInitialize.argtypes = c_void_p, _POINTER(_c_int), _POINTER(_c_int)
_lib.eglTerminate.argtypes = c_void_p,
_lib.eglChooseConfig.argtypes = (c_void_p, _POINTER(_c_int),
_POINTER(c_void_p), _c_int, _POINTER(_c_int))
_lib.eglCreateWindowSurface.argtypes = (c_void_p, c_void_p,
c_void_p, _POINTER(_c_int))
_lib.eglCreateWindowSurface.restype = c_void_p
_lib.eglCreatePbufferSurface.argtypes = (c_void_p, c_void_p, _POINTER(_c_int))
_lib.eglCreatePbufferSurface.restype = c_void_p
_lib.eglCreateContext.argtypes = c_void_p, c_void_p, c_void_p, _POINTER(_c_int)
_lib.eglCreateContext.restype = c_void_p
_lib.eglMakeCurrent.argtypes = (c_void_p,) * 4
_lib.eglBindAPI.argtypes = _c_int,
_lib.eglSwapBuffers.argtypes = (c_void_p,) * 2
_lib.eglDestroySurface.argtypes = (c_void_p,) * 2
_lib.eglQueryString.argtypes = (c_void_p, _c_int)
_lib.eglQueryString.restype = c_char_p
def eglGetError():
""" Check for errors, returns an enum (int).
"""
return _lib.eglGetError()
def eglGetDisplay(display=EGL_DEFAULT_DISPLAY):
""" Connect to the EGL display server.
"""
res = _lib.eglGetDisplay(display)
if not res or res == EGL_NO_DISPLAY:
raise RuntimeError('Could not create display')
return c_void_p(res)
def eglInitialize(display):
""" Initialize EGL and return EGL version tuple.
"""
majorVersion = (_c_int*1)()
minorVersion = (_c_int*1)()
res = _lib.eglInitialize(display, majorVersion, minorVersion)
if res == EGL_FALSE:
raise RuntimeError('Could not initialize')
return majorVersion[0], minorVersion[0]
def eglTerminate(display):
""" Initialize EGL and return EGL version tuple.
"""
_lib.eglTerminate(display)
def eglQueryString(display, name):
""" Query string from display
"""
out = _lib.eglQueryString(display, name)
if not out:
raise RuntimeError('Could not query %s' % name)
return out
DEFAULT_ATTRIB_LIST = (EGL_RED_SIZE, 8, EGL_BLUE_SIZE, 8,
EGL_GREEN_SIZE, 8, EGL_ALPHA_SIZE, 8,
EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE,
EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER,
EGL_CONFORMANT, EGL_OPENGL_ES2_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_NATIVE_RENDERABLE, EGL_TRUE,
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT)
def _convert_attrib_list(attribList):
attribList = attribList or []
attribList = [a for a in attribList] + [EGL_NONE]
attribList = (_c_int*len(attribList))(*attribList)
return attribList
def eglChooseConfig(display, attribList=DEFAULT_ATTRIB_LIST):
attribList = _convert_attrib_list(attribList)
numConfigs = (_c_int*1)()
_lib.eglChooseConfig(display, attribList, None, 0, numConfigs)
n = numConfigs[0]
if n <= 0:
raise RuntimeError('Could not find any suitable config.')
config = (c_void_p*n)()
_lib.eglChooseConfig(display, attribList, config, n, numConfigs)
return config
def _check_res(res):
if res == EGL_NO_SURFACE:
e = eglGetError()
else:
return res
if e == EGL_BAD_MATCH:
raise ValueError('Cannot create surface: attributes do not match ' +
'or given config cannot render in window.')
elif e == EGL_BAD_CONFIG:
raise ValueError('Cannot create surface: given config is not ' +
'supported by this system.')
elif e == EGL_BAD_NATIVE_WINDOW:
raise ValueError('Cannot create surface: the given native window ' +
'handle is invalid.')
elif e == EGL_BAD_ALLOC:
raise RuntimeError('Could not allocate surface: not enough ' +
'resources or native window already associated ' +
'with another config.')
else:
raise RuntimeError('Could not create window surface due to ' +
'unknown error: %i' % e)
def eglCreateWindowSurface(display, config, window, attribList=None):
# Deal with attrib list
attribList = _convert_attrib_list(attribList)
surface = c_void_p(_lib.eglCreateWindowSurface(display, config, window, attribList))
return _check_res(surface)
def eglCreatePbufferSurface(display, config, attribList=None):
# Deal with attrib list
attribList = _convert_attrib_list(attribList)
#
surface = c_void_p(_lib.eglCreatePbufferSurface(display, config, attribList))
return _check_res(surface)
def eglCreateContext(display, config, shareContext=EGL_NO_CONTEXT,
attribList=None):
# Deal with attrib list
attribList = attribList or [EGL_CONTEXT_CLIENT_VERSION, 2]
attribList = [a for a in attribList] + [EGL_NONE]
attribList = (_c_int*len(attribList))(*attribList)
#
res = c_void_p(_lib.eglCreateContext(display, config, shareContext, attribList))
if res == EGL_NO_CONTEXT:
e = eglGetError()
if e == EGL_BAD_CONFIG:
raise ValueError('Could not create context: given config is ' +
'not supported by this system.')
else:
raise RuntimeError('Could not create context due to ' +
'unknown error: %i' % e)
return res
def eglMakeCurrent(display, draw, read, context):
res = _lib.eglMakeCurrent(display, draw, read, context)
if res == EGL_FALSE:
raise RuntimeError('Could not make the context current.')
def eglBindAPI(api):
""" Set the current rendering API (OpenGL, OpenGL ES or OpenVG)
"""
res = _lib.eglBindAPI(api)
if res == EGL_FALSE:
raise RuntimeError('Could not bind API %d' % api)
return res
def eglSwapBuffers(display, surface):
res = _lib.eglSwapBuffers(display, surface)
if res == EGL_FALSE:
raise RuntimeError('Could not swap buffers.')
def eglDestroySurface(display, surface):
res = _lib.eglDestroySurface(display, surface)
if res == EGL_FALSE:
raise RuntimeError('Could not destroy surface')
|