File: tile.c

package info (click to toggle)
gimp 1.0.2-3
  • links: PTS
  • area: main
  • in suites: slink
  • size: 17,116 kB
  • ctags: 16,070
  • sloc: ansic: 226,067; lisp: 8,497; sh: 4,965; makefile: 4,543
file content (159 lines) | stat: -rw-r--r-- 3,245 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#include "tile.h"
#include "tile_cache.h"
#include "tile_manager.h"
#include "tile_swap.h"


void
tile_init (Tile *tile,
	   int   bpp)
{
  tile->ref_count = 0;
  tile->dirty = FALSE;
  tile->valid = FALSE;
  tile->ewidth = TILE_WIDTH;
  tile->eheight = TILE_HEIGHT;
  tile->bpp = bpp;
  tile->tile_num = -1;
  tile->data = NULL;
  tile->swap_num = 1;
  tile->swap_offset = -1;
  tile->tm = NULL;
}

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
{
  /*  g_print ("tile_ref:    0x%08x  %s\n", tile, func_name); */

  tile_ref_count += 1;

  /* Increment the reference count.
   */
  tile->ref_count += 1;

  /* 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)
    {
      tile_swap_in (tile);

      /*  the tile must be clean  */
      tile->dirty = FALSE;
    }

  /* 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);

  /* Call 'tile_manager_validate' if the tile was invalid.
   */
  if (!tile->valid)
    tile_manager_validate ((TileManager*) tile->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
{
  /*  g_print ("tile_unref:  0x%08x  %s\n", tile, func_name); */

  tile_ref_count -= 1;

  /* Decrement the reference count.
   */
  tile->ref_count -= 1;

  /* Mark the tile dirty if indicated
   */
  tile->dirty |= dirty;

  /* 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
       */
      else
	{
	  g_free (tile->data);
	  tile->data = NULL;
	}
    }
}

void
tile_alloc (Tile *tile)
{
  if (tile->data)
    return;

  /* Allocate the data for the tile.
   */
  tile->data = g_new (guchar, tile_size (tile));
}

int
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;
}

void
tile_invalidate (Tile *tile)
{
  /* Invalidate the tile. (Must be valid first).
   */
  if (tile->valid)
    {
      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);
	}
    }
}