Suprhimp commited on
Commit
a23ea39
1 Parent(s): 7e9e319
Files changed (3) hide show
  1. lib/glcontext.py +142 -0
  2. opengl.py +2 -1
  3. requirements.txt +1 -2
lib/glcontext.py ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Headless GPU-accelerated OpenGL context creation on Google Colaboratory.
2
+
3
+ Typical usage:
4
+
5
+ # Optional PyOpenGL configuratiopn can be done here.
6
+ # import OpenGL
7
+ # OpenGL.ERROR_CHECKING = True
8
+
9
+ # 'glcontext' must be imported before any OpenGL.* API.
10
+ from lucid.misc.gl.glcontext import create_opengl_context
11
+
12
+ # Now it's safe to import OpenGL and EGL functions
13
+ import OpenGL.GL as gl
14
+
15
+ # create_opengl_context() creates a GL context that is attached to an
16
+ # offscreen surface of the specified size. Note that rendering to buffers
17
+ # of other sizes and formats is still possible with OpenGL Framebuffers.
18
+ #
19
+ # Users are expected to directly use the EGL API in case more advanced
20
+ # context management is required.
21
+ width, height = 640, 480
22
+ create_opengl_context((width, height))
23
+
24
+ # OpenGL context is available here.
25
+
26
+ """
27
+
28
+ from __future__ import print_function
29
+
30
+ # pylint: disable=unused-import,g-import-not-at-top,g-statement-before-imports
31
+
32
+ try:
33
+ import OpenGL
34
+ except:
35
+ print('This module depends on PyOpenGL.')
36
+ print('Please run "\033[1m!pip install -q pyopengl\033[0m" '
37
+ 'prior importing this module.')
38
+ raise
39
+
40
+ import ctypes
41
+ from ctypes import pointer, util
42
+ import os
43
+
44
+ os.environ['PYOPENGL_PLATFORM'] = 'egl'
45
+
46
+ # OpenGL loading workaround.
47
+ #
48
+ # * PyOpenGL tries to load libGL, but we need libOpenGL, see [1,2].
49
+ # This could have been solved by a symlink libGL->libOpenGL, but:
50
+ #
51
+ # * Python 2.7 can't find libGL and linEGL due to a bug (see [3])
52
+ # in ctypes.util, that was only wixed in Python 3.6.
53
+ #
54
+ # So, the only solution I've found is to monkeypatch ctypes.util
55
+ # [1] https://devblogs.nvidia.com/egl-eye-opengl-visualization-without-x-server/
56
+ # [2] https://devblogs.nvidia.com/linking-opengl-server-side-rendering/
57
+ # [3] https://bugs.python.org/issue9998
58
+ _find_library_old = ctypes.util.find_library
59
+ try:
60
+
61
+ def _find_library_new(name):
62
+ return {
63
+ 'GL': 'libOpenGL.so',
64
+ 'EGL': 'libEGL.so',
65
+ }.get(name, _find_library_old(name))
66
+ util.find_library = _find_library_new
67
+ import OpenGL.GL as gl
68
+ import OpenGL.EGL as egl
69
+ from OpenGL import error
70
+ from OpenGL.EGL.EXT.device_base import egl_get_devices
71
+ from OpenGL.raw.EGL.EXT.platform_device import EGL_PLATFORM_DEVICE_EXT
72
+ except:
73
+ print('Unable to load OpenGL libraries. '
74
+ 'Make sure you use GPU-enabled backend.')
75
+ print('Press "Runtime->Change runtime type" and set '
76
+ '"Hardware accelerator" to GPU.')
77
+ raise
78
+ finally:
79
+ util.find_library = _find_library_old
80
+
81
+ def create_initialized_headless_egl_display():
82
+ """Creates an initialized EGL display directly on a device."""
83
+ for device in egl_get_devices():
84
+ display = egl.eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT, device, None)
85
+
86
+ if display != egl.EGL_NO_DISPLAY and egl.eglGetError() == egl.EGL_SUCCESS:
87
+ # `eglInitialize` may or may not raise an exception on failure depending
88
+ # on how PyOpenGL is configured. We therefore catch a `GLError` and also
89
+ # manually check the output of `eglGetError()` here.
90
+ try:
91
+ initialized = egl.eglInitialize(display, None, None)
92
+ except error.GLError:
93
+ pass
94
+ else:
95
+ if initialized == egl.EGL_TRUE and egl.eglGetError() == egl.EGL_SUCCESS:
96
+ return display
97
+ return egl.EGL_NO_DISPLAY
98
+
99
+ def create_opengl_context(surface_size=(640, 480)):
100
+ """Create offscreen OpenGL context and make it current.
101
+
102
+ Users are expected to directly use EGL API in case more advanced
103
+ context management is required.
104
+
105
+ Args:
106
+ surface_size: (width, height), size of the offscreen rendering surface.
107
+ """
108
+ egl_display = create_initialized_headless_egl_display()
109
+ if egl_display == egl.EGL_NO_DISPLAY:
110
+ raise ImportError('Cannot initialize a headless EGL display.')
111
+
112
+ major, minor = egl.EGLint(), egl.EGLint()
113
+ egl.eglInitialize(egl_display, pointer(major), pointer(minor))
114
+
115
+ config_attribs = [
116
+ egl.EGL_SURFACE_TYPE, egl.EGL_PBUFFER_BIT, egl.EGL_BLUE_SIZE, 8,
117
+ egl.EGL_GREEN_SIZE, 8, egl.EGL_RED_SIZE, 8, egl.EGL_DEPTH_SIZE, 24,
118
+ egl.EGL_RENDERABLE_TYPE, egl.EGL_OPENGL_BIT, egl.EGL_NONE
119
+ ]
120
+ config_attribs = (egl.EGLint * len(config_attribs))(*config_attribs)
121
+
122
+ num_configs = egl.EGLint()
123
+ egl_cfg = egl.EGLConfig()
124
+ egl.eglChooseConfig(egl_display, config_attribs, pointer(egl_cfg), 1,
125
+ pointer(num_configs))
126
+
127
+ width, height = surface_size
128
+ pbuffer_attribs = [
129
+ egl.EGL_WIDTH,
130
+ width,
131
+ egl.EGL_HEIGHT,
132
+ height,
133
+ egl.EGL_NONE,
134
+ ]
135
+ pbuffer_attribs = (egl.EGLint * len(pbuffer_attribs))(*pbuffer_attribs)
136
+ egl_surf = egl.eglCreatePbufferSurface(egl_display, egl_cfg, pbuffer_attribs)
137
+
138
+ egl.eglBindAPI(egl.EGL_OPENGL_API)
139
+
140
+ egl_context = egl.eglCreateContext(egl_display, egl_cfg, egl.EGL_NO_CONTEXT,
141
+ None)
142
+ egl.eglMakeCurrent(egl_display, egl_surf, egl_surf, egl_context)
opengl.py CHANGED
@@ -15,7 +15,8 @@
15
  import OpenGL
16
  import ctypes
17
  import ctypes.util
18
- from lucid.misc.gl.glcontext import create_opengl_context
 
19
 
20
  from OpenGL.GL import *
21
  import OpenGL.GL.shaders
 
15
  import OpenGL
16
  import ctypes
17
  import ctypes.util
18
+ # from lucid.misc.gl.glcontext import create_opengl_context
19
+ from lib.glcontext import create_opengl_context
20
 
21
  from OpenGL.GL import *
22
  import OpenGL.GL.shaders
requirements.txt CHANGED
@@ -5,5 +5,4 @@ uvicorn
5
  pydantic
6
  glfw
7
  PyOpenGL==3.1.5
8
- boto3
9
- lucid==0.2.3
 
5
  pydantic
6
  glfw
7
  PyOpenGL==3.1.5
8
+ boto3