mirror of https://github.com/GNOME/gimp.git
app/paint_funcs.c app/pixel_processor.c app/tile.c app/tile_cache.c
2001-01-23 Sven Neumann <sven@gimp.org> * app/paint_funcs.c * app/pixel_processor.c * app/tile.c * app/tile_cache.c * app/tile_manager.c * app/tile_pvt.h * app/tile_swap.[ch]: cleanups, indentation
This commit is contained in:
parent
b102101e94
commit
6c3ef74547
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
2001-01-23 Sven Neumann <sven@gimp.org>
|
||||
|
||||
* app/paint_funcs.c
|
||||
* app/pixel_processor.c
|
||||
* app/tile.c
|
||||
* app/tile_cache.c
|
||||
* app/tile_manager.c
|
||||
* app/tile_pvt.h
|
||||
* app/tile_swap.[ch]: cleanups, indentation
|
||||
|
||||
2001-01-23 Sven Neumann <sven@gimp.org>
|
||||
|
||||
* app/convert.c
|
||||
|
|
|
@ -20,10 +20,6 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef ENABLE_MP
|
||||
#include <pthread.h>
|
||||
#define IF_THREAD(statement) statement
|
||||
|
@ -31,9 +27,9 @@
|
|||
#define IF_THREAD(statement)
|
||||
#endif /* ENABLE_MP */
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include <apptypes.h>
|
||||
#include "apptypes.h"
|
||||
|
||||
#include "pixel_processor.h"
|
||||
#include "pixel_region.h"
|
||||
|
@ -75,7 +71,7 @@ struct _PixelProcessor
|
|||
|
||||
IF_THREAD(
|
||||
static void *
|
||||
do_parallel_regions (PixelProcessor *p_s)
|
||||
do_parallel_regions (PixelProcessor *p_s)
|
||||
{
|
||||
PixelRegion tr[4];
|
||||
int ntiles = 0;
|
||||
|
@ -161,7 +157,7 @@ do_parallel_regions (PixelProcessor *p_s)
|
|||
(p_s->PRI = (PixelRegionIterator*)pixel_regions_process(p_s->PRI)));
|
||||
|
||||
p_s->nthreads--;
|
||||
/* fprintf(stderr, "processed %d tiles\n", ntiles); */
|
||||
|
||||
pthread_mutex_unlock(&p_s->mutex);
|
||||
|
||||
return NULL;
|
||||
|
@ -176,30 +172,33 @@ do_parallel_regions (PixelProcessor *p_s)
|
|||
* configured --with-mp
|
||||
*/
|
||||
|
||||
static void *
|
||||
do_parallel_regions_single(PixelProcessor *p_s)
|
||||
static gpointer
|
||||
do_parallel_regions_single (PixelProcessor *p_s)
|
||||
{
|
||||
int cont = 1;
|
||||
gint cont = 1;
|
||||
|
||||
do
|
||||
{
|
||||
switch(p_s->n_regions)
|
||||
switch (p_s->n_regions)
|
||||
{
|
||||
case 1:
|
||||
((p1_func)p_s->f)(p_s->data,
|
||||
p_s->r[0]);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
((p2_func)p_s->f)(p_s->data,
|
||||
p_s->r[0],
|
||||
p_s->r[1]);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
((p3_func)p_s->f)(p_s->data,
|
||||
p_s->r[0],
|
||||
p_s->r[1],
|
||||
p_s->r[2]);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
((p4_func)p_s->f)(p_s->data,
|
||||
p_s->r[0],
|
||||
|
@ -207,180 +206,207 @@ do_parallel_regions_single(PixelProcessor *p_s)
|
|||
p_s->r[2],
|
||||
p_s->r[3]);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_message("do_parallel_regions_single: Bad number of regions %d\n",
|
||||
p_s->n_regions);
|
||||
}
|
||||
|
||||
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,
|
||||
p_s->r[0]->w, p_s->r[0]->h))
|
||||
if (!p_s->progress_report_func (p_s->progress_report_data,
|
||||
p_s->r[0]->x, p_s->r[0]->y,
|
||||
p_s->r[0]->w, p_s->r[0]->h))
|
||||
cont = 0;
|
||||
} while (cont && p_s->PRI &&
|
||||
(p_s->PRI = (PixelRegionIterator*)pixel_regions_process(p_s->PRI)));
|
||||
}
|
||||
while (cont && p_s->PRI &&
|
||||
(p_s->PRI = (PixelRegionIterator*)pixel_regions_process(p_s->PRI)));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define MAX_THREADS 30
|
||||
|
||||
static void
|
||||
pixel_regions_do_parallel(PixelProcessor *p_s)
|
||||
pixel_regions_do_parallel (PixelProcessor *p_s)
|
||||
{
|
||||
IF_THREAD(
|
||||
int nthreads;
|
||||
nthreads = MIN(num_processors, MAX_THREADS);
|
||||
IF_THREAD(
|
||||
gint nthreads;
|
||||
|
||||
nthreads = MIN (num_processors, MAX_THREADS);
|
||||
|
||||
/* make sure we have at least one tile per thread */
|
||||
nthreads = MIN(nthreads,
|
||||
(p_s->PRI->region_width * p_s->PRI->region_height)
|
||||
/(TILE_WIDTH*TILE_HEIGHT));
|
||||
/* make sure we have at least one tile per thread */
|
||||
nthreads = MIN (nthreads,
|
||||
(p_s->PRI->region_width * p_s->PRI->region_height)
|
||||
/ (TILE_WIDTH * TILE_HEIGHT));
|
||||
|
||||
if (nthreads > 1)
|
||||
if (nthreads > 1)
|
||||
{
|
||||
int i;
|
||||
gint i;
|
||||
pthread_t threads[MAX_THREADS];
|
||||
pthread_attr_t pthread_attr;
|
||||
|
||||
pthread_attr_init (&pthread_attr);
|
||||
|
||||
for (i = 0; i < nthreads; i++)
|
||||
{
|
||||
pthread_create (&threads[i], &pthread_attr,
|
||||
(void *(*)(void *)) do_parallel_regions,
|
||||
p_s);
|
||||
}
|
||||
{
|
||||
pthread_create (&threads[i], &pthread_attr,
|
||||
(void *(*)(void *)) do_parallel_regions,
|
||||
p_s);
|
||||
}
|
||||
for (i = 0; i < nthreads; i++)
|
||||
{
|
||||
int ret;
|
||||
if ((ret = pthread_join(threads[i], NULL)))
|
||||
{
|
||||
fprintf(stderr, "pixel_regions_do_parallel:: pthread_join returned: %d\n", ret);
|
||||
}
|
||||
}
|
||||
{
|
||||
gint ret;
|
||||
|
||||
if ((ret = pthread_join(threads[i], NULL)))
|
||||
{
|
||||
g_printerr ("pixel_regions_do_parallel:: pthread_join returned: %d\n", ret);
|
||||
}
|
||||
}
|
||||
if (p_s->nthreads != 0)
|
||||
fprintf(stderr, "pixel_regions_do_prarallel: we lost a thread\n");
|
||||
g_printerr ("pixel_regions_do_prarallel: we lost a thread\n");
|
||||
}
|
||||
else
|
||||
)
|
||||
do_parallel_regions_single(p_s);
|
||||
else
|
||||
)
|
||||
do_parallel_regions_single (p_s);
|
||||
}
|
||||
|
||||
static PixelProcessor *
|
||||
pixel_regions_real_process_parallel(p_func f, void *data,
|
||||
ProgressReportFunc report_func,
|
||||
void *report_data,
|
||||
int num_regions, va_list ap)
|
||||
pixel_regions_real_process_parallel (p_func f,
|
||||
gpointer data,
|
||||
ProgressReportFunc report_func,
|
||||
gpointer report_data,
|
||||
gint num_regions,
|
||||
va_list ap)
|
||||
{
|
||||
int i;
|
||||
gint i;
|
||||
PixelProcessor *p_s;
|
||||
|
||||
|
||||
p_s = g_new(PixelProcessor, 1);
|
||||
|
||||
p_s = g_new (PixelProcessor, 1);
|
||||
|
||||
for (i = 0; i < num_regions; i++)
|
||||
p_s->r[i] = va_arg (ap, PixelRegion *);
|
||||
|
||||
switch(num_regions)
|
||||
{
|
||||
case 1:
|
||||
p_s->PRI = (PixelRegionIterator *) pixel_regions_register(num_regions,
|
||||
p_s->r[0]);
|
||||
break;
|
||||
case 2:
|
||||
p_s->PRI = (PixelRegionIterator *) pixel_regions_register(num_regions,
|
||||
p_s->r[0],
|
||||
p_s->r[1]);
|
||||
{
|
||||
case 1:
|
||||
p_s->PRI = (PixelRegionIterator *) pixel_regions_register (num_regions,
|
||||
p_s->r[0]);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
p_s->PRI = (PixelRegionIterator *) pixel_regions_register (num_regions,
|
||||
p_s->r[0],
|
||||
p_s->r[1]);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
p_s->PRI = (PixelRegionIterator *) pixel_regions_register(num_regions,
|
||||
p_s->r[0],
|
||||
p_s->r[1],
|
||||
p_s->r[2]);
|
||||
p_s->PRI = (PixelRegionIterator *) pixel_regions_register (num_regions,
|
||||
p_s->r[0],
|
||||
p_s->r[1],
|
||||
p_s->r[2]);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
p_s->PRI = (PixelRegionIterator *) pixel_regions_register(num_regions,
|
||||
p_s->r[0],
|
||||
p_s->r[1],
|
||||
p_s->r[2],
|
||||
p_s->r[3]);
|
||||
p_s->PRI = (PixelRegionIterator *) pixel_regions_register (num_regions,
|
||||
p_s->r[0],
|
||||
p_s->r[1],
|
||||
p_s->r[2],
|
||||
p_s->r[3]);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_message("pixel_regions_real_process_parallel: Bad number of regions %d\n",
|
||||
p_s->n_regions);
|
||||
g_message ("pixel_regions_real_process_parallel: Bad number of regions %d\n",
|
||||
p_s->n_regions);
|
||||
}
|
||||
|
||||
if (!p_s->PRI)
|
||||
{
|
||||
pixel_processor_free(p_s);
|
||||
return NULL;
|
||||
}
|
||||
{
|
||||
pixel_processor_free (p_s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Why would we wan't to set dirty_tiles to 0 here? */
|
||||
/* IF_THREAD(p_s->PRI->dirty_tiles = 0;) */
|
||||
p_s->f = f;
|
||||
p_s->data = data;
|
||||
p_s->n_regions = num_regions;
|
||||
IF_THREAD(pthread_mutex_init(&(p_s->mutex), NULL);)
|
||||
IF_THREAD (pthread_mutex_init(&(p_s->mutex), NULL);)
|
||||
p_s->nthreads = 0;
|
||||
|
||||
p_s->progress_report_data = report_data;
|
||||
p_s->progress_report_func = report_func;
|
||||
|
||||
|
||||
pixel_regions_do_parallel(p_s);
|
||||
pixel_regions_do_parallel (p_s);
|
||||
|
||||
if (p_s->PRI)
|
||||
return p_s;
|
||||
|
||||
pixel_processor_free (p_s);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
pixel_regions_process_parallel(p_func f, void *data, int num_regions, ...)
|
||||
pixel_regions_process_parallel (p_func f,
|
||||
gpointer data,
|
||||
gint num_regions,
|
||||
...)
|
||||
{
|
||||
va_list va;
|
||||
|
||||
va_start (va, num_regions);
|
||||
|
||||
pixel_regions_real_process_parallel(f, data, NULL, NULL, num_regions, va);
|
||||
pixel_regions_real_process_parallel (f, data, NULL, NULL, num_regions, va);
|
||||
|
||||
va_end (va);
|
||||
}
|
||||
|
||||
PixelProcessor *
|
||||
pixel_regions_process_parallel_progress(p_func f, void *data,
|
||||
ProgressReportFunc progress_func,
|
||||
void *progress_data, int num_regions,
|
||||
...)
|
||||
pixel_regions_process_parallel_progress (p_func f,
|
||||
gpointer data,
|
||||
ProgressReportFunc progress_func,
|
||||
gpointer progress_data,
|
||||
gint num_regions,
|
||||
...)
|
||||
{
|
||||
PixelProcessor *ret;
|
||||
va_list va;
|
||||
va_start (va, num_regions);
|
||||
va_list va;
|
||||
|
||||
ret = pixel_regions_real_process_parallel(f, data,
|
||||
progress_func, progress_data,
|
||||
num_regions, va);
|
||||
va_start (va, num_regions);
|
||||
|
||||
ret = pixel_regions_real_process_parallel (f, data,
|
||||
progress_func, progress_data,
|
||||
num_regions, va);
|
||||
|
||||
va_end (va);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
pixel_processor_stop(PixelProcessor *pp)
|
||||
pixel_processor_stop (PixelProcessor *pp)
|
||||
{
|
||||
if (!pp)
|
||||
return;
|
||||
|
||||
if (pp->PRI)
|
||||
{
|
||||
pixel_regions_process_stop (pp->PRI);
|
||||
pp->PRI = NULL;
|
||||
}
|
||||
pixel_processor_free(pp);
|
||||
{
|
||||
pixel_regions_process_stop (pp->PRI);
|
||||
pp->PRI = NULL;
|
||||
}
|
||||
pixel_processor_free (pp);
|
||||
}
|
||||
|
||||
PixelProcessor *
|
||||
pixel_processor_cont(PixelProcessor *pp)
|
||||
pixel_processor_cont (PixelProcessor *pp)
|
||||
{
|
||||
pixel_regions_do_parallel(pp);
|
||||
pixel_regions_do_parallel (pp);
|
||||
|
||||
if (pp->PRI)
|
||||
return pp;
|
||||
|
||||
pixel_processor_free (pp);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -388,7 +414,7 @@ void
|
|||
pixel_processor_free (PixelProcessor *pp)
|
||||
{
|
||||
if (pp->PRI)
|
||||
pixel_processor_stop(pp);
|
||||
pixel_processor_stop (pp);
|
||||
else
|
||||
g_free(pp);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef USE_PTHREADS
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
@ -37,23 +36,28 @@
|
|||
/* This is the percentage of the maximum cache size that should be cleared
|
||||
* from the cache when an eviction is necessary
|
||||
*/
|
||||
#define FREE_QUANTUM 0.1
|
||||
#define FREE_QUANTUM 0.1
|
||||
|
||||
static void tile_cache_init (void);
|
||||
static gint tile_cache_zorch_next (void);
|
||||
static void tile_cache_flush_internal (Tile *tile);
|
||||
#define IDLE_SWAPPER_TIMEOUT 250
|
||||
|
||||
|
||||
static void tile_cache_init (void);
|
||||
static gint tile_cache_zorch_next (void);
|
||||
static void tile_cache_flush_internal (Tile *tile);
|
||||
|
||||
#ifdef USE_PTHREADS
|
||||
static void* tile_idle_thread (void *);
|
||||
static gpointer tile_idle_thread (gpointer data);
|
||||
#else
|
||||
static gint tile_idle_preswap (gpointer);
|
||||
static gint tile_idle_preswap (gpointer data);
|
||||
#endif
|
||||
|
||||
|
||||
static int initialize = TRUE;
|
||||
|
||||
typedef struct _TileList {
|
||||
Tile* first;
|
||||
Tile* last;
|
||||
typedef struct _TileList
|
||||
{
|
||||
Tile *first;
|
||||
Tile *last;
|
||||
} TileList;
|
||||
|
||||
static unsigned long max_tile_size = TILE_WIDTH * TILE_HEIGHT * 4;
|
||||
|
@ -222,7 +226,7 @@ tile_cache_flush_internal (Tile *tile)
|
|||
|
||||
/* untested -- ADM */
|
||||
void
|
||||
tile_cache_set_size (unsigned long cache_size)
|
||||
tile_cache_set_size (gulong cache_size)
|
||||
{
|
||||
if (initialize)
|
||||
tile_cache_init ();
|
||||
|
@ -239,7 +243,7 @@ tile_cache_set_size (unsigned long cache_size)
|
|||
|
||||
|
||||
static void
|
||||
tile_cache_init ()
|
||||
tile_cache_init (void)
|
||||
{
|
||||
if (initialize)
|
||||
{
|
||||
|
@ -253,7 +257,7 @@ tile_cache_init ()
|
|||
#ifdef USE_PTHREADS
|
||||
pthread_create (&preswap_thread, NULL, &tile_idle_thread, NULL);
|
||||
#else
|
||||
idle_swapper = gtk_timeout_add (250,
|
||||
idle_swapper = gtk_timeout_add (IDLE_SWAPPER_TIMEOUT,
|
||||
(GtkFunction) tile_idle_preswap,
|
||||
(gpointer) 0);
|
||||
#endif
|
||||
|
@ -261,15 +265,16 @@ tile_cache_init ()
|
|||
}
|
||||
|
||||
static gint
|
||||
tile_cache_zorch_next ()
|
||||
tile_cache_zorch_next (void)
|
||||
{
|
||||
Tile *tile;
|
||||
|
||||
/* fprintf(stderr, "cache zorch: %u/%u\n", cur_cache_size, cur_cache_dirty);*/
|
||||
|
||||
if (clean_list.first) tile = clean_list.first;
|
||||
else if (dirty_list.first) tile = dirty_list.first;
|
||||
else return FALSE;
|
||||
if (clean_list.first)
|
||||
tile = clean_list.first;
|
||||
else if (dirty_list.first)
|
||||
tile = dirty_list.first;
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
CACHE_UNLOCK;
|
||||
TILE_MUTEX_LOCK (tile);
|
||||
|
@ -279,29 +284,34 @@ tile_cache_zorch_next ()
|
|||
{
|
||||
tile_swap_out (tile);
|
||||
}
|
||||
if (! tile->dirty) {
|
||||
g_free (tile->data);
|
||||
tile->data = NULL;
|
||||
TILE_MUTEX_UNLOCK (tile);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (! tile->dirty)
|
||||
{
|
||||
g_free (tile->data);
|
||||
tile->data = NULL;
|
||||
TILE_MUTEX_UNLOCK (tile);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* unable to swap out tile for some reason */
|
||||
TILE_MUTEX_UNLOCK (tile);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#if USE_PTHREADS
|
||||
static void *
|
||||
tile_idle_thread (void *data)
|
||||
static gpointer
|
||||
tile_idle_thread (gpointer data)
|
||||
{
|
||||
Tile *tile;
|
||||
Tile *tile;
|
||||
TileList *list;
|
||||
int count;
|
||||
gint count;
|
||||
|
||||
fprintf (stderr, "starting tile preswapper\n");
|
||||
g_printerr ("starting tile preswapper\n");
|
||||
|
||||
count = 0;
|
||||
while (1)
|
||||
while (TRUE)
|
||||
{
|
||||
CACHE_LOCK;
|
||||
if (count > 5 || dirty_list.first == NULL)
|
||||
|
|
|
@ -18,19 +18,17 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include "apptypes.h"
|
||||
|
||||
#include "tile.h"
|
||||
#include "tile_pvt.h"
|
||||
#include "tile_cache.h"
|
||||
#include "tile_manager.h"
|
||||
#include "tile_manager_pvt.h"
|
||||
#include "tile_swap.h"
|
||||
|
||||
#include "tile_pvt.h" /* ick. */
|
||||
|
||||
|
||||
static gint tile_manager_get_tile_num (TileManager *tm,
|
||||
gint xpixel,
|
||||
|
@ -301,8 +299,8 @@ tile_manager_invalidate_tiles (TileManager *tm,
|
|||
col = toplevel_tile->tlink->tile_num % tm->ntile_cols;
|
||||
row = toplevel_tile->tlink->tile_num / tm->ntile_cols;
|
||||
|
||||
x = (col * TILE_WIDTH + toplevel_tile->ewidth / 2.0) / (double) tm->width;
|
||||
y = (row * TILE_HEIGHT + toplevel_tile->eheight / 2.0) / (double) tm->height;
|
||||
x = (col * TILE_WIDTH + toplevel_tile->ewidth / 2.0) / (gdouble) tm->width;
|
||||
y = (row * TILE_HEIGHT + toplevel_tile->eheight / 2.0) / (gdouble) tm->height;
|
||||
|
||||
if (tm->tiles)
|
||||
{
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#define __TILE_PVT_H__
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef USE_PTHREADS
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
@ -9,20 +11,18 @@
|
|||
#include <sys/types.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "tile.h"
|
||||
|
||||
typedef struct _TileLink TileLink;
|
||||
|
||||
struct _TileLink
|
||||
{
|
||||
TileLink *next;
|
||||
int tile_num; /* the number of this tile within the drawable */
|
||||
void *tm; /* A pointer to the tile manager for this tile.
|
||||
* We need this in order to call the tile managers
|
||||
* validate proc whenever the tile is referenced yet
|
||||
* invalid.
|
||||
*/
|
||||
TileLink *next;
|
||||
gint tile_num; /* the number of this tile within the drawable */
|
||||
TileManager *tm; /* A pointer to the tile manager for this tile.
|
||||
* We need this in order to call the tile managers
|
||||
* validate proc whenever the tile is referenced
|
||||
* yet invalid.
|
||||
*/
|
||||
};
|
||||
|
||||
struct _Tile
|
||||
|
|
|
@ -18,11 +18,9 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
@ -47,8 +45,9 @@
|
|||
#include "apptypes.h"
|
||||
|
||||
#include "tile.h"
|
||||
#include "tile_pvt.h"
|
||||
#include "tile_swap.h"
|
||||
#include "tile_pvt.h" /* ick. */
|
||||
|
||||
|
||||
#define MAX_OPEN_SWAP_FILES 16
|
||||
|
||||
|
@ -59,96 +58,97 @@ typedef struct _AsyncSwapArgs AsyncSwapArgs;
|
|||
|
||||
struct _SwapFile
|
||||
{
|
||||
char *filename;
|
||||
int swap_num;
|
||||
SwapFunc swap_func;
|
||||
gpointer user_data;
|
||||
int fd;
|
||||
gchar *filename;
|
||||
gint swap_num;
|
||||
SwapFunc swap_func;
|
||||
gpointer user_data;
|
||||
gint fd;
|
||||
};
|
||||
|
||||
struct _DefSwapFile
|
||||
{
|
||||
GList *gaps;
|
||||
long swap_file_end;
|
||||
off_t cur_position;
|
||||
glong swap_file_end;
|
||||
off_t cur_position;
|
||||
};
|
||||
|
||||
struct _Gap
|
||||
{
|
||||
long start;
|
||||
long end;
|
||||
glong start;
|
||||
glong end;
|
||||
};
|
||||
|
||||
struct _AsyncSwapArgs
|
||||
{
|
||||
DefSwapFile *def_swap_file;
|
||||
int fd;
|
||||
gint fd;
|
||||
Tile *tile;
|
||||
};
|
||||
|
||||
|
||||
static void tile_swap_init (void);
|
||||
static guint tile_swap_hash (int *key);
|
||||
static gint tile_swap_compare (int *a,
|
||||
int *b);
|
||||
static void tile_swap_command (Tile *tile,
|
||||
int command);
|
||||
static void tile_swap_open (SwapFile *swap_file);
|
||||
static void tile_swap_init (void);
|
||||
static guint tile_swap_hash (gint *key);
|
||||
static gint tile_swap_compare (gint *a,
|
||||
gint *b);
|
||||
static void tile_swap_command (Tile *tile,
|
||||
gint command);
|
||||
static void tile_swap_open (SwapFile *swap_file);
|
||||
|
||||
static int tile_swap_default (int fd,
|
||||
Tile *tile,
|
||||
int cmd,
|
||||
gpointer user_data);
|
||||
static void tile_swap_default_in (DefSwapFile *def_swap_file,
|
||||
int fd,
|
||||
Tile *tile);
|
||||
static void tile_swap_default_in_async (DefSwapFile *def_swap_file,
|
||||
int fd,
|
||||
Tile *tile);
|
||||
static void tile_swap_default_out (DefSwapFile *def_swap_file,
|
||||
int fd,
|
||||
Tile *tile);
|
||||
static void tile_swap_default_delete (DefSwapFile *def_swap_file,
|
||||
int fd,
|
||||
Tile *tile);
|
||||
static long tile_swap_find_offset (DefSwapFile *def_swap_file,
|
||||
int fd,
|
||||
int bytes);
|
||||
static void tile_swap_resize (DefSwapFile *def_swap_file,
|
||||
int fd,
|
||||
long new_size);
|
||||
static Gap* tile_swap_gap_new (long start,
|
||||
long end);
|
||||
static void tile_swap_gap_destroy (Gap *gap);
|
||||
static gint tile_swap_default (gint fd,
|
||||
Tile *tile,
|
||||
gint cmd,
|
||||
gpointer user_data);
|
||||
static void tile_swap_default_in (DefSwapFile *def_swap_file,
|
||||
gint fd,
|
||||
Tile *tile);
|
||||
static void tile_swap_default_in_async (DefSwapFile *def_swap_file,
|
||||
gint fd,
|
||||
Tile *tile);
|
||||
static void tile_swap_default_out (DefSwapFile *def_swap_file,
|
||||
gint fd,
|
||||
Tile *tile);
|
||||
static void tile_swap_default_delete (DefSwapFile *def_swap_file,
|
||||
gint fd,
|
||||
Tile *tile);
|
||||
static glong tile_swap_find_offset (DefSwapFile *def_swap_file,
|
||||
gint fd,
|
||||
gint bytes);
|
||||
static void tile_swap_resize (DefSwapFile *def_swap_file,
|
||||
gint fd,
|
||||
glong new_size);
|
||||
static Gap * tile_swap_gap_new (glong start,
|
||||
glong end);
|
||||
static void tile_swap_gap_destroy (Gap *gap);
|
||||
#ifdef USE_PTHREADS
|
||||
static void* tile_swap_in_thread (void *);
|
||||
static gpointer tile_swap_in_thread (gpointer);
|
||||
#endif
|
||||
|
||||
|
||||
static int initialize = TRUE;
|
||||
static GHashTable *swap_files = NULL;
|
||||
static GList *open_swap_files = NULL;
|
||||
static int nopen_swap_files = 0;
|
||||
static int next_swap_num = 1;
|
||||
static long swap_file_grow = 16 * TILE_WIDTH * TILE_HEIGHT * 4;
|
||||
static gboolean initialize = TRUE;
|
||||
static GHashTable * swap_files = NULL;
|
||||
static GList * open_swap_files = NULL;
|
||||
static gint nopen_swap_files = 0;
|
||||
static gint next_swap_num = 1;
|
||||
static glong swap_file_grow = 16 * TILE_WIDTH * TILE_HEIGHT * 4;
|
||||
#ifdef USE_PTHREADS
|
||||
static pthread_mutex_t swapfile_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_mutex_t swapfile_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/* async_swapin_mutex protects only the list, not the tiles therein */
|
||||
static pthread_t swapin_thread;
|
||||
static pthread_mutex_t async_swapin_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t async_swapin_signal = PTHREAD_COND_INITIALIZER;
|
||||
static GSList *async_swapin_tiles = NULL;
|
||||
static GSList *async_swapin_tiles_end = NULL;
|
||||
static pthread_t swapin_thread;
|
||||
static pthread_mutex_t async_swapin_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t async_swapin_signal = PTHREAD_COND_INITIALIZER;
|
||||
static GSList * async_swapin_tiles = NULL;
|
||||
static GSList * async_swapin_tiles_end = NULL;
|
||||
#endif
|
||||
|
||||
static gboolean seek_err_msg = TRUE, read_err_msg = TRUE, write_err_msg = TRUE;
|
||||
|
||||
|
||||
static void
|
||||
tile_swap_print_gaps (DefSwapFile *def_swap_file)
|
||||
{
|
||||
GList *gaps;
|
||||
Gap *gap;
|
||||
Gap *gap;
|
||||
|
||||
gaps = def_swap_file->gaps;
|
||||
while (gaps)
|
||||
|
@ -165,8 +165,8 @@ tile_swap_exit1 (gpointer key,
|
|||
gpointer value,
|
||||
gpointer data)
|
||||
{
|
||||
extern int tile_ref_count;
|
||||
SwapFile *swap_file;
|
||||
extern gint tile_ref_count;
|
||||
SwapFile *swap_file;
|
||||
DefSwapFile *def_swap_file;
|
||||
|
||||
if (tile_ref_count != 0)
|
||||
|
@ -194,27 +194,26 @@ tile_swap_exit1 (gpointer key,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
tile_swap_exit ()
|
||||
tile_swap_exit (void)
|
||||
{
|
||||
#ifdef HINTS_SANITY
|
||||
extern int tile_exist_peak;
|
||||
|
||||
fprintf(stderr,"Tile exist peak was %d Tile structs (%d bytes)",
|
||||
tile_exist_peak, tile_exist_peak * sizeof(Tile));
|
||||
g_printerr ("Tile exist peak was %d Tile structs (%d bytes)",
|
||||
tile_exist_peak, tile_exist_peak * sizeof(Tile));
|
||||
#endif
|
||||
|
||||
if (swap_files)
|
||||
g_hash_table_foreach (swap_files, tile_swap_exit1, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
tile_swap_add (char *filename,
|
||||
gint
|
||||
tile_swap_add (gchar *filename,
|
||||
SwapFunc swap_func,
|
||||
gpointer user_data)
|
||||
{
|
||||
SwapFile *swap_file;
|
||||
SwapFile *swap_file;
|
||||
DefSwapFile *def_swap_file;
|
||||
|
||||
#ifdef USE_PTHREADS
|
||||
|
@ -253,7 +252,7 @@ tile_swap_add (char *filename,
|
|||
}
|
||||
|
||||
void
|
||||
tile_swap_remove (int swap_num)
|
||||
tile_swap_remove (gint swap_num)
|
||||
{
|
||||
SwapFile *swap_file;
|
||||
|
||||
|
@ -315,13 +314,13 @@ tile_swap_delete (Tile *tile)
|
|||
}
|
||||
|
||||
void
|
||||
tile_swap_compress (int swap_num)
|
||||
tile_swap_compress (gint swap_num)
|
||||
{
|
||||
tile_swap_command (NULL, SWAP_COMPRESS);
|
||||
}
|
||||
|
||||
static void
|
||||
tile_swap_init ()
|
||||
tile_swap_init (void)
|
||||
{
|
||||
|
||||
if (initialize)
|
||||
|
@ -338,21 +337,21 @@ tile_swap_init ()
|
|||
}
|
||||
|
||||
static guint
|
||||
tile_swap_hash (int *key)
|
||||
tile_swap_hash (gint *key)
|
||||
{
|
||||
return ((guint) *key);
|
||||
return (guint) *key;
|
||||
}
|
||||
|
||||
static gint
|
||||
tile_swap_compare (int *a,
|
||||
int *b)
|
||||
tile_swap_compare (gint *a,
|
||||
gint *b)
|
||||
{
|
||||
return (*a == *b);
|
||||
}
|
||||
|
||||
static void
|
||||
tile_swap_command (Tile *tile,
|
||||
int command)
|
||||
gint command)
|
||||
{
|
||||
SwapFile *swap_file;
|
||||
#ifdef USE_PTHREADS
|
||||
|
@ -377,11 +376,15 @@ tile_swap_command (Tile *tile,
|
|||
if (swap_file->fd == -1)
|
||||
goto out;
|
||||
}
|
||||
} while ((* swap_file->swap_func) (swap_file->fd, tile, command, swap_file->user_data));
|
||||
}
|
||||
while ((* swap_file->swap_func) (swap_file->fd,
|
||||
tile, command, swap_file->user_data));
|
||||
|
||||
out:
|
||||
#ifdef USE_PTHREADS
|
||||
pthread_mutex_unlock(&swapfile_mutex);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -427,9 +430,9 @@ tile_swap_open (SwapFile *swap_file)
|
|||
*/
|
||||
|
||||
static int
|
||||
tile_swap_default (int fd,
|
||||
tile_swap_default (gint fd,
|
||||
Tile *tile,
|
||||
int cmd,
|
||||
gint cmd,
|
||||
gpointer user_data)
|
||||
{
|
||||
DefSwapFile *def_swap_file;
|
||||
|
@ -460,7 +463,7 @@ tile_swap_default (int fd,
|
|||
|
||||
static void
|
||||
tile_swap_default_in_async (DefSwapFile *def_swap_file,
|
||||
int fd,
|
||||
gint fd,
|
||||
Tile *tile)
|
||||
{
|
||||
#ifdef NOTDEF /* USE_PTHREADS */
|
||||
|
@ -506,12 +509,12 @@ tile_swap_default_in_async (DefSwapFile *def_swap_file,
|
|||
*/
|
||||
static void
|
||||
tile_swap_default_in (DefSwapFile *def_swap_file,
|
||||
int fd,
|
||||
gint fd,
|
||||
Tile *tile)
|
||||
{
|
||||
int bytes;
|
||||
int err;
|
||||
int nleft;
|
||||
gint bytes;
|
||||
gint err;
|
||||
gint nleft;
|
||||
off_t offset;
|
||||
|
||||
err = -1;
|
||||
|
@ -541,14 +544,17 @@ tile_swap_default_in (DefSwapFile *def_swap_file,
|
|||
nleft = bytes;
|
||||
while (nleft > 0)
|
||||
{
|
||||
do {
|
||||
err = read (fd, tile->data + bytes - nleft, nleft);
|
||||
} while ((err == -1) && ((errno == EAGAIN) || (errno == EINTR)));
|
||||
do
|
||||
{
|
||||
err = read (fd, tile->data + bytes - nleft, nleft);
|
||||
}
|
||||
while ((err == -1) && ((errno == EAGAIN) || (errno == EINTR)));
|
||||
|
||||
if (err <= 0)
|
||||
{
|
||||
if (read_err_msg)
|
||||
g_message ("unable to read tile data from disk: %d/%d ( %d ) bytes read", err, errno, nleft);
|
||||
g_message ("unable to read tile data from disk: %s (%d/%d bytes read)",
|
||||
g_strerror (errno), err, nleft);
|
||||
read_err_msg = FALSE;
|
||||
return;
|
||||
}
|
||||
|
@ -569,12 +575,11 @@ tile_swap_default_out (DefSwapFile *def_swap_file,
|
|||
int fd,
|
||||
Tile *tile)
|
||||
{
|
||||
int bytes;
|
||||
int rbytes;
|
||||
int err;
|
||||
int nleft;
|
||||
gint bytes;
|
||||
gint rbytes;
|
||||
gint err;
|
||||
gint nleft;
|
||||
off_t offset;
|
||||
|
||||
off_t newpos;
|
||||
|
||||
bytes = TILE_WIDTH * TILE_HEIGHT * tile->bpp;
|
||||
|
@ -592,7 +597,8 @@ tile_swap_default_out (DefSwapFile *def_swap_file,
|
|||
if (offset == -1)
|
||||
{
|
||||
if (seek_err_msg)
|
||||
g_message ("unable to seek to tile location on disk: %d", errno);
|
||||
g_message ("unable to seek to tile location on disk: %s",
|
||||
g_strerror (errno));
|
||||
seek_err_msg = FALSE;
|
||||
return;
|
||||
}
|
||||
|
@ -606,7 +612,8 @@ tile_swap_default_out (DefSwapFile *def_swap_file,
|
|||
if (err <= 0)
|
||||
{
|
||||
if (write_err_msg)
|
||||
g_message ("unable to write tile data to disk: %d ( %d ) bytes written", err, nleft);
|
||||
g_message ("unable to write tile data to disk: %s (%d/%d bytes written)",
|
||||
g_strerror (errno), err, nleft);
|
||||
write_err_msg = FALSE;
|
||||
return;
|
||||
}
|
||||
|
@ -627,15 +634,15 @@ tile_swap_default_out (DefSwapFile *def_swap_file,
|
|||
|
||||
static void
|
||||
tile_swap_default_delete (DefSwapFile *def_swap_file,
|
||||
int fd,
|
||||
gint fd,
|
||||
Tile *tile)
|
||||
{
|
||||
GList *tmp;
|
||||
GList *tmp2;
|
||||
Gap *gap;
|
||||
Gap *gap2;
|
||||
long start;
|
||||
long end;
|
||||
Gap *gap;
|
||||
Gap *gap2;
|
||||
glong start;
|
||||
glong end;
|
||||
|
||||
if (tile->swap_offset == -1)
|
||||
return;
|
||||
|
@ -660,7 +667,8 @@ tile_swap_default_delete (DefSwapFile *def_swap_file,
|
|||
{
|
||||
gap2->end = gap->end;
|
||||
tile_swap_gap_destroy (gap);
|
||||
def_swap_file->gaps = g_list_remove_link (def_swap_file->gaps, tmp);
|
||||
def_swap_file->gaps =
|
||||
g_list_remove_link (def_swap_file->gaps, tmp);
|
||||
g_list_free (tmp);
|
||||
}
|
||||
}
|
||||
|
@ -677,7 +685,8 @@ tile_swap_default_delete (DefSwapFile *def_swap_file,
|
|||
{
|
||||
gap2->start = gap->start;
|
||||
tile_swap_gap_destroy (gap);
|
||||
def_swap_file->gaps = g_list_remove_link (def_swap_file->gaps, tmp);
|
||||
def_swap_file->gaps =
|
||||
g_list_remove_link (def_swap_file->gaps, tmp);
|
||||
g_list_free (tmp);
|
||||
}
|
||||
}
|
||||
|
@ -731,26 +740,25 @@ tile_swap_default_delete (DefSwapFile *def_swap_file,
|
|||
|
||||
static void
|
||||
tile_swap_resize (DefSwapFile *def_swap_file,
|
||||
int fd,
|
||||
long new_size)
|
||||
gint fd,
|
||||
glong new_size)
|
||||
{
|
||||
if (def_swap_file->swap_file_end > new_size)
|
||||
{
|
||||
ftruncate (fd, new_size);
|
||||
/*fprintf(stderr, "TRUNCATED SWAP from %d to %d bytes.\n",
|
||||
(int)def_swap_file->swap_file_end, (int) new_size);*/
|
||||
}
|
||||
|
||||
def_swap_file->swap_file_end = new_size;
|
||||
}
|
||||
|
||||
static long
|
||||
tile_swap_find_offset (DefSwapFile *def_swap_file,
|
||||
int fd,
|
||||
int bytes)
|
||||
gint fd,
|
||||
gint bytes)
|
||||
{
|
||||
GList *tmp;
|
||||
Gap *gap;
|
||||
long offset;
|
||||
Gap *gap;
|
||||
glong offset;
|
||||
|
||||
tmp = def_swap_file->gaps;
|
||||
while (tmp)
|
||||
|
@ -765,7 +773,8 @@ tile_swap_find_offset (DefSwapFile *def_swap_file,
|
|||
if (gap->start == gap->end)
|
||||
{
|
||||
tile_swap_gap_destroy (gap);
|
||||
def_swap_file->gaps = g_list_remove_link (def_swap_file->gaps, tmp);
|
||||
def_swap_file->gaps =
|
||||
g_list_remove_link (def_swap_file->gaps, tmp);
|
||||
g_list_free (tmp);
|
||||
}
|
||||
|
||||
|
@ -777,7 +786,8 @@ tile_swap_find_offset (DefSwapFile *def_swap_file,
|
|||
|
||||
offset = def_swap_file->swap_file_end;
|
||||
|
||||
tile_swap_resize (def_swap_file, fd, def_swap_file->swap_file_end + swap_file_grow);
|
||||
tile_swap_resize (def_swap_file, fd,
|
||||
def_swap_file->swap_file_end + swap_file_grow);
|
||||
|
||||
if ((offset + bytes) < (def_swap_file->swap_file_end))
|
||||
{
|
||||
|
@ -788,9 +798,9 @@ tile_swap_find_offset (DefSwapFile *def_swap_file,
|
|||
return offset;
|
||||
}
|
||||
|
||||
static Gap*
|
||||
tile_swap_gap_new (long start,
|
||||
long end)
|
||||
static Gap *
|
||||
tile_swap_gap_new (glong start,
|
||||
glong end)
|
||||
{
|
||||
Gap *gap;
|
||||
|
||||
|
@ -822,12 +832,12 @@ tile_swap_gap_destroy (Gap *gap)
|
|||
|
||||
static void
|
||||
tile_swap_in_attempt (DefSwapFile *def_swap_file,
|
||||
int fd,
|
||||
gint fd,
|
||||
Tile *tile)
|
||||
{
|
||||
int bytes;
|
||||
int err;
|
||||
int nleft;
|
||||
gint bytes;
|
||||
gint err;
|
||||
gint nleft;
|
||||
off_t offset;
|
||||
|
||||
err = -1;
|
||||
|
@ -854,9 +864,11 @@ tile_swap_in_attempt (DefSwapFile *def_swap_file,
|
|||
nleft = bytes;
|
||||
while (nleft > 0)
|
||||
{
|
||||
do {
|
||||
err = read (fd, tile->data + bytes - nleft, nleft);
|
||||
} while ((err == -1) && ((errno == EAGAIN) || (errno == EINTR)));
|
||||
do
|
||||
{
|
||||
err = read (fd, tile->data + bytes - nleft, nleft);
|
||||
}
|
||||
while ((err == -1) && ((errno == EAGAIN) || (errno == EINTR)));
|
||||
|
||||
if (err <= 0)
|
||||
{
|
||||
|
@ -873,13 +885,13 @@ out:
|
|||
TILE_MUTEX_UNLOCK (tile);
|
||||
}
|
||||
|
||||
static void *
|
||||
tile_swap_in_thread (void *data)
|
||||
static gpointer
|
||||
tile_swap_in_thread (gpointer data)
|
||||
{
|
||||
AsyncSwapArgs *args;
|
||||
GSList *free_item;
|
||||
GSList *free_item;
|
||||
|
||||
while (1)
|
||||
while (TRUE)
|
||||
{
|
||||
pthread_mutex_lock (&async_swapin_mutex);
|
||||
|
||||
|
@ -892,6 +904,7 @@ tile_swap_in_thread (void *data)
|
|||
free_item = async_swapin_tiles;
|
||||
async_swapin_tiles = async_swapin_tiles->next;
|
||||
g_slist_free_1(free_item);
|
||||
|
||||
if (!async_swapin_tiles)
|
||||
async_swapin_tiles_end = NULL;
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ typedef enum
|
|||
} SwapCommand;
|
||||
|
||||
typedef gint (*SwapFunc) (gint fd,
|
||||
Tile *tile,
|
||||
Tile *tile,
|
||||
gint cmd,
|
||||
gpointer user_data);
|
||||
|
||||
|
|
|
@ -18,11 +18,9 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <apptypes.h>
|
||||
#include "apptypes.h"
|
||||
|
||||
#include "tile.h"
|
||||
#include "tile_pvt.h"
|
||||
|
@ -168,7 +166,6 @@ tile_lock (Tile *tile)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
tile_release (Tile *tile, int dirty)
|
||||
{
|
||||
|
@ -280,7 +277,6 @@ tile_destroy (Tile *tile)
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
gint
|
||||
tile_size (Tile *tile)
|
||||
{
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
#include "pixel_processor.h"
|
||||
#include "pixel_region.h"
|
||||
#include "tile_manager.h"
|
||||
#include "tile_pvt.h"
|
||||
#include "tile.h"
|
||||
|
||||
#include "libgimp/gimpmath.h"
|
||||
|
@ -161,7 +160,7 @@ update_tile_rowhints (Tile *tile,
|
|||
tile_sanitize_rowhints (tile);
|
||||
|
||||
bpp = tile_bpp (tile);
|
||||
ewidth = tile->ewidth;
|
||||
ewidth = tile_ewidth (tile);
|
||||
|
||||
if (bpp == 1 || bpp == 3)
|
||||
{
|
||||
|
@ -3458,10 +3457,10 @@ copy_region (PixelRegion *src,
|
|||
src->curtile && dest->curtile &&
|
||||
src->offx == 0 && dest->offx == 0 &&
|
||||
src->offy == 0 && dest->offy == 0 &&
|
||||
src->w == (src->curtile->ewidth) &&
|
||||
dest->w == (dest->curtile->ewidth) &&
|
||||
src->h == tile_eheight(src->curtile) &&
|
||||
dest->h == tile_eheight(dest->curtile))
|
||||
src->w == tile_ewidth (src->curtile) &&
|
||||
dest->w == tile_ewidth (dest->curtile) &&
|
||||
src->h == tile_eheight (src->curtile) &&
|
||||
dest->h == tile_eheight (dest->curtile))
|
||||
{
|
||||
#ifdef COWSHOW
|
||||
fputc('!',stderr);
|
||||
|
@ -4639,12 +4638,15 @@ shapeburst_region (PixelRegion *srcPR,
|
|||
|
||||
while (y >= end)
|
||||
{
|
||||
tile = tile_manager_get_tile (srcPR->tiles, x, y, TRUE, FALSE);
|
||||
tile_data = tile_data_pointer (tile, x%TILE_WIDTH, y%TILE_HEIGHT);
|
||||
tile = tile_manager_get_tile (srcPR->tiles,
|
||||
x, y, TRUE, FALSE);
|
||||
tile_data = tile_data_pointer (tile,
|
||||
x % TILE_WIDTH,
|
||||
y % TILE_HEIGHT);
|
||||
boundary = MIN ((y % TILE_HEIGHT),
|
||||
(tile->ewidth - (x % TILE_WIDTH) - 1));
|
||||
(tile_ewidth (tile) - (x % TILE_WIDTH) - 1));
|
||||
boundary = MIN (boundary, (y - end)) + 1;
|
||||
inc = 1 - (tile->ewidth);
|
||||
inc = 1 - tile_ewidth (tile);
|
||||
|
||||
while (boundary--)
|
||||
{
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
#include "pixel_processor.h"
|
||||
#include "pixel_region.h"
|
||||
#include "tile_manager.h"
|
||||
#include "tile_pvt.h"
|
||||
#include "tile.h"
|
||||
|
||||
#include "libgimp/gimpmath.h"
|
||||
|
@ -161,7 +160,7 @@ update_tile_rowhints (Tile *tile,
|
|||
tile_sanitize_rowhints (tile);
|
||||
|
||||
bpp = tile_bpp (tile);
|
||||
ewidth = tile->ewidth;
|
||||
ewidth = tile_ewidth (tile);
|
||||
|
||||
if (bpp == 1 || bpp == 3)
|
||||
{
|
||||
|
@ -3458,10 +3457,10 @@ copy_region (PixelRegion *src,
|
|||
src->curtile && dest->curtile &&
|
||||
src->offx == 0 && dest->offx == 0 &&
|
||||
src->offy == 0 && dest->offy == 0 &&
|
||||
src->w == (src->curtile->ewidth) &&
|
||||
dest->w == (dest->curtile->ewidth) &&
|
||||
src->h == tile_eheight(src->curtile) &&
|
||||
dest->h == tile_eheight(dest->curtile))
|
||||
src->w == tile_ewidth (src->curtile) &&
|
||||
dest->w == tile_ewidth (dest->curtile) &&
|
||||
src->h == tile_eheight (src->curtile) &&
|
||||
dest->h == tile_eheight (dest->curtile))
|
||||
{
|
||||
#ifdef COWSHOW
|
||||
fputc('!',stderr);
|
||||
|
@ -4639,12 +4638,15 @@ shapeburst_region (PixelRegion *srcPR,
|
|||
|
||||
while (y >= end)
|
||||
{
|
||||
tile = tile_manager_get_tile (srcPR->tiles, x, y, TRUE, FALSE);
|
||||
tile_data = tile_data_pointer (tile, x%TILE_WIDTH, y%TILE_HEIGHT);
|
||||
tile = tile_manager_get_tile (srcPR->tiles,
|
||||
x, y, TRUE, FALSE);
|
||||
tile_data = tile_data_pointer (tile,
|
||||
x % TILE_WIDTH,
|
||||
y % TILE_HEIGHT);
|
||||
boundary = MIN ((y % TILE_HEIGHT),
|
||||
(tile->ewidth - (x % TILE_WIDTH) - 1));
|
||||
(tile_ewidth (tile) - (x % TILE_WIDTH) - 1));
|
||||
boundary = MIN (boundary, (y - end)) + 1;
|
||||
inc = 1 - (tile->ewidth);
|
||||
inc = 1 - tile_ewidth (tile);
|
||||
|
||||
while (boundary--)
|
||||
{
|
||||
|
|
|
@ -20,10 +20,6 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef ENABLE_MP
|
||||
#include <pthread.h>
|
||||
#define IF_THREAD(statement) statement
|
||||
|
@ -31,9 +27,9 @@
|
|||
#define IF_THREAD(statement)
|
||||
#endif /* ENABLE_MP */
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include <apptypes.h>
|
||||
#include "apptypes.h"
|
||||
|
||||
#include "pixel_processor.h"
|
||||
#include "pixel_region.h"
|
||||
|
@ -75,7 +71,7 @@ struct _PixelProcessor
|
|||
|
||||
IF_THREAD(
|
||||
static void *
|
||||
do_parallel_regions (PixelProcessor *p_s)
|
||||
do_parallel_regions (PixelProcessor *p_s)
|
||||
{
|
||||
PixelRegion tr[4];
|
||||
int ntiles = 0;
|
||||
|
@ -161,7 +157,7 @@ do_parallel_regions (PixelProcessor *p_s)
|
|||
(p_s->PRI = (PixelRegionIterator*)pixel_regions_process(p_s->PRI)));
|
||||
|
||||
p_s->nthreads--;
|
||||
/* fprintf(stderr, "processed %d tiles\n", ntiles); */
|
||||
|
||||
pthread_mutex_unlock(&p_s->mutex);
|
||||
|
||||
return NULL;
|
||||
|
@ -176,30 +172,33 @@ do_parallel_regions (PixelProcessor *p_s)
|
|||
* configured --with-mp
|
||||
*/
|
||||
|
||||
static void *
|
||||
do_parallel_regions_single(PixelProcessor *p_s)
|
||||
static gpointer
|
||||
do_parallel_regions_single (PixelProcessor *p_s)
|
||||
{
|
||||
int cont = 1;
|
||||
gint cont = 1;
|
||||
|
||||
do
|
||||
{
|
||||
switch(p_s->n_regions)
|
||||
switch (p_s->n_regions)
|
||||
{
|
||||
case 1:
|
||||
((p1_func)p_s->f)(p_s->data,
|
||||
p_s->r[0]);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
((p2_func)p_s->f)(p_s->data,
|
||||
p_s->r[0],
|
||||
p_s->r[1]);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
((p3_func)p_s->f)(p_s->data,
|
||||
p_s->r[0],
|
||||
p_s->r[1],
|
||||
p_s->r[2]);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
((p4_func)p_s->f)(p_s->data,
|
||||
p_s->r[0],
|
||||
|
@ -207,180 +206,207 @@ do_parallel_regions_single(PixelProcessor *p_s)
|
|||
p_s->r[2],
|
||||
p_s->r[3]);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_message("do_parallel_regions_single: Bad number of regions %d\n",
|
||||
p_s->n_regions);
|
||||
}
|
||||
|
||||
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,
|
||||
p_s->r[0]->w, p_s->r[0]->h))
|
||||
if (!p_s->progress_report_func (p_s->progress_report_data,
|
||||
p_s->r[0]->x, p_s->r[0]->y,
|
||||
p_s->r[0]->w, p_s->r[0]->h))
|
||||
cont = 0;
|
||||
} while (cont && p_s->PRI &&
|
||||
(p_s->PRI = (PixelRegionIterator*)pixel_regions_process(p_s->PRI)));
|
||||
}
|
||||
while (cont && p_s->PRI &&
|
||||
(p_s->PRI = (PixelRegionIterator*)pixel_regions_process(p_s->PRI)));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define MAX_THREADS 30
|
||||
|
||||
static void
|
||||
pixel_regions_do_parallel(PixelProcessor *p_s)
|
||||
pixel_regions_do_parallel (PixelProcessor *p_s)
|
||||
{
|
||||
IF_THREAD(
|
||||
int nthreads;
|
||||
nthreads = MIN(num_processors, MAX_THREADS);
|
||||
IF_THREAD(
|
||||
gint nthreads;
|
||||
|
||||
nthreads = MIN (num_processors, MAX_THREADS);
|
||||
|
||||
/* make sure we have at least one tile per thread */
|
||||
nthreads = MIN(nthreads,
|
||||
(p_s->PRI->region_width * p_s->PRI->region_height)
|
||||
/(TILE_WIDTH*TILE_HEIGHT));
|
||||
/* make sure we have at least one tile per thread */
|
||||
nthreads = MIN (nthreads,
|
||||
(p_s->PRI->region_width * p_s->PRI->region_height)
|
||||
/ (TILE_WIDTH * TILE_HEIGHT));
|
||||
|
||||
if (nthreads > 1)
|
||||
if (nthreads > 1)
|
||||
{
|
||||
int i;
|
||||
gint i;
|
||||
pthread_t threads[MAX_THREADS];
|
||||
pthread_attr_t pthread_attr;
|
||||
|
||||
pthread_attr_init (&pthread_attr);
|
||||
|
||||
for (i = 0; i < nthreads; i++)
|
||||
{
|
||||
pthread_create (&threads[i], &pthread_attr,
|
||||
(void *(*)(void *)) do_parallel_regions,
|
||||
p_s);
|
||||
}
|
||||
{
|
||||
pthread_create (&threads[i], &pthread_attr,
|
||||
(void *(*)(void *)) do_parallel_regions,
|
||||
p_s);
|
||||
}
|
||||
for (i = 0; i < nthreads; i++)
|
||||
{
|
||||
int ret;
|
||||
if ((ret = pthread_join(threads[i], NULL)))
|
||||
{
|
||||
fprintf(stderr, "pixel_regions_do_parallel:: pthread_join returned: %d\n", ret);
|
||||
}
|
||||
}
|
||||
{
|
||||
gint ret;
|
||||
|
||||
if ((ret = pthread_join(threads[i], NULL)))
|
||||
{
|
||||
g_printerr ("pixel_regions_do_parallel:: pthread_join returned: %d\n", ret);
|
||||
}
|
||||
}
|
||||
if (p_s->nthreads != 0)
|
||||
fprintf(stderr, "pixel_regions_do_prarallel: we lost a thread\n");
|
||||
g_printerr ("pixel_regions_do_prarallel: we lost a thread\n");
|
||||
}
|
||||
else
|
||||
)
|
||||
do_parallel_regions_single(p_s);
|
||||
else
|
||||
)
|
||||
do_parallel_regions_single (p_s);
|
||||
}
|
||||
|
||||
static PixelProcessor *
|
||||
pixel_regions_real_process_parallel(p_func f, void *data,
|
||||
ProgressReportFunc report_func,
|
||||
void *report_data,
|
||||
int num_regions, va_list ap)
|
||||
pixel_regions_real_process_parallel (p_func f,
|
||||
gpointer data,
|
||||
ProgressReportFunc report_func,
|
||||
gpointer report_data,
|
||||
gint num_regions,
|
||||
va_list ap)
|
||||
{
|
||||
int i;
|
||||
gint i;
|
||||
PixelProcessor *p_s;
|
||||
|
||||
|
||||
p_s = g_new(PixelProcessor, 1);
|
||||
|
||||
p_s = g_new (PixelProcessor, 1);
|
||||
|
||||
for (i = 0; i < num_regions; i++)
|
||||
p_s->r[i] = va_arg (ap, PixelRegion *);
|
||||
|
||||
switch(num_regions)
|
||||
{
|
||||
case 1:
|
||||
p_s->PRI = (PixelRegionIterator *) pixel_regions_register(num_regions,
|
||||
p_s->r[0]);
|
||||
break;
|
||||
case 2:
|
||||
p_s->PRI = (PixelRegionIterator *) pixel_regions_register(num_regions,
|
||||
p_s->r[0],
|
||||
p_s->r[1]);
|
||||
{
|
||||
case 1:
|
||||
p_s->PRI = (PixelRegionIterator *) pixel_regions_register (num_regions,
|
||||
p_s->r[0]);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
p_s->PRI = (PixelRegionIterator *) pixel_regions_register (num_regions,
|
||||
p_s->r[0],
|
||||
p_s->r[1]);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
p_s->PRI = (PixelRegionIterator *) pixel_regions_register(num_regions,
|
||||
p_s->r[0],
|
||||
p_s->r[1],
|
||||
p_s->r[2]);
|
||||
p_s->PRI = (PixelRegionIterator *) pixel_regions_register (num_regions,
|
||||
p_s->r[0],
|
||||
p_s->r[1],
|
||||
p_s->r[2]);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
p_s->PRI = (PixelRegionIterator *) pixel_regions_register(num_regions,
|
||||
p_s->r[0],
|
||||
p_s->r[1],
|
||||
p_s->r[2],
|
||||
p_s->r[3]);
|
||||
p_s->PRI = (PixelRegionIterator *) pixel_regions_register (num_regions,
|
||||
p_s->r[0],
|
||||
p_s->r[1],
|
||||
p_s->r[2],
|
||||
p_s->r[3]);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_message("pixel_regions_real_process_parallel: Bad number of regions %d\n",
|
||||
p_s->n_regions);
|
||||
g_message ("pixel_regions_real_process_parallel: Bad number of regions %d\n",
|
||||
p_s->n_regions);
|
||||
}
|
||||
|
||||
if (!p_s->PRI)
|
||||
{
|
||||
pixel_processor_free(p_s);
|
||||
return NULL;
|
||||
}
|
||||
{
|
||||
pixel_processor_free (p_s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Why would we wan't to set dirty_tiles to 0 here? */
|
||||
/* IF_THREAD(p_s->PRI->dirty_tiles = 0;) */
|
||||
p_s->f = f;
|
||||
p_s->data = data;
|
||||
p_s->n_regions = num_regions;
|
||||
IF_THREAD(pthread_mutex_init(&(p_s->mutex), NULL);)
|
||||
IF_THREAD (pthread_mutex_init(&(p_s->mutex), NULL);)
|
||||
p_s->nthreads = 0;
|
||||
|
||||
p_s->progress_report_data = report_data;
|
||||
p_s->progress_report_func = report_func;
|
||||
|
||||
|
||||
pixel_regions_do_parallel(p_s);
|
||||
pixel_regions_do_parallel (p_s);
|
||||
|
||||
if (p_s->PRI)
|
||||
return p_s;
|
||||
|
||||
pixel_processor_free (p_s);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
pixel_regions_process_parallel(p_func f, void *data, int num_regions, ...)
|
||||
pixel_regions_process_parallel (p_func f,
|
||||
gpointer data,
|
||||
gint num_regions,
|
||||
...)
|
||||
{
|
||||
va_list va;
|
||||
|
||||
va_start (va, num_regions);
|
||||
|
||||
pixel_regions_real_process_parallel(f, data, NULL, NULL, num_regions, va);
|
||||
pixel_regions_real_process_parallel (f, data, NULL, NULL, num_regions, va);
|
||||
|
||||
va_end (va);
|
||||
}
|
||||
|
||||
PixelProcessor *
|
||||
pixel_regions_process_parallel_progress(p_func f, void *data,
|
||||
ProgressReportFunc progress_func,
|
||||
void *progress_data, int num_regions,
|
||||
...)
|
||||
pixel_regions_process_parallel_progress (p_func f,
|
||||
gpointer data,
|
||||
ProgressReportFunc progress_func,
|
||||
gpointer progress_data,
|
||||
gint num_regions,
|
||||
...)
|
||||
{
|
||||
PixelProcessor *ret;
|
||||
va_list va;
|
||||
va_start (va, num_regions);
|
||||
va_list va;
|
||||
|
||||
ret = pixel_regions_real_process_parallel(f, data,
|
||||
progress_func, progress_data,
|
||||
num_regions, va);
|
||||
va_start (va, num_regions);
|
||||
|
||||
ret = pixel_regions_real_process_parallel (f, data,
|
||||
progress_func, progress_data,
|
||||
num_regions, va);
|
||||
|
||||
va_end (va);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
pixel_processor_stop(PixelProcessor *pp)
|
||||
pixel_processor_stop (PixelProcessor *pp)
|
||||
{
|
||||
if (!pp)
|
||||
return;
|
||||
|
||||
if (pp->PRI)
|
||||
{
|
||||
pixel_regions_process_stop (pp->PRI);
|
||||
pp->PRI = NULL;
|
||||
}
|
||||
pixel_processor_free(pp);
|
||||
{
|
||||
pixel_regions_process_stop (pp->PRI);
|
||||
pp->PRI = NULL;
|
||||
}
|
||||
pixel_processor_free (pp);
|
||||
}
|
||||
|
||||
PixelProcessor *
|
||||
pixel_processor_cont(PixelProcessor *pp)
|
||||
pixel_processor_cont (PixelProcessor *pp)
|
||||
{
|
||||
pixel_regions_do_parallel(pp);
|
||||
pixel_regions_do_parallel (pp);
|
||||
|
||||
if (pp->PRI)
|
||||
return pp;
|
||||
|
||||
pixel_processor_free (pp);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -388,7 +414,7 @@ void
|
|||
pixel_processor_free (PixelProcessor *pp)
|
||||
{
|
||||
if (pp->PRI)
|
||||
pixel_processor_stop(pp);
|
||||
pixel_processor_stop (pp);
|
||||
else
|
||||
g_free(pp);
|
||||
}
|
||||
|
|
|
@ -18,11 +18,9 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <apptypes.h>
|
||||
#include "apptypes.h"
|
||||
|
||||
#include "tile.h"
|
||||
#include "tile_pvt.h"
|
||||
|
@ -168,7 +166,6 @@ tile_lock (Tile *tile)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
tile_release (Tile *tile, int dirty)
|
||||
{
|
||||
|
@ -280,7 +277,6 @@ tile_destroy (Tile *tile)
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
gint
|
||||
tile_size (Tile *tile)
|
||||
{
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef USE_PTHREADS
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
@ -37,23 +36,28 @@
|
|||
/* This is the percentage of the maximum cache size that should be cleared
|
||||
* from the cache when an eviction is necessary
|
||||
*/
|
||||
#define FREE_QUANTUM 0.1
|
||||
#define FREE_QUANTUM 0.1
|
||||
|
||||
static void tile_cache_init (void);
|
||||
static gint tile_cache_zorch_next (void);
|
||||
static void tile_cache_flush_internal (Tile *tile);
|
||||
#define IDLE_SWAPPER_TIMEOUT 250
|
||||
|
||||
|
||||
static void tile_cache_init (void);
|
||||
static gint tile_cache_zorch_next (void);
|
||||
static void tile_cache_flush_internal (Tile *tile);
|
||||
|
||||
#ifdef USE_PTHREADS
|
||||
static void* tile_idle_thread (void *);
|
||||
static gpointer tile_idle_thread (gpointer data);
|
||||
#else
|
||||
static gint tile_idle_preswap (gpointer);
|
||||
static gint tile_idle_preswap (gpointer data);
|
||||
#endif
|
||||
|
||||
|
||||
static int initialize = TRUE;
|
||||
|
||||
typedef struct _TileList {
|
||||
Tile* first;
|
||||
Tile* last;
|
||||
typedef struct _TileList
|
||||
{
|
||||
Tile *first;
|
||||
Tile *last;
|
||||
} TileList;
|
||||
|
||||
static unsigned long max_tile_size = TILE_WIDTH * TILE_HEIGHT * 4;
|
||||
|
@ -222,7 +226,7 @@ tile_cache_flush_internal (Tile *tile)
|
|||
|
||||
/* untested -- ADM */
|
||||
void
|
||||
tile_cache_set_size (unsigned long cache_size)
|
||||
tile_cache_set_size (gulong cache_size)
|
||||
{
|
||||
if (initialize)
|
||||
tile_cache_init ();
|
||||
|
@ -239,7 +243,7 @@ tile_cache_set_size (unsigned long cache_size)
|
|||
|
||||
|
||||
static void
|
||||
tile_cache_init ()
|
||||
tile_cache_init (void)
|
||||
{
|
||||
if (initialize)
|
||||
{
|
||||
|
@ -253,7 +257,7 @@ tile_cache_init ()
|
|||
#ifdef USE_PTHREADS
|
||||
pthread_create (&preswap_thread, NULL, &tile_idle_thread, NULL);
|
||||
#else
|
||||
idle_swapper = gtk_timeout_add (250,
|
||||
idle_swapper = gtk_timeout_add (IDLE_SWAPPER_TIMEOUT,
|
||||
(GtkFunction) tile_idle_preswap,
|
||||
(gpointer) 0);
|
||||
#endif
|
||||
|
@ -261,15 +265,16 @@ tile_cache_init ()
|
|||
}
|
||||
|
||||
static gint
|
||||
tile_cache_zorch_next ()
|
||||
tile_cache_zorch_next (void)
|
||||
{
|
||||
Tile *tile;
|
||||
|
||||
/* fprintf(stderr, "cache zorch: %u/%u\n", cur_cache_size, cur_cache_dirty);*/
|
||||
|
||||
if (clean_list.first) tile = clean_list.first;
|
||||
else if (dirty_list.first) tile = dirty_list.first;
|
||||
else return FALSE;
|
||||
if (clean_list.first)
|
||||
tile = clean_list.first;
|
||||
else if (dirty_list.first)
|
||||
tile = dirty_list.first;
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
CACHE_UNLOCK;
|
||||
TILE_MUTEX_LOCK (tile);
|
||||
|
@ -279,29 +284,34 @@ tile_cache_zorch_next ()
|
|||
{
|
||||
tile_swap_out (tile);
|
||||
}
|
||||
if (! tile->dirty) {
|
||||
g_free (tile->data);
|
||||
tile->data = NULL;
|
||||
TILE_MUTEX_UNLOCK (tile);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (! tile->dirty)
|
||||
{
|
||||
g_free (tile->data);
|
||||
tile->data = NULL;
|
||||
TILE_MUTEX_UNLOCK (tile);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* unable to swap out tile for some reason */
|
||||
TILE_MUTEX_UNLOCK (tile);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#if USE_PTHREADS
|
||||
static void *
|
||||
tile_idle_thread (void *data)
|
||||
static gpointer
|
||||
tile_idle_thread (gpointer data)
|
||||
{
|
||||
Tile *tile;
|
||||
Tile *tile;
|
||||
TileList *list;
|
||||
int count;
|
||||
gint count;
|
||||
|
||||
fprintf (stderr, "starting tile preswapper\n");
|
||||
g_printerr ("starting tile preswapper\n");
|
||||
|
||||
count = 0;
|
||||
while (1)
|
||||
while (TRUE)
|
||||
{
|
||||
CACHE_LOCK;
|
||||
if (count > 5 || dirty_list.first == NULL)
|
||||
|
|
|
@ -18,19 +18,17 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include "apptypes.h"
|
||||
|
||||
#include "tile.h"
|
||||
#include "tile_pvt.h"
|
||||
#include "tile_cache.h"
|
||||
#include "tile_manager.h"
|
||||
#include "tile_manager_pvt.h"
|
||||
#include "tile_swap.h"
|
||||
|
||||
#include "tile_pvt.h" /* ick. */
|
||||
|
||||
|
||||
static gint tile_manager_get_tile_num (TileManager *tm,
|
||||
gint xpixel,
|
||||
|
@ -301,8 +299,8 @@ tile_manager_invalidate_tiles (TileManager *tm,
|
|||
col = toplevel_tile->tlink->tile_num % tm->ntile_cols;
|
||||
row = toplevel_tile->tlink->tile_num / tm->ntile_cols;
|
||||
|
||||
x = (col * TILE_WIDTH + toplevel_tile->ewidth / 2.0) / (double) tm->width;
|
||||
y = (row * TILE_HEIGHT + toplevel_tile->eheight / 2.0) / (double) tm->height;
|
||||
x = (col * TILE_WIDTH + toplevel_tile->ewidth / 2.0) / (gdouble) tm->width;
|
||||
y = (row * TILE_HEIGHT + toplevel_tile->eheight / 2.0) / (gdouble) tm->height;
|
||||
|
||||
if (tm->tiles)
|
||||
{
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#define __TILE_PVT_H__
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef USE_PTHREADS
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
@ -9,20 +11,18 @@
|
|||
#include <sys/types.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "tile.h"
|
||||
|
||||
typedef struct _TileLink TileLink;
|
||||
|
||||
struct _TileLink
|
||||
{
|
||||
TileLink *next;
|
||||
int tile_num; /* the number of this tile within the drawable */
|
||||
void *tm; /* A pointer to the tile manager for this tile.
|
||||
* We need this in order to call the tile managers
|
||||
* validate proc whenever the tile is referenced yet
|
||||
* invalid.
|
||||
*/
|
||||
TileLink *next;
|
||||
gint tile_num; /* the number of this tile within the drawable */
|
||||
TileManager *tm; /* A pointer to the tile manager for this tile.
|
||||
* We need this in order to call the tile managers
|
||||
* validate proc whenever the tile is referenced
|
||||
* yet invalid.
|
||||
*/
|
||||
};
|
||||
|
||||
struct _Tile
|
||||
|
|
267
app/tile_swap.c
267
app/tile_swap.c
|
@ -18,11 +18,9 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
@ -47,8 +45,9 @@
|
|||
#include "apptypes.h"
|
||||
|
||||
#include "tile.h"
|
||||
#include "tile_pvt.h"
|
||||
#include "tile_swap.h"
|
||||
#include "tile_pvt.h" /* ick. */
|
||||
|
||||
|
||||
#define MAX_OPEN_SWAP_FILES 16
|
||||
|
||||
|
@ -59,96 +58,97 @@ typedef struct _AsyncSwapArgs AsyncSwapArgs;
|
|||
|
||||
struct _SwapFile
|
||||
{
|
||||
char *filename;
|
||||
int swap_num;
|
||||
SwapFunc swap_func;
|
||||
gpointer user_data;
|
||||
int fd;
|
||||
gchar *filename;
|
||||
gint swap_num;
|
||||
SwapFunc swap_func;
|
||||
gpointer user_data;
|
||||
gint fd;
|
||||
};
|
||||
|
||||
struct _DefSwapFile
|
||||
{
|
||||
GList *gaps;
|
||||
long swap_file_end;
|
||||
off_t cur_position;
|
||||
glong swap_file_end;
|
||||
off_t cur_position;
|
||||
};
|
||||
|
||||
struct _Gap
|
||||
{
|
||||
long start;
|
||||
long end;
|
||||
glong start;
|
||||
glong end;
|
||||
};
|
||||
|
||||
struct _AsyncSwapArgs
|
||||
{
|
||||
DefSwapFile *def_swap_file;
|
||||
int fd;
|
||||
gint fd;
|
||||
Tile *tile;
|
||||
};
|
||||
|
||||
|
||||
static void tile_swap_init (void);
|
||||
static guint tile_swap_hash (int *key);
|
||||
static gint tile_swap_compare (int *a,
|
||||
int *b);
|
||||
static void tile_swap_command (Tile *tile,
|
||||
int command);
|
||||
static void tile_swap_open (SwapFile *swap_file);
|
||||
static void tile_swap_init (void);
|
||||
static guint tile_swap_hash (gint *key);
|
||||
static gint tile_swap_compare (gint *a,
|
||||
gint *b);
|
||||
static void tile_swap_command (Tile *tile,
|
||||
gint command);
|
||||
static void tile_swap_open (SwapFile *swap_file);
|
||||
|
||||
static int tile_swap_default (int fd,
|
||||
Tile *tile,
|
||||
int cmd,
|
||||
gpointer user_data);
|
||||
static void tile_swap_default_in (DefSwapFile *def_swap_file,
|
||||
int fd,
|
||||
Tile *tile);
|
||||
static void tile_swap_default_in_async (DefSwapFile *def_swap_file,
|
||||
int fd,
|
||||
Tile *tile);
|
||||
static void tile_swap_default_out (DefSwapFile *def_swap_file,
|
||||
int fd,
|
||||
Tile *tile);
|
||||
static void tile_swap_default_delete (DefSwapFile *def_swap_file,
|
||||
int fd,
|
||||
Tile *tile);
|
||||
static long tile_swap_find_offset (DefSwapFile *def_swap_file,
|
||||
int fd,
|
||||
int bytes);
|
||||
static void tile_swap_resize (DefSwapFile *def_swap_file,
|
||||
int fd,
|
||||
long new_size);
|
||||
static Gap* tile_swap_gap_new (long start,
|
||||
long end);
|
||||
static void tile_swap_gap_destroy (Gap *gap);
|
||||
static gint tile_swap_default (gint fd,
|
||||
Tile *tile,
|
||||
gint cmd,
|
||||
gpointer user_data);
|
||||
static void tile_swap_default_in (DefSwapFile *def_swap_file,
|
||||
gint fd,
|
||||
Tile *tile);
|
||||
static void tile_swap_default_in_async (DefSwapFile *def_swap_file,
|
||||
gint fd,
|
||||
Tile *tile);
|
||||
static void tile_swap_default_out (DefSwapFile *def_swap_file,
|
||||
gint fd,
|
||||
Tile *tile);
|
||||
static void tile_swap_default_delete (DefSwapFile *def_swap_file,
|
||||
gint fd,
|
||||
Tile *tile);
|
||||
static glong tile_swap_find_offset (DefSwapFile *def_swap_file,
|
||||
gint fd,
|
||||
gint bytes);
|
||||
static void tile_swap_resize (DefSwapFile *def_swap_file,
|
||||
gint fd,
|
||||
glong new_size);
|
||||
static Gap * tile_swap_gap_new (glong start,
|
||||
glong end);
|
||||
static void tile_swap_gap_destroy (Gap *gap);
|
||||
#ifdef USE_PTHREADS
|
||||
static void* tile_swap_in_thread (void *);
|
||||
static gpointer tile_swap_in_thread (gpointer);
|
||||
#endif
|
||||
|
||||
|
||||
static int initialize = TRUE;
|
||||
static GHashTable *swap_files = NULL;
|
||||
static GList *open_swap_files = NULL;
|
||||
static int nopen_swap_files = 0;
|
||||
static int next_swap_num = 1;
|
||||
static long swap_file_grow = 16 * TILE_WIDTH * TILE_HEIGHT * 4;
|
||||
static gboolean initialize = TRUE;
|
||||
static GHashTable * swap_files = NULL;
|
||||
static GList * open_swap_files = NULL;
|
||||
static gint nopen_swap_files = 0;
|
||||
static gint next_swap_num = 1;
|
||||
static glong swap_file_grow = 16 * TILE_WIDTH * TILE_HEIGHT * 4;
|
||||
#ifdef USE_PTHREADS
|
||||
static pthread_mutex_t swapfile_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_mutex_t swapfile_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/* async_swapin_mutex protects only the list, not the tiles therein */
|
||||
static pthread_t swapin_thread;
|
||||
static pthread_mutex_t async_swapin_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t async_swapin_signal = PTHREAD_COND_INITIALIZER;
|
||||
static GSList *async_swapin_tiles = NULL;
|
||||
static GSList *async_swapin_tiles_end = NULL;
|
||||
static pthread_t swapin_thread;
|
||||
static pthread_mutex_t async_swapin_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t async_swapin_signal = PTHREAD_COND_INITIALIZER;
|
||||
static GSList * async_swapin_tiles = NULL;
|
||||
static GSList * async_swapin_tiles_end = NULL;
|
||||
#endif
|
||||
|
||||
static gboolean seek_err_msg = TRUE, read_err_msg = TRUE, write_err_msg = TRUE;
|
||||
|
||||
|
||||
static void
|
||||
tile_swap_print_gaps (DefSwapFile *def_swap_file)
|
||||
{
|
||||
GList *gaps;
|
||||
Gap *gap;
|
||||
Gap *gap;
|
||||
|
||||
gaps = def_swap_file->gaps;
|
||||
while (gaps)
|
||||
|
@ -165,8 +165,8 @@ tile_swap_exit1 (gpointer key,
|
|||
gpointer value,
|
||||
gpointer data)
|
||||
{
|
||||
extern int tile_ref_count;
|
||||
SwapFile *swap_file;
|
||||
extern gint tile_ref_count;
|
||||
SwapFile *swap_file;
|
||||
DefSwapFile *def_swap_file;
|
||||
|
||||
if (tile_ref_count != 0)
|
||||
|
@ -194,27 +194,26 @@ tile_swap_exit1 (gpointer key,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
tile_swap_exit ()
|
||||
tile_swap_exit (void)
|
||||
{
|
||||
#ifdef HINTS_SANITY
|
||||
extern int tile_exist_peak;
|
||||
|
||||
fprintf(stderr,"Tile exist peak was %d Tile structs (%d bytes)",
|
||||
tile_exist_peak, tile_exist_peak * sizeof(Tile));
|
||||
g_printerr ("Tile exist peak was %d Tile structs (%d bytes)",
|
||||
tile_exist_peak, tile_exist_peak * sizeof(Tile));
|
||||
#endif
|
||||
|
||||
if (swap_files)
|
||||
g_hash_table_foreach (swap_files, tile_swap_exit1, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
tile_swap_add (char *filename,
|
||||
gint
|
||||
tile_swap_add (gchar *filename,
|
||||
SwapFunc swap_func,
|
||||
gpointer user_data)
|
||||
{
|
||||
SwapFile *swap_file;
|
||||
SwapFile *swap_file;
|
||||
DefSwapFile *def_swap_file;
|
||||
|
||||
#ifdef USE_PTHREADS
|
||||
|
@ -253,7 +252,7 @@ tile_swap_add (char *filename,
|
|||
}
|
||||
|
||||
void
|
||||
tile_swap_remove (int swap_num)
|
||||
tile_swap_remove (gint swap_num)
|
||||
{
|
||||
SwapFile *swap_file;
|
||||
|
||||
|
@ -315,13 +314,13 @@ tile_swap_delete (Tile *tile)
|
|||
}
|
||||
|
||||
void
|
||||
tile_swap_compress (int swap_num)
|
||||
tile_swap_compress (gint swap_num)
|
||||
{
|
||||
tile_swap_command (NULL, SWAP_COMPRESS);
|
||||
}
|
||||
|
||||
static void
|
||||
tile_swap_init ()
|
||||
tile_swap_init (void)
|
||||
{
|
||||
|
||||
if (initialize)
|
||||
|
@ -338,21 +337,21 @@ tile_swap_init ()
|
|||
}
|
||||
|
||||
static guint
|
||||
tile_swap_hash (int *key)
|
||||
tile_swap_hash (gint *key)
|
||||
{
|
||||
return ((guint) *key);
|
||||
return (guint) *key;
|
||||
}
|
||||
|
||||
static gint
|
||||
tile_swap_compare (int *a,
|
||||
int *b)
|
||||
tile_swap_compare (gint *a,
|
||||
gint *b)
|
||||
{
|
||||
return (*a == *b);
|
||||
}
|
||||
|
||||
static void
|
||||
tile_swap_command (Tile *tile,
|
||||
int command)
|
||||
gint command)
|
||||
{
|
||||
SwapFile *swap_file;
|
||||
#ifdef USE_PTHREADS
|
||||
|
@ -377,11 +376,15 @@ tile_swap_command (Tile *tile,
|
|||
if (swap_file->fd == -1)
|
||||
goto out;
|
||||
}
|
||||
} while ((* swap_file->swap_func) (swap_file->fd, tile, command, swap_file->user_data));
|
||||
}
|
||||
while ((* swap_file->swap_func) (swap_file->fd,
|
||||
tile, command, swap_file->user_data));
|
||||
|
||||
out:
|
||||
#ifdef USE_PTHREADS
|
||||
pthread_mutex_unlock(&swapfile_mutex);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -427,9 +430,9 @@ tile_swap_open (SwapFile *swap_file)
|
|||
*/
|
||||
|
||||
static int
|
||||
tile_swap_default (int fd,
|
||||
tile_swap_default (gint fd,
|
||||
Tile *tile,
|
||||
int cmd,
|
||||
gint cmd,
|
||||
gpointer user_data)
|
||||
{
|
||||
DefSwapFile *def_swap_file;
|
||||
|
@ -460,7 +463,7 @@ tile_swap_default (int fd,
|
|||
|
||||
static void
|
||||
tile_swap_default_in_async (DefSwapFile *def_swap_file,
|
||||
int fd,
|
||||
gint fd,
|
||||
Tile *tile)
|
||||
{
|
||||
#ifdef NOTDEF /* USE_PTHREADS */
|
||||
|
@ -506,12 +509,12 @@ tile_swap_default_in_async (DefSwapFile *def_swap_file,
|
|||
*/
|
||||
static void
|
||||
tile_swap_default_in (DefSwapFile *def_swap_file,
|
||||
int fd,
|
||||
gint fd,
|
||||
Tile *tile)
|
||||
{
|
||||
int bytes;
|
||||
int err;
|
||||
int nleft;
|
||||
gint bytes;
|
||||
gint err;
|
||||
gint nleft;
|
||||
off_t offset;
|
||||
|
||||
err = -1;
|
||||
|
@ -541,14 +544,17 @@ tile_swap_default_in (DefSwapFile *def_swap_file,
|
|||
nleft = bytes;
|
||||
while (nleft > 0)
|
||||
{
|
||||
do {
|
||||
err = read (fd, tile->data + bytes - nleft, nleft);
|
||||
} while ((err == -1) && ((errno == EAGAIN) || (errno == EINTR)));
|
||||
do
|
||||
{
|
||||
err = read (fd, tile->data + bytes - nleft, nleft);
|
||||
}
|
||||
while ((err == -1) && ((errno == EAGAIN) || (errno == EINTR)));
|
||||
|
||||
if (err <= 0)
|
||||
{
|
||||
if (read_err_msg)
|
||||
g_message ("unable to read tile data from disk: %d/%d ( %d ) bytes read", err, errno, nleft);
|
||||
g_message ("unable to read tile data from disk: %s (%d/%d bytes read)",
|
||||
g_strerror (errno), err, nleft);
|
||||
read_err_msg = FALSE;
|
||||
return;
|
||||
}
|
||||
|
@ -569,12 +575,11 @@ tile_swap_default_out (DefSwapFile *def_swap_file,
|
|||
int fd,
|
||||
Tile *tile)
|
||||
{
|
||||
int bytes;
|
||||
int rbytes;
|
||||
int err;
|
||||
int nleft;
|
||||
gint bytes;
|
||||
gint rbytes;
|
||||
gint err;
|
||||
gint nleft;
|
||||
off_t offset;
|
||||
|
||||
off_t newpos;
|
||||
|
||||
bytes = TILE_WIDTH * TILE_HEIGHT * tile->bpp;
|
||||
|
@ -592,7 +597,8 @@ tile_swap_default_out (DefSwapFile *def_swap_file,
|
|||
if (offset == -1)
|
||||
{
|
||||
if (seek_err_msg)
|
||||
g_message ("unable to seek to tile location on disk: %d", errno);
|
||||
g_message ("unable to seek to tile location on disk: %s",
|
||||
g_strerror (errno));
|
||||
seek_err_msg = FALSE;
|
||||
return;
|
||||
}
|
||||
|
@ -606,7 +612,8 @@ tile_swap_default_out (DefSwapFile *def_swap_file,
|
|||
if (err <= 0)
|
||||
{
|
||||
if (write_err_msg)
|
||||
g_message ("unable to write tile data to disk: %d ( %d ) bytes written", err, nleft);
|
||||
g_message ("unable to write tile data to disk: %s (%d/%d bytes written)",
|
||||
g_strerror (errno), err, nleft);
|
||||
write_err_msg = FALSE;
|
||||
return;
|
||||
}
|
||||
|
@ -627,15 +634,15 @@ tile_swap_default_out (DefSwapFile *def_swap_file,
|
|||
|
||||
static void
|
||||
tile_swap_default_delete (DefSwapFile *def_swap_file,
|
||||
int fd,
|
||||
gint fd,
|
||||
Tile *tile)
|
||||
{
|
||||
GList *tmp;
|
||||
GList *tmp2;
|
||||
Gap *gap;
|
||||
Gap *gap2;
|
||||
long start;
|
||||
long end;
|
||||
Gap *gap;
|
||||
Gap *gap2;
|
||||
glong start;
|
||||
glong end;
|
||||
|
||||
if (tile->swap_offset == -1)
|
||||
return;
|
||||
|
@ -660,7 +667,8 @@ tile_swap_default_delete (DefSwapFile *def_swap_file,
|
|||
{
|
||||
gap2->end = gap->end;
|
||||
tile_swap_gap_destroy (gap);
|
||||
def_swap_file->gaps = g_list_remove_link (def_swap_file->gaps, tmp);
|
||||
def_swap_file->gaps =
|
||||
g_list_remove_link (def_swap_file->gaps, tmp);
|
||||
g_list_free (tmp);
|
||||
}
|
||||
}
|
||||
|
@ -677,7 +685,8 @@ tile_swap_default_delete (DefSwapFile *def_swap_file,
|
|||
{
|
||||
gap2->start = gap->start;
|
||||
tile_swap_gap_destroy (gap);
|
||||
def_swap_file->gaps = g_list_remove_link (def_swap_file->gaps, tmp);
|
||||
def_swap_file->gaps =
|
||||
g_list_remove_link (def_swap_file->gaps, tmp);
|
||||
g_list_free (tmp);
|
||||
}
|
||||
}
|
||||
|
@ -731,26 +740,25 @@ tile_swap_default_delete (DefSwapFile *def_swap_file,
|
|||
|
||||
static void
|
||||
tile_swap_resize (DefSwapFile *def_swap_file,
|
||||
int fd,
|
||||
long new_size)
|
||||
gint fd,
|
||||
glong new_size)
|
||||
{
|
||||
if (def_swap_file->swap_file_end > new_size)
|
||||
{
|
||||
ftruncate (fd, new_size);
|
||||
/*fprintf(stderr, "TRUNCATED SWAP from %d to %d bytes.\n",
|
||||
(int)def_swap_file->swap_file_end, (int) new_size);*/
|
||||
}
|
||||
|
||||
def_swap_file->swap_file_end = new_size;
|
||||
}
|
||||
|
||||
static long
|
||||
tile_swap_find_offset (DefSwapFile *def_swap_file,
|
||||
int fd,
|
||||
int bytes)
|
||||
gint fd,
|
||||
gint bytes)
|
||||
{
|
||||
GList *tmp;
|
||||
Gap *gap;
|
||||
long offset;
|
||||
Gap *gap;
|
||||
glong offset;
|
||||
|
||||
tmp = def_swap_file->gaps;
|
||||
while (tmp)
|
||||
|
@ -765,7 +773,8 @@ tile_swap_find_offset (DefSwapFile *def_swap_file,
|
|||
if (gap->start == gap->end)
|
||||
{
|
||||
tile_swap_gap_destroy (gap);
|
||||
def_swap_file->gaps = g_list_remove_link (def_swap_file->gaps, tmp);
|
||||
def_swap_file->gaps =
|
||||
g_list_remove_link (def_swap_file->gaps, tmp);
|
||||
g_list_free (tmp);
|
||||
}
|
||||
|
||||
|
@ -777,7 +786,8 @@ tile_swap_find_offset (DefSwapFile *def_swap_file,
|
|||
|
||||
offset = def_swap_file->swap_file_end;
|
||||
|
||||
tile_swap_resize (def_swap_file, fd, def_swap_file->swap_file_end + swap_file_grow);
|
||||
tile_swap_resize (def_swap_file, fd,
|
||||
def_swap_file->swap_file_end + swap_file_grow);
|
||||
|
||||
if ((offset + bytes) < (def_swap_file->swap_file_end))
|
||||
{
|
||||
|
@ -788,9 +798,9 @@ tile_swap_find_offset (DefSwapFile *def_swap_file,
|
|||
return offset;
|
||||
}
|
||||
|
||||
static Gap*
|
||||
tile_swap_gap_new (long start,
|
||||
long end)
|
||||
static Gap *
|
||||
tile_swap_gap_new (glong start,
|
||||
glong end)
|
||||
{
|
||||
Gap *gap;
|
||||
|
||||
|
@ -822,12 +832,12 @@ tile_swap_gap_destroy (Gap *gap)
|
|||
|
||||
static void
|
||||
tile_swap_in_attempt (DefSwapFile *def_swap_file,
|
||||
int fd,
|
||||
gint fd,
|
||||
Tile *tile)
|
||||
{
|
||||
int bytes;
|
||||
int err;
|
||||
int nleft;
|
||||
gint bytes;
|
||||
gint err;
|
||||
gint nleft;
|
||||
off_t offset;
|
||||
|
||||
err = -1;
|
||||
|
@ -854,9 +864,11 @@ tile_swap_in_attempt (DefSwapFile *def_swap_file,
|
|||
nleft = bytes;
|
||||
while (nleft > 0)
|
||||
{
|
||||
do {
|
||||
err = read (fd, tile->data + bytes - nleft, nleft);
|
||||
} while ((err == -1) && ((errno == EAGAIN) || (errno == EINTR)));
|
||||
do
|
||||
{
|
||||
err = read (fd, tile->data + bytes - nleft, nleft);
|
||||
}
|
||||
while ((err == -1) && ((errno == EAGAIN) || (errno == EINTR)));
|
||||
|
||||
if (err <= 0)
|
||||
{
|
||||
|
@ -873,13 +885,13 @@ out:
|
|||
TILE_MUTEX_UNLOCK (tile);
|
||||
}
|
||||
|
||||
static void *
|
||||
tile_swap_in_thread (void *data)
|
||||
static gpointer
|
||||
tile_swap_in_thread (gpointer data)
|
||||
{
|
||||
AsyncSwapArgs *args;
|
||||
GSList *free_item;
|
||||
GSList *free_item;
|
||||
|
||||
while (1)
|
||||
while (TRUE)
|
||||
{
|
||||
pthread_mutex_lock (&async_swapin_mutex);
|
||||
|
||||
|
@ -892,6 +904,7 @@ tile_swap_in_thread (void *data)
|
|||
free_item = async_swapin_tiles;
|
||||
async_swapin_tiles = async_swapin_tiles->next;
|
||||
g_slist_free_1(free_item);
|
||||
|
||||
if (!async_swapin_tiles)
|
||||
async_swapin_tiles_end = NULL;
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ typedef enum
|
|||
} SwapCommand;
|
||||
|
||||
typedef gint (*SwapFunc) (gint fd,
|
||||
Tile *tile,
|
||||
Tile *tile,
|
||||
gint cmd,
|
||||
gpointer user_data);
|
||||
|
||||
|
|
Loading…
Reference in New Issue