app/base/tile-cache.c app/base/tile-manager.c app/base/tile-private.h

2005-09-29  Sven Neumann  <sven@gimp.org>

	* app/base/tile-cache.c
	* app/base/tile-manager.c
	* app/base/tile-private.h
	* app/base/tile-swap.c
	* app/base/tile.c: keep the data size of a tile in the Tile struct
	instead of recalculating it over and over again. Adds an overhead
	of 4 bytes per tile but speeds up the tile cache significantly.
This commit is contained in:
Sven Neumann 2005-09-29 22:24:57 +00:00 committed by Sven Neumann
parent b3a7108d07
commit c995db3ce0
6 changed files with 71 additions and 65 deletions

View File

@ -1,3 +1,13 @@
2005-09-29 Sven Neumann <sven@gimp.org>
* app/base/tile-cache.c
* app/base/tile-manager.c
* app/base/tile-private.h
* app/base/tile-swap.c
* app/base/tile.c: keep the data size of a tile in the Tile struct
instead of recalculating it over and over again. Adds 4 bytes per
tile but speeds up the tile cache significantly.
2005-09-29 Sven Neumann <sven@gimp.org>
* app/base/siox.c: optimizations by Tobias Lenz.

View File

@ -149,7 +149,7 @@ tile_cache_insert (Tile *tile)
tile->listhead = NULL;
if (list == &dirty_list)
cur_cache_dirty -= tile_size_inline (tile);
cur_cache_dirty -= tile->size;
}
else
{
@ -168,7 +168,7 @@ tile_cache_insert (Tile *tile)
}
}
cur_cache_size += tile_size_inline (tile);
cur_cache_size += tile->size;
}
/* Put the tile at the end of the proper list */
@ -191,7 +191,7 @@ tile_cache_insert (Tile *tile)
if (tile->dirty || (tile->swap_offset == -1))
{
cur_cache_dirty += tile_size_inline (tile);
cur_cache_dirty += tile->size;
#ifdef ENABLE_THREADED_TILE_SWAPPER
g_mutex_lock (dirty_mutex);
@ -226,10 +226,10 @@ tile_cache_flush_internal (Tile *tile)
if (list)
{
cur_cache_size -= tile_size_inline (tile);
cur_cache_size -= tile->size;
if (list == &dirty_list)
cur_cache_dirty -= tile_size_inline (tile);
cur_cache_dirty -= tile->size;
if (tile->next)
tile->next->prev = tile->prev;
@ -342,7 +342,7 @@ tile_idle_thread (gpointer data)
list = tile->listhead;
if (list == &dirty_list)
cur_cache_dirty -= tile_size_inline (tile);
cur_cache_dirty -= tile->size;
if (tile->next)
tile->next->prev = tile->prev;
@ -416,7 +416,7 @@ tile_idle_preswap (gpointer data)
clean_list.first = tile;
clean_list.last = tile;
cur_cache_dirty -= tile_size_inline (tile);
cur_cache_dirty -= tile->size;
}
return TRUE;

View File

@ -184,15 +184,20 @@ tile_manager_get (TileManager *tm,
{
for (j = 0; j < ncols; j++, k++)
{
tiles[k] = g_new (Tile, 1);
tile_init (tiles[k], tm->bpp);
tile_attach (tiles[k], tm, k);
Tile *new = g_new (Tile, 1);
tile_init (new, tm->bpp);
tile_attach (new, tm, k);
if (j == (ncols - 1))
tiles[k]->ewidth = right_tile;
new->ewidth = right_tile;
if (i == (nrows - 1))
tiles[k]->eheight = bottom_tile;
new->eheight = bottom_tile;
new->size = new->ewidth * new->eheight * new->bpp;
tiles[k] = new;
}
}
}
@ -218,42 +223,41 @@ tile_manager_get (TileManager *tm,
if ((*tile_ptr)->share_count > 1)
{
/* Copy-on-write required */
Tile *newtile = g_new (Tile, 1);
gint newsize;
Tile *new = g_new (Tile, 1);
tile_init (newtile, (*tile_ptr)->bpp);
tile_init (new, (*tile_ptr)->bpp);
newtile->ewidth = (*tile_ptr)->ewidth;
newtile->eheight = (*tile_ptr)->eheight;
newtile->valid = (*tile_ptr)->valid;
new->ewidth = (*tile_ptr)->ewidth;
new->eheight = (*tile_ptr)->eheight;
new->valid = (*tile_ptr)->valid;
newsize = tile_size_inline (newtile);
newtile->data = g_new (guchar, newsize);
new->size = new->ewidth * new->eheight * new->bpp;
new->data = g_new (guchar, new->size);
if (!newtile->valid)
if (!new->valid)
g_warning ("Oh boy, r/w tile is invalid... we suck. "
"Please report.");
if ((*tile_ptr)->rowhint)
newtile->rowhint = g_memdup ((*tile_ptr)->rowhint,
newtile->eheight *
new->rowhint = g_memdup ((*tile_ptr)->rowhint,
new->eheight *
sizeof (TileRowHint));
if ((*tile_ptr)->data)
{
memcpy (newtile->data, (*tile_ptr)->data, newsize);
memcpy (new->data, (*tile_ptr)->data, new->size);
}
else
{
tile_lock (*tile_ptr);
memcpy (newtile->data, (*tile_ptr)->data, newsize);
memcpy (new->data, (*tile_ptr)->data, new->size);
tile_release (*tile_ptr, FALSE);
}
tile_detach (*tile_ptr, tm, tile_num);
TILE_MUTEX_LOCK (newtile);
tile_attach (newtile, tm, tile_num);
*tile_ptr = newtile;
TILE_MUTEX_LOCK (new);
tile_attach (new, tm, tile_num);
*tile_ptr = new;
}
(*tile_ptr)->write_count++;
@ -374,18 +378,19 @@ tile_invalidate (Tile **tile_ptr,
if (tile->share_count > 1)
{
/* This tile is shared. Replace it with a new, invalid tile. */
Tile *newtile = g_new (Tile, 1);
Tile *new = g_new (Tile, 1);
g_print ("invalidating shared tile (executing buggy code!!!)\n");
tile_init (newtile, tile->bpp);
newtile->ewidth = tile->ewidth;
newtile->eheight = tile->eheight;
tile_init (new, tile->bpp);
new->ewidth = tile->ewidth;
new->eheight = tile->eheight;
new->size = tile->size;
tile_detach (tile, tm, tile_num);
TILE_MUTEX_LOCK (newtile);
tile_attach (newtile, tm, tile_num);
tile = *tile_ptr = newtile;
TILE_MUTEX_LOCK (new);
tile_attach (new, tm, tile_num);
tile = *tile_ptr = new;
}
if (tile->listhead)
@ -471,18 +476,23 @@ tile_manager_map (TileManager *tm,
{
for (j = 0; j < ncols; j++, k++)
{
Tile *new = g_new (Tile, 1);
#ifdef DEBUG_TILE_MANAGER
g_printerr (",");
#endif
tiles[k] = g_new (Tile, 1);
tile_init (tiles[k], tm->bpp);
tile_attach (tiles[k], tm, k);
tile_init (new, tm->bpp);
tile_attach (new, tm, k);
if (j == (ncols - 1))
tiles[k]->ewidth = right_tile;
new->ewidth = right_tile;
if (i == (nrows - 1))
tiles[k]->eheight = bottom_tile;
new->eheight = bottom_tile;
new->size = new->ewidth * new->eheight * new->bpp;
tiles[k] = new;
}
}
}

View File

@ -57,6 +57,7 @@ struct _Tile
* (but not larger) than TILE_WIDTH and TILE_HEIGHT.
* this is to handle edge tiles of a drawable.
*/
gint size; /* size of the tile data (ewidth * eheight * bpp) */
TileRowHint *rowhint; /* An array of hints for rendering purposes */
@ -94,13 +95,4 @@ struct _Tile
#endif
/* an inlined version of tile_size() */
static inline gint
tile_size_inline (Tile *tile)
{
return tile->ewidth * tile->eheight * tile->bpp;
}
#endif /* __TILE_PRIVATE_H__ */

View File

@ -585,7 +585,6 @@ tile_swap_default_in (DefSwapFile *def_swap_file,
gint fd,
Tile *tile)
{
gint bytes;
gint err;
gint nleft;
off_t offset;
@ -611,15 +610,14 @@ tile_swap_default_in (DefSwapFile *def_swap_file,
}
}
bytes = tile_size_inline (tile);
tile_alloc (tile);
nleft = bytes;
nleft = tile->size;
while (nleft > 0)
{
do
{
err = read (fd, tile->data + bytes - nleft, nleft);
err = read (fd, tile->data + tile->size - nleft, nleft);
}
while ((err == -1) && ((errno == EAGAIN) || (errno == EINTR)));
@ -635,7 +633,7 @@ tile_swap_default_in (DefSwapFile *def_swap_file,
nleft -= err;
}
def_swap_file->cur_position += bytes;
def_swap_file->cur_position += tile->size;
/* Do not delete the swap from the file */
/* tile_swap_default_delete (def_swap_file, fd, tile); */
@ -649,14 +647,12 @@ tile_swap_default_out (DefSwapFile *def_swap_file,
Tile *tile)
{
gint bytes;
gint rbytes;
gint err;
gint nleft;
off_t offset;
off_t newpos;
bytes = TILE_WIDTH * TILE_HEIGHT * tile->bpp;
rbytes = tile_size_inline (tile);
/* If there is already a valid swap_offset, use it */
if (tile->swap_offset == -1)
@ -678,10 +674,10 @@ tile_swap_default_out (DefSwapFile *def_swap_file,
def_swap_file->cur_position = newpos;
}
nleft = rbytes;
nleft = tile->size;
while (nleft > 0)
{
err = write (fd, tile->data + rbytes - nleft, nleft);
err = write (fd, tile->data + tile->size - nleft, nleft);
if (err <= 0)
{
if (write_err_msg)
@ -694,7 +690,7 @@ tile_swap_default_out (DefSwapFile *def_swap_file,
nleft -= err;
}
def_swap_file->cur_position += rbytes;
def_swap_file->cur_position += tile->size;
/* Do NOT free tile->data because we may be pre-swapping.
* tile->data is freed in tile_cache_zorch_next
@ -912,7 +908,6 @@ tile_swap_in_attempt (DefSwapFile *def_swap_file,
gint fd,
Tile *tile)
{
gint bytes;
gint err;
gint nleft;
off_t offset;
@ -935,15 +930,14 @@ tile_swap_in_attempt (DefSwapFile *def_swap_file,
return;
}
bytes = tile_size_inline (tile);
tile_alloc (tile);
nleft = bytes;
nleft = tile->size;
while (nleft > 0)
{
do
{
err = read (fd, tile->data + bytes - nleft, nleft);
err = read (fd, tile->data + tile->size - nleft, nleft);
}
while ((err == -1) && ((errno == EAGAIN) || (errno == EINTR)));

View File

@ -218,7 +218,7 @@ tile_alloc (Tile *tile)
/* Allocate the data for the tile.
*/
tile->data = g_new (guchar, tile_size_inline (tile));
tile->data = g_new (guchar, tile->size);
#ifdef HINTS_SANITY
tile_exist_count++;
@ -281,7 +281,7 @@ tile_size (Tile *tile)
/* Return the actual size of the tile data.
* (Based on its effective width and height).
*/
return tile->ewidth * tile->eheight * tile->bpp;
return tile->size;
}
gint