Browse Source

Add more bank procedures

master
cancel 6 years ago
parent
commit
7636f011e4
  1. 17
      bank.c
  2. 46
      bank.h
  3. 32
      base.h

17
bank.c

@ -5,6 +5,19 @@ void bank_init(Bank* bank) {
bank->capacity = 0; bank->capacity = 0;
} }
void bank_deinit(Bank* bank) { void bank_deinit(Bank* bank) { free(bank->data); }
free(bank->data);
void bank_enlarge_to(Bank* bank, Usz bytes) {
Usz new_cap = orca_round_up_power2(bytes);
bank->data = realloc(bank->data, new_cap);
bank->capacity = new_cap;
}
void bank_reserve(Bank* bank, Usz entries, Usz avg_count) {
Usz avg_size = bank_entry_size(avg_count);
Usz total_bytes = entries * avg_size;
if (bank->capacity < total_bytes) {
Usz new_cap = orca_round_up_power2(total_bytes);
bank->data = realloc(bank->data, new_cap);
}
} }

46
bank.h

@ -10,7 +10,51 @@ typedef struct {
Usz capacity; Usz capacity;
} Bank; } Bank;
typedef char* Bank_cursor; typedef size_t Bank_cursor;
#define ORCA_BANK_GRID_INDEX_MAX UINT32_MAX
#define ORCA_BANK_ENTRY_GLYPHS_MAX UINT8_MAX
#define ORCA_BANK_ENTRY_HEADER (sizeof(U32) + sizeof(U8))
#define ORCA_BANK_ENTRY_ALIGN sizeof(Bank_entry)
void bank_init(Bank* bank); void bank_init(Bank* bank);
void bank_deinit(Bank* bank); void bank_deinit(Bank* bank);
void bank_enlarge_to(Bank* bank, Usz bytes);
void bank_reserve_average(Bank* bank, Usz num_entries, Usz avg_glyph_count);
static inline Usz bank_append(Bank* restrict bank, Usz cur_size, Usz grid_index,
Glyph* restrict glyphs, Usz glyph_count);
ORCA_FORCE_STATIC_INLINE
Usz bank_entry_padding(Usz glyph_count) {
return ORCA_BANK_ENTRY_ALIGN -
(ORCA_BANK_ENTRY_HEADER + glyph_count) % ORCA_BANK_ENTRY_ALIGN;
}
ORCA_FORCE_STATIC_INLINE
Usz bank_entry_size(Usz glyph_count) {
return ORCA_BANK_ENTRY_HEADER + bank_entry_padding(glyph_count);
}
static inline Usz bank_append(Bank* restrict bank, Usz cur_size, Usz grid_index,
Glyph* restrict glyphs, Usz glyph_count) {
assert(grid_index <= ORCA_BANK_GRID_INDEX_MAX);
assert(glyph_count <= ORCA_BANK_ENTRY_GLYPHS_MAX);
// no overflow check
Usz new_size = cur_size + bank_entry_size(glyph_count);
if (new_size > bank->capacity)
bank_enlarge_to(bank, new_size);
char* data = bank->data;
{
Bank_entry* entry =
(Bank_entry*)ORCA_ASSUME_ALIGNED(data, ORCA_BANK_ENTRY_ALIGN);
entry->grid_index = (U32)grid_index;
entry->size = (U8)glyph_count;
}
data += ORCA_BANK_ENTRY_HEADER;
memcpy(data, glyphs, glyph_count);
#ifndef NDEBUG
Usz padding = bank_entry_padding(glyph_count);
memset(data + glyph_count, 0x1c, padding);
#endif
return new_size;
}

32
base.h

@ -10,10 +10,28 @@
#if defined(__GNUC__) || defined(__clang__) #if defined(__GNUC__) || defined(__clang__)
#define ORCA_FORCE_INLINE __attribute__((always_inline)) inline #define ORCA_FORCE_INLINE __attribute__((always_inline)) inline
#define ORCA_FORCE_STATIC_INLINE __attribute__((always_inline)) static inline
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
#define ORCA_FORCE_INLINE __forceinline #define ORCA_FORCE_INLINE __forceinline
#define ORCA_FORCE_STATIC_INLINE __forceinline static
#else #else
#define ORCA_FORCE_INLINE inline #define ORCA_FORCE_INLINE inline
#define ORCA_FORCE_STATIC_INLINE inline static
#endif
#if defined(__GNUC__) || defined(__clang__)
#define ORCA_FORCE_NO_INLINE __attribute__((noinline))
#elif defined(_MSC_VER)
#define ORCA_FORCE_NO_INLINE __declspec(noinline)
#else
#define ORCA_FORCE_NO_INLINE
#endif
#if defined(__GNUC__) || defined(__clang__)
#define ORCA_ASSUME_ALIGNED(_ptr, _alignment) \
__builtin_assume_aligned(_ptr, _alignment)
#else
#define ORCA_ASSUME_ALIGNED(_ptr, _alignment) (_ptr)
#endif #endif
#define ORCA_Y_MAX UINT16_MAX #define ORCA_Y_MAX UINT16_MAX
@ -39,3 +57,17 @@ typedef struct {
U16 height; U16 height;
U16 width; U16 width;
} Field; } Field;
ORCA_FORCE_STATIC_INLINE Usz orca_round_up_power2(Usz x) {
assert(x <= SIZE_MAX / 2 + 1);
x -= 1;
x |= (x >> 1);
x |= (x >> 2);
x |= (x >> 4);
x |= (x >> 8);
x |= (x >> 16);
#if SIZE_MAX > UINT32_MAX
x |= (x >> 32);
#endif
return x + 1;
}

Loading…
Cancel
Save