https://bugs.kde.org/show_bug.cgi?id=369349

Dmitry Kazakov <dimul...@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |dimul...@gmail.com

--- Comment #32 from Dmitry Kazakov <dimul...@gmail.com> ---
(In reply to RN from comment #31)

> Forcing the visual updates (what the delayed painter is doing) when the
> window manager can't keep up with visual updates in the first place is not
> going to give the expected result, it would stutter anyway.

Don't mix window updates rate, tablet events rate and painting rate. They are
three different things.

Tablet events rate is the rate we get the tablet events from the driver. In
normal situation the events come at rate 1 event per 7-14ms. Long window
updates may delay the events and they will start coming in bunches 4-5 events
per every 40-50ms.

Then we have "painting rate", that is a rate we generate dabs with the
stabilizer algorithm and pass them to the painting code.

After passing the points to the painting code, the painting code paints and
generates window updates, but the updates are not passed to the GPU directly.
They first compressed to not overload the pipeline with too many small updates,
and only after that are passed to the GPU (on GPUs supporting glFenceSync).
This final flow of updates in "painting rate" and it cannot be higher than the
GPU can handle.

Basically, the flow looks like that:

1) Tablet events come in bunches every 7-50 ms.
2) KisStabilizedEventsSampler delays the flow by 50ms. That allows it to group
the evens into 50ms groups and to adjust the time as if the events inside the
group were flowing uniformly (e.g. for group of 5 events, the sampler will
modify them as if they they were issues every 10ms).
3) These groups of events come to KisStabilizerDelayedPaintHelper, that
regroups the groups from the sampler into groups of 20ms (20ms == 40fps, which
should be enough for everyone(c)) and passes them to the painting code every 20
ms.

Now I see that a thing that can happen is that delayed painter is not
synchronized with the sampler. That is, it might happen that the delay helper
can have "empty" cycles, where the samples from the sampler are not ready yet.
To avoid the problem we should sync the timers of sampler and delay helper to
be a multiple of each other.


A quite test for this hypothesis might be to set:

stabilizerSampleSize=60
stabilizerDelayedPaintInterval=20

That is still not very "sync", but if it makes the things better then we should
move into this direction further. Probably, by merging the two timers into one.






> In Dmitry's case the timer interval would've grown
> until reaching 50ms or more.
> The timer is stopped when the stroke ends, and when a new stroke begins the
> timer interval starts at some default value (16ms for example, or 1ms like
> 2.9.11 although that might be too fast).

In feedback control systems theory it is called "proportional regulator". And
it it really a bad thing to use, unless there is no other choice. What if the I
accidentally have a delay of 200ms? Will all my further strokes be smoothed by
200ms? And if not, then we should do some PI-regulator, which is stable enough
and still does the job. It may have quite a lot of unexpected consequences.


> Whatever is decided, I think something should be added to the interface
> (maybe in Configure Krita -> Tablet Preferences), like spinboxes to set
> timer values so that users don't have to go and modify 'kritarc' themselves,
> and be able to quickly test different values without having to restart the
> program. Someone above mentioned having difficulty doing that, for example.
> Regards.

I have a feeling that there is some bug in how we handle the events flow. We
should first try to fix it, instead of giving the user an option to control
such non-obvious property.

As a direction of further work, it might be a good idea to have a log of how
many events are usually handled in 

KisStabilizerDelayedPaintHelper::stabilizerDelayedPaint() 

when isEndStroke is false.

If the number of events is always the same, then my theory is probably not
correct. If it interleaves with zero like "10,0,11,0,9,0...", then my theory is
correct.

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to