Release GIL in MuJoCo Studio Python bindings.

This change adds py::gil_scoped_release to various functions in the parser, renderer, sim and ux modules of the MuJoCo Studio Python bindings. This allows other Python threads to execute while these C++ functions, which can sometimes be time-consuming, are running. The two heaviest operations Present() (rendering) and Advance() (physics) now both release the GIL in C++.

PiperOrigin-RevId: 930645361
Change-Id: Ib239fb54edc7ac0d8b1d94bec8c57a447d5f4d27
This commit is contained in:
Matija Kecman
2026-06-11 11:31:28 -07:00
committed by Copybara-Service
parent ab17ff5552
commit 37084a5c0b
4 changed files with 46 additions and 6 deletions
+12 -5
View File
@@ -36,12 +36,16 @@ class Renderer {
using GraphicsMode = mujoco::platform::GraphicsMode;
Renderer(const std::string& graphics_mode_str) {
py::gil_scoped_release no_gil;
const GraphicsMode mode = mujoco::platform::GraphicsModeFromString(
graphics_mode_str, GraphicsMode::FilamentOpenGl);
impl_ = std::make_unique<RendererImpl>(nullptr, mode);
}
void Init(const MjModelWrapper& model) { impl_->Init(model.get()); }
void Init(const MjModelWrapper& model) {
py::gil_scoped_release no_gil;
impl_->Init(model.get());
}
pybind11::bytes Render(const MjModelWrapper& model, MjDataWrapper& data,
std::optional<MjvPerturbWrapper>& perturb,
@@ -49,10 +53,13 @@ class Renderer {
std::optional<MjvOptionWrapper>& vis_option, int width,
int height) {
std::vector<std::byte> pixels(width * height * 3);
impl_->Render(
model.get(), data.get(), perturb ? perturb.value().get() : nullptr,
camera ? camera.value().get() : nullptr,
vis_option ? vis_option.value().get() : nullptr, width, height, pixels);
{
py::gil_scoped_release no_gil;
impl_->Render(
model.get(), data.get(), perturb ? perturb.value().get() : nullptr,
camera ? camera.value().get() : nullptr,
vis_option ? vis_option.value().get() : nullptr, width, height, pixels);
}
return pybind11::bytes((const char*)pixels.data(), pixels.size());
}