Beispiel #1
0
void _sort_rects(DArray rects_in) {
	assert(rects_in.size > 1);

	// Insertion sort for small buffers
	if(rects_in.size <= 8) {
		_insertion_sort(rects_in);
		return;
	}

	// Assure out buffer is big enough
	rects_out.size = 0;
	if(rects_out.reserved < rects_in.size)
		darray_reserve(&rects_out, MAX(rects_in.size, rects_out.reserved*2));

	assert(rects_out.reserved >= rects_in.size);
	assert(rects_out.item_size == rects_in.item_size);

	TexturedRectDesc* r_in = DARRAY_DATA_PTR(rects_in, TexturedRectDesc);
	TexturedRectDesc* r_out = DARRAY_DATA_PTR(rects_out, TexturedRectDesc);

	uint i, unique_textures = 0, switches = 0;
	memset(radix_counts, 0, sizeof(radix_counts));

	// If there is more than 255 textures our simple count sort won't work
	assert(textures.size < 256);

	// Calculate histogram, unsorted texture switches, unique textures
	for(i = 0; i < rects_in.size; ++i) {
		size_t idx = r_in[i].tex & 0xFF;
		radix_counts[idx]++;
		if (radix_counts[idx] == 1)
			unique_textures++;
		if(i > 0 && r_in[i].tex != r_in[i-1].tex)
			switches++;
	}

	// Don't bother sorting if it wouldn't decrease batch count
	if(unique_textures < 3 || unique_textures == switches)
		return;

	// Convert histogram to start indices
	for(i = 1; i < 256; ++i)
		radix_counts[i] = radix_counts[i-1] + radix_counts[i];

	// Count sort (single pass of radix sort - texture amount is not a large
	// number)
	uint r0 = 0;
	for(i = 0; i < rects_in.size; ++i) {
		size_t idx = r_in[i].tex & 0xFF;
		uint* dest = idx ? &radix_counts[idx-1] : &r0;
		r_out[(*dest)++] = r_in[i];
	}

	memcpy(r_in, r_out, rects_in.size * rects_in.item_size);
}
Beispiel #2
0
// Allocates new node in node pool
NodeIdx _alloc_node(MMLObject* mml) {
	assert(mml);

	if(mml->node_pool.size + 1 <= mml->node_pool.reserved)
		goto end;

	uint new_size = (mml->node_pool.size * 3) / 2;
	darray_reserve(&(mml->node_pool), new_size);

end:
	return mml->node_pool.size++;
}
Beispiel #3
0
// Allocates new string in string pool
StrIdx _alloc_str(MMLObject* mml, uint length) {
	assert(mml);
	assert(length);
	
	uint new_size, req_size = mml->str_pool.size + length;
	if(req_size <= mml->str_pool.reserved)
		goto end;

	new_size = mml->str_pool.size;
	do {
		new_size = (new_size * 3) / 2;
	} while(new_size <= req_size);

	darray_reserve(&(mml->str_pool), new_size);

end:
	mml->str_pool.size += length;
	return mml->str_pool.size - length;
}