1 #ifndef ASSTORAGE_H_HEADER_INCLUDED 2 #define ASSTORAGE_H_HEADER_INCLUDED 3 4 5 #define AS_STORAGE_PAGE_SIZE 4096 6 7 /* 8 * there could be up to 16 arrays of 1024 pointers to slots each in Storage Block 9 * There could be 2^18 StorageBlocks in ASStorage 10 */ 11 #define AS_STORAGE_SLOTS_BATCH 1024 /* we allocate pointers to slots in batches of one page eache */ 12 #define AS_STORAGE_SLOT_ID_BITS 14 /* 32*512 == 2^14 */ 13 #define AS_STORAGE_MAX_SLOTS_CNT (0x01<<AS_STORAGE_SLOT_ID_BITS) 14 15 #define AS_STORAGE_BLOCK_ID_BITS (32-AS_STORAGE_SLOT_ID_BITS) 16 #define AS_STORAGE_MAX_BLOCK_CNT (0x01<<AS_STORAGE_BLOCK_ID_BITS) 17 /* #define AS_STORAGE_DEF_BLOCK_SIZE (1024*256) */ 18 #define AS_STORAGE_DEF_BLOCK_SIZE (1024*128) /* 128 Kb */ 19 #define AS_STORAGE_NOUSE_THRESHOLD (1024*8) /* 8 Kb if total_free < 8K we should not try and use that 20 * block as we may fall into trap constantly defragmenting it 21 * so we prefer to leave memory unused since 2 pages is not too much to loose */ 22 23 24 #define ASStorageSlot_SIZE 16 /* 16 bytes */ 25 #define ASStorageSlot_USABLE_SIZE(slot) (((slot)->size+15)&0x8FFFFFF0) 26 #define ASStorageSlot_FULL_SIZE(slot) (ASStorageSlot_USABLE_SIZE(slot)+ASStorageSlot_SIZE) 27 /* space for slots is allocated in 16 byte increments */ 28 #define AS_STORAGE_GetNextSlot(slot) ((slot)+1+(ASStorageSlot_USABLE_SIZE(slot)>>4)) 29 30 31 /* RLE encoding of difference 32 * We calculate difference between following bytes. If differece is zero - its RLE encoded. 33 * If its +-1 - its encoded as 2 bit values 34 * If Its +-(from 2 to 7) - its encoded using 4 bit values 35 * If Its +-(from 8 to 127) - its encoded using 8 bit values 36 * If Its +-(from 128 to 255) - its encoded using 9 bit values 37 * 38 * The hope is that most of the bytes will be reduced to 0 39 * The next likely value will be from 2 to 7 40 * and only few cases will fall in other categories 41 * 42 * For bitmaps we store lengths of ones and zerous, assuming that each string tsarts with 0 43 * 44 * */ 45 46 /* The following lines is used only for non-bitmaps : */ 47 #define RLE_ZERO_MASK 0x0080 /* M */ 48 #define RLE_ZERO_LENGTH 0x007F /* LLLLLLL */ 49 #define RLE_ZERO_SIG 0x0000 /* 0LLLLLLL - identical to a string of LLLLLLL zeros */ 50 51 #define RLE_NOZERO_SHORT_MASK 0x00C0 /* MM */ 52 #define RLE_NOZERO_SHORT_LENGTH 0x003F /* LLLLLL */ 53 #define RLE_NOZERO_SHORT_SIG 0x00C0 /* 11LLLLLL followed by stream of LLLLLL 4 or 2 bit values */ 54 55 #define RLE_NOZERO_LONG_MASK 0x00F0 /* MMMM */ 56 #define RLE_NOZERO_LONG_LENGTH 0x000F /* LLLL */ 57 #define RLE_NOZERO_LONG1_SIG 0x00A0 /* 1010LLLL followed by stream of LLLL 2 or 4 bit values */ 58 #define RLE_NOZERO_LONG2_SIG 0x00B0 /* 1011LLLL followed by stream of LLLL 1 byte values */ 59 60 #define RLE_9BIT_SIG 0x0080 /* 1000LLLL followed by stream of LLLL 1 byte values 61 that change sign from byte to byte starting with positive */ 62 #define RLE_9BIT_NEG_SIG 0x0090 /* 1001LLLL followed by stream of LLLL 1 byte values 63 that change sign from byte to byte starting with negative */ 64 65 #define AS_STORAGE_DEFAULT_BMAP_THRESHOLD 0x7F 66 #define AS_STORAGE_DEFAULT_BMAP_VALUE 0xFF 67 68 69 typedef struct ASStorageSlot 70 { 71 /* Pointer to ASStorageSlot is the pointer to used memory beginning - ASStorageSlot_SIZE 72 * thus we need not to store it separately 73 */ 74 #define ASStorage_ZlibCompress (0x01<<0) /* do we really want that ? */ 75 #define ASStorage_RLEDiffCompress (0x01<<1) /* RLE of difference */ 76 77 #define ASStorage_CompressionType (0x0F<<0) /* allow for 16 compression schemes */ 78 #define ASStorage_Used (0x01<<4) 79 #define ASStorage_NotTileable (0x01<<5) 80 #define ASStorage_Reference (0x01<<6) /* data is the id of some other slot */ 81 #define ASStorage_Bitmap (0x01<<7) /* data is 1 bpp */ 82 #define ASStorage_32Bit (0x01<<8) /* data is 32 bpp with only first 8 bits being significant */ 83 #define ASStorage_BitShiftFlagPos 9 84 #define ASStorage_BitShift (0x03<<ASStorage_BitShiftFlagPos) 85 #define ASStorage_8BitShift (0x01<<ASStorage_BitShiftFlagPos) 86 /* data is 32 bpp shifted left by 8 bit 87 * (must combine with _32Bit flag )*/ 88 #define ASStorage_16BitShift (0x01<<(ASStorage_BitShiftFlagPos+1)) 89 /* data is 32 bpp shifted left by 16 bit 90 * (must combine with _32Bit flag ) 91 * If combined with 8BitShift - results in 24 bit shift */ 92 #define ASStorage_24BitShift (ASStorage_8BitShift|ASStorage_16BitShift) 93 #define ASStorage_Flags2ShiftIdx(f) (((f)>>ASStorage_BitShiftFlagPos)&0x03) 94 #define ASStorage_Flags2Shift(f) (ASStorage_Flags2ShiftIdx(f)*8) 95 #define ASStorage_Masked (0x01<<11) /* mask 32bit value to filter out higher 24 bits 96 * if combined with BitShift - bitshift is done 97 * prior to masking */ 98 99 100 #define ASStorage_32BitRLE (ASStorage_RLEDiffCompress|ASStorage_32Bit) 101 102 CARD16 flags ; 103 CARD16 ref_count ; 104 CARD32 size ; 105 CARD32 uncompressed_size ; 106 CARD16 index ; /* reverse mapping of slot address into index in array */ 107 /* slots may be placed in array pointing into different areas of the memory 108 * block, since we will need to implement some sort of garbadge collection and 109 * defragmentation mechanism - we need to be able to process them in orderly 110 * fashion. 111 * So finally : 112 * 1) slot's index does not specify where in the memory slot 113 * is located, it is only used to address slot from outside. 114 * 2) Using slots memory address and its size we can go through the chain of slots 115 * and perform all the maintenance tasks as long as we have reverse mapping 116 * of addresses into indexes. 117 * 118 */ 119 CARD16 reserved ; /* to make us have size rounded by 16 bytes margin */ 120 /* Data immidiately follows here : 121 * CARD8 data[0] ; */ 122 123 #define ASStorage_Data(s) ((CARD8*)((s)+1)) 124 125 }ASStorageSlot; 126 127 /* turns out there is no performance gains from using int here instead of short - 128 so save some memory if we can : */ 129 typedef short ASStorageDiff; 130 131 132 typedef void (*compute_diff_func_type)(ASStorageDiff*,CARD8*,int); 133 typedef int (*copy_data32_func_type)(CARD8*,CARD32*,int); 134 typedef int (*copy_data32_tinted_func_type)(CARD8*,CARD32*,int,CARD32); 135 136 137 typedef struct ASStorageBlock 138 { 139 #define ASStorage_MonoliticBlock (0x01<<0) /* block consists of a single batch of storage */ 140 CARD32 flags ; 141 int size ; 142 143 int total_free; 144 ASStorageSlot *start, *end; 145 /* array of pointers to slots is allocated separately, so that we can reallocate it 146 in case we have lots of small slots */ 147 ASStorageSlot **slots; 148 int slots_count, unused_count ; 149 int first_free, last_used ; 150 int long_searches ; 151 152 }ASStorageBlock; 153 154 typedef struct ASStorage 155 { 156 int default_block_size ; 157 158 159 ASStorageBlock **blocks ; 160 int blocks_count; 161 162 ASStorageDiff *diff_buf ; 163 CARD8 *comp_buf ; 164 size_t comp_buf_size ; 165 166 }ASStorage; 167 168 169 typedef CARD32 ASStorageID ; 170 171 ASStorageID store_data(ASStorage *storage, CARD8 *data, int size, ASFlagType flags, CARD8 bitmap_threshold); 172 ASStorageID store_data_tinted(ASStorage *storage, CARD8 *data, int size, ASFlagType flags, CARD16 tint); 173 174 /* data will be fetched fromthe slot identified by id and placed into buffer. 175 * Data will be fetched from offset and will count buf_size bytes if buf_size is greater then 176 * available data - data will be tiled to accomodate this size, unless NotTileable is set */ 177 int fetch_data(ASStorage *storage, ASStorageID id, CARD8 *buffer, int offset, int buf_size, CARD8 bitmap_value, int *original_size); 178 int fetch_data32(ASStorage *storage, ASStorageID id, CARD32 *buffer, int offset, int buf_size, CARD8 bitmap_value, int *original_size); 179 int threshold_stored_data(ASStorage *storage, ASStorageID id, unsigned int *runs, int width, unsigned int threshold); 180 181 /* slot identified by id will be marked as unused */ 182 void forget_data(ASStorage *storage, ASStorageID id); 183 184 void print_storage(ASStorage *storage); 185 186 int print_storage_slot(ASStorage *storage, ASStorageID id); 187 Bool query_storage_slot(ASStorage *storage, ASStorageID id, ASStorageSlot *dst ); 188 189 /* returns new ID without copying data. Data will be stored as copy-on-right. 190 * Reference count of the data will be increased. If optional dst_id is specified - 191 * its data will be erased, and it will point to the data of src_id: 192 */ 193 ASStorageID dup_data(ASStorage *storage, ASStorageID src_id); 194 195 /* this will provide access to default storage heap that is used whenever above functions get 196 * NULL passed as ASStorage parameter : 197 */ 198 void flush_default_asstorage(); 199 int set_asstorage_block_size( ASStorage *storage, int new_size ); 200 201 202 #endif 203