Bug 455570 - Krita plus 5.1.0 prealpha : complex brush outline causes performance lag
Summary: Krita plus 5.1.0 prealpha : complex brush outline causes performance lag
Status: RESOLVED FIXED
Alias: None
Product: krita
Classification: Applications
Component: Brush engines (show other bugs)
Version: nightly build (please specify the git hash!)
Platform: Microsoft Windows Microsoft Windows
: NOR normal
Target Milestone: ---
Assignee: Dmitry Kazakov
URL:
Keywords:
: 456172 (view as bug list)
Depends on: 465086
Blocks:
  Show dependency treegraph
 
Reported: 2022-06-18 22:01 UTC by stephen
Modified: 2023-04-13 13:51 UTC (History)
5 users (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments
Texture of the gauze brush (392.50 KB, image/png)
2022-06-18 22:01 UTC, stephen
Details
stutter with the moo bubble (51.68 KB, application/x-krita)
2022-06-30 23:15 UTC, stephen
Details
Beta1 vs July 6 - Linux hover draw test - moo bubble (Celeron N3060+iGPU) (1.48 MB, video/mp4)
2022-07-07 01:37 UTC, Protoniv
Details
beta 1 vs July 6 - Linux hover draw test - moo bubble (i7 2670QM+GT540M) (2.57 MB, video/mp4)
2022-07-07 01:46 UTC, Protoniv
Details
Tablet_log (20.47 KB, image/png)
2022-08-06 02:09 UTC, stephen
Details
tablet log (i7 2670QM+GT540M linux machine) (149.97 KB, text/x-log)
2022-08-16 08:05 UTC, Protoniv
Details
tablet log (Celeron N3060+igpu linux machine) (976.94 KB, text/x-log)
2022-08-16 08:12 UTC, Protoniv
Details
tablet log (Pentium 3825U+igpu Win10 machine) (79.82 KB, text/plain)
2022-08-17 04:39 UTC, Protoniv
Details
Happened with drawing tablet before and after commit 2e81d96f7552d0e760112026eb1a8b7b3bd206f1 (970.33 KB, video/mp4)
2023-01-20 13:10 UTC, Protoniv
Details

Note You need to log in before you can comment on or make changes to this bug.
Description stephen 2022-06-18 22:01:59 UTC
Created attachment 149907 [details]
Texture of the gauze brush

SUMMARY
There's a gauze brush that causes Krita to stutter and lag
for some unknown reason.
In order to have you make investigation, I'll append the picture of the
brush tip here. It's noticeable when you try to paint or to resize the brush with
the Shift+drag combination. 
Because of that, I can't use it to work.

STEPS TO REPRODUCE
1. create a custom brush with the provided png file
2. Settings for the custom brush as follows :
# Sharpness mod ON : pressure(min : 30%, max : 60%)
# Rotation mod ON : fuzzy dab(min : -180°, max : 180°)
# Spacing : 0.37(auto : off)
3. Try to paint strokes with the brush at 500 pixels size or more.
4. See if you can increase size to 1000 pixels with smooth updated renders, using the Shift+drag method.

OBSERVED RESULT
Krita struggles to update the rendered outline preview of the brush when the size is
big(500-1000px), noticeable frame rate drop or stutters.
Krita paints the stamps at a slower speed than expected when the size is big(500-1000px).

EXPECTED RESULT
No stutter or framerate drop.

SOFTWARE/OS VERSIONS
Windows: 10 21H1
Qt versions :  Version (compiled): 5.12.12, Version (loaded): 5.12.12
Comment 1 stephen 2022-06-18 22:04:35 UTC
Krita version : prealpha e429092
Comment 2 Dmitry Kazakov 2022-06-21 06:54:01 UTC
Hi, Stephen!

Could you please tell, what is exactly the the stutter/slowdown you experience? And which one is the biggest problem for you?

1) The stutter when doing shift+drag brush resize gesture
2) A small delay (about 200ms) in the beginning of the first brush stroke after brush resize. The following brush strokes don't have it.
3) The delay/stutter when painting with the second and the following strokes after resize

I can personally reproduce the first two issues. I can fix the first one. The second one is kind of "expected behavior" (disputable). And I cannot see the third variant of the issue. If you have the third one, please attach a video of the problem.
Comment 3 Dmitry Kazakov 2022-06-22 08:03:17 UTC
Git commit f01f8837d0980f3fb1c00b2b5e0b9ef038417b74 by Dmitry Kazakov.
Committed on 22/06/2022 at 08:03.
Pushed by dkazakov into branch 'master'.

Fix a slowdown when Shift+gestrure-resize huge and complex brushes

This patch does two things:

1) Now the brush outline is generated **not** from the real brush tip,
   generated by generateMaskAndApplyMaskOrCreateDab(), but from the
   original brushTipImage(). It should generate the same outline, unless
   any of our brush modes support changing opacity of the brush tip
   (afaict, none of them support that).

2) The outline and pyramid caches are now shared between the source and
   cloned brush tips. That is, updating a cache inside a cloned brush will
   also update the cache inside the source brush (in the registry). This
   decision is a bit scary, but solves really a lot of performance troubles.
   The link between the two brush objects will be reset only when one of
   the objects calls `cache.reset()`.

M  +19   -20   libs/brush/kis_brush.cpp
M  +139  -16   libs/global/KisLazySharedCacheStorage.h

https://invent.kde.org/graphics/krita/commit/f01f8837d0980f3fb1c00b2b5e0b9ef038417b74
Comment 4 Dmitry Kazakov 2022-06-22 08:03:54 UTC
Git commit a81e8bdb60a8d86fa7c593fb4237f168663df068 by Dmitry Kazakov.
Committed on 22/06/2022 at 08:03.
Pushed by dkazakov into branch 'krita/5.1'.

Fix a slowdown when Shift+gestrure-resize huge and complex brushes

This patch does two things:

1) Now the brush outline is generated **not** from the real brush tip,
   generated by generateMaskAndApplyMaskOrCreateDab(), but from the
   original brushTipImage(). It should generate the same outline, unless
   any of our brush modes support changing opacity of the brush tip
   (afaict, none of them support that).

2) The outline and pyramid caches are now shared between the source and
   cloned brush tips. That is, updating a cache inside a cloned brush will
   also update the cache inside the source brush (in the registry). This
   decision is a bit scary, but solves really a lot of performance troubles.
   The link between the two brush objects will be reset only when one of
   the objects calls `cache.reset()`.

M  +19   -20   libs/brush/kis_brush.cpp
M  +139  -16   libs/global/KisLazySharedCacheStorage.h

https://invent.kde.org/graphics/krita/commit/a81e8bdb60a8d86fa7c593fb4237f168663df068
Comment 5 Dmitry Kazakov 2022-06-22 12:54:10 UTC
Git commit bef36adac9ed3934c68431da838045041fa4a31d by Dmitry Kazakov.
Committed on 22/06/2022 at 12:48.
Pushed by dkazakov into branch 'krita/5.1'.

Fix a slowdown when Shift+gestrure-resize huge and complex brushes

This patch does two things:

1) Now the brush outline is generated **not** from the real brush tip,
   generated by generateMaskAndApplyMaskOrCreateDab(), but from the
   original brushTipImage(). It should generate the same outline, unless
   any of our brush modes support changing opacity of the brush tip
   (afaict, none of them support that).

2) The outline and pyramid caches are now shared between the source and
   cloned brush tips. That is, updating a cache inside a cloned brush will
   also update the cache inside the source brush (in the registry). This
   decision is a bit scary, but solves really a lot of performance troubles.
   The link between the two brush objects will be reset only when one of
   the objects calls `cache.reset()`.

M  +19   -20   libs/brush/kis_brush.cpp
M  +139  -16   libs/global/KisLazySharedCacheStorage.h

https://invent.kde.org/graphics/krita/commit/bef36adac9ed3934c68431da838045041fa4a31d
Comment 6 stephen 2022-06-28 00:15:18 UTC
(In reply to Dmitry Kazakov from comment #5)
> Git commit bef36adac9ed3934c68431da838045041fa4a31d by Dmitry Kazakov.
> Committed on 22/06/2022 at 12:48.
> Pushed by dkazakov into branch 'krita/5.1'.
> 
> Fix a slowdown when Shift+gestrure-resize huge and complex brushes
> 
> This patch does two things:
> 
> 1) Now the brush outline is generated **not** from the real brush tip,
>    generated by generateMaskAndApplyMaskOrCreateDab(), but from the
>    original brushTipImage(). It should generate the same outline, unless
>    any of our brush modes support changing opacity of the brush tip
>    (afaict, none of them support that).
> 
> 2) The outline and pyramid caches are now shared between the source and
>    cloned brush tips. That is, updating a cache inside a cloned brush will
>    also update the cache inside the source brush (in the registry). This
>    decision is a bit scary, but solves really a lot of performance troubles.
>    The link between the two brush objects will be reset only when one of
>    the objects calls `cache.reset()`.
> 
> M  +19   -20   libs/brush/kis_brush.cpp
> M  +139  -16   libs/global/KisLazySharedCacheStorage.h
> 
> https://invent.kde.org/graphics/krita/commit/
> bef36adac9ed3934c68431da838045041fa4a31d

Hello Dmitry. 
Thank you for caring about the issue.
There's another problem again now that the issue is fixed. 
I'll make another bug report for it.
The problem is that some brush tips, especially the complex ones, are showing squares or rectangles instead of the actual brush outline shape.
Comment 7 stephen 2022-06-28 19:07:47 UTC
(In reply to Dmitry Kazakov from comment #5)
> Git commit bef36adac9ed3934c68431da838045041fa4a31d by Dmitry Kazakov.
> Committed on 22/06/2022 at 12:48.
> Pushed by dkazakov into branch 'krita/5.1'.
> 
> Fix a slowdown when Shift+gestrure-resize huge and complex brushes
> 
> This patch does two things:
> 
> 1) Now the brush outline is generated **not** from the real brush tip,
>    generated by generateMaskAndApplyMaskOrCreateDab(), but from the
>    original brushTipImage(). It should generate the same outline, unless
>    any of our brush modes support changing opacity of the brush tip
>    (afaict, none of them support that).
> 
> 2) The outline and pyramid caches are now shared between the source and
>    cloned brush tips. That is, updating a cache inside a cloned brush will
>    also update the cache inside the source brush (in the registry). This
>    decision is a bit scary, but solves really a lot of performance troubles.
>    The link between the two brush objects will be reset only when one of
>    the objects calls `cache.reset()`.
> 
> M  +19   -20   libs/brush/kis_brush.cpp
> M  +139  -16   libs/global/KisLazySharedCacheStorage.h
> 
> https://invent.kde.org/graphics/krita/commit/
> bef36adac9ed3934c68431da838045041fa4a31d

Greetings. 
Also I want to say that the issue is not really fixed.
Because the problem remains  when the brush size is
very complex or around 1700 px.
But there's this brush from the moo ink bundle, called the "moo bubble".
I swear that even right now, only at 150 px, it stutters a freaking lot. 
Because of this, I'll say that there's been an improvement but it's not really fixed completely yet.
Comment 8 stephen 2022-06-28 19:10:10 UTC
If possible, the cursor shouldn't stutter at all.
The rendering on the canvas can be slow, but not the cursor.
I tried to paint in the scratchpad and believe that the performance in the scratchpad is the
expected behavior. 
Because of the stutter, performance in the scratchpad is much faster than on the canvas.
Comment 9 Halla Rempt 2022-06-30 13:10:53 UTC
If you're using very big and very complex brushes, well, your computer is going to have to do a lot of work, and it needs time to do that work: go big and complex enough and rendering a brush outline will always become noticable. You probably should use one of the other cursor options if you're using brushes like that. 

Also, it's not up to the bug reporter to re-open reports developers closed. Please do not do that again.
Comment 10 stephen 2022-06-30 14:13:20 UTC
(In reply to Halla Rempt from comment #9)
> If you're using very big and very complex brushes, well, your computer is
> going to have to do a lot of work, and it needs time to do that work: go big
> and complex enough and rendering a brush outline will always become
> noticeable. You probably should use one of the other cursor options if you're
> using brushes like that. 
> 
> Also, it's not up to the bug reporter to re-open reports developers closed.
> Please do not do that again.

Sorry. I wasn't sure whether I should submit it as "reported" or leave it as it was. 
Though I don't think the cursor alone should cause any lag at all no matter the complexity of the
brush. It's rather the dab/stroke that should be slow if the brush is too complex. 
The lag I observed with the "gauze brush" tip is exactly the same with the "moo bubble" tip.
Even with 100 pixels, it stutters a lot. I'll be making another bug report with the brush causing the stutter.
Comment 11 wolthera 2022-06-30 17:45:57 UTC
*** Bug 456172 has been marked as a duplicate of this bug. ***
Comment 12 stephen 2022-06-30 23:15:00 UTC
Created attachment 150306 [details]
stutter with the moo bubble

(In reply to wolthera from comment #11)
> *** Bug 456172 has been marked as a duplicate of this bug. ***

I should've appended this file here along with the 1st brush causing the stutters. 
I imagined that the 1st fix would solve everything, but after some testing, the issue remains again
on my side with this new brush. If you don't mind and would like to make Krita's brush engine more performant,
here it is. (see moo-animated-brush.bundle for more investigation)
Comment 13 Dmitry Kazakov 2022-07-01 09:03:52 UTC
Git commit 2130f06ac829aa8bedb4f9c85956aa246e75ca44 by Dmitry Kazakov.
Committed on 01/07/2022 at 09:03.
Pushed by dkazakov into branch 'master'.

Fix extremely slow outline rendering with fuzzy brushes

If the brush is very fuzzy, then it may generate too many polygons,
which would make QPainterPath::toSubpathPolygons() extremely slow
(especially on Windows due to slow memory allocations). And since
we call this function on every frame render it may make Krita GUI
stutter a lot.

To workaround this issue this patch implements a special class
KisOptimizedBrushOutline. Its main purpose is to make sure that
the brush outline cache is stored in already prepared format
of QVector<QPolygonF>, so that we wouldn't have to convert
QPainterPath into polygons on every frame generation.

The class also makes sure that the original set of polygons is
immutable, so no extra allocations happen while the outline is
passed from the brush to the GUI rendering code. It is implemented
via storing the transformation and extra paths in separate objects.

M  +2    -1    libs/brush/kis_auto_brush.cpp
M  +1    -1    libs/brush/kis_auto_brush.h
M  +5    -4    libs/brush/kis_brush.cpp
M  +2    -1    libs/brush/kis_brush.h
M  +2    -2    libs/brush/kis_imagepipe_brush.cpp
M  +1    -1    libs/brush/kis_imagepipe_brush.h
M  +1    -0    libs/image/CMakeLists.txt
A  +135  -0    libs/image/brushengine/KisOptimizedBrushOutline.cpp  *
A  +110  -0    libs/image/brushengine/KisOptimizedBrushOutline.h  *
M  +4    -3    libs/image/brushengine/kis_paintop_settings.cpp
M  +3    -2    libs/image/brushengine/kis_paintop_settings.h
M  +4    -4    libs/ui/opengl/KisOpenGLCanvasRenderer.cpp
M  +2    -1    libs/ui/opengl/KisOpenGLCanvasRenderer.h
M  +1    -1    libs/ui/opengl/kis_opengl_canvas2.cpp
M  +2    -1    libs/ui/opengl/kis_opengl_canvas2.h
M  +15   -2    libs/ui/tool/kis_tool.cc
M  +4    -1    libs/ui/tool/kis_tool.h
M  +3    -2    libs/ui/tool/kis_tool_freehand.cc
M  +3    -3    libs/ui/tool/kis_tool_freehand.h
M  +6    -5    libs/ui/tool/kis_tool_freehand_helper.cpp
M  +4    -4    libs/ui/tool/kis_tool_freehand_helper.h
M  +17   -11   libs/ui/tool/kis_tool_paint.cc
M  +6    -5    libs/ui/tool/kis_tool_paint.h
M  +12   -7    plugins/paintops/defaultpaintops/duplicate/kis_duplicateop_settings.cpp
M  +1    -1    plugins/paintops/defaultpaintops/duplicate/kis_duplicateop_settings.h
M  +3    -2    plugins/paintops/deform/kis_deform_paintop_settings.cpp
M  +1    -1    plugins/paintops/deform/kis_deform_paintop_settings.h
M  +3    -1    plugins/paintops/experiment/kis_experiment_paintop_settings.cpp
M  +1    -1    plugins/paintops/experiment/kis_experiment_paintop_settings.h
M  +5    -4    plugins/paintops/gridbrush/kis_grid_paintop_settings.cpp
M  +1    -1    plugins/paintops/gridbrush/kis_grid_paintop_settings.h
M  +2    -1    plugins/paintops/hairy/kis_hairy_paintop_settings.cpp
M  +1    -1    plugins/paintops/hairy/kis_hairy_paintop_settings.h
M  +5    -4    plugins/paintops/libpaintop/kis_brush_based_paintop_settings.cpp
M  +2    -2    plugins/paintops/libpaintop/kis_brush_based_paintop_settings.h
M  +3    -9    plugins/paintops/libpaintop/kis_current_outline_fetcher.cpp
M  +10   -8    plugins/paintops/libpaintop/kis_current_outline_fetcher.h
M  +3    -3    plugins/paintops/mypaint/MyPaintPaintOpSettings.cpp
M  +1    -1    plugins/paintops/mypaint/MyPaintPaintOpSettings.h
M  +3    -3    plugins/paintops/roundmarker/kis_roundmarkerop_settings.cpp
M  +1    -1    plugins/paintops/roundmarker/kis_roundmarkerop_settings.h
M  +4    -4    plugins/paintops/sketch/kis_sketch_paintop_settings.cpp
M  +1    -1    plugins/paintops/sketch/kis_sketch_paintop_settings.h
M  +3    -2    plugins/paintops/spray/kis_spray_paintop_settings.cpp
M  +1    -1    plugins/paintops/spray/kis_spray_paintop_settings.h
M  +1    -0    plugins/tools/basictools/kis_tool_move.cc
M  +1    -1    plugins/tools/selectiontools/KisToolSelectMagnetic.cc
M  +1    -0    plugins/tools/selectiontools/kis_tool_select_path.cc
M  +4    -4    plugins/tools/tool_enclose_and_fill/subtools/KisToolBasicBrushBase.cpp
M  +1    -1    plugins/tools/tool_enclose_and_fill/subtools/KisToolBasicBrushBase.h
M  +1    -0    plugins/tools/tool_transform2/kis_tool_transform.cc

The files marked with a * at the end have a non valid license. Please read: https://community.kde.org/Policies/Licensing_Policy and use the headers which are listed at that page.


https://invent.kde.org/graphics/krita/commit/2130f06ac829aa8bedb4f9c85956aa246e75ca44
Comment 14 Dmitry Kazakov 2022-07-01 09:04:48 UTC
Git commit f58beab329ecc38e2c2472bf69bc5a43bafe7e57 by Dmitry Kazakov.
Committed on 01/07/2022 at 09:04.
Pushed by dkazakov into branch 'krita/5.1'.

Fix extremely slow outline rendering with fuzzy brushes

If the brush is very fuzzy, then it may generate too many polygons,
which would make QPainterPath::toSubpathPolygons() extremely slow
(especially on Windows due to slow memory allocations). And since
we call this function on every frame render it may make Krita GUI
stutter a lot.

To workaround this issue this patch implements a special class
KisOptimizedBrushOutline. Its main purpose is to make sure that
the brush outline cache is stored in already prepared format
of QVector<QPolygonF>, so that we wouldn't have to convert
QPainterPath into polygons on every frame generation.

The class also makes sure that the original set of polygons is
immutable, so no extra allocations happen while the outline is
passed from the brush to the GUI rendering code. It is implemented
via storing the transformation and extra paths in separate objects.

M  +2    -1    libs/brush/kis_auto_brush.cpp
M  +1    -1    libs/brush/kis_auto_brush.h
M  +5    -4    libs/brush/kis_brush.cpp
M  +2    -1    libs/brush/kis_brush.h
M  +2    -2    libs/brush/kis_imagepipe_brush.cpp
M  +1    -1    libs/brush/kis_imagepipe_brush.h
M  +1    -0    libs/image/CMakeLists.txt
A  +135  -0    libs/image/brushengine/KisOptimizedBrushOutline.cpp  *
A  +110  -0    libs/image/brushengine/KisOptimizedBrushOutline.h  *
M  +4    -3    libs/image/brushengine/kis_paintop_settings.cpp
M  +3    -2    libs/image/brushengine/kis_paintop_settings.h
M  +4    -4    libs/ui/opengl/KisOpenGLCanvasRenderer.cpp
M  +2    -1    libs/ui/opengl/KisOpenGLCanvasRenderer.h
M  +1    -1    libs/ui/opengl/kis_opengl_canvas2.cpp
M  +2    -1    libs/ui/opengl/kis_opengl_canvas2.h
M  +15   -2    libs/ui/tool/kis_tool.cc
M  +4    -1    libs/ui/tool/kis_tool.h
M  +3    -2    libs/ui/tool/kis_tool_freehand.cc
M  +3    -3    libs/ui/tool/kis_tool_freehand.h
M  +6    -5    libs/ui/tool/kis_tool_freehand_helper.cpp
M  +4    -4    libs/ui/tool/kis_tool_freehand_helper.h
M  +17   -11   libs/ui/tool/kis_tool_paint.cc
M  +6    -5    libs/ui/tool/kis_tool_paint.h
M  +12   -7    plugins/paintops/defaultpaintops/duplicate/kis_duplicateop_settings.cpp
M  +1    -1    plugins/paintops/defaultpaintops/duplicate/kis_duplicateop_settings.h
M  +3    -2    plugins/paintops/deform/kis_deform_paintop_settings.cpp
M  +1    -1    plugins/paintops/deform/kis_deform_paintop_settings.h
M  +3    -1    plugins/paintops/experiment/kis_experiment_paintop_settings.cpp
M  +1    -1    plugins/paintops/experiment/kis_experiment_paintop_settings.h
M  +5    -4    plugins/paintops/gridbrush/kis_grid_paintop_settings.cpp
M  +1    -1    plugins/paintops/gridbrush/kis_grid_paintop_settings.h
M  +2    -1    plugins/paintops/hairy/kis_hairy_paintop_settings.cpp
M  +1    -1    plugins/paintops/hairy/kis_hairy_paintop_settings.h
M  +5    -4    plugins/paintops/libpaintop/kis_brush_based_paintop_settings.cpp
M  +2    -2    plugins/paintops/libpaintop/kis_brush_based_paintop_settings.h
M  +3    -9    plugins/paintops/libpaintop/kis_current_outline_fetcher.cpp
M  +10   -8    plugins/paintops/libpaintop/kis_current_outline_fetcher.h
M  +3    -3    plugins/paintops/mypaint/MyPaintPaintOpSettings.cpp
M  +1    -1    plugins/paintops/mypaint/MyPaintPaintOpSettings.h
M  +3    -3    plugins/paintops/roundmarker/kis_roundmarkerop_settings.cpp
M  +1    -1    plugins/paintops/roundmarker/kis_roundmarkerop_settings.h
M  +4    -4    plugins/paintops/sketch/kis_sketch_paintop_settings.cpp
M  +1    -1    plugins/paintops/sketch/kis_sketch_paintop_settings.h
M  +3    -2    plugins/paintops/spray/kis_spray_paintop_settings.cpp
M  +1    -1    plugins/paintops/spray/kis_spray_paintop_settings.h
M  +1    -0    plugins/tools/basictools/kis_tool_move.cc
M  +1    -1    plugins/tools/selectiontools/KisToolSelectMagnetic.cc
M  +1    -0    plugins/tools/selectiontools/kis_tool_select_path.cc
M  +4    -4    plugins/tools/tool_enclose_and_fill/subtools/KisToolBasicBrushBase.cpp
M  +1    -1    plugins/tools/tool_enclose_and_fill/subtools/KisToolBasicBrushBase.h
M  +1    -0    plugins/tools/tool_transform2/kis_tool_transform.cc

The files marked with a * at the end have a non valid license. Please read: https://community.kde.org/Policies/Licensing_Policy and use the headers which are listed at that page.


https://invent.kde.org/graphics/krita/commit/f58beab329ecc38e2c2472bf69bc5a43bafe7e57
Comment 15 Dmitry Kazakov 2022-07-01 09:07:59 UTC
Hi, Stephen!

I have fixed the problem that was triggered by the "moo bubble" brush. That stutter should go now. Though I haven't even checked the part of the bug that is related to 1700px brushes, because Krita officially doesn't support brushes bigger that 1000px. Usage of such brushes is "at your own risk" :)
Comment 16 stephen 2022-07-01 12:12:51 UTC
(In reply to Dmitry Kazakov from comment #15)
> Hi, Stephen!
> 
> I have fixed the problem that was triggered by the "moo bubble" brush. That
> stutter should go now. Though I haven't even checked the part of the bug
> that is related to 1700px brushes, because Krita officially doesn't support
> brushes bigger that 1000px. Usage of such brushes is "at your own risk" :)

Thank you a lot Dmitry ! God blesses you!
Also good to know that Krita officially doesn't support brushes bigger than 1000 px.
I wasn't aware of that.
Comment 17 stephen 2022-07-01 23:20:25 UTC
(In reply to Dmitry Kazakov from comment #15)
> Hi, Stephen!
> 
> I have fixed the problem that was triggered by the "moo bubble" brush. That
> stutter should go now. Though I haven't even checked the part of the bug
> that is related to 1700px brushes, because Krita officially doesn't support
> brushes bigger that 1000px. Usage of such brushes is "at your own risk" :)

Alright.
Greetings everyone. 
So after a new test, using krita 5.1.0 beta2 git ef3b190, I can't say that there's a big difference. 
The stutters remains, even just with hovering.
When I paint, and continuously paint for 10s, the cursor freezes on the canvas for those 10s and the rendering will update
many seconds later after I lift my pen. 
It this an expected behavior ?
For the gauze brush, the performance improvement is noticeable.
But with this fuzzy brush, it's not there yet...
Comment 18 stephen 2022-07-02 12:58:42 UTC
(In reply to Dmitry Kazakov from comment #15)
> Hi, Stephen!
> 
> I have fixed the problem that was triggered by the "moo bubble" brush. That
> stutter should go now. Though I haven't even checked the part of the bug
> that is related to 1700px brushes, because Krita officially doesn't support
> brushes bigger that 1000px. Usage of such brushes is "at your own risk" :)

To make sure my test was well performed, I double checked again. 
And this is my experience on Windows : 
1) Hovering doesn't stutter anymore however selecting this fuzzy brush leads to considerable frame drops
even just with hovering.
2) When I use my mouse to paint, the cursor doesn't freeze on the canvas, but the frame drop is even more noticeable as it increases while painting;
3) When I use my pen to paint, the cursor will freeze, the stroke will not render in real time even if it's slow, and I must wait about 3 s after I release my pen before I can see the cursor moving again and the stroke rendered on the canvas. 
4) I confirm that using shift+drag is smooth, but the framerate drop of the GUI seems abnormal.

So yeah. The gui's frame rate drops severly as if what is happening on the canvas is somewhat linked to GUI. 
Sound like a rendering issue overall.
Comment 19 Dmitry Kazakov 2022-07-06 06:52:51 UTC
Hi, @stephen!

Could you please clarify, what brush do you mean by "fuzzy brush"? "moo bubble" or something else?
Comment 20 Protoniv 2022-07-06 07:02:49 UTC
(In reply to Dmitry Kazakov from comment #19)
> Hi, @stephen!
> 
> Could you please clarify, what brush do you mean by "fuzzy brush"? "moo
> bubble" or something else?

Hi Dmitry!
Though not very sure, from what I read from the reply, stephen means "moo bubble" brush IMO
https://krita-artists.org/t/krita-5-1-0-beta-2-the-intolerable-cursor-stutters-continues-despite-a-fix/43484/4
Comment 21 Dmitry Kazakov 2022-07-06 07:51:10 UTC
And one more question: does the framedrop happens **only** when **all** these conditions are met?

1) Some brush sensor (e.g. rotation) is set to "Fuzzy Dab", and
2) The framedrop happens only when the brush stroke is started and the ceases when the stylus is lifted from the tablet surface and starts hovering
Comment 22 Dmitry Kazakov 2022-07-06 10:05:02 UTC
Hi, @stephen!

I couldn't reproduce the exact issue you described. I have fixed a minor slowdown I could find in the profiler, so please check this build when it is completed:

https://binary-factory.kde.org/job/Krita_Stable_Windows_Build/1540/

If you are still able to reproduce any issue with this build, please make a video of it. 

PS:
The fact that FPS drops a bit when you start painting is kind of expected with the current design of the canvas. The point is that the outline is painted alongside the canvas image itself. And when start painting more data on the canvas (the image), then FPS also drops.
Comment 23 Protoniv 2022-07-06 12:04:34 UTC
Hi @Dmitry,
Sorry for my interruption.
I'd like to feedback the performance regression (from my test) after July 1st build on linux (OpenSUSE Leap 15.4).
===============
GPU: Nvidia GT540M ; Intel iGPU (different machine)
test package: 
krita-5.1.0-beta1.appimage
krita-5.1.0-beta2-bd5563bad0.appimage (July 1st)
================
Test brush 1 : b)Basic-2 Opacity -> switch to "moo bubble" brushtip, 500px
Test brush 2 : b)Basic-2 Opacity -> density 25~30%, 500px, Canvas 200%(to get the fuzzy outline)

5.1.0-beta1 : Brush outline "drawing performance" and "hover performance" are quite similar
beta2-bd5563bad0 : Brush outline "drawing performance" is now much slower than "hover performance"

The "hover performance" in these two build are very similar, but "drawing performance" has regression on July 1st build.

#########################

(In reply to Dmitry Kazakov from comment #22)
> PS:
> The fact that FPS drops a bit when you start painting is kind of expected
> with the current design of the canvas. The point is that the outline is
> painted alongside the canvas image itself. And when start painting more data
> on the canvas (the image), then FPS also drops.

About brush outline stuck when start drawing on Windows (Not on linux),
the outline actually stuck several seconds if not release the stylus, in every stroke on my machine (intel iGPU), can be seen in the video in this thread.
https://krita-artists.org/t/krita-5-1-0-beta-2-the-intolerable-cursor-stutters-continues-despite-a-fix/43484/5
I haven't test on pc with Nvidia dGPU yet.
Comment 24 stephen 2022-07-06 17:36:14 UTC
(In reply to Dmitry Kazakov from comment #19)
> Hi, @stephen!
> 
> Could you please clarify, what brush do you mean by "fuzzy brush"? "moo
> bubble" or something else?

Yes Dmitry. It was the "moo bubble" brush.

(In reply to Dmitry Kazakov from comment #21)
> And one more question: does the framedrop happens **only** when **all**
> these conditions are met?
> 
> 1) Some brush sensor (e.g. rotation) is set to "Fuzzy Dab", and
> 2) The framedrop happens only when the brush stroke is started and the
> ceases when the stylus is lifted from the tablet surface and starts hovering

No, there are other conditions where the framedrop happens.
One of these conditions is choosing the "moo bubble" brush and just hovering the cursor without doing anything else.

1) When there's absolutely no sensor active, the framedrop happens(hovering gives framedrops during the test) 
2) The framedrop happens at all time as you hover the cursor.{
2.a : the framedrop is huge while painting with mouse;
2.b : the whole gui freezes when you start a stroke using your pen on Windows;
2.c : The GUI freezing won't stop if you don't lift your pen from the tablet's surface;
2.d : The freezing goes away about 3s after you lift your pen from the tablet's surface. }

Since there are more conditions, the answer is no. 

Matter of fact, compare the following :
I. hovering the cursor of a basic round brush.
II. hovering the cursor of the "moo bubble" brush.

You'll notice that hovering in condition "I" is faster than hovering in condition "II".
Which means, that already with just hovering, there's a framedrop on the canvas if you pick the "moo bubble" brush. 

Years ago, I reported to "halla" that the brush outline cursor would be best if :
A. it was as fast as the system cursor, but he was apparently "too busy".
B. its color was only shifting between black/white, and stays correctly visible no matter the color on the canvas.
But he/she had no clue about the best way to take care of the issue.
Comment 25 Protoniv 2022-07-07 01:37:39 UTC
Created attachment 150455 [details]
Beta1 vs July 6 - Linux hover draw test - moo bubble (Celeron N3060+iGPU)

I'm sorry, after some more test, my linux feedback need some correction
(In reply to Protoniv from comment #23)
> The "hover performance" in these two build are very similar, but "drawing performance" has regression on July 1st build.

> About brush outline stuck when start drawing on Windows (Not on Linux),

Hover performance has improved on Linux, but lower when drawing with drawing tablet. (see attachment)
And it also get stuck when making stroke, with this low end machine.
Don't know if it related to iGPU, both my test setup (Windows/Linux) with iGPU will stuck when drawing with drawing tablet
Comment 26 Protoniv 2022-07-07 01:46:09 UTC
Created attachment 150456 [details]
beta 1 vs July 6 - Linux hover draw test - moo bubble (i7 2670QM+GT540M)

Another Linux test (beta1 vs July 6) on a better machine with dGPU.
Hover improvement is now not that noticeable, and only have framedrop while drawing with tablet.

(In reply to stephen from comment #24)
> Years ago, I reported to "halla" that the brush outline cursor would be best
> if :
> A. it was as fast as the system cursor, 
> B. its color was only shifting between black/white, and stays correctly
> visible no matter the color on the canvas.
This is how Photoshop handle their brush outline, if I remember correctly.
Comment 27 Dmitry Kazakov 2022-07-11 10:58:23 UTC
Hi, Stephen!

> [...] the brush outline cursor would be best if :
> A. it was as fast as the system cursor

It is technically impossible to make the brush outline to be as fast as the system cursor. The outline of the brush will always be slower than the cursor. The reason is easy: the cursor is painted with a special fast-path routine by hardware. And the brush outline is painted by software alongside the canvas painting. We can make it "faster" to some extent, but it will always be several frames slower than the hardware cursor.

> its color was only shifting between black/white, and stays correctly visible no matter the color on the canvas.

That's a different issue, let's not drift from the main topic :)

For Stephen and Protoniv:

I'm afraid I cannot reproduce the regression you report. I tried the two brushes described by Protoniv and both of them work fine with with mouse, stylus+winink, stylus+wintab on Windows.

The video on the forum looks as if Krita has the "Thread limit" set to '1' in the performance preferences. Could you try resetting Krita settings and recheck?

https://docs.krita.org/en/KritaFAQ.html#resetting-krita-configuration
Comment 28 Protoniv 2022-07-11 11:29:36 UTC
(In reply to Dmitry Kazakov from comment #27)
Hi, Dmitry !
> I'm afraid I cannot reproduce the regression you report. I tried the two
> brushes described by Protoniv and both of them work fine with with mouse,
> stylus+winink, stylus+wintab on Windows.
This is... interesting, thanks a lot for your investment anyway :)

> The video on the forum looks as if Krita has the "Thread limit" set to '1'
> in the performance preferences. Could you try resetting Krita settings and
> recheck?
Actually I usually wipe all Krita config files when testing new nighty build.
Have double checked , the "Thread limit" in my Windows machine is 4 (cpu is 2C4T).
Comment 29 stephen 2022-07-11 16:50:59 UTC
(In reply to Dmitry Kazakov from comment #27)
> Hi, Stephen!
> 
> > [...] the brush outline cursor would be best if :
> > A. it was as fast as the system cursor
> 
> It is technically impossible to make the brush outline to be as fast as the
> system cursor. The outline of the brush will always be slower than the
> cursor. The reason is easy: the cursor is painted with a special fast-path
> routine by hardware. And the brush outline is painted by software alongside
> the canvas painting. We can make it "faster" to some extent, but it will
> always be several frames slower than the hardware cursor.
> 
> > its color was only shifting between black/white, and stays correctly visible no matter the color on the canvas.
> 
> That's a different issue, let's not drift from the main topic :)
> 
> For Stephen and Protoniv:
> 
> I'm afraid I cannot reproduce the regression you report. I tried the two
> brushes described by Protoniv and both of them work fine with with mouse,
> stylus+winink, stylus+wintab on Windows.
> 
> The video on the forum looks as if Krita has the "Thread limit" set to '1'
> in the performance preferences. Could you try resetting Krita settings and
> recheck?
> 
> https://docs.krita.org/en/KritaFAQ.html#resetting-krita-configuration

Hello Dmitry.
So, I've reset my settings as suggested, but using the stylus, it's the same.
On my side, the cursor gets stuck while painting with stylus+Wintab and stylus+WinInk.
Comment 30 Dmitry Kazakov 2022-08-02 10:33:09 UTC
Hi, Stephen and Protoniv!

Could you please check two things:

1) Check if the "cursor is stuck while doing a stroke" problem also happens with normal brushes, like "Basic-5 Size"?
2) Could you also make a tablet log for this situation? Just make sure that the log contains a single (failing) stroke not more

Instructions for the log: https://docs.krita.org/en/KritaFAQ.html#what-if-your-tablet-is-not-recognized-by-krita
Comment 31 stephen 2022-08-03 02:45:44 UTC
(In reply to Dmitry Kazakov from comment #27)
> Hi, Stephen!
> 
> > [...] the brush outline cursor would be best if :
> > A. it was as fast as the system cursor
> 
> It is technically impossible to make the brush outline to be as fast as the
> system cursor. The outline of the brush will always be slower than the
> cursor. The reason is easy: the cursor is painted with a special fast-path
> routine by hardware. And the brush outline is painted by software alongside
> the canvas painting. We can make it "faster" to some extent, but it will
> always be several frames slower than the hardware cursor.
> 
> > its color was only shifting between black/white, and stays correctly visible no matter the color on the canvas.
> 
> That's a different issue, let's not drift from the main topic :)

Hello Dmitry and Krita devs.
Hope you're well. 
It's not the main topic, but I want to encourage you by saying that it's not technically impossible to make the outline cursor as fast as the system cursor. 
I believe one solution is to target the function that renders the system cursor, and modify it from Krita by inserting the code logic which draws the brush outline shape in it. This code logic would work in a way that, the outline shape is rendered when the cursor hovers in Krita's viewport area, obviously yes, you probably know this one already. 
Well... if you can use a custom brush cursor icon, then I believe there's a way.
The research required for it would probably consist of finding out, how you can use the hardware fast path routine and hack it in a certain way though. Now, I don't know what exactly are the limits of this method given the available tools in your hands. So there might be another technical constraint I'm not aware of. Just saying. 
Thank you for your hard work.
Comment 32 Dmitry Kazakov 2022-08-05 12:02:14 UTC
Hi, Stephen!

Could you please reply to my questions above? I want to understand whether this bug can be closed or not, since none of us can reproduce this issue.

PS:

About the hardware cursors:

1) Hardware cursors are usually limited to 32 pixels in size
2) They are not dynamic (and our outlines dynamically change their shape depending on the state of the sensors)

If you want to use hardware cursor, just activate "small circle" cursor in Krita settings. It will be hardware-optimized and fast.
Comment 33 stephen 2022-08-06 02:09:42 UTC
Created attachment 151140 [details]
Tablet_log

(In reply to Dmitry Kazakov from comment #32)
> Hi, Stephen!
> 
> Could you please reply to my questions above? I want to understand whether
> this bug can be closed or not, since none of us can reproduce this issue.
> 
> PS:
> 
> About the hardware cursors:
> 
> 1) Hardware cursors are usually limited to 32 pixels in size
> 2) They are not dynamic (and our outlines dynamically change their shape
> depending on the state of the sensors)
> 
> If you want to use hardware cursor, just activate "small circle" cursor in
> Krita settings. It will be hardware-optimized and fast.

Hello Dmitry. 
You're definitely right. No matter what is done, it's impossible to perfectly match the system cursor speed. 
From your return, I decided to make one last test and use CSP to see if it would display the brush cursor shape given that it also possesses the feature in its latest release. Turns out that even without GPU, the software is able to show it. 
And I noticed that there's like a two to 8 pixels distance between the brush cursor and the system cursor in Clip Studio when I hover with very high speed. In conclusion, their code is either very well optimized or they use a lower level approach to make the cursor very very fast.
Still with both my integrated and dedicated GPUs disabled, with a big enough brush size, CSP starts to drop a lot of frames while painting. 
So it's all up to software solution then. Debate can be closed now. Thank you again for being informative.

Now to answer your above questions :

1. Before the tablet log, no the "basic-5-size" brush works fine, be it with stylus or mouse. 
2. With the tablet log on : I couldn't even do anything. 
Hovering freezes the software with the use of the stylus. 
Painting with stylus also freezes the software.
Software won't stop getting frozen until I stop using stylus or stop putting stylus in detection range.
Comment 34 acc4commissions 2022-08-12 16:15:41 UTC
This might not be a good place to ask this very question but is it expected that the hover speed mentioned in the discussion is slower when using tablet pen but faster when using mouse?
Comment 35 Halla Rempt 2022-08-12 18:08:11 UTC
Yes, a pen sends many more events than a mouse. And they need to be handled.
Comment 36 Protoniv 2022-08-16 08:05:34 UTC
Created attachment 151350 [details]
tablet log  (i7 2670QM+GT540M linux machine)

(In reply to Dmitry Kazakov from comment #30)

> 1) Check if the "cursor is stuck while doing a stroke" problem also happens
> with normal brushes, like "Basic-5 Size"?
> 2) Could you also make a tablet log for this situation? Just make sure that
> the log contains a single (failing) stroke not more

Hi, Dmitry, sorry for the late reply!

Re 1: No, it won't get stuck.
Re 2: There seems no fail on this machine (i7 2670QM+GT540M), but this machine also won't get stuck forever by "moo bubble", just have many frame drop. I need to test on another machine later.

Just found one thing on this machine:
If using "moo bubble" or some very complicate brush outline, which will cause frame drop 'when painting', then one CPU thread will be max out at 100%
Comment 37 Protoniv 2022-08-16 08:12:27 UTC
Created attachment 151351 [details]
tablet log (Celeron N3060+igpu linux machine)

Ok, this is the tablet log on a much lower end machine.
Brush outline will get stuck with "moo bubble" and very complex outline (auto brushtip 30% density, zoom canvas 200%, large brush)
When brush outline get stuck, one cpu thread will keep at 100%, until brush outline can move again.
Comment 38 Protoniv 2022-08-17 04:39:02 UTC
Created attachment 151366 [details]
tablet log (Pentium 3825U+igpu Win10 machine)

Here is a tablet test log on my lower end Windows 10 machine.
Testing with a very complex outline (auto brushtip 30% density, zoom canvas 200%, large brush ~800px), 
and outline is getting stuck.

However, Windows 10 is spreading one thread load to all core on Task Manager (have seen this with single core stress test), it is really hard to observe if the "brush outline + drawing tablet" is stuck at single thread speed under windows.
Comment 39 Dmitry Kazakov 2023-01-19 11:57:41 UTC
Git commit 2e81d96f7552d0e760112026eb1a8b7b3bd206f1 by Dmitry Kazakov.
Committed on 19/01/2023 at 11:57.
Pushed by dkazakov into branch 'master'.

Optimize KisOptimizedBrushOutline::boundingRect() further

It does two optimizations:

1) KisOptimizedBrushOutline::boundingRect() is now cached

2) The points accumulation is done in a slightly more efficient
   manner. Now it avoids expensive calls to isEmpty(), right() and
   bottom().

M  +25   -5    libs/global/kis_algebra_2d.h
M  +36   -4    libs/image/brushengine/KisOptimizedBrushOutline.cpp
M  +1    -0    libs/image/brushengine/KisOptimizedBrushOutline.h

https://invent.kde.org/graphics/krita/commit/2e81d96f7552d0e760112026eb1a8b7b3bd206f1
Comment 40 Protoniv 2023-01-20 13:10:58 UTC
Created attachment 155452 [details]
Happened with drawing tablet before and after commit 2e81d96f7552d0e760112026eb1a8b7b3bd206f1

Hi, Dmitry!
Many thanks to your follow up and patches!
I have test today's Nightly build which contains commit 2e81d96f7552d0e760112026eb1a8b7b3bd206f1.
The complex brush outline will still stuck with a stylus, but the "double cursor" (see attachment) seems follow faster, which means the performance have improved, but is still bottlenecked when a stylus signal is fighting single thread resource with the brush outline on lower-end machine.

Another issue appears after commit 2e81d96f7552d0e760112026eb1a8b7b3bd206f1:
When the complex outline hovering to *right* or *bottom* direction, the right or bottom side will be partially cut off, dependng on hover speed and performance, looks like it is not update fast enough with these two direction.
Comment 41 Protoniv 2023-01-21 01:43:53 UTC
> still bottlenecked when a stylus signal is fighting single thread 
> resource with the brush outline on lower-end machine.

I think it might be easier to reproduce single thread bottleneck issue with CPU frequency cap, which is easier to adjust on Windows 10.
Search "Edit Power Plan" and enter -> Change advanced power setting -> find "Processor power management" -> change the "Maximum processor state" to lower than 100% and apply, the cpu frequency will be capped at "base-clock * x%"
Comment 42 amyspark 2023-01-31 16:12:57 UTC
Reopening as the fix for this is causing 465086.