Skip to content

Commit 4f77cbf

Browse files
committed
fix(egl): fail fast when rendering is requested without egl
1 parent e2b57f0 commit 4f77cbf

3 files changed

Lines changed: 36 additions & 3 deletions

File tree

python/rcs/camera/sim.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from rcs._core.sim import SimCameraConfig
1212
from rcs._core.sim import SimCameraSet as _SimCameraSet
1313
from rcs.camera.interface import BaseCameraSet, CameraFrame, DataFrame, Frame, FrameSet
14+
from rcs.sim import egl_bootstrap
1415

1516
from rcs import sim
1617

@@ -31,6 +32,7 @@ def __init__(
3132
self.cameras = cameras
3233
self.physical_units = physical_units
3334

35+
egl_bootstrap.require("simulation camera rendering")
3436
super().__init__(simulation, cameras, render_on_demand=render_on_demand)
3537
self._sim: sim.Sim
3638

python/rcs/sim/egl_bootstrap.py

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,15 @@
1010
import os
1111

1212
_egl_available = False
13+
_egl_error = None
1314
_addr_make_current = None
1415
_egl_display = None
1516
_egl_context = None
1617

1718
name = ctypes.util.find_library("EGL")
18-
if name is not None:
19+
if name is None:
20+
_egl_error = "Could not find libEGL via ctypes.util.find_library('EGL')."
21+
else:
1922
try:
2023
import mujoco.egl
2124
from mujoco.egl import GLContext
@@ -26,8 +29,28 @@
2629
_egl_display = int(mujoco.egl.EGL_DISPLAY.address)
2730
_egl_context = int(_ctx._context.address)
2831
_egl_available = True
29-
except Exception:
30-
pass
32+
except Exception as exc:
33+
_egl_error = f"Failed to initialize MuJoCo EGL context: {exc!r}"
34+
35+
36+
def is_available() -> bool:
37+
return _egl_available
38+
39+
40+
def failure_reason() -> str | None:
41+
return _egl_error
42+
43+
44+
def require(feature: str = "offscreen rendering"):
45+
if _egl_available:
46+
return
47+
reason = _egl_error or "unknown EGL initialization failure"
48+
message = (
49+
f"EGL is required for {feature}, but it is not available. {reason} "
50+
"If you do not need rendering, run RCS without simulation cameras/viewers. "
51+
"If you do need headless rendering, install the system EGL/OpenGL runtime libraries."
52+
)
53+
raise RuntimeError(message)
3154

3255

3356
def bootstrap():

src/rcs/utils.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ void bootstrap_egl(uintptr_t fn_addr, uintptr_t dpy, uintptr_t ctx) {
1818
}
1919

2020
void ensure_current() {
21+
if (g_makeCurrent == nullptr || g_display == EGL_NO_DISPLAY ||
22+
g_context == EGL_NO_CONTEXT) {
23+
throw std::runtime_error(
24+
"EGL rendering was requested, but EGL was not bootstrapped. "
25+
"This usually means libEGL or the MuJoCo EGL context is unavailable. "
26+
"Run without cameras/viewers if you do not need rendering, or install "
27+
"the required system EGL/OpenGL runtime libraries.");
28+
}
2129
if (!g_makeCurrent(g_display, g_surface, g_surface, g_context))
2230
throw std::runtime_error("eglMakeCurrent failed");
2331
}

0 commit comments

Comments
 (0)