Small program to quickly test OpenGL GLSL shaders.
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.
 
 
 

146 lines
2.9 KiB

#ifndef UTIL_H
#define UTIL_H
#include <cassert>
#include <cstring>
#include "types.h"
//-----------------
// Hashing
// NOTE: FNV1a hashing algorithm http://www.isthe.com/chongo/tech/comp/fnv/
#define FNV1_64_INIT ((u64) 0xcbf29ce484222325ULL)
#define FNV_64_PRIME ((u64) 0x100000001b3ULL)
u64
utilFNV64a_str(const char *str, u64 hval = FNV1_64_INIT);
//-----------------
// Memory allocation
struct memory_arena
{
size_t max_size;
void* head;
void* next_free;
};
#define DEFAULT_ARENA_SIZE 10 * 1024 * 1024 // 10MB
memory_arena* arenaInit(size_t initial_size = DEFAULT_ARENA_SIZE);
void arenaFree(memory_arena*& arena);
uint arenaGetFreeSize(memory_arena* arena);
#define ARENA_ALLOC(arena, type, count) \
(type*) arenaAllocateBlock(arena, sizeof(type) * count)
void* arenaAllocateBlock(memory_arena* arena, size_t block_size);
#define MAX_NAME_LENGTH 256
char* arenaCopyCStr(memory_arena* arena,
const char* input,
u32 max_len = MAX_NAME_LENGTH);
char* utilAllocateCStr(const char* str, u32 max_len = 256);
void utilSafeFree(void* p);
#endif // UTIL_H
#ifdef UTIL_IMPLEMENTATION
//-----------------
// Hashing
uint64_t
utilFNV64a_str(const char* str, uint64_t hval)
{
unsigned char* s = (unsigned char *)str; // unsigned string
// FNV-1a hash each octet of the string
while (*s) {
// xor the bottom with the current octet
hval ^= (uint64_t)*s++;
// multiply by the 64 bit FNV magic prime mod 2^64
hval *= FNV_64_PRIME;
}
return hval;
}
//-----------------
// Memory allocation
memory_arena*
arenaInit(size_t initial_size)
{
uint sz = sizeof(memory_arena);
memory_arena* arena =
(memory_arena*) std::calloc(initial_size + sz, sizeof(u8));
arena->head = arena->next_free = (uint8_t*) arena + sz;
arena->max_size = initial_size;
return arena;
}
void
arenaFree(memory_arena*& arena)
{
if (arena != nullptr) {
std::free(arena);
arena = nullptr;
}
}
uint
arenaGetFreeSize(memory_arena* arena)
{
return (uint8_t*) arena->head
+ arena->max_size
- (uint8_t*) arena->next_free;
}
void*
arenaAllocateBlock(memory_arena* arena, size_t block_size)
{
// TODO: resizable memory arena
assert(arenaGetFreeSize(arena) >= block_size);
assert(block_size > 0);
void* ret = arena->next_free;
arena->next_free = (uint8_t*) arena->next_free + block_size;
return ret;
}
char*
arenaCopyCStr(memory_arena* arena, const char* input, u32 max_len)
{
u32 name_len = std::strlen(input) + 1;
assert(name_len < max_len);
char* out = ARENA_ALLOC(arena, char, name_len);
std::strncpy(out, input, name_len);
return out;
}
char*
utilAllocateCStr(const char* str, u32 max_len)
{
u32 len = strlen(str) + 1;
if (len > max_len) {
printf("%s(), %s , longer than %i\n", __FUNCTION__, str, max_len);
return nullptr;
}
char* out = (char*) std::calloc(len, sizeof(u8));
strncpy(out, str, len - 1);
return out;
}
void
utilSafeFree(void* p)
{
assert(p != nullptr);
free(p);
}
#endif