Tile overhaul. Mostly minor changes, except for tile*.*, which are

barely recognizable.
This commit is contained in:
scott 1998-07-10 02:43:12 +00:00
parent 1f1c9e1684
commit 9ccef4a648
90 changed files with 1247 additions and 2306 deletions

View File

@ -1,3 +1,17 @@
Thu Jul 9 21:23:46 1998 Scott Goehring <scott@poverty.bloomington.in.us>
* tile.c tile_manager.c tile_cache.c tile.h tile_manager.h
tile_manager_pvt.h tile_pvt.h:
completely redid tile management.
* blend.c boundary.c by_color_select.c channel.c color_picker.c
drawable_cmds.c frac.c fuzzy_select.c gimpimage.c image_render.c
ink.c layer.c paint_core.c paint_funcs.c pixel_region.c
plug_in.c preferences_dialog.c procedural_db.c transform_core.c
undo.c xcf.c:
changed to reflect new tile management protocols. (Also killed
a few compilation warnings.)
Thu Jul 9 22:04:04 EDT 1998 Michael K. Johnson <johnsonm@redhat.com>
* app/clone.c: clone_motion: silently ignore cloning if the

View File

@ -1353,7 +1353,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_info->tile_num, 0);
tile = tile_manager_get (tm, tile_info->tile_num, 0, TRUE, TRUE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1361,14 +1361,12 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_ref2 (tile, TRUE);
if (tile_data.use_shm)
memcpy (tile->data, shm_addr, tile_size (tile));
else
memcpy (tile->data, tile_info->data, tile_size (tile));
tile_unref (tile, TRUE);
tile_release (tile, TRUE);
wire_destroy (&msg);
if (!gp_tile_ack_write (current_writefd))
@ -1392,7 +1390,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_req->tile_num, 0);
tile = tile_manager_get (tm, tile_req->tile_num, 0, TRUE, FALSE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1408,8 +1406,6 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
tile_data.height = tile->eheight;
tile_data.use_shm = (shm_ID == -1) ? FALSE : TRUE;
tile_ref2 (tile, FALSE);
if (tile_data.use_shm)
memcpy (shm_addr, tile->data, tile_size (tile));
else
@ -1422,7 +1418,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
if (!wire_read_msg (current_readfd, &msg))
{

View File

@ -124,9 +124,8 @@ find_empty_segs (PixelRegion *maskPR,
if ((x / TILE_WIDTH) != tilex)
{
if (tile)
tile_unref (tile, FALSE);
tile = tile_manager_get_tile (maskPR->tiles, x, scanline, 0);
tile_ref2 (tile, FALSE);
tile_release (tile, FALSE);
tile = tile_manager_get_tile (maskPR->tiles, x, scanline, 0, TRUE, FALSE);
data = tile->data + tile->bpp *
((scanline % TILE_HEIGHT) * tile->ewidth + (x % TILE_WIDTH)) + (tile->bpp - 1);
tilex = x / TILE_WIDTH;
@ -153,7 +152,7 @@ find_empty_segs (PixelRegion *maskPR,
empty_segs[(*num_empty)++] = G_MAXINT;
if (tile)
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
}

View File

@ -124,8 +124,7 @@ pixel_region_get_row (PR, x, y, w, data, subsample)
while (x < end)
{
tile = tile_manager_get_tile (PR->tiles, x, y, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (PR->tiles, x, y, 0, TRUE, FALSE);
tile_data = tile->data + tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
boundary = x + (tile->ewidth - (x % TILE_WIDTH));
inc = subsample * tile->bpp;
@ -137,7 +136,7 @@ pixel_region_get_row (PR, x, y, w, data, subsample)
tile_data += inc;
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
}
}
@ -159,8 +158,7 @@ pixel_region_set_row (PR, x, y, w, data)
while (x < end)
{
tile = tile_manager_get_tile (PR->tiles, x, y, 0);
tile_ref2 (tile, TRUE);
tile = tile_manager_get_tile (PR->tiles, x, y, 0, TRUE, TRUE);
tile_data = tile->data + tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
boundary = x + (tile->ewidth - (x % TILE_WIDTH));
@ -170,7 +168,7 @@ pixel_region_set_row (PR, x, y, w, data)
*tile_data++ = *data++;
}
tile_unref (tile, TRUE);
tile_release (tile, TRUE);
}
}
@ -194,8 +192,7 @@ pixel_region_get_col (PR, x, y, h, data, subsample)
while (y < end)
{
tile = tile_manager_get_tile (PR->tiles, x, y, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (PR->tiles, x, y, 0, TRUE, FALSE);
tile_data = tile->data + tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
boundary = y + (tile->eheight - (y % TILE_HEIGHT));
inc = subsample * tile->bpp * tile->ewidth;
@ -207,7 +204,7 @@ pixel_region_get_col (PR, x, y, h, data, subsample)
tile_data += inc;
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
}
}
@ -230,8 +227,7 @@ pixel_region_set_col (PR, x, y, h, data)
while (y < end)
{
tile = tile_manager_get_tile (PR->tiles, x, y, 0);
tile_ref2 (tile, TRUE);
tile = tile_manager_get_tile (PR->tiles, x, y, 0, TRUE, TRUE);
tile_data = tile->data + tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
boundary = y + (tile->eheight - (y % TILE_HEIGHT));
inc = tile->bpp * tile->ewidth;
@ -243,7 +239,7 @@ pixel_region_set_col (PR, x, y, h, data)
tile_data += inc;
}
tile_unref (tile, TRUE);
tile_release (tile, TRUE);
}
}
@ -329,8 +325,8 @@ pixel_regions_process (PRI_ptr)
/* Unref the last referenced tile if the underlying region is a tile manager */
if (PRH->PR->tiles)
{
Tile *tile = tile_manager_get_tile (PRH->PR->tiles, PRH->PR->x, PRH->PR->y, 0);
tile_unref (tile, PRH->PR->dirty);
Tile *tile = tile_manager_get_tile (PRH->PR->tiles, PRH->PR->x, PRH->PR->y, 0, FALSE, FALSE);
tile_release (tile, PRH->PR->dirty);
}
PRH->PR->x += PRI->portion_width;
@ -376,8 +372,8 @@ pixel_regions_process_stop (PRI_ptr)
/* Unref the last referenced tile if the underlying region is a tile manager */
if (PRH->PR->tiles)
{
Tile *tile = tile_manager_get_tile (PRH->PR->tiles, PRH->PR->x, PRH->PR->y, 0);
tile_unref (tile, PRH->PR->dirty);
Tile *tile = tile_manager_get_tile (PRH->PR->tiles, PRH->PR->x, PRH->PR->y, 0, FALSE, FALSE);
tile_release (tile, PRH->PR->dirty);
}
}
@ -550,8 +546,7 @@ pixel_region_configure (PRH, PRI)
Tile *tile;
int offx, offy;
tile = tile_manager_get_tile (PRH->PR->tiles, PRH->PR->x, PRH->PR->y, 0);
tile_ref2 (tile, PRH->PR->dirty);
tile = tile_manager_get_tile (PRH->PR->tiles, PRH->PR->x, PRH->PR->y, 0, TRUE, PRH->PR->dirty);
offx = PRH->PR->x % TILE_WIDTH;
offy = PRH->PR->y % TILE_HEIGHT;

View File

@ -46,8 +46,12 @@ static pthread_t preswap_thread;
static pthread_mutex_t dirty_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t dirty_signal = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t tile_mutex = PTHREAD_MUTEX_INITIALIZER;
#define CACHE_LOCK pthread_mutex_lock(&tile_mutex)
#define CACHE_UNLOCK pthread_mutex_unlock(&tile_mutex)
#else
static gint idle_swapper = 0;
#define CACHE_LOCK /*nothing*/
#define CACHE_UNLOCK /*nothing*/
#endif
@ -60,9 +64,7 @@ tile_cache_insert (Tile *tile)
if (initialize)
tile_cache_init ();
#if USE_PTHREADS
pthread_mutex_lock(&tile_mutex);
#endif
CACHE_LOCK;
if (tile->data == NULL) goto out;
/* First check and see if the tile is already
@ -100,6 +102,7 @@ tile_cache_insert (Tile *tile)
* if there is room in the cache. If not then we'll have
* to make room first. Note: it might be the case that the
* cache is smaller than the size of a tile in which case
* it won't be possible to put it in the cache.
*/
while ((cur_cache_size + max_tile_size) > max_cache_size)
@ -111,24 +114,6 @@ tile_cache_insert (Tile *tile)
* is referencing.
*/
cur_cache_size += tile_size (tile);
/* Reference the tile so that it won't be swapped out
* to disk. Swap the tile in if necessary.
* "tile_ref" cannot be used here since it calls this
* function.
*/
tile->ref_count += 1;
{
extern int tile_ref_count;
tile_ref_count += 1;
}
if (tile->ref_count == 1)
{
tile_swap_in (tile);
/* the tile must be clean */
tile->dirty = FALSE;
}
}
/* Put the tile at the end of the proper list */
@ -151,9 +136,7 @@ tile_cache_insert (Tile *tile)
#endif
}
out:
#ifdef USE_PTHREADS
pthread_mutex_unlock(&tile_mutex);
#endif
CACHE_UNLOCK;
}
@ -163,15 +146,9 @@ tile_cache_flush (Tile *tile)
if (initialize)
tile_cache_init ();
#ifdef USE_PTHREADS
pthread_mutex_lock(&tile_mutex);
#endif
CACHE_LOCK;
tile_cache_flush_internal (tile);
#ifdef USE_PTHREADS
pthread_mutex_unlock(&tile_mutex);
#endif
CACHE_UNLOCK;
}
static void
@ -203,34 +180,6 @@ tile_cache_flush_internal (Tile *tile)
list->first = tile->next;
tile->listhead = NULL;
/* Unreference the tile.
*/
{
extern int tile_ref_count;
tile_ref_count -= 1;
}
/* Decrement the reference count.
*/
tile->ref_count -= 1;
/* If this was the last reference to the tile, then
* swap it out to disk.
*/
if (tile->ref_count == 0)
{
/* Only need to swap out in two cases:
* 1) The tile is dirty
* 2) The tile has never been swapped
*/
if (tile->dirty || tile->swap_offset == -1)
tile_swap_out (tile);
/* Otherwise, just throw out the data--the same stuff is in swap
*/
g_free (tile->data);
tile->data = NULL;
}
}
}
@ -241,17 +190,12 @@ tile_cache_set_size (unsigned long cache_size)
tile_cache_init ();
max_cache_size = cache_size;
#if USE_PTHREADS
pthread_mutex_lock(&tile_mutex);
#endif
CACHE_LOCK;
while (cache_size >= max_cache_size)
{
if (!tile_cache_zorch_next ()) break;
}
#if USE_PTHREADS
pthread_mutex_unlock(&tile_mutex);
#endif
CACHE_UNLOCK;
}
@ -286,15 +230,11 @@ tile_cache_zorch_next ()
else if (dirty_list.first) tile = dirty_list.first;
else return FALSE;
#ifdef USE_PTHREADS
pthread_mutex_unlock(&tile_mutex);
pthread_mutex_lock(&(tile->mutex));
pthread_mutex_lock(&tile_mutex);
#endif
CACHE_UNLOCK;
TILE_MUTEX_LOCK (tile);
CACHE_LOCK;
tile_cache_flush_internal (tile);
#ifdef USE_PTHREADS
pthread_mutex_unlock(&(tile->mutex));
#endif
TILE_MUTEX_UNLOCK (tile);
return TRUE;
}
@ -315,10 +255,10 @@ tile_idle_thread (void *data)
pthread_cond_wait(&dirty_signal,&dirty_mutex);
pthread_mutex_unlock(&dirty_mutex);
}
if ((tile = dirty_list.first) &&
(pthread_mutex_lock(&(tile->mutex)) == 0))
if ((tile = dirty_list.first))
{
pthread_mutex_lock(&tile_mutex);
TILE_MUTEX_LOCK (tile);
CACHE_LOCK;
list = tile->listhead;
@ -342,9 +282,10 @@ tile_idle_thread (void *data)
else clean_list.first = tile;
clean_list.last = tile;
pthread_mutex_unlock(&tile_mutex);
CACHE_UNLOCK;
tile_swap_out(tile);
pthread_mutex_unlock(&(tile->mutex));
TILE_MUTEX_UNLOCK (tile);
}
}
}
@ -377,3 +318,4 @@ tile_idle_preswap (gpointer data)
return TRUE;
}
#endif

View File

@ -29,7 +29,7 @@ struct _TileLevel
int ntile_rows; /* the number of tiles in each row */
int ntile_cols; /* the number of tiles in each columns */
Tile *tiles; /* the tiles for this level */
Tile **tiles; /* the tiles for this level */
};
struct _TileManager

View File

@ -23,7 +23,9 @@
#include "tile_manager_pvt.h"
#include "tile_pvt.h" /* ick. */
static void tile_manager_destroy_level (TileLevel *level);
static void tile_manager_destroy_level (TileManager *tm,
TileLevel *level);
static void tile_invalidate (Tile **tile_ptr, TileManager *tm, int tile_num);
TileManager*
@ -71,7 +73,7 @@ tile_manager_destroy (TileManager *tm)
int i;
for (i = 0; i < tm->nlevels; i++)
tile_manager_destroy_level (&tm->levels[i]);
tile_manager_destroy_level (tm, &tm->levels[i]);
g_free (tm->levels);
g_free (tm);
@ -138,7 +140,7 @@ tile_manager_set_nlevels (TileManager *tm,
levels[i] = tm->levels[i];
for (; i < tm->nlevels; i++)
tile_manager_destroy_level (&tm->levels[i]);
tile_manager_destroy_level (tm, &tm->levels[i]);
}
g_free (tm->levels);
@ -158,7 +160,9 @@ Tile*
tile_manager_get_tile (TileManager *tm,
int xpixel,
int ypixel,
int level)
int level,
int wantread,
int wantwrite)
{
TileLevel *tile_level;
int tile_row;
@ -177,16 +181,19 @@ tile_manager_get_tile (TileManager *tm,
tile_col = xpixel / TILE_WIDTH;
tile_num = tile_row * tile_level->ntile_cols + tile_col;
return tile_manager_get (tm, tile_num, level);
return tile_manager_get (tm, tile_num, level, wantread, wantwrite);
}
Tile*
tile_manager_get (TileManager *tm,
int tile_num,
int level)
int level,
int wantread,
int wantwrite)
{
TileLevel *tile_level;
Tile *tiles;
Tile **tiles;
Tile **tile_ptr;
int ntiles;
int nrows, ncols;
int right_tile;
@ -204,7 +211,7 @@ tile_manager_get (TileManager *tm,
if (!tile_level->tiles)
{
tile_level->tiles = g_new (Tile, ntiles);
tile_level->tiles = g_new (Tile*, ntiles);
tiles = tile_level->tiles;
nrows = tile_level->ntile_rows;
@ -217,20 +224,53 @@ tile_manager_get (TileManager *tm,
{
for (j = 0; j < ncols; j++, k++)
{
tile_init (&tiles[k], tile_level->bpp);
tiles[k].tile_num = k;
tiles[k].tm = tm;
tiles[k] = g_new (Tile, 1);
tile_init (tiles[k], tile_level->bpp);
tile_attach (tiles[k], tm, k);
if (j == (ncols - 1))
tiles[k].ewidth = right_tile;
tiles[k]->ewidth = right_tile;
if (i == (nrows - 1))
tiles[k].eheight = bottom_tile;
tiles[k]->eheight = bottom_tile;
}
}
}
return &tile_level->tiles[tile_num];
tile_ptr = &tile_level->tiles[tile_num];
if (wantread)
{
TILE_MUTEX_LOCK (*tile_ptr);
if (wantwrite)
{
if ((*tile_ptr)->share_count > 1)
{
/* Copy-on-write required */
Tile *newtile = g_new (Tile, 1);
tile_init (newtile, (*tile_ptr)->bpp);
newtile->ewidth = (*tile_ptr)->ewidth;
newtile->eheight = (*tile_ptr)->eheight;
newtile->valid = (*tile_ptr)->valid;
if ((*tile_ptr)->data != NULL)
{
newtile->data = g_new (guchar, tile_size (newtile));
memcpy (newtile->data, (*tile_ptr)->data, tile_size (newtile));
}
tile_detach (*tile_ptr, tm, tile_num);
TILE_MUTEX_LOCK (newtile);
tile_attach (newtile, tm, tile_num);
*tile_ptr = newtile;
}
(*tile_ptr)->write_count++;
(*tile_ptr)->dirty = 1;
}
TILE_MUTEX_UNLOCK (*tile_ptr);
tile_lock (*tile_ptr);
}
return *tile_ptr;
}
void
@ -253,8 +293,8 @@ tile_manager_invalidate_tiles (TileManager *tm,
int num;
int i;
col = toplevel_tile->tile_num % tm->levels[0].ntile_cols;
row = toplevel_tile->tile_num / tm->levels[0].ntile_cols;
col = toplevel_tile->tlink->tile_num % tm->levels[0].ntile_cols;
row = toplevel_tile->tlink->tile_num / tm->levels[0].ntile_cols;
x = (col * TILE_WIDTH + toplevel_tile->ewidth / 2.0) / (double) tm->levels[0].width;
y = (row * TILE_HEIGHT + toplevel_tile->eheight / 2.0) / (double) tm->levels[0].height;
@ -267,7 +307,7 @@ tile_manager_invalidate_tiles (TileManager *tm,
col = x * level->width / TILE_WIDTH;
row = y * level->height / TILE_HEIGHT;
num = row * level->ntile_cols + col;
tile_invalidate (&level->tiles[num]);
tile_invalidate (&level->tiles[num], tm, num);
}
}
}
@ -284,7 +324,7 @@ tile_manager_invalidate_sublevels (TileManager *tm)
{
ntiles = tm->levels[i].ntile_rows * tm->levels[i].ntile_cols;
for (j = 0; j < ntiles; j++)
tile_invalidate (&tm->levels[i].tiles[j]);
tile_invalidate (&tm->levels[i].tiles[j], tm, j);
}
}
}
@ -309,8 +349,8 @@ tile_manager_update_tile (TileManager *tm,
if ((level < 1) || (level >= tm->nlevels))
return;
col = toplevel_tile->tile_num % tm->levels[0].ntile_cols;
row = toplevel_tile->tile_num / tm->levels[0].ntile_cols;
col = toplevel_tile->tlink->tile_num % tm->levels[0].ntile_cols;
row = toplevel_tile->tlink->tile_num / tm->levels[0].ntile_cols;
x = (col * TILE_WIDTH + toplevel_tile->ewidth / 2.0) / (double) tm->levels[0].width;
y = (row * TILE_HEIGHT + toplevel_tile->eheight / 2.0) / (double) tm->levels[0].height;
@ -338,10 +378,9 @@ tile_manager_update_tile (TileManager *tm,
row = (y * tile_level->height) / TILE_HEIGHT;
num = row * tile_level->ntile_cols + col;
tile = tile_manager_get (tm, num, level);
tile = tile_manager_get (tm, num, level, TRUE, TRUE);
tile_ref2 (tile, TRUE);
tile_ref2 (toplevel_tile, FALSE);
tile_lock (toplevel_tile);
tilew += tilex;
tileh += tiley;
@ -366,13 +405,13 @@ tile_manager_update_tile (TileManager *tm,
}
}
tile_unref (tile, TRUE);
tile_unref (toplevel_tile, FALSE);
tile_release (tile, TRUE);
tile_release (toplevel_tile, FALSE);
}
static void
tile_manager_destroy_level (TileLevel *level)
tile_manager_destroy_level (TileManager *tm, TileLevel *level)
{
int ntiles;
int i;
@ -382,8 +421,146 @@ tile_manager_destroy_level (TileLevel *level)
ntiles = level->ntile_rows * level->ntile_cols;
for (i = 0; i < ntiles; i++)
tile_invalidate (&level->tiles[i]);
{
TILE_MUTEX_LOCK (level->tiles[i]);
tile_detach (level->tiles[i], tm, i);
}
g_free (level->tiles);
}
}
static void
tile_invalidate (Tile **tile_ptr, TileManager *tm, int tile_num)
{
Tile *tile = *tile_ptr;
TILE_MUTEX_LOCK (tile);
if (!tile->valid)
goto leave;
if (tile->share_count > 1)
{
/* This tile is shared. Replace it with a new, invalid tile. */
Tile *newtile = g_new (Tile, 1);
tile_init (newtile, tile->bpp);
newtile->ewidth = tile->ewidth;
newtile->eheight = tile->eheight;
tile_detach (tile, tm, tile_num);
TILE_MUTEX_LOCK (newtile);
tile_attach (newtile, tm, tile_num);
tile = *tile_ptr = newtile;
}
if (tile->listhead)
tile_cache_flush (tile);
tile->valid = FALSE;
if (tile->data)
{
g_free (tile->data);
tile->data = NULL;
}
if (tile->swap_offset != -1)
{
/* If the tile is on disk, then delete its
* presence there.
*/
tile_swap_delete (tile);
}
leave:
TILE_MUTEX_UNLOCK (tile);
}
void
tile_manager_map_tile (TileManager *tm,
int xpixel,
int ypixel,
int level,
Tile *srctile)
{
TileLevel *tile_level;
int tile_row;
int tile_col;
int tile_num;
if ((level < 0) || (level >= tm->nlevels))
return;
tile_level = &tm->levels[level];
if ((xpixel < 0) || (xpixel >= tile_level->width) ||
(ypixel < 0) || (ypixel >= tile_level->height))
return;
tile_row = ypixel / TILE_HEIGHT;
tile_col = xpixel / TILE_WIDTH;
tile_num = tile_row * tile_level->ntile_cols + tile_col;
tile_manager_map (tm, tile_num, level, srctile);
}
void
tile_manager_map (TileManager *tm,
int tile_num,
int level,
Tile *srctile)
{
TileLevel *tile_level;
Tile **tiles;
Tile **tile_ptr;
int ntiles;
int nrows, ncols;
int right_tile;
int bottom_tile;
int i, j, k;
if ((level < 0) || (level >= tm->nlevels))
return;
tile_level = &tm->levels[level];
ntiles = tile_level->ntile_rows * tile_level->ntile_cols;
if ((tile_num < 0) || (tile_num >= ntiles))
return;
if (!tile_level->tiles)
{
tile_level->tiles = g_new (Tile*, ntiles);
tiles = tile_level->tiles;
nrows = tile_level->ntile_rows;
ncols = tile_level->ntile_cols;
right_tile = tile_level->width - ((ncols - 1) * TILE_WIDTH);
bottom_tile = tile_level->height - ((nrows - 1) * TILE_HEIGHT);
for (i = 0, k = 0; i < nrows; i++)
{
for (j = 0; j < ncols; j++, k++)
{
tiles[k] = g_new (Tile, 1);
tile_init (tiles[k], tile_level->bpp);
tile_attach (tiles[k], tm, k);
if (j == (ncols - 1))
tiles[k]->ewidth = right_tile;
if (i == (nrows - 1))
tiles[k]->eheight = bottom_tile;
}
}
}
tile_ptr = &tile_level->tiles[tile_num];
TILE_MUTEX_LOCK (*tile_ptr);
tile_detach (*tile_ptr, tm, tile_num);
TILE_MUTEX_LOCK (srctile);
tile_attach (srctile, tm, tile_num);
*tile_ptr = srctile;
TILE_MUTEX_UNLOCK (srctile);
}

View File

@ -81,13 +81,28 @@ void tile_manager_set_validate_proc (TileManager *tm,
Tile* tile_manager_get_tile (TileManager *tm,
int xpixel,
int ypixel,
int level);
int level,
int wantread,
int wantwrite);
/* Get a specified tile from a tile manager.
*/
Tile* tile_manager_get (TileManager *tm,
int tile_num,
int level);
int level,
int wantread,
int wantwrite);
void tile_manager_map_tile (TileManager *tm,
int xpixel,
int ypixel,
int level,
Tile *srctile);
void tile_manager_map (TileManager *tm,
int time_num,
int level,
Tile *srctile);
/* Validate a tiles memory.
*/

View File

@ -11,6 +11,19 @@
#include "config.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.
*/
};
struct _Tile
{
short ref_count; /* reference count. when the reference count is
@ -19,6 +32,10 @@ struct _Tile
* is 0 then the "data" for this tile must be
* NULL.
*/
short write_count; /* write count: number of references that are
for write access */
short share_count; /* share count: number of tile managers that
hold this tile */
guint dirty : 1; /* is the tile dirty? has it been modified? */
guint valid : 1; /* is the tile valid? */
@ -26,20 +43,6 @@ struct _Tile
* case the tile data is on disk.
*/
Tile *real_tile_ptr;/* if this tile's 'data' pointer is just a copy-on-write
* mirror of another's, this is that source tile.
* (real_tile itself can actually be a virtual tile
* too.) This is NULL if this tile is not a virtual
* tile.
*/
Tile *mirrored_by; /* If another tile is mirroring this one, this is
* a pointer to that tile, otherwise this is NULL.
* Note that only one tile may be _directly_ mirroring
* another given tile. This ensures that the graph
* of mirrorings is no more complex than a linked
* list.
*/
int ewidth; /* the effective width of the tile */
int eheight; /* the effective height of the tile */
/* a tile's effective width and height may be smaller
@ -47,19 +50,14 @@ struct _Tile
* this is to handle edge tiles of a drawable.
*/
int bpp; /* the bytes per pixel (1, 2, 3 or 4) */
int tile_num; /* the number of this tile within the drawable */
int swap_num; /* the index into the file table of the file to be used
* for swapping. swap_num 1 is always the global swap file.
*/
off_t swap_offset; /* the offset within the swap file of the tile data.
* if the tile data is in memory this will be set to -1.
*/
TileLink *tlink;
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.
*/
Tile *next;
Tile *prev; /* List pointers for the tile cache lists */
void *listhead; /* Pointer to the head of the list this tile is on */
@ -68,4 +66,13 @@ struct _Tile
#endif
};
#ifdef USE_PTHREADS
#define TILE_MUTEX_LOCK(tile) pthread_mutex_lock(&((tile)->mutex))
#define TILE_MUTEX_UNLOCK(tile) pthread_mutex_unlock(&((tile)->mutex))
#else
#define TILE_MUTEX_LOCK(tile) /* nothing */
#define TILE_MUTEX_UNLOCK(tile) /* nothing */
#endif
#endif /* __TILE_PVT_H__ */

View File

@ -32,13 +32,8 @@
* list instead...
*/
/*
* Define MUCH_TILE_DEBUG in addition to TILE_DEBUG to get
* debugging for every single tile_ref2 and tile_unref (that's
* a lot).
#define MUCH_TILE_DEBUG heckyeah
*/
static void tile_destroy (Tile *tile);
void
@ -46,18 +41,17 @@ tile_init (Tile *tile,
int bpp)
{
tile->ref_count = 0;
tile->write_count = 0;
tile->share_count = 0;
tile->dirty = FALSE;
tile->valid = FALSE;
tile->data = NULL;
tile->real_tile_ptr = NULL;
tile->mirrored_by = NULL;
tile->ewidth = TILE_WIDTH;
tile->eheight = TILE_HEIGHT;
tile->bpp = bpp;
tile->tile_num = -1;
tile->swap_num = 1;
tile->swap_offset = -1;
tile->tm = NULL;
tile->tlink = NULL;
tile->next = tile->prev = NULL;
tile->listhead = NULL;
#ifdef USE_PTHREADS
@ -67,524 +61,81 @@ tile_init (Tile *tile,
#endif
}
int tile_ref_count = 0;
void
#if defined (TILE_DEBUG) && defined (__GNUC__)
_tile_ref (Tile *tile, char *func_name)
#else
tile_ref (Tile *tile)
#endif
tile_lock (Tile *tile)
{
/* While things get moved over to the new tile_ref2
* interface, tile_ref is a wrapper which just says
* 'yes, we'll be dirtying the tile'
*/
#if defined (TILE_DEBUG) && defined (__GNUC__)
printf("COW-Warning: function %s is using obsolete tile_ref interface\n",
func_name);
#endif
#if defined (TILE_DEBUG) && defined (__GNUC__)
_tile_ref2 (tile, TRUE, func_name);
#else
tile_ref2 (tile, TRUE);
#endif
}
gboolean
tile_is_mirroring (Tile *tile)
{
return (tile->real_tile_ptr != NULL);
}
gboolean
tile_is_mirrored (Tile *tile)
{
return (tile->mirrored_by != NULL);
}
gboolean
tile_is_real (Tile *tile)
{
return (tile->real_tile_ptr == NULL);
}
/* Follow the real_tile_ptr links back to the tile which provides
* the real source data for the given tile
*/
Tile *
tile_find_nonmirroring (Tile *tile)
{
if (! tile_is_mirroring (tile))
{
return tile;
}
else
{
return tile_find_nonmirroring (tile->real_tile_ptr);
}
}
/*
*/
Tile *
tile_find_finalmirroring (Tile *tile)
{
if (! tile_is_mirrored (tile))
{
return tile;
}
else
{
return tile_find_finalmirroring (tile->mirrored_by);
}
}
/* Take a mirroring-tile and turn it into a bona fide self-contained
* tile.
*/
void
tile_devirtualize (Tile *tile)
{
Tile *real_tile;
/* Sanity */
if (tile_is_real (tile))
g_error ("Tried to devirtualize a real tile");
#if defined (TILE_DEBUG)
if (tile->ref_count == 0)
g_warning ("Trying to devirtualize a mirroring-tile with no ref_count");
#endif
/* Go find the tile ('real_tile') which owns the real data
*/
real_tile = tile_find_nonmirroring (tile);
/* Sanity */
#if defined (TILE_DEBUG)
if (real_tile->ref_count == 0)
g_warning ("Trying to devirtualize a mirroring-tile whose real_tile has no ref_count");
#endif
if (!real_tile->valid)
g_warning ("Trying to devirtualize a mirroring-tile whose real_tile is !valid");
/* Copy the actual tile data from the real_tile to this tile
*/
tile->data = NULL;
tile_alloc (tile);
/* printf ("{ %dx%d : %d - %p[%p]->%p[%p] }", real_tile->ewidth, real_tile->eheight,
real_tile->bpp, real_tile, real_tile->data, tile, tile->data);
fflush(stdout);*/
memcpy (tile->data, real_tile->data, tile_size(real_tile));
/* 'tile' is now a real tile. */
tile->real_tile_ptr = NULL;
tile->valid = TRUE;
tile_cache_insert(tile);
#if defined (TILE_DEBUG)
g_print ("Tile at %p is now devirtualized.\n", tile);
#endif
}
/* Make this tile self-contained.
*
* The next tile in the linked-list of tiles which are mirroring 'tile'
* is promoted to a real physical tile and unlinked from 'tile'. This
* renders 'tile' safe for dirtying (or destruction).
*/
void
tile_isolate (Tile *tile)
{
Tile *temp_tileptr;
/* Sanity
*/
if (! (tile_is_mirrored (tile) || tile_is_mirroring (tile)))
{
g_warning ("Tried to isolate a tile which is neither a mirror source "
"nor destination");
return;
}
/* This tile is both linked to and linked from? */
if (tile_is_mirrored (tile) && tile_is_mirroring (tile))
{
temp_tileptr = tile->real_tile_ptr;
#if defined (TILE_DEBUG)
g_print ("tile %p: was middle of chain - relinking %p and %p\n",
tile,
temp_tileptr,
tile->mirrored_by);
#endif
tile->mirrored_by->real_tile_ptr = temp_tileptr;
temp_tileptr->mirrored_by = tile->mirrored_by;
tile_ref2 (temp_tileptr, FALSE);
tile_devirtualize (tile);
tile_unref (temp_tileptr, FALSE);
tile->mirrored_by = NULL;
return;
}
/* This tile is mirroring another, but is not mirrored itself? */
if (tile_is_mirroring (tile))
{
temp_tileptr = tile->real_tile_ptr;
#if defined (TILE_DEBUG)
g_print ("tile %p: was end of chain - cauterizing %p\n",
tile,
temp_tileptr);
#endif
/* We stop mirroring the tile which we previously were -
* so reset that tile's mirrored_by pointer.
*/
temp_tileptr->mirrored_by = NULL;
tile_ref2 (temp_tileptr, FALSE);
tile_devirtualize (tile);
tile_unref (temp_tileptr, FALSE);
return;
}
/* This tile is mirrored by another, but is not itself a mirror. */
if (tile_is_mirrored (tile))
{
#if defined (TILE_DEBUG)
g_print ("tile %p: was source of chain - devirtualizing %p\n",
tile,
tile->mirrored_by);
#endif
temp_tileptr = tile->mirrored_by;
tile_ref2 (temp_tileptr, FALSE);
tile_devirtualize (temp_tileptr);
tile_unref (temp_tileptr, FALSE);
/* The tile which was dependant on this one no longer is -
* so we can unref once.
*/
tile_unref (tile, FALSE);
tile->mirrored_by = NULL;
return;
}
}
/* Turns dest_tile into a mirroring-tile which mirrors the given
* src_tile using copy-on-write.
*/
void
tile_mirror (Tile *dest_tile, Tile *src_tile)
{
Tile *finalmirroring;
if (dest_tile == src_tile)
{
g_warning ("TRIED TO MIRROR TILE TO ITSELF");
return;
}
#if defined (TILE_DEBUG)
g_print ("mirroring ");
#endif
if (tile_is_real (dest_tile))
{
#if defined (TILE_DEBUG)
g_print ("TO REAL ");
#endif
tile_invalidate (dest_tile);
}
else
{
tile_invalidate (dest_tile);
}
/* dest_tile->ref_count = 0; */
dest_tile->dirty = FALSE;
dest_tile->valid = FALSE;
dest_tile->data = NULL;
dest_tile->ewidth = src_tile->ewidth;
dest_tile->eheight = src_tile->eheight;
dest_tile->bpp = src_tile->bpp;
dest_tile->tile_num = -1; /* ! */
/*
*/
finalmirroring = tile_find_finalmirroring (src_tile);
dest_tile->real_tile_ptr = finalmirroring;
finalmirroring->mirrored_by = dest_tile;
#if defined (TILE_DEBUG)
g_print ("%p -> %p\n", finalmirroring, dest_tile);
#endif
/* The following should be irrelevant in a mirroring tile - mirroring
* tiles by definition don't have real data of their own, so they can't
* be swapped. They don't have associated TileManagers either, since they
* rely on their mirrored source tile to contain validated data.
*/
dest_tile->swap_num = 1;
dest_tile->swap_offset = -1;
dest_tile->tm = NULL;
}
void
#if defined (TILE_DEBUG) && defined (__GNUC__)
_tile_ref2 (Tile *tile, int dirty, char *func_name)
#else
tile_ref2 (Tile *tile, int dirty)
#endif
{
#ifdef USE_PTHREADS
pthread_mutex_lock(&(tile->mutex));
#endif
#if defined (TILE_DEBUG) && defined (__GNUC__) && defined (MUCH_TILE_DEBUG)
g_print ("tile_ref2: %02d %c %p %s\n", tile->ref_count,
dirty?'d':' ',
tile,
func_name);
#endif
/*g_print ("tile_ref2: %02d %c %p\n", tile->ref_count,
dirty?'d':' ',
tile);*/
/* Increment the global reference count.
*/
tile_ref_count += 1;
/* Increment this tile's reference count.
*/
TILE_MUTEX_LOCK (tile);
tile->ref_count += 1;
#if defined (TILE_DEBUG)
if (tile_is_mirrored (tile) && dirty)
if (tile->ref_count++ == 1)
{
g_print ("Dirtying a mirrored tile: %p.\n", tile);
}
#endif
/*
if (dirty && tile->dirty)
{
g_print ("Not good: Dirtying a write-locked tile: %p.\n", tile);
} */
/* if this is a read-only attachment to a mirroring tile,
* then ref the chain, update the data pointer, and return.
*/
if ((!dirty) && (tile_is_mirroring (tile)))
{
/* ref each of the tiles in the chain, back to the
* 'real' tile which sits at the start.
*/
#if USE_PTHREADS
pthread_mutex_unlock(&(tile->mutex));
#endif
tile_ref2 (tile->real_tile_ptr, FALSE);
tile->data = tile->real_tile_ptr->data;
return;
}
/* dirty, or clean-and-real */
/* Real tile - first reference. */
if (!tile_is_mirroring (tile))
{
/* If this is the first reference to the tile then
* swap the tile data in from disk. Note: this will
* properly handle the case where the tile data isn't
* on disk.
*/
if (tile->ref_count == 1)
if (tile->listhead)
{
/* remove from cache, move to main store */
tile_cache_flush (tile);
}
if (tile->data == NULL)
{
/* There is no data, so the tile must be swapped out */
tile_swap_in (tile);
}
/* Insert the tile into the cache. If the tile is already
* in the cache this will have the affect of "touching"
* the tile.
*/
tile_cache_insert (tile);
}
#if USE_PTHREADS
pthread_mutex_unlock(&(tile->mutex));
#endif
/* Read/write attachment to a mirrored/ing tile - must be
* thoughtful.
*/
if (dirty)
{
/* Doing a read/write reference to a mirroring/ed tile -
* we'll have to turn the tile into a 'real' tile.
* Then return - we're done.
*/
{
if (tile_is_mirroring (tile) | tile_is_mirrored (tile))
{
#if defined (TILE_DEBUG)
g_print ("r/w to mir'd/ing - isolating: ");
#endif
tile_isolate (tile);
}
}
}
/* Mark the tile as dirty if it's being ref'd as dirtyable.
*/
tile->dirty |= dirty;
TILE_MUTEX_UNLOCK (tile);
/* Call 'tile_manager_validate' if the tile was invalid.
*/
if (!tile->valid)
tile_manager_validate ((TileManager*) tile->tm, tile);
{
/* an invalid tile should never be shared, so this should work */
tile_manager_validate ((TileManager*) tile->tlink->tm, tile);
}
}
void
#if defined (TILE_DEBUG) && defined (__GNUC__)
_tile_unref (Tile *tile, int dirty, char *func_name)
#else
tile_unref (Tile *tile, int dirty)
#endif
tile_release (Tile *tile, int dirty)
{
#ifdef USE_PTHREADS
pthread_mutex_lock(&(tile->mutex));
#endif
#if defined (TILE_DEBUG) && defined (__GNUC__) && defined (MUCH_TILE_DEBUG)
g_print ("tile_unref: %02d %c %p %s\n", tile->ref_count,
dirty?'d':' ',
tile, func_name);
#endif
/* g_print ("tile_unref: %02d %c %p\n", tile->ref_count,
dirty?'d':' ',
tile);*/
/* Decrement the global reference count.
*/
tile_ref_count -= 1;
TILE_MUTEX_LOCK(tile);
/* Decrement this tile's reference count.
*/
tile->ref_count -= 1;
/* Mark the tile dirty if indicated
*
* commented out - we now dirty on ref, not unref
/* Decrement write ref count if dirtying
*/
/*
tile->dirty |= dirty;
*/
if (dirty)
tile->write_count -= 1;
#if defined (TILE_DEBUG)
if (tile_is_mirroring (tile))
{
/* Mirroring tiles aren't allowed to be submitted as dirty -
* they should have been isolated at ref time.
*/
if (dirty)
g_warning ("Mirroring tile unref'd as dirty.");
}
if (tile_is_mirrored (tile))
{
/* Mirrored tiles aren't allowed to be submitted as dirty -
* they should have been isolated at ref time.
*/
fflush(stdout);
if (dirty)
g_warning ("Mirrored tile unref'd as dirty.");
}
#endif
/* When we unref a mirroring tile, also unref the tile which
* was being mirrored.
*/
if (tile_is_mirroring (tile))
{
/* Mirroring tiles aren't allowed to be submitted as dirty -
* they should have been ref'd as dirty in the first place so we
* could turn them into 'real' tiles.
*/
if (dirty)
{
g_warning ("Bleh, tried to unref a mirroring tile as dirty.");
}
/* Go find the mirrored tile and unref that too. */
#if USE_PTHREADS
pthread_mutex_unlock(&(tile->mutex));
#endif
tile_unref (tile->real_tile_ptr, FALSE);
return;
}
/* If this was the last reference to the tile, then
* swap it out to disk.
*/
if (tile->ref_count == 0)
{
/* Only need to swap out in two cases:
* 1) The tile is dirty }
* 2) The tile has never been swapped } and is not mirroring
*/
if ((tile->dirty || tile->swap_offset == -1)
&& !tile_is_mirroring (tile))
tile_swap_out (tile);
/* Otherwise, just throw out the data--the same stuff is in swap
*/
else
if (tile->share_count == 0)
{
if (! tile_is_mirroring (tile))
g_free (tile->data);
tile->data = NULL;
/* tile is dead */
tile_destroy (tile);
return; /* skip terminal unlock */
}
else
{
/* last reference was just released, so move the tile to the
tile cache */
tile_cache_insert (tile);
}
}
#if USE_PTHREADS
pthread_mutex_unlock(&(tile->mutex));
#endif
TILE_MUTEX_UNLOCK (tile);
}
void
@ -599,6 +150,29 @@ tile_alloc (Tile *tile)
out:
}
static void
tile_destroy (Tile *tile)
{
if (tile->data)
{
g_free (tile->data);
tile->data = NULL;
}
if (tile->swap_offset != -1)
{
/* If the tile is on disk, then delete its
* presence there.
*/
tile_swap_delete (tile);
}
if (tile->listhead)
tile_cache_flush (tile);
TILE_MUTEX_UNLOCK (tile);
g_free (tile);
}
int
tile_size (Tile *tile)
{
@ -610,167 +184,62 @@ tile_size (Tile *tile)
return size;
}
void
tile_invalidate (Tile *tile)
tile_attach (Tile *tile, void *tm, int tile_num)
{
#ifdef USE_PTHREADS
pthread_mutex_lock(&(tile->mutex));
#endif
#if defined (TILE_DEBUG)
if (tile->ref_count > 1)
TileLink *tmp;
if (tile->share_count > 0 && !tile->valid)
{
g_print (" (inv%p:ref%d) ", tile, tile->ref_count);
}
else
{
g_print (" (inv%p) ", tile);
/* trying to share invalid tiles is problematic, not to mention silly */
tile_manager_validate ((TileManager*) tile->tlink->tm, tile);
}
tile->share_count++;
#ifdef TILE_DEBUG
g_print("tile_attach: %p -> (%p,%d) *%d\n", tile, tm, tile_num, tile->share_count);
#endif
/* If this tile is mirrored/ing, then maybe isolate it before we
* invalidate it, so that we don't accidentally delete a tile
* whose data is still in use by a mirror.
*/
if (tile_is_mirrored (tile))
{
if (tile_is_mirroring (tile))
{
/* tile is in the middle of a chain. just relink its
* successor and predecessor. that's all we need to do for
* a cleanup.
*/
#if defined (TILE_DEBUG)
g_print ("tile %p: was middle of chain - relinking %p and %p, "
"no isolation\n",
tile,
tile->real_tile_ptr,
tile->mirrored_by);
#endif
tile->mirrored_by->real_tile_ptr = tile->real_tile_ptr;
tile->real_tile_ptr->mirrored_by = tile->mirrored_by;
}
else
{
/* tile is real, and mirrored. Copy its vital statistics to
* its successor in the tile chain, so it can be safely deleted.
*/
#if defined (TILE_DEBUG)
g_print ("tile %p: was source of chain - successor %p swallows soul"
", no isolation\n",
tile,
tile->mirrored_by);
/* link this tile into the tile's tilelink chain */
tmp = g_new (TileLink, 1);
tmp->tm = tm;
tmp->tile_num = tile_num;
tmp->next = tile->tlink;
tile->tlink = tmp;
}
void
tile_detach (Tile *tile, void *tm, int tile_num)
{
TileLink **link;
TileLink *tmp;
#ifdef TILE_DEBUG
g_print("tile_detach: %p ~> (%p,%d) *%d\n", tile, tm, tile_num, tile->share_count);
#endif
/* remove 'tile' from cache - but keep the ref_count up
* so that the tile_unref() which tile_cache_flush() calls
* won't invalidate the tile (we'll be doing that ourselves).
*/
tile->ref_count++;
tile_cache_flush (tile);
tile->ref_count--;
for (link = &tile->tlink; *link; link = &(*link)->next)
if ((*link)->tm == tm && (*link)->tile_num == tile_num)
break;
/* imbue our successor with our data pointer, validity,
* tile manager, swap_num, swap_offset, and dirty
* flag
*/
tile->mirrored_by->data = tile->data;
tile->data = NULL;
tile->mirrored_by->dirty = tile->dirty;
tile->dirty = FALSE;
tile->mirrored_by->valid = tile->valid;
tile->valid = FALSE;
tile->mirrored_by->swap_num = tile->swap_num;
tile->swap_num = 0;
tile->mirrored_by->swap_offset = tile->swap_offset;
tile->swap_num = -1;
tile->mirrored_by->tm = tile->tm;
tile->tm = NULL;
/* sever links with our successor in both directions.
* our successor is now the new chain source.
*
* also register this newly-born 'real' tile with the tile cache.
*/
tile->mirrored_by->real_tile_ptr = NULL;
tile_cache_insert (tile->mirrored_by);
tile->mirrored_by = NULL;
/* This tile is as clean and invalid as it's going to get.
* Return.
*/
return;
}
}
else /* not mirrored, maybe mirroring */
if (*link == NULL)
{
/* for a non-real tile at the end of a chain, the only cleanup
* we have to do for its safe destruction is cauterize the
* flapping mirrored_by pointer of its predecessor on the chain.
*/
if (tile_is_mirroring (tile))
{
#if defined (TILE_DEBUG)
g_print ("tile %p: was end of chain - cauterizing %p, no "
"isolation\n",
tile,
tile->real_tile_ptr);
#endif
tile->real_tile_ptr->mirrored_by = NULL;
}
}
/* If this isn't a 'real' tile then it doesn't need invalidating,
* since it doesn't have any unique data associated with it.
*/
if (!tile_is_real (tile))
{
if (tile->valid)
{
g_warning ("tried to invalidate a mirroring tile which was valid.");
tile->valid = FALSE;
}
g_warning ("Tried to detach a nonattached tile");
return;
}
tmp = *link;
*link = tmp->next;
g_free (tmp);
/* Only 'real' tiles permitted past this point.
*/
/* Invalidate the tile. (Must be valid first).
*/
if (tile->valid)
tile->share_count--;
if (tile->share_count == 0 && tile->ref_count == 0)
{
tile->valid = FALSE;
if (tile->data)
{
/* If the tile is in memory then trick the
* tile cache routines. We temporarily increment
* the reference count so that flushing a tile does
* not cause it to go out to disk.
*/
tile->ref_count += 1;
tile_cache_flush (tile);
tile->ref_count -= 1;
/* We then free the tile data.
*/
g_free (tile->data);
tile->data = NULL;
}
if (tile->swap_offset != -1)
{
/* If the tile is on disk, then delete its
* presence there.
*/
tile_swap_delete (tile);
}
tile_destroy (tile);
return;
}
#if USE_PTHREADS
pthread_mutex_unlock(&(tile->mutex));
#endif
TILE_MUTEX_UNLOCK (tile);
}

View File

@ -24,55 +24,18 @@ typedef struct _Tile Tile;
void tile_init (Tile *tile,
int bpp);
/*
* c-o-w
*/
void tile_mirror (Tile *dest_tile, Tile *src_tile);
/* Referencing a tile causes the reference count to be incremented.
* If the reference count was previously 0 the tile will will be
* swapped into memory from disk.
*
* tile_ref2 is a new tile-referencing interface through which you
* should register your intent to dirty the tile. This will facilitate
* copy-on-write tile semantics.
* tile_lock locks a tile into memory. This does what tile_ref used
* to do. It is the responsibility of the tile manager to take care
* of the copy-on-write semantics. Locks stack; a tile remains locked
* in memory as long as it's been locked more times than it has been
* released. tile_release needs to know whether the release was for
* write access. (This is a hack, and should be handled better.)
*/
#if defined (TILE_DEBUG) && defined (__GNUC__)
#define tile_ref(t) _tile_ref (t, __PRETTY_FUNCTION__)
void _tile_ref (Tile *tile, char *func_name);
#define tile_ref2(t,d) _tile_ref2 (t, d, __PRETTY_FUNCTION__)
void _tile_ref2 (Tile *tile, int dirty, char *func_name);
#else
void tile_ref (Tile *tile);
void tile_ref2 (Tile *tile, int dirty);
#endif
/* Unreferencing a tile causes the reference count to be decremented.
* When the reference count reaches 0 the tile data will be swapped
* out to disk. Note that the tile may be in the tile cache which
* also references the tile causing the reference count not to
* fall below 1 until the tile is removed from the cache.
* The dirty flag indicates whether the tile data has been dirtied
* while referenced.
*/
#if defined (TILE_DEBUG) && defined (__GNUC__)
#define tile_unref(t,d) _tile_unref (t, d, __PRETTY_FUNCTION__)
void _tile_unref (Tile *tile, int dirty, char *func_name);
#else
void tile_unref (Tile *tile, int dirty);
#endif
void tile_lock (Tile *);
void tile_release (Tile *, int);
/* Allocate the data for the tile.
*/
@ -82,15 +45,15 @@ void tile_alloc (Tile *tile);
*/
int tile_size (Tile *tile);
/* Invalidates a tile. This involves setting its invalid bit and
* a) if the tile is in memory deleting the tile data or b) if the
* tile is in the swap file, deleting the space it occupies. This
* will cause the tile data to need to be recalculated.
* This should probably only be used on sublevel tiles. Invalidating
* a toplevel tile would mean that it needs to be recalculated. But
* what do you recalculate a toplevel tile from?
/* tile_attach attaches a tile to a tile manager: this function
* increments the tile's share count and inserts a tilelink into the
* tile's link list. tile_detach reverses the process.
* If a tile's share count is zero after a tile_detach, the tile is
* discarded.
*/
void tile_invalidate (Tile *tile);
void tile_attach (Tile *tile, void *tm, int tile_num);
void tile_detach (Tile *tile, void *tm, int tile_num);
#endif /* __TILE_H__ */

View File

@ -1014,10 +1014,9 @@ gradient_calc_shapeburst_angular_factor (double x,
ix = (int) BOUNDS (x, 0, distR.w);
iy = (int) BOUNDS (y, 0, distR.h);
tile = tile_manager_get_tile (distR.tiles, ix, iy, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (distR.tiles, ix, iy, 0, TRUE, FALSE);
value = 1.0 - *(((float *) tile->data) + ((iy % TILE_HEIGHT) * tile->ewidth + (ix % TILE_WIDTH)));
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
return value;
}
@ -1033,11 +1032,10 @@ gradient_calc_shapeburst_spherical_factor (double x,
ix = (int) BOUNDS (x, 0, distR.w);
iy = (int) BOUNDS (y, 0, distR.h);
tile = tile_manager_get_tile (distR.tiles, ix, iy, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (distR.tiles, ix, iy, 0, TRUE, FALSE);
value = *(((float *) tile->data) + ((iy % TILE_HEIGHT) * tile->ewidth + (ix % TILE_WIDTH)));
value = 1.0 - sin (0.5 * M_PI * value);
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
return value;
}
@ -1053,11 +1051,10 @@ gradient_calc_shapeburst_dimpled_factor (double x,
ix = (int) BOUNDS (x, 0, distR.w);
iy = (int) BOUNDS (y, 0, distR.h);
tile = tile_manager_get_tile (distR.tiles, ix, iy, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (distR.tiles, ix, iy, 0, TRUE, FALSE);
value = *(((float *) tile->data) + ((iy % TILE_HEIGHT) * tile->ewidth + (ix % TILE_WIDTH)));
value = cos (0.5 * M_PI * value);
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
return value;
}

View File

@ -124,9 +124,8 @@ find_empty_segs (PixelRegion *maskPR,
if ((x / TILE_WIDTH) != tilex)
{
if (tile)
tile_unref (tile, FALSE);
tile = tile_manager_get_tile (maskPR->tiles, x, scanline, 0);
tile_ref2 (tile, FALSE);
tile_release (tile, FALSE);
tile = tile_manager_get_tile (maskPR->tiles, x, scanline, 0, TRUE, FALSE);
data = tile->data + tile->bpp *
((scanline % TILE_HEIGHT) * tile->ewidth + (x % TILE_WIDTH)) + (tile->bpp - 1);
tilex = x / TILE_WIDTH;
@ -153,7 +152,7 @@ find_empty_segs (PixelRegion *maskPR,
empty_segs[(*num_empty)++] = G_MAXINT;
if (tile)
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
}

View File

@ -360,21 +360,19 @@ by_color_select_button_release (Tool *tool,
{
if (x < 0 || y < 0 || x >= gdisp->gimage->width || y >= gdisp->gimage->height)
return;
tile = tile_manager_get_tile (gimage_composite (gdisp->gimage), x, y, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (gimage_composite (gdisp->gimage), x, y, 0, TRUE, FALSE);
data = tile->data + tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
gimage_get_color (gdisp->gimage, gimage_composite_type(gdisp->gimage), col, data);
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
}
else
{
if (x < 0 || y < 0 || x >= drawable_width (drawable) || y >= drawable_height (drawable))
return;
tile = tile_manager_get_tile (drawable_data (drawable), x, y, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (drawable_data (drawable), x, y, 0, TRUE, FALSE);
data = tile->data + tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
gimage_get_color (gdisp->gimage, drawable_type(drawable), col, data);
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
}
/* select the area */
@ -933,8 +931,7 @@ by_color_select_preview_button_press (ByColorDialog *bcd,
y = bcd->gimage->height * bevent->y / bcd->preview->requisition.height;
if (x < 0 || y < 0 || x >= bcd->gimage->width || y >= bcd->gimage->height)
return;
tile = tile_manager_get_tile (gimage_composite (bcd->gimage), x, y, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (gimage_composite (bcd->gimage), x, y, 0, TRUE, FALSE);
col = tile->data + tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
}
else
@ -946,8 +943,7 @@ by_color_select_preview_button_press (ByColorDialog *bcd,
y = drawable_height (drawable) * bevent->y / bcd->preview->requisition.height - offy;
if (x < 0 || y < 0 || x >= drawable_width (drawable) || y >= drawable_height (drawable))
return;
tile = tile_manager_get_tile (drawable_data (drawable), x, y, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (drawable_data (drawable), x, y, 0, TRUE, FALSE);
col = tile->data + tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
}
@ -959,7 +955,7 @@ by_color_select_preview_button_press (ByColorDialog *bcd,
by_color_options->feather_radius,
by_color_options->sample_merged);
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
/* show selection on all views */
gdisplays_flush ();

View File

@ -548,10 +548,9 @@ channel_value (Channel *mask, int x, int y)
return 0;
}
tile = tile_manager_get_tile (GIMP_DRAWABLE(mask)->tiles, x, y, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (GIMP_DRAWABLE(mask)->tiles, x, y, 0, TRUE, FALSE);
val = tile->data[(y % TILE_HEIGHT) * TILE_WIDTH + (x % TILE_WIDTH)];
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
return val;
}

View File

@ -327,8 +327,7 @@ get_color (GImage *gimage,
if (x >= 0 && y >= 0 && x < width && y < height)
{
tile = tile_manager_get_tile (tiles, x, y, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (tiles, x, y, 0, TRUE, FALSE);
src = tile->data + tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
}
@ -369,7 +368,7 @@ get_color (GImage *gimage,
break;
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
palette_set_active_color (col_value [RED_PIX], col_value [GREEN_PIX],
col_value [BLUE_PIX], final);

View File

@ -548,10 +548,9 @@ channel_value (Channel *mask, int x, int y)
return 0;
}
tile = tile_manager_get_tile (GIMP_DRAWABLE(mask)->tiles, x, y, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (GIMP_DRAWABLE(mask)->tiles, x, y, 0, TRUE, FALSE);
val = tile->data[(y % TILE_HEIGHT) * TILE_WIDTH + (x % TILE_WIDTH)];
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
return val;
}

View File

@ -548,10 +548,9 @@ channel_value (Channel *mask, int x, int y)
return 0;
}
tile = tile_manager_get_tile (GIMP_DRAWABLE(mask)->tiles, x, y, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (GIMP_DRAWABLE(mask)->tiles, x, y, 0, TRUE, FALSE);
val = tile->data[(y % TILE_HEIGHT) * TILE_WIDTH + (x % TILE_WIDTH)];
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
return val;
}

View File

@ -1014,10 +1014,9 @@ gradient_calc_shapeburst_angular_factor (double x,
ix = (int) BOUNDS (x, 0, distR.w);
iy = (int) BOUNDS (y, 0, distR.h);
tile = tile_manager_get_tile (distR.tiles, ix, iy, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (distR.tiles, ix, iy, 0, TRUE, FALSE);
value = 1.0 - *(((float *) tile->data) + ((iy % TILE_HEIGHT) * tile->ewidth + (ix % TILE_WIDTH)));
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
return value;
}
@ -1033,11 +1032,10 @@ gradient_calc_shapeburst_spherical_factor (double x,
ix = (int) BOUNDS (x, 0, distR.w);
iy = (int) BOUNDS (y, 0, distR.h);
tile = tile_manager_get_tile (distR.tiles, ix, iy, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (distR.tiles, ix, iy, 0, TRUE, FALSE);
value = *(((float *) tile->data) + ((iy % TILE_HEIGHT) * tile->ewidth + (ix % TILE_WIDTH)));
value = 1.0 - sin (0.5 * M_PI * value);
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
return value;
}
@ -1053,11 +1051,10 @@ gradient_calc_shapeburst_dimpled_factor (double x,
ix = (int) BOUNDS (x, 0, distR.w);
iy = (int) BOUNDS (y, 0, distR.h);
tile = tile_manager_get_tile (distR.tiles, ix, iy, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (distR.tiles, ix, iy, 0, TRUE, FALSE);
value = *(((float *) tile->data) + ((iy % TILE_HEIGHT) * tile->ewidth + (ix % TILE_WIDTH)));
value = cos (0.5 * M_PI * value);
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
return value;
}

View File

@ -1226,7 +1226,7 @@ gimp_image_invalidate (GimpImage *gimage, int x, int y, int w, int h, int x1, in
for (i = y; i < (y + h); i += (TILE_HEIGHT - (i % TILE_HEIGHT)))
for (j = x; j < (x + w); j += (TILE_WIDTH - (j % TILE_WIDTH)))
{
tile = tile_manager_get_tile (tm, j, i, 0);
tile = tile_manager_get_tile (tm, j, i, 0, FALSE, FALSE);
/* invalidate all lower level tiles */
/*tile_manager_invalidate_tiles (gimp_image_projection (gimage), tile);*/
@ -1286,8 +1286,8 @@ gimp_image_validate (TileManager *tm, Tile *tile, int level)
gimage = (GimpImage *) tm->user_data;
/* Find the coordinates of this tile */
x = TILE_WIDTH * (tile->tile_num % tm->levels[0].ntile_cols);
y = TILE_HEIGHT * (tile->tile_num / tm->levels[0].ntile_cols);
x = TILE_WIDTH * (tile->tlink->tile_num % tm->levels[0].ntile_cols);
y = TILE_HEIGHT * (tile->tlink->tile_num / tm->levels[0].ntile_cols);
w = tile->ewidth;
h = tile->eheight;

View File

@ -1226,7 +1226,7 @@ gimp_image_invalidate (GimpImage *gimage, int x, int y, int w, int h, int x1, in
for (i = y; i < (y + h); i += (TILE_HEIGHT - (i % TILE_HEIGHT)))
for (j = x; j < (x + w); j += (TILE_WIDTH - (j % TILE_WIDTH)))
{
tile = tile_manager_get_tile (tm, j, i, 0);
tile = tile_manager_get_tile (tm, j, i, 0, FALSE, FALSE);
/* invalidate all lower level tiles */
/*tile_manager_invalidate_tiles (gimp_image_projection (gimage), tile);*/
@ -1286,8 +1286,8 @@ gimp_image_validate (TileManager *tm, Tile *tile, int level)
gimage = (GimpImage *) tm->user_data;
/* Find the coordinates of this tile */
x = TILE_WIDTH * (tile->tile_num % tm->levels[0].ntile_cols);
y = TILE_HEIGHT * (tile->tile_num / tm->levels[0].ntile_cols);
x = TILE_WIDTH * (tile->tlink->tile_num % tm->levels[0].ntile_cols);
y = TILE_HEIGHT * (tile->tlink->tile_num / tm->levels[0].ntile_cols);
w = tile->ewidth;
h = tile->eheight;

View File

@ -1226,7 +1226,7 @@ gimp_image_invalidate (GimpImage *gimage, int x, int y, int w, int h, int x1, in
for (i = y; i < (y + h); i += (TILE_HEIGHT - (i % TILE_HEIGHT)))
for (j = x; j < (x + w); j += (TILE_WIDTH - (j % TILE_WIDTH)))
{
tile = tile_manager_get_tile (tm, j, i, 0);
tile = tile_manager_get_tile (tm, j, i, 0, FALSE, FALSE);
/* invalidate all lower level tiles */
/*tile_manager_invalidate_tiles (gimp_image_projection (gimage), tile);*/
@ -1286,8 +1286,8 @@ gimp_image_validate (TileManager *tm, Tile *tile, int level)
gimage = (GimpImage *) tm->user_data;
/* Find the coordinates of this tile */
x = TILE_WIDTH * (tile->tile_num % tm->levels[0].ntile_cols);
y = TILE_HEIGHT * (tile->tile_num / tm->levels[0].ntile_cols);
x = TILE_WIDTH * (tile->tlink->tile_num % tm->levels[0].ntile_cols);
y = TILE_HEIGHT * (tile->tlink->tile_num / tm->levels[0].ntile_cols);
w = tile->ewidth;
h = tile->eheight;

View File

@ -1226,7 +1226,7 @@ gimp_image_invalidate (GimpImage *gimage, int x, int y, int w, int h, int x1, in
for (i = y; i < (y + h); i += (TILE_HEIGHT - (i % TILE_HEIGHT)))
for (j = x; j < (x + w); j += (TILE_WIDTH - (j % TILE_WIDTH)))
{
tile = tile_manager_get_tile (tm, j, i, 0);
tile = tile_manager_get_tile (tm, j, i, 0, FALSE, FALSE);
/* invalidate all lower level tiles */
/*tile_manager_invalidate_tiles (gimp_image_projection (gimage), tile);*/
@ -1286,8 +1286,8 @@ gimp_image_validate (TileManager *tm, Tile *tile, int level)
gimage = (GimpImage *) tm->user_data;
/* Find the coordinates of this tile */
x = TILE_WIDTH * (tile->tile_num % tm->levels[0].ntile_cols);
y = TILE_HEIGHT * (tile->tile_num / tm->levels[0].ntile_cols);
x = TILE_WIDTH * (tile->tlink->tile_num % tm->levels[0].ntile_cols);
y = TILE_HEIGHT * (tile->tlink->tile_num / tm->levels[0].ntile_cols);
w = tile->ewidth;
h = tile->eheight;

View File

@ -1226,7 +1226,7 @@ gimp_image_invalidate (GimpImage *gimage, int x, int y, int w, int h, int x1, in
for (i = y; i < (y + h); i += (TILE_HEIGHT - (i % TILE_HEIGHT)))
for (j = x; j < (x + w); j += (TILE_WIDTH - (j % TILE_WIDTH)))
{
tile = tile_manager_get_tile (tm, j, i, 0);
tile = tile_manager_get_tile (tm, j, i, 0, FALSE, FALSE);
/* invalidate all lower level tiles */
/*tile_manager_invalidate_tiles (gimp_image_projection (gimage), tile);*/
@ -1286,8 +1286,8 @@ gimp_image_validate (TileManager *tm, Tile *tile, int level)
gimage = (GimpImage *) tm->user_data;
/* Find the coordinates of this tile */
x = TILE_WIDTH * (tile->tile_num % tm->levels[0].ntile_cols);
y = TILE_HEIGHT * (tile->tile_num / tm->levels[0].ntile_cols);
x = TILE_WIDTH * (tile->tlink->tile_num % tm->levels[0].ntile_cols);
y = TILE_HEIGHT * (tile->tlink->tile_num / tm->levels[0].ntile_cols);
w = tile->ewidth;
h = tile->eheight;

View File

@ -613,17 +613,15 @@ undo_pop_image (GImage *gimage,
{
for (j = x; j < image_undo->x2; j += (TILE_WIDTH - (j % TILE_WIDTH)))
{
src_tile = tile_manager_get_tile (tiles, j, i, 0);
src_tile = tile_manager_get_tile (tiles, j, i, 0, TRUE, TRUE);
if (src_tile->valid == TRUE)
{
dest_tile = tile_manager_get_tile (drawable_data (image_undo->drawable), j, i, 0);
tile_ref2 (src_tile, TRUE);
tile_ref2 (dest_tile, TRUE);
dest_tile = tile_manager_get_tile (drawable_data (image_undo->drawable), j, i, 0, TRUE, TRUE);
swap_pixels (src_tile->data, dest_tile->data,
(src_tile->ewidth * src_tile->eheight * src_tile->bpp));
tile_unref (src_tile, TRUE);
tile_unref (dest_tile, TRUE);
tile_release (dest_tile, TRUE);
}
tile_release (src_tile, TRUE);
}
}
}

View File

@ -1226,7 +1226,7 @@ gimp_image_invalidate (GimpImage *gimage, int x, int y, int w, int h, int x1, in
for (i = y; i < (y + h); i += (TILE_HEIGHT - (i % TILE_HEIGHT)))
for (j = x; j < (x + w); j += (TILE_WIDTH - (j % TILE_WIDTH)))
{
tile = tile_manager_get_tile (tm, j, i, 0);
tile = tile_manager_get_tile (tm, j, i, 0, FALSE, FALSE);
/* invalidate all lower level tiles */
/*tile_manager_invalidate_tiles (gimp_image_projection (gimage), tile);*/
@ -1286,8 +1286,8 @@ gimp_image_validate (TileManager *tm, Tile *tile, int level)
gimage = (GimpImage *) tm->user_data;
/* Find the coordinates of this tile */
x = TILE_WIDTH * (tile->tile_num % tm->levels[0].ntile_cols);
y = TILE_HEIGHT * (tile->tile_num / tm->levels[0].ntile_cols);
x = TILE_WIDTH * (tile->tlink->tile_num % tm->levels[0].ntile_cols);
y = TILE_HEIGHT * (tile->tlink->tile_num / tm->levels[0].ntile_cols);
w = tile->ewidth;
h = tile->eheight;

View File

@ -940,19 +940,17 @@ layer_pick_correlate (layer, x, y)
/* Otherwise, determine if the alpha value at
* the given point is non-zero
*/
tile = tile_manager_get_tile (GIMP_DRAWABLE(layer)->tiles, x, y, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (GIMP_DRAWABLE(layer)->tiles, x, y, 0, TRUE, FALSE);
val = tile->data[tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH) + 1) - 1];
if (layer->mask)
{
mask_tile = tile_manager_get_tile (GIMP_DRAWABLE(layer->mask)->tiles, x, y, 0);
tile_ref2 (mask_tile, FALSE);
mask_tile = tile_manager_get_tile (GIMP_DRAWABLE(layer->mask)->tiles, x, y, 0, TRUE, FALSE);
val = (val * mask_tile->data[mask_tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH)]) / 255;
tile_unref (mask_tile, FALSE);
tile_release (mask_tile, FALSE);
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
if (val > 63)
return TRUE;

View File

@ -1226,7 +1226,7 @@ gimp_image_invalidate (GimpImage *gimage, int x, int y, int w, int h, int x1, in
for (i = y; i < (y + h); i += (TILE_HEIGHT - (i % TILE_HEIGHT)))
for (j = x; j < (x + w); j += (TILE_WIDTH - (j % TILE_WIDTH)))
{
tile = tile_manager_get_tile (tm, j, i, 0);
tile = tile_manager_get_tile (tm, j, i, 0, FALSE, FALSE);
/* invalidate all lower level tiles */
/*tile_manager_invalidate_tiles (gimp_image_projection (gimage), tile);*/
@ -1286,8 +1286,8 @@ gimp_image_validate (TileManager *tm, Tile *tile, int level)
gimage = (GimpImage *) tm->user_data;
/* Find the coordinates of this tile */
x = TILE_WIDTH * (tile->tile_num % tm->levels[0].ntile_cols);
y = TILE_HEIGHT * (tile->tile_num / tm->levels[0].ntile_cols);
x = TILE_WIDTH * (tile->tlink->tile_num % tm->levels[0].ntile_cols);
y = TILE_HEIGHT * (tile->tlink->tile_num / tm->levels[0].ntile_cols);
w = tile->ewidth;
h = tile->eheight;

View File

@ -62,7 +62,7 @@ static void file_prefs_save_callback (GtkWidget *, GtkWidget *);
static void file_prefs_cancel_callback (GtkWidget *, GtkWidget *);
static gint file_prefs_delete_callback (GtkWidget *, GdkEvent *, GtkWidget *);
static void file_prefs_toggle_callback (GtkWidget *, gpointer);
static void file_prefs_text_callback (GtkWidget *, gpointer);
/* static void file_prefs_text_callback (GtkWidget *, gpointer); */
static void file_prefs_spinbutton_callback (GtkWidget *, gpointer);
static void file_prefs_preview_size_callback (GtkWidget *, gpointer);
static void file_prefs_mem_size_unit_callback (GtkWidget *, gpointer);
@ -527,6 +527,7 @@ file_prefs_mem_size_unit_callback (GtkWidget *widget,
}
}
/* commented out because it's not used
static void
file_prefs_text_callback (GtkWidget *widget,
gpointer data)
@ -536,6 +537,7 @@ file_prefs_text_callback (GtkWidget *widget,
val = data;
*val = atoi (gtk_entry_get_text (GTK_ENTRY (widget)));
}
*/
static void
file_prefs_spinbutton_callback (GtkWidget *widget,

View File

@ -2434,11 +2434,10 @@ render_image_tile_fault (RenderInfo *info)
tilex = info->src_x / TILE_WIDTH;
tiley = info->src_y / TILE_HEIGHT;
tile = tile_manager_get_tile (info->src_tiles, info->src_x, info->src_y, 0);
tile = tile_manager_get_tile (info->src_tiles, info->src_x, info->src_y, 0, TRUE, FALSE);
if (!tile)
return NULL;
tile_ref2 (tile, FALSE);
data = (tile->data +
((info->src_y % TILE_HEIGHT) * tile->ewidth +
(info->src_x % TILE_WIDTH)) * tile->bpp);
@ -2462,14 +2461,13 @@ render_image_tile_fault (RenderInfo *info)
if ((x >> tile_shift) != tilex)
{
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
tilex += 1;
tile = tile_manager_get_tile (info->src_tiles, x, info->src_y, 0);
tile = tile_manager_get_tile (info->src_tiles, x, info->src_y, 0, TRUE, FALSE);
if (!tile)
return tile_buf;
tile_ref2 (tile, FALSE);
data = (tile->data +
((info->src_y % TILE_HEIGHT) * tile->ewidth +
(x % TILE_WIDTH)) * tile->bpp);
@ -2477,6 +2475,6 @@ render_image_tile_fault (RenderInfo *info)
}
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
return tile_buf;
}

View File

@ -2434,11 +2434,10 @@ render_image_tile_fault (RenderInfo *info)
tilex = info->src_x / TILE_WIDTH;
tiley = info->src_y / TILE_HEIGHT;
tile = tile_manager_get_tile (info->src_tiles, info->src_x, info->src_y, 0);
tile = tile_manager_get_tile (info->src_tiles, info->src_x, info->src_y, 0, TRUE, FALSE);
if (!tile)
return NULL;
tile_ref2 (tile, FALSE);
data = (tile->data +
((info->src_y % TILE_HEIGHT) * tile->ewidth +
(info->src_x % TILE_WIDTH)) * tile->bpp);
@ -2462,14 +2461,13 @@ render_image_tile_fault (RenderInfo *info)
if ((x >> tile_shift) != tilex)
{
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
tilex += 1;
tile = tile_manager_get_tile (info->src_tiles, x, info->src_y, 0);
tile = tile_manager_get_tile (info->src_tiles, x, info->src_y, 0, TRUE, FALSE);
if (!tile)
return tile_buf;
tile_ref2 (tile, FALSE);
data = (tile->data +
((info->src_y % TILE_HEIGHT) * tile->ewidth +
(x % TILE_WIDTH)) * tile->bpp);
@ -2477,6 +2475,6 @@ render_image_tile_fault (RenderInfo *info)
}
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
return tile_buf;
}

View File

@ -1264,8 +1264,7 @@ drawable_set_pixel_invoker (Argument *args)
if (success)
{
tile = tile_manager_get_tile (drawable_data (drawable), x, y, 0);
tile_ref2 (tile, TRUE);
tile = tile_manager_get_tile (drawable_data (drawable), x, y, 0, TRUE, TRUE);
x %= TILE_WIDTH;
y %= TILE_HEIGHT;
@ -1274,7 +1273,7 @@ drawable_set_pixel_invoker (Argument *args)
for (b = 0; b < num_channels; b++)
*p++ = *pixel++;
tile_unref (tile, TRUE);
tile_release (tile, TRUE);
}
return procedural_db_return_args (&drawable_set_pixel_proc, success);
@ -1369,8 +1368,7 @@ drawable_get_pixel_invoker (Argument *args)
if (success)
{
pixel = (unsigned char *) g_new (unsigned char, num_channels);
tile = tile_manager_get_tile (drawable_data (drawable), x, y, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (drawable_data (drawable), x, y, 0, TRUE, FALSE);
x %= TILE_WIDTH;
y %= TILE_HEIGHT;
@ -1379,7 +1377,7 @@ drawable_get_pixel_invoker (Argument *args)
for (b = 0; b < num_channels; b++)
pixel[b] = p[b];
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
}
return_args = procedural_db_return_args (&drawable_get_pixel_proc, success);

View File

@ -293,7 +293,7 @@ xcf_load_frac_compressed_tile (XcfInfo *info, Tile *tile)
g_print ("Returned from decompressTile (tile, num_channels=%i)\n",
num_channels_arr[layer_type]);
tile_unref (tile, TRUE);
tile_release (tile, TRUE);
return 1;
}
@ -422,7 +422,7 @@ xcf_save_frac_compressed_tile (XcfInfo *info, Tile *tile)
CloseOutputBitFile (frac_file);
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
return 1;

View File

@ -124,14 +124,12 @@ ref_tiles (TileManager *src, TileManager *mask, Tile **s_tile, Tile **m_tile,
int x, int y, unsigned char **s, unsigned char **m)
{
if (*s_tile != NULL)
tile_unref (*s_tile, FALSE);
tile_release (*s_tile, FALSE);
if (*m_tile != NULL)
tile_unref (*m_tile, TRUE);
tile_release (*m_tile, TRUE);
*s_tile = tile_manager_get_tile (src, x, y, 0);
*m_tile = tile_manager_get_tile (mask, x, y, 0);
tile_ref2 (*s_tile, FALSE);
tile_ref2 (*m_tile, TRUE);
*s_tile = tile_manager_get_tile (src, x, y, 0, TRUE, FALSE);
*m_tile = tile_manager_get_tile (mask, x, y, 0, TRUE, TRUE);
*s = (*s_tile)->data + (*s_tile)->bpp * ((*s_tile)->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
*m = (*m_tile)->data + (*m_tile)->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH);
@ -154,8 +152,8 @@ find_contiguous_segment (unsigned char *col, PixelRegion *src,
if (! (diff = is_pixel_sufficiently_different (col, s, antialias,
threshold, bytes, has_alpha)))
{
tile_unref (s_tile, FALSE);
tile_unref (m_tile, TRUE);
tile_release (s_tile, FALSE);
tile_release (m_tile, TRUE);
return FALSE;
}
@ -196,8 +194,8 @@ find_contiguous_segment (unsigned char *col, PixelRegion *src,
}
}
tile_unref (s_tile, FALSE);
tile_unref (m_tile, TRUE);
tile_release (s_tile, FALSE);
tile_release (m_tile, TRUE);
return TRUE;
}
@ -216,10 +214,9 @@ find_contiguous_region_helper (PixelRegion *mask, PixelRegion *src,
if (x < 0 || x >= src->w) return;
if (y < 0 || y >= src->h) return;
tile = tile_manager_get_tile (mask->tiles, x, y, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (mask->tiles, x, y, 0, TRUE, FALSE);
val = tile->data[tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH)];
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
if (val != 0)
return;
@ -283,17 +280,15 @@ find_contiguous_region (GImage *gimage, GimpDrawable *drawable, int antialias,
mask = channel_new_mask (gimage, srcPR.w, srcPR.h);
pixel_region_init (&maskPR, drawable_data (GIMP_DRAWABLE(mask)), 0, 0, drawable_width (GIMP_DRAWABLE(mask)), drawable_height (GIMP_DRAWABLE(mask)), TRUE);
tile = tile_manager_get_tile (srcPR.tiles, x, y, 0);
tile = tile_manager_get_tile (srcPR.tiles, x, y, 0, TRUE, FALSE);
if (tile)
{
tile_ref2 (tile, FALSE);
start = tile->data + tile->ewidth * tile->bpp * (y % TILE_HEIGHT) +
tile->bpp * (x % TILE_WIDTH);
find_contiguous_region_helper (&maskPR, &srcPR, has_alpha, antialias, threshold, bytes, x, y, start);
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
}
return mask;

View File

@ -548,10 +548,9 @@ channel_value (Channel *mask, int x, int y)
return 0;
}
tile = tile_manager_get_tile (GIMP_DRAWABLE(mask)->tiles, x, y, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (GIMP_DRAWABLE(mask)->tiles, x, y, 0, TRUE, FALSE);
val = tile->data[(y % TILE_HEIGHT) * TILE_WIDTH + (x % TILE_WIDTH)];
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
return val;
}

View File

@ -1226,7 +1226,7 @@ gimp_image_invalidate (GimpImage *gimage, int x, int y, int w, int h, int x1, in
for (i = y; i < (y + h); i += (TILE_HEIGHT - (i % TILE_HEIGHT)))
for (j = x; j < (x + w); j += (TILE_WIDTH - (j % TILE_WIDTH)))
{
tile = tile_manager_get_tile (tm, j, i, 0);
tile = tile_manager_get_tile (tm, j, i, 0, FALSE, FALSE);
/* invalidate all lower level tiles */
/*tile_manager_invalidate_tiles (gimp_image_projection (gimage), tile);*/
@ -1286,8 +1286,8 @@ gimp_image_validate (TileManager *tm, Tile *tile, int level)
gimage = (GimpImage *) tm->user_data;
/* Find the coordinates of this tile */
x = TILE_WIDTH * (tile->tile_num % tm->levels[0].ntile_cols);
y = TILE_HEIGHT * (tile->tile_num / tm->levels[0].ntile_cols);
x = TILE_WIDTH * (tile->tlink->tile_num % tm->levels[0].ntile_cols);
y = TILE_HEIGHT * (tile->tlink->tile_num / tm->levels[0].ntile_cols);
w = tile->ewidth;
h = tile->eheight;

View File

@ -940,19 +940,17 @@ layer_pick_correlate (layer, x, y)
/* Otherwise, determine if the alpha value at
* the given point is non-zero
*/
tile = tile_manager_get_tile (GIMP_DRAWABLE(layer)->tiles, x, y, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (GIMP_DRAWABLE(layer)->tiles, x, y, 0, TRUE, FALSE);
val = tile->data[tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH) + 1) - 1];
if (layer->mask)
{
mask_tile = tile_manager_get_tile (GIMP_DRAWABLE(layer->mask)->tiles, x, y, 0);
tile_ref2 (mask_tile, FALSE);
mask_tile = tile_manager_get_tile (GIMP_DRAWABLE(layer->mask)->tiles, x, y, 0, TRUE, FALSE);
val = (val * mask_tile->data[mask_tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH)]) / 255;
tile_unref (mask_tile, FALSE);
tile_release (mask_tile, FALSE);
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
if (val > 63)
return TRUE;

View File

@ -1353,7 +1353,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_info->tile_num, 0);
tile = tile_manager_get (tm, tile_info->tile_num, 0, TRUE, TRUE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1361,14 +1361,12 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_ref2 (tile, TRUE);
if (tile_data.use_shm)
memcpy (tile->data, shm_addr, tile_size (tile));
else
memcpy (tile->data, tile_info->data, tile_size (tile));
tile_unref (tile, TRUE);
tile_release (tile, TRUE);
wire_destroy (&msg);
if (!gp_tile_ack_write (current_writefd))
@ -1392,7 +1390,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_req->tile_num, 0);
tile = tile_manager_get (tm, tile_req->tile_num, 0, TRUE, FALSE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1408,8 +1406,6 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
tile_data.height = tile->eheight;
tile_data.use_shm = (shm_ID == -1) ? FALSE : TRUE;
tile_ref2 (tile, FALSE);
if (tile_data.use_shm)
memcpy (shm_addr, tile->data, tile_size (tile));
else
@ -1422,7 +1418,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
if (!wire_read_msg (current_readfd, &msg))
{

View File

@ -1353,7 +1353,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_info->tile_num, 0);
tile = tile_manager_get (tm, tile_info->tile_num, 0, TRUE, TRUE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1361,14 +1361,12 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_ref2 (tile, TRUE);
if (tile_data.use_shm)
memcpy (tile->data, shm_addr, tile_size (tile));
else
memcpy (tile->data, tile_info->data, tile_size (tile));
tile_unref (tile, TRUE);
tile_release (tile, TRUE);
wire_destroy (&msg);
if (!gp_tile_ack_write (current_writefd))
@ -1392,7 +1390,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_req->tile_num, 0);
tile = tile_manager_get (tm, tile_req->tile_num, 0, TRUE, FALSE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1408,8 +1406,6 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
tile_data.height = tile->eheight;
tile_data.use_shm = (shm_ID == -1) ? FALSE : TRUE;
tile_ref2 (tile, FALSE);
if (tile_data.use_shm)
memcpy (shm_addr, tile->data, tile_size (tile));
else
@ -1422,7 +1418,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
if (!wire_read_msg (current_readfd, &msg))
{

View File

@ -62,7 +62,7 @@ static void file_prefs_save_callback (GtkWidget *, GtkWidget *);
static void file_prefs_cancel_callback (GtkWidget *, GtkWidget *);
static gint file_prefs_delete_callback (GtkWidget *, GdkEvent *, GtkWidget *);
static void file_prefs_toggle_callback (GtkWidget *, gpointer);
static void file_prefs_text_callback (GtkWidget *, gpointer);
/* static void file_prefs_text_callback (GtkWidget *, gpointer); */
static void file_prefs_spinbutton_callback (GtkWidget *, gpointer);
static void file_prefs_preview_size_callback (GtkWidget *, gpointer);
static void file_prefs_mem_size_unit_callback (GtkWidget *, gpointer);
@ -527,6 +527,7 @@ file_prefs_mem_size_unit_callback (GtkWidget *widget,
}
}
/* commented out because it's not used
static void
file_prefs_text_callback (GtkWidget *widget,
gpointer data)
@ -536,6 +537,7 @@ file_prefs_text_callback (GtkWidget *widget,
val = data;
*val = atoi (gtk_entry_get_text (GTK_ENTRY (widget)));
}
*/
static void
file_prefs_spinbutton_callback (GtkWidget *widget,

View File

@ -2434,11 +2434,10 @@ render_image_tile_fault (RenderInfo *info)
tilex = info->src_x / TILE_WIDTH;
tiley = info->src_y / TILE_HEIGHT;
tile = tile_manager_get_tile (info->src_tiles, info->src_x, info->src_y, 0);
tile = tile_manager_get_tile (info->src_tiles, info->src_x, info->src_y, 0, TRUE, FALSE);
if (!tile)
return NULL;
tile_ref2 (tile, FALSE);
data = (tile->data +
((info->src_y % TILE_HEIGHT) * tile->ewidth +
(info->src_x % TILE_WIDTH)) * tile->bpp);
@ -2462,14 +2461,13 @@ render_image_tile_fault (RenderInfo *info)
if ((x >> tile_shift) != tilex)
{
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
tilex += 1;
tile = tile_manager_get_tile (info->src_tiles, x, info->src_y, 0);
tile = tile_manager_get_tile (info->src_tiles, x, info->src_y, 0, TRUE, FALSE);
if (!tile)
return tile_buf;
tile_ref2 (tile, FALSE);
data = (tile->data +
((info->src_y % TILE_HEIGHT) * tile->ewidth +
(x % TILE_WIDTH)) * tile->bpp);
@ -2477,6 +2475,6 @@ render_image_tile_fault (RenderInfo *info)
}
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
return tile_buf;
}

View File

@ -972,16 +972,15 @@ ink_set_undo_tiles (drawable, x, y, w, h)
{
for (j = x; j < (x + w); j += (TILE_WIDTH - (j % TILE_WIDTH)))
{
dest_tile = tile_manager_get_tile (undo_tiles, j, i, 0);
dest_tile = tile_manager_get_tile (undo_tiles, j, i, 0, FALSE, FALSE);
if (dest_tile->valid == FALSE)
{
src_tile = tile_manager_get_tile (drawable_data (drawable), j, i, 0);
tile_ref (src_tile);
tile_ref (dest_tile);
dest_tile = tile_manager_get_tile (undo_tiles, j, i, 0, TRUE, TRUE);
src_tile = tile_manager_get_tile (drawable_data (drawable), j, i, 0, TRUE, FALSE);
memcpy (dest_tile->data, src_tile->data,
(src_tile->ewidth * src_tile->eheight * src_tile->bpp));
tile_unref (src_tile, FALSE);
tile_unref (dest_tile, TRUE);
tile_release (src_tile, FALSE);
tile_release (dest_tile, TRUE);
}
}
}
@ -1000,12 +999,12 @@ ink_set_canvas_tiles (x, y, w, h)
{
for (j = x; j < (x + w); j += (TILE_WIDTH - (j % TILE_WIDTH)))
{
tile = tile_manager_get_tile (canvas_tiles, j, i, 0);
tile = tile_manager_get_tile (canvas_tiles, j, i, 0, FALSE, FALSE);
if (tile->valid == FALSE)
{
tile_ref (tile);
tile = tile_manager_get_tile (canvas_tiles, j, i, 0, TRUE, TRUE);
memset (tile->data, 0, (tile->ewidth * tile->eheight * tile->bpp));
tile_unref (tile, TRUE);
tile_release (tile, TRUE);
}
}
}

View File

@ -940,19 +940,17 @@ layer_pick_correlate (layer, x, y)
/* Otherwise, determine if the alpha value at
* the given point is non-zero
*/
tile = tile_manager_get_tile (GIMP_DRAWABLE(layer)->tiles, x, y, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (GIMP_DRAWABLE(layer)->tiles, x, y, 0, TRUE, FALSE);
val = tile->data[tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH) + 1) - 1];
if (layer->mask)
{
mask_tile = tile_manager_get_tile (GIMP_DRAWABLE(layer->mask)->tiles, x, y, 0);
tile_ref2 (mask_tile, FALSE);
mask_tile = tile_manager_get_tile (GIMP_DRAWABLE(layer->mask)->tiles, x, y, 0, TRUE, FALSE);
val = (val * mask_tile->data[mask_tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH)]) / 255;
tile_unref (mask_tile, FALSE);
tile_release (mask_tile, FALSE);
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
if (val > 63)
return TRUE;

View File

@ -1353,7 +1353,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_info->tile_num, 0);
tile = tile_manager_get (tm, tile_info->tile_num, 0, TRUE, TRUE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1361,14 +1361,12 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_ref2 (tile, TRUE);
if (tile_data.use_shm)
memcpy (tile->data, shm_addr, tile_size (tile));
else
memcpy (tile->data, tile_info->data, tile_size (tile));
tile_unref (tile, TRUE);
tile_release (tile, TRUE);
wire_destroy (&msg);
if (!gp_tile_ack_write (current_writefd))
@ -1392,7 +1390,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_req->tile_num, 0);
tile = tile_manager_get (tm, tile_req->tile_num, 0, TRUE, FALSE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1408,8 +1406,6 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
tile_data.height = tile->eheight;
tile_data.use_shm = (shm_ID == -1) ? FALSE : TRUE;
tile_ref2 (tile, FALSE);
if (tile_data.use_shm)
memcpy (shm_addr, tile->data, tile_size (tile));
else
@ -1422,7 +1418,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
if (!wire_read_msg (current_readfd, &msg))
{

View File

@ -97,7 +97,9 @@ static unsigned char no_mask = OPAQUE_OPACITY;
/* Local function prototypes */
static int * make_curve (double, int *);
static void run_length_encode (unsigned char *, int *, int, int);
#if 0
static void draw_segments (PixelRegion *, BoundSeg *, int, int, int, int);
#endif
static double cubic (double, int, int, int, int);
static void apply_layer_mode_replace (unsigned char *, unsigned char *,
unsigned char *, unsigned char *,
@ -194,7 +196,7 @@ run_length_encode (unsigned char *src,
}
}
#if 0
static void
draw_segments (PixelRegion *destPR,
BoundSeg *bs,
@ -261,7 +263,7 @@ draw_segments (PixelRegion *destPR,
}
}
}
#endif
static double
cubic (double dx,
@ -2434,7 +2436,6 @@ copy_region (PixelRegion *src,
)
{
Tile *src_tile;
Tile *dest_tile;
gint xstepper,ystepper;
#if defined (TILE_DEBUG)
@ -2453,18 +2454,12 @@ copy_region (PixelRegion *src,
{
src_tile = tile_manager_get_tile (src->tiles,
xstepper, ystepper,
0);
dest_tile = tile_manager_get_tile (dest->tiles,
xstepper, ystepper,
0);
0, FALSE, FALSE);
if (src_tile && dest_tile)
{
/* printf(" @%p/%p@ ",
tile_find_nonmirroring (src_tile),
tile_find_nonmirroring (dest_tile));*/
tile_mirror (dest_tile, src_tile);
}
tile_manager_map_tile (dest->tiles,
xstepper, ystepper, 0,
src_tile);
}
}
#if defined (TILE_DEBUG)
@ -3506,8 +3501,7 @@ shapeburst_region (PixelRegion *srcPR,
while (y >= end)
{
tile = tile_manager_get_tile (srcPR->tiles, x, y, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (srcPR->tiles, x, y, 0, TRUE, FALSE);
tile_data = tile->data + (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
boundary = MINIMUM ((y % TILE_HEIGHT), (tile->ewidth - (x % TILE_WIDTH) - 1));
boundary = MINIMUM (boundary, (y - end)) + 1;
@ -3530,7 +3524,7 @@ shapeburst_region (PixelRegion *srcPR,
tile_data += inc;
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
}
}

View File

@ -972,16 +972,15 @@ ink_set_undo_tiles (drawable, x, y, w, h)
{
for (j = x; j < (x + w); j += (TILE_WIDTH - (j % TILE_WIDTH)))
{
dest_tile = tile_manager_get_tile (undo_tiles, j, i, 0);
dest_tile = tile_manager_get_tile (undo_tiles, j, i, 0, FALSE, FALSE);
if (dest_tile->valid == FALSE)
{
src_tile = tile_manager_get_tile (drawable_data (drawable), j, i, 0);
tile_ref (src_tile);
tile_ref (dest_tile);
dest_tile = tile_manager_get_tile (undo_tiles, j, i, 0, TRUE, TRUE);
src_tile = tile_manager_get_tile (drawable_data (drawable), j, i, 0, TRUE, FALSE);
memcpy (dest_tile->data, src_tile->data,
(src_tile->ewidth * src_tile->eheight * src_tile->bpp));
tile_unref (src_tile, FALSE);
tile_unref (dest_tile, TRUE);
tile_release (src_tile, FALSE);
tile_release (dest_tile, TRUE);
}
}
}
@ -1000,12 +999,12 @@ ink_set_canvas_tiles (x, y, w, h)
{
for (j = x; j < (x + w); j += (TILE_WIDTH - (j % TILE_WIDTH)))
{
tile = tile_manager_get_tile (canvas_tiles, j, i, 0);
tile = tile_manager_get_tile (canvas_tiles, j, i, 0, FALSE, FALSE);
if (tile->valid == FALSE)
{
tile_ref (tile);
tile = tile_manager_get_tile (canvas_tiles, j, i, 0, TRUE, TRUE);
memset (tile->data, 0, (tile->ewidth * tile->eheight * tile->bpp));
tile_unref (tile, TRUE);
tile_release (tile, TRUE);
}
}
}

View File

@ -616,7 +616,6 @@ paint_core_get_orig_image (paint_core, drawable, x1, y1, x2, y2)
Tile *undo_tile;
int h;
int pixelwidth;
int refd;
unsigned char * s, * d;
void * pr;
@ -639,18 +638,15 @@ paint_core_get_orig_image (paint_core, drawable, x1, y1, x2, y2)
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
{
/* If the undo tile corresponding to this location is valid, use it */
undo_tile = tile_manager_get_tile (undo_tiles, srcPR.x, srcPR.y, 0);
undo_tile = tile_manager_get_tile (undo_tiles, srcPR.x, srcPR.y, 0, TRUE, FALSE);
if (undo_tile->valid == TRUE)
{
tile_ref2 (undo_tile, FALSE);
s = undo_tile->data + srcPR.rowstride * (srcPR.y % TILE_HEIGHT) +
srcPR.bytes * (srcPR.x % TILE_WIDTH);
refd = TRUE;
}
else
{
s = srcPR.data;
refd = FALSE;
}
d = destPR.data;
@ -663,8 +659,7 @@ paint_core_get_orig_image (paint_core, drawable, x1, y1, x2, y2)
d += destPR.rowstride;
}
if (refd)
tile_unref (undo_tile, FALSE);
tile_release (undo_tile, FALSE);
}
return orig_buf;
@ -1208,16 +1203,15 @@ set_undo_tiles (drawable, x, y, w, h)
{
for (j = x; j < (x + w); j += (TILE_WIDTH - (j % TILE_WIDTH)))
{
dest_tile = tile_manager_get_tile (undo_tiles, j, i, 0);
dest_tile = tile_manager_get_tile (undo_tiles, j, i, 0, FALSE, FALSE);
if (dest_tile->valid == FALSE)
{
src_tile = tile_manager_get_tile (drawable_data (drawable), j, i, 0);
tile_ref2 (src_tile, FALSE);
tile_ref2 (dest_tile, TRUE);
dest_tile = tile_manager_get_tile (undo_tiles, j, i, 0, TRUE, TRUE);
src_tile = tile_manager_get_tile (drawable_data (drawable), j, i, 0, TRUE, FALSE);
memcpy (dest_tile->data, src_tile->data,
(src_tile->ewidth * src_tile->eheight * src_tile->bpp));
tile_unref (src_tile, FALSE);
tile_unref (dest_tile, TRUE);
tile_release (src_tile, FALSE);
tile_release (dest_tile, TRUE);
}
}
}
@ -1235,12 +1229,12 @@ set_canvas_tiles (x, y, w, h)
{
for (j = x; j < (x + w); j += (TILE_WIDTH - (j % TILE_WIDTH)))
{
tile = tile_manager_get_tile (canvas_tiles, j, i, 0);
tile = tile_manager_get_tile (canvas_tiles, j, i, 0, FALSE, FALSE);
if (tile->valid == FALSE)
{
tile_ref2 (tile, TRUE);
tile = tile_manager_get_tile (canvas_tiles, j, i, 0, TRUE, TRUE);
memset (tile->data, 0, (tile->ewidth * tile->eheight * tile->bpp));
tile_unref (tile, TRUE);
tile_release (tile, TRUE);
}
}
}

View File

@ -97,7 +97,9 @@ static unsigned char no_mask = OPAQUE_OPACITY;
/* Local function prototypes */
static int * make_curve (double, int *);
static void run_length_encode (unsigned char *, int *, int, int);
#if 0
static void draw_segments (PixelRegion *, BoundSeg *, int, int, int, int);
#endif
static double cubic (double, int, int, int, int);
static void apply_layer_mode_replace (unsigned char *, unsigned char *,
unsigned char *, unsigned char *,
@ -194,7 +196,7 @@ run_length_encode (unsigned char *src,
}
}
#if 0
static void
draw_segments (PixelRegion *destPR,
BoundSeg *bs,
@ -261,7 +263,7 @@ draw_segments (PixelRegion *destPR,
}
}
}
#endif
static double
cubic (double dx,
@ -2434,7 +2436,6 @@ copy_region (PixelRegion *src,
)
{
Tile *src_tile;
Tile *dest_tile;
gint xstepper,ystepper;
#if defined (TILE_DEBUG)
@ -2453,18 +2454,12 @@ copy_region (PixelRegion *src,
{
src_tile = tile_manager_get_tile (src->tiles,
xstepper, ystepper,
0);
dest_tile = tile_manager_get_tile (dest->tiles,
xstepper, ystepper,
0);
0, FALSE, FALSE);
if (src_tile && dest_tile)
{
/* printf(" @%p/%p@ ",
tile_find_nonmirroring (src_tile),
tile_find_nonmirroring (dest_tile));*/
tile_mirror (dest_tile, src_tile);
}
tile_manager_map_tile (dest->tiles,
xstepper, ystepper, 0,
src_tile);
}
}
#if defined (TILE_DEBUG)
@ -3506,8 +3501,7 @@ shapeburst_region (PixelRegion *srcPR,
while (y >= end)
{
tile = tile_manager_get_tile (srcPR->tiles, x, y, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (srcPR->tiles, x, y, 0, TRUE, FALSE);
tile_data = tile->data + (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
boundary = MINIMUM ((y % TILE_HEIGHT), (tile->ewidth - (x % TILE_WIDTH) - 1));
boundary = MINIMUM (boundary, (y - end)) + 1;
@ -3530,7 +3524,7 @@ shapeburst_region (PixelRegion *srcPR,
tile_data += inc;
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
}
}

View File

@ -124,8 +124,7 @@ pixel_region_get_row (PR, x, y, w, data, subsample)
while (x < end)
{
tile = tile_manager_get_tile (PR->tiles, x, y, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (PR->tiles, x, y, 0, TRUE, FALSE);
tile_data = tile->data + tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
boundary = x + (tile->ewidth - (x % TILE_WIDTH));
inc = subsample * tile->bpp;
@ -137,7 +136,7 @@ pixel_region_get_row (PR, x, y, w, data, subsample)
tile_data += inc;
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
}
}
@ -159,8 +158,7 @@ pixel_region_set_row (PR, x, y, w, data)
while (x < end)
{
tile = tile_manager_get_tile (PR->tiles, x, y, 0);
tile_ref2 (tile, TRUE);
tile = tile_manager_get_tile (PR->tiles, x, y, 0, TRUE, TRUE);
tile_data = tile->data + tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
boundary = x + (tile->ewidth - (x % TILE_WIDTH));
@ -170,7 +168,7 @@ pixel_region_set_row (PR, x, y, w, data)
*tile_data++ = *data++;
}
tile_unref (tile, TRUE);
tile_release (tile, TRUE);
}
}
@ -194,8 +192,7 @@ pixel_region_get_col (PR, x, y, h, data, subsample)
while (y < end)
{
tile = tile_manager_get_tile (PR->tiles, x, y, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (PR->tiles, x, y, 0, TRUE, FALSE);
tile_data = tile->data + tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
boundary = y + (tile->eheight - (y % TILE_HEIGHT));
inc = subsample * tile->bpp * tile->ewidth;
@ -207,7 +204,7 @@ pixel_region_get_col (PR, x, y, h, data, subsample)
tile_data += inc;
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
}
}
@ -230,8 +227,7 @@ pixel_region_set_col (PR, x, y, h, data)
while (y < end)
{
tile = tile_manager_get_tile (PR->tiles, x, y, 0);
tile_ref2 (tile, TRUE);
tile = tile_manager_get_tile (PR->tiles, x, y, 0, TRUE, TRUE);
tile_data = tile->data + tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
boundary = y + (tile->eheight - (y % TILE_HEIGHT));
inc = tile->bpp * tile->ewidth;
@ -243,7 +239,7 @@ pixel_region_set_col (PR, x, y, h, data)
tile_data += inc;
}
tile_unref (tile, TRUE);
tile_release (tile, TRUE);
}
}
@ -329,8 +325,8 @@ pixel_regions_process (PRI_ptr)
/* Unref the last referenced tile if the underlying region is a tile manager */
if (PRH->PR->tiles)
{
Tile *tile = tile_manager_get_tile (PRH->PR->tiles, PRH->PR->x, PRH->PR->y, 0);
tile_unref (tile, PRH->PR->dirty);
Tile *tile = tile_manager_get_tile (PRH->PR->tiles, PRH->PR->x, PRH->PR->y, 0, FALSE, FALSE);
tile_release (tile, PRH->PR->dirty);
}
PRH->PR->x += PRI->portion_width;
@ -376,8 +372,8 @@ pixel_regions_process_stop (PRI_ptr)
/* Unref the last referenced tile if the underlying region is a tile manager */
if (PRH->PR->tiles)
{
Tile *tile = tile_manager_get_tile (PRH->PR->tiles, PRH->PR->x, PRH->PR->y, 0);
tile_unref (tile, PRH->PR->dirty);
Tile *tile = tile_manager_get_tile (PRH->PR->tiles, PRH->PR->x, PRH->PR->y, 0, FALSE, FALSE);
tile_release (tile, PRH->PR->dirty);
}
}
@ -550,8 +546,7 @@ pixel_region_configure (PRH, PRI)
Tile *tile;
int offx, offy;
tile = tile_manager_get_tile (PRH->PR->tiles, PRH->PR->x, PRH->PR->y, 0);
tile_ref2 (tile, PRH->PR->dirty);
tile = tile_manager_get_tile (PRH->PR->tiles, PRH->PR->x, PRH->PR->y, 0, TRUE, PRH->PR->dirty);
offx = PRH->PR->x % TILE_WIDTH;
offy = PRH->PR->y % TILE_HEIGHT;

View File

@ -1353,7 +1353,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_info->tile_num, 0);
tile = tile_manager_get (tm, tile_info->tile_num, 0, TRUE, TRUE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1361,14 +1361,12 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_ref2 (tile, TRUE);
if (tile_data.use_shm)
memcpy (tile->data, shm_addr, tile_size (tile));
else
memcpy (tile->data, tile_info->data, tile_size (tile));
tile_unref (tile, TRUE);
tile_release (tile, TRUE);
wire_destroy (&msg);
if (!gp_tile_ack_write (current_writefd))
@ -1392,7 +1390,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_req->tile_num, 0);
tile = tile_manager_get (tm, tile_req->tile_num, 0, TRUE, FALSE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1408,8 +1406,6 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
tile_data.height = tile->eheight;
tile_data.use_shm = (shm_ID == -1) ? FALSE : TRUE;
tile_ref2 (tile, FALSE);
if (tile_data.use_shm)
memcpy (shm_addr, tile->data, tile_size (tile));
else
@ -1422,7 +1418,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
if (!wire_read_msg (current_readfd, &msg))
{

View File

@ -1353,7 +1353,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_info->tile_num, 0);
tile = tile_manager_get (tm, tile_info->tile_num, 0, TRUE, TRUE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1361,14 +1361,12 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_ref2 (tile, TRUE);
if (tile_data.use_shm)
memcpy (tile->data, shm_addr, tile_size (tile));
else
memcpy (tile->data, tile_info->data, tile_size (tile));
tile_unref (tile, TRUE);
tile_release (tile, TRUE);
wire_destroy (&msg);
if (!gp_tile_ack_write (current_writefd))
@ -1392,7 +1390,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_req->tile_num, 0);
tile = tile_manager_get (tm, tile_req->tile_num, 0, TRUE, FALSE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1408,8 +1406,6 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
tile_data.height = tile->eheight;
tile_data.use_shm = (shm_ID == -1) ? FALSE : TRUE;
tile_ref2 (tile, FALSE);
if (tile_data.use_shm)
memcpy (shm_addr, tile->data, tile_size (tile));
else
@ -1422,7 +1418,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
if (!wire_read_msg (current_readfd, &msg))
{

View File

@ -1353,7 +1353,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_info->tile_num, 0);
tile = tile_manager_get (tm, tile_info->tile_num, 0, TRUE, TRUE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1361,14 +1361,12 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_ref2 (tile, TRUE);
if (tile_data.use_shm)
memcpy (tile->data, shm_addr, tile_size (tile));
else
memcpy (tile->data, tile_info->data, tile_size (tile));
tile_unref (tile, TRUE);
tile_release (tile, TRUE);
wire_destroy (&msg);
if (!gp_tile_ack_write (current_writefd))
@ -1392,7 +1390,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_req->tile_num, 0);
tile = tile_manager_get (tm, tile_req->tile_num, 0, TRUE, FALSE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1408,8 +1406,6 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
tile_data.height = tile->eheight;
tile_data.use_shm = (shm_ID == -1) ? FALSE : TRUE;
tile_ref2 (tile, FALSE);
if (tile_data.use_shm)
memcpy (shm_addr, tile->data, tile_size (tile));
else
@ -1422,7 +1418,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
if (!wire_read_msg (current_readfd, &msg))
{

View File

@ -1353,7 +1353,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_info->tile_num, 0);
tile = tile_manager_get (tm, tile_info->tile_num, 0, TRUE, TRUE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1361,14 +1361,12 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_ref2 (tile, TRUE);
if (tile_data.use_shm)
memcpy (tile->data, shm_addr, tile_size (tile));
else
memcpy (tile->data, tile_info->data, tile_size (tile));
tile_unref (tile, TRUE);
tile_release (tile, TRUE);
wire_destroy (&msg);
if (!gp_tile_ack_write (current_writefd))
@ -1392,7 +1390,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_req->tile_num, 0);
tile = tile_manager_get (tm, tile_req->tile_num, 0, TRUE, FALSE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1408,8 +1406,6 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
tile_data.height = tile->eheight;
tile_data.use_shm = (shm_ID == -1) ? FALSE : TRUE;
tile_ref2 (tile, FALSE);
if (tile_data.use_shm)
memcpy (shm_addr, tile->data, tile_size (tile));
else
@ -1422,7 +1418,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
if (!wire_read_msg (current_readfd, &msg))
{

View File

@ -1353,7 +1353,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_info->tile_num, 0);
tile = tile_manager_get (tm, tile_info->tile_num, 0, TRUE, TRUE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1361,14 +1361,12 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_ref2 (tile, TRUE);
if (tile_data.use_shm)
memcpy (tile->data, shm_addr, tile_size (tile));
else
memcpy (tile->data, tile_info->data, tile_size (tile));
tile_unref (tile, TRUE);
tile_release (tile, TRUE);
wire_destroy (&msg);
if (!gp_tile_ack_write (current_writefd))
@ -1392,7 +1390,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_req->tile_num, 0);
tile = tile_manager_get (tm, tile_req->tile_num, 0, TRUE, FALSE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1408,8 +1406,6 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
tile_data.height = tile->eheight;
tile_data.use_shm = (shm_ID == -1) ? FALSE : TRUE;
tile_ref2 (tile, FALSE);
if (tile_data.use_shm)
memcpy (shm_addr, tile->data, tile_size (tile));
else
@ -1422,7 +1418,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
if (!wire_read_msg (current_readfd, &msg))
{

View File

@ -1353,7 +1353,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_info->tile_num, 0);
tile = tile_manager_get (tm, tile_info->tile_num, 0, TRUE, TRUE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1361,14 +1361,12 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_ref2 (tile, TRUE);
if (tile_data.use_shm)
memcpy (tile->data, shm_addr, tile_size (tile));
else
memcpy (tile->data, tile_info->data, tile_size (tile));
tile_unref (tile, TRUE);
tile_release (tile, TRUE);
wire_destroy (&msg);
if (!gp_tile_ack_write (current_writefd))
@ -1392,7 +1390,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_req->tile_num, 0);
tile = tile_manager_get (tm, tile_req->tile_num, 0, TRUE, FALSE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1408,8 +1406,6 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
tile_data.height = tile->eheight;
tile_data.use_shm = (shm_ID == -1) ? FALSE : TRUE;
tile_ref2 (tile, FALSE);
if (tile_data.use_shm)
memcpy (shm_addr, tile->data, tile_size (tile));
else
@ -1422,7 +1418,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
if (!wire_read_msg (current_readfd, &msg))
{

View File

@ -1353,7 +1353,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_info->tile_num, 0);
tile = tile_manager_get (tm, tile_info->tile_num, 0, TRUE, TRUE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1361,14 +1361,12 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_ref2 (tile, TRUE);
if (tile_data.use_shm)
memcpy (tile->data, shm_addr, tile_size (tile));
else
memcpy (tile->data, tile_info->data, tile_size (tile));
tile_unref (tile, TRUE);
tile_release (tile, TRUE);
wire_destroy (&msg);
if (!gp_tile_ack_write (current_writefd))
@ -1392,7 +1390,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_req->tile_num, 0);
tile = tile_manager_get (tm, tile_req->tile_num, 0, TRUE, FALSE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1408,8 +1406,6 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
tile_data.height = tile->eheight;
tile_data.use_shm = (shm_ID == -1) ? FALSE : TRUE;
tile_ref2 (tile, FALSE);
if (tile_data.use_shm)
memcpy (shm_addr, tile->data, tile_size (tile));
else
@ -1422,7 +1418,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
if (!wire_read_msg (current_readfd, &msg))
{

View File

@ -1353,7 +1353,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_info->tile_num, 0);
tile = tile_manager_get (tm, tile_info->tile_num, 0, TRUE, TRUE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1361,14 +1361,12 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_ref2 (tile, TRUE);
if (tile_data.use_shm)
memcpy (tile->data, shm_addr, tile_size (tile));
else
memcpy (tile->data, tile_info->data, tile_size (tile));
tile_unref (tile, TRUE);
tile_release (tile, TRUE);
wire_destroy (&msg);
if (!gp_tile_ack_write (current_writefd))
@ -1392,7 +1390,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_req->tile_num, 0);
tile = tile_manager_get (tm, tile_req->tile_num, 0, TRUE, FALSE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1408,8 +1406,6 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
tile_data.height = tile->eheight;
tile_data.use_shm = (shm_ID == -1) ? FALSE : TRUE;
tile_ref2 (tile, FALSE);
if (tile_data.use_shm)
memcpy (shm_addr, tile->data, tile_size (tile));
else
@ -1422,7 +1418,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
if (!wire_read_msg (current_readfd, &msg))
{

View File

@ -1353,7 +1353,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_info->tile_num, 0);
tile = tile_manager_get (tm, tile_info->tile_num, 0, TRUE, TRUE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1361,14 +1361,12 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_ref2 (tile, TRUE);
if (tile_data.use_shm)
memcpy (tile->data, shm_addr, tile_size (tile));
else
memcpy (tile->data, tile_info->data, tile_size (tile));
tile_unref (tile, TRUE);
tile_release (tile, TRUE);
wire_destroy (&msg);
if (!gp_tile_ack_write (current_writefd))
@ -1392,7 +1390,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_req->tile_num, 0);
tile = tile_manager_get (tm, tile_req->tile_num, 0, TRUE, FALSE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1408,8 +1406,6 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
tile_data.height = tile->eheight;
tile_data.use_shm = (shm_ID == -1) ? FALSE : TRUE;
tile_ref2 (tile, FALSE);
if (tile_data.use_shm)
memcpy (shm_addr, tile->data, tile_size (tile));
else
@ -1422,7 +1418,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
if (!wire_read_msg (current_readfd, &msg))
{

View File

@ -1353,7 +1353,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_info->tile_num, 0);
tile = tile_manager_get (tm, tile_info->tile_num, 0, TRUE, TRUE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1361,14 +1361,12 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_ref2 (tile, TRUE);
if (tile_data.use_shm)
memcpy (tile->data, shm_addr, tile_size (tile));
else
memcpy (tile->data, tile_info->data, tile_size (tile));
tile_unref (tile, TRUE);
tile_release (tile, TRUE);
wire_destroy (&msg);
if (!gp_tile_ack_write (current_writefd))
@ -1392,7 +1390,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_req->tile_num, 0);
tile = tile_manager_get (tm, tile_req->tile_num, 0, TRUE, FALSE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1408,8 +1406,6 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
tile_data.height = tile->eheight;
tile_data.use_shm = (shm_ID == -1) ? FALSE : TRUE;
tile_ref2 (tile, FALSE);
if (tile_data.use_shm)
memcpy (shm_addr, tile->data, tile_size (tile));
else
@ -1422,7 +1418,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
if (!wire_read_msg (current_readfd, &msg))
{

View File

@ -1353,7 +1353,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_info->tile_num, 0);
tile = tile_manager_get (tm, tile_info->tile_num, 0, TRUE, TRUE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1361,14 +1361,12 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_ref2 (tile, TRUE);
if (tile_data.use_shm)
memcpy (tile->data, shm_addr, tile_size (tile));
else
memcpy (tile->data, tile_info->data, tile_size (tile));
tile_unref (tile, TRUE);
tile_release (tile, TRUE);
wire_destroy (&msg);
if (!gp_tile_ack_write (current_writefd))
@ -1392,7 +1390,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_req->tile_num, 0);
tile = tile_manager_get (tm, tile_req->tile_num, 0, TRUE, FALSE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1408,8 +1406,6 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
tile_data.height = tile->eheight;
tile_data.use_shm = (shm_ID == -1) ? FALSE : TRUE;
tile_ref2 (tile, FALSE);
if (tile_data.use_shm)
memcpy (shm_addr, tile->data, tile_size (tile));
else
@ -1422,7 +1418,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
if (!wire_read_msg (current_readfd, &msg))
{

View File

@ -1353,7 +1353,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_info->tile_num, 0);
tile = tile_manager_get (tm, tile_info->tile_num, 0, TRUE, TRUE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1361,14 +1361,12 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_ref2 (tile, TRUE);
if (tile_data.use_shm)
memcpy (tile->data, shm_addr, tile_size (tile));
else
memcpy (tile->data, tile_info->data, tile_size (tile));
tile_unref (tile, TRUE);
tile_release (tile, TRUE);
wire_destroy (&msg);
if (!gp_tile_ack_write (current_writefd))
@ -1392,7 +1390,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_req->tile_num, 0);
tile = tile_manager_get (tm, tile_req->tile_num, 0, TRUE, FALSE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1408,8 +1406,6 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
tile_data.height = tile->eheight;
tile_data.use_shm = (shm_ID == -1) ? FALSE : TRUE;
tile_ref2 (tile, FALSE);
if (tile_data.use_shm)
memcpy (shm_addr, tile->data, tile_size (tile));
else
@ -1422,7 +1418,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
if (!wire_read_msg (current_readfd, &msg))
{

View File

@ -1353,7 +1353,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_info->tile_num, 0);
tile = tile_manager_get (tm, tile_info->tile_num, 0, TRUE, TRUE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1361,14 +1361,12 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_ref2 (tile, TRUE);
if (tile_data.use_shm)
memcpy (tile->data, shm_addr, tile_size (tile));
else
memcpy (tile->data, tile_info->data, tile_size (tile));
tile_unref (tile, TRUE);
tile_release (tile, TRUE);
wire_destroy (&msg);
if (!gp_tile_ack_write (current_writefd))
@ -1392,7 +1390,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_req->tile_num, 0);
tile = tile_manager_get (tm, tile_req->tile_num, 0, TRUE, FALSE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1408,8 +1406,6 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
tile_data.height = tile->eheight;
tile_data.use_shm = (shm_ID == -1) ? FALSE : TRUE;
tile_ref2 (tile, FALSE);
if (tile_data.use_shm)
memcpy (shm_addr, tile->data, tile_size (tile));
else
@ -1422,7 +1418,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
if (!wire_read_msg (current_readfd, &msg))
{

View File

@ -1353,7 +1353,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_info->tile_num, 0);
tile = tile_manager_get (tm, tile_info->tile_num, 0, TRUE, TRUE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1361,14 +1361,12 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_ref2 (tile, TRUE);
if (tile_data.use_shm)
memcpy (tile->data, shm_addr, tile_size (tile));
else
memcpy (tile->data, tile_info->data, tile_size (tile));
tile_unref (tile, TRUE);
tile_release (tile, TRUE);
wire_destroy (&msg);
if (!gp_tile_ack_write (current_writefd))
@ -1392,7 +1390,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_req->tile_num, 0);
tile = tile_manager_get (tm, tile_req->tile_num, 0, TRUE, FALSE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1408,8 +1406,6 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
tile_data.height = tile->eheight;
tile_data.use_shm = (shm_ID == -1) ? FALSE : TRUE;
tile_ref2 (tile, FALSE);
if (tile_data.use_shm)
memcpy (shm_addr, tile->data, tile_size (tile));
else
@ -1422,7 +1418,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
if (!wire_read_msg (current_readfd, &msg))
{

View File

@ -1353,7 +1353,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_info->tile_num, 0);
tile = tile_manager_get (tm, tile_info->tile_num, 0, TRUE, TRUE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1361,14 +1361,12 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_ref2 (tile, TRUE);
if (tile_data.use_shm)
memcpy (tile->data, shm_addr, tile_size (tile));
else
memcpy (tile->data, tile_info->data, tile_size (tile));
tile_unref (tile, TRUE);
tile_release (tile, TRUE);
wire_destroy (&msg);
if (!gp_tile_ack_write (current_writefd))
@ -1392,7 +1390,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_req->tile_num, 0);
tile = tile_manager_get (tm, tile_req->tile_num, 0, TRUE, FALSE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1408,8 +1406,6 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
tile_data.height = tile->eheight;
tile_data.use_shm = (shm_ID == -1) ? FALSE : TRUE;
tile_ref2 (tile, FALSE);
if (tile_data.use_shm)
memcpy (shm_addr, tile->data, tile_size (tile));
else
@ -1422,7 +1418,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
if (!wire_read_msg (current_readfd, &msg))
{

View File

@ -1353,7 +1353,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_info->tile_num, 0);
tile = tile_manager_get (tm, tile_info->tile_num, 0, TRUE, TRUE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1361,14 +1361,12 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_ref2 (tile, TRUE);
if (tile_data.use_shm)
memcpy (tile->data, shm_addr, tile_size (tile));
else
memcpy (tile->data, tile_info->data, tile_size (tile));
tile_unref (tile, TRUE);
tile_release (tile, TRUE);
wire_destroy (&msg);
if (!gp_tile_ack_write (current_writefd))
@ -1392,7 +1390,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile = tile_manager_get (tm, tile_req->tile_num, 0);
tile = tile_manager_get (tm, tile_req->tile_num, 0, TRUE, FALSE);
if (!tile)
{
g_message ("plug-in requested invalid tile (killing)\n");
@ -1408,8 +1406,6 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
tile_data.height = tile->eheight;
tile_data.use_shm = (shm_ID == -1) ? FALSE : TRUE;
tile_ref2 (tile, FALSE);
if (tile_data.use_shm)
memcpy (shm_addr, tile->data, tile_size (tile));
else
@ -1422,7 +1418,7 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
return;
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
if (!wire_read_msg (current_readfd, &msg))
{

View File

@ -62,7 +62,7 @@ static void file_prefs_save_callback (GtkWidget *, GtkWidget *);
static void file_prefs_cancel_callback (GtkWidget *, GtkWidget *);
static gint file_prefs_delete_callback (GtkWidget *, GdkEvent *, GtkWidget *);
static void file_prefs_toggle_callback (GtkWidget *, gpointer);
static void file_prefs_text_callback (GtkWidget *, gpointer);
/* static void file_prefs_text_callback (GtkWidget *, gpointer); */
static void file_prefs_spinbutton_callback (GtkWidget *, gpointer);
static void file_prefs_preview_size_callback (GtkWidget *, gpointer);
static void file_prefs_mem_size_unit_callback (GtkWidget *, gpointer);
@ -527,6 +527,7 @@ file_prefs_mem_size_unit_callback (GtkWidget *widget,
}
}
/* commented out because it's not used
static void
file_prefs_text_callback (GtkWidget *widget,
gpointer data)
@ -536,6 +537,7 @@ file_prefs_text_callback (GtkWidget *widget,
val = data;
*val = atoi (gtk_entry_get_text (GTK_ENTRY (widget)));
}
*/
static void
file_prefs_spinbutton_callback (GtkWidget *widget,

View File

@ -1250,9 +1250,12 @@ procedural_db_hash_func (gconstpointer key)
/* The id system's remnants ... */
static gint next_image_id;
/*
static gint next_drawable_id;
static gint next_display_id;
*/
static GHashTable* image_hash;
static GHashTable* drawable_hash;

View File

@ -32,13 +32,8 @@
* list instead...
*/
/*
* Define MUCH_TILE_DEBUG in addition to TILE_DEBUG to get
* debugging for every single tile_ref2 and tile_unref (that's
* a lot).
#define MUCH_TILE_DEBUG heckyeah
*/
static void tile_destroy (Tile *tile);
void
@ -46,18 +41,17 @@ tile_init (Tile *tile,
int bpp)
{
tile->ref_count = 0;
tile->write_count = 0;
tile->share_count = 0;
tile->dirty = FALSE;
tile->valid = FALSE;
tile->data = NULL;
tile->real_tile_ptr = NULL;
tile->mirrored_by = NULL;
tile->ewidth = TILE_WIDTH;
tile->eheight = TILE_HEIGHT;
tile->bpp = bpp;
tile->tile_num = -1;
tile->swap_num = 1;
tile->swap_offset = -1;
tile->tm = NULL;
tile->tlink = NULL;
tile->next = tile->prev = NULL;
tile->listhead = NULL;
#ifdef USE_PTHREADS
@ -67,524 +61,81 @@ tile_init (Tile *tile,
#endif
}
int tile_ref_count = 0;
void
#if defined (TILE_DEBUG) && defined (__GNUC__)
_tile_ref (Tile *tile, char *func_name)
#else
tile_ref (Tile *tile)
#endif
tile_lock (Tile *tile)
{
/* While things get moved over to the new tile_ref2
* interface, tile_ref is a wrapper which just says
* 'yes, we'll be dirtying the tile'
*/
#if defined (TILE_DEBUG) && defined (__GNUC__)
printf("COW-Warning: function %s is using obsolete tile_ref interface\n",
func_name);
#endif
#if defined (TILE_DEBUG) && defined (__GNUC__)
_tile_ref2 (tile, TRUE, func_name);
#else
tile_ref2 (tile, TRUE);
#endif
}
gboolean
tile_is_mirroring (Tile *tile)
{
return (tile->real_tile_ptr != NULL);
}
gboolean
tile_is_mirrored (Tile *tile)
{
return (tile->mirrored_by != NULL);
}
gboolean
tile_is_real (Tile *tile)
{
return (tile->real_tile_ptr == NULL);
}
/* Follow the real_tile_ptr links back to the tile which provides
* the real source data for the given tile
*/
Tile *
tile_find_nonmirroring (Tile *tile)
{
if (! tile_is_mirroring (tile))
{
return tile;
}
else
{
return tile_find_nonmirroring (tile->real_tile_ptr);
}
}
/*
*/
Tile *
tile_find_finalmirroring (Tile *tile)
{
if (! tile_is_mirrored (tile))
{
return tile;
}
else
{
return tile_find_finalmirroring (tile->mirrored_by);
}
}
/* Take a mirroring-tile and turn it into a bona fide self-contained
* tile.
*/
void
tile_devirtualize (Tile *tile)
{
Tile *real_tile;
/* Sanity */
if (tile_is_real (tile))
g_error ("Tried to devirtualize a real tile");
#if defined (TILE_DEBUG)
if (tile->ref_count == 0)
g_warning ("Trying to devirtualize a mirroring-tile with no ref_count");
#endif
/* Go find the tile ('real_tile') which owns the real data
*/
real_tile = tile_find_nonmirroring (tile);
/* Sanity */
#if defined (TILE_DEBUG)
if (real_tile->ref_count == 0)
g_warning ("Trying to devirtualize a mirroring-tile whose real_tile has no ref_count");
#endif
if (!real_tile->valid)
g_warning ("Trying to devirtualize a mirroring-tile whose real_tile is !valid");
/* Copy the actual tile data from the real_tile to this tile
*/
tile->data = NULL;
tile_alloc (tile);
/* printf ("{ %dx%d : %d - %p[%p]->%p[%p] }", real_tile->ewidth, real_tile->eheight,
real_tile->bpp, real_tile, real_tile->data, tile, tile->data);
fflush(stdout);*/
memcpy (tile->data, real_tile->data, tile_size(real_tile));
/* 'tile' is now a real tile. */
tile->real_tile_ptr = NULL;
tile->valid = TRUE;
tile_cache_insert(tile);
#if defined (TILE_DEBUG)
g_print ("Tile at %p is now devirtualized.\n", tile);
#endif
}
/* Make this tile self-contained.
*
* The next tile in the linked-list of tiles which are mirroring 'tile'
* is promoted to a real physical tile and unlinked from 'tile'. This
* renders 'tile' safe for dirtying (or destruction).
*/
void
tile_isolate (Tile *tile)
{
Tile *temp_tileptr;
/* Sanity
*/
if (! (tile_is_mirrored (tile) || tile_is_mirroring (tile)))
{
g_warning ("Tried to isolate a tile which is neither a mirror source "
"nor destination");
return;
}
/* This tile is both linked to and linked from? */
if (tile_is_mirrored (tile) && tile_is_mirroring (tile))
{
temp_tileptr = tile->real_tile_ptr;
#if defined (TILE_DEBUG)
g_print ("tile %p: was middle of chain - relinking %p and %p\n",
tile,
temp_tileptr,
tile->mirrored_by);
#endif
tile->mirrored_by->real_tile_ptr = temp_tileptr;
temp_tileptr->mirrored_by = tile->mirrored_by;
tile_ref2 (temp_tileptr, FALSE);
tile_devirtualize (tile);
tile_unref (temp_tileptr, FALSE);
tile->mirrored_by = NULL;
return;
}
/* This tile is mirroring another, but is not mirrored itself? */
if (tile_is_mirroring (tile))
{
temp_tileptr = tile->real_tile_ptr;
#if defined (TILE_DEBUG)
g_print ("tile %p: was end of chain - cauterizing %p\n",
tile,
temp_tileptr);
#endif
/* We stop mirroring the tile which we previously were -
* so reset that tile's mirrored_by pointer.
*/
temp_tileptr->mirrored_by = NULL;
tile_ref2 (temp_tileptr, FALSE);
tile_devirtualize (tile);
tile_unref (temp_tileptr, FALSE);
return;
}
/* This tile is mirrored by another, but is not itself a mirror. */
if (tile_is_mirrored (tile))
{
#if defined (TILE_DEBUG)
g_print ("tile %p: was source of chain - devirtualizing %p\n",
tile,
tile->mirrored_by);
#endif
temp_tileptr = tile->mirrored_by;
tile_ref2 (temp_tileptr, FALSE);
tile_devirtualize (temp_tileptr);
tile_unref (temp_tileptr, FALSE);
/* The tile which was dependant on this one no longer is -
* so we can unref once.
*/
tile_unref (tile, FALSE);
tile->mirrored_by = NULL;
return;
}
}
/* Turns dest_tile into a mirroring-tile which mirrors the given
* src_tile using copy-on-write.
*/
void
tile_mirror (Tile *dest_tile, Tile *src_tile)
{
Tile *finalmirroring;
if (dest_tile == src_tile)
{
g_warning ("TRIED TO MIRROR TILE TO ITSELF");
return;
}
#if defined (TILE_DEBUG)
g_print ("mirroring ");
#endif
if (tile_is_real (dest_tile))
{
#if defined (TILE_DEBUG)
g_print ("TO REAL ");
#endif
tile_invalidate (dest_tile);
}
else
{
tile_invalidate (dest_tile);
}
/* dest_tile->ref_count = 0; */
dest_tile->dirty = FALSE;
dest_tile->valid = FALSE;
dest_tile->data = NULL;
dest_tile->ewidth = src_tile->ewidth;
dest_tile->eheight = src_tile->eheight;
dest_tile->bpp = src_tile->bpp;
dest_tile->tile_num = -1; /* ! */
/*
*/
finalmirroring = tile_find_finalmirroring (src_tile);
dest_tile->real_tile_ptr = finalmirroring;
finalmirroring->mirrored_by = dest_tile;
#if defined (TILE_DEBUG)
g_print ("%p -> %p\n", finalmirroring, dest_tile);
#endif
/* The following should be irrelevant in a mirroring tile - mirroring
* tiles by definition don't have real data of their own, so they can't
* be swapped. They don't have associated TileManagers either, since they
* rely on their mirrored source tile to contain validated data.
*/
dest_tile->swap_num = 1;
dest_tile->swap_offset = -1;
dest_tile->tm = NULL;
}
void
#if defined (TILE_DEBUG) && defined (__GNUC__)
_tile_ref2 (Tile *tile, int dirty, char *func_name)
#else
tile_ref2 (Tile *tile, int dirty)
#endif
{
#ifdef USE_PTHREADS
pthread_mutex_lock(&(tile->mutex));
#endif
#if defined (TILE_DEBUG) && defined (__GNUC__) && defined (MUCH_TILE_DEBUG)
g_print ("tile_ref2: %02d %c %p %s\n", tile->ref_count,
dirty?'d':' ',
tile,
func_name);
#endif
/*g_print ("tile_ref2: %02d %c %p\n", tile->ref_count,
dirty?'d':' ',
tile);*/
/* Increment the global reference count.
*/
tile_ref_count += 1;
/* Increment this tile's reference count.
*/
TILE_MUTEX_LOCK (tile);
tile->ref_count += 1;
#if defined (TILE_DEBUG)
if (tile_is_mirrored (tile) && dirty)
if (tile->ref_count++ == 1)
{
g_print ("Dirtying a mirrored tile: %p.\n", tile);
}
#endif
/*
if (dirty && tile->dirty)
{
g_print ("Not good: Dirtying a write-locked tile: %p.\n", tile);
} */
/* if this is a read-only attachment to a mirroring tile,
* then ref the chain, update the data pointer, and return.
*/
if ((!dirty) && (tile_is_mirroring (tile)))
{
/* ref each of the tiles in the chain, back to the
* 'real' tile which sits at the start.
*/
#if USE_PTHREADS
pthread_mutex_unlock(&(tile->mutex));
#endif
tile_ref2 (tile->real_tile_ptr, FALSE);
tile->data = tile->real_tile_ptr->data;
return;
}
/* dirty, or clean-and-real */
/* Real tile - first reference. */
if (!tile_is_mirroring (tile))
{
/* If this is the first reference to the tile then
* swap the tile data in from disk. Note: this will
* properly handle the case where the tile data isn't
* on disk.
*/
if (tile->ref_count == 1)
if (tile->listhead)
{
/* remove from cache, move to main store */
tile_cache_flush (tile);
}
if (tile->data == NULL)
{
/* There is no data, so the tile must be swapped out */
tile_swap_in (tile);
}
/* Insert the tile into the cache. If the tile is already
* in the cache this will have the affect of "touching"
* the tile.
*/
tile_cache_insert (tile);
}
#if USE_PTHREADS
pthread_mutex_unlock(&(tile->mutex));
#endif
/* Read/write attachment to a mirrored/ing tile - must be
* thoughtful.
*/
if (dirty)
{
/* Doing a read/write reference to a mirroring/ed tile -
* we'll have to turn the tile into a 'real' tile.
* Then return - we're done.
*/
{
if (tile_is_mirroring (tile) | tile_is_mirrored (tile))
{
#if defined (TILE_DEBUG)
g_print ("r/w to mir'd/ing - isolating: ");
#endif
tile_isolate (tile);
}
}
}
/* Mark the tile as dirty if it's being ref'd as dirtyable.
*/
tile->dirty |= dirty;
TILE_MUTEX_UNLOCK (tile);
/* Call 'tile_manager_validate' if the tile was invalid.
*/
if (!tile->valid)
tile_manager_validate ((TileManager*) tile->tm, tile);
{
/* an invalid tile should never be shared, so this should work */
tile_manager_validate ((TileManager*) tile->tlink->tm, tile);
}
}
void
#if defined (TILE_DEBUG) && defined (__GNUC__)
_tile_unref (Tile *tile, int dirty, char *func_name)
#else
tile_unref (Tile *tile, int dirty)
#endif
tile_release (Tile *tile, int dirty)
{
#ifdef USE_PTHREADS
pthread_mutex_lock(&(tile->mutex));
#endif
#if defined (TILE_DEBUG) && defined (__GNUC__) && defined (MUCH_TILE_DEBUG)
g_print ("tile_unref: %02d %c %p %s\n", tile->ref_count,
dirty?'d':' ',
tile, func_name);
#endif
/* g_print ("tile_unref: %02d %c %p\n", tile->ref_count,
dirty?'d':' ',
tile);*/
/* Decrement the global reference count.
*/
tile_ref_count -= 1;
TILE_MUTEX_LOCK(tile);
/* Decrement this tile's reference count.
*/
tile->ref_count -= 1;
/* Mark the tile dirty if indicated
*
* commented out - we now dirty on ref, not unref
/* Decrement write ref count if dirtying
*/
/*
tile->dirty |= dirty;
*/
if (dirty)
tile->write_count -= 1;
#if defined (TILE_DEBUG)
if (tile_is_mirroring (tile))
{
/* Mirroring tiles aren't allowed to be submitted as dirty -
* they should have been isolated at ref time.
*/
if (dirty)
g_warning ("Mirroring tile unref'd as dirty.");
}
if (tile_is_mirrored (tile))
{
/* Mirrored tiles aren't allowed to be submitted as dirty -
* they should have been isolated at ref time.
*/
fflush(stdout);
if (dirty)
g_warning ("Mirrored tile unref'd as dirty.");
}
#endif
/* When we unref a mirroring tile, also unref the tile which
* was being mirrored.
*/
if (tile_is_mirroring (tile))
{
/* Mirroring tiles aren't allowed to be submitted as dirty -
* they should have been ref'd as dirty in the first place so we
* could turn them into 'real' tiles.
*/
if (dirty)
{
g_warning ("Bleh, tried to unref a mirroring tile as dirty.");
}
/* Go find the mirrored tile and unref that too. */
#if USE_PTHREADS
pthread_mutex_unlock(&(tile->mutex));
#endif
tile_unref (tile->real_tile_ptr, FALSE);
return;
}
/* If this was the last reference to the tile, then
* swap it out to disk.
*/
if (tile->ref_count == 0)
{
/* Only need to swap out in two cases:
* 1) The tile is dirty }
* 2) The tile has never been swapped } and is not mirroring
*/
if ((tile->dirty || tile->swap_offset == -1)
&& !tile_is_mirroring (tile))
tile_swap_out (tile);
/* Otherwise, just throw out the data--the same stuff is in swap
*/
else
if (tile->share_count == 0)
{
if (! tile_is_mirroring (tile))
g_free (tile->data);
tile->data = NULL;
/* tile is dead */
tile_destroy (tile);
return; /* skip terminal unlock */
}
else
{
/* last reference was just released, so move the tile to the
tile cache */
tile_cache_insert (tile);
}
}
#if USE_PTHREADS
pthread_mutex_unlock(&(tile->mutex));
#endif
TILE_MUTEX_UNLOCK (tile);
}
void
@ -599,6 +150,29 @@ tile_alloc (Tile *tile)
out:
}
static void
tile_destroy (Tile *tile)
{
if (tile->data)
{
g_free (tile->data);
tile->data = NULL;
}
if (tile->swap_offset != -1)
{
/* If the tile is on disk, then delete its
* presence there.
*/
tile_swap_delete (tile);
}
if (tile->listhead)
tile_cache_flush (tile);
TILE_MUTEX_UNLOCK (tile);
g_free (tile);
}
int
tile_size (Tile *tile)
{
@ -610,167 +184,62 @@ tile_size (Tile *tile)
return size;
}
void
tile_invalidate (Tile *tile)
tile_attach (Tile *tile, void *tm, int tile_num)
{
#ifdef USE_PTHREADS
pthread_mutex_lock(&(tile->mutex));
#endif
#if defined (TILE_DEBUG)
if (tile->ref_count > 1)
TileLink *tmp;
if (tile->share_count > 0 && !tile->valid)
{
g_print (" (inv%p:ref%d) ", tile, tile->ref_count);
}
else
{
g_print (" (inv%p) ", tile);
/* trying to share invalid tiles is problematic, not to mention silly */
tile_manager_validate ((TileManager*) tile->tlink->tm, tile);
}
tile->share_count++;
#ifdef TILE_DEBUG
g_print("tile_attach: %p -> (%p,%d) *%d\n", tile, tm, tile_num, tile->share_count);
#endif
/* If this tile is mirrored/ing, then maybe isolate it before we
* invalidate it, so that we don't accidentally delete a tile
* whose data is still in use by a mirror.
*/
if (tile_is_mirrored (tile))
{
if (tile_is_mirroring (tile))
{
/* tile is in the middle of a chain. just relink its
* successor and predecessor. that's all we need to do for
* a cleanup.
*/
#if defined (TILE_DEBUG)
g_print ("tile %p: was middle of chain - relinking %p and %p, "
"no isolation\n",
tile,
tile->real_tile_ptr,
tile->mirrored_by);
#endif
tile->mirrored_by->real_tile_ptr = tile->real_tile_ptr;
tile->real_tile_ptr->mirrored_by = tile->mirrored_by;
}
else
{
/* tile is real, and mirrored. Copy its vital statistics to
* its successor in the tile chain, so it can be safely deleted.
*/
#if defined (TILE_DEBUG)
g_print ("tile %p: was source of chain - successor %p swallows soul"
", no isolation\n",
tile,
tile->mirrored_by);
/* link this tile into the tile's tilelink chain */
tmp = g_new (TileLink, 1);
tmp->tm = tm;
tmp->tile_num = tile_num;
tmp->next = tile->tlink;
tile->tlink = tmp;
}
void
tile_detach (Tile *tile, void *tm, int tile_num)
{
TileLink **link;
TileLink *tmp;
#ifdef TILE_DEBUG
g_print("tile_detach: %p ~> (%p,%d) *%d\n", tile, tm, tile_num, tile->share_count);
#endif
/* remove 'tile' from cache - but keep the ref_count up
* so that the tile_unref() which tile_cache_flush() calls
* won't invalidate the tile (we'll be doing that ourselves).
*/
tile->ref_count++;
tile_cache_flush (tile);
tile->ref_count--;
for (link = &tile->tlink; *link; link = &(*link)->next)
if ((*link)->tm == tm && (*link)->tile_num == tile_num)
break;
/* imbue our successor with our data pointer, validity,
* tile manager, swap_num, swap_offset, and dirty
* flag
*/
tile->mirrored_by->data = tile->data;
tile->data = NULL;
tile->mirrored_by->dirty = tile->dirty;
tile->dirty = FALSE;
tile->mirrored_by->valid = tile->valid;
tile->valid = FALSE;
tile->mirrored_by->swap_num = tile->swap_num;
tile->swap_num = 0;
tile->mirrored_by->swap_offset = tile->swap_offset;
tile->swap_num = -1;
tile->mirrored_by->tm = tile->tm;
tile->tm = NULL;
/* sever links with our successor in both directions.
* our successor is now the new chain source.
*
* also register this newly-born 'real' tile with the tile cache.
*/
tile->mirrored_by->real_tile_ptr = NULL;
tile_cache_insert (tile->mirrored_by);
tile->mirrored_by = NULL;
/* This tile is as clean and invalid as it's going to get.
* Return.
*/
return;
}
}
else /* not mirrored, maybe mirroring */
if (*link == NULL)
{
/* for a non-real tile at the end of a chain, the only cleanup
* we have to do for its safe destruction is cauterize the
* flapping mirrored_by pointer of its predecessor on the chain.
*/
if (tile_is_mirroring (tile))
{
#if defined (TILE_DEBUG)
g_print ("tile %p: was end of chain - cauterizing %p, no "
"isolation\n",
tile,
tile->real_tile_ptr);
#endif
tile->real_tile_ptr->mirrored_by = NULL;
}
}
/* If this isn't a 'real' tile then it doesn't need invalidating,
* since it doesn't have any unique data associated with it.
*/
if (!tile_is_real (tile))
{
if (tile->valid)
{
g_warning ("tried to invalidate a mirroring tile which was valid.");
tile->valid = FALSE;
}
g_warning ("Tried to detach a nonattached tile");
return;
}
tmp = *link;
*link = tmp->next;
g_free (tmp);
/* Only 'real' tiles permitted past this point.
*/
/* Invalidate the tile. (Must be valid first).
*/
if (tile->valid)
tile->share_count--;
if (tile->share_count == 0 && tile->ref_count == 0)
{
tile->valid = FALSE;
if (tile->data)
{
/* If the tile is in memory then trick the
* tile cache routines. We temporarily increment
* the reference count so that flushing a tile does
* not cause it to go out to disk.
*/
tile->ref_count += 1;
tile_cache_flush (tile);
tile->ref_count -= 1;
/* We then free the tile data.
*/
g_free (tile->data);
tile->data = NULL;
}
if (tile->swap_offset != -1)
{
/* If the tile is on disk, then delete its
* presence there.
*/
tile_swap_delete (tile);
}
tile_destroy (tile);
return;
}
#if USE_PTHREADS
pthread_mutex_unlock(&(tile->mutex));
#endif
TILE_MUTEX_UNLOCK (tile);
}

View File

@ -24,55 +24,18 @@ typedef struct _Tile Tile;
void tile_init (Tile *tile,
int bpp);
/*
* c-o-w
*/
void tile_mirror (Tile *dest_tile, Tile *src_tile);
/* Referencing a tile causes the reference count to be incremented.
* If the reference count was previously 0 the tile will will be
* swapped into memory from disk.
*
* tile_ref2 is a new tile-referencing interface through which you
* should register your intent to dirty the tile. This will facilitate
* copy-on-write tile semantics.
* tile_lock locks a tile into memory. This does what tile_ref used
* to do. It is the responsibility of the tile manager to take care
* of the copy-on-write semantics. Locks stack; a tile remains locked
* in memory as long as it's been locked more times than it has been
* released. tile_release needs to know whether the release was for
* write access. (This is a hack, and should be handled better.)
*/
#if defined (TILE_DEBUG) && defined (__GNUC__)
#define tile_ref(t) _tile_ref (t, __PRETTY_FUNCTION__)
void _tile_ref (Tile *tile, char *func_name);
#define tile_ref2(t,d) _tile_ref2 (t, d, __PRETTY_FUNCTION__)
void _tile_ref2 (Tile *tile, int dirty, char *func_name);
#else
void tile_ref (Tile *tile);
void tile_ref2 (Tile *tile, int dirty);
#endif
/* Unreferencing a tile causes the reference count to be decremented.
* When the reference count reaches 0 the tile data will be swapped
* out to disk. Note that the tile may be in the tile cache which
* also references the tile causing the reference count not to
* fall below 1 until the tile is removed from the cache.
* The dirty flag indicates whether the tile data has been dirtied
* while referenced.
*/
#if defined (TILE_DEBUG) && defined (__GNUC__)
#define tile_unref(t,d) _tile_unref (t, d, __PRETTY_FUNCTION__)
void _tile_unref (Tile *tile, int dirty, char *func_name);
#else
void tile_unref (Tile *tile, int dirty);
#endif
void tile_lock (Tile *);
void tile_release (Tile *, int);
/* Allocate the data for the tile.
*/
@ -82,15 +45,15 @@ void tile_alloc (Tile *tile);
*/
int tile_size (Tile *tile);
/* Invalidates a tile. This involves setting its invalid bit and
* a) if the tile is in memory deleting the tile data or b) if the
* tile is in the swap file, deleting the space it occupies. This
* will cause the tile data to need to be recalculated.
* This should probably only be used on sublevel tiles. Invalidating
* a toplevel tile would mean that it needs to be recalculated. But
* what do you recalculate a toplevel tile from?
/* tile_attach attaches a tile to a tile manager: this function
* increments the tile's share count and inserts a tilelink into the
* tile's link list. tile_detach reverses the process.
* If a tile's share count is zero after a tile_detach, the tile is
* discarded.
*/
void tile_invalidate (Tile *tile);
void tile_attach (Tile *tile, void *tm, int tile_num);
void tile_detach (Tile *tile, void *tm, int tile_num);
#endif /* __TILE_H__ */

View File

@ -46,8 +46,12 @@ static pthread_t preswap_thread;
static pthread_mutex_t dirty_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t dirty_signal = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t tile_mutex = PTHREAD_MUTEX_INITIALIZER;
#define CACHE_LOCK pthread_mutex_lock(&tile_mutex)
#define CACHE_UNLOCK pthread_mutex_unlock(&tile_mutex)
#else
static gint idle_swapper = 0;
#define CACHE_LOCK /*nothing*/
#define CACHE_UNLOCK /*nothing*/
#endif
@ -60,9 +64,7 @@ tile_cache_insert (Tile *tile)
if (initialize)
tile_cache_init ();
#if USE_PTHREADS
pthread_mutex_lock(&tile_mutex);
#endif
CACHE_LOCK;
if (tile->data == NULL) goto out;
/* First check and see if the tile is already
@ -100,6 +102,7 @@ tile_cache_insert (Tile *tile)
* if there is room in the cache. If not then we'll have
* to make room first. Note: it might be the case that the
* cache is smaller than the size of a tile in which case
* it won't be possible to put it in the cache.
*/
while ((cur_cache_size + max_tile_size) > max_cache_size)
@ -111,24 +114,6 @@ tile_cache_insert (Tile *tile)
* is referencing.
*/
cur_cache_size += tile_size (tile);
/* Reference the tile so that it won't be swapped out
* to disk. Swap the tile in if necessary.
* "tile_ref" cannot be used here since it calls this
* function.
*/
tile->ref_count += 1;
{
extern int tile_ref_count;
tile_ref_count += 1;
}
if (tile->ref_count == 1)
{
tile_swap_in (tile);
/* the tile must be clean */
tile->dirty = FALSE;
}
}
/* Put the tile at the end of the proper list */
@ -151,9 +136,7 @@ tile_cache_insert (Tile *tile)
#endif
}
out:
#ifdef USE_PTHREADS
pthread_mutex_unlock(&tile_mutex);
#endif
CACHE_UNLOCK;
}
@ -163,15 +146,9 @@ tile_cache_flush (Tile *tile)
if (initialize)
tile_cache_init ();
#ifdef USE_PTHREADS
pthread_mutex_lock(&tile_mutex);
#endif
CACHE_LOCK;
tile_cache_flush_internal (tile);
#ifdef USE_PTHREADS
pthread_mutex_unlock(&tile_mutex);
#endif
CACHE_UNLOCK;
}
static void
@ -203,34 +180,6 @@ tile_cache_flush_internal (Tile *tile)
list->first = tile->next;
tile->listhead = NULL;
/* Unreference the tile.
*/
{
extern int tile_ref_count;
tile_ref_count -= 1;
}
/* Decrement the reference count.
*/
tile->ref_count -= 1;
/* If this was the last reference to the tile, then
* swap it out to disk.
*/
if (tile->ref_count == 0)
{
/* Only need to swap out in two cases:
* 1) The tile is dirty
* 2) The tile has never been swapped
*/
if (tile->dirty || tile->swap_offset == -1)
tile_swap_out (tile);
/* Otherwise, just throw out the data--the same stuff is in swap
*/
g_free (tile->data);
tile->data = NULL;
}
}
}
@ -241,17 +190,12 @@ tile_cache_set_size (unsigned long cache_size)
tile_cache_init ();
max_cache_size = cache_size;
#if USE_PTHREADS
pthread_mutex_lock(&tile_mutex);
#endif
CACHE_LOCK;
while (cache_size >= max_cache_size)
{
if (!tile_cache_zorch_next ()) break;
}
#if USE_PTHREADS
pthread_mutex_unlock(&tile_mutex);
#endif
CACHE_UNLOCK;
}
@ -286,15 +230,11 @@ tile_cache_zorch_next ()
else if (dirty_list.first) tile = dirty_list.first;
else return FALSE;
#ifdef USE_PTHREADS
pthread_mutex_unlock(&tile_mutex);
pthread_mutex_lock(&(tile->mutex));
pthread_mutex_lock(&tile_mutex);
#endif
CACHE_UNLOCK;
TILE_MUTEX_LOCK (tile);
CACHE_LOCK;
tile_cache_flush_internal (tile);
#ifdef USE_PTHREADS
pthread_mutex_unlock(&(tile->mutex));
#endif
TILE_MUTEX_UNLOCK (tile);
return TRUE;
}
@ -315,10 +255,10 @@ tile_idle_thread (void *data)
pthread_cond_wait(&dirty_signal,&dirty_mutex);
pthread_mutex_unlock(&dirty_mutex);
}
if ((tile = dirty_list.first) &&
(pthread_mutex_lock(&(tile->mutex)) == 0))
if ((tile = dirty_list.first))
{
pthread_mutex_lock(&tile_mutex);
TILE_MUTEX_LOCK (tile);
CACHE_LOCK;
list = tile->listhead;
@ -342,9 +282,10 @@ tile_idle_thread (void *data)
else clean_list.first = tile;
clean_list.last = tile;
pthread_mutex_unlock(&tile_mutex);
CACHE_UNLOCK;
tile_swap_out(tile);
pthread_mutex_unlock(&(tile->mutex));
TILE_MUTEX_UNLOCK (tile);
}
}
}
@ -377,3 +318,4 @@ tile_idle_preswap (gpointer data)
return TRUE;
}
#endif

View File

@ -23,7 +23,9 @@
#include "tile_manager_pvt.h"
#include "tile_pvt.h" /* ick. */
static void tile_manager_destroy_level (TileLevel *level);
static void tile_manager_destroy_level (TileManager *tm,
TileLevel *level);
static void tile_invalidate (Tile **tile_ptr, TileManager *tm, int tile_num);
TileManager*
@ -71,7 +73,7 @@ tile_manager_destroy (TileManager *tm)
int i;
for (i = 0; i < tm->nlevels; i++)
tile_manager_destroy_level (&tm->levels[i]);
tile_manager_destroy_level (tm, &tm->levels[i]);
g_free (tm->levels);
g_free (tm);
@ -138,7 +140,7 @@ tile_manager_set_nlevels (TileManager *tm,
levels[i] = tm->levels[i];
for (; i < tm->nlevels; i++)
tile_manager_destroy_level (&tm->levels[i]);
tile_manager_destroy_level (tm, &tm->levels[i]);
}
g_free (tm->levels);
@ -158,7 +160,9 @@ Tile*
tile_manager_get_tile (TileManager *tm,
int xpixel,
int ypixel,
int level)
int level,
int wantread,
int wantwrite)
{
TileLevel *tile_level;
int tile_row;
@ -177,16 +181,19 @@ tile_manager_get_tile (TileManager *tm,
tile_col = xpixel / TILE_WIDTH;
tile_num = tile_row * tile_level->ntile_cols + tile_col;
return tile_manager_get (tm, tile_num, level);
return tile_manager_get (tm, tile_num, level, wantread, wantwrite);
}
Tile*
tile_manager_get (TileManager *tm,
int tile_num,
int level)
int level,
int wantread,
int wantwrite)
{
TileLevel *tile_level;
Tile *tiles;
Tile **tiles;
Tile **tile_ptr;
int ntiles;
int nrows, ncols;
int right_tile;
@ -204,7 +211,7 @@ tile_manager_get (TileManager *tm,
if (!tile_level->tiles)
{
tile_level->tiles = g_new (Tile, ntiles);
tile_level->tiles = g_new (Tile*, ntiles);
tiles = tile_level->tiles;
nrows = tile_level->ntile_rows;
@ -217,20 +224,53 @@ tile_manager_get (TileManager *tm,
{
for (j = 0; j < ncols; j++, k++)
{
tile_init (&tiles[k], tile_level->bpp);
tiles[k].tile_num = k;
tiles[k].tm = tm;
tiles[k] = g_new (Tile, 1);
tile_init (tiles[k], tile_level->bpp);
tile_attach (tiles[k], tm, k);
if (j == (ncols - 1))
tiles[k].ewidth = right_tile;
tiles[k]->ewidth = right_tile;
if (i == (nrows - 1))
tiles[k].eheight = bottom_tile;
tiles[k]->eheight = bottom_tile;
}
}
}
return &tile_level->tiles[tile_num];
tile_ptr = &tile_level->tiles[tile_num];
if (wantread)
{
TILE_MUTEX_LOCK (*tile_ptr);
if (wantwrite)
{
if ((*tile_ptr)->share_count > 1)
{
/* Copy-on-write required */
Tile *newtile = g_new (Tile, 1);
tile_init (newtile, (*tile_ptr)->bpp);
newtile->ewidth = (*tile_ptr)->ewidth;
newtile->eheight = (*tile_ptr)->eheight;
newtile->valid = (*tile_ptr)->valid;
if ((*tile_ptr)->data != NULL)
{
newtile->data = g_new (guchar, tile_size (newtile));
memcpy (newtile->data, (*tile_ptr)->data, tile_size (newtile));
}
tile_detach (*tile_ptr, tm, tile_num);
TILE_MUTEX_LOCK (newtile);
tile_attach (newtile, tm, tile_num);
*tile_ptr = newtile;
}
(*tile_ptr)->write_count++;
(*tile_ptr)->dirty = 1;
}
TILE_MUTEX_UNLOCK (*tile_ptr);
tile_lock (*tile_ptr);
}
return *tile_ptr;
}
void
@ -253,8 +293,8 @@ tile_manager_invalidate_tiles (TileManager *tm,
int num;
int i;
col = toplevel_tile->tile_num % tm->levels[0].ntile_cols;
row = toplevel_tile->tile_num / tm->levels[0].ntile_cols;
col = toplevel_tile->tlink->tile_num % tm->levels[0].ntile_cols;
row = toplevel_tile->tlink->tile_num / tm->levels[0].ntile_cols;
x = (col * TILE_WIDTH + toplevel_tile->ewidth / 2.0) / (double) tm->levels[0].width;
y = (row * TILE_HEIGHT + toplevel_tile->eheight / 2.0) / (double) tm->levels[0].height;
@ -267,7 +307,7 @@ tile_manager_invalidate_tiles (TileManager *tm,
col = x * level->width / TILE_WIDTH;
row = y * level->height / TILE_HEIGHT;
num = row * level->ntile_cols + col;
tile_invalidate (&level->tiles[num]);
tile_invalidate (&level->tiles[num], tm, num);
}
}
}
@ -284,7 +324,7 @@ tile_manager_invalidate_sublevels (TileManager *tm)
{
ntiles = tm->levels[i].ntile_rows * tm->levels[i].ntile_cols;
for (j = 0; j < ntiles; j++)
tile_invalidate (&tm->levels[i].tiles[j]);
tile_invalidate (&tm->levels[i].tiles[j], tm, j);
}
}
}
@ -309,8 +349,8 @@ tile_manager_update_tile (TileManager *tm,
if ((level < 1) || (level >= tm->nlevels))
return;
col = toplevel_tile->tile_num % tm->levels[0].ntile_cols;
row = toplevel_tile->tile_num / tm->levels[0].ntile_cols;
col = toplevel_tile->tlink->tile_num % tm->levels[0].ntile_cols;
row = toplevel_tile->tlink->tile_num / tm->levels[0].ntile_cols;
x = (col * TILE_WIDTH + toplevel_tile->ewidth / 2.0) / (double) tm->levels[0].width;
y = (row * TILE_HEIGHT + toplevel_tile->eheight / 2.0) / (double) tm->levels[0].height;
@ -338,10 +378,9 @@ tile_manager_update_tile (TileManager *tm,
row = (y * tile_level->height) / TILE_HEIGHT;
num = row * tile_level->ntile_cols + col;
tile = tile_manager_get (tm, num, level);
tile = tile_manager_get (tm, num, level, TRUE, TRUE);
tile_ref2 (tile, TRUE);
tile_ref2 (toplevel_tile, FALSE);
tile_lock (toplevel_tile);
tilew += tilex;
tileh += tiley;
@ -366,13 +405,13 @@ tile_manager_update_tile (TileManager *tm,
}
}
tile_unref (tile, TRUE);
tile_unref (toplevel_tile, FALSE);
tile_release (tile, TRUE);
tile_release (toplevel_tile, FALSE);
}
static void
tile_manager_destroy_level (TileLevel *level)
tile_manager_destroy_level (TileManager *tm, TileLevel *level)
{
int ntiles;
int i;
@ -382,8 +421,146 @@ tile_manager_destroy_level (TileLevel *level)
ntiles = level->ntile_rows * level->ntile_cols;
for (i = 0; i < ntiles; i++)
tile_invalidate (&level->tiles[i]);
{
TILE_MUTEX_LOCK (level->tiles[i]);
tile_detach (level->tiles[i], tm, i);
}
g_free (level->tiles);
}
}
static void
tile_invalidate (Tile **tile_ptr, TileManager *tm, int tile_num)
{
Tile *tile = *tile_ptr;
TILE_MUTEX_LOCK (tile);
if (!tile->valid)
goto leave;
if (tile->share_count > 1)
{
/* This tile is shared. Replace it with a new, invalid tile. */
Tile *newtile = g_new (Tile, 1);
tile_init (newtile, tile->bpp);
newtile->ewidth = tile->ewidth;
newtile->eheight = tile->eheight;
tile_detach (tile, tm, tile_num);
TILE_MUTEX_LOCK (newtile);
tile_attach (newtile, tm, tile_num);
tile = *tile_ptr = newtile;
}
if (tile->listhead)
tile_cache_flush (tile);
tile->valid = FALSE;
if (tile->data)
{
g_free (tile->data);
tile->data = NULL;
}
if (tile->swap_offset != -1)
{
/* If the tile is on disk, then delete its
* presence there.
*/
tile_swap_delete (tile);
}
leave:
TILE_MUTEX_UNLOCK (tile);
}
void
tile_manager_map_tile (TileManager *tm,
int xpixel,
int ypixel,
int level,
Tile *srctile)
{
TileLevel *tile_level;
int tile_row;
int tile_col;
int tile_num;
if ((level < 0) || (level >= tm->nlevels))
return;
tile_level = &tm->levels[level];
if ((xpixel < 0) || (xpixel >= tile_level->width) ||
(ypixel < 0) || (ypixel >= tile_level->height))
return;
tile_row = ypixel / TILE_HEIGHT;
tile_col = xpixel / TILE_WIDTH;
tile_num = tile_row * tile_level->ntile_cols + tile_col;
tile_manager_map (tm, tile_num, level, srctile);
}
void
tile_manager_map (TileManager *tm,
int tile_num,
int level,
Tile *srctile)
{
TileLevel *tile_level;
Tile **tiles;
Tile **tile_ptr;
int ntiles;
int nrows, ncols;
int right_tile;
int bottom_tile;
int i, j, k;
if ((level < 0) || (level >= tm->nlevels))
return;
tile_level = &tm->levels[level];
ntiles = tile_level->ntile_rows * tile_level->ntile_cols;
if ((tile_num < 0) || (tile_num >= ntiles))
return;
if (!tile_level->tiles)
{
tile_level->tiles = g_new (Tile*, ntiles);
tiles = tile_level->tiles;
nrows = tile_level->ntile_rows;
ncols = tile_level->ntile_cols;
right_tile = tile_level->width - ((ncols - 1) * TILE_WIDTH);
bottom_tile = tile_level->height - ((nrows - 1) * TILE_HEIGHT);
for (i = 0, k = 0; i < nrows; i++)
{
for (j = 0; j < ncols; j++, k++)
{
tiles[k] = g_new (Tile, 1);
tile_init (tiles[k], tile_level->bpp);
tile_attach (tiles[k], tm, k);
if (j == (ncols - 1))
tiles[k]->ewidth = right_tile;
if (i == (nrows - 1))
tiles[k]->eheight = bottom_tile;
}
}
}
tile_ptr = &tile_level->tiles[tile_num];
TILE_MUTEX_LOCK (*tile_ptr);
tile_detach (*tile_ptr, tm, tile_num);
TILE_MUTEX_LOCK (srctile);
tile_attach (srctile, tm, tile_num);
*tile_ptr = srctile;
TILE_MUTEX_UNLOCK (srctile);
}

View File

@ -81,13 +81,28 @@ void tile_manager_set_validate_proc (TileManager *tm,
Tile* tile_manager_get_tile (TileManager *tm,
int xpixel,
int ypixel,
int level);
int level,
int wantread,
int wantwrite);
/* Get a specified tile from a tile manager.
*/
Tile* tile_manager_get (TileManager *tm,
int tile_num,
int level);
int level,
int wantread,
int wantwrite);
void tile_manager_map_tile (TileManager *tm,
int xpixel,
int ypixel,
int level,
Tile *srctile);
void tile_manager_map (TileManager *tm,
int time_num,
int level,
Tile *srctile);
/* Validate a tiles memory.
*/

View File

@ -29,7 +29,7 @@ struct _TileLevel
int ntile_rows; /* the number of tiles in each row */
int ntile_cols; /* the number of tiles in each columns */
Tile *tiles; /* the tiles for this level */
Tile **tiles; /* the tiles for this level */
};
struct _TileManager

View File

@ -11,6 +11,19 @@
#include "config.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.
*/
};
struct _Tile
{
short ref_count; /* reference count. when the reference count is
@ -19,6 +32,10 @@ struct _Tile
* is 0 then the "data" for this tile must be
* NULL.
*/
short write_count; /* write count: number of references that are
for write access */
short share_count; /* share count: number of tile managers that
hold this tile */
guint dirty : 1; /* is the tile dirty? has it been modified? */
guint valid : 1; /* is the tile valid? */
@ -26,20 +43,6 @@ struct _Tile
* case the tile data is on disk.
*/
Tile *real_tile_ptr;/* if this tile's 'data' pointer is just a copy-on-write
* mirror of another's, this is that source tile.
* (real_tile itself can actually be a virtual tile
* too.) This is NULL if this tile is not a virtual
* tile.
*/
Tile *mirrored_by; /* If another tile is mirroring this one, this is
* a pointer to that tile, otherwise this is NULL.
* Note that only one tile may be _directly_ mirroring
* another given tile. This ensures that the graph
* of mirrorings is no more complex than a linked
* list.
*/
int ewidth; /* the effective width of the tile */
int eheight; /* the effective height of the tile */
/* a tile's effective width and height may be smaller
@ -47,19 +50,14 @@ struct _Tile
* this is to handle edge tiles of a drawable.
*/
int bpp; /* the bytes per pixel (1, 2, 3 or 4) */
int tile_num; /* the number of this tile within the drawable */
int swap_num; /* the index into the file table of the file to be used
* for swapping. swap_num 1 is always the global swap file.
*/
off_t swap_offset; /* the offset within the swap file of the tile data.
* if the tile data is in memory this will be set to -1.
*/
TileLink *tlink;
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.
*/
Tile *next;
Tile *prev; /* List pointers for the tile cache lists */
void *listhead; /* Pointer to the head of the list this tile is on */
@ -68,4 +66,13 @@ struct _Tile
#endif
};
#ifdef USE_PTHREADS
#define TILE_MUTEX_LOCK(tile) pthread_mutex_lock(&((tile)->mutex))
#define TILE_MUTEX_UNLOCK(tile) pthread_mutex_unlock(&((tile)->mutex))
#else
#define TILE_MUTEX_LOCK(tile) /* nothing */
#define TILE_MUTEX_UNLOCK(tile) /* nothing */
#endif
#endif /* __TILE_PVT_H__ */

View File

@ -1014,10 +1014,9 @@ gradient_calc_shapeburst_angular_factor (double x,
ix = (int) BOUNDS (x, 0, distR.w);
iy = (int) BOUNDS (y, 0, distR.h);
tile = tile_manager_get_tile (distR.tiles, ix, iy, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (distR.tiles, ix, iy, 0, TRUE, FALSE);
value = 1.0 - *(((float *) tile->data) + ((iy % TILE_HEIGHT) * tile->ewidth + (ix % TILE_WIDTH)));
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
return value;
}
@ -1033,11 +1032,10 @@ gradient_calc_shapeburst_spherical_factor (double x,
ix = (int) BOUNDS (x, 0, distR.w);
iy = (int) BOUNDS (y, 0, distR.h);
tile = tile_manager_get_tile (distR.tiles, ix, iy, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (distR.tiles, ix, iy, 0, TRUE, FALSE);
value = *(((float *) tile->data) + ((iy % TILE_HEIGHT) * tile->ewidth + (ix % TILE_WIDTH)));
value = 1.0 - sin (0.5 * M_PI * value);
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
return value;
}
@ -1053,11 +1051,10 @@ gradient_calc_shapeburst_dimpled_factor (double x,
ix = (int) BOUNDS (x, 0, distR.w);
iy = (int) BOUNDS (y, 0, distR.h);
tile = tile_manager_get_tile (distR.tiles, ix, iy, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (distR.tiles, ix, iy, 0, TRUE, FALSE);
value = *(((float *) tile->data) + ((iy % TILE_HEIGHT) * tile->ewidth + (ix % TILE_WIDTH)));
value = cos (0.5 * M_PI * value);
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
return value;
}

View File

@ -360,21 +360,19 @@ by_color_select_button_release (Tool *tool,
{
if (x < 0 || y < 0 || x >= gdisp->gimage->width || y >= gdisp->gimage->height)
return;
tile = tile_manager_get_tile (gimage_composite (gdisp->gimage), x, y, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (gimage_composite (gdisp->gimage), x, y, 0, TRUE, FALSE);
data = tile->data + tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
gimage_get_color (gdisp->gimage, gimage_composite_type(gdisp->gimage), col, data);
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
}
else
{
if (x < 0 || y < 0 || x >= drawable_width (drawable) || y >= drawable_height (drawable))
return;
tile = tile_manager_get_tile (drawable_data (drawable), x, y, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (drawable_data (drawable), x, y, 0, TRUE, FALSE);
data = tile->data + tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
gimage_get_color (gdisp->gimage, drawable_type(drawable), col, data);
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
}
/* select the area */
@ -933,8 +931,7 @@ by_color_select_preview_button_press (ByColorDialog *bcd,
y = bcd->gimage->height * bevent->y / bcd->preview->requisition.height;
if (x < 0 || y < 0 || x >= bcd->gimage->width || y >= bcd->gimage->height)
return;
tile = tile_manager_get_tile (gimage_composite (bcd->gimage), x, y, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (gimage_composite (bcd->gimage), x, y, 0, TRUE, FALSE);
col = tile->data + tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
}
else
@ -946,8 +943,7 @@ by_color_select_preview_button_press (ByColorDialog *bcd,
y = drawable_height (drawable) * bevent->y / bcd->preview->requisition.height - offy;
if (x < 0 || y < 0 || x >= drawable_width (drawable) || y >= drawable_height (drawable))
return;
tile = tile_manager_get_tile (drawable_data (drawable), x, y, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (drawable_data (drawable), x, y, 0, TRUE, FALSE);
col = tile->data + tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
}
@ -959,7 +955,7 @@ by_color_select_preview_button_press (ByColorDialog *bcd,
by_color_options->feather_radius,
by_color_options->sample_merged);
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
/* show selection on all views */
gdisplays_flush ();

View File

@ -327,8 +327,7 @@ get_color (GImage *gimage,
if (x >= 0 && y >= 0 && x < width && y < height)
{
tile = tile_manager_get_tile (tiles, x, y, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (tiles, x, y, 0, TRUE, FALSE);
src = tile->data + tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
}
@ -369,7 +368,7 @@ get_color (GImage *gimage,
break;
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
palette_set_active_color (col_value [RED_PIX], col_value [GREEN_PIX],
col_value [BLUE_PIX], final);

View File

@ -124,14 +124,12 @@ ref_tiles (TileManager *src, TileManager *mask, Tile **s_tile, Tile **m_tile,
int x, int y, unsigned char **s, unsigned char **m)
{
if (*s_tile != NULL)
tile_unref (*s_tile, FALSE);
tile_release (*s_tile, FALSE);
if (*m_tile != NULL)
tile_unref (*m_tile, TRUE);
tile_release (*m_tile, TRUE);
*s_tile = tile_manager_get_tile (src, x, y, 0);
*m_tile = tile_manager_get_tile (mask, x, y, 0);
tile_ref2 (*s_tile, FALSE);
tile_ref2 (*m_tile, TRUE);
*s_tile = tile_manager_get_tile (src, x, y, 0, TRUE, FALSE);
*m_tile = tile_manager_get_tile (mask, x, y, 0, TRUE, TRUE);
*s = (*s_tile)->data + (*s_tile)->bpp * ((*s_tile)->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
*m = (*m_tile)->data + (*m_tile)->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH);
@ -154,8 +152,8 @@ find_contiguous_segment (unsigned char *col, PixelRegion *src,
if (! (diff = is_pixel_sufficiently_different (col, s, antialias,
threshold, bytes, has_alpha)))
{
tile_unref (s_tile, FALSE);
tile_unref (m_tile, TRUE);
tile_release (s_tile, FALSE);
tile_release (m_tile, TRUE);
return FALSE;
}
@ -196,8 +194,8 @@ find_contiguous_segment (unsigned char *col, PixelRegion *src,
}
}
tile_unref (s_tile, FALSE);
tile_unref (m_tile, TRUE);
tile_release (s_tile, FALSE);
tile_release (m_tile, TRUE);
return TRUE;
}
@ -216,10 +214,9 @@ find_contiguous_region_helper (PixelRegion *mask, PixelRegion *src,
if (x < 0 || x >= src->w) return;
if (y < 0 || y >= src->h) return;
tile = tile_manager_get_tile (mask->tiles, x, y, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (mask->tiles, x, y, 0, TRUE, FALSE);
val = tile->data[tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH)];
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
if (val != 0)
return;
@ -283,17 +280,15 @@ find_contiguous_region (GImage *gimage, GimpDrawable *drawable, int antialias,
mask = channel_new_mask (gimage, srcPR.w, srcPR.h);
pixel_region_init (&maskPR, drawable_data (GIMP_DRAWABLE(mask)), 0, 0, drawable_width (GIMP_DRAWABLE(mask)), drawable_height (GIMP_DRAWABLE(mask)), TRUE);
tile = tile_manager_get_tile (srcPR.tiles, x, y, 0);
tile = tile_manager_get_tile (srcPR.tiles, x, y, 0, TRUE, FALSE);
if (tile)
{
tile_ref2 (tile, FALSE);
start = tile->data + tile->ewidth * tile->bpp * (y % TILE_HEIGHT) +
tile->bpp * (x % TILE_WIDTH);
find_contiguous_region_helper (&maskPR, &srcPR, has_alpha, antialias, threshold, bytes, x, y, start);
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
}
return mask;

View File

@ -1014,10 +1014,9 @@ gradient_calc_shapeburst_angular_factor (double x,
ix = (int) BOUNDS (x, 0, distR.w);
iy = (int) BOUNDS (y, 0, distR.h);
tile = tile_manager_get_tile (distR.tiles, ix, iy, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (distR.tiles, ix, iy, 0, TRUE, FALSE);
value = 1.0 - *(((float *) tile->data) + ((iy % TILE_HEIGHT) * tile->ewidth + (ix % TILE_WIDTH)));
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
return value;
}
@ -1033,11 +1032,10 @@ gradient_calc_shapeburst_spherical_factor (double x,
ix = (int) BOUNDS (x, 0, distR.w);
iy = (int) BOUNDS (y, 0, distR.h);
tile = tile_manager_get_tile (distR.tiles, ix, iy, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (distR.tiles, ix, iy, 0, TRUE, FALSE);
value = *(((float *) tile->data) + ((iy % TILE_HEIGHT) * tile->ewidth + (ix % TILE_WIDTH)));
value = 1.0 - sin (0.5 * M_PI * value);
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
return value;
}
@ -1053,11 +1051,10 @@ gradient_calc_shapeburst_dimpled_factor (double x,
ix = (int) BOUNDS (x, 0, distR.w);
iy = (int) BOUNDS (y, 0, distR.h);
tile = tile_manager_get_tile (distR.tiles, ix, iy, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (distR.tiles, ix, iy, 0, TRUE, FALSE);
value = *(((float *) tile->data) + ((iy % TILE_HEIGHT) * tile->ewidth + (ix % TILE_WIDTH)));
value = cos (0.5 * M_PI * value);
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
return value;
}

View File

@ -360,21 +360,19 @@ by_color_select_button_release (Tool *tool,
{
if (x < 0 || y < 0 || x >= gdisp->gimage->width || y >= gdisp->gimage->height)
return;
tile = tile_manager_get_tile (gimage_composite (gdisp->gimage), x, y, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (gimage_composite (gdisp->gimage), x, y, 0, TRUE, FALSE);
data = tile->data + tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
gimage_get_color (gdisp->gimage, gimage_composite_type(gdisp->gimage), col, data);
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
}
else
{
if (x < 0 || y < 0 || x >= drawable_width (drawable) || y >= drawable_height (drawable))
return;
tile = tile_manager_get_tile (drawable_data (drawable), x, y, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (drawable_data (drawable), x, y, 0, TRUE, FALSE);
data = tile->data + tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
gimage_get_color (gdisp->gimage, drawable_type(drawable), col, data);
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
}
/* select the area */
@ -933,8 +931,7 @@ by_color_select_preview_button_press (ByColorDialog *bcd,
y = bcd->gimage->height * bevent->y / bcd->preview->requisition.height;
if (x < 0 || y < 0 || x >= bcd->gimage->width || y >= bcd->gimage->height)
return;
tile = tile_manager_get_tile (gimage_composite (bcd->gimage), x, y, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (gimage_composite (bcd->gimage), x, y, 0, TRUE, FALSE);
col = tile->data + tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
}
else
@ -946,8 +943,7 @@ by_color_select_preview_button_press (ByColorDialog *bcd,
y = drawable_height (drawable) * bevent->y / bcd->preview->requisition.height - offy;
if (x < 0 || y < 0 || x >= drawable_width (drawable) || y >= drawable_height (drawable))
return;
tile = tile_manager_get_tile (drawable_data (drawable), x, y, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (drawable_data (drawable), x, y, 0, TRUE, FALSE);
col = tile->data + tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
}
@ -959,7 +955,7 @@ by_color_select_preview_button_press (ByColorDialog *bcd,
by_color_options->feather_radius,
by_color_options->sample_merged);
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
/* show selection on all views */
gdisplays_flush ();

View File

@ -124,14 +124,12 @@ ref_tiles (TileManager *src, TileManager *mask, Tile **s_tile, Tile **m_tile,
int x, int y, unsigned char **s, unsigned char **m)
{
if (*s_tile != NULL)
tile_unref (*s_tile, FALSE);
tile_release (*s_tile, FALSE);
if (*m_tile != NULL)
tile_unref (*m_tile, TRUE);
tile_release (*m_tile, TRUE);
*s_tile = tile_manager_get_tile (src, x, y, 0);
*m_tile = tile_manager_get_tile (mask, x, y, 0);
tile_ref2 (*s_tile, FALSE);
tile_ref2 (*m_tile, TRUE);
*s_tile = tile_manager_get_tile (src, x, y, 0, TRUE, FALSE);
*m_tile = tile_manager_get_tile (mask, x, y, 0, TRUE, TRUE);
*s = (*s_tile)->data + (*s_tile)->bpp * ((*s_tile)->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
*m = (*m_tile)->data + (*m_tile)->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH);
@ -154,8 +152,8 @@ find_contiguous_segment (unsigned char *col, PixelRegion *src,
if (! (diff = is_pixel_sufficiently_different (col, s, antialias,
threshold, bytes, has_alpha)))
{
tile_unref (s_tile, FALSE);
tile_unref (m_tile, TRUE);
tile_release (s_tile, FALSE);
tile_release (m_tile, TRUE);
return FALSE;
}
@ -196,8 +194,8 @@ find_contiguous_segment (unsigned char *col, PixelRegion *src,
}
}
tile_unref (s_tile, FALSE);
tile_unref (m_tile, TRUE);
tile_release (s_tile, FALSE);
tile_release (m_tile, TRUE);
return TRUE;
}
@ -216,10 +214,9 @@ find_contiguous_region_helper (PixelRegion *mask, PixelRegion *src,
if (x < 0 || x >= src->w) return;
if (y < 0 || y >= src->h) return;
tile = tile_manager_get_tile (mask->tiles, x, y, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (mask->tiles, x, y, 0, TRUE, FALSE);
val = tile->data[tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH)];
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
if (val != 0)
return;
@ -283,17 +280,15 @@ find_contiguous_region (GImage *gimage, GimpDrawable *drawable, int antialias,
mask = channel_new_mask (gimage, srcPR.w, srcPR.h);
pixel_region_init (&maskPR, drawable_data (GIMP_DRAWABLE(mask)), 0, 0, drawable_width (GIMP_DRAWABLE(mask)), drawable_height (GIMP_DRAWABLE(mask)), TRUE);
tile = tile_manager_get_tile (srcPR.tiles, x, y, 0);
tile = tile_manager_get_tile (srcPR.tiles, x, y, 0, TRUE, FALSE);
if (tile)
{
tile_ref2 (tile, FALSE);
start = tile->data + tile->ewidth * tile->bpp * (y % TILE_HEIGHT) +
tile->bpp * (x % TILE_WIDTH);
find_contiguous_region_helper (&maskPR, &srcPR, has_alpha, antialias, threshold, bytes, x, y, start);
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
}
return mask;

View File

@ -972,16 +972,15 @@ ink_set_undo_tiles (drawable, x, y, w, h)
{
for (j = x; j < (x + w); j += (TILE_WIDTH - (j % TILE_WIDTH)))
{
dest_tile = tile_manager_get_tile (undo_tiles, j, i, 0);
dest_tile = tile_manager_get_tile (undo_tiles, j, i, 0, FALSE, FALSE);
if (dest_tile->valid == FALSE)
{
src_tile = tile_manager_get_tile (drawable_data (drawable), j, i, 0);
tile_ref (src_tile);
tile_ref (dest_tile);
dest_tile = tile_manager_get_tile (undo_tiles, j, i, 0, TRUE, TRUE);
src_tile = tile_manager_get_tile (drawable_data (drawable), j, i, 0, TRUE, FALSE);
memcpy (dest_tile->data, src_tile->data,
(src_tile->ewidth * src_tile->eheight * src_tile->bpp));
tile_unref (src_tile, FALSE);
tile_unref (dest_tile, TRUE);
tile_release (src_tile, FALSE);
tile_release (dest_tile, TRUE);
}
}
}
@ -1000,12 +999,12 @@ ink_set_canvas_tiles (x, y, w, h)
{
for (j = x; j < (x + w); j += (TILE_WIDTH - (j % TILE_WIDTH)))
{
tile = tile_manager_get_tile (canvas_tiles, j, i, 0);
tile = tile_manager_get_tile (canvas_tiles, j, i, 0, FALSE, FALSE);
if (tile->valid == FALSE)
{
tile_ref (tile);
tile = tile_manager_get_tile (canvas_tiles, j, i, 0, TRUE, TRUE);
memset (tile->data, 0, (tile->ewidth * tile->eheight * tile->bpp));
tile_unref (tile, TRUE);
tile_release (tile, TRUE);
}
}
}

View File

@ -124,14 +124,12 @@ ref_tiles (TileManager *src, TileManager *mask, Tile **s_tile, Tile **m_tile,
int x, int y, unsigned char **s, unsigned char **m)
{
if (*s_tile != NULL)
tile_unref (*s_tile, FALSE);
tile_release (*s_tile, FALSE);
if (*m_tile != NULL)
tile_unref (*m_tile, TRUE);
tile_release (*m_tile, TRUE);
*s_tile = tile_manager_get_tile (src, x, y, 0);
*m_tile = tile_manager_get_tile (mask, x, y, 0);
tile_ref2 (*s_tile, FALSE);
tile_ref2 (*m_tile, TRUE);
*s_tile = tile_manager_get_tile (src, x, y, 0, TRUE, FALSE);
*m_tile = tile_manager_get_tile (mask, x, y, 0, TRUE, TRUE);
*s = (*s_tile)->data + (*s_tile)->bpp * ((*s_tile)->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
*m = (*m_tile)->data + (*m_tile)->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH);
@ -154,8 +152,8 @@ find_contiguous_segment (unsigned char *col, PixelRegion *src,
if (! (diff = is_pixel_sufficiently_different (col, s, antialias,
threshold, bytes, has_alpha)))
{
tile_unref (s_tile, FALSE);
tile_unref (m_tile, TRUE);
tile_release (s_tile, FALSE);
tile_release (m_tile, TRUE);
return FALSE;
}
@ -196,8 +194,8 @@ find_contiguous_segment (unsigned char *col, PixelRegion *src,
}
}
tile_unref (s_tile, FALSE);
tile_unref (m_tile, TRUE);
tile_release (s_tile, FALSE);
tile_release (m_tile, TRUE);
return TRUE;
}
@ -216,10 +214,9 @@ find_contiguous_region_helper (PixelRegion *mask, PixelRegion *src,
if (x < 0 || x >= src->w) return;
if (y < 0 || y >= src->h) return;
tile = tile_manager_get_tile (mask->tiles, x, y, 0);
tile_ref2 (tile, FALSE);
tile = tile_manager_get_tile (mask->tiles, x, y, 0, TRUE, FALSE);
val = tile->data[tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH)];
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
if (val != 0)
return;
@ -283,17 +280,15 @@ find_contiguous_region (GImage *gimage, GimpDrawable *drawable, int antialias,
mask = channel_new_mask (gimage, srcPR.w, srcPR.h);
pixel_region_init (&maskPR, drawable_data (GIMP_DRAWABLE(mask)), 0, 0, drawable_width (GIMP_DRAWABLE(mask)), drawable_height (GIMP_DRAWABLE(mask)), TRUE);
tile = tile_manager_get_tile (srcPR.tiles, x, y, 0);
tile = tile_manager_get_tile (srcPR.tiles, x, y, 0, TRUE, FALSE);
if (tile)
{
tile_ref2 (tile, FALSE);
start = tile->data + tile->ewidth * tile->bpp * (y % TILE_HEIGHT) +
tile->bpp * (x % TILE_WIDTH);
find_contiguous_region_helper (&maskPR, &srcPR, has_alpha, antialias, threshold, bytes, x, y, start);
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
}
return mask;

View File

@ -972,16 +972,15 @@ ink_set_undo_tiles (drawable, x, y, w, h)
{
for (j = x; j < (x + w); j += (TILE_WIDTH - (j % TILE_WIDTH)))
{
dest_tile = tile_manager_get_tile (undo_tiles, j, i, 0);
dest_tile = tile_manager_get_tile (undo_tiles, j, i, 0, FALSE, FALSE);
if (dest_tile->valid == FALSE)
{
src_tile = tile_manager_get_tile (drawable_data (drawable), j, i, 0);
tile_ref (src_tile);
tile_ref (dest_tile);
dest_tile = tile_manager_get_tile (undo_tiles, j, i, 0, TRUE, TRUE);
src_tile = tile_manager_get_tile (drawable_data (drawable), j, i, 0, TRUE, FALSE);
memcpy (dest_tile->data, src_tile->data,
(src_tile->ewidth * src_tile->eheight * src_tile->bpp));
tile_unref (src_tile, FALSE);
tile_unref (dest_tile, TRUE);
tile_release (src_tile, FALSE);
tile_release (dest_tile, TRUE);
}
}
}
@ -1000,12 +999,12 @@ ink_set_canvas_tiles (x, y, w, h)
{
for (j = x; j < (x + w); j += (TILE_WIDTH - (j % TILE_WIDTH)))
{
tile = tile_manager_get_tile (canvas_tiles, j, i, 0);
tile = tile_manager_get_tile (canvas_tiles, j, i, 0, FALSE, FALSE);
if (tile->valid == FALSE)
{
tile_ref (tile);
tile = tile_manager_get_tile (canvas_tiles, j, i, 0, TRUE, TRUE);
memset (tile->data, 0, (tile->ewidth * tile->eheight * tile->bpp));
tile_unref (tile, TRUE);
tile_release (tile, TRUE);
}
}
}

View File

@ -616,7 +616,6 @@ paint_core_get_orig_image (paint_core, drawable, x1, y1, x2, y2)
Tile *undo_tile;
int h;
int pixelwidth;
int refd;
unsigned char * s, * d;
void * pr;
@ -639,18 +638,15 @@ paint_core_get_orig_image (paint_core, drawable, x1, y1, x2, y2)
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
{
/* If the undo tile corresponding to this location is valid, use it */
undo_tile = tile_manager_get_tile (undo_tiles, srcPR.x, srcPR.y, 0);
undo_tile = tile_manager_get_tile (undo_tiles, srcPR.x, srcPR.y, 0, TRUE, FALSE);
if (undo_tile->valid == TRUE)
{
tile_ref2 (undo_tile, FALSE);
s = undo_tile->data + srcPR.rowstride * (srcPR.y % TILE_HEIGHT) +
srcPR.bytes * (srcPR.x % TILE_WIDTH);
refd = TRUE;
}
else
{
s = srcPR.data;
refd = FALSE;
}
d = destPR.data;
@ -663,8 +659,7 @@ paint_core_get_orig_image (paint_core, drawable, x1, y1, x2, y2)
d += destPR.rowstride;
}
if (refd)
tile_unref (undo_tile, FALSE);
tile_release (undo_tile, FALSE);
}
return orig_buf;
@ -1208,16 +1203,15 @@ set_undo_tiles (drawable, x, y, w, h)
{
for (j = x; j < (x + w); j += (TILE_WIDTH - (j % TILE_WIDTH)))
{
dest_tile = tile_manager_get_tile (undo_tiles, j, i, 0);
dest_tile = tile_manager_get_tile (undo_tiles, j, i, 0, FALSE, FALSE);
if (dest_tile->valid == FALSE)
{
src_tile = tile_manager_get_tile (drawable_data (drawable), j, i, 0);
tile_ref2 (src_tile, FALSE);
tile_ref2 (dest_tile, TRUE);
dest_tile = tile_manager_get_tile (undo_tiles, j, i, 0, TRUE, TRUE);
src_tile = tile_manager_get_tile (drawable_data (drawable), j, i, 0, TRUE, FALSE);
memcpy (dest_tile->data, src_tile->data,
(src_tile->ewidth * src_tile->eheight * src_tile->bpp));
tile_unref (src_tile, FALSE);
tile_unref (dest_tile, TRUE);
tile_release (src_tile, FALSE);
tile_release (dest_tile, TRUE);
}
}
}
@ -1235,12 +1229,12 @@ set_canvas_tiles (x, y, w, h)
{
for (j = x; j < (x + w); j += (TILE_WIDTH - (j % TILE_WIDTH)))
{
tile = tile_manager_get_tile (canvas_tiles, j, i, 0);
tile = tile_manager_get_tile (canvas_tiles, j, i, 0, FALSE, FALSE);
if (tile->valid == FALSE)
{
tile_ref2 (tile, TRUE);
tile = tile_manager_get_tile (canvas_tiles, j, i, 0, TRUE, TRUE);
memset (tile->data, 0, (tile->ewidth * tile->eheight * tile->bpp));
tile_unref (tile, TRUE);
tile_release (tile, TRUE);
}
}
}

View File

@ -61,8 +61,7 @@ static double cubic (double, int, int, int, int);
dy * ((1-dx)*jk1 + dx*j1k1))
#define REF_TILE(i,x,y) \
tile[i] = tile_manager_get_tile (float_tiles, x, y, 0); \
tile_ref2 (tile[i], FALSE); \
tile[i] = tile_manager_get_tile (float_tiles, x, y, 0, TRUE, FALSE); \
src[i] = tile[i]->data + tile[i]->bpp * (tile[i]->ewidth * ((y) % TILE_HEIGHT) + ((x) % TILE_WIDTH));
@ -1111,7 +1110,7 @@ transform_core_do (gimage, drawable, float_tiles, interpolation, matrix)
*d++ = a_val;
for (b = 0; b < 16; b++)
tile_unref (tile[b], FALSE);
tile_release (tile[b], FALSE);
}
else /* linear */
{
@ -1168,7 +1167,7 @@ transform_core_do (gimage, drawable, float_tiles, interpolation, matrix)
*d++ = a_val;
for (b = 0; b < 4; b++)
tile_unref (tile[b], FALSE);
tile_release (tile[b], FALSE);
}
}
else /* no interpolation */
@ -1178,7 +1177,7 @@ transform_core_do (gimage, drawable, float_tiles, interpolation, matrix)
for (b = 0; b < bytes; b++)
*d++ = src[0][b];
tile_unref (tile[0], FALSE);
tile_release (tile[0], FALSE);
}
}
else

View File

@ -61,8 +61,7 @@ static double cubic (double, int, int, int, int);
dy * ((1-dx)*jk1 + dx*j1k1))
#define REF_TILE(i,x,y) \
tile[i] = tile_manager_get_tile (float_tiles, x, y, 0); \
tile_ref2 (tile[i], FALSE); \
tile[i] = tile_manager_get_tile (float_tiles, x, y, 0, TRUE, FALSE); \
src[i] = tile[i]->data + tile[i]->bpp * (tile[i]->ewidth * ((y) % TILE_HEIGHT) + ((x) % TILE_WIDTH));
@ -1111,7 +1110,7 @@ transform_core_do (gimage, drawable, float_tiles, interpolation, matrix)
*d++ = a_val;
for (b = 0; b < 16; b++)
tile_unref (tile[b], FALSE);
tile_release (tile[b], FALSE);
}
else /* linear */
{
@ -1168,7 +1167,7 @@ transform_core_do (gimage, drawable, float_tiles, interpolation, matrix)
*d++ = a_val;
for (b = 0; b < 4; b++)
tile_unref (tile[b], FALSE);
tile_release (tile[b], FALSE);
}
}
else /* no interpolation */
@ -1178,7 +1177,7 @@ transform_core_do (gimage, drawable, float_tiles, interpolation, matrix)
for (b = 0; b < bytes; b++)
*d++ = src[0][b];
tile_unref (tile[0], FALSE);
tile_release (tile[0], FALSE);
}
}
else

View File

@ -613,17 +613,15 @@ undo_pop_image (GImage *gimage,
{
for (j = x; j < image_undo->x2; j += (TILE_WIDTH - (j % TILE_WIDTH)))
{
src_tile = tile_manager_get_tile (tiles, j, i, 0);
src_tile = tile_manager_get_tile (tiles, j, i, 0, TRUE, TRUE);
if (src_tile->valid == TRUE)
{
dest_tile = tile_manager_get_tile (drawable_data (image_undo->drawable), j, i, 0);
tile_ref2 (src_tile, TRUE);
tile_ref2 (dest_tile, TRUE);
dest_tile = tile_manager_get_tile (drawable_data (image_undo->drawable), j, i, 0, TRUE, TRUE);
swap_pixels (src_tile->data, dest_tile->data,
(src_tile->ewidth * src_tile->eheight * src_tile->bpp));
tile_unref (src_tile, TRUE);
tile_unref (dest_tile, TRUE);
tile_release (dest_tile, TRUE);
}
tile_release (src_tile, TRUE);
}
}
}

101
app/xcf.c
View File

@ -1046,16 +1046,16 @@ xcf_save_level (XcfInfo *info,
switch (info->compression)
{
case COMPRESS_NONE:
xcf_save_tile (info, &level->tiles[i]);
xcf_save_tile (info, level->tiles[i]);
break;
case COMPRESS_RLE:
xcf_save_tile_rle (info, &level->tiles[i]);
xcf_save_tile_rle (info, level->tiles[i]);
break;
case COMPRESS_ZLIB:
g_error ("xcf: zlib compression unimplemented");
break;
case COMPRESS_FRACTAL:
xcf_save_frac_compressed_tile (info, &level->tiles[i]);
xcf_save_frac_compressed_tile (info, level->tiles[i]);
break;
}
@ -1089,9 +1089,9 @@ static void
xcf_save_tile (XcfInfo *info,
Tile *tile)
{
tile_ref2 (tile, FALSE);
tile_lock (tile);
info->cp += xcf_write_int8 (info->fp, tile->data, tile_size (tile));
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
}
static void
@ -1108,7 +1108,7 @@ xcf_save_tile_rle (XcfInfo *info,
int bpp;
int i, j, k;
tile_ref2 (tile, FALSE);
tile_lock (tile);
bpp = tile->bpp;
@ -1211,7 +1211,7 @@ xcf_save_tile_rle (XcfInfo *info,
g_print ("xcf: uh oh! xcf rle tile saving error: %d\n", count);
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
}
@ -1851,39 +1851,6 @@ xcf_load_hierarchy (XcfInfo *info,
return TRUE;
}
static void
tile_compare_and_maybe_mirror (Tile *new, Tile *old)
{
if (
(old->ewidth == new->ewidth) &&
(old->eheight == new->eheight) &&
(old->bpp == new->bpp)
)
{
tile_ref2 (new, FALSE);
tile_ref2 (old, FALSE);
if (memcmp (new->data, old->data,
old->ewidth * old->eheight * old->bpp) == 0)
{
#if defined (TILE_DEBUG)
g_print ("M");
#endif
tile_unref (new, FALSE);
tile_unref (old, FALSE);
tile_mirror (new, old);
}
else
{
#if defined (TILE_DEBUG)
g_print (".");
#endif
tile_unref (new, FALSE);
tile_unref (old, FALSE);
}
}
}
static gint
xcf_load_level (XcfInfo *info,
@ -1897,7 +1864,9 @@ xcf_load_level (XcfInfo *info,
int width;
int height;
int i;
int fail;
Tile *previous;
Tile *tile;
info->cp += xcf_read_int32 (info->fp, (guint32*) &width, 1);
info->cp += xcf_read_int32 (info->fp, (guint32*) &height, 1);
@ -1914,12 +1883,6 @@ xcf_load_level (XcfInfo *info,
if (offset == 0)
return TRUE;
/* get the first tile from this level. this will
* cause 'level->tiles' to be created so that
* we can load in the tiles.
*/
tile_manager_get (tiles, 0, level_num);
/* Initialise the reference for the in-memory tile-compression
*/
previous = NULL;
@ -1927,6 +1890,8 @@ xcf_load_level (XcfInfo *info,
ntiles = level->ntile_rows * level->ntile_cols;
for (i = 0; i < ntiles; i++)
{
fail = FALSE;
if (offset == 0)
{
g_message ("not enough tiles found in level");
@ -1941,16 +1906,19 @@ xcf_load_level (XcfInfo *info,
/* seek to the tile offset */
xcf_seek_pos (info, offset);
/* get the tile from the tile manager */
tile = tile_manager_get (tiles, i, level_num, TRUE, TRUE);
/* read in the tile */
switch (info->compression)
{
case COMPRESS_NONE:
if (!xcf_load_tile (info, &level->tiles[i]))
return FALSE;
if (!xcf_load_tile (info, tile))
fail = TRUE;
break;
case COMPRESS_RLE:
if (!xcf_load_tile_rle (info, &level->tiles[i]))
return FALSE;
if (!xcf_load_tile_rle (info, tile))
fail = TRUE;
break;
case COMPRESS_ZLIB:
g_error ("xcf: zlib compression unimplemented");
@ -1960,15 +1928,34 @@ xcf_load_level (XcfInfo *info,
break;
}
if (fail)
{
tile_release (tile, TRUE);
return FALSE;
}
/* To potentially save memory, we compare the
* newly-fetched tile against the last one, and
* if they're the same we copy-on-write mirror one against
* the other.
*/
if (previous != NULL)
tile_compare_and_maybe_mirror (&level->tiles[i], previous);
previous = &level->tiles[i];
if (previous != NULL)
{
tile_lock (previous);
if (tile_size (tile) == tile_size (previous) &&
memcmp (tile->data, previous->data,
tile_size (tile)) == 0)
{
tile_release (tile, TRUE);
tile_manager_map (tiles, i, level_num, previous);
}
else
{
tile_release (tile, TRUE);
}
tile_release (previous, FALSE);
}
previous = tile;
/* restore the saved position so we'll be ready to
* read the next offset.
@ -2006,9 +1993,7 @@ xcf_load_tile (XcfInfo *info,
#else
tile_ref2 (tile, TRUE);
info->cp += xcf_read_int8 (info->fp, tile->data, tile_size (tile));
tile_unref (tile, TRUE);
#endif
@ -2029,8 +2014,6 @@ xcf_load_tile_rle (XcfInfo *info,
int bpp;
int i, j;
tile_ref2 (tile, TRUE);
data = tile->data;
bpp = tile->bpp;
@ -2096,8 +2079,6 @@ xcf_load_tile_rle (XcfInfo *info,
}
}
tile_unref (tile, TRUE);
return TRUE;
}

View File

@ -1046,16 +1046,16 @@ xcf_save_level (XcfInfo *info,
switch (info->compression)
{
case COMPRESS_NONE:
xcf_save_tile (info, &level->tiles[i]);
xcf_save_tile (info, level->tiles[i]);
break;
case COMPRESS_RLE:
xcf_save_tile_rle (info, &level->tiles[i]);
xcf_save_tile_rle (info, level->tiles[i]);
break;
case COMPRESS_ZLIB:
g_error ("xcf: zlib compression unimplemented");
break;
case COMPRESS_FRACTAL:
xcf_save_frac_compressed_tile (info, &level->tiles[i]);
xcf_save_frac_compressed_tile (info, level->tiles[i]);
break;
}
@ -1089,9 +1089,9 @@ static void
xcf_save_tile (XcfInfo *info,
Tile *tile)
{
tile_ref2 (tile, FALSE);
tile_lock (tile);
info->cp += xcf_write_int8 (info->fp, tile->data, tile_size (tile));
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
}
static void
@ -1108,7 +1108,7 @@ xcf_save_tile_rle (XcfInfo *info,
int bpp;
int i, j, k;
tile_ref2 (tile, FALSE);
tile_lock (tile);
bpp = tile->bpp;
@ -1211,7 +1211,7 @@ xcf_save_tile_rle (XcfInfo *info,
g_print ("xcf: uh oh! xcf rle tile saving error: %d\n", count);
}
tile_unref (tile, FALSE);
tile_release (tile, FALSE);
}
@ -1851,39 +1851,6 @@ xcf_load_hierarchy (XcfInfo *info,
return TRUE;
}
static void
tile_compare_and_maybe_mirror (Tile *new, Tile *old)
{
if (
(old->ewidth == new->ewidth) &&
(old->eheight == new->eheight) &&
(old->bpp == new->bpp)
)
{
tile_ref2 (new, FALSE);
tile_ref2 (old, FALSE);
if (memcmp (new->data, old->data,
old->ewidth * old->eheight * old->bpp) == 0)
{
#if defined (TILE_DEBUG)
g_print ("M");
#endif
tile_unref (new, FALSE);
tile_unref (old, FALSE);
tile_mirror (new, old);
}
else
{
#if defined (TILE_DEBUG)
g_print (".");
#endif
tile_unref (new, FALSE);
tile_unref (old, FALSE);
}
}
}
static gint
xcf_load_level (XcfInfo *info,
@ -1897,7 +1864,9 @@ xcf_load_level (XcfInfo *info,
int width;
int height;
int i;
int fail;
Tile *previous;
Tile *tile;
info->cp += xcf_read_int32 (info->fp, (guint32*) &width, 1);
info->cp += xcf_read_int32 (info->fp, (guint32*) &height, 1);
@ -1914,12 +1883,6 @@ xcf_load_level (XcfInfo *info,
if (offset == 0)
return TRUE;
/* get the first tile from this level. this will
* cause 'level->tiles' to be created so that
* we can load in the tiles.
*/
tile_manager_get (tiles, 0, level_num);
/* Initialise the reference for the in-memory tile-compression
*/
previous = NULL;
@ -1927,6 +1890,8 @@ xcf_load_level (XcfInfo *info,
ntiles = level->ntile_rows * level->ntile_cols;
for (i = 0; i < ntiles; i++)
{
fail = FALSE;
if (offset == 0)
{
g_message ("not enough tiles found in level");
@ -1941,16 +1906,19 @@ xcf_load_level (XcfInfo *info,
/* seek to the tile offset */
xcf_seek_pos (info, offset);
/* get the tile from the tile manager */
tile = tile_manager_get (tiles, i, level_num, TRUE, TRUE);
/* read in the tile */
switch (info->compression)
{
case COMPRESS_NONE:
if (!xcf_load_tile (info, &level->tiles[i]))
return FALSE;
if (!xcf_load_tile (info, tile))
fail = TRUE;
break;
case COMPRESS_RLE:
if (!xcf_load_tile_rle (info, &level->tiles[i]))
return FALSE;
if (!xcf_load_tile_rle (info, tile))
fail = TRUE;
break;
case COMPRESS_ZLIB:
g_error ("xcf: zlib compression unimplemented");
@ -1960,15 +1928,34 @@ xcf_load_level (XcfInfo *info,
break;
}
if (fail)
{
tile_release (tile, TRUE);
return FALSE;
}
/* To potentially save memory, we compare the
* newly-fetched tile against the last one, and
* if they're the same we copy-on-write mirror one against
* the other.
*/
if (previous != NULL)
tile_compare_and_maybe_mirror (&level->tiles[i], previous);
previous = &level->tiles[i];
if (previous != NULL)
{
tile_lock (previous);
if (tile_size (tile) == tile_size (previous) &&
memcmp (tile->data, previous->data,
tile_size (tile)) == 0)
{
tile_release (tile, TRUE);
tile_manager_map (tiles, i, level_num, previous);
}
else
{
tile_release (tile, TRUE);
}
tile_release (previous, FALSE);
}
previous = tile;
/* restore the saved position so we'll be ready to
* read the next offset.
@ -2006,9 +1993,7 @@ xcf_load_tile (XcfInfo *info,
#else
tile_ref2 (tile, TRUE);
info->cp += xcf_read_int8 (info->fp, tile->data, tile_size (tile));
tile_unref (tile, TRUE);
#endif
@ -2029,8 +2014,6 @@ xcf_load_tile_rle (XcfInfo *info,
int bpp;
int i, j;
tile_ref2 (tile, TRUE);
data = tile->data;
bpp = tile->bpp;
@ -2096,8 +2079,6 @@ xcf_load_tile_rle (XcfInfo *info,
}
}
tile_unref (tile, TRUE);
return TRUE;
}