123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- /*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
- #include <OptickProfilerEventForwarder.h>
- #include <AzCore/Debug/ProfilerBus.h>
- #include <AzCore/Interface/Interface.h>
- #include <AzCore/Serialization/SerializeContext.h>
- #include <AzCore/Utils/Utils.h>
- #include <AzCore/std/parallel/thread.h>
- #include <AzCore/std/time.h>
- #include <optick.h>
- namespace OptickProfiler
- {
- thread_local Optick::EventStorage* OptickProfilerEventForwarder::m_pOptickStorage = nullptr;
- bool OnOptickStateChanged(Optick::State::Type state)
- {
- switch (state)
- {
- case Optick::State::DUMP_CAPTURE:
- {
- auto projectName = AZ::Utils::GetProjectName();
- Optick::AttachSummary("Project", projectName.c_str());
- }
- break;
- }
- return true;
- }
- void OptickProfilerEventForwarder::Init()
- {
- AZ::Interface<AZ::Debug::Profiler>::Register(this);
- AZ::TickBus::Handler::BusConnect();
- AZStd::ThreadEventBus::Handler::BusConnect();
- Optick::SetStateChangedCallback(OnOptickStateChanged);
- m_pOptickFrameTag = Optick::EventDescription::Create("Frame", "", 0);
- m_pOptickStorage = Optick::RegisterStorage("Main Thread", AZStd::this_thread::get_id().m_id);
- m_initialized = true;
- }
- void OptickProfilerEventForwarder::Shutdown()
- {
- if (!m_initialized)
- {
- return;
- }
- // When this call is made, no more thread profiling calls can be performed anymore
- AZ::Interface<AZ::Debug::Profiler>::Unregister(this);
- // Wait for the remaining threads that might still be processing its profiling calls
- AZStd::unique_lock<AZStd::shared_mutex> shutdownLock(m_shutdownMutex);
- AZStd::ThreadEventBus::Handler::BusDisconnect();
- AZ::TickBus::Handler::BusDisconnect();
- Optick::StopCapture();
- Optick::Shutdown();
- }
- void OptickProfilerEventForwarder::BeginRegion(
- [[maybe_unused]] const AZ::Debug::Budget* budget, [[maybe_unused]] const char* eventName, ...)
- {
- if (!m_pOptickStorage && m_threadIdToNameMutex.try_lock_shared())
- {
- AZStd::native_thread_id_type id = AZStd::this_thread::get_id().m_id;
- const AZStd::string& name = m_threadIdToName.contains(id) ? m_threadIdToName.at(id) : "";
- m_pOptickStorage = Optick::RegisterStorage(name.c_str(), id);
- m_threadIdToNameMutex.unlock_shared();
- }
- // Try to lock here, the shutdownMutex will only be contested when the CpuProfiler is shutting down.
- if (m_shutdownMutex.try_lock_shared())
- {
- Optick::EventDescription* pDesc = Optick::EventDescription::CreateShared(eventName);
- Optick::Event::Push(m_pOptickStorage, pDesc, Optick::GetHighPrecisionTime());
- m_shutdownMutex.unlock_shared();
- }
- }
- void OptickProfilerEventForwarder::EndRegion([[maybe_unused]] const AZ::Debug::Budget* budget)
- {
- // Try to lock here, the shutdownMutex will only be contested when the CpuProfiler is shutting down.
- if (m_shutdownMutex.try_lock_shared())
- {
- Optick::Event::Pop(m_pOptickStorage, Optick::GetHighPrecisionTime());
- m_shutdownMutex.unlock_shared();
- }
- }
- int OptickProfilerEventForwarder::GetTickOrder()
- {
- return AZ::ComponentTickBus::TICK_FIRST;
- }
- void OptickProfilerEventForwarder::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint timePoint)
- {
- const int64_t frameTick = Optick::GetHighPrecisionTime();
- Optick::Event::Pop(m_pOptickStorage, frameTick);
- Optick::EndFrame(Optick::FrameType::CPU);
- Optick::Update();
- const uint32_t frameNumber = Optick::BeginFrame(Optick::FrameType::CPU, frameTick);
- Optick::Event::Push(m_pOptickStorage, Optick::GetFrameDescription(), frameTick);
- Optick::AttachTag(m_pOptickStorage, *m_pOptickFrameTag, frameNumber, frameTick);
- }
- void OptickProfilerEventForwarder::OnThreadEnter(const AZStd::thread::id& id, const AZStd::thread_desc* desc)
- {
- AZStd::unique_lock<AZStd::shared_mutex> lock(m_threadIdToNameMutex);
- m_threadIdToName[id.m_id] = desc->m_name;
- }
- void OptickProfilerEventForwarder::OnThreadExit([[maybe_unused]] const AZStd::thread::id& id)
- {
- }
- } // namespace OptickProfiler
|