Repository: Genesis-Embodied-AI/Genesis
File: genesis/engine/sensors/camera.py (Python)

Code before:
            # This avoids OpenGL context conflicts since visualizer's rasterizer routes through viewer.render_offscreen()
            visualizer = getattr(scene, "visualizer", None)
            viewer = getattr(visualizer, "_viewer", None) if visualizer else None

            if viewer is not None:
                # Use visualizer's rasterizer - it will use viewer.render_offscreen() which handles context properly
                self._shared_metadata.context = visualizer.context
                self._shared_metadata.renderer = visualizer.rasterizer
            else:
                # No viewer - create standalone rasterizer with offscreen context
                self._shared_metadata.context = self._create_standalone_context(scene)
                self._shared_metadata.renderer = Rasterizer(viewer=None, context=self._shared_metadata.context)
                self._shared_metadata.renderer.build()

        self._shared_metadata.sensors.append(self)

        # Register camera now if standalone (offscreen), or defer to first render if using visualizer's rasterizer
        # (visualizer isn't built yet at sensor.build() time)
        if self._shared_metadata.renderer.offscreen:
            self._register_camera_with_renderer()

        _B = max(self._manager._sim.n_envs, 1)
        w, h = self._options.res
        self._shared_metadata.image_cache[self._idx] = torch.zeros((_B, h, w, 3), dtype=torch.uint8, device=gs.device)

    def _register_camera_with_renderer(self):
        """Register this camera with the renderer."""
        if self._camera_registered:
            return

        # Add lights from options to the context
        for light_config in self._options.lights:
            if self._shared_metadata.lights is not None:
                light_dict = self._convert_light_config_to_rasterizer(light_config)
                self._shared_metadata.context.add_light(light_dict)

        camera_wrapper = self._get_camera_wrapper()
        self._shared_metadata.renderer.add_camera(camera_wrapper)
        self._update_camera_pose()
        self._camera_registered = True

    def _create_standalone_context(self, scene):
        """Create a simplified RasterizerContext for camera sensors."""
        if not scene.sim._rigid_only and scene.n_envs > 1:
            gs.raise_exception("Rasterizer with n_envs > 1, does not work when using non rigid simulation")
        if sys.platform == "darwin":
            if scene.n_envs > 1:
                gs.raise_exception(
                    "Rasterizer with n_envs > 1, does not work on Metal because it doesn't support OpenGL 4.2"
                )
            env_separate_rigid = False

Review comment (suggestion):
Rename this function `_ensure_camera_registered` or anything that may indicate that it is safe to call this function repeatedly. Moreover, what is the point of adding `_with_renderer`? If you think it is useful you can keep it but I'm not sure it is adding much value here. 

Code after:
            # If a viewer is active, reuse its windowed OpenGL context for both offscreen and onscreen
            # rendering, rather than creating a separate headless context which is fragile.
            if scene.viewer is not None:
                self._shared_metadata.context = scene.visualizer.context
                self._shared_metadata.renderer = scene.visualizer.rasterizer
            else:
                # No viewer - create standalone rasterizer with offscreen context
                self._shared_metadata.context = self._create_standalone_context(scene)
                self._shared_metadata.renderer = Rasterizer(viewer=None, context=self._shared_metadata.context)
                self._shared_metadata.renderer.build()

        self._shared_metadata.sensors.append(self)

        # Register camera now if standalone (offscreen), or defer to first render if using visualizer's rasterizer
        # (visualizer isn't built yet at sensor.build() time)
        if self._shared_metadata.renderer.offscreen:
            self._ensure_camera_registered()

        _B = max(self._manager._sim.n_envs, 1)
        w, h = self._options.res
        self._shared_metadata.image_cache[self._idx] = torch.zeros((_B, h, w, 3), dtype=torch.uint8, device=gs.device)

    def _ensure_camera_registered(self):
        """Register this camera with the renderer (no-op if already registered)."""
        if self._is_camera_registered:
            return

        # Add lights from options to the context
        for light_config in self._options.lights:
            if self._shared_metadata.lights is not None:
                light_dict = self._convert_light_config_to_rasterizer(light_config)
                self._shared_metadata.context.add_light(light_dict)

        if self._camera_wrapper is None:
            self._camera_wrapper = RasterizerCameraWrapper(self)
        self._shared_metadata.renderer.add_camera(self._camera_wrapper)
        self._update_camera_pose()
        self._is_camera_registered = True

    def _create_standalone_context(self, scene):
        """Create a simplified RasterizerContext for camera sensors."""
        if not scene.sim._rigid_only and scene.n_envs > 1:
            gs.raise_exception("Rasterizer with n_envs > 1, does not work when using non rigid simulation")
        if sys.platform == "darwin":
            if scene.n_envs > 1:
                gs.raise_exception(
                    "Rasterizer with n_envs > 1, does not work on Metal because it doesn't support OpenGL 4.2"
                )
            env_separate_rigid = False
        else:
            if scene.n_envs > 1: