pyrender
pyrender copied to clipboard
re-create pyrender.OffscreenRenderer exception
I am running in a docker container based on nvidia/cudagl:11.4.2-runtime-ubuntu20.04 with python 3.8.10 and pyrender (0.1.45) installed (via pip). If I copy this example into a file (adding os.environ['PYOPENGL_PLATFORM'] = 'egl'
to the beginning of the file), and then try to recreate the renderer and render again:
# ...
r = pyrender.OffscreenRenderer(400, 400)
color, depth = r.render(scene)
I get the following exception when I run the file:
Traceback (most recent call last):
File "testing.py", line 27, in <module>
color, depth = r.render(scene)
File "/venv/lib/python3.8/site-packages/pyrender/offscreen.py", line 86, in render
self._platform.make_current()
File "/venv/lib/python3.8/site-packages/pyrender/platforms/egl.py", line 196, in make_current
assert eglMakeCurrent(
File "/venv/lib/python3.8/site-packages/OpenGL/error.py", line 228, in glCheckError
raise GLError(
OpenGL.error.GLError: GLError(
err = 12296,
baseOperation = eglMakeCurrent,
cArguments = (
<OpenGL._opaque.EGLDisplay_pointer object at 0x7fbfa0c60ac0>,
<OpenGL._opaque.EGLSurface_pointer object at 0x7fbfa10d2c40>,
<OpenGL._opaque.EGLSurface_pointer object at 0x7fbfa10d2c40>,
<OpenGL._opaque.EGLContext_pointer object at 0x7fbfa0c60dc0>,
),
result = 0
)
I have found that if I set the offscreen renderer r
to None
before re-creating it I can run without problem.
# ...
r = None
r = pyrender.OffscreenRenderer(400, 400)
color, depth = r.render(scene)
This suggests to me that something is not being reference counted correctly because re-creating the renderer, r
, should drop the reference count to the renderer object to 0 and destruct it just like when we set r
to None
explicitly.
I guess the reference count of r
does not go to 0 until after the new OffscreenRenderer is constructed. So if only one OffscreenRenderer can be constructed at at time, then the behavior makes sense. Is that correct?
@scott-vsi Something more pythonic should be context-manager:
with pyrender.OffscreenRenderer(400, 400) as r:
color, depth = r.render(scene)
It could be implemented within the source code or just use:
from contextlib import contextmanager
@contextmanager
def manager(obj):
try:
yield obj
finally:
obj.delete()
with manager(pyrender.OffscreenRenderer(400, 400)) as r:
color, depth = r.render(scene)
Yes. This is a great suggestion.
I had missed this, but the need to destruct r
is mentioned in the documentation at the end of this section: https://pyrender.readthedocs.io/en/latest/examples/offscreen.html#running-the-renderer
Calling r.delete() could trigger the same GLError 12289. In my case the r.render(scene) was called on many different scenes for many times, then I called r.delete() and triggered this error.