Skip to content

Commit

Permalink
BUG: Better Wayland and open-source 3D support (#13012)
Browse files Browse the repository at this point in the history
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
  • Loading branch information
larsoner and autofix-ci[bot] authored Dec 14, 2024
1 parent bd4a160 commit 9b7b559
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 13 deletions.
1 change: 1 addition & 0 deletions doc/changes/devel/13012.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix errant detection of software-rendered vs hardware-rendered MESA GL contexts in 3D rendering on Linux, by `Eric Larson`_.
14 changes: 14 additions & 0 deletions doc/install/advanced.rst
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,20 @@ of VTK and/or QT are incompatible. This series of commands should fix it:
If you installed VTK using ``pip`` rather than ``conda``, substitute the first
line for ``pip uninstall -y vtk``.

3D plotting trouble on Linux
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you are having trouble with 3D plotting on Linux, one possibility is that you
are using Wayland for graphics. To check, you can do:

.. code-block:: console
$ echo $XDG_SESSION_TYPE
wayland
If so, you will need to tell Qt to use X11 instead of Wayland. You can do this
by setting ``export QT_QPA_PLATFORM=xcb`` in your terminal session. To make it
permanent for your logins, you can set it for example in ``~/.profile``.

.. LINKS
Expand Down
13 changes: 8 additions & 5 deletions mne/viz/backends/_pyvista.py
Original file line number Diff line number Diff line change
Expand Up @@ -837,7 +837,7 @@ def _toggle_antialias(self):
"""Enable it everywhere except on systems with problematic OpenGL."""
# MESA can't seem to handle MSAA and depth peeling simultaneously, see
# https://github.com/pyvista/pyvista/issues/4867
bad_system = _is_mesa(self.plotter)
bad_system = _is_osmesa(self.plotter)
for plotter in self._all_plotters:
if bad_system or not self.antialias:
plotter.disable_anti_aliasing()
Expand Down Expand Up @@ -1319,10 +1319,11 @@ def _disabled_depth_peeling():
depth_peeling["enabled"] = depth_peeling_enabled


def _is_mesa(plotter):
def _is_osmesa(plotter):
# MESA (could use GPUInfo / _get_gpu_info here, but it takes
# > 700 ms to make a new window + report capabilities!)
# CircleCI's is: "Mesa 20.0.8 via llvmpipe (LLVM 10.0.0, 256 bits)"
# and a working Nouveau is: "Mesa 24.2.3-1ubuntu1 via NVE6"
if platform.system() == "Darwin": # segfaults on macOS sometimes
return False
gpu_info_full = plotter.ren_win.ReportCapabilities()
Expand All @@ -1331,8 +1332,9 @@ def _is_mesa(plotter):
gpu_info_full,
)
gpu_info = " ".join(gpu_info).lower()
is_mesa = "mesa" in gpu_info.split()
if is_mesa:
is_osmesa = "mesa" in gpu_info.split()
print(is_osmesa)
if is_osmesa:
# Try to warn if it's ancient
version = re.findall("mesa ([0-9.]+)[ -].*", gpu_info) or re.findall(
"OpenGL version string: .* Mesa ([0-9.]+)\n", gpu_info_full
Expand All @@ -1345,7 +1347,8 @@ def _is_mesa(plotter):
"surface rendering, consider upgrading to 18.3.6 or "
"later."
)
return is_mesa
is_osmesa = "via llvmpipe" in gpu_info
return is_osmesa


class _SafeBackgroundPlotter(BackgroundPlotter):
Expand Down
1 change: 0 additions & 1 deletion mne/viz/backends/_qt.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@
_check_3d_figure, # noqa: F401
_close_3d_figure, # noqa: F401
_close_all, # noqa: F401
_is_mesa, # noqa: F401
_PyVistaRenderer,
_set_3d_title, # noqa: F401
_set_3d_view, # noqa: F401
Expand Down
19 changes: 12 additions & 7 deletions mne/viz/backends/tests/test_renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,16 +217,21 @@ def fail(x):
def test_3d_warning(renderer_pyvistaqt, monkeypatch):
"""Test that warnings are emitted for old Mesa."""
fig = renderer_pyvistaqt.create_3d_figure((800, 600))
_is_mesa = renderer_pyvistaqt.backend._is_mesa
from mne.viz.backends._pyvista import _is_osmesa

plotter = fig.plotter
good = "OpenGL renderer string: OpenGL 3.3 (Core Profile) Mesa 20.0.8 via llvmpipe (LLVM 10.0.0, 256 bits)\n" # noqa
bad = "OpenGL renderer string: OpenGL 3.3 (Core Profile) Mesa 18.3.4 via llvmpipe (LLVM 7.0, 256 bits)\n" # noqa
pre = "OpenGL renderer string: "
good = f"{pre}OpenGL 3.3 (Core Profile) Mesa 20.0.8 via llvmpipe (LLVM 10.0.0, 256 bits)\n" # noqa
bad = f"{pre}OpenGL 3.3 (Core Profile) Mesa 18.3.4 via llvmpipe (LLVM 7.0, 256 bits)\n" # noqa
monkeypatch.setattr(platform, "system", lambda: "Linux") # avoid short-circuit
monkeypatch.setattr(plotter.ren_win, "ReportCapabilities", lambda: good)
assert _is_mesa(plotter)
assert _is_osmesa(plotter)
monkeypatch.setattr(plotter.ren_win, "ReportCapabilities", lambda: bad)
with pytest.warns(RuntimeWarning, match=r"18\.3\.4 is too old"):
assert _is_mesa(plotter)
non = "OpenGL 4.1 Metal - 76.3 via Apple M1 Pro\n"
assert _is_osmesa(plotter)
non = f"{pre}OpenGL 4.1 Metal - 76.3 via Apple M1 Pro\n"
monkeypatch.setattr(plotter.ren_win, "ReportCapabilities", lambda: non)
assert not _is_osmesa(plotter)
non = f"{pre}OpenGL 4.5 (Core Profile) Mesa 24.2.3-1ubuntu1 via NVE6\n"
monkeypatch.setattr(plotter.ren_win, "ReportCapabilities", lambda: non)
assert not _is_mesa(plotter)
assert not _is_osmesa(plotter)

0 comments on commit 9b7b559

Please sign in to comment.