You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ugui/text_rendering/cache.c

128 lines
2.5 KiB

2 years ago
#define _POSIX_C_SOURCE 200809l
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
2 years ago
#include "cache.h"
2 years ago
#include "hash.h"
#include "font.h"
#include "util.h"
static struct hm_ref *hash_table;
static struct font_glyph cache_array[CACHE_SIZE] = {0};
// bitmap size is aligned to word
// 2^6 == 64 bits, number of bits in a uint64_t
#define _BSIZE (((CACHE_SIZE+0x3f)&(~0x3f))>>6)
2 years ago
static uint64_t bitmap[_BSIZE] = {0};
// bitmap operations
#define B_RESET() for (int i = 0; i < _BSIZE; bitmap[i++] = 0);
#define B_SET(x) bitmap[(x)>>6] |= (uint64_t)1<<((x)%64)
#define B_TEST(x) (bitmap[(x)>>6]&((uint64_t)1<<((x)%64)))
2 years ago
// reset the bitmap every n cycles
#define NCYCLES (CACHE_SIZE/2)
static int cycles = 0;
static inline void set_bit(unsigned int x)
{
// printf("cycles: %d, set: %d\n", cycles, x);
cycles = (cycles+1)%NCYCLES;
if (!cycles) B_RESET();
B_SET(x);
}
void cache_init(void)
{
hash_table = hm_create(CACHE_SIZE);
}
void cache_destroy(void)
{
hm_destroy(hash_table);
}
2 years ago
const struct font_glyph * cache_search(unsigned int code)
2 years ago
{
struct hm_entry *r = hm_search(hash_table, code);
// miss
if (!r)
return NULL;
// hit
set_bit((struct font_glyph *)(r->data)-cache_array);
return (struct font_glyph *)(r->data);
}
2 years ago
// return the first free spot into the cache
unsigned int cache_get(void)
2 years ago
{
uint32_t x = 0;
// find an open spot in the cache
// TODO: use __builtin_clz to speed this up
for (; x < CACHE_SIZE; x++) {
//printf("testing spot %d\n", x);
//print_byte(bitmap[0]>>56);
//print_byte(bitmap[0]>>48);
//print_byte(bitmap[0]>>40);
//print_byte(bitmap[0]>>32);
//print_byte(bitmap[0]>>24);
//print_byte(bitmap[0]>>16);
//print_byte(bitmap[0]>>8);
//print_byte(bitmap[0]);
//printf("%lx", bitmap[i]);
//printf("\n");
2 years ago
if (!B_TEST(x))
break;
}
2 years ago
return x;
}
// inserts the font glyph into the cache
2 years ago
const struct font_glyph * cache_insert(const struct font_glyph *g, unsigned int x)
2 years ago
{
struct font_glyph *spot = NULL;
2 years ago
// allocation in cache failed
if (B_TEST(x))
2 years ago
return NULL;
2 years ago
set_bit(x);
spot = &cache_array[x];
*spot = *g;
/*
for (int i = 0; i < _BSIZE; i++) {
//print_byte(bitmap[i]);
//print_byte(bitmap[i]>>8);
//print_byte(bitmap[i]>>16);
//print_byte(bitmap[i]>>24);
//print_byte(bitmap[i]>>32);
//print_byte(bitmap[i]>>40);
//print_byte(bitmap[i]>>48);
//print_byte(bitmap[i]>>56);
printf("%lx", bitmap[i]);
}
printf("\n");
*/
struct hm_entry e = { .code = g->codepoint, .data = spot};
if (!hm_insert(hash_table, &e))
2 years ago
return NULL;
2 years ago
2 years ago
return spot;
2 years ago
}