Bug 458475

Summary: Performance highly degraded with filters
Product: [Applications] krita Reporter: grum999
Component: Layer StackAssignee: Dmitry Kazakov <dimula73>
Status: RESOLVED FIXED    
Severity: normal CC: dimula73, halla, tomtomtomreportingin
Priority: NOR Keywords: triaged
Version First Reported In: nightly build (please specify the git hash!)   
Target Milestone: ---   
Platform: Other   
OS: Linux   
Latest Commit: Version Fixed/Implemented In:
Sentry Crash Report:
Attachments: video example of execution times
File used in example video

Description grum999 2022-08-29 16:23:33 UTC
SUMMARY
For a simple combination of filters, Krita took 10minutes to refresh document....


STEPS TO REPRODUCE
1. Create a document large enough (7000x5000)
2. Add a group layer "G1"
3. In group layer "G1", add a paint layer "PL1"; fill it with a color 
4. On paint layer "PL1", add a transform mask ("mesh transform") "TM1"
5. In group layer "G1", add a filter layer "FL1" (type gaussian blur with default value of 5pixels)
6. Select paint layer "PL1"
7. Fill it with another color

OBSERVED RESULT
From step 7, it took ~10minutes of "updating" process on my computer...

EXPECTED RESULT
The gaussian filter normally took a second to be applied
The transform mask normally took 2-3 second to be applied 

Combination of both shouldn't take 10minutes to be applied


SOFTWARE/OS VERSIONS
Krita

 Version: 5.2.0-prealpha (git 785619b)
 Hidpi: false

Qt

  Version (compiled): 5.12.12
  Version (loaded): 5.12.12

OS Information

  Build ABI: x86_64-little_endian-lp64
  Build CPU: x86_64
  CPU: x86_64
  Kernel Type: linux
  Kernel Version: 4.19.0-21-amd64
  Pretty Productname: Debian GNU/Linux 10 (buster)
  Product Type: debian
  Product Version: 10
  Desktop: KDE

Hardware Information

  GPU Acceleration: auto
  Memory: 64389 Mb
  Number of Cores: 24
  Swap Location: /tmp
  Built for: sse2
  Base instruction set: sse2
  Supported instruction sets: fma3+avx2 avx2 fma3+avx avx fma4 fma3+sse4.2 sse4.2 sse4.1 ssse3 sse3 sse2 

Current Settings

  Current Swap Location: /tmp
  Current Swap Location writable: true
  Undo Enabled: true
  Undo Stack Limit: 350
  Use OpenGL: true
  Use OpenGL Texture Buffer: true
  Disable Vector Optimizations: false
  Disable AVX Optimizations: false
  Canvas State: OPENGL_SUCCESS
  Autosave Interval: 600
  Use Backup Files: true
  Number of Backups Kept: 4
  Backup File Suffix: ~
  Backup Location: Same Folder as the File
  Backup Location writable: false
  Use Win8 Pointer Input: false
  Use RightMiddleTabletButton Workaround: false
  Levels of Detail Enabled: false
  Use Zip64: false

ADDITIONAL INFORMATION
It can be reproduced with different combination of filter layer, filter mask, transform mask...
This combination is really representative of problem (some other combination like 2 gaussian filters are less visible)
Comment 1 grum999 2022-08-29 16:31:38 UTC
Note: there's different case for which the problem occurs 

Seven (with more or less performances impact) are described here:
https://krita-artists.org/t/locking-unlocking-layer-does-it-need-to-recompute-everything/46462/8?u=grum999

Grum999
Comment 2 Halla Rempt 2022-09-05 09:49:22 UTC
I'm sorry, but I don't see any performance different between 5.0.6 and git master here.
Comment 3 grum999 2022-09-05 09:55:19 UTC
Hi

My bug declaration is not good, sorry :( 

The problem might occurs from a long time, didn't tried it on prior version to 5.1.0 
But I think there's a problem as 2 operation that just take a couple of second when applied independently needs 10minutes when applied in the same layer stack...

After maybe problems occurs only on my side, I don't know
I unfortunately got no feedback from KA about this case


Grum999
Comment 4 Halla Rempt 2022-09-05 10:02:57 UTC
I was actually surprised myself at how fast it was on this, admittedly, very fast PC...
Comment 5 grum999 2022-09-05 11:57:02 UTC
Created attachment 151826 [details]
video example of execution times

I've attached a recording video of my Krita window, with timer clock (displaying seconds) visible

Video is 12minutes long, so quality is not really good as it should not be too big to be updated.
Looking all video is useless, here the interesting part:
- 00:00:00 to 00:00:20 ==> we can see that applying transform mask took ~9s and gaussian blur mask (100px) ~2s
- 00:00:27 to 00:00:40 ==> we can see that filling canvas with only transform tool active takes ~13s to update everything (fill+transform)
- 00:00:50 to 00:11:45 ==>  we can see that filling canvas with transform tool active + gaussian blur takes ~11minutes to update everything (fill+transform)

Expected total time: 13s + 2s = ~15s :-) 
Real total time: 11minutes :-(

Tested on 5.2.0-prealpha (git 785619b)


Grum999
Comment 6 grum999 2022-09-05 12:51:33 UTC
Updated bug to refer v5.2

Grum999
Comment 7 Halla Rempt 2022-09-07 09:00:54 UTC
Could you maybe also upload the actual .kra file?
Comment 8 grum999 2022-09-07 09:19:16 UTC
Created attachment 151883 [details]
File used in example video

Hi

Yes of course, here the Krita file I used for my video example

Grum999
Comment 9 Halla Rempt 2022-09-07 09:42:37 UTC
Hm, one interesting difference with my test is that I created a filter layer as per steps to reproduce, and this file actually has a filter mask on the group layer. With a filter layer inside the group everything is pretty fast, with this file and a filter mask on the group, I can reproduce the slowness.
Comment 10 Halla Rempt 2022-09-07 09:43:44 UTC
I also see an abnormal memory consumption of Krita: it quickly rises to 2.8 GB when putting a gradient on the paint layer.
Comment 11 Raghavendra kamath 2022-09-22 18:23:20 UTC
*** Bug 459517 has been marked as a duplicate of this bug. ***
Comment 12 Dmitry Kazakov 2023-04-25 12:48:39 UTC
Git commit faee475b16081146c760aa2ff33aca48a03d26d5 by Dmitry Kazakov.
Committed on 25/04/2023 at 12:48.
Pushed by dkazakov into branch 'master'.

Fix a huge slowdown with mesh transform added as a transform mask

The Mesh Transform used to have very rough approximations for needRect
and changeRect functions (basically, all touched patches were dragged
into the changeRect). It caused each update thread to update the whole
image, instead of its own part of it (which was slow).

The patch introduces a better approximation of need/changeRects using
a binary search in the param space followed by random rect sampling.

M  +1    -0    libs/global/CMakeLists.txt
A  +215  -0    libs/global/KisBezierPatchParamSpaceUtils.h     [License: GPL(v2.0+)]
A  +82   -0    libs/global/KisBezierPatchParamToSourceSampler.h     [License: GPL(v2.0+)]
M  +1    -1    libs/global/KisBezierUtils.h
M  +17   -0    libs/global/KisCppQuirks.h
A  +80   -0    libs/global/KisSampleRectIterator.cpp     [License: GPL(v2.0+)]
A  +69   -0    libs/global/KisSampleRectIterator.h     [License: GPL(v2.0+)]
M  +12   -0    libs/global/kis_algebra_2d.h
M  +170  -12   libs/image/KisBezierTransformMesh.cpp
M  +9    -0    libs/image/KisBezierTransformMesh.h
M  +0    -1    libs/image/kis_transform_mask.cpp
M  +192  -0    libs/image/tests/kis_mesh_transform_worker_test.cpp
M  +8    -0    libs/image/tests/kis_mesh_transform_worker_test.h
M  +16   -0    sdk/tests/testutil.h

https://invent.kde.org/graphics/krita/commit/faee475b16081146c760aa2ff33aca48a03d26d5
Comment 13 grum999 2023-05-09 16:53:03 UTC
Hi

Don't know if I have to reopen or not the bug.

I'm testing the appimage build from 45dfa5f, for which I think the commit faee475b16081146c760aa2ff33aca48a03d26d5 is talen in account

Opening the attached document 

CASE A: let gaussian filter mask not visible/not applied
1) Change visibility of transform mask --> not visible to visible  
==> krita become unresponsive during approximately 55seconds before layer transform is applied and visible on canvas
==> on previous version, it took a couple of seconds to be applied
2) Change visibility of transform mask --> visible to not visible  
==> krita become unresponsive during approximately 50seconds before layer transform is removed and visible on canvas
==> on previous version, it took a couple of seconds to be unapplied

>> In comparison to previous version, performances are highly degraded just for transform mask.

CASE B: set gaussian filter mask visible/applied
1) Change visibility of transform mask --> not visible to visible  
==> krita become unresponsive during approximately 5minutes before layer transform is applied and visible on canvas
==> on previous version, it took ~10minutes
2) Change visibility of transform mask --> visible to not visible  
==> krita become unresponsive during approximately 5minutes before layer transform is applied and visible on canvas

So performances has been improved in the second case but:
- In first case (just transform mask) it became really worse 
- In second case, it still weird (from a user point of view) to understand how 2 operations that individually take a couple of seconds need a long couple of minutes to be applied sequentially


Do I have to reopen the bug, or it's better to create a new one?

---Note: computer spec are unchanged, tested bug fix on the same computer 


Grum999
Comment 14 Dmitry Kazakov 2023-05-10 12:05:02 UTC
Let's reopen it for now, until I check your notes.
Comment 15 grum999 2023-05-10 15:52:39 UTC
Hi

Ok thanks

Here are some additional comparison tests made between, provided under a table; should be easier to read :-) 

- Krita 5.2 - krita-5.2.0-prealpha-9cb8ac659f-x86_64.appimage (2022-11-26)
- Krita 5.2 - krita-5.2.0-prealpha-45dfa5f2ee-x86_64.appimage (2023-05-??)
Using document `test_bugs_lockunlock--case03.kra` provided as attachement

> | Action                                  | 9cb8ac659f | 45dfa5f2ee   |
> | 1) Open file                            |            |              |
> | 2) Set transform mask visibility=yes    | ~9s        | ~55s (~38s*) |
> | 3) Set transform mask visibility=no     | immediate  | ~50s (~37s*) |
> | 4) Set filter mask visibility=yes       | ~2s        | ~2s          |
> | 5) Set filter mask visibility=no        | immediate  | immediate    |
> | 6) Set filter mask visibility=yes       | ~2s        | ~2s          |
> | 7) Fill layer (SHIFT+BACKSPACE)         | ~2s        | ~2s          |
> | 8) Set filter mask visibility=no        | immediate  | immediate    |
> | 9) Set transform mask visibility=yes    | ~9s        | ~55s (~38s*) |
> |10) Fill layer (SHIFT+BACKSPACE)         | ~12s       |              |
> |11) Set filter mask visibility=yes       | ~10min**   | ~5min**      |
> |12) Fill layer (SHIFT+BACKSPACE)         | ~10min**   | ~25s         |

*  Second indicated time is delay between click on "eye icon" in layer stack and update of icon in layer stack; during this delay, Krita is totaly unresponsive (after it start to become responsive again with high slowness)
** Not courageaous enough to make again tests for case "filter mask visibility=yes + Set transform mask visibility=yes"; this what I see from previous tests

In settings, I use the 24CPU
If I reduce number of CPU to 2, process is longer on both appimage

I've made test on another computer (my laptop) for which performances are powerless (16CPU); it's longuer too :) 


So the last tested step (number 12) there's a high improvement
But all previous steps (especially 2, 3, 9, 11) are not really good


Grum999
Comment 16 grum999 2023-05-10 15:54:51 UTC
For test 11:
> |11) Set filter mask visibility=yes       | ~10min**   | ~5min        |

Grum999
Comment 17 Dmitry Kazakov 2023-05-16 15:01:23 UTC
Git commit a92c1c611a385f01dff51af64672bdc9c131ccd3 by Dmitry Kazakov.
Committed on 16/05/2023 at 15:01.
Pushed by dkazakov into branch 'master'.

Fix too slow computation of the needRect for the mest transform masks

That was a misprint: we should use the minimal limit

M  +1    -1    libs/image/KisBezierTransformMesh.cpp

https://invent.kde.org/graphics/krita/commit/a92c1c611a385f01dff51af64672bdc9c131ccd3
Comment 18 Dmitry Kazakov 2023-05-16 15:02:40 UTC
Hi, grum999!

The bug should be fixed now, please check the following build:

https://binary-factory.kde.org/job/Krita_Nightly_Appimage_Build/2006/

(it should also include the VM-screen detection crash)
Comment 19 grum999 2023-05-18 12:23:22 UTC
Aaaahh yyess!!
It's perfect :-) 

Execution times are now as expected!!

Many thank :)


Grum999