-
Notifications
You must be signed in to change notification settings - Fork 10
Async bitmap present #138
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
base: main
Are you sure you want to change the base?
Async bitmap present #138
Conversation
|
wow! |
|
I would love to help benchmark on some unique systems configurations i have: i was having a hard time getting pyside6 to show fps numbers above 60 fps on my (linux) machine. I feel like I must set:
Happy to setup a development environment for this, i can readily test on:
|
|
Create a canvas like this (e.g. taking our cube.py example): canvas = RenderCanvas(
title= $backend - $fps fps",
update_mode="fastest",
vsync=False,
present_method='bitmap' # bitmap or screen
)Then the fps is shown in the title bar. There is no actual null backend. I just temporarily made My first benchmarks were on my Mac M1. I will add some tests with Intel and NVidia GPU's later. |
|
This piece of work was brutal, but it's nearly done now. Apart from higher fps, this also reduces the delay between processing events and drawing. Below are two movies with an artificial low fps (10 fps). The first shows the previous behaviour: Screen.Recording.2026-01-23.at.16.42.41.movIn the new situation, even though the fps is low, the delay is small, which is really important to get a 'smooth' experience (maybe more so than high fps): Screen.Recording.2026-01-23.at.16.45.46.mov |
|
does your example mean that you've somehow found a way to shed 1 frame without sacrificing usability? |
It's more a question of timing. In remote rendering, you're pushing frames (over the network), and you want a mechanism for that downstream system to throttle the fps. Jupyter-rfb already has such a feedback mechanism based on the number of in-flight frames. The naive way. By the time you send it, it may already be 'old'. In current In this PR, we have |
|
I see, so placing |
|
Ready; added notes to top post. |
Co-authored-by: Jan <Vipitis@users.noreply.github.com>
|
I don't have time to carefully review, go ahead :) |
Ref #66
PRs that led up to this PR
First, we moved the context classes to
rendercanvas, allowingrendercanvasto implement custom behavior.Then we applied several changes, allowing
wgpuand andrendercanvasto interoperate for their async work, and to make it efficient and fast using threading:loop.call_soon_threadsafe()and re-implement precise sleep #146And some PRs related to present-method selection:
What this PR contributes
General:
Internal API changes:
BaseRenderCanvas._draw_frame_and_present()is removed.BaseRenderCanvas._rc_request_draw()is split in_rc_request_draw()and_rc_request_paint().BaseRenderCanvas._rc_request_draw()should eventually or directly call_time_to_draw(), when the canvas is ready to receive another frame.BaseRenderCanvas._rc_request_paint()should eventually call_time_to_paint(),inside the paint-event if applicable.
BaseRenderCanvas._set_visible()can be used by subclasses to disbale drawingwhile the canvas is invisible (e.g. mimimized).
BaseRenderCanvas._rc_force_draw()is renamed to_rc_force_paint().Context._rc_present()becomesContext._rc_present(*, force_sync:bool=False).force_syncis not set.Context._rc_set_present_params(**present_params).Timings
All numbers are in FPS, on a full-screen window on a Retina display (physical size 5120x2774).
The Cocoa is a WIP native backend for MacOS that uses Metal to display a texture that's stored in RAM.
The Null backend has
_rc_present_bitmapas a no-op, so the bitmap is downloaded to CPU and then discarted.Cube example
- Glfw: 180-200
- Qt: 120-190
- Qt: ~51
- Cocoa: 65-70
- Null: 70-80
- Qt: ~70
- Cocoa: 110
- Null: 140
Heavy example
- Glfw: 48-51
- Qt: 48-51
- Qt: 21-23
- Cocoa: 25-27
- Null: 27-30
- Qt: 46-51
- Cocoa: 46-51
- Null: 46-51
Interpretation