Issue #4793 - Layer-group preview-update blocks UI when adding/removing layers

In gimp_drawable_get_sub_preview_async(), use
gimp_idle_run_async_full() to render the preview in a low-priority
idle source when the drawable uses a validate handler (i.e., when
it's a group layer), to avoid rendering the preview before the
projection is done rendering, causing a noticeable freeze.

(cherry picked from commit fee159e6b4)
This commit is contained in:
Ell
2020-03-14 00:37:22 +02:00
parent d0d43ce252
commit d4b79fdcf1

View File

@ -36,6 +36,7 @@
#include "gimp.h" #include "gimp.h"
#include "gimp-parallel.h" #include "gimp-parallel.h"
#include "gimp-utils.h"
#include "gimpasync.h" #include "gimpasync.h"
#include "gimpchannel.h" #include "gimpchannel.h"
#include "gimpimage.h" #include "gimpimage.h"
@ -45,6 +46,8 @@
#include "gimplayer.h" #include "gimplayer.h"
#include "gimptempbuf.h" #include "gimptempbuf.h"
#include "gimp-priorities.h"
typedef struct typedef struct
{ {
@ -387,8 +390,7 @@ gimp_drawable_get_sub_preview_async (GimpDrawable *drawable,
(g_getenv ("GIMP_NO_ASYNC_DRAWABLE_PREVIEWS") != NULL); (g_getenv ("GIMP_NO_ASYNC_DRAWABLE_PREVIEWS") != NULL);
} }
if (no_async_drawable_previews || if (no_async_drawable_previews)
gimp_tile_handler_validate_get_assigned (buffer))
{ {
GimpAsync *async = gimp_async_new (); GimpAsync *async = gimp_async_new ();
@ -411,13 +413,28 @@ gimp_drawable_get_sub_preview_async (GimpDrawable *drawable,
scaled_x = RINT ((gdouble) src_x * scale); scaled_x = RINT ((gdouble) src_x * scale);
scaled_y = RINT ((gdouble) src_y * scale); scaled_y = RINT ((gdouble) src_y * scale);
return gimp_parallel_run_async_full ( if (gimp_tile_handler_validate_get_assigned (buffer))
+1, {
(GimpRunAsyncFunc) gimp_drawable_get_sub_preview_async_func, return gimp_idle_run_async_full (
sub_preview_data_new ( GIMP_PRIORITY_VIEWABLE_IDLE,
gimp_drawable_get_preview_format (drawable), (GimpRunAsyncFunc) gimp_drawable_get_sub_preview_async_func,
buffer, sub_preview_data_new (
GEGL_RECTANGLE (scaled_x, scaled_y, dest_width, dest_height), gimp_drawable_get_preview_format (drawable),
scale), buffer,
(GDestroyNotify) sub_preview_data_free); GEGL_RECTANGLE (scaled_x, scaled_y, dest_width, dest_height),
scale),
(GDestroyNotify) sub_preview_data_free);
}
else
{
return gimp_parallel_run_async_full (
+1,
(GimpRunAsyncFunc) gimp_drawable_get_sub_preview_async_func,
sub_preview_data_new (
gimp_drawable_get_preview_format (drawable),
buffer,
GEGL_RECTANGLE (scaled_x, scaled_y, dest_width, dest_height),
scale),
(GDestroyNotify) sub_preview_data_free);
}
} }