/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYCOMMON_IDEFRAGALLOCATOR_H
#define CRYINCLUDE_CRYCOMMON_IDEFRAGALLOCATOR_H
#pragma once
struct IDefragAllocatorStats
{
size_t nCapacity;
size_t nInUseSize;
uint32 nInUseBlocks;
uint32 nFreeBlocks;
uint32 nPinnedBlocks;
uint32 nMovingBlocks;
uint32 nLargestFreeBlockSize;
uint32 nSmallestFreeBlockSize;
uint32 nMeanFreeBlockSize;
uint32 nCancelledMoveCount;
};
struct IDefragAllocatorCopyNotification
{
IDefragAllocatorCopyNotification()
: bDstIsValid(false)
, bSrcIsUnneeded(false)
, bCancel(false)
{
}
bool bDstIsValid;
bool bSrcIsUnneeded;
// Flag to indicate that the copy can't be initiated after all - currently only cancelling before a relocate
// is begun is supported, and the destination region must be stable
bool bCancel;
};
class IDefragAllocatorPolicy
{
public:
enum
{
InvalidUserMoveId = 0xffffffff
};
public:
//
virtual uint32 BeginCopy(void* pContext, UINT_PTR dstOffset, UINT_PTR srcOffset, UINT_PTR size, IDefragAllocatorCopyNotification* pNotification) = 0;
virtual void Relocate(uint32 userMoveId, void* pContext, UINT_PTR newOffset, UINT_PTR oldOffset, UINT_PTR size) = 0;
virtual void CancelCopy(uint32 userMoveId, void* pContext, bool bSync) = 0;
// Perform the copy and relocate immediately - will only be called when UnAppendSegment is
virtual void SyncCopy(void* pContext, UINT_PTR dstOffset, UINT_PTR srcOffset, UINT_PTR size) = 0;
//
protected:
virtual ~IDefragAllocatorPolicy() {}
};
class IDefragAllocator
{
public:
typedef uint32 Hdl;
enum
{
InvalidHdl = 0,
};
struct AllocatePinnedResult
{
Hdl hdl;
UINT_PTR offs;
UINT_PTR usableSize;
};
enum EBlockSearchKind
{
eBSK_BestFit,
eBSK_FirstFit
};
struct Policy
{
Policy()
: pDefragPolicy(NULL)
, maxAllocs(0)
, maxSegments(1)
, blockSearchKind(eBSK_BestFit)
{
}
IDefragAllocatorPolicy* pDefragPolicy;
size_t maxAllocs;
size_t maxSegments;
EBlockSearchKind blockSearchKind;
};
public:
//
virtual void Release(bool bDiscard = false) = 0;
virtual void Init(UINT_PTR capacity, UINT_PTR alignment, const Policy& policy = Policy()) = 0;
virtual bool AppendSegment(UINT_PTR capacity) = 0;
virtual void UnAppendSegment() = 0;
virtual Hdl Allocate(size_t sz, const char* source, void* pContext = NULL) = 0;
virtual Hdl AllocateAligned(size_t sz, size_t alignment, const char* source, void* pContext = NULL) = 0;
virtual AllocatePinnedResult AllocatePinned(size_t sz, const char* source, void* pContext = NULL) = 0;
virtual bool Free(Hdl hdl) = 0;
virtual void ChangeContext(Hdl hdl, void* pNewContext) = 0;
virtual size_t GetAllocated() const = 0;
virtual IDefragAllocatorStats GetStats() = 0;
virtual void DisplayMemoryUsage(const char* title, unsigned int allocatorDisplayOffset = 0) = 0;
virtual size_t DefragmentTick(size_t maxMoves, size_t maxAmount, bool bForce = false) = 0;
virtual UINT_PTR UsableSize(Hdl hdl) = 0;
// Pin the chunk until the next defrag tick, when it will be automatically unpinned
virtual UINT_PTR WeakPin(Hdl hdl) = 0;
// Pin the chunk until Unpin is called
virtual UINT_PTR Pin(Hdl hdl) = 0;
virtual void Unpin(Hdl hdl) = 0;
virtual const char* GetSourceOf(Hdl hdl) = 0;
//
#ifndef _RELEASE
virtual void DumpState(const char* filename) = 0;
virtual void RestoreState(const char* filename) = 0;
#endif
protected:
virtual ~IDefragAllocator() {}
};
#endif // CRYINCLUDE_CRYCOMMON_IDEFRAGALLOCATOR_H