app: guarantee fully-COWed copies in more cases in paint code

This commit is contained in:
Ell
2019-07-30 20:27:11 +03:00
parent 2d80d4d138
commit fb679f9efa
2 changed files with 37 additions and 31 deletions

View File

@ -57,11 +57,8 @@
#include "gimp-intl.h" #include "gimp-intl.h"
#define PAINT_COPY_CHUNK_WIDTH 128 #define PAINT_UPDATE_CHUNK_WIDTH 32
#define PAINT_COPY_CHUNK_HEIGHT 128 #define PAINT_UPDATE_CHUNK_HEIGHT 32
#define PAINT_UPDATE_CHUNK_WIDTH 32
#define PAINT_UPDATE_CHUNK_HEIGHT 32
enum enum
@ -1086,48 +1083,50 @@ gimp_drawable_update (GimpDrawable *drawable,
{ {
GeglRectangle rect; GeglRectangle rect;
rect.x = floor ((gdouble) x / PAINT_COPY_CHUNK_WIDTH) * PAINT_COPY_CHUNK_WIDTH;
rect.y = floor ((gdouble) y / PAINT_COPY_CHUNK_HEIGHT) * PAINT_COPY_CHUNK_HEIGHT;
rect.width = ceil ((gdouble) (x + width) / PAINT_COPY_CHUNK_WIDTH) * PAINT_COPY_CHUNK_WIDTH - rect.x;
rect.height = ceil ((gdouble) (y + height) / PAINT_COPY_CHUNK_HEIGHT) * PAINT_COPY_CHUNK_HEIGHT - rect.y;
if (gegl_rectangle_intersect ( if (gegl_rectangle_intersect (
&rect, &rect,
&rect, GEGL_RECTANGLE (x, y, width, height),
GEGL_RECTANGLE (0, 0, GEGL_RECTANGLE (0, 0,
gimp_item_get_width (GIMP_ITEM (drawable)), gimp_item_get_width (GIMP_ITEM (drawable)),
gimp_item_get_height (GIMP_ITEM (drawable))))) gimp_item_get_height (GIMP_ITEM (drawable)))))
{ {
GeglRectangle aligned_rect;
gegl_rectangle_align_to_buffer (&aligned_rect, &rect,
gimp_drawable_get_buffer (drawable),
GEGL_RECTANGLE_ALIGNMENT_SUPERSET);
if (drawable->private->paint_copy_region) if (drawable->private->paint_copy_region)
{ {
cairo_region_union_rectangle ( cairo_region_union_rectangle (
drawable->private->paint_copy_region, drawable->private->paint_copy_region,
(const cairo_rectangle_int_t *) &rect); (const cairo_rectangle_int_t *) &aligned_rect);
} }
else else
{ {
drawable->private->paint_copy_region = drawable->private->paint_copy_region =
cairo_region_create_rectangle ( cairo_region_create_rectangle (
(const cairo_rectangle_int_t *) &rect); (const cairo_rectangle_int_t *) &aligned_rect);
} }
rect.x = floor ((gdouble) x / PAINT_UPDATE_CHUNK_WIDTH) * PAINT_UPDATE_CHUNK_WIDTH; gegl_rectangle_align (&aligned_rect, &rect,
rect.y = floor ((gdouble) y / PAINT_UPDATE_CHUNK_HEIGHT) * PAINT_UPDATE_CHUNK_HEIGHT; GEGL_RECTANGLE (0, 0,
rect.width = ceil ((gdouble) (x + width) / PAINT_UPDATE_CHUNK_WIDTH) * PAINT_UPDATE_CHUNK_WIDTH - rect.x; PAINT_UPDATE_CHUNK_WIDTH,
rect.height = ceil ((gdouble) (y + height) / PAINT_UPDATE_CHUNK_HEIGHT) * PAINT_UPDATE_CHUNK_HEIGHT - rect.y; PAINT_UPDATE_CHUNK_HEIGHT),
GEGL_RECTANGLE_ALIGNMENT_SUPERSET);
if (drawable->private->paint_update_region) if (drawable->private->paint_update_region)
{ {
cairo_region_union_rectangle ( cairo_region_union_rectangle (
drawable->private->paint_update_region, drawable->private->paint_update_region,
(const cairo_rectangle_int_t *) &rect); (const cairo_rectangle_int_t *) &aligned_rect);
} }
else else
{ {
drawable->private->paint_update_region = drawable->private->paint_update_region =
cairo_region_create_rectangle ( cairo_region_create_rectangle (
(const cairo_rectangle_int_t *) &rect); (const cairo_rectangle_int_t *) &aligned_rect);
} }
} }
} }
} }

View File

@ -568,11 +568,18 @@ gimp_paint_core_cancel (GimpPaintCore *core,
gimp_item_get_height (GIMP_ITEM (drawable)), gimp_item_get_height (GIMP_ITEM (drawable)),
&x, &y, &width, &height)) &x, &y, &width, &height))
{ {
GeglRectangle rect;
gegl_rectangle_align_to_buffer (&rect,
GEGL_RECTANGLE (x, y, width, height),
gimp_drawable_get_buffer (drawable),
GEGL_RECTANGLE_ALIGNMENT_SUPERSET);
gimp_gegl_buffer_copy (core->undo_buffer, gimp_gegl_buffer_copy (core->undo_buffer,
GEGL_RECTANGLE (x, y, width, height), &rect,
GEGL_ABYSS_NONE, GEGL_ABYSS_NONE,
gimp_drawable_get_buffer (drawable), gimp_drawable_get_buffer (drawable),
GEGL_RECTANGLE (x, y, width, height)); &rect);
} }
g_clear_object (&core->undo_buffer); g_clear_object (&core->undo_buffer);