TracyProfilerEventForwarder.cpp 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <TracyProfilerEventForwarder.h>
  9. #include <AzCore/Interface/Interface.h>
  10. #include <AzCore/Serialization/SerializeContext.h>
  11. namespace TracyProfiler
  12. {
  13. thread_local TracyProfilerEventForwarder::EventIdStack TracyProfilerEventForwarder::ms_threadLocalStorage;
  14. void TracyProfilerEventForwarder::Init()
  15. {
  16. AZ::Interface<AZ::Debug::Profiler>::Register(this);
  17. AZ::TickBus::Handler::BusConnect();
  18. m_initialized = true;
  19. }
  20. void TracyProfilerEventForwarder::Shutdown()
  21. {
  22. if (!m_initialized)
  23. {
  24. return;
  25. }
  26. // When this call is made, no more thread profiling calls can be performed anymore
  27. AZ::Interface<AZ::Debug::Profiler>::Unregister(this);
  28. // Wait for the remaining threads that might still be processing its profiling calls
  29. AZStd::unique_lock<AZStd::shared_mutex> shutdownLock(m_shutdownMutex);
  30. AZ::TickBus::Handler::BusDisconnect();
  31. }
  32. void TracyProfilerEventForwarder::BeginRegion(const AZ::Debug::Budget* budget, const char* eventName, ...)
  33. {
  34. // Try to lock here, the shutdownMutex will only be contested when the CpuProfiler is shutting down.
  35. if (m_shutdownMutex.try_lock_shared())
  36. {
  37. // Do not use the macro as we don't want to use static storage (else events are wrong)
  38. ms_threadLocalStorage.push_back({});
  39. TracyCZoneCtx& ctx = ms_threadLocalStorage.back();
  40. ctx = ___tracy_emit_zone_begin_alloc_callstack(
  41. ___tracy_alloc_srcloc_name(
  42. __LINE__, __FILE__, strlen(__FILE__), __FUNCTION__, strlen(__FUNCTION__), eventName, strlen(eventName), budget->Crc()),
  43. TRACY_CALLSTACK,
  44. true);
  45. TracyCZoneText(ctx, budget->Name(), 1);
  46. m_shutdownMutex.unlock_shared();
  47. }
  48. }
  49. void TracyProfilerEventForwarder::EndRegion([[maybe_unused]] const AZ::Debug::Budget* budget)
  50. {
  51. // Try to lock here, the shutdownMutex will only be contested when the CpuProfiler is shutting down.
  52. if (m_shutdownMutex.try_lock_shared() && !ms_threadLocalStorage.empty())
  53. {
  54. auto& ctx = ms_threadLocalStorage.back();
  55. TracyCZoneEnd(ctx);
  56. ms_threadLocalStorage.pop_back();
  57. m_shutdownMutex.unlock_shared();
  58. }
  59. }
  60. int TracyProfilerEventForwarder::GetTickOrder()
  61. {
  62. return AZ::ComponentTickBus::TICK_LAST;
  63. }
  64. void TracyProfilerEventForwarder::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint timePoint)
  65. {
  66. // From Tracy documentation about FrameMark : "Ideally, that would be right after the swap buffers command"
  67. TracyCFrameMark;
  68. }
  69. } // namespace TracyProfiler