Bug 449964

Summary: Rendering error when using many Clone Layers with Transform Masks
Product: [Applications] krita Reporter: Bek <plumfumble>
Component: Tools/TransformAssignee: Krita Bugs <krita-bugs-null>
Status: RESOLVED FIXED    
Severity: critical CC: griffinvalley
Priority: NOR    
Version: 5.0.2   
Target Milestone: ---   
Platform: Other   
OS: Microsoft Windows   
Latest Commit: Version Fixed In:
Sentry Crash Report:
Attachments: Example file, where at least 2 users have had similar results.

Description Bek 2022-02-10 19:19:33 UTC
Created attachment 146548 [details]
Example file, where at least 2 users have had similar results.

SUMMARY
Rendering error when using many Clone Layers with Transform Masks


STEPS TO REPRODUCE
1.  Have a group layer with raster layers to clone.
2.  Create many clones of this group layer, each with transform masks, which have a Warp transform done to them.
3.  Save the file, close Krita.
4. Open the file in Krita again.

OBSERVED RESULT
Some layers will not render at all, and the ones that do tend to have some errors (some looking like they are partially erased, not possible with clone layers). Turning off and on the visibility of a parent layer to the clones may lead to some more layers becoming visible again, but still not all, and still tend to have errors. Which clone layers are visible changes in some random way every time the parent of the clone layers is set to visible, or every time the file is opened. The layers are there, as when entering transform mode on a clone layer's transform mask, the Warp Control points are in the right spot, and if the transform mask is set to invisible, the layer appears where it should be.

EXPECTED RESULT
All of the clone layers appear in their place, affected by their transform masks, without unintended distortions.

SOFTWARE/OS VERSIONS
Windows: Windows 10

ADDITIONAL INFORMATION
Note -- This is different from Bug ID 407383 in that Krita "finishes" the calculations necessary, and lets you take other actions, such as saving.
There is some explanation that seems more clear found on the krita-artists.org forum post I made for this, made by another user. https://krita-artists.org/t/clone-layer-transform-mask-not-rendering-not-animation/36654/4
Comment 1 wolthera 2022-02-10 19:37:53 UTC
OK, can confirm.

So, we could flip back and forth about whether or not warp transform should take time, as the primary bug here seems to be that saved Kra files just load incorrectly somehow. That *is* a data-loss error, therefore setting this to critical.

Interestingly, if I play around with the options: Clone layer 36 is a layer with a warp transform mask, when I try editing it, the mask doesn't show any effect. However, when I set the preview option to 'fast', the editing does show a preview, however, applying it, and the layer contents become invisible again, which very much is a bug. I guess there's something going on with the proper-application of the transform if the accurate preview and final result don't show.
Comment 2 Dmitry Kazakov 2024-08-22 16:38:46 UTC
Remove triaged keyword from CONFIRMED bugs
Comment 3 Dmitry Kazakov 2024-09-10 14:28:30 UTC
Git commit 1e0e095b69513d9a9d0a9b53c0512f50e3fc7977 by Dmitry Kazakov.
Committed on 10/09/2024 at 14:27.
Pushed by dkazakov into branch 'master'.

Fix incorrect threaded image access in multiple clone layers

We used to do an additional KisAsyncMerger pass in KisUpdateOriginalVisitor,
which could cause the walker to go out of its declared accessRect().
It could happen when the source layer had transform masks with non-
affine transformations. For such transformations, needRect depends on
the extent() of the parent layer, hence accessRect() may change between
the walker pass and the async merger pass.

Now the design is slightly changed. The source layers of the clones
are added to the main pass of the walker, so they are processed in the
same async merger and their application rect is guaranteed to stay
stable.

M  +1    -0    libs/image/CMakeLists.txt
M  +10   -59   libs/image/kis_async_merger.cpp
M  +0    -8    libs/image/kis_async_merger.h
A  +114  -0    libs/image/kis_base_rects_walker.cpp     [License: GPL(v2.0+)]
M  +39   -14   libs/image/kis_base_rects_walker.h
M  +8    -4    libs/image/kis_full_refresh_walker.h
M  +3    -3    libs/image/kis_merge_walker.cc
M  +26   -53   libs/image/kis_refresh_subtree_walker.h
M  +99   -14   libs/image/tests/kis_walkers_test.cpp
M  +2    -0    libs/image/tests/kis_walkers_test.h

https://invent.kde.org/graphics/krita/-/commit/1e0e095b69513d9a9d0a9b53c0512f50e3fc7977
Comment 4 Dmitry Kazakov 2024-09-10 14:29:23 UTC
Git commit f3aa706299df82c3cc045dfd20a721bf1be546db by Dmitry Kazakov.
Committed on 10/09/2024 at 14:28.
Pushed by dkazakov into branch 'krita/5.2'.

Fix incorrect threaded image access in multiple clone layers

We used to do an additional KisAsyncMerger pass in KisUpdateOriginalVisitor,
which could cause the walker to go out of its declared accessRect().
It could happen when the source layer had transform masks with non-
affine transformations. For such transformations, needRect depends on
the extent() of the parent layer, hence accessRect() may change between
the walker pass and the async merger pass.

Now the design is slightly changed. The source layers of the clones
are added to the main pass of the walker, so they are processed in the
same async merger and their application rect is guaranteed to stay
stable.

M  +1    -0    libs/image/CMakeLists.txt
M  +10   -59   libs/image/kis_async_merger.cpp
M  +0    -8    libs/image/kis_async_merger.h
A  +114  -0    libs/image/kis_base_rects_walker.cpp     [License: GPL(v2.0+)]
M  +39   -14   libs/image/kis_base_rects_walker.h
M  +8    -4    libs/image/kis_full_refresh_walker.h
M  +3    -3    libs/image/kis_merge_walker.cc
M  +26   -53   libs/image/kis_refresh_subtree_walker.h
M  +99   -14   libs/image/tests/kis_walkers_test.cpp
M  +2    -0    libs/image/tests/kis_walkers_test.h

https://invent.kde.org/graphics/krita/-/commit/f3aa706299df82c3cc045dfd20a721bf1be546db