|
2 | 2 | The scheduler class/loop. |
3 | 3 | """ |
4 | 4 |
|
| 5 | +import sys |
5 | 6 | import time |
6 | 7 | import weakref |
7 | 8 |
|
8 | 9 | from ._coreutils import BaseEnum |
9 | 10 | from .utils.asyncs import sleep, Event |
10 | 11 |
|
11 | 12 |
|
| 13 | +IS_WIN = sys.platform.startswith("win") |
| 14 | + |
| 15 | + |
12 | 16 | class UpdateMode(BaseEnum): |
13 | 17 | """The UpdateMode enum specifies the different modes to schedule draws for the canvas.""" |
14 | 18 |
|
@@ -123,14 +127,23 @@ async def __scheduler_task(self): |
123 | 127 | delay = 1 / self._max_fps |
124 | 128 | delay = 0 if delay < 0 else delay # 0 means cannot keep up |
125 | 129 |
|
126 | | - # Offset delay for time spent on processing events, etc. |
127 | | - time_since_tick_start = time.perf_counter() - last_tick_time |
128 | | - delay -= time_since_tick_start |
129 | | - delay = max(0, delay) |
130 | | - |
131 | | - # Wait. Even if delay is zero, it gives control back to the loop, |
132 | | - # allowing other tasks to do work. |
133 | | - await sleep(delay) |
| 130 | + # Determine amount of sleep |
| 131 | + sleep_time = delay - (time.perf_counter() - last_tick_time) |
| 132 | + |
| 133 | + if IS_WIN: |
| 134 | + # On Windows OS-level timers have an in accuracy of 15.6 ms. |
| 135 | + # This can cause sleep to take longer than intended. So we sleep |
| 136 | + # less, and then do a few small sync-sleeps that have high accuracy. |
| 137 | + await sleep(max(0, sleep_time - 0.0156)) |
| 138 | + sleep_time = delay - (time.perf_counter() - last_tick_time) |
| 139 | + while sleep_time > 0: |
| 140 | + time.sleep(min(sleep_time, 0.001)) # sleep hard for at most 1ms |
| 141 | + await sleep(0) # Allow other tasks to run but don't wait |
| 142 | + sleep_time = delay - (time.perf_counter() - last_tick_time) |
| 143 | + else: |
| 144 | + # Wait. Even if delay is zero, it gives control back to the loop, |
| 145 | + # allowing other tasks to do work. |
| 146 | + await sleep(max(0, sleep_time)) |
134 | 147 |
|
135 | 148 | # Below is the "tick" |
136 | 149 |
|
|
0 commit comments