added a variant of pixel_regions_process_parallel() that takes a progress
2005-02-16 Sven Neumann <sven@gimp.org> * app/base/pixel-processor.[ch]: added a variant of pixel_regions_process_parallel() that takes a progress callback and progress data. Does only work for the single-threaded case yet. * app/core/gimpdrawable-blend.c (gradient_fill_region): parallelized.
This commit is contained in:
committed by
Sven Neumann
parent
6be469171d
commit
82a5329fbf
@ -37,6 +37,10 @@
|
||||
#include "tile.h"
|
||||
#endif
|
||||
|
||||
|
||||
#define PROGRESS_TIMEOUT 64
|
||||
|
||||
|
||||
static gint max_threads = 0;
|
||||
|
||||
|
||||
@ -60,17 +64,19 @@ typedef struct _PixelProcessor PixelProcessor;
|
||||
|
||||
struct _PixelProcessor
|
||||
{
|
||||
gpointer data;
|
||||
PixelProcessorFunc func;
|
||||
PixelRegionIterator *PRI;
|
||||
gpointer data;
|
||||
|
||||
#ifdef ENABLE_MP
|
||||
GStaticMutex mutex;
|
||||
gint threads;
|
||||
#endif
|
||||
|
||||
PixelRegionIterator *PRI;
|
||||
gint num_regions;
|
||||
PixelRegion *regions[4];
|
||||
|
||||
gulong progress;
|
||||
};
|
||||
|
||||
|
||||
@ -98,6 +104,9 @@ do_parallel_regions (PixelProcessor *processor)
|
||||
|
||||
do
|
||||
{
|
||||
guint pixels = (processor->PRI->portion_width *
|
||||
processor->PRI->portion_height);
|
||||
|
||||
for (i = 0; i < processor->num_regions; i++)
|
||||
if (processor->regions[i])
|
||||
{
|
||||
@ -141,18 +150,19 @@ do_parallel_regions (PixelProcessor *processor)
|
||||
g_warning ("do_parallel_regions: Bad number of regions %d\n",
|
||||
processor->num_regions);
|
||||
break;
|
||||
}
|
||||
|
||||
g_static_mutex_lock (&processor->mutex);
|
||||
|
||||
for (i = 0; i < processor->num_regions; i++)
|
||||
if (processor->regions[i])
|
||||
{
|
||||
if (tr[i].tiles)
|
||||
tile_release (tr[i].curtile, tr[i].dirty);
|
||||
}
|
||||
|
||||
processor->progress += pixels;
|
||||
}
|
||||
|
||||
g_static_mutex_lock (&processor->mutex);
|
||||
|
||||
for (i = 0; i < processor->num_regions; i++)
|
||||
if (processor->regions[i])
|
||||
{
|
||||
if (tr[i].tiles)
|
||||
tile_release (tr[i].curtile, tr[i].dirty);
|
||||
}
|
||||
}
|
||||
|
||||
while (processor->PRI &&
|
||||
(processor->PRI = pixel_regions_process (processor->PRI)));
|
||||
|
||||
@ -169,8 +179,16 @@ do_parallel_regions (PixelProcessor *processor)
|
||||
*/
|
||||
|
||||
static gpointer
|
||||
do_parallel_regions_single (PixelProcessor *processor)
|
||||
do_parallel_regions_single (PixelProcessor *processor,
|
||||
PixelProcessorProgressFunc progress_func,
|
||||
gpointer progress_data,
|
||||
gulong total)
|
||||
{
|
||||
GTimeVal last_time;
|
||||
|
||||
if (progress_func)
|
||||
g_get_current_time (&last_time);
|
||||
|
||||
do
|
||||
{
|
||||
switch (processor->num_regions)
|
||||
@ -205,8 +223,26 @@ do_parallel_regions_single (PixelProcessor *processor)
|
||||
g_warning ("do_parallel_regions_single: Bad number of regions %d\n",
|
||||
processor->num_regions);
|
||||
}
|
||||
}
|
||||
|
||||
if (progress_func)
|
||||
{
|
||||
GTimeVal now;
|
||||
|
||||
processor->progress += (processor->PRI->portion_width *
|
||||
processor->PRI->portion_height);
|
||||
|
||||
g_get_current_time (&now);
|
||||
|
||||
if (((now.tv_sec - last_time.tv_sec) * 1024 +
|
||||
(now.tv_usec - last_time.tv_usec) / 1024) > PROGRESS_TIMEOUT)
|
||||
{
|
||||
progress_func (progress_data,
|
||||
(gdouble) processor->progress / (gdouble) total);
|
||||
|
||||
last_time = now;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (processor->PRI &&
|
||||
(processor->PRI = pixel_regions_process (processor->PRI)));
|
||||
|
||||
@ -217,11 +253,15 @@ do_parallel_regions_single (PixelProcessor *processor)
|
||||
#define TILES_PER_THREAD 8
|
||||
|
||||
static void
|
||||
pixel_regions_do_parallel (PixelProcessor *processor)
|
||||
pixel_regions_do_parallel (PixelProcessor *processor,
|
||||
PixelProcessorProgressFunc progress_func,
|
||||
gpointer progress_data)
|
||||
{
|
||||
gulong pixels = (processor->PRI->region_width *
|
||||
processor->PRI->region_height);
|
||||
|
||||
#ifdef ENABLE_MP
|
||||
glong tiles = (processor->PRI->region_width *
|
||||
processor->PRI->region_height) / (TILE_WIDTH * TILE_HEIGHT);
|
||||
gulong tiles = pixels / (TILE_WIDTH * TILE_HEIGHT);
|
||||
|
||||
if (max_threads > 1 && tiles > TILES_PER_THREAD)
|
||||
{
|
||||
@ -255,15 +295,18 @@ pixel_regions_do_parallel (PixelProcessor *processor)
|
||||
else
|
||||
#endif
|
||||
{
|
||||
do_parallel_regions_single (processor);
|
||||
do_parallel_regions_single (processor,
|
||||
progress_func, progress_data, pixels);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pixel_regions_process_parallel_valist (PixelProcessorFunc func,
|
||||
gpointer data,
|
||||
gint num_regions,
|
||||
va_list ap)
|
||||
pixel_regions_process_parallel_valist (PixelProcessorFunc func,
|
||||
gpointer data,
|
||||
PixelProcessorProgressFunc progress_func,
|
||||
gpointer progress_data,
|
||||
gint num_regions,
|
||||
va_list ap)
|
||||
{
|
||||
PixelProcessor processor = { NULL, };
|
||||
gint i;
|
||||
@ -271,7 +314,7 @@ pixel_regions_process_parallel_valist (PixelProcessorFunc func,
|
||||
for (i = 0; i < num_regions; i++)
|
||||
processor.regions[i] = va_arg (ap, PixelRegion *);
|
||||
|
||||
switch(num_regions)
|
||||
switch (num_regions)
|
||||
{
|
||||
case 1:
|
||||
processor.PRI = pixel_regions_register (num_regions,
|
||||
@ -300,8 +343,8 @@ pixel_regions_process_parallel_valist (PixelProcessorFunc func,
|
||||
break;
|
||||
|
||||
default:
|
||||
g_warning ("pixel_regions_process_parallel:"
|
||||
"Bad number of regions %d\n", processor.num_regions);
|
||||
g_warning ("pixel_regions_process_parallel: "
|
||||
"bad number of regions (%d)\n", processor.num_regions);
|
||||
}
|
||||
|
||||
if (! processor.PRI)
|
||||
@ -317,7 +360,9 @@ pixel_regions_process_parallel_valist (PixelProcessorFunc func,
|
||||
processor.threads = 0;
|
||||
#endif
|
||||
|
||||
pixel_regions_do_parallel (&processor);
|
||||
processor.progress = 0;
|
||||
|
||||
pixel_regions_do_parallel (&processor, progress_func, progress_data);
|
||||
}
|
||||
|
||||
void
|
||||
@ -332,6 +377,8 @@ pixel_processor_set_num_threads (gint num_threads)
|
||||
g_return_if_fail (num_threads > 0);
|
||||
|
||||
max_threads = CLAMP (num_threads, 1, GIMP_MAX_NUM_THREADS);
|
||||
|
||||
g_printerr ("max_threads: %d\n", max_threads);
|
||||
}
|
||||
|
||||
void
|
||||
@ -350,7 +397,28 @@ pixel_regions_process_parallel (PixelProcessorFunc func,
|
||||
|
||||
va_start (va, num_regions);
|
||||
|
||||
pixel_regions_process_parallel_valist (func, data, num_regions, va);
|
||||
pixel_regions_process_parallel_valist (func, data,
|
||||
NULL, NULL,
|
||||
num_regions, va);
|
||||
|
||||
va_end (va);
|
||||
}
|
||||
|
||||
void
|
||||
pixel_regions_process_parallel_progress (PixelProcessorFunc func,
|
||||
gpointer data,
|
||||
PixelProcessorProgressFunc progress_func,
|
||||
gpointer progress_data,
|
||||
gint num_regions,
|
||||
...)
|
||||
{
|
||||
va_list va;
|
||||
|
||||
va_start (va, num_regions);
|
||||
|
||||
pixel_regions_process_parallel_valist (func, data,
|
||||
progress_func, progress_data,
|
||||
num_regions, va);
|
||||
|
||||
va_end (va);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user