+ size_t offset = block.offset;
+ if(type!=block.type && block.prev>=0 && type!=blocks[block.prev].type)
+ {
+ offset += buffer_image_granularity-1;
+ offset -= offset%buffer_image_granularity;
+ }
+
+ offset += align-1;
+ offset -= offset%align;
+
+ if(type==BUFFER)
+ {
+ size_t offset2 = block.offset+block.size-size;
+ offset2 -= offset2%align;
+ offset = max(offset, offset2);
+ }
+
+ return offset-block.offset;
+}
+
+void MemoryAllocator::update_largest_free(Pool &pool)
+{
+ for(auto i=pool.free_blocks.end(); ((pool.largest_free_buffer<0 || pool.largest_free_image<0) && i!=pool.free_blocks.begin()); )
+ {
+ --i;
+ if(pool.largest_free_buffer<0 && (blocks[*i].type==BUFFER || blocks[*i].type==UNDECIDED))
+ pool.largest_free_buffer = *i;
+ if(pool.largest_free_image<0 && (blocks[*i].type==IMAGE || blocks[*i].type==UNDECIDED))
+ pool.largest_free_image = *i;
+ }
+}
+
+unsigned MemoryAllocator::allocate(size_t size, size_t align, unsigned type_bits, MemoryType mem_type, BlockType block_type)
+{
+ unsigned pool_index = find_memory_pool(type_bits, mem_type);