forked from bartvdbraak/blender
120 lines
2.8 KiB
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;
|
|
}
|