home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
-
- #include "tile.h"
- #include "tile_pvt.h"
- #include "tile_cache.h"
- #include "tile_manager.h"
- #include "tile_swap.h"
-
-
- static void tile_destroy (Tile *tile);
-
- int tile_count = 0;
-
- void
- tile_sanitize_rowhints (Tile *tile)
- {
- int height, y;
-
- /* If tile has rowhints array already, do nothing. */
- if (tile->rowhint)
- return;
-
- height = tile->eheight;
-
- tile->rowhint = g_new (TileRowHint, height);
-
- for (y=0; y<height; y++)
- {
- tile->rowhint[y] = TILEROWHINT_UNKNOWN;
- }
- }
-
- TileRowHint
- tile_get_rowhint (Tile *tile, int yoff)
- {
- #ifdef HINTS_SANITY
- if (yoff < tile_eheight(tile) && yoff>=0)
- {
- return tile->rowhint[yoff];
- }
- else
- g_error("GET_ROWHINT OUT OF RANGE");
- return TILEROWHINT_OUTOFRANGE;
- #else
- return tile->rowhint[yoff];
- #endif
- }
-
- void
- tile_set_rowhint (Tile *tile, int yoff, TileRowHint rowhint)
- {
- #ifdef HINTS_SANITY
- if (yoff < tile_eheight(tile) && yoff>=0)
- {
- tile->rowhint[yoff] = rowhint;
- }
- else
- g_error("SET_ROWHINT OUT OF RANGE");
- #else
- tile->rowhint[yoff] = rowhint;
- #endif
- }
-
- void
- 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->ewidth = TILE_WIDTH;
- tile->eheight = TILE_HEIGHT;
- tile->bpp = bpp;
- tile->swap_num = 1;
- tile->swap_offset = -1;
- tile->tlink = NULL;
- tile->next = tile->prev = NULL;
- tile->listhead = NULL;
- tile->rowhint = NULL;
-
- #ifdef USE_PTHREADS
- {
- pthread_mutex_init(&tile->mutex, NULL);
- }
- tile_count++;
- #endif
- }
-
- int tile_ref_count = 0;
- int tile_share_count = 0;
- int tile_active_count = 0;
-
- #ifdef HINTS_SANITY
- int tile_exist_peak = 0;
- int tile_exist_count = 0;
- #endif
-
- void
- tile_lock (Tile *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 (tile->ref_count == 1)
- {
- if (tile->listhead)
- {
- /* remove from cache, move to main store */
- tile_cache_flush (tile);
- }
- tile_active_count ++;
- }
- if (tile->data == NULL)
- {
- /* There is no data, so the tile must be swapped out */
- tile_swap_in (tile);
- }
-
- TILE_MUTEX_UNLOCK (tile);
-
- /* Call 'tile_manager_validate' if the tile was invalid.
- */
- if (!tile->valid)
- {
- /* an invalid tile should never be shared, so this should work */
- tile_manager_validate ((TileManager*) tile->tlink->tm, tile);
- }
-
-
- }
-
-
- void
- tile_release (Tile *tile, int dirty)
- {
- /* Decrement the global reference count.
- */
- tile_ref_count -= 1;
-
- TILE_MUTEX_LOCK(tile);
-
- /* Decrement this tile's reference count.
- */
- tile->ref_count -= 1;
-
- /* Decrement write ref count if dirtying
- */
- if (dirty)
- {
- int y;
-
- tile->write_count -= 1;
-
- if (tile->rowhint)
- {
- for (y = 0; y < tile->eheight; y++)
- {
- tile->rowhint[y] = TILEROWHINT_UNKNOWN;
- }
- }
- }
-
- if (tile->ref_count == 0)
- {
- tile_active_count--;
- if (tile->share_count == 0)
- {
- /* tile is truly 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);
- }
- }
-
- TILE_MUTEX_UNLOCK (tile);
- }
-
- void
- tile_alloc (Tile *tile)
- {
- if (tile->data)
- return;
-
- /* Allocate the data for the tile.
- */
- tile->data = g_new (guchar, tile_size (tile));
-
- #ifdef HINTS_SANITY
- tile_exist_count++;
- if (tile_exist_count > tile_exist_peak)
- tile_exist_peak = tile_exist_count;
- #endif
- }
-
- static void
- tile_destroy (Tile *tile)
- {
- if (tile->ref_count)
- {
- g_warning ("tried to destroy a ref'd tile");
- return;
- }
- if (tile->share_count)
- {
- g_warning ("tried to destroy an attached tile");
- return;
- }
- if (tile->data)
- {
- g_free (tile->data);
- tile->data = NULL;
- }
- if (tile->rowhint)
- {
- g_free (tile->rowhint);
- tile->rowhint = 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);
- tile_count --;
-
- #ifdef HINTS_SANITY
- tile_exist_count--;
- #endif
- }
-
-
- int
- tile_size (Tile *tile)
- {
- int size;
- /* Return the actual size of the tile data.
- * (Based on its effective width and height).
- */
- size = tile->ewidth * tile->eheight * tile->bpp;
- return size;
- }
-
-
- int
- tile_ewidth (Tile *tile)
- {
- return tile->ewidth;
- }
-
-
- int
- tile_eheight (Tile *tile)
- {
- return tile->eheight;
- }
-
-
- int
- tile_bpp (Tile *tile)
- {
- return tile->bpp;
- }
-
-
- int
- tile_is_valid (Tile *tile)
- {
- return tile->valid;
- }
-
-
- void
- tile_mark_valid (Tile *tile)
- {
- TILE_MUTEX_LOCK (tile);
- tile->valid = TRUE;
- TILE_MUTEX_UNLOCK (tile);
- }
-
-
- void
- tile_attach (Tile *tile, void *tm, int tile_num)
- {
- TileLink *tmp;
-
- if ((tile->share_count > 0) && (!tile->valid))
- {
- /* trying to share invalid tiles is problematic, not to mention silly */
- tile_manager_validate ((TileManager*) tile->tlink->tm, tile);
- }
- tile->share_count++;
- tile_share_count++;
- #ifdef TILE_DEBUG
- g_print("tile_attach: %p -> (%p,%d) *%d\n", tile, tm, tile_num, tile->share_count);
- #endif
-
- /* 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) r%d *%d\n", tile, tm, tile_num,
- tile->ref_count, tile->share_count);
- #endif
-
- for (link = &tile->tlink;
- *link != NULL;
- link = &(*link)->next)
- {
- if (((*link)->tm == tm) && ((*link)->tile_num == tile_num))
- break;
- }
-
- if (*link == NULL)
- {
- g_warning ("Tried to detach a nonattached tile -- TILE BUG!");
- return;
- }
-
- tmp = *link;
- *link = tmp->next;
- g_free (tmp);
-
- tile_share_count--;
- tile->share_count--;
-
- if (tile->share_count == 0 && tile->ref_count == 0)
- {
- tile_destroy (tile);
- return;
- }
- TILE_MUTEX_UNLOCK (tile);
- }
-
-
- void *
- tile_data_pointer (Tile *tile, int xoff, int yoff)
- {
- int offset = yoff * tile->ewidth + xoff;
- return (void *)(tile->data + offset * tile->bpp);
- }
-