AkJobWorkerScheduler.cpp 3.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /*******************************************************************************
  2. The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
  3. Technology released in source code form as part of the game integration package.
  4. The content of this file may not be used without valid licenses to the
  5. AUDIOKINETIC Wwise Technology.
  6. Note that the use of the game engine is subject to the Unreal(R) Engine End User
  7. License Agreement at https://www.unrealengine.com/en-US/eula/unreal
  8. License Usage
  9. Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
  10. this file in accordance with the end user license agreement provided with the
  11. software or, alternatively, in accordance with the terms contained
  12. in a written agreement between you and Audiokinetic Inc.
  13. Copyright (c) 2023 Audiokinetic Inc.
  14. *******************************************************************************/
  15. #include "AkJobWorkerScheduler.h"
  16. #include "AkAudioDevice.h"
  17. #include "Wwise/API/WwiseMemoryMgrAPI.h"
  18. #define AK_DECLARE_JOB_TYPE(__job__, __desc__, __thread__) \
  19. DECLARE_CYCLE_STAT(TEXT(__desc__), STAT_AkJob##__job__, STATGROUP_Audio); \
  20. static ENamedThreads::Type kThread##__job__ = __thread__;
  21. #define AK_DEFINE_JOB_CASE(__job__) \
  22. case AkJobType_##__job__: \
  23. jobStatId = GET_STATID(STAT_AkJob##__job__); \
  24. jobThreadType = kThread##__job__
  25. static_assert(AK_NUM_JOB_TYPES == 3, "Update the stat groups and switch cases below for new job types!");
  26. AK_DECLARE_JOB_TYPE(Generic, "Wwise Generic Job", ENamedThreads::AnyHiPriThreadNormalTask);
  27. AK_DECLARE_JOB_TYPE(AudioProcessing, "Wwise Audio Processing Job", ENamedThreads::AnyHiPriThreadNormalTask);
  28. AK_DECLARE_JOB_TYPE(SpatialAudio, "Wwise Spatial Audio Job", ENamedThreads::AnyHiPriThreadNormalTask);
  29. static void OnJobWorkerRequest(AkJobWorkerFunc in_fnJobWorker, AkJobType in_jobType, AkUInt32 in_uNumWorkers, void* in_pUserData)
  30. {
  31. FAkJobWorkerScheduler* pScheduler = static_cast<FAkJobWorkerScheduler*>(in_pUserData);
  32. AkUInt32 uMaxExecutionTime = pScheduler->uMaxExecutionTime;
  33. TStatId jobStatId;
  34. ENamedThreads::Type jobThreadType;
  35. switch (in_jobType)
  36. {
  37. AK_DEFINE_JOB_CASE(AudioProcessing); break;
  38. AK_DEFINE_JOB_CASE(SpatialAudio); break;
  39. default:
  40. check(!"Unknown job type.");
  41. // Fall-through
  42. AK_DEFINE_JOB_CASE(Generic);
  43. }
  44. for (int i=0; i < (int)in_uNumWorkers; i++)
  45. {
  46. FFunctionGraphTask::CreateAndDispatchWhenReady([=]() {
  47. in_fnJobWorker(in_jobType, uMaxExecutionTime);
  48. // After completion of the worker function, release any thread-local memory resources
  49. if (auto* MemoryManager = IWwiseMemoryMgrAPI::Get())
  50. {
  51. MemoryManager->TrimForThread();
  52. }
  53. }, jobStatId, nullptr, jobThreadType);
  54. }
  55. }
  56. void FAkJobWorkerScheduler::InstallJobWorkerScheduler(uint32 in_uMaxExecutionTime, uint32 in_uMaxWorkerCount, AkJobMgrSettings & out_settings)
  57. {
  58. if (!FTaskGraphInterface::Get().IsRunning())
  59. {
  60. UE_LOG(LogAkAudio, Warning, TEXT("Multi-core rendering was requested, but Task Graph is not running. Multi-core rendering disabled."));
  61. }
  62. else if (!FPlatformProcess::SupportsMultithreading())
  63. {
  64. UE_LOG(LogAkAudio, Warning, TEXT("Multi-core rendering was requested, platform does not support multi-threading. Multi-core rendering disabled."));
  65. }
  66. else
  67. {
  68. check(ENamedThreads::bHasHighPriorityThreads);
  69. uMaxExecutionTime = in_uMaxExecutionTime;
  70. AkUInt32 uNumWorkerThreads = FTaskGraphInterface::Get().GetNumWorkerThreads();
  71. AkUInt32 uMaxActiveWorkers = FMath::Min(uNumWorkerThreads, in_uMaxWorkerCount);
  72. if (uMaxActiveWorkers > 0)
  73. {
  74. out_settings.fnRequestJobWorker = OnJobWorkerRequest;
  75. out_settings.pClientData = this;
  76. for (int i = 0; i < AK_NUM_JOB_TYPES; i++)
  77. {
  78. out_settings.uMaxActiveWorkers[i] = uMaxActiveWorkers;
  79. }
  80. }
  81. else
  82. {
  83. UE_LOG(LogAkAudio, Warning, TEXT("Multi-core rendering was requested, but Max Num Job Workers is set to 0. Multi-core rendering disabled."));
  84. }
  85. }
  86. }