File: egl.py

package info (click to toggle)
python-vispy 0.6.6-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 21,240 kB
  • sloc: python: 57,407; javascript: 6,810; makefile: 63; sh: 5
file content (382 lines) | stat: -rw-r--r-- 12,208 bytes parent folder | download | duplicates (2)
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')