-
-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor wgpu.gui for scheduling #618
base: main
Are you sure you want to change the base?
Conversation
I've been working on this for more than a week. This is hard, but it's beginning to take shape now. |
This implements (amongst other things) the ideas presented in http://gameprogrammingpatterns.com/game-loop.html As robert says: In addition to that, we also gave multiple different GUI systems and event loops.
In our case that actually depends 😅 The scheduling code assumes it runs on an externally provided eventloop. For glfw we do provide the loop, but the scheduling logic does not know this. |
wgpu/gui/base.py
Outdated
self._events.submit({"event_type": "before_draw"}) | ||
self._events.flush() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just realized that this flush also flushes other pending events, which is not what should happen, and very likely the cause for why I cannot get force_draw()
working on Qt.
I threw my hands in the air when I realized, hit my cup of tea, which fell over, spilling tea all over my desk, barely missing my laptop ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well... all is well that ends well. Good find!
These args can be passed when the canvas is instantiated. For now, we can leave it at that (no changing these at runtime). |
Ok, this is almost done. All backends are working and tested on different platforms. I'm going to do a round of self-review and cleanup. I think we will never merge this here, but in the new repo: #627 |
if time.perf_counter() - self._draw_request_time > 0.02: | ||
self._process_events() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc @kushalkolar
_surface_id = ffi.NULL | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change should be applied to wgpu
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is ready for review. It does not actually break compatibility so much. You can run pygfx examples with it. When this pr is approved, I'll re-recreate the pr at |
Refs
Summary
Canvas
WgpuAutoGui
, since its no simply a part ofWgpuCanvasBase
WgpuCanvasBase
is cleaner because it moves events and scheduling out.Events
Scheduling
WgpuCanvasBase
implements a scheduling mechanic (Canvas implementations no longer have to do this).max_fps
applies (only) to continuous and ondemand mode.force_draw()
method for a blocking render call.Public loop API
run()
andcall_later()
functions are replaced with aloop
object that has both as a method.call_later
method returns a timer object, so the callback can be cancelled.call_repeated()
that returns a timer object that keeps ticking. We really needed an abstract timer object for the scheduling. Might as well provide it to our users.Design decisions
canvas.add_event_handler()
or do we switch tocanvas.events.add_handler()
orcanvas.events.connect()
?canvas.add_event_handler()
feels a bit long, but it is explicit, and helps the canvas feel flat/simple.canvas.scheduler.max_fps
,canvas.scheduler.mode
, etc.API changes
canvas.force_draw()
.from wgpu.gui.xx import WgpuCanvas, run
withfrom wgpu.gui.xx import WgpuCanvas, loop
WgpuAutoGui
mixin class is removed.Tasks
request_draw()
in the draw function equal 'continuous'. -> we test that this is the case.After this PR
draw_func
to be an asyn function.present()
out ofCanvasContext()
?request_draw()
?