xref: /plan9/sys/src/cmd/gs/src/gxbcache.h (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 1995, 1996 Aladdin Enterprises.  All rights reserved.
2 
3   This software is provided AS-IS with no warranty, either express or
4   implied.
5 
6   This software is distributed under license and may not be copied,
7   modified or distributed except as expressly authorized under the terms
8   of the license contained in the file LICENSE in this distribution.
9 
10   For more information about licensing, please refer to
11   http://www.ghostscript.com/licensing/. For information on
12   commercial licensing, go to http://www.artifex.com/licensing/ or
13   contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14   San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15 */
16 
17 /* $Id: gxbcache.h,v 1.5 2002/06/16 08:45:43 lpd Exp $ */
18 /* Bitmap cache structures */
19 
20 #ifndef gxbcache_INCLUDED
21 #  define gxbcache_INCLUDED
22 
23 #include "gxbitmap.h"
24 
25 /*
26  * These structures are superclasses for a cache in which the 'value' is
27  * a bitmap.  The structures defined here don't take any position about
28  * the nature of the 'key'.
29  */
30 
31 /* ---------------- Bitmap cache entry ---------------- */
32 
33 /*
34  * The cache may contain both used and free blocks.
35  * All blocks have a common header; free blocks have ONLY the header.
36  */
37 typedef struct gx_cached_bits_head_s {
38     uint size;			/* total block size in bytes */
39     uint depth;			/* bits per pixel, free block if 0 */
40 } gx_cached_bits_head;
41 
42 #define cb_head_is_free(cbh) ((cbh)->depth == 0)
43 #define cb_head_set_free(cbh) ((cbh)->depth = 0)
44 #define gx_cached_bits_common\
45 	gx_cached_bits_head head;	/* must be first */\
46 		/* The rest of the entry is an abbreviation of */\
47 		/* gx_strip_bitmap, sans data. */\
48 	ushort width, height, shift;\
49 	ushort raster;\
50 	gx_bitmap_id id
51 /* Define aliases for head members. */
52 #define cb_depth head.depth
53 /* Define aliases for common members formerly in the head. */
54 #define cb_raster raster
55 typedef struct gx_cached_bits_s {
56     gx_cached_bits_common;
57 } gx_cached_bits;
58 
59 #define cb_is_free(cb) cb_head_is_free(&(cb)->head)
60 /*
61  * Define the alignment of the gx_cached_bits structure.  We must ensure
62  * that an immediately following bitmap will be properly aligned.
63  */
64 #define align_cached_bits_mod\
65   (max(align_bitmap_mod, max(arch_align_ptr_mod, arch_align_long_mod)))
66 
67 /*
68  * We may allocate a bitmap cache in chunks, so as not to tie up memory
69  * prematurely if it isn't needed (or something else needs it more).
70  * Thus there is a structure for managing an entire cache, and another
71  * structure for managing each chunk.
72  */
73 typedef struct gx_bits_cache_chunk_s gx_bits_cache_chunk;
74 struct gx_bits_cache_chunk_s {
75     gx_bits_cache_chunk *next;
76     byte *data;			/* gx_cached_bits_head * */
77     uint size;
78     uint allocated;		/* amount of allocated data */
79 };
80 
81 /* ---------------- Bitmap cache ---------------- */
82 
83 #define gx_bits_cache_common\
84 	gx_bits_cache_chunk *chunks;	/* current chunk in circular list */\
85 	uint cnext;			/* rover for allocating entries */\
86 					/* in current chunk */\
87 	uint bsize;			/* total # of bytes for all entries */\
88 	uint csize		/* # of entries */
89 typedef struct gx_bits_cache_s {
90     gx_bits_cache_common;
91 } gx_bits_cache;
92 
93 /* ---------------- Procedural interface ---------------- */
94 
95 /* ------ Entire cache ------ */
96 
97 /* Initialize a cache.  The caller must allocate and initialize */
98 /* the first chunk. */
99 void gx_bits_cache_init(gx_bits_cache *, gx_bits_cache_chunk *);
100 
101 /* ------ Chunks ------ */
102 
103 /* Initialize a chunk.  The caller must allocate it and its data. */
104 void gx_bits_cache_chunk_init(gx_bits_cache_chunk *, byte *, uint);
105 
106 /* ------ Individual entries ------ */
107 
108 /* Attempt to allocate an entry.  If successful, set *pcbh and return 0. */
109 /* If there isn't enough room, set *pcbh to an entry requiring freeing, */
110 /* or to 0 if we are at the end of the chunk, and return -1. */
111 int gx_bits_cache_alloc(gx_bits_cache *, ulong, gx_cached_bits_head **);
112 
113 /* Shorten an entry by a given amount. */
114 void gx_bits_cache_shorten(gx_bits_cache *, gx_cached_bits_head *,
115 			   uint, gx_bits_cache_chunk *);
116 
117 /* Free an entry.  The caller is responsible for removing the entry */
118 /* from any other structures (like a hash table). */
119 void gx_bits_cache_free(gx_bits_cache *, gx_cached_bits_head *,
120 			gx_bits_cache_chunk *);
121 
122 #endif /* gxbcache_INCLUDED */
123