Files
expvintl 419f2e4752 init
2025-02-23 17:40:52 +08:00

220 lines
6.7 KiB
C++

//
// streaming/streamingcleanup.h
//
// Copyright (C) 1999-2009 Rockstar Games. All Rights Reserved.
//
#ifndef STREAMING_STREAMINGCLEANUP_H
#define STREAMING_STREAMINGCLEANUP_H
#include "data/base.h"
// game headers
#include "fwtl\linklist.h"
#include "scene/streamer/SceneScoring.h"
#include "streaming/streamingdefs.h"
namespace rage
{
class bkGroup;
class fwEntity;
class rmcDrawable;
}
struct CStreamingBucketSet;
struct BucketEntry;
struct DeletionMap;
struct StreamingEntry;
// Doubt we'll ship with that - nosim is faster and has been in use for the past few years
#define SUPPORT_STREAMING_SIM_MODE (0)
//
// class containing methods for cleaning up scene
//
class CStreamingCleanup : public datBase
{
public:
enum RecurseResult
{
MUST_ABORT = -1,
NOTHING_DELETED = 0,
DELETED_DUMMIES = 1,
FREED_MEMORY = 2,
};
// Memory clean-up result
enum CleanupResult
{
CLEANUP_ABORTED = -1, // Allocation was aborted since
CLEANUP_FAILED = 0, // Not enough memory could be freed up
CLEANUP_SUCCESS = 1, // Cleanup was able to free up memory
};
void Init();
void Shutdown();
void RequestFlush(bool loadscene);
void RequestFlushNonMission(bool scriptsOnly);
bool HasFlushBeenProcessed() { return m_flushProcessed; }
void Update();
bool HasSpaceFor(strStreamingAllocator& allocator, size_t virtualSize, size_t physicalSize);
#if RSG_PC
size_t GetPhysicalSize(datResourceMap &map);
size_t GetVirtualSize(datResourceMap &map);
bool HandleOutOfMemory(size_t virtualSize, size_t physicalSize);
#endif // RSG_PC
bool MakeSpaceForMap(datResourceMap& map, strIndex index, bool keepMemory);
bool MakeSpaceForResourceFile(const char* filename, const char* ext, s32 version);
// PURPOSE: Check to see whether the last call to MakeSpaceForMap() was aborted because
// it was determined that the object isn't worth freeing memory for. This flag will only
// be updated after calling MakeSpaceForMap() with a valid strIndex.
bool WasLastAllocationAborted() const;
// PURPOSE: Check to see whether the last call to MakeSpaceForMap() on the main
// thread was unsuccessful due to fragmentation.
bool WasLastAllocationFragmented() const;
// PURPOSE: Delete all entities that are not in use and unlikely to be needed again
// in the next few frames. This can be called whenever the entity count is getting too high
// for comfort.
//
// PARAMS:
// maxObjsToDelete - Maximum number of entities that may be deleted.
// mustDelete - Asserts if we didn't delete at least one entity.
// scoreCutoff - Only entities with a score equal or less than this value will be deleted.
//
// RETURNS: The number of entities that were deleted.
int DeleteUnusedEntities(int maxObjsToDelete, bool mustDelete, float scoreCutoff);
// PURPOSE: Dump out all active entities and assert. This should be called when we have
// tons of active entities and want to find out why.
void AssertAndDumpEntities();
// PURPOSE: If we have a critical number of entities, delete some of the ones we think
// won't be missed - we'll assert if we do though.
void RemoveExcessEntities();
void DeleteAllDrawableReferences();
bool PurgeDrawable(rmcDrawable* pDrawable);
#if STREAMING_DETAILED_STATS
void MarkDrawHandlerDeleted(CEntity *entity, float score);
void MarkDrawHandlerCreated(CEntity *entity, float score);
void DisplayChurnStats();
#endif // STREAMING_DETAILED_STATS
#if __BANK
void DisplayChurnPoint();
bool *GetDisableChurnProtectionPtr() { return &m_DisableChurnProtection; }
void AddWidgets(bkGroup &group);
void UpdateNonClipsFlushControls();
void UpdateClipsFlushControls();
#endif // __BANK
#if SUPPORT_STREAMING_SIM_MODE && __BANK
inline bool IsSceneStreamingNoSim() { return m_enableStreamingSystemNoSim; }
#else // __BANK
inline bool IsSceneStreamingNoSim() { return true; }
#endif // __BANK
private:
void Flush();
bool DeleteLeastUsed(u32 ignoreFlags, s32& stage);
bool DeleteVehiclesAndPeds(bool bCutscene);
// Tell all logs and debug channels that we didn't load something due to churnProtection.
void LogChurnProtectionEvent(BucketEntry &bucketEntry);
CleanupResult FindLowestScoringEntityToDelete(strIndex indexNeedingMemory, u32 ignoreFlags);
RecurseResult DeleteEntityAndDependencies(DeletionMap &deletionMap, BucketEntry *bucketEntry, CEntity *entity, strIndex indexNeedingMemory, u32 ignoreFlags, CStreamingBucketSet &bucketSet);
RecurseResult RecurseDeleteDependencies(strIndex index, strIndex indexNeedingMemory, u32 ignoreFlags);
#if !__FINAL
// Called after a failed allocation due to complete lack of memory (not because an allocation was aborted because it wasn't important)
void MarkFailedAllocation();
#endif // !__FINAL
static bool PerformRemoval(strIndex index, u32 ignoreFlags, int &virtualMemoryToFree, int &physicalMemoryToFree, strIndex indexNeedingMemory, bool *mustAbort);
#if SUPPORT_STREAMING_SIM_MODE
static bool SimulateRemovalNew(DeletionMap &deletionMap, StreamingEntry *entry, int &virtualMemoryToFree, int &physicalMemoryToFree);
static StreamingEntry* AddCandidateNew(DeletionMap &deletionMap, BucketEntry *bucketEntry, strIndex index, u32 ignoreFlags, StreamingEntry *parent, int &virtualMemoryToFree, int &physicalMemoryToFree, strIndex indexNeedingMemory, bool *mustAbort);
#endif // SUPPORT_STREAMING_SIM_MODE
#if STREAM_STATS
int m_numCleanupCalls;
int m_numValidationAttempts;
#endif
#if STREAMING_DETAILED_STATS
enum
{
MAX_DELETED_COUNT = 128,
MAX_DELETED_CHURN_FRAMES = 3,
};
struct DeletedDrawableHandler
{
// The bucket score of the entity
float m_BucketScore;
};
atSimplePooledMapType<CEntity *, DeletedDrawableHandler> m_LastDeletedHandlers[MAX_DELETED_CHURN_FRAMES];
int m_LastDeletedHandlerIndex;
int m_ChurnCounts[MAX_DELETED_CHURN_FRAMES];
#endif // STREAMING_DETAILED_STATS
#if !__FINAL
u32 m_LastFailedAlloc;
#endif // !__FINAL
bool m_flushRequested;
bool m_loadSceneAfterFlush;
bool m_flushProcessed;
// True if the last clean-up with a valid strIndex was aborted. See WasLastAllocationAborted().
bool m_LastAllocationWasAborted;
// True if the last failed allocation on the main thread unsuccessful due to fragmention.
bool m_LastAllocationWasFragmented;
// If true, the map store will be flushed during a flush
bool m_FlushMapStore;
bool m_FlushVehicles;
bool m_FlushPeds;
bool m_FlushCollisions;
bool m_FlushClips;
bool m_FlushObjects;
bool m_FlushCloth;
bool m_FlushClouds;
#if __BANK
// If true, we won't turn an entity stream request down to prevent churn.
bool m_DisableChurnProtection;
// Most recent churn point.
float m_LastChurnPoint;
// Timestamp on when the last churn occurred.
u32 m_LastChurnTimestamp;
#if SUPPORT_STREAMING_SIM_MODE
bool m_enableStreamingSystemNoSim;
#endif // SUPPORT_STREAMING_SIM_MODE
#endif // __BANK
};
#endif // STREAMING_STREAMINGCLEANUP_H