pyrender icon indicating copy to clipboard operation
pyrender copied to clipboard

re-create pyrender.OffscreenRenderer exception

Open scott-vsi opened this issue 2 years ago • 5 comments

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.

scott-vsi avatar Apr 26 '22 16:04 scott-vsi

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 avatar Apr 26 '22 19:04 scott-vsi

@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)

eyllanesc avatar May 01 '22 00:05 eyllanesc

Yes. This is a great suggestion.

scott-vsi avatar May 01 '22 11:05 scott-vsi

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

scott-vsi avatar May 05 '22 02:05 scott-vsi

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.

chaihahaha avatar Nov 07 '22 12:11 chaihahaha