Bug 443766

Summary: Continuously Updating (non animated)Transform Masks
Product: [Applications] krita Reporter: Ahab Greybeard <ahab.greybeard>
Component: Layer StackAssignee: Dmitry Kazakov <dimula73>
Status: RESOLVED FIXED    
Severity: normal CC: dimula73, halla, matt.coudert, michelist.tracksbugs
Priority: NOR    
Version: nightly build (please specify the git hash!)   
Target Milestone: ---   
Platform: Debian stable   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:
Attachments: Example for testing

Description Ahab Greybeard 2021-10-15 07:23:52 UTC
Created attachment 142459 [details]
Example for testing

SUMMARY
This affects all versions from 4.4.7 onwards, including the latest Oct 14 5.1.0-prealpha (git 5441a29) appimages.

An example file (Cycling-Transform-Masks.kra) is attached.

If a group has a layer with a transform mask on it, then the group is cloned and a transform mask is applied to the clone layer, the transform masks continuously update.

STEPS TO REPRODUCE
1. Open the attached 'Cycling-Transform-Masks.kra file' and observe the layers docker indication of layer activity.
2. Turn off the visibility of the Clone layer transform mask and wait.
3. Turn on the visibility of the Clone layer transform mask and wait.
4. Make any change to the paint layer such as painting in it.
5. Do Steps 2 and 3 to stop the cycling updates.
6. Turn off visibility of the paint layer transform mask and wait.
7. Turn on visibility of the paint layer transform mask.

OBSERVED RESULT
1. The transform masks both update every four seconds.
2. The transform masks stop updating after one or two cycles of activity on the still visible transform mask.
3. There are one or two cycles of activity then the they stop updating.
4. The cycling updates start again.
5. The cycling stops.
6. After one or two updates, the cycling stops.
7. The cycling starts again.

With two paint layers in the group, or a paint layer and a vector layer, both with transform masks, the update cycling takes up most of the time and it's difficult or impossible to do any further work on the image.

EXPECTED RESULT
The masks should not continuously update.

SOFTWARE/OS VERSIONS
Krita

 Version: 5.1.0-prealpha (git 5441a29)
 Languages: en_GB, en, en, en_GB, en
 Hidpi: false

Qt

  Version (compiled): 5.12.11
  Version (loaded): 5.12.11

OS Information

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

OpenGL Info
 
  Vendor:  "NVIDIA Corporation" 
  Renderer:  "GeForce GTX 750 Ti/PCIe/SSE2" 
  Version:  "4.6.0 NVIDIA 460.73.01" 
  Shading language:  "4.60 NVIDIA" 
  Requested format:  QSurfaceFormat(version 3.0, options QFlags<QSurfaceFormat::FormatOption>(DeprecatedFunctions), depthBufferSize 24, redBufferSize 8, greenBufferSize 8, blueBufferSize 8, alphaBufferSize 8, stencilBufferSize 8, samples -1, swapBehavior QSurfaceFormat::DoubleBuffer, swapInterval 0, colorSpace QSurfaceFormat::DefaultColorSpace, profile  QSurfaceFormat::CompatibilityProfile) 
  Current format:    QSurfaceFormat(version 4.6, options QFlags<QSurfaceFormat::FormatOption>(DeprecatedFunctions), depthBufferSize 24, redBufferSize 8, greenBufferSize 8, blueBufferSize 8, alphaBufferSize 8, stencilBufferSize 8, samples -1, swapBehavior QSurfaceFormat::DoubleBuffer, swapInterval 0, colorSpace QSurfaceFormat::DefaultColorSpace, profile  QSurfaceFormat::CompatibilityProfile) 
     Version: 4.6
     Supports deprecated functions true 
     is OpenGL ES: false 
  supportsBufferMapping: true 
  supportsBufferInvalidation: true 

QPA OpenGL Detection Info 
  supportsDesktopGL: true 
  supportsOpenGLES: true 
  isQtPreferOpenGLES: false 

useBufferInvalidation (config option): false


Hardware Information

  GPU Acceleration: auto
  Memory: 16039 Mb
  Number of Cores: 8
  Swap Location: /tmp

Current Settings

  Current Swap Location: /tmp
  Current Swap Location writable: true
  Undo Enabled: true
  Undo Stack Limit: 30
  Use OpenGL: true
  Use OpenGL Texture Buffer: true
  Disable Vector Optimizations: false
  Disable AVX Optimizations: false
  Canvas State: OPENGL_SUCCESS
  Autosave Interval: 900
  Use Backup Files: true
  Number of Backups Kept: 1
  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
Comment 1 Halla Rempt 2022-06-28 12:35:03 UTC
I'm sorry for the late reply, but I don't see this happening with master 958a8d7aafd7ac6f693f677cc5be052d60a85b07
Comment 2 Ahab Greybeard 2022-06-28 14:06:31 UTC
I've just tried it and see it happening with the 5.1.0-beta1 and Jun 27th 5.2.0-prealpha (git 7d765f9da2) appimages on Debian 10.
Then I see it with the 5.1.0-beta1 and Jun 28th 5.2.0-prealpha (git d771a56323) portable .zip packages on Windows 10.

I'll ask on the forum to see if it's just me and my old desktop PC.
Comment 3 mako_matt 2022-06-28 15:02:18 UTC
i can confirm the same behavior on Windows 10 with krita 5.1.0 beta1 and krita-nightly-x64-5.2.0-prealpha-d771a56323
Comment 4 mako_matt 2022-06-28 15:06:43 UTC
(In reply to mcoudert from comment #3)
> i can confirm the same behavior on Windows 10 with krita 5.1.0 beta1 and
> krita-nightly-x64-5.2.0-prealpha-d771a56323

On windows 11 sorry
Comment 5 Michael Strothotte 2022-06-28 15:36:02 UTC
The activities of the Transform masks described by Ahab also happen to me with the 5.2.0 prealpha (git 0f478fc) and Windows 10. 

Michael Strothotte/Michelist

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

Krita

 Version: 5.2.0-prealpha (git 0f478fc)
 Installation type: installer / portable package
 Hidpi: true

Qt

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

OS Information

  Build ABI: x86_64-little_endian-llp64
  Build CPU: x86_64
  CPU: x86_64
  Kernel Type: winnt
  Kernel Version: 10.0.19044
  Pretty Productname: Windows 10 (10.0)
  Product Type: windows
  Product Version: 10

Locale

  Languages: de, en_US
  C locale: C
  QLocale current: de
  QLocale system: de
  QTextCodec for locale: UTF-8
  Process ACP: 65001 (UTF-8)
  System locale default ACP: 1252  (ANSI - Lateinisch I)

OpenGL Info
 
  Vendor:  "Google Inc. (AMD)" 
  Renderer:  "ANGLE (AMD, Radeon RX 580 Series Direct3D11 vs_5_0 ps_5_0, D3D11-30.0.15021.11005)" 
  Version:  "OpenGL ES 3.0.0 (ANGLE 2.1.0 git hash: f2280c0c5f93+krita_qt5.12.12)" 
  Shading language:  "OpenGL ES GLSL ES 3.00 (ANGLE 2.1.0 git hash: f2280c0c5f93+krita_qt5.12.12)" 
  Requested format:  QSurfaceFormat(version 3.0, options QFlags<QSurfaceFormat::FormatOption>(DeprecatedFunctions), depthBufferSize 24, redBufferSize 8, greenBufferSize 8, blueBufferSize 8, alphaBufferSize 8, stencilBufferSize 8, samples -1, swapBehavior QSurfaceFormat::DoubleBuffer, swapInterval 0, colorSpace QSurfaceFormat::DefaultColorSpace, profile  QSurfaceFormat::CompatibilityProfile) 
  Current format:  QSurfaceFormat(version 3.0, options QFlags<QSurfaceFormat::FormatOption>(), depthBufferSize 24, redBufferSize 8, greenBufferSize 8, blueBufferSize 8, alphaBufferSize 8, stencilBufferSize 8, samples 0, swapBehavior QSurfaceFormat::DefaultSwapBehavior, swapInterval 0, colorSpace QSurfaceFormat::DefaultColorSpace, profile  QSurfaceFormat::NoProfile) 
     Version: 3.0
     Supports deprecated functions false 
     is OpenGL ES: true 
  supportsBufferMapping: true 
  supportsBufferInvalidation: false 
  forceDisableTextureBuffers: true 
  Extensions: 
     "GL_ANGLE_provoking_vertex" 
     "GL_OES_EGL_image_external" 
     "GL_EXT_texture_compression_rgtc" 
     "GL_ANGLE_instanced_arrays" 
     "GL_OES_texture_float" 
     "GL_ANGLE_memory_size" 
     "GL_OES_texture_border_clamp" 
     "GL_NV_framebuffer_blit" 
     "GL_KHR_parallel_shader_compile" 
     "GL_OES_compressed_EAC_R11_unsigned_texture" 
     "GL_EXT_color_buffer_half_float" 
     "GL_ANGLE_copy_texture_3d" 
     "GL_ANGLE_texture_usage" 
     "GL_OES_texture_half_float_linear" 
     "GL_ANGLE_framebuffer_blit" 
     "GL_CHROMIUM_bind_generates_resource" 
     "GL_OES_standard_derivatives" 
     "GL_EXT_draw_elements_base_vertex" 
     "GL_EXT_texture_norm16" 
     "GL_EXT_texture_filter_anisotropic" 
     "GL_OES_compressed_EAC_R11_signed_texture" 
     "GL_ANGLE_client_arrays" 
     "GL_EXT_debug_marker" 
     "GL_OES_EGL_image" 
     "GL_EXT_occlusion_query_boolean" 
     "GL_ANGLE_multi_draw" 
     "GL_ANGLE_depth_texture" 
     "GL_ANGLE_texture_compression_dxt3" 
     "GL_OES_compressed_ETC2_RGBA8_texture" 
     "GL_ANGLE_framebuffer_multisample" 
     "GL_ANGLE_robust_client_memory" 
     "GL_EXT_unpack_subimage" 
     "GL_OES_compressed_ETC2_punchthroughA_sRGB8_alpha_texture" 
     "GL_EXT_shader_texture_lod" 
     "GL_OES_mapbuffer" 
     "GL_OES_compressed_ETC2_sRGB8_texture" 
     "GL_OES_get_program_binary" 
     "GL_OES_vertex_array_object" 
     "GL_OES_packed_depth_stencil" 
     "GL_ANGLE_request_extension" 
     "GL_OES_rgb8_rgba8" 
     "GL_EXT_texture_compression_bptc" 
     "GL_OES_compressed_ETC2_RGB8_texture" 
     "GL_OES_fbo_render_mipmap" 
     "GL_OVR_multiview" 
     "GL_WEBGL_video_texture" 
     "GL_EXT_blend_func_extended" 
     "GL_EXT_float_blend" 
     "GL_OES_depth24" 
     "GL_CHROMIUM_sync_query" 
     "GL_OES_compressed_EAC_RG11_unsigned_texture" 
     "GL_AMD_performance_monitor" 
     "GL_EXT_robustness" 
     "GL_ANGLE_multiview_multisample" 
     "GL_EXT_texture_compression_s3tc_srgb" 
     "GL_OES_EGL_image_external_essl3" 
     "GL_EXT_read_format_bgra" 
     "GL_EXT_instanced_arrays" 
     "GL_EXT_color_buffer_float" 
     "GL_ANGLE_pack_reverse_row_order" 
     "GL_OES_compressed_ETC2_punchthroughA_RGBA8_texture" 
     "GL_EXT_texture_rg" 
     "GL_EXT_debug_label" 
     "GL_OVR_multiview2" 
     "GL_ANGLE_base_vertex_base_instance" 
     "GL_EXT_blend_minmax" 
     "GL_EXT_map_buffer_range" 
     "GL_OES_element_index_uint" 
     "GL_EXT_EGL_image_external_wrap_modes" 
     "GL_EXT_discard_framebuffer" 
     "GL_OES_texture_float_linear" 
     "GL_ANGLE_lossy_etc_decode" 
     "GL_ANGLE_translated_shader_source" 
     "GL_EXT_sRGB" 
     "GL_OES_draw_elements_base_vertex" 
     "GL_OES_texture_half_float" 
     "GL_CHROMIUM_copy_compressed_texture" 
     "GL_OES_draw_buffers_indexed" 
     "GL_CHROMIUM_copy_texture" 
     "GL_EXT_draw_buffers" 
     "GL_EXT_texture_storage" 
     "GL_CHROMIUM_bind_uniform_location" 
     "GL_EXT_texture_format_BGRA8888" 
     "GL_EXT_texture_type_2_10_10_10_REV" 
     "" 
     "GL_OES_compressed_EAC_RG11_signed_texture" 
     "GL_ANGLE_get_serialized_context_string" 
     "GL_EXT_draw_buffers_indexed" 
     "GL_OES_surfaceless_context" 
     "GL_OES_depth32" 
     "GL_ANGLE_program_cache_control" 
     "GL_EXT_multi_draw_indirect" 
     "GL_ANGLE_texture_multisample" 
     "GL_NV_pack_subimage" 
     "GL_ANGLE_base_vertex_base_instance_shader_builtin" 
     "GL_ANGLE_texture_compression_dxt5" 
     "GL_EXT_frag_depth" 
     "GL_NV_EGL_stream_consumer_external" 
     "GL_OES_texture_npot" 
     "GL_OES_texture_stencil8" 
     "GL_EXT_texture_compression_dxt1" 
     "GL_NV_fence" 
     "GL_ANGLE_get_tex_level_parameter" 
     "GL_CHROMIUM_lose_context" 
     "GL_EXT_clip_control" 
     "GL_EXT_multisampled_render_to_texture" 
     "GL_KHR_debug" 
     "GL_OES_compressed_ETC2_sRGB8_alpha8_texture" 
     "GL_EXT_disjoint_timer_query" 
     "GL_NV_pixel_buffer_object" 

QPA OpenGL Detection Info 
  supportsDesktopGL: true 
  supportsAngleD3D11: true 
  isQtPreferAngle: true 

useBufferInvalidation (config option): false


Hardware Information

  GPU Acceleration: angle
  Memory: 98227 Mb
  Number of Cores: 24
  Swap Location: D:/_TEMP
  Built for: sse2
  Base instruction set: sse2
  Supported instruction sets: sse4.2 sse4.1 ssse3 sse3 sse2 

Current Settings

  Current Swap Location: D:/_TEMP
  Current Swap Location writable: true
  Undo Enabled: true
  Undo Stack Limit: 200
  Use OpenGL: true
  Use OpenGL Texture Buffer: true
  Disable Vector Optimizations: false
  Disable AVX Optimizations: false
  Canvas State: OPENGL_SUCCESS
  Autosave Interval: 900
  Use Backup Files: true
  Number of Backups Kept: 5
  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


Display Information
Number of screens: 2
	Screen: 0
		Name: \\.\DISPLAY1
		Depth: 32
		Scale: 2
		Position: 0, 0
		Resolution in pixels: 1920x1080
		Manufacturer: 
		Model: 
		Refresh Rate: 60
	Screen: 1
		Name: \\.\DISPLAY2
		Depth: 32
		Scale: 1
		Position: -1920, 0
		Resolution in pixels: 1920x1200
		Manufacturer: 
		Model: 
		Refresh Rate: 60
Comment 6 Dmitry Kazakov 2023-10-16 15:43:15 UTC
I can confirm this issue happening even in my branch: https://invent.kde.org/graphics/krita/-/merge_requests/1958
Comment 7 Dmitry Kazakov 2024-08-22 16:39:01 UTC
Remove triaged keyword from CONFIRMED bugs
Comment 8 Dmitry Kazakov 2024-09-05 11:41:58 UTC
Git commit bc0757f08dc4c0ba69ac28c66d93b73c73e3c93f by Dmitry Kazakov.
Committed on 05/09/2024 at 11:37.
Pushed by dkazakov into branch 'master'.

Fix more cycling updates in clone/transform-masks combinations

If a layer has multiple transform masks (or any other masks with
complex need rects), we the transform mask update rect may leak
from outside-image position to the inside-image position, which
would cause the transform mask to start an async update. Hence we
cannot use the update rect position for prohibiting the transform
mask async updates.

To fix this issue we now have KisRenderPassFlags flags that are
passed to KisAsyncMerger and define is transform masks should do
any async updates. When a clone layer starts preparing hidden area
for itself, it just sets this flag and guarantees that no cycling
updates would happen.

A  +17   -0    libs/image/KisRenderPassFlags.h     [License: GPL(v2.0+)]
M  +2    -1    libs/image/kis_abstract_projection_plane.cpp
M  +2    -2    libs/image/kis_abstract_projection_plane.h
M  +25   -10   libs/image/kis_async_merger.cpp
M  +9    -0    libs/image/kis_async_merger.h
M  +3    -1    libs/image/kis_filter_mask.cpp
M  +2    -1    libs/image/kis_filter_mask.h
M  +7    -6    libs/image/kis_layer.cc
M  +6    -2    libs/image/kis_layer.h
M  +2    -2    libs/image/kis_layer_projection_plane.cpp
M  +1    -1    libs/image/kis_layer_projection_plane.h
M  +10   -7    libs/image/kis_mask.cc
M  +6    -3    libs/image/kis_mask.h
M  +2    -1    libs/image/kis_mask_projection_plane.cpp
M  +1    -1    libs/image/kis_mask_projection_plane.h
M  +4    -1    libs/image/kis_selection_mask.cpp
M  +1    -1    libs/image/kis_selection_mask.h
M  +4    -3    libs/image/kis_transform_mask.cpp
M  +2    -1    libs/image/kis_transform_mask.h
M  +3    -1    libs/image/kis_transparency_mask.cc
M  +2    -1    libs/image/kis_transparency_mask.h
M  +2    -1    libs/image/layerstyles/kis_layer_style_filter_projection_plane.cpp
M  +1    -1    libs/image/layerstyles/kis_layer_style_filter_projection_plane.h
M  +4    -4    libs/image/layerstyles/kis_layer_style_projection_plane.cpp
M  +1    -1    libs/image/layerstyles/kis_layer_style_projection_plane.h
M  +3    -1    libs/image/lazybrush/kis_colorize_mask.cpp
M  +2    -1    libs/image/lazybrush/kis_colorize_mask.h
A  +-    --    libs/image/tests/data/clone_layer_test/tmask_x2_source_00_initial.png
A  +-    --    libs/image/tests/data/clone_layer_test/tmask_x2_source_10_transform_mask_initial_static.png
A  +-    --    libs/image/tests/data/clone_layer_test/tmask_x2_source_20_final.png
M  +114  -0    libs/image/tests/kis_clone_layer_test.cpp
M  +1    -0    libs/image/tests/kis_clone_layer_test.h
M  +2    -2    libs/image/tests/kis_filter_mask_test.cpp
M  +6    -6    libs/image/tests/kis_layer_style_projection_plane_test.cpp
M  +1    -1    libs/image/tests/kis_mask_test.cpp
M  +3    -3    libs/image/tests/kis_paint_layer_test.cpp
M  +3    -3    libs/image/tests/kis_transparency_mask_test.cpp
M  +1    -1    libs/ui/widgets/kis_scratch_pad.cpp

https://invent.kde.org/graphics/krita/-/commit/bc0757f08dc4c0ba69ac28c66d93b73c73e3c93f
Comment 9 Dmitry Kazakov 2024-09-05 11:46:15 UTC
Git commit 86a3c70093fc571dc99e874c74b4b98f4b799244 by Dmitry Kazakov.
Committed on 05/09/2024 at 11:45.
Pushed by dkazakov into branch 'krita/5.2'.

Fix more cycling updates in clone/transform-masks combinations

If a layer has multiple transform masks (or any other masks with
complex need rects), we the transform mask update rect may leak
from outside-image position to the inside-image position, which
would cause the transform mask to start an async update. Hence we
cannot use the update rect position for prohibiting the transform
mask async updates.

To fix this issue we now have KisRenderPassFlags flags that are
passed to KisAsyncMerger and define is transform masks should do
any async updates. When a clone layer starts preparing hidden area
for itself, it just sets this flag and guarantees that no cycling
updates would happen.

A  +17   -0    libs/image/KisRenderPassFlags.h     [License: GPL(v2.0+)]
M  +2    -1    libs/image/kis_abstract_projection_plane.cpp
M  +2    -2    libs/image/kis_abstract_projection_plane.h
M  +25   -10   libs/image/kis_async_merger.cpp
M  +9    -0    libs/image/kis_async_merger.h
M  +3    -1    libs/image/kis_filter_mask.cpp
M  +2    -1    libs/image/kis_filter_mask.h
M  +7    -6    libs/image/kis_layer.cc
M  +6    -2    libs/image/kis_layer.h
M  +2    -2    libs/image/kis_layer_projection_plane.cpp
M  +1    -1    libs/image/kis_layer_projection_plane.h
M  +10   -7    libs/image/kis_mask.cc
M  +6    -3    libs/image/kis_mask.h
M  +2    -1    libs/image/kis_mask_projection_plane.cpp
M  +1    -1    libs/image/kis_mask_projection_plane.h
M  +4    -1    libs/image/kis_selection_mask.cpp
M  +1    -1    libs/image/kis_selection_mask.h
M  +4    -3    libs/image/kis_transform_mask.cpp
M  +2    -1    libs/image/kis_transform_mask.h
M  +3    -1    libs/image/kis_transparency_mask.cc
M  +2    -1    libs/image/kis_transparency_mask.h
M  +2    -1    libs/image/layerstyles/kis_layer_style_filter_projection_plane.cpp
M  +1    -1    libs/image/layerstyles/kis_layer_style_filter_projection_plane.h
M  +4    -4    libs/image/layerstyles/kis_layer_style_projection_plane.cpp
M  +1    -1    libs/image/layerstyles/kis_layer_style_projection_plane.h
M  +3    -1    libs/image/lazybrush/kis_colorize_mask.cpp
M  +2    -1    libs/image/lazybrush/kis_colorize_mask.h
A  +-    --    libs/image/tests/data/clone_layer_test/tmask_x2_source_00_initial.png
A  +-    --    libs/image/tests/data/clone_layer_test/tmask_x2_source_10_transform_mask_initial_static.png
A  +-    --    libs/image/tests/data/clone_layer_test/tmask_x2_source_20_final.png
M  +114  -0    libs/image/tests/kis_clone_layer_test.cpp
M  +1    -0    libs/image/tests/kis_clone_layer_test.h
M  +2    -2    libs/image/tests/kis_filter_mask_test.cpp
M  +6    -6    libs/image/tests/kis_layer_style_projection_plane_test.cpp
M  +1    -1    libs/image/tests/kis_mask_test.cpp
M  +3    -3    libs/image/tests/kis_paint_layer_test.cpp
M  +3    -3    libs/image/tests/kis_transparency_mask_test.cpp
M  +1    -1    libs/ui/widgets/kis_scratch_pad.cpp

https://invent.kde.org/graphics/krita/-/commit/86a3c70093fc571dc99e874c74b4b98f4b799244