diff --git a/python/mujoco/functions.h b/python/mujoco/functions.h index 5a318850..ac7934d0 100644 --- a/python/mujoco/functions.h +++ b/python/mujoco/functions.h @@ -192,6 +192,14 @@ static constexpr void Def( ::pybind11::call_guard<::pybind11::gil_scoped_release>()); } +template +MUJOCO_ALWAYS_INLINE +static constexpr void DefWithGil(::pybind11::module_& m, Func&& func) { + WithNamedArgs(MjTraits::param_names).def( + m, MjTraits::name, util::UnwrapArgs(std::forward(func)), + ::pybind11::doc(MjTraits::doc)); +} + // Should only be invoked via the DEF_WITH_OMITTED_PY_ARGS macro. template struct DefWithOmittedPyArgsImpl { diff --git a/python/mujoco/render.cc b/python/mujoco/render.cc index 1d73e415..1681f036 100644 --- a/python/mujoco/render.cc +++ b/python/mujoco/render.cc @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include #include @@ -252,14 +253,19 @@ PYBIND11_MODULE(_render, pymodule) { Def(pymodule); Def(pymodule); Def(pymodule); - Def( - pymodule, [](std::optional> rgb, + DefWithGil( + pymodule, [](std::optional> rgb, std::optional> depth, const raw::MjrRect* viewport, const raw::MjrContext* con) { - return InterceptMjErrors(::mjr_readPixels)( - rgb.has_value() ? rgb->mutable_data() : nullptr, - depth.has_value() ? depth->mutable_data() : nullptr, *viewport, - con); + std::uint8_t* const rgb_data = + rgb.has_value() ? rgb->mutable_data() : nullptr; + float* const depth_data = + depth.has_value() ? depth->mutable_data() : nullptr; + { + py::gil_scoped_release no_gil; + return InterceptMjErrors(::mjr_readPixels)(rgb_data, depth_data, + *viewport, con); + } }); Def( pymodule,