GFXMeshBuffer gfx_mesh_add_buffer( GFXMesh* mesh, size_t size, const void* data) { GFX_Mesh* internal = (GFX_Mesh*)mesh; /* Insert new vector element */ GFXSharedBuffer* it = gfx_vector_insert( &internal->buffers, NULL, internal->buffers.end ); if(it == internal->buffers.end) return 0; /* Create new shared buffer */ /* Align with largest integer so index offset can be aligned */ GFXDataType type; type.unpacked = GFX_LARGE_INTEGER; if(!gfx_shared_buffer_init_align(it, size, data, type)) { gfx_vector_erase(&internal->buffers, it); return 0; } /* Return ID */ return gfx_vector_get_size(&internal->buffers); }
static void _gfx_mesh_shrink_buckets( GFX_Mesh* mesh, unsigned int level) { /* Size will be smaller than the actual stored size in buckets */ /* As this is only allowed to be called when the lod map is smaller */ size_t size = _gfx_mesh_bucket_size((GFXMesh*)mesh, UINT_MAX); size_t total = gfx_vector_get_size(&mesh->buckets); /* Remove the source from all buckets */ size_t ind = _gfx_mesh_bucket_size((GFXMesh*)mesh, level + 1); while(ind < total) { gfx_vector_erase_range_at( &mesh->buckets, sizeof(GFXBucketSource), ind ); total -= sizeof(GFXBucketSource); ind += size; } }
static int _gfx_mesh_expand_buckets( GFX_Mesh* mesh, unsigned int level) { size_t size = _gfx_mesh_bucket_size((GFXMesh*)mesh, UINT_MAX); size_t total = gfx_vector_get_size(&mesh->buckets); /* First reserve some memory */ /* Size cannot be zero, so no worries */ if(!gfx_vector_reserve( &mesh->buckets, total + (total / size) * sizeof(GFXBucketSource))) { return 0; } /* Append an empty source to all buckets */ GFXBucketSource insert = 0; size_t ind = _gfx_mesh_bucket_size((GFXMesh*)mesh, level + 1); while(total) { total -= size; gfx_vector_insert_range_at( &mesh->buckets, sizeof(GFXBucketSource), &insert, total + ind ); } return 1; }
void gfx_mesh_free( GFXMesh* mesh) { if(mesh) { GFX_Mesh* internal = (GFX_Mesh*)mesh; /* Remove all buckets */ size_t size = _gfx_mesh_bucket_size(mesh, UINT_MAX); size_t total = gfx_vector_get_size(&internal->buckets); while(total) { total -= size; _gfx_mesh_erase_bucket( internal, gfx_vector_at(&internal->buckets, total), size ); } /* Free all layouts */ GFXVectorIterator it; for( it = internal->layouts.begin; it != internal->layouts.end; it = gfx_vector_next(&internal->layouts, it)) { gfx_vertex_layout_free(*(GFXVertexLayout**)it); } /* Clear all shared buffers */ for( it = internal->buffers.begin; it != internal->buffers.end; it = gfx_vector_next(&internal->buffers, it)) { gfx_shared_buffer_clear((GFXSharedBuffer*)it, 1); } /* Free everything */ gfx_vector_clear(&internal->layouts); gfx_vector_clear(&internal->buckets); gfx_vector_clear(&internal->buffers); _gfx_lod_map_clear((GFX_LodMap*)internal); free(mesh); } }
static GFX_Task _gfx_thread_pool_pop( GFX_Pool* pool) { GFX_Task* et = pool->tasks.begin; GFX_Task ret = *et; /* Override root and remove element */ size_t size = gfx_vector_get_size(&pool->tasks) - 1; *et = *(GFX_Task*)gfx_vector_at(&pool->tasks, size); gfx_vector_erase_at(&pool->tasks, size); /* Heapify the root */ size_t elem = 0; while(1) { GFX_Task* bt = et; size_t b = elem; /* Get child with largest priority */ size_t l = (elem << 1) + 1; size_t r = (elem << 1) + 2; GFX_Task* lt = gfx_vector_at(&pool->tasks, l); GFX_Task* rt = gfx_vector_at(&pool->tasks, r); if(l < size && lt->priority < bt->priority) bt = lt, b = l; if(r < size && rt->priority < bt->priority) bt = rt, b = r; if(b == elem) break; /* Swap */ GFX_Task temp = *bt; *bt = *et; *et = temp; elem = b; et = bt; } return ret; }
static size_t _gfx_x11_init_modes( Screen* scr, XRRScreenResources* res) { /* Split depth */ GFXColorDepth depth; _gfx_split_depth( XDefaultDepthOfScreen(scr), &depth.redBits, &depth.greenBits, &depth.blueBits ); /* Reserve space for all modes */ size_t first = gfx_vector_get_size(&_gfx_x11.modes); gfx_vector_reserve(&_gfx_x11.modes, first + res->nmode); unsigned int i; for(i = 0; i < res->nmode; ++i) { /* Skip refresh rate of zero */ unsigned int refresh = 0; if(res->modes[i].hTotal && res->modes[i].vTotal) { refresh = (unsigned int)lround((double)res->modes[i].dotClock / ((double)res->modes[i].hTotal * (double)res->modes[i].vTotal)); } if(refresh) { /* Create new mode */ GFX_X11_Mode mode; mode.id = res->modes[i].id; mode.mode.width = res->modes[i].width; mode.mode.height = res->modes[i].height; mode.mode.depth = depth; mode.mode.refresh = refresh; gfx_vector_insert(&_gfx_x11.modes, &mode, _gfx_x11.modes.end); } } return first; }
static GFXMeshLayout _gfx_mesh_insert_layout( GFX_Mesh* mesh, GFXVertexLayout* layout) { GFXVectorIterator it = gfx_vector_insert( &mesh->layouts, &layout, mesh->layouts.end ); if(it == mesh->layouts.end) { /* Free on failure */ gfx_vertex_layout_free(layout); return 0; } /* Return the ID */ return gfx_vector_get_size(&mesh->layouts); }
static int _gfx_thread_pool_push( GFX_Pool* pool, GFX_Task task) { /* Insert the new element */ size_t elem = gfx_vector_get_size(&pool->tasks); GFX_Task* et = gfx_vector_insert( &pool->tasks, &task, pool->tasks.end ); if(et == pool->tasks.end) return 0; /* Correct heap again */ while(elem > 0) { /* Get parent and compare */ size_t parent = (elem - 1) >> 1; GFX_Task* pt = gfx_vector_at(&pool->tasks, parent); if(pt->priority <= et->priority) break; /* Swap */ task = *pt; *pt = *et; *et = task; elem = parent; } return 1; }
int gfx_lod_map_add( GFXLodMap* map, unsigned int level, void* data) { GFX_LodMap* internal = (GFX_LodMap*)map; /* Overflow */ size_t size = gfx_vector_get_size(&internal->data); if(level > map->levels || size == UINT_MAX) return 0; /* Get level iterator */ GFXVectorIterator levIt; if(level == map->levels) { /* Insert the level if it doesn't exist yet */ unsigned int upper = size; levIt = gfx_vector_insert( &internal->levels, &upper, internal->levels.end ); if(levIt == internal->levels.end) return 0; ++map->levels; } else { /* Check single data flag */ if(map->flags & GFX_LOD_SINGLE_DATA) return 0; levIt = gfx_vector_at(&internal->levels, level); } /* Get boundaries */ unsigned int begin; unsigned int end; _gfx_lod_map_get_boundaries( internal, levIt, &begin, &end ); /* Insert the data */ GFXVectorIterator it = gfx_vector_insert_at( &internal->data, data, end ); if(it == internal->data.end) { if(begin == end) { gfx_vector_erase(&internal->levels, levIt); --map->levels; } return 0; } /* Increase upper bounds */ while(levIt != internal->levels.end) { ++(*(unsigned int*)levIt); levIt = gfx_vector_next(&internal->levels, levIt); } return 1; }