Skip to content

Commit

Permalink
draw_to_screen -> present_method
Browse files Browse the repository at this point in the history
  • Loading branch information
almarklein committed Sep 18, 2024
1 parent 02c9600 commit 4685a0b
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 34 deletions.
4 changes: 2 additions & 2 deletions wgpu/gui/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,12 @@ class WgpuCanvasBase(WgpuCanvasInterface):
also want to set ``vsync`` to False.
"""

def __init__(self, *args, max_fps=30, vsync=True, draw_to_screen=True, **kwargs):
def __init__(self, *args, max_fps=30, vsync=True, present_method=None, **kwargs):
super().__init__(*args, **kwargs)
self._last_draw_time = 0
self._max_fps = float(max_fps)
self._vsync = bool(vsync)
draw_to_screen # We just catch the arg here in case a backend does implement support it
present_method # We just catch the arg here in case a backend does implement support it

def __del__(self):
# On delete, we call the custom close method.
Expand Down
48 changes: 29 additions & 19 deletions wgpu/gui/qt.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,13 +142,28 @@ def enable_hidpi():
class QWgpuWidget(WgpuAutoGui, WgpuCanvasBase, QtWidgets.QWidget):
"""A QWidget representing a wgpu canvas that can be embedded in a Qt application."""

def __init__(self, *args, draw_to_screen=True, **kwargs):
def __init__(self, *args, present_method=None, **kwargs):
super().__init__(*args, **kwargs)

# Determine present method
self._surface_ids = self._get_surface_ids()
self._draw_to_screen = draw_to_screen and bool(self._surface_ids)
if not present_method:
self._present_to_screen = True
if SYSTEM_IS_WAYLAND:
# Trying to render to screen on Wayland segfaults. This might be because
# the "display" is not the real display id. We can tell Qt to use
# XWayland, so we can use the X11 path. This worked at some point,
# but later this resulted in a Rust panic. So, until this is sorted
# out, we fall back to rendering via an image.
self._present_to_screen = False
elif present_method == "screen":
self._present_to_screen = True
elif present_method == "image":
self._present_to_screen = False
else:
raise ValueError(f"Invalid present_method {present_method}")

self.setAttribute(WA_PaintOnScreen, self._draw_to_screen)
self.setAttribute(WA_PaintOnScreen, self._present_to_screen)
self.setAutoFillBackground(False)
self.setAttribute(WA_DeleteOnClose, True)
self.setAttribute(WA_InputMethodEnabled, True)
Expand All @@ -163,7 +178,7 @@ def __init__(self, *args, draw_to_screen=True, **kwargs):

def paintEngine(self): # noqa: N802 - this is a Qt method
# https://doc.qt.io/qt-5/qt.html#WidgetAttribute-enum WA_PaintOnScreen
if self._draw_to_screen:
if self._present_to_screen:
return None
else:
return super().paintEngine()
Expand All @@ -179,18 +194,13 @@ def _get_surface_ids(self):
"window": int(self.winId()),
}
elif sys.platform.startswith("linux"):
if SYSTEM_IS_WAYLAND:
# Trying to do it the Wayland way segfaults. This might be because
# the "display" is not the real display id. We can tell Qt to use
# XWayland, so we can use the X11 path. This worked at some point,
# but later this resulted in a Rust panic. So, until this is sorted
# out, we fall back to rendering via an image.
return None
# return {
# "platform": "wayland",
# "window": int(self.winId()),
# "display": int(get_alt_wayland_display()),
# }
if False:
# We fall back to XWayland, see _gui_utils.py
return {
"platform": "wayland",
"window": int(self.winId()),
"display": int(get_alt_wayland_display()),
}
else:
return {
"platform": "x11",
Expand All @@ -200,7 +210,7 @@ def _get_surface_ids(self):

def get_present_info(self):
global _show_image_method_warning
if self._draw_to_screen and self._surface_ids:
if self._present_to_screen:
info = {"method": "screen"}
info.update(self._surface_ids)
else:
Expand Down Expand Up @@ -424,7 +434,7 @@ class QWgpuCanvas(WgpuAutoGui, WgpuCanvasBase, QtWidgets.QWidget):
# detect this. See https://github.com/pygfx/wgpu-py/pull/68

def __init__(
self, *, size=None, title=None, max_fps=30, draw_to_screen=True, **kwargs
self, *, size=None, title=None, max_fps=30, present_method=None, **kwargs
):
# When using Qt, there needs to be an
# application before any widget is created
Expand All @@ -437,7 +447,7 @@ def __init__(
self.setMouseTracking(True)

self._subwidget = QWgpuWidget(
self, max_fps=max_fps, draw_to_screen=draw_to_screen
self, max_fps=max_fps, present_method=present_method
)
self._subwidget.add_event_handler(weakbind(self.handle_event), "*")

Expand Down
36 changes: 23 additions & 13 deletions wgpu/gui/wx.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,11 +134,22 @@ def Notify(self, *args): # noqa: N802
class WxWgpuWindow(WgpuAutoGui, WgpuCanvasBase, wx.Window):
"""A wx Window representing a wgpu canvas that can be embedded in a wx application."""

def __init__(self, *args, draw_to_screen=True, **kwargs):
def __init__(self, *args, present_method=None, **kwargs):
super().__init__(*args, **kwargs)

# Determine present method
self._surface_ids = self._get_surface_ids()
self._draw_to_screen = draw_to_screen and bool(self._surface_ids)
if not present_method:
self._present_to_screen = True
if SYSTEM_IS_WAYLAND:
# See comments in same place in qt.py
self._present_to_screen = False
elif present_method == "screen":
self._present_to_screen = True
elif present_method == "image":
self._present_to_screen = False
else:
raise ValueError(f"Invalid present_method {present_method}")

# A timer for limiting fps
self._request_draw_timer = TimerWithCallback(self.Refresh)
Expand Down Expand Up @@ -322,14 +333,13 @@ def _get_surface_ids(self):
"window": int(self.GetHandle()),
}
elif sys.platform.startswith("linux"):
if SYSTEM_IS_WAYLAND:
# Fallback to offscreen rendering. See comment in same place in qt.py.
return None
# return {
# "platform": "wayland",
# "window": int(self.GetHandle()),
# "display": int(get_alt_wayland_display()),
# }
if False:
# We fall back to XWayland, see _gui_utils.py
return {
"platform": "wayland",
"window": int(self.GetHandle()),
"display": int(get_alt_wayland_display()),
}
else:
return {
"platform": "x11",
Expand All @@ -341,7 +351,7 @@ def _get_surface_ids(self):

def get_present_info(self):
global _show_image_method_warning
if self._draw_to_screen and self._surface_ids:
if self._present_to_screen and self._surface_ids:
info = {"method": "screen"}
info.update(self._surface_ids)
else:
Expand Down Expand Up @@ -420,7 +430,7 @@ def __init__(
size=None,
title=None,
max_fps=30,
draw_to_screen=True,
present_method=None,
**kwargs,
):
get_app()
Expand All @@ -430,7 +440,7 @@ def __init__(
self.SetTitle(title or "wx wgpu canvas")

self._subwidget = WxWgpuWindow(
parent=self, max_fps=max_fps, draw_to_screen=draw_to_screen
parent=self, max_fps=max_fps, present_method=present_method
)
self._subwidget.add_event_handler(weakbind(self.handle_event), "*")
self.Bind(wx.EVT_CLOSE, lambda e: self.Destroy())
Expand Down

0 comments on commit 4685a0b

Please sign in to comment.