void USoundWave::FreeResources()
{
	check(IsInAudioThread());

	// Housekeeping of stats
	DEC_FLOAT_STAT_BY( STAT_AudioBufferTime, Duration );
	DEC_FLOAT_STAT_BY( STAT_AudioBufferTimeChannels, NumChannels * Duration );

	// GEngine is NULL during script compilation and GEngine->Client and its audio device might be
	// destroyed first during the exit purge.
	if( GEngine && !GExitPurge )
	{
		// Notify the audio device to free the bulk data associated with this wave.
		FAudioDeviceManager* AudioDeviceManager = GEngine->GetAudioDeviceManager();
		if (AudioDeviceManager)
		{
			AudioDeviceManager->StopSoundsUsingResource(this);
			AudioDeviceManager->FreeResource(this);
		}
	}

	if (CachedRealtimeFirstBuffer)
	{
		FMemory::Free(CachedRealtimeFirstBuffer);
		CachedRealtimeFirstBuffer = nullptr;
	}

	// Just in case the data was created but never uploaded
	if (RawPCMData)
	{
		FMemory::Free(RawPCMData);
		RawPCMData = nullptr;
	}

	// Remove the compressed copy of the data
	RemoveAudioResource();

	// Stat housekeeping
	DEC_DWORD_STAT_BY(STAT_AudioMemorySize, TrackedMemoryUsage);
	DEC_DWORD_STAT_BY(STAT_AudioMemory, TrackedMemoryUsage);
	TrackedMemoryUsage = 0;

	ResourceID = 0;
	bDynamicResource = false;
	DecompressionType = DTYPE_Setup;
	bDecompressedFromOgg = 0;

	USoundWave* SoundWave = this;
	FAudioThread::RunCommandOnGameThread([SoundWave]()
	{
		SoundWave->ResourceState = ESoundWaveResourceState::Freed;
	}, TStatId());
}
Example #2
0
FShaderResource::~FShaderResource()
{
	check(Canary == FShader::ShaderMagic_Uninitialized || Canary == FShader::ShaderMagic_CleaningUp || Canary == FShader::ShaderMagic_Initialized);
	check(NumRefs == 0);
	Canary = 0;

	DEC_DWORD_STAT_BY_FName(GetMemoryStatType((EShaderFrequency)Target.Frequency).GetName(), Code.Num());
	DEC_DWORD_STAT_BY(STAT_Shaders_ShaderResourceMemory, GetSizeBytes());
	DEC_DWORD_STAT_BY(STAT_Shaders_NumShaderResourcesLoaded, 1);
}
Example #3
0
void FShader::Release()
{
	check(NumRefs != 0);
	if(--NumRefs == 0)
	{
		DEC_DWORD_STAT_BY(STAT_Shaders_ShaderMemory, GetSizeBytes());
		DEC_DWORD_STAT_BY(STAT_Shaders_NumShadersLoaded,1);

		// Deregister the shader now to eliminate references to it by the type's ShaderIdMap
		Deregister();

		BeginCleanup(this);
	}
}
Example #4
0
int32 FAsyncIOSystemBase::CancelRequests( uint64* RequestIndices, int32 NumIndices )
{
	FScopeLock ScopeLock( CriticalSection );

	// Iterate over all outstanding requests and cancel matching ones.
	int32 RequestsCanceled = 0;
	for( int32 OutstandingIndex=OutstandingRequests.Num()-1; OutstandingIndex>=0 && RequestsCanceled<NumIndices; OutstandingIndex-- )
	{
		// Iterate over all indices of requests to cancel
		for( int32 TheRequestIndex=0; TheRequestIndex<NumIndices; TheRequestIndex++ )
		{
			// Look for matching request index in queue.
			const FAsyncIORequest IORequest = OutstandingRequests[OutstandingIndex];
			if( IORequest.RequestIndex == RequestIndices[TheRequestIndex] )
			{
				INC_DWORD_STAT( STAT_AsyncIO_CanceledReadCount );
				INC_DWORD_STAT_BY( STAT_AsyncIO_CanceledReadSize, IORequest.Size );
				DEC_DWORD_STAT( STAT_AsyncIO_OutstandingReadCount );
				DEC_DWORD_STAT_BY( STAT_AsyncIO_OutstandingReadSize, IORequest.Size );				
				// Decrement thread-safe counter to indicate that request has been "completed".
				IORequest.Counter->Decrement();
				// IORequest variable no longer valid after removal.
				OutstandingRequests.RemoveAt( OutstandingIndex );
				RequestsCanceled++;
				// Break out of loop as we've modified OutstandingRequests AND it no longer is valid.
				break;
			}
		}
	}
	return RequestsCanceled;
}
void FStreamingWaveData::FreeLoadedChunk(FLoadedAudioChunk& LoadedChunk)
{
	if (LoadedChunk.Data != NULL)
	{
		FMemory::Free(LoadedChunk.Data);

		// Stat housekeeping
		DEC_DWORD_STAT_BY(STAT_AudioMemorySize, LoadedChunk.MemorySize);
		DEC_DWORD_STAT_BY(STAT_AudioMemory, LoadedChunk.MemorySize);

		LoadedChunk.Data = NULL;
		LoadedChunk.DataSize = 0;
		LoadedChunk.MemorySize = 0;
		LoadedChunk.Index = 0;
	}
}
Example #6
0
	virtual void ReleaseRHI() override
	{
		DEC_DWORD_STAT_BY( STAT_TextureMemory, TextureSize );
		DEC_DWORD_STAT_FNAME_BY( LODGroupStatName, TextureSize );
		RHIUpdateTextureReference(Owner->TextureReference.TextureReferenceRHI,FTextureRHIParamRef());
		TextureCubeRHI.SafeRelease();
		FTextureResource::ReleaseRHI();
	}
Example #7
0
void FStaticShadowDepthMap::Empty()
{
	DEC_DWORD_STAT_BY(STAT_PrecomputedShadowDepthMapMemory, DepthSamples.GetAllocatedSize());

	ShadowMapSizeX = 0;
	ShadowMapSizeY = 0;
	DepthSamples.Empty();
}
FPrecomputedLightVolume::~FPrecomputedLightVolume()
{
	if (bInitialized)
	{
		const SIZE_T VolumeBytes = GetAllocatedBytes();
		DEC_DWORD_STAT_BY(STAT_PrecomputedLightVolumeMemory, VolumeBytes);
	}
}
Example #9
0
void FShader::Release()
{
	// Lock the shader id map. Note that we don't necessarily have to deregister at this point but
	// the shader id map has to be locked while we remove references to this shader so that nothing
	// can find the shader in the map after we remove the final reference but before we deregister the shader
	LockShaderIdMap();
	if(--NumRefs == 0)
	{
		DEC_DWORD_STAT_BY(STAT_Shaders_ShaderMemory, GetSizeBytes());
		DEC_DWORD_STAT_BY(STAT_Shaders_NumShadersLoaded,1);

		// Deregister the shader now to eliminate references to it by the type's ShaderIdMap
		Deregister();

		Canary = ShaderMagic_CleaningUp;
		BeginCleanup(this);
	}
	UnlockShaderIdMap();
}
Example #10
0
void USoundWave::FreeResources()
{
	// Housekeeping of stats
	DEC_FLOAT_STAT_BY( STAT_AudioBufferTime, Duration );
	DEC_FLOAT_STAT_BY( STAT_AudioBufferTimeChannels, NumChannels * Duration );

	// GEngine is NULL during script compilation and GEngine->Client and its audio device might be
	// destroyed first during the exit purge.
	if( GEngine && !GExitPurge )
	{
		// Notify the audio device to free the bulk data associated with this wave.
		FAudioDevice* AudioDevice = GEngine->GetAudioDevice();
		if (AudioDevice != NULL)
		{
			TArray<UAudioComponent*> StoppedComponents;
			AudioDevice->StopSoundsUsingResource(this, StoppedComponents);
			AudioDevice->FreeResource( this );
		}
	}

	// Just in case the data was created but never uploaded
	if (RawPCMData != NULL)
	{
		FMemory::Free(RawPCMData);
		RawPCMData = NULL;
	}

	// Remove the compressed copy of the data
	RemoveAudioResource();

	// Stat housekeeping
	DEC_DWORD_STAT_BY(STAT_AudioMemorySize, TrackedMemoryUsage);
	DEC_DWORD_STAT_BY(STAT_AudioMemory, TrackedMemoryUsage);
	TrackedMemoryUsage = 0;

	SampleRate = 0;
	Duration = 0.0f;
	ResourceID = 0;
	bDynamicResource = false;
	DecompressionType = DTYPE_Setup;
	bDecompressedFromOgg = 0;
	RawPCMDataSize = 0;
}
Example #11
0
void FShaderResource::ReleaseRHI()
{
	DEC_DWORD_STAT_BY(STAT_Shaders_NumShadersUsedForRendering, 1);

	VertexShader.SafeRelease();
	PixelShader.SafeRelease();
	HullShader.SafeRelease();
	DomainShader.SafeRelease();
	GeometryShader.SafeRelease();
	ComputeShader.SafeRelease();
}
void UFontBulkData::Unlock() const
{
	bool bWasLoaded = BulkData.IsBulkDataLoaded();
	int32 BulkDataSize = BulkData.GetBulkDataSize(); 
	BulkData.Unlock();

#if STATS
	if( bWasLoaded && !BulkData.IsBulkDataLoaded() )
	{
		DEC_DWORD_STAT_BY( STAT_SlateBulkFontDataMemory, BulkDataSize );
	}
#endif
	CriticalSection.Unlock();
}
Example #13
0
void FShaderResource::InitRHI()
{
	checkf(Code.Num() > 0, TEXT("FShaderResource::InitRHI was called with empty bytecode, which can happen if the resource is initialized multiple times on platforms with no editor data."));

	// we can't have this called on the wrong platform's shaders
	if (!ArePlatformsCompatible(GMaxRHIShaderPlatform, (EShaderPlatform)Target.Platform))
 	{
 		if (FPlatformProperties::RequiresCookedData())
 		{
 			UE_LOG(LogShaders, Fatal, TEXT("FShaderResource::InitRHI got platform %s but it is not compatible with %s"), 
				*LegacyShaderPlatformToShaderFormat((EShaderPlatform)Target.Platform).ToString(), *LegacyShaderPlatformToShaderFormat(GMaxRHIShaderPlatform).ToString());
 		}
 		return;
 	}

	INC_DWORD_STAT_BY(STAT_Shaders_NumShadersUsedForRendering, 1);
	SCOPE_CYCLE_COUNTER(STAT_Shaders_RTShaderLoadTime);

	if(Target.Frequency == SF_Vertex)
	{
		VertexShader = RHICreateVertexShader(Code);
	}
	else if(Target.Frequency == SF_Pixel)
	{
		PixelShader = RHICreatePixelShader(Code);
	}
	else if(Target.Frequency == SF_Hull)
	{
		HullShader = RHICreateHullShader(Code);
	}
	else if(Target.Frequency == SF_Domain)
	{
		DomainShader = RHICreateDomainShader(Code);
	}
	else if(Target.Frequency == SF_Geometry)
	{
		GeometryShader = RHICreateGeometryShader(Code);
	}
	else if(Target.Frequency == SF_Compute)
	{
		ComputeShader = RHICreateComputeShader(Code);
	}

	if (!FPlatformProperties::HasEditorOnlyData())
	{
		DEC_DWORD_STAT_BY_FName(GetMemoryStatType((EShaderFrequency)Target.Frequency).GetName(), Code.Num());
		DEC_DWORD_STAT_BY(STAT_Shaders_ShaderResourceMemory, Code.GetAllocatedSize());
		Code.Empty();
	}
}
Example #14
0
void FShaderResource::InitRHI()
{
	checkf(Code.Num() > 0, TEXT("FShaderResource::InitRHI was called with empty bytecode, which can happen if the resource is initialized multiple times on platforms with no editor data."));

	// we can't have this called on the wrong platform's shaders
	if (!ArePlatformsCompatible(GMaxRHIShaderPlatform, (EShaderPlatform)Target.Platform))
 	{
 		if (FPlatformProperties::RequiresCookedData())
 		{
 			UE_LOG(LogShaders, Fatal, TEXT("FShaderResource::InitRHI got platform %s but it is not compatible with %s"), 
				*LegacyShaderPlatformToShaderFormat((EShaderPlatform)Target.Platform).ToString(), *LegacyShaderPlatformToShaderFormat(GMaxRHIShaderPlatform).ToString());
 		}
 		return;
 	}

	INC_DWORD_STAT_BY(STAT_Shaders_NumShadersUsedForRendering, 1);
	SCOPE_CYCLE_COUNTER(STAT_Shaders_RTShaderLoadTime);

	FShaderCache* ShaderCache = FShaderCache::GetShaderCache();

	if(Target.Frequency == SF_Vertex)
	{
		VertexShader = ShaderCache ? ShaderCache->GetVertexShader((EShaderPlatform)Target.Platform, OutputHash, Code) : RHICreateVertexShader(Code);
	}
	else if(Target.Frequency == SF_Pixel)
	{
		PixelShader = ShaderCache ? ShaderCache->GetPixelShader((EShaderPlatform)Target.Platform, OutputHash, Code) : RHICreatePixelShader(Code);
	}
	else if(Target.Frequency == SF_Hull)
	{
		HullShader = ShaderCache ? ShaderCache->GetHullShader((EShaderPlatform)Target.Platform, OutputHash, Code) : RHICreateHullShader(Code);
	}
	else if(Target.Frequency == SF_Domain)
	{
		DomainShader = ShaderCache ? ShaderCache->GetDomainShader((EShaderPlatform)Target.Platform, OutputHash, Code) : RHICreateDomainShader(Code);
	}
	else if(Target.Frequency == SF_Geometry)
	{
		if (SpecificType)
		{
			FStreamOutElementList ElementList;
			TArray<uint32> StreamStrides;
			int32 RasterizedStream = -1;
			SpecificType->GetStreamOutElements(ElementList, StreamStrides, RasterizedStream);
			checkf(ElementList.Num(), *FString::Printf(TEXT("Shader type %s was given GetStreamOutElements implementation that had no elements!"), SpecificType->GetName()));

			//@todo - not using the cache
			GeometryShader = RHICreateGeometryShaderWithStreamOutput(Code, ElementList, StreamStrides.Num(), StreamStrides.GetData(), RasterizedStream);
		}
		else
		{
			GeometryShader = ShaderCache ? ShaderCache->GetGeometryShader((EShaderPlatform)Target.Platform, OutputHash, Code) : RHICreateGeometryShader(Code);
		}
	}
	else if(Target.Frequency == SF_Compute)
	{
		ComputeShader = ShaderCache ? ShaderCache->GetComputeShader((EShaderPlatform)Target.Platform, Code) : RHICreateComputeShader(Code);
	}

	if (Target.Frequency != SF_Geometry)
	{
		checkf(!SpecificType, *FString::Printf(TEXT("Only geometry shaders can use GetStreamOutElements, shader type %s"), SpecificType->GetName()));
	}

	if (!FPlatformProperties::HasEditorOnlyData())
	{
		DEC_DWORD_STAT_BY_FName(GetMemoryStatType((EShaderFrequency)Target.Frequency).GetName(), Code.Num());
		DEC_DWORD_STAT_BY(STAT_Shaders_ShaderResourceMemory, Code.GetAllocatedSize());
		Code.Empty();
	}
}
void FEnvQueryInstance::ExecuteOneStep(double InTimeLimit)
{
	if (!Owner.IsValid())
	{
		Status = EEnvQueryStatus::OwnerLost;
		return;
	}

	FEnvQueryOptionInstance& OptionItem = Options[OptionIndex];
	CONDITIONAL_SCOPE_CYCLE_COUNTER(STAT_AI_EnvQuery_GeneratorTime, CurrentTest < 0);
	CONDITIONAL_SCOPE_CYCLE_COUNTER(STAT_AI_EnvQuery_TestTime, CurrentTest >= 0);

	bool bStepDone = true;
	TimeLimit = InTimeLimit;

	if (CurrentTest < 0)
	{
		DEC_DWORD_STAT_BY(STAT_AI_EnvQuery_NumItems, Items.Num());

		RawData.Reset();
		Items.Reset();
		ItemType = OptionItem.ItemType;
		ValueSize = ((UEnvQueryItemType*)ItemType->GetDefaultObject())->GetValueSize();

		OptionItem.GenerateDelegate.Execute(*this);
		FinalizeGeneration();
	}
	else
	{
		const int32 ItemsAlreadyProcessed = CurrentTestStartingItem;
		OptionItem.TestDelegates[CurrentTest].Execute(*this);
		bStepDone = CurrentTestStartingItem >= Items.Num() || bFoundSingleResult
			// or no items processed ==> this means error
			|| (ItemsAlreadyProcessed == CurrentTestStartingItem);

		if (bStepDone)
		{
			FinalizeTest();
		}
	}
	
	if (bStepDone)
	{
#if WITH_EDITOR
		if (bStoreDebugInfo)
		{
			DebugData.Store(this);
		}
#endif // WITH_EDITOR

		CurrentTest++;
		CurrentTestStartingItem = 0;
	}

	// sort results or switch to next option when all tests are performed
	if (Status == EEnvQueryStatus::Processing &&
		(OptionItem.TestDelegates.Num() == CurrentTest || NumValidItems <= 0))
	{
		if (NumValidItems > 0)
		{
			// found items, sort and finish
			FinalizeQuery();
		}
		else
		{
			// no items here, go to next option or finish			
			if (OptionIndex + 1 >= Options.Num())
			{
				// out of options, finish processing without errors
				FinalizeQuery();
			}
			else
			{
				// not doing it always for debugging purposes
				OptionIndex++;
				CurrentTest = -1;
			}
		}
	}
}
Example #16
0
void FAsyncIOSystemBase::Tick()
{
	// Create file handles.
	{
		TArray<FString> FileNamesToCacheHandles; 
		// Only enter critical section for copying existing array over. We don't operate on the 
		// real array as creating file handles might take a while and we don't want to have other
		// threads stalling on submission of requests.
		{
			FScopeLock ScopeLock( CriticalSection );

			for( int32 RequestIdx=0; RequestIdx<OutstandingRequests.Num(); RequestIdx++ )
			{
				// Early outs avoid unnecessary work and string copies with implicit allocator churn.
				FAsyncIORequest& OutstandingRequest = OutstandingRequests[RequestIdx];
				if( OutstandingRequest.bHasAlreadyRequestedHandleToBeCached == false
				&&	OutstandingRequest.bIsDestroyHandleRequest == false 
				&&	FindCachedFileHandle( OutstandingRequest.FileNameHash ) == NULL )
				{
					new(FileNamesToCacheHandles)FString(*OutstandingRequest.FileName);
					OutstandingRequest.bHasAlreadyRequestedHandleToBeCached = true;
				}
			}
		}
		// Create file handles for requests down the pipe. This is done here so we can later on
		// use the handles to figure out the sort keys.
		for( int32 FileNameIndex=0; FileNameIndex<FileNamesToCacheHandles.Num(); FileNameIndex++ )
		{
			GetCachedFileHandle( FileNamesToCacheHandles[FileNameIndex] );
		}
	}

	// Copy of request.
	FAsyncIORequest IORequest;
	bool			bIsRequestPending	= false;
	{
		FScopeLock ScopeLock( CriticalSection );
		if( OutstandingRequests.Num() )
		{
			// Gets next request index based on platform specific criteria like layout on disc.
			int32 TheRequestIndex = PlatformGetNextRequestIndex();
			if( TheRequestIndex != INDEX_NONE )
			{					
				// We need to copy as we're going to remove it...
				IORequest = OutstandingRequests[ TheRequestIndex ];
				// ...right here.
				// NOTE: this needs to be a Remove, not a RemoveSwap because the base implementation
				// of PlatformGetNextRequestIndex is a FIFO taking priority into account
				OutstandingRequests.RemoveAt( TheRequestIndex );		
				// We're busy. Updated inside scoped lock to ensure BlockTillAllRequestsFinished works correctly.
				BusyWithRequest.Increment();
				bIsRequestPending = true;
			}
		}
	}

	// We only have work to do if there's a request pending.
	if( bIsRequestPending )
	{
		// handle a destroy handle request from the queue
		if( IORequest.bIsDestroyHandleRequest )
		{
			IFileHandle*	FileHandle = FindCachedFileHandle( IORequest.FileNameHash );
			if( FileHandle )
			{
				// destroy and remove the handle
				delete FileHandle;
				NameHashToHandleMap.Remove(IORequest.FileNameHash);
			}
		}
		else
		{
			// Retrieve cached handle or create it if it wasn't cached. We purposefully don't look at currently
			// set value as it might be stale by now.
			IFileHandle* FileHandle = GetCachedFileHandle( IORequest.FileName );
			if( FileHandle )
			{
				if( IORequest.UncompressedSize )
				{
					// Data is compressed on disc so we need to also decompress.
					FulfillCompressedRead( IORequest, FileHandle );
				}
				else
				{
					// Read data after seeking.
					InternalRead( FileHandle, IORequest.Offset, IORequest.Size, IORequest.Dest );
				}
				INC_DWORD_STAT( STAT_AsyncIO_FulfilledReadCount );
				INC_DWORD_STAT_BY( STAT_AsyncIO_FulfilledReadSize, IORequest.Size );
			}
			else
			{
				//@todo streaming: add warning once we have thread safe logging.
			}

			DEC_DWORD_STAT( STAT_AsyncIO_OutstandingReadCount );
			DEC_DWORD_STAT_BY( STAT_AsyncIO_OutstandingReadSize, IORequest.Size );
		}

		// Request fulfilled.
		if( IORequest.Counter )
		{
			IORequest.Counter->Decrement(); 
		}
		// We're done reading for now.
		BusyWithRequest.Decrement();	
	}
	else
	{
		if( !OutstandingRequests.Num() && FPlatformProcess::SupportsMultithreading() )
		{
			// We're really out of requests now, wait till the calling thread signals further work
			OutstandingRequestsEvent->Wait();
		}
	}
}
Example #17
0
FShaderResource::~FShaderResource()
{
	DEC_DWORD_STAT_BY_FName(GetMemoryStatType((EShaderFrequency)Target.Frequency).GetName(), Code.Num());
	DEC_DWORD_STAT_BY(STAT_Shaders_ShaderResourceMemory, GetSizeBytes());
	DEC_DWORD_STAT_BY(STAT_Shaders_NumShaderResourcesLoaded, 1);
}
FNavigationOctree::~FNavigationOctree()
{
	DEC_DWORD_STAT_BY( STAT_NavigationMemory, sizeof(*this) );
	DEC_MEMORY_STAT_BY(STAT_Navigation_CollisionTreeMemory, NodesMemory);
}