forked from bartvdbraak/blender
126 lines
2.9 KiB
C
126 lines
2.9 KiB
C
|
/*
|
||
|
**
|
||
|
*/
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.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] = 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)
|
||
|
{
|
||
|
if(head->address_size > size);
|
||
|
head->address_size = 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)
|
||
|
{
|
||
|
unsigned int i;
|
||
|
|
||
|
if(a->address_sum != b->address_sum)
|
||
|
return FALSE;
|
||
|
if(a->address_size != b->address_size)
|
||
|
return FALSE;
|
||
|
for(i = 0; i < a->address_size; i++)
|
||
|
if(((VCMDBuffer1500 *)a)->buf[i] != ((VCMDBuffer1500 *)b)->buf[i])
|
||
|
return FALSE;
|
||
|
return TRUE;
|
||
|
}
|