mirror of https://github.com/GNOME/gimp.git
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:
parent
b3a7108d07
commit
c995db3ce0
10
ChangeLog
10
ChangeLog
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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)));
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue