You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Code/Tools/Standalone/Source/Driller/Profiler/ProfilerEvents.h

241 lines
8.8 KiB
C++

/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#ifndef DRILLER_PROFILER_EVENTS_H
#define DRILLER_PROFILER_EVENTS_H
#include "Source/Driller/DrillerEvent.h"
namespace Driller
{
namespace Profiler
{
/// Time register data.
struct TimeData
{
AZ::u64 m_time; ///< Total inclusive time current and children in microseconds.
AZ::u64 m_childrenTime; ///< Time taken by child profilers in microseconds.
AZ::s64 m_calls; ///< Number of calls for this register.
AZ::s64 m_childrenCalls;///< Number of children calls.
AZ::u64 m_lastParentRegisterId; ///< Id of the last parent register.
};
/// Value register data.
struct ValuesData
{
AZ::s64 m_value1;
AZ::s64 m_value2;
AZ::s64 m_value3;
AZ::s64 m_value4;
AZ::s64 m_value5;
};
/// Data that will change every frame (technically only when registers are called)
struct RegisterData
{
RegisterData()
{
m_valueData.m_value1 = 0;
m_valueData.m_value2 = 0;
m_valueData.m_value3 = 0;
m_valueData.m_value4 = 0;
m_valueData.m_value5 = 0;
}
union
{
TimeData m_timeData;
ValuesData m_valueData;
};
};
/// Data that never changes
struct RegisterInfo
{
RegisterInfo()
: m_id(0)
, m_threadId(0)
, m_name(nullptr)
, m_function(nullptr)
, m_line(-1)
, m_systemId(0)
{}
enum Type
{
PRT_TIME = 0, ///< Time register - RegisterData::m_time data is used.
PRT_VALUE, ///< Value register - RegisterData::m_values data is used.
};
unsigned char m_type; ///< Register type (time or values)
AZ::u64 m_id; ///< Register id (technically the pointer during execution).
AZ::u64 m_threadId; ///< Native thread handle (AZStd::native_thread_id_type) typically a pointer too.
const char* m_name; ///< Name/description of the register it's optional for time registers.
const char* m_function; ///< Name of the function which we are sampling.
int m_line; ///< Line in the code where this register is created (start sampling).
AZ::u32 m_systemId; ///< Crc32 of the system name provided by the user.
};
enum ProfilerEventType
{
PET_NEW_REGISTER = 0,
PET_UPDATE_REGISTER,
PET_ENTER_THREAD,
PET_EXIT_THREAD,
PET_REGISTER_SYSTEM,
PET_UNREGISTER_SYSTEM,
};
}
class ProfilerDrillerNewRegisterEvent;
class ProfilerDataAggregator;
class ProfilerDrillerUpdateRegisterEvent
: public DrillerEvent
{
friend class ProfilerDrillerNewRegisterEvent;
friend class ProfilerDrillerHandlerParser;
public:
AZ_CLASS_ALLOCATOR(ProfilerDrillerUpdateRegisterEvent, AZ::SystemAllocator, 0)
ProfilerDrillerUpdateRegisterEvent()
: DrillerEvent(Profiler::PET_UPDATE_REGISTER)
, m_register(nullptr)
, m_previousSample(nullptr)
{}
virtual void StepForward(Aggregator* data);
virtual void StepBackward(Aggregator* data);
void PreComputeForward(ProfilerDrillerNewRegisterEvent* newEvt);
const Profiler::RegisterData& GetData() const { return m_registerData; }
const ProfilerDrillerNewRegisterEvent* GetRegister() const { return m_register; }
const ProfilerDrillerUpdateRegisterEvent* GetPreviousSample() const { return m_previousSample; }
const AZ::u64 GetRegisterId() const { return m_registerId; }
private:
AZ::u64 m_registerId; ///< Id if the register.
Profiler::RegisterData m_registerData; ///< Register sample data.
ProfilerDrillerNewRegisterEvent* m_register; ///< Cached pointer to the register.
ProfilerDrillerUpdateRegisterEvent* m_previousSample; ///< Pointer to the previous register values (null if this is the first sample).
};
class ProfilerDrillerNewRegisterEvent
: public DrillerEvent
{
friend class ProfilerDrillerUpdateRegisterEvent;
friend class ProfilerDrillerHandlerParser;
public:
AZ_CLASS_ALLOCATOR(ProfilerDrillerNewRegisterEvent, AZ::SystemAllocator, 0)
ProfilerDrillerNewRegisterEvent()
: DrillerEvent(Profiler::PET_NEW_REGISTER)
, m_lastUpdate(nullptr)
, m_lastPrecomputed(nullptr)
{}
virtual void StepForward(Aggregator* data);
virtual void StepBackward(Aggregator* data);
const Profiler::RegisterData& GetData() const { return m_lastUpdate ? m_lastUpdate->m_registerData : m_registerData; }
const Profiler::RegisterInfo& GetInfo() const { return m_registerInfo; }
const ProfilerDrillerUpdateRegisterEvent* GetLastSample() const { return m_lastUpdate; }
private:
Profiler::RegisterInfo m_registerInfo; ///< Register information.
Profiler::RegisterData m_registerData; ///< Register sample data.
// m_lastUpdate is actually also the current scrubber frame for that register.
ProfilerDrillerUpdateRegisterEvent* m_lastUpdate; ///< Pointer to the last set of RegisterData (null if there is not last set)
// because we precompute a small number of registers in order to show the note track in the main view, we need
// a seperate pointer to the prior precomputed data.
ProfilerDrillerUpdateRegisterEvent* m_lastPrecomputed;
};
class ProfilerDrillerEnterThreadEvent
: public DrillerEvent
{
public:
AZ_CLASS_ALLOCATOR(ProfilerDrillerEnterThreadEvent, AZ::SystemAllocator, 0)
ProfilerDrillerEnterThreadEvent()
: DrillerEvent(Profiler::PET_ENTER_THREAD)
{}
virtual void StepForward(Aggregator* data);
virtual void StepBackward(Aggregator* data);
AZ::u64 m_threadId;
const char* m_threadName; ///< Debug name of thread if one is provided.
AZ::s32 m_cpuId; ///< If of the CPU where this thread should run.
AZ::s32 m_priority;
AZ::u32 m_stackSize;
};
class ProfilerDrillerExitThreadEvent
: public DrillerEvent
{
public:
AZ_CLASS_ALLOCATOR(ProfilerDrillerExitThreadEvent, AZ::SystemAllocator, 0)
ProfilerDrillerExitThreadEvent()
: DrillerEvent(Profiler::PET_EXIT_THREAD)
, m_threadData(nullptr)
{}
virtual void StepForward(Aggregator* data);
virtual void StepBackward(Aggregator* data);
AZ::u64 m_threadId;
ProfilerDrillerEnterThreadEvent* m_threadData;
};
class ProfilerDrillerRegisterSystemEvent
: public DrillerEvent
{
public:
AZ_CLASS_ALLOCATOR(ProfilerDrillerRegisterSystemEvent, AZ::SystemAllocator, 0)
ProfilerDrillerRegisterSystemEvent()
: DrillerEvent(Profiler::PET_REGISTER_SYSTEM)
{}
virtual void StepForward(Aggregator* data);
virtual void StepBackward(Aggregator* data);
AZ::u32 m_systemId;
const char* m_name; ///< Debug name of thread system.
};
class ProfilerDrillerUnregisterSystemEvent
: public DrillerEvent
{
public:
AZ_CLASS_ALLOCATOR(ProfilerDrillerUnregisterSystemEvent, AZ::SystemAllocator, 0)
ProfilerDrillerUnregisterSystemEvent()
: DrillerEvent(Profiler::PET_UNREGISTER_SYSTEM)
, m_systemData(nullptr)
{}
virtual void StepForward(Aggregator* data);
virtual void StepBackward(Aggregator* data);
AZ::u32 m_systemId;
ProfilerDrillerRegisterSystemEvent* m_systemData;
};
}
#endif