示例#1
0
QPoolAllocator::QPoolAllocator(const pointer_uint_q uSize, const pointer_uint_q uBlockSize, const QAlignment &alignment) :
            m_uBlockSize(uBlockSize),
            m_uPoolSize(uSize),
            m_uAllocatedBytes(0),
            m_uAlignment(alignment),
            m_bNeedDestroyMemoryChunk(true)
{
    QE_ASSERT_ERROR( 0 != uSize, "Size cannot be zero"  );
    QE_ASSERT_ERROR( 0 != uBlockSize, "Block size cannot be zero" );

    m_pAllocatedMemory = operator new(m_uPoolSize, alignment);
    QE_ASSERT_ERROR( null_q != m_pAllocatedMemory, "Pointer to allocated memory is null" );

    m_pFirst = m_pAllocatedMemory;

    m_uBlocksCount = m_uPoolSize / uBlockSize;

    this->AllocateFreeBlocksList();
}
示例#2
0
void QPoolAllocator::AllocateFreeBlocksList()
{
    m_ppFreeBlocks = (void**) operator new(m_uBlocksCount * sizeof(void**));
    QE_ASSERT_ERROR( null_q != m_ppFreeBlocks, "Pointer to allocated memory for internals is null" );

    m_ppNextFreeBlock = m_ppFreeBlocks;
    m_uSize = m_uPoolSize + m_uBlocksCount * sizeof(void**);

    this->ClearFreeBlocksList();
}
void SQPoint::Translate(const float_q &fTranslationX, const float_q &fTranslationY, const float_q &fTranslationZ, QVector4* arPoints, const unsigned int &uElements)
{
    // Checks that the point array is not null
    QE_ASSERT_ERROR( arPoints != null_q, "Input array must not be null" );

    for(unsigned int i = 0; i < uElements; ++i)
    {
        SQPoint::Translate(fTranslationX, fTranslationY, fTranslationZ, arPoints[i]);
    }
}
void SQPoint::Transform(const QTransformationMatrix3x3 &transformation, QVector2* arPoints, const unsigned int &uElements)
{
    // Checks that the point array is not null
    QE_ASSERT_ERROR( arPoints != null_q, "Input array must not be null" );

    for(unsigned int i = 0; i < uElements; ++i)
    {
        arPoints[i] = arPoints[i].Transform(transformation);
    }
}
QLinearAllocator::QLinearAllocator(const pointer_uint_q uSize, const QAlignment &alignment) : 
                                                                 m_uSize(uSize),
                                                                 m_bUsesExternalBuffer(false),
                                                                 m_uAlignment(alignment)
{
    QE_ASSERT_ERROR(uSize > 0, "The size of the buffer cannot be zero.");

    m_pBase = ::operator new(uSize, alignment);
    m_pTop = m_pBase;
}
void SQPoint::Translate(const QTranslationMatrix<QMatrix4x4> &translation, QVector4* arPoints, const unsigned int &uElements)
{
    // Checks that the point array is not null
    QE_ASSERT_ERROR( arPoints != null_q, "Input array must not be null" );

    for(unsigned int i = 0; i < uElements; ++i)
    {
        SQPoint::Translate(translation, arPoints[i]);
    }
}
QLinearAllocator::QLinearAllocator(const pointer_uint_q uSize, void* pBuffer, const QAlignment &alignment) : 
                                                                                m_pBase(pBuffer),
                                                                                m_pTop(pBuffer),
                                                                                m_uSize(uSize),
                                                                                m_bUsesExternalBuffer(true),
                                                                                m_uAlignment(alignment)
{
    QE_ASSERT_ERROR(uSize > 0, "The size of the buffer cannot be zero.");
    QE_ASSERT_ERROR(pBuffer != null_q, "The pointer to the external buffer cannot be null.");

    pointer_uint_q uAdjustment = m_uAlignment - ((pointer_uint_q)m_pBase & (m_uAlignment - 1U));

    // Changes the base pointer to the first memory address that is aligned as intended
    if(uAdjustment != m_uAlignment)
    {
        m_pBase = (void*)((pointer_uint_q)m_pBase + uAdjustment);
        m_pTop = m_pBase;
        m_uSize -= uAdjustment; // Some free space is lost
    }
}
bool QLinearAllocator::CanAllocate(const pointer_uint_q uSize, const QAlignment &alignment) const
{
    QE_ASSERT_ERROR(uSize > 0, "The size of the memory block to be allocated cannot be zero.");

    pointer_uint_q uAdjustment = alignment - ((pointer_uint_q)m_pTop & (alignment - 1U));

    if(uAdjustment == alignment)
        uAdjustment = 0;

    return m_uSize - this->GetAllocatedBytes() >= uSize + uAdjustment;
}
void QLinearAllocator::CopyTo(QLinearAllocator &destination) const
{
    QE_ASSERT_ERROR(destination.GetSize() >= this->GetAllocatedBytes(), "The input allocator's size must be greater than or equal to the size of the allocated bytes in the resident allocator.");
    QE_ASSERT_WARNING(destination.m_uAlignment == m_uAlignment, "The alignment of the input allocator is different from the resident allocator's.");

    const pointer_uint_q BYTES_TO_COPY = this->GetAllocatedBytes();

    memcpy(destination.m_pBase, m_pBase, BYTES_TO_COPY);

    destination.m_pTop = (void*)((pointer_uint_q)destination.m_pBase + BYTES_TO_COPY);
}
void SQPoint::Scale(const float_q &fScaleX, const float_q &fScaleY, QVector2* arPoints, const unsigned int &uElements)
{
    // Checks that the point array is not null
    QE_ASSERT_ERROR( arPoints != null_q, "Input array must not be null" );

    for(unsigned int i = 0; i < uElements; ++i)
    {
        arPoints[i].x *= fScaleX;
        arPoints[i].y *= fScaleY;
    }
}
示例#11
0
QPoolAllocator::QPoolAllocator(const pointer_uint_q uSize, const pointer_uint_q uBlockSize, const void *pBuffer) :
            m_uBlockSize(uBlockSize),
            m_uPoolSize(uSize),
            m_uAllocatedBytes(0),
            m_uAlignment(QAlignment(sizeof(void**))),
            m_bNeedDestroyMemoryChunk(false)
{
    QE_ASSERT_ERROR( 0 != uSize, "Size cannot be zero" );
    QE_ASSERT_ERROR( 0 != uBlockSize, "Block size cannot be zero" );
    QE_ASSERT_ERROR( 0 != pBuffer, "Pointer to buffer cannot be null" );

    // Calculates needed memory address offset (adjustment) for the chunk starts at multiple of alignment
    pointer_uint_q uAdjustment = m_uAlignment - ((pointer_uint_q)pBuffer & (m_uAlignment - 1));
    if(uAdjustment == m_uAlignment )
        uAdjustment = 0;

    m_pAllocatedMemory = (void**)((pointer_uint_q)pBuffer + uAdjustment);
    m_pFirst = m_pAllocatedMemory;

    m_uBlocksCount = (m_uPoolSize - uAdjustment) / uBlockSize;

    this->AllocateFreeBlocksList();
}
void SQPoint::RotateWithPivot(const QRotationMatrix3x3 &rotation, const QBaseVector3 &vPivot, QVector3* arPoints, const unsigned int &uElements)
{
    // Checks that the point array is not null
    QE_ASSERT_ERROR( arPoints != null_q, "Input array must not be null" );

    for(unsigned int i = 0; i < uElements; ++i)
    {
        arPoints[i] -= vPivot;

        SQPoint::Rotate(rotation, arPoints[i]);

        arPoints[i] += vPivot;
    }
}
void SQPoint::RotateWithPivot(const float_q &fRotationAngle, const QBaseVector2 &vPivot, QVector2* arPoints, const unsigned int &uElements)
{
    // Checks that the point array is not null
    QE_ASSERT_ERROR( arPoints != null_q, "Input array must not be null" );

    for(unsigned int i = 0; i < uElements; ++i)
    {
        arPoints[i] -= vPivot;

        arPoints[i] = arPoints[i].Transform(fRotationAngle);

        arPoints[i] += vPivot;
    }
}
void SQPoint::ScaleWithPivot(const QScalingMatrix3x3 &scale, const QBaseVector4 &vPivot, QVector4* arPoints, const unsigned int &uElements)
{
    // Checks that the point array is not null
    QE_ASSERT_ERROR( arPoints != null_q, "Input array must not be null" );

    for(unsigned int i = 0; i < uElements; ++i)
    {
        arPoints[i] -= vPivot;

        SQPoint::Scale(scale, arPoints[i]);

        arPoints[i] += vPivot;
    }
}
示例#15
0
QPoolAllocator::QPoolAllocator(const pointer_uint_q uSize, const pointer_uint_q uBlockSize, const void *pBuffer, const QAlignment &alignment) :
            m_uBlockSize(uBlockSize),
            m_uPoolSize(uSize),
            m_uAllocatedBytes(0),
            m_uAlignment(alignment),
            m_bNeedDestroyMemoryChunk(false)
{
    QE_ASSERT_ERROR( 0 != uSize, "Size cannot be zero" );
    QE_ASSERT_ERROR( 0 != uBlockSize, "Block size cannot be zero" );
    QE_ASSERT_ERROR( 0 != pBuffer, "Pointer to buffer cannot be null" );

    pointer_uint_q uAdjustment = alignment - ((pointer_uint_q)pBuffer & (alignment - 1));

    if(uAdjustment == alignment )
        uAdjustment = 0;

    m_pAllocatedMemory = (void**)((pointer_uint_q)pBuffer + uAdjustment);
    m_pFirst = m_pAllocatedMemory;
    m_uPoolSize -= uAdjustment; // Some free space is lost

    m_uBlocksCount = m_uPoolSize / uBlockSize;

    this->AllocateFreeBlocksList();
}
void SQPoint::ScaleWithPivot(const float_q &fScaleX, const float_q  fScaleY, const float_q &fScaleZ, const QBaseVector3 &vPivot,
                                    QVector3* arPoints, const unsigned int &uElements)
{
    // Checks that the point array is not null
    QE_ASSERT_ERROR( arPoints != null_q, "Input array must not be null" );

    for(unsigned int i = 0; i < uElements; ++i)
    {
        arPoints[i] -= vPivot;

        SQPoint::Scale(fScaleX, fScaleY, fScaleZ, arPoints[i]);

        arPoints[i] += vPivot;
    }
}
示例#17
0
void* QLinearAllocator::Allocate(const pointer_uint_q uSize)
{
    QE_ASSERT_ERROR(uSize > 0, "The size of the memory block to be allocated cannot be zero.");
    QE_ASSERT_WARNING(this->CanAllocate(uSize), "The size of the memory block to be allocated does not fit in the available free space.");

    void* pAllocatedMemory = null_q;
    
    if(this->CanAllocate(uSize))
    {
        pAllocatedMemory = m_pTop;
        m_pTop = (void*)((pointer_uint_q)m_pTop + uSize);
    }

    return pAllocatedMemory;
}
示例#18
0
void QPoolAllocator::Reallocate(const pointer_uint_q uNewSize, const void* pNewLocation)
{
    QE_ASSERT_WARNING(uNewSize > m_uPoolSize, "The new size must be greater than the current size of the pool.");
    QE_ASSERT_ERROR(pNewLocation != null_q, "The input new location cannot be null.");

    if(uNewSize > m_uPoolSize && pNewLocation != null_q)
    {
        pointer_uint_q uNewLocationAddress = (pointer_uint_q)pNewLocation;
        pointer_uint_q uAlignmentOffset = m_uAlignment - (uNewLocationAddress % m_uAlignment);
        void* pAdjustedNewLocation = (void*)((pointer_uint_q)pNewLocation + uAlignmentOffset);

        this->InternalReallocate(uNewSize, pAdjustedNewLocation);

        m_bNeedDestroyMemoryChunk = false;
    }
}
示例#19
0
void QLinearAllocator::Reallocate(const pointer_uint_q uNewSize)
{
    QE_ASSERT_ERROR(!m_bUsesExternalBuffer, "This allocator uses an external buffer so internal reallocation is not possible");
    QE_ASSERT_WARNING(uNewSize > m_uSize, "The new size must be greater than the current size");

    if(uNewSize > m_uSize)
    {
        const pointer_uint_q BYTES_TO_COPY = this->GetAllocatedBytes();

        void* pNewBuffer = ::operator new(uNewSize, QAlignment(m_uAlignment));
        memcpy(pNewBuffer, m_pBase, BYTES_TO_COPY);
        ::operator delete(m_pBase, QAlignment(m_uAlignment));
        m_pBase = pNewBuffer;
        m_pTop = (void*)((pointer_uint_q)m_pBase + BYTES_TO_COPY);
        m_uSize = uNewSize;
    }
}
void SQPoint::TransformWithPivot(const QTransformationMatrix<QMatrix4x4> &transformation, const QBaseVector4 &vPivot, QVector4* arPoints,
                                        const unsigned int &uElements)
{
    // Checks that the point array is not null
    QE_ASSERT_ERROR( arPoints != null_q, "Input array must not be null" );

    for(unsigned int i = 0; i < uElements; ++i)
    {
        arPoints[i].x -= vPivot.x;
        arPoints[i].y -= vPivot.y;
        arPoints[i].z -= vPivot.z;

        SQPoint::Transform(transformation, arPoints[i]);

        arPoints[i].x += vPivot.x;
        arPoints[i].y += vPivot.y;
        arPoints[i].z += vPivot.z;
    }
}
示例#21
0
void* QLinearAllocator::Allocate(const pointer_uint_q uSize, const QAlignment &alignment)
{
    QE_ASSERT_ERROR(uSize > 0, "The size of the memory block to be allocated cannot be zero.");
    QE_ASSERT_WARNING(this->CanAllocate(uSize, alignment), "The size of the memory block to be allocated (plus the alignment adjustment) does not fit in the available free space.");

    void* pAllocatedMemory = null_q;

    if(this->CanAllocate(uSize, alignment))
    {
        pointer_uint_q uAdjustment = alignment - ((pointer_uint_q)m_pTop & (alignment - 1U));

        if(uAdjustment == alignment)
            uAdjustment = 0;

        pAllocatedMemory = (void*)((pointer_uint_q)m_pTop + uAdjustment);
        m_pTop = (void*)((pointer_uint_q)m_pTop + uSize + uAdjustment);
    }

    return pAllocatedMemory;
}
示例#22
0
void QPoolAllocator::InternalReallocate(const pointer_uint_q uNewSize, void* pNewLocation)
{
    pointer_uint_q uNewBlocksCount = uNewSize / m_uBlockSize;

    QE_ASSERT_ERROR( null_q != pNewLocation, "Pointer to allocated memory is null" );

    memcpy(pNewLocation, m_pFirst, m_uBlockSize * m_uBlocksCount);

    // Copies the free block list
    // -----------------------------------
    void** ppNewFreeBlockList = (void**) operator new(uNewBlocksCount * sizeof(void**));

    QE_ASSERT_ERROR( null_q != ppNewFreeBlockList, "Pointer to allocated memory for internals is null" );

    if(null_q == m_ppNextFreeBlock) // No free blocks in source.
    {
        // Appends extra destination free blocks pointers
        // ppNext = first free block of remaining free blocks.
        void** ppNext = ppNewFreeBlockList + m_uBlocksCount;

        // Assigns the next free block
        m_ppNextFreeBlock = ppNext;

        // Frees remaining blocks from destination redoing the rest of the list.
        for( pointer_uint_q uIndex = m_uBlocksCount; uIndex < uNewBlocksCount - 1U; ++uIndex )
        {
            *ppNext = (void*)(ppNext + 1U);
            ++ppNext;
        }

        *ppNext = null_q;
    }
    else
    {
        // Copy free blocks pointers list from source to destination
        void** ppLastFreeBlock = m_ppNextFreeBlock;

        while( null_q != *ppLastFreeBlock )
        {
            // Index of the next free block in the source = *ppLastFreeBlock - m_ppFreeBlocks
            pointer_uint_q uLastFreeBlockPosition = (void**)(ppLastFreeBlock) - m_ppFreeBlocks;
            pointer_uint_q uNextFreeBlockPosition = (void**)(*ppLastFreeBlock) - m_ppFreeBlocks;
            *(ppNewFreeBlockList + uLastFreeBlockPosition) = ppNewFreeBlockList + uNextFreeBlockPosition;

            // Moves to the next free block
            ppLastFreeBlock = (void**)*ppLastFreeBlock;
        }

        // Assigns the next free block in the destination (same block index as in origin).
        m_ppNextFreeBlock = ppNewFreeBlockList + (m_ppNextFreeBlock - m_ppFreeBlocks);

        // Appends extra free blocks pointers of destination
        // Links copied free blocks list from source to remaining free blocks from destination.

        // ppNext = first free block of remaining free blocks.
        void** ppNext = ppNewFreeBlockList + m_uBlocksCount;

        // Links two lists.
        *(ppNewFreeBlockList + (ppLastFreeBlock - m_ppFreeBlocks)) = ppNext;

        // Frees the rest of blocks from destination redoing the rest of the list.
        for( pointer_uint_q uIndex = m_uBlocksCount; uIndex < uNewBlocksCount - 1U; ++uIndex )
        {
            *ppNext = (void*)(ppNext + 1U);
            ++ppNext;
        }

        *ppNext = null_q;
    }

    // Updates some additional fields
    // ---------------------------------
    m_uBlocksCount = uNewBlocksCount;
    m_uPoolSize = uNewSize;
    m_uSize = m_uPoolSize + sizeof(void**) * m_uBlocksCount;

    // Frees the old buffers
    // -------------------------
    if(m_bNeedDestroyMemoryChunk)
        operator delete(m_pAllocatedMemory, m_uAlignment);
    
    m_pAllocatedMemory = pNewLocation;
    m_pFirst = m_pAllocatedMemory;

    operator delete(m_ppFreeBlocks);
    m_ppFreeBlocks = ppNewFreeBlockList;
}
示例#23
0
bool QLinearAllocator::CanAllocate(const pointer_uint_q uSize) const
{
    QE_ASSERT_ERROR(uSize > 0, "The size of the memory block to be allocated cannot be zero.");

    return m_uSize - this->GetAllocatedBytes() >= uSize;
}
示例#24
0
void QPoolAllocator::CopyTo(QPoolAllocator &poolAllocator) const
{
    QE_ASSERT_ERROR(m_uBlocksCount <= poolAllocator.m_uBlocksCount, "Blocks count of destination pool allocator must be greater or equal than the source pool allocator" );
    QE_ASSERT_ERROR(m_uPoolSize <= poolAllocator.m_uPoolSize, "Chunk size for allocations must be greater or equal in the destination pool allocator than in the source pool allocator" );
    QE_ASSERT_ERROR(m_uBlockSize == poolAllocator.m_uBlockSize, "Block sizes of origin and destination pool allocators must be equal");
    QE_ASSERT_WARNING(poolAllocator.m_uAlignment == m_uAlignment, "The alignment of the input allocator is different from the resident allocator's.");

    if(null_q == m_ppNextFreeBlock)
    {
        // No free blocks in source. Append extra destination free blocks pointers if it has more blocks count.
        if(m_uBlocksCount < poolAllocator.m_uBlocksCount)
        {
            // ppNext = first free block of remaining free blocks.
            void **ppNext = poolAllocator.m_ppFreeBlocks + m_uBlocksCount;

            // Assigns the next free block in the destination pool
            poolAllocator.m_ppNextFreeBlock = ppNext;

            // Frees remaining blocks from destination redoing the rest of the list.
            for( pointer_uint_q uIndex = m_uBlocksCount; uIndex < poolAllocator.m_uBlocksCount - 1; ++uIndex )
            {
                *ppNext = (void*)((void**)ppNext + 1);
                ppNext = (void**)*ppNext;
            }

            *ppNext = null_q;
        }
        else
        {
            poolAllocator.m_ppNextFreeBlock = null_q;
        }
    }
    else
    {
        // Assigns the next free block in the destination pool (same block index as in origin).
        poolAllocator.m_ppNextFreeBlock = poolAllocator.m_ppFreeBlocks + (m_ppNextFreeBlock - m_ppFreeBlocks);

        // Copy free blocks pointers list from source to destination
        void **ppLastFreeBlock = m_ppNextFreeBlock;

        while( null_q != *ppLastFreeBlock )
        {
            // Index of the next free block in the source = *ppLastFreeBlock - m_ppFreeBlocks
            *(poolAllocator.m_ppFreeBlocks + ((void**)ppLastFreeBlock - m_ppFreeBlocks)) =
                                    poolAllocator.m_ppFreeBlocks + ((void**)*ppLastFreeBlock - m_ppFreeBlocks);

            // ppLastFreeBlock will contain the pointer to last free block in the list or null if there are no free blocks
            // when exits from the while loop.
            if(null_q != *ppLastFreeBlock)
                ppLastFreeBlock = (void**)*ppLastFreeBlock;
        }

        if(m_uBlocksCount < poolAllocator.m_uBlocksCount)
        {
            // Appends extra free blocks pointers of destination

            // Links copied free blocks list from source to remaining free blocks from destination.

            // ppNext = first free block of remaining free blocks.
            void **ppNext = poolAllocator.m_ppFreeBlocks + m_uBlocksCount;

            // Links two lists.
            *(poolAllocator.m_ppFreeBlocks +  (ppLastFreeBlock - m_ppFreeBlocks)) = ppNext;

            // Frees the rest of blocks from destination redoing the rest of the list.
            for( pointer_uint_q uIndex = m_uBlocksCount; uIndex < poolAllocator.m_uBlocksCount - 1; uIndex++ )
            {
                *ppNext = (void*)((void**)ppNext + 1);
                ppNext = (void**)*ppNext;
            }

            *ppNext = null_q;
        }
    }

    // Copies all source blocks in destination
    memcpy(poolAllocator.m_pFirst, m_pFirst, m_uBlockSize * m_uBlocksCount);

    poolAllocator.m_uAllocatedBytes = m_uAllocatedBytes;
}