diff --git a/ChangeLog b/ChangeLog index 97650bb18d..57c8dba7a7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +Tue Jul 27 01:21:02 1999 Jay Cox (jay@elan) + + * app/clone.c: more cursor support. + * app/cursorutil.[ch], cursors/{bad,badmsk}: new cursor + * app/paint_core.c: fix that rounding error the right way this time. + * app/pixel_processor.c, app/pixel_region.c: Lock the tiles while + they are being processed. Only create new threads if the region + being processed is large enough to warrant it. + 1999-07-27 Tuomas Kuosmanen * pixmaps/zoom_in.xpm @@ -52,7 +61,7 @@ Mon Jul 26 20:11:01 MEST 1999 Sven Neumann Sun Jul 25 23:37:48 1999 Jay Cox (jaycox@earthlink.net) - * paint_core.c: fixed longstanding roundoff error in + * paint_core.c: fixed long standing roundoff error in paint_core_subsample_mask. A couple of minor code cleanups. 1999-07-24 Michael Natterer diff --git a/app/base/pixel-processor.c b/app/base/pixel-processor.c index 96df600a37..8e76edc814 100644 --- a/app/base/pixel-processor.c +++ b/app/base/pixel-processor.c @@ -22,6 +22,7 @@ #include "pixel_processor.h" #include "pixel_region.h" +#include "pixel_regionP.h" #include "gimprc.h" #include #include @@ -47,8 +48,6 @@ typedef void (*p3_func)(void *, PixelRegion * ,PixelRegion *, PixelRegion *); typedef void (*p4_func)(void *, PixelRegion * ,PixelRegion *, PixelRegion *, PixelRegion *); -typedef struct _PixelRegionIterator PixelRegionIterator; - struct _PixelProcessor { void *data; @@ -85,7 +84,13 @@ do_parallel_regions(PixelProcessor *p_s) { for (i = 0; i < p_s->n_regions; i++) if (p_s->r[i]) + { memcpy(&tr[i], p_s->r[i], sizeof(PixelRegion)); + IF_THREAD( + if (tr[i].tiles) + tile_lock(tr[i].curtile); + ) + } IF_THREAD(pthread_mutex_unlock(&p_s->mutex);) ntiles++; switch(p_s->n_regions) @@ -117,6 +122,15 @@ do_parallel_regions(PixelProcessor *p_s) p_s->n_regions); } IF_THREAD(pthread_mutex_lock(&p_s->mutex);) + IF_THREAD( + { + for (i = 0; i < p_s->n_regions; i++) + if (p_s->r[i]) + { + if (tr[i].tiles) + tile_release(tr[i].curtile, tr[i].dirty); + } + }) if (p_s->progress_report_func) if (!p_s->progress_report_func(p_s->progress_report_data, p_s->r[0]->x, p_s->r[0]->y, @@ -142,7 +156,10 @@ pixel_regions_do_parallel(PixelProcessor *p_s) /* (p_s->PRI->region_width * p_s->PRI->region_height) /(64*64)); */ IF_THREAD( - nthreads = MIN(num_processors, 5); + nthreads = MIN(num_processors, MAX_THREADS); + nthreads = MIN(nthreads, 1 + + (p_s->PRI->region_width * p_s->PRI->region_height) + /(TILE_WIDTH*TILE_HEIGHT)); if (nthreads > 1) { pthread_attr_init (&pthread_attr); @@ -213,6 +230,7 @@ pixel_regions_real_process_parallel(p_func f, void *data, pixel_processor_free(p_s); return NULL; } + IF_THREAD(p_s->PRI->dirty_tiles = 0;) p_s->f = f; p_s->data = data; p_s->n_regions = num_regions; diff --git a/app/base/pixel-region.c b/app/base/pixel-region.c index 7c08048303..9e7cc03159 100644 --- a/app/base/pixel-region.c +++ b/app/base/pixel-region.c @@ -21,35 +21,13 @@ #include #include "appenv.h" #include "pixel_region.h" +#include "pixel_regionP.h" #include "gimprc.h" #include "tile_manager_pvt.h" #include "tile.h" /* ick. */ -typedef struct _PixelRegionHolder PixelRegionHolder; - -struct _PixelRegionHolder -{ - PixelRegion *PR; - unsigned char *original_data; - int startx, starty; - int count; -}; - - -typedef struct _PixelRegionIterator PixelRegionIterator; - -struct _PixelRegionIterator -{ - GSList *pixel_regions; - int region_width; - int region_height; - int portion_width; - int portion_height; - int process_count; -}; - /*********************/ /* Local Variables */ @@ -306,6 +284,7 @@ pixel_regions_register (int num_regions, PRI = (PixelRegionIterator *) g_malloc (sizeof (PixelRegionIterator)); PRI->pixel_regions = NULL; PRI->process_count = 0; + PRI->dirty_tiles = 1; if (num_regions < 1) return FALSE; @@ -374,7 +353,9 @@ pixel_regions_process (void *PRI_ptr) /* Unref the last referenced tile if the underlying region is a tile manager */ if (PRH->PR->tiles) { - tile_release (PRH->PR->curtile, PRH->PR->dirty); + /* only set the dirty flag if PRH->dirty_tiles = true */ + tile_release (PRH->PR->curtile, + PRH->PR->dirty * PRI->dirty_tiles); PRH->PR->curtile = NULL; } diff --git a/app/clone.c b/app/clone.c index b37e31d5f6..3d1c9d8635 100644 --- a/app/clone.c +++ b/app/clone.c @@ -30,6 +30,7 @@ #include "clone.h" #include "selection.h" #include "tools.h" +#include "cursorutil.h" #include "libgimp/gimpintl.h" @@ -387,6 +388,15 @@ clone_cursor_update (Tool *tool, ctype = GDK_PENCIL; } } + + if (clone_options->type == IMAGE_CLONE) + { + if (mevent->state & GDK_CONTROL_MASK) + ctype = GDK_CROSSHAIR; + else if (!src_drawable_) + ctype = GIMP_BAD_CURSOR; + } + gdisplay_install_tool_cursor (gdisp, ctype); } diff --git a/app/cursorutil.c b/app/cursorutil.c index e3673f9d6c..73209c9a5e 100644 --- a/app/cursorutil.c +++ b/app/cursorutil.c @@ -43,6 +43,8 @@ #include "../cursors/mouse1_selmmsk" #include "../cursors/mouse1_selp" #include "../cursors/mouse1_selpmsk" +#include "../cursors/bad" +#include "../cursors/badmsk" typedef struct { @@ -80,6 +82,8 @@ static BM_Cursor gimp_cursors[] = mouse1_selm_x_hot, mouse1_selm_y_hot, NULL}, { mouse1_sel_bits, mouse1_selmsk_bits, mouse1_sel_width, mouse1_sel_height, mouse1_sel_x_hot, mouse1_sel_y_hot, NULL}, + { bad_bits, badmsk_bits, bad_width, bad_height, + bad_x_hot, bad_y_hot, NULL}, }; diff --git a/app/cursorutil.h b/app/cursorutil.h index 31a84d3511..85dc7e670c 100644 --- a/app/cursorutil.h +++ b/app/cursorutil.h @@ -34,6 +34,7 @@ typedef enum GIMP_MOUSE1SELP_CURSOR, GIMP_MOUSE1SELM_CURSOR, GIMP_MOUSE1SEL_CURSOR, + GIMP_BAD_CURSOR, GIMP_LAST_CURSOR_ENTRY } GimpCursorType; diff --git a/app/paint/gimpclone.c b/app/paint/gimpclone.c index b37e31d5f6..3d1c9d8635 100644 --- a/app/paint/gimpclone.c +++ b/app/paint/gimpclone.c @@ -30,6 +30,7 @@ #include "clone.h" #include "selection.h" #include "tools.h" +#include "cursorutil.h" #include "libgimp/gimpintl.h" @@ -387,6 +388,15 @@ clone_cursor_update (Tool *tool, ctype = GDK_PENCIL; } } + + if (clone_options->type == IMAGE_CLONE) + { + if (mevent->state & GDK_CONTROL_MASK) + ctype = GDK_CROSSHAIR; + else if (!src_drawable_) + ctype = GIMP_BAD_CURSOR; + } + gdisplay_install_tool_cursor (gdisp, ctype); } diff --git a/app/paint/gimpsourcecore.c b/app/paint/gimpsourcecore.c index b37e31d5f6..3d1c9d8635 100644 --- a/app/paint/gimpsourcecore.c +++ b/app/paint/gimpsourcecore.c @@ -30,6 +30,7 @@ #include "clone.h" #include "selection.h" #include "tools.h" +#include "cursorutil.h" #include "libgimp/gimpintl.h" @@ -387,6 +388,15 @@ clone_cursor_update (Tool *tool, ctype = GDK_PENCIL; } } + + if (clone_options->type == IMAGE_CLONE) + { + if (mevent->state & GDK_CONTROL_MASK) + ctype = GDK_CROSSHAIR; + else if (!src_drawable_) + ctype = GIMP_BAD_CURSOR; + } + gdisplay_install_tool_cursor (gdisp, ctype); } diff --git a/app/paint_core.c b/app/paint_core.c index 19d99061dd..edb92f92b2 100644 --- a/app/paint_core.c +++ b/app/paint_core.c @@ -1052,7 +1052,7 @@ paint_core_subsample_mask (MaskBuf *mask, s = KERNEL_WIDTH; while (s--) { - new_val = *d + ((*m * *k++) /255); + new_val = *d + ((*m * *k++ + 128) >> 8); *d++ = MINIMUM (new_val, 255); } } diff --git a/app/pixel_processor.c b/app/pixel_processor.c index 96df600a37..8e76edc814 100644 --- a/app/pixel_processor.c +++ b/app/pixel_processor.c @@ -22,6 +22,7 @@ #include "pixel_processor.h" #include "pixel_region.h" +#include "pixel_regionP.h" #include "gimprc.h" #include #include @@ -47,8 +48,6 @@ typedef void (*p3_func)(void *, PixelRegion * ,PixelRegion *, PixelRegion *); typedef void (*p4_func)(void *, PixelRegion * ,PixelRegion *, PixelRegion *, PixelRegion *); -typedef struct _PixelRegionIterator PixelRegionIterator; - struct _PixelProcessor { void *data; @@ -85,7 +84,13 @@ do_parallel_regions(PixelProcessor *p_s) { for (i = 0; i < p_s->n_regions; i++) if (p_s->r[i]) + { memcpy(&tr[i], p_s->r[i], sizeof(PixelRegion)); + IF_THREAD( + if (tr[i].tiles) + tile_lock(tr[i].curtile); + ) + } IF_THREAD(pthread_mutex_unlock(&p_s->mutex);) ntiles++; switch(p_s->n_regions) @@ -117,6 +122,15 @@ do_parallel_regions(PixelProcessor *p_s) p_s->n_regions); } IF_THREAD(pthread_mutex_lock(&p_s->mutex);) + IF_THREAD( + { + for (i = 0; i < p_s->n_regions; i++) + if (p_s->r[i]) + { + if (tr[i].tiles) + tile_release(tr[i].curtile, tr[i].dirty); + } + }) if (p_s->progress_report_func) if (!p_s->progress_report_func(p_s->progress_report_data, p_s->r[0]->x, p_s->r[0]->y, @@ -142,7 +156,10 @@ pixel_regions_do_parallel(PixelProcessor *p_s) /* (p_s->PRI->region_width * p_s->PRI->region_height) /(64*64)); */ IF_THREAD( - nthreads = MIN(num_processors, 5); + nthreads = MIN(num_processors, MAX_THREADS); + nthreads = MIN(nthreads, 1 + + (p_s->PRI->region_width * p_s->PRI->region_height) + /(TILE_WIDTH*TILE_HEIGHT)); if (nthreads > 1) { pthread_attr_init (&pthread_attr); @@ -213,6 +230,7 @@ pixel_regions_real_process_parallel(p_func f, void *data, pixel_processor_free(p_s); return NULL; } + IF_THREAD(p_s->PRI->dirty_tiles = 0;) p_s->f = f; p_s->data = data; p_s->n_regions = num_regions; diff --git a/app/pixel_region.c b/app/pixel_region.c index 7c08048303..9e7cc03159 100644 --- a/app/pixel_region.c +++ b/app/pixel_region.c @@ -21,35 +21,13 @@ #include #include "appenv.h" #include "pixel_region.h" +#include "pixel_regionP.h" #include "gimprc.h" #include "tile_manager_pvt.h" #include "tile.h" /* ick. */ -typedef struct _PixelRegionHolder PixelRegionHolder; - -struct _PixelRegionHolder -{ - PixelRegion *PR; - unsigned char *original_data; - int startx, starty; - int count; -}; - - -typedef struct _PixelRegionIterator PixelRegionIterator; - -struct _PixelRegionIterator -{ - GSList *pixel_regions; - int region_width; - int region_height; - int portion_width; - int portion_height; - int process_count; -}; - /*********************/ /* Local Variables */ @@ -306,6 +284,7 @@ pixel_regions_register (int num_regions, PRI = (PixelRegionIterator *) g_malloc (sizeof (PixelRegionIterator)); PRI->pixel_regions = NULL; PRI->process_count = 0; + PRI->dirty_tiles = 1; if (num_regions < 1) return FALSE; @@ -374,7 +353,9 @@ pixel_regions_process (void *PRI_ptr) /* Unref the last referenced tile if the underlying region is a tile manager */ if (PRH->PR->tiles) { - tile_release (PRH->PR->curtile, PRH->PR->dirty); + /* only set the dirty flag if PRH->dirty_tiles = true */ + tile_release (PRH->PR->curtile, + PRH->PR->dirty * PRI->dirty_tiles); PRH->PR->curtile = NULL; } diff --git a/app/tools/clone.c b/app/tools/clone.c index b37e31d5f6..3d1c9d8635 100644 --- a/app/tools/clone.c +++ b/app/tools/clone.c @@ -30,6 +30,7 @@ #include "clone.h" #include "selection.h" #include "tools.h" +#include "cursorutil.h" #include "libgimp/gimpintl.h" @@ -387,6 +388,15 @@ clone_cursor_update (Tool *tool, ctype = GDK_PENCIL; } } + + if (clone_options->type == IMAGE_CLONE) + { + if (mevent->state & GDK_CONTROL_MASK) + ctype = GDK_CROSSHAIR; + else if (!src_drawable_) + ctype = GIMP_BAD_CURSOR; + } + gdisplay_install_tool_cursor (gdisp, ctype); } diff --git a/app/tools/gimpclonetool.c b/app/tools/gimpclonetool.c index b37e31d5f6..3d1c9d8635 100644 --- a/app/tools/gimpclonetool.c +++ b/app/tools/gimpclonetool.c @@ -30,6 +30,7 @@ #include "clone.h" #include "selection.h" #include "tools.h" +#include "cursorutil.h" #include "libgimp/gimpintl.h" @@ -387,6 +388,15 @@ clone_cursor_update (Tool *tool, ctype = GDK_PENCIL; } } + + if (clone_options->type == IMAGE_CLONE) + { + if (mevent->state & GDK_CONTROL_MASK) + ctype = GDK_CROSSHAIR; + else if (!src_drawable_) + ctype = GIMP_BAD_CURSOR; + } + gdisplay_install_tool_cursor (gdisp, ctype); } diff --git a/app/tools/gimpsourcetool.c b/app/tools/gimpsourcetool.c index b37e31d5f6..3d1c9d8635 100644 --- a/app/tools/gimpsourcetool.c +++ b/app/tools/gimpsourcetool.c @@ -30,6 +30,7 @@ #include "clone.h" #include "selection.h" #include "tools.h" +#include "cursorutil.h" #include "libgimp/gimpintl.h" @@ -387,6 +388,15 @@ clone_cursor_update (Tool *tool, ctype = GDK_PENCIL; } } + + if (clone_options->type == IMAGE_CLONE) + { + if (mevent->state & GDK_CONTROL_MASK) + ctype = GDK_CROSSHAIR; + else if (!src_drawable_) + ctype = GIMP_BAD_CURSOR; + } + gdisplay_install_tool_cursor (gdisp, ctype); } diff --git a/app/tools/paint_core.c b/app/tools/paint_core.c index 19d99061dd..edb92f92b2 100644 --- a/app/tools/paint_core.c +++ b/app/tools/paint_core.c @@ -1052,7 +1052,7 @@ paint_core_subsample_mask (MaskBuf *mask, s = KERNEL_WIDTH; while (s--) { - new_val = *d + ((*m * *k++) /255); + new_val = *d + ((*m * *k++ + 128) >> 8); *d++ = MINIMUM (new_val, 255); } } diff --git a/app/widgets/gimpcursor.c b/app/widgets/gimpcursor.c index e3673f9d6c..73209c9a5e 100644 --- a/app/widgets/gimpcursor.c +++ b/app/widgets/gimpcursor.c @@ -43,6 +43,8 @@ #include "../cursors/mouse1_selmmsk" #include "../cursors/mouse1_selp" #include "../cursors/mouse1_selpmsk" +#include "../cursors/bad" +#include "../cursors/badmsk" typedef struct { @@ -80,6 +82,8 @@ static BM_Cursor gimp_cursors[] = mouse1_selm_x_hot, mouse1_selm_y_hot, NULL}, { mouse1_sel_bits, mouse1_selmsk_bits, mouse1_sel_width, mouse1_sel_height, mouse1_sel_x_hot, mouse1_sel_y_hot, NULL}, + { bad_bits, badmsk_bits, bad_width, bad_height, + bad_x_hot, bad_y_hot, NULL}, }; diff --git a/app/widgets/gimpcursor.h b/app/widgets/gimpcursor.h index 31a84d3511..85dc7e670c 100644 --- a/app/widgets/gimpcursor.h +++ b/app/widgets/gimpcursor.h @@ -34,6 +34,7 @@ typedef enum GIMP_MOUSE1SELP_CURSOR, GIMP_MOUSE1SELM_CURSOR, GIMP_MOUSE1SEL_CURSOR, + GIMP_BAD_CURSOR, GIMP_LAST_CURSOR_ENTRY } GimpCursorType; diff --git a/cursors/bad b/cursors/bad new file mode 100644 index 0000000000..dcea54d364 --- /dev/null +++ b/cursors/bad @@ -0,0 +1,8 @@ +#define bad_width 16 +#define bad_height 16 +#define bad_x_hot 7 +#define bad_y_hot 7 +static unsigned char bad_bits[] = { + 0x00, 0x00, 0xe0, 0x03, 0x10, 0x04, 0x08, 0x08, 0x04, 0x14, 0x02, 0x22, + 0x02, 0x21, 0x82, 0x20, 0x42, 0x20, 0x22, 0x20, 0x14, 0x10, 0x08, 0x08, + 0x10, 0x04, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00}; diff --git a/cursors/badmsk b/cursors/badmsk new file mode 100644 index 0000000000..c8c1631652 --- /dev/null +++ b/cursors/badmsk @@ -0,0 +1,8 @@ +#define badmsk_width 16 +#define badmsk_height 16 +#define badmsk_x_hot 7 +#define badmsk_y_hot 7 +static unsigned char badmsk_bits[] = { + 0xc0, 0x01, 0xf0, 0x07, 0xf8, 0x0f, 0x1c, 0x1c, 0x0e, 0x3e, 0x06, 0x37, + 0x87, 0x73, 0xc7, 0x71, 0xe7, 0x70, 0x76, 0x30, 0x3e, 0x38, 0x1c, 0x1c, + 0xf8, 0x0f, 0xf0, 0x07, 0xc0, 0x01, 0x00, 0x00};