Example #1
0
        VboBlock* Vbo::freeBlock(VboBlock& block) {
#ifdef _DEBUG_VBO
            checkBlockChain();
            checkFreeBlocks();
#endif

            VboBlock* previous = block.m_previous;
            VboBlock* next = block.m_next;
            
            m_freeCapacity += block.capacity();
            block.m_free = true;
            
            if (previous != NULL && previous->free() && next != NULL && next->free()) {
                resizeBlock(*previous, previous->capacity() + block.capacity() + next->capacity());
                if (m_last == next) m_last = previous;
                removeFreeBlock(*next);
                previous->insertBetween(previous->m_previous, next->m_next);
                delete █
                delete next;
                return previous;
            }
            
            if (previous != NULL && previous->free()) {
                resizeBlock(*previous, previous->capacity() + block.capacity());
                if (m_last == &block) m_last = previous;
                previous->insertBetween(previous->m_previous, next);
                delete █
                return previous;
            }
            
            if (next != NULL && next->free()) {
                if (m_last == next) m_last = █
                removeFreeBlock(*next);
                block.m_capacity += next->capacity();
                block.m_free = true;
                block.insertBetween(previous, next->m_next);
                insertFreeBlock(block);
                delete next;
                return █
            }
            
            insertFreeBlock(block);

#ifdef _DEBUG_VBO
            checkBlockChain();
            checkFreeBlocks();
#endif

            return █
        }
Example #2
0
	void * realloc(void * ptr, size_t size)
	{
		char * charPtr = static_cast<char *>(ptr);
		Block & block = blocks.at(charPtr);
		Block & next = nextBlock(charPtr);

		/* There is enough place ahead of the current block */
		if(block.size == size)
		{

		}
		else if(block.size > size)
		{
			splitBlock(block, size);
			Block & rest = blocks.at(block.ptr + size);
			markBlockFree(rest);
			if(next.free)
			{
				resizeBlock(rest, rest.size + next.size);
				removeBlock(next);
			}
		}
		else if(next.free && block.size + next.size >= size)
		{
			splitBlock(next, size-block.size);
			removeBlock(next);
			resizeBlock(block, size);
		}
		else
		{	
			void * newPtr = alloc(size);
			if(newPtr != NULL)
			{
				memcpy(newPtr, ptr, block.size);
				free(ptr);
				ptr = newPtr;
			}
		}


		#ifdef SELFTEST
		selfTest();
		#endif

		return ptr;
	}
Example #3
0
	void splitBlock(Block & block, size_t newSize)
	{
	    assert(block.size >= newSize);
	    size_t oldSize = block.size;
	    resizeBlock(block, newSize);
	    if(newSize < oldSize)
	    	createBlock(block.ptr+newSize, oldSize-newSize, block.free);
	}
Example #4
0
	void free(void * ptr)
	{
		char * charPtr = static_cast<char *>(ptr);
		Block & prev = prevBlock(charPtr);
		Block & next = nextBlock(charPtr);
		Block & block = blocks.at(charPtr);

		assert(block.free == false);
		assert(prev.ptr == NULL || prev.ptr + prev.size == block.ptr);
		assert(next.ptr == NULL || block.ptr + block.size == next.ptr);

		/* prev is busy and next is busy */
		/* just mark current block as free */
		if(!prev.free && !next.free)
		{	
			markBlockFree(block);
		}
		/* prev is free and next is busy */
		/* concat prev and curr block into one free block */
		else if(prev.free && !next.free)
		{
			resizeBlock(prev, prev.size + block.size);
			removeBlock(block);
		}
		/* prev is busy and next is free */
		/* concat curr and next block into one free block */
		else if(!prev.free && next.free)
		{
			resizeBlock(block, block.size + next.size);
			removeBlock(next);
			markBlockFree(block);
		}
		/* concat all three blocks into one block*/
		else if(prev.free && next.free)
		{
			resizeBlock(prev, prev.size + block.size + next.size);
			removeBlock(block);
			removeBlock(next);
		}
		#ifdef SELFTEST
		selfTest();
		#endif
	}
Example #5
0
        VboBlock* Vbo::packBlock(VboBlock& block) {
            VboBlock* first = block.m_next;
            if (first == NULL)
                return NULL;
            
            VboBlock* previous = NULL;
            VboBlock* last = first;
            size_t size = 0;
            size_t address = first->address();
            
            do {
                last->m_address -= block.capacity();
                size += last->capacity();
                previous = last;
                last = last->m_next;
            } while (last != NULL && !last->free());
            
            memmove(m_buffer + block.address(), m_buffer + address, size);
            
            if (last != NULL) {
                last->m_address -= block.capacity();
                resizeBlock(*last, last->capacity() + block.capacity());
            } else {
                VboBlock* newBlock = new VboBlock(*this, previous->address() + previous->capacity(), block.capacity());
                insertFreeBlock(*newBlock);
                newBlock->insertBetween(previous, NULL);
                m_last = newBlock;
            }
            
            if (m_first == &block) m_first = block.m_next;
            
            removeFreeBlock(block);
            if (block.m_previous != NULL) block.m_previous->m_next = block.m_next;
            if (block.m_next != NULL) block.m_next->m_previous = block.m_previous;
            delete &block;

            return last;
        }
Example #6
0
        void Vbo::resizeVbo(size_t newCapacity) {
            VboState oldState = m_state;
            
            unsigned char* temp = NULL;
            MemBlock::List memBlocks;
            if (m_vboId != 0 && m_freeCapacity < m_totalCapacity) {
                VboBlock* currentBlock = m_first;
                size_t totalLength = 0;
                
                while (currentBlock != NULL) {
                    while (currentBlock != NULL && currentBlock->free())
                        currentBlock = currentBlock->m_next;
                    if (currentBlock != NULL) {
                        size_t start = currentBlock->address();
                        size_t length = 0;
                        while (currentBlock != NULL && !currentBlock->free()) {
                            length += currentBlock->capacity();
                            currentBlock = currentBlock->m_next;
                        }
                        memBlocks.push_back(MemBlock(start, length));
                        totalLength += length;
                    }
                }
                
                if (m_state < VboActive)
                    activate();
                if (m_state < VboMapped)
                    map();

                temp = new unsigned char[totalLength];
                size_t offset = 0;
                MemBlock::List::const_iterator it, end;
                for (it = memBlocks.begin(), end = memBlocks.end(); it != end; ++it) {
                    const MemBlock& memBlock = *it;
                    memcpy(temp + offset, m_buffer + memBlock.start, memBlock.length);
                    offset += memBlock.length;
                }
            }
            
            size_t addedCapacity = newCapacity - m_totalCapacity;
            m_freeCapacity = newCapacity - (m_totalCapacity - m_freeCapacity);
            m_totalCapacity = newCapacity;
            
            if (m_last->free()) {
                resizeBlock(*m_last, m_last->capacity() + addedCapacity);
            } else {
                VboBlock* block = new VboBlock(*this, m_last->address() + m_last->capacity(), addedCapacity);
                block->insertBetween(m_last, NULL);
                insertFreeBlock(*block);
                m_last = block;
            }
            
            if (m_vboId != 0) {
                if (m_state == VboMapped)
                    unmap();
                if (m_state == VboActive)
                    deactivate();
                glDeleteBuffers(1, &m_vboId);
                m_vboId = 0;
            }
            
            if (temp != NULL) {
                assert(!memBlocks.empty());
                
                if (m_state < VboActive)
                    activate();
                if (m_state < VboMapped)
                    map();
                
                size_t offset = 0;
                MemBlock::List::const_iterator it, end;
                for (it = memBlocks.begin(), end = memBlocks.end(); it != end; ++it) {
                    const MemBlock& memBlock = *it;
                    memcpy(m_buffer + memBlock.start, temp + offset, memBlock.length);
                }
                
                delete [] temp;
                temp = NULL;
                memBlocks.clear();
                
                if (oldState < VboMapped)
                    unmap();
                if (oldState < VboActive)
                    deactivate();
            } else {
                if (oldState > VboInactive && m_state < VboActive)
                    activate();
                if (oldState > VboActive && m_state < VboMapped)
                    map();
            }
            
#ifdef _DEBUG_VBO
            checkBlockChain();
            checkFreeBlocks();
#endif
        }