blender/extern/verse/dist/v_cmd_buf.c

120 lines
2.8 KiB
C

/*
**
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "verse_header.h"
#include "v_pack.h"
#include "v_cmd_buf.h"
static const size_t vcmdbuf_chunk_size[] = { 10000, 10000, 10000, 10000, 8000, 5000, 500 }; /* If you think memory is cheap, set this to a high value. */
/* Sizes of individual command buffers, indexable by VCMDBufSize values. Switch-killer. */
static const size_t vcmdbuf_size[] = {
sizeof (VCMDBuffer10), sizeof (VCMDBuffer20), sizeof (VCMDBuffer30), sizeof (VCMDBuffer80),
sizeof (VCMDBuffer160), sizeof (VCMDBuffer320), sizeof (VCMDBuffer1500)
};
#define VCMDBUF_INIT_CHUNK_FACTOR 0.5
static struct {
VCMDBufHead *buffers[VCMDBS_COUNT];
unsigned int available[VCMDBS_COUNT];
} VCMDBufData;
static boolean v_cmd_buf_initialized = FALSE;
void cmd_buf_init(void)
{
unsigned int i, j;
VCMDBufHead *buf, *b;
for(i = 0; i < VCMDBS_COUNT; i++)
{
VCMDBufData.buffers[i] = NULL;
VCMDBufData.available[i] = (unsigned int) (vcmdbuf_chunk_size[i] * VCMDBUF_INIT_CHUNK_FACTOR);
for(j = 0, buf = NULL; j < VCMDBufData.available[i]; j++, buf = b)
{
b = v_cmd_buf_allocate(i);
b->next = buf;
}
VCMDBufData.buffers[i] = buf;
}
v_cmd_buf_initialized = TRUE;
}
VCMDBufHead * v_cmd_buf_allocate(VCMDBufSize buf_size)
{
VCMDBufHead *output = NULL;
if(VCMDBufData.buffers[buf_size] != NULL)
{
output = VCMDBufData.buffers[buf_size];
VCMDBufData.buffers[buf_size] = output->next;
VCMDBufData.available[buf_size]--;
}
else
{
if(buf_size < sizeof vcmdbuf_size / sizeof *vcmdbuf_size)
output = malloc(vcmdbuf_size[buf_size]);
else
{
fprintf(stderr, "v_cmd_buf.c: Can't handle buffer size %d\n", buf_size);
return NULL;
}
output->buf_size = buf_size;
}
output->next = NULL;
output->packet = 0;
output->size = 0;
output->address_size = -1;
return output;
}
void v_cmd_buf_free(VCMDBufHead *head)
{
if(VCMDBufData.available[head->buf_size] < vcmdbuf_chunk_size[head->buf_size])
{
head->next = VCMDBufData.buffers[head->buf_size];
VCMDBufData.buffers[head->buf_size] = head;
VCMDBufData.available[head->buf_size]++;
}
else
free(head);
}
void v_cmd_buf_set_size(VCMDBufHead *head, unsigned int size)
{
head->size = size;
}
void v_cmd_buf_set_address_size(VCMDBufHead *head, unsigned int size)
{
unsigned int i;
head->address_size = size;
head->address_sum = 0;
for(i = 1; i < size + 1; i++)
head->address_sum += i * i * (uint32)(((VCMDBuffer1500 *)head)->buf[i - 1]);
}
void v_cmd_buf_set_unique_address_size(VCMDBufHead *head, unsigned int size)
{
static unsigned int i = 0;
head->address_size = size;
head->address_sum = i++;
}
boolean v_cmd_buf_compare(VCMDBufHead *a, VCMDBufHead *b)
{
if(a->address_sum != b->address_sum)
return FALSE;
if(a->address_size != b->address_size)
return FALSE;
return memcmp(((VCMDBuffer1500 *)a)->buf, ((VCMDBuffer1500 *)b)->buf, a->address_size) == 0;
}