Summary: | Low pointer polling rates cause inconsistent frame 'timings' in functions tied to pointer movement. | ||
---|---|---|---|
Product: | [Applications] krita | Reporter: | Ralek Kolemios <info> |
Component: | OpenGL Canvas | Assignee: | Krita Bugs <krita-bugs-null> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | griffinvalley, info |
Priority: | NOR | ||
Version First Reported In: | nightly build (please specify the git hash!) | ||
Target Milestone: | --- | ||
Platform: | Microsoft Windows | ||
OS: | Microsoft Windows | ||
Latest Commit: | Version Fixed In: | ||
Sentry Crash Report: | |||
Attachments: |
Timelapse of a canvas pan using various input methods
polling rate comparison Proposed fix |
Description
Ralek Kolemios
2021-06-24 09:33:19 UTC
Created attachment 139651 [details]
polling rate comparison
A graphic describing why I believe this issue happens.
Created attachment 139652 [details] Proposed fix Text taken from https://krita-artists.org/t/what-makes-kritas-canvas-operations-feel-so-wrong/25377/20?u=ralek My concept for how to fix this. Of course I don't understand the inner working of QT or Krita, I'm just an artist, so this is going off of theoretical data and my desire to help. In the background, asynchronously, a pointer pseudoposition function is constantly receiving inputs from the actual pointer. It keeps the last 2 (or more if you’re a math major) of these positions and timings in-memory for later reference. At any point in time that an action requires an ‘up to date’ and ‘consistent’ but not necessarily extremely accurate pointer position, such as for panning, zooming, rotating, etc, instead of grabbing the current pointer position, it calls the pointerPseudoposition function. This function grabs the current microtime, and extrapolates a ‘current’ pointer position given the previous 2 mouse positions and microtime. I’d imagine the math would look something like: x1 = last known x position x2 = last x position before x1 y1 = last known y position y2 = last y position before y1 time1 = time int in microseconds of last known pointer input time2 = time int in microseconds of previously known pointer input before time1 currentTime = the microseconds of when the function is called newX = x1 + ( (currentTime - time1) / (time1 - time2) * (x1 - x2)) newY = y1 + ( (currentTime - time1) / (time1 - time2) * (y1 - y2)) This will output an X and Y position of the ‘mouse’ which should slot into whatever function the current pan/rotate/zoom function uses when it calls for the mouse position. This will cause slightly weird behavior if the pointer changes directions instantaneously, but for natural movements such as tablet pens, this could be a lifesaver. Perhaps it could be a toggle-able feature called ‘polling rate compensation’. There's a new option in the tablet settings in Krita 5.0, which suggests using the driver time stamp instead of a timer based one. If that doesn't work, I'm afraid we can't do much. The problem isn't so much whether your tablet can sent events, the problem is that the OS compresses them and only sents it to Krita whenever it feels like it. So we can't really do anything here. |