Instrumentpr
- Added Instrumentor * Instrumentor (class) * InstrumentorTimer (class, used statically) * ScopeProfileResult (struct) - Tidy * wWindow::wWindow
This commit is contained in:
parent
3363239c8d
commit
cd30d0bba1
9 changed files with 171 additions and 15 deletions
|
@ -11,6 +11,8 @@
|
|||
|
||||
#include "UserInterface/UserInterface.h"
|
||||
|
||||
#include "Debug/Instrumentor.h"
|
||||
|
||||
#include "Time/Timer.h"
|
||||
|
||||
#include <filesystem>
|
||||
|
@ -20,12 +22,16 @@ namespace Light {
|
|||
Application::Application()
|
||||
{
|
||||
Logger::Initialize();
|
||||
m_Instrumentor = std::unique_ptr<Instrumentor>(Instrumentor::Create());
|
||||
|
||||
m_Instrumentor->BeginSession("Logs/ProfileResults_Startup.json");
|
||||
m_Window = std::unique_ptr<Light::Window>(Light::Window::Create(std::bind(&Light::Application::OnEvent, this, std::placeholders::_1)));
|
||||
}
|
||||
|
||||
Application::~Application()
|
||||
{
|
||||
LT_ENGINE_TRACE("Application::~Application()");
|
||||
m_Instrumentor->EndSession(); // ProfileResults_Termination //
|
||||
}
|
||||
|
||||
void Application::GameLoop()
|
||||
|
@ -42,29 +48,46 @@ namespace Light {
|
|||
// reveal window
|
||||
m_Window->SetVisibility(true);
|
||||
|
||||
DeltaTimer deltaTimer;
|
||||
m_Instrumentor->EndSession(); // ProfileResults_GameLoop //
|
||||
m_Instrumentor->BeginSession("Logs/ProfileResults_GameLoop.json");
|
||||
|
||||
//** GAMELOOP **//
|
||||
DeltaTimer deltaTimer;
|
||||
while (!m_Window->IsClosed())
|
||||
{
|
||||
// update layers
|
||||
m_LayerStack.OnUpdate(deltaTimer.GetDeltaTime());
|
||||
{
|
||||
// update layers
|
||||
LT_PROFILE_SCOPE("GameLoop::Update");
|
||||
m_LayerStack.OnUpdate(deltaTimer.GetDeltaTime());
|
||||
}
|
||||
|
||||
// render layers
|
||||
m_Window->GetGfxContext()->GetRenderer()->BeginFrame();
|
||||
m_LayerStack.OnRender();
|
||||
m_Window->GetGfxContext()->GetRenderer()->EndFrame();
|
||||
{
|
||||
// render layers
|
||||
LT_PROFILE_SCOPE("GameLoop::Render");
|
||||
m_Window->GetGfxContext()->GetRenderer()->BeginFrame();
|
||||
m_LayerStack.OnRender();
|
||||
m_Window->GetGfxContext()->GetRenderer()->EndFrame();
|
||||
}
|
||||
|
||||
// render user interface
|
||||
m_Window->GetGfxContext()->GetUserInterface()->Begin();
|
||||
m_Window->GetGfxContext()->GetUserInterface()->End();
|
||||
{
|
||||
// render user interface
|
||||
LT_PROFILE_SCOPE("GameLoop::UserInterface");
|
||||
m_Window->GetGfxContext()->GetUserInterface()->Begin();
|
||||
m_Window->GetGfxContext()->GetUserInterface()->End();
|
||||
}
|
||||
|
||||
// poll events
|
||||
m_Window->PollEvents();
|
||||
{
|
||||
// poll events
|
||||
LT_PROFILE_SCOPE("GameLoop::Events");
|
||||
m_Window->PollEvents();
|
||||
}
|
||||
|
||||
/// update delta time
|
||||
deltaTimer.Update();
|
||||
}
|
||||
|
||||
m_Instrumentor->EndSession(); // ProfileResults_GameLoop //
|
||||
m_Instrumentor->BeginSession("Logs/ProfileResults_Termination.json");
|
||||
}
|
||||
|
||||
void Application::OnEvent(const Event& event)
|
||||
|
|
|
@ -9,9 +9,12 @@ namespace Light {
|
|||
class Window;
|
||||
class Event;
|
||||
|
||||
class Instrumentor;
|
||||
|
||||
class Application
|
||||
{
|
||||
private:
|
||||
std::unique_ptr<Instrumentor> m_Instrumentor = nullptr;
|
||||
LayerStack m_LayerStack;
|
||||
|
||||
protected:
|
||||
|
|
70
Engine/src/Engine/Debug/Instrumentor.cpp
Normal file
70
Engine/src/Engine/Debug/Instrumentor.cpp
Normal file
|
@ -0,0 +1,70 @@
|
|||
#include "ltpch.h"
|
||||
#include "Instrumentor.h"
|
||||
|
||||
namespace Light {
|
||||
|
||||
Instrumentor* Instrumentor::s_Context = nullptr;
|
||||
|
||||
Instrumentor* Instrumentor::Create()
|
||||
{
|
||||
return new Instrumentor;
|
||||
}
|
||||
|
||||
Instrumentor::Instrumentor()
|
||||
{
|
||||
// #todo: maintenance
|
||||
LT_ENGINE_ASSERT(!s_Context, "Instrumentor::Instrumentor: an instance of 'Instrumentor' already exists, do not construct this class!");
|
||||
s_Context = this;
|
||||
}
|
||||
|
||||
void Instrumentor::BeginSessionImpl(const std::string& outputPath)
|
||||
{
|
||||
m_OutputFileStream.open(outputPath);
|
||||
m_OutputFileStream << "{\"traceEvents\":[";
|
||||
}
|
||||
|
||||
void Instrumentor::EndSessionImpl()
|
||||
{
|
||||
m_OutputFileStream << "]}";
|
||||
m_OutputFileStream.flush();
|
||||
m_OutputFileStream.close();
|
||||
}
|
||||
|
||||
void Instrumentor::SubmitScopeProfileImpl(const ScopeProfileResult& profileResult)
|
||||
{
|
||||
static bool test = true;
|
||||
|
||||
if (test)
|
||||
{
|
||||
test = false;
|
||||
m_OutputFileStream << "{";
|
||||
}
|
||||
else
|
||||
m_OutputFileStream << ",{";
|
||||
|
||||
m_OutputFileStream << "\"name\":\"" << profileResult.name << "\",";
|
||||
m_OutputFileStream << "\"cat\": \"scope\",";
|
||||
m_OutputFileStream << "\"ph\": \"X\",";
|
||||
m_OutputFileStream << "\"ts\":" << profileResult.start << ",";
|
||||
m_OutputFileStream << "\"dur\":" << profileResult.duration << ",";
|
||||
m_OutputFileStream << "\"pid\":0,";
|
||||
m_OutputFileStream << "\"tid\":" << profileResult.threadID<< "";
|
||||
m_OutputFileStream << "}";
|
||||
}
|
||||
|
||||
InstrumentorTimer::InstrumentorTimer(const std::string& scopeName)
|
||||
: m_Result( { scopeName, 0, 0, 0 } ), m_Start(std::chrono::steady_clock::now())
|
||||
{
|
||||
}
|
||||
|
||||
InstrumentorTimer::~InstrumentorTimer()
|
||||
{
|
||||
auto end = std::chrono::steady_clock::now();
|
||||
|
||||
m_Result.start = std::chrono::time_point_cast<std::chrono::microseconds>(m_Start).time_since_epoch().count();
|
||||
m_Result.duration = std::chrono::time_point_cast<std::chrono::microseconds>(end).time_since_epoch().count() - m_Result.start;
|
||||
|
||||
Instrumentor::SubmitScopeProfile(m_Result);
|
||||
}
|
||||
|
||||
}
|
59
Engine/src/Engine/Debug/Instrumentor.h
Normal file
59
Engine/src/Engine/Debug/Instrumentor.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
#pragma once
|
||||
|
||||
#include "Base.h"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace Light {
|
||||
|
||||
struct ScopeProfileResult
|
||||
{
|
||||
std::string name;
|
||||
long long start, duration;
|
||||
uint32_t threadID;
|
||||
};
|
||||
|
||||
// #todo: add event categories
|
||||
// #todo: use ofstream in a seperate thread
|
||||
class Instrumentor
|
||||
{
|
||||
private:
|
||||
static Instrumentor* s_Context;
|
||||
|
||||
std::ofstream m_OutputFileStream;
|
||||
bool m_FirstScopeProfile = true;
|
||||
|
||||
public:
|
||||
static Instrumentor* Create();
|
||||
|
||||
static inline void BeginSession(const std::string& outputPath) { s_Context->BeginSessionImpl(outputPath); }
|
||||
static inline void EndSession() { s_Context->EndSessionImpl(); }
|
||||
|
||||
static inline void SubmitScopeProfile(const ScopeProfileResult& profileResult) { s_Context->SubmitScopeProfileImpl(profileResult); }
|
||||
|
||||
private:
|
||||
Instrumentor();
|
||||
|
||||
void BeginSessionImpl(const std::string& outputPath);
|
||||
void EndSessionImpl();
|
||||
|
||||
void SubmitScopeProfileImpl(const ScopeProfileResult& profileResult);
|
||||
};
|
||||
|
||||
class InstrumentorTimer
|
||||
{
|
||||
private:
|
||||
ScopeProfileResult m_Result;
|
||||
std::chrono::time_point<std::chrono::steady_clock> m_Start;
|
||||
|
||||
public:
|
||||
InstrumentorTimer(const std::string& scopeName);
|
||||
~InstrumentorTimer();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#define LT_PROFILE_SCOPE(name) InstrumentorTimer timer##__LINE__ (name)
|
||||
#define LT_PROFILE_FUNCTION LT_PROFILE_SCOPE(__FUNCSIG__)
|
||||
#define LT_PROFILE_BEGIN_SESSION(outputPath) ::Light::Instrumentor::BeginSession(outputPath)
|
||||
#define LT_PROFILE_END_SESSION() ::Light::Instrumentor::EndSession()
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#define LT_LOG_FILE_LOCATION "Log.txt";
|
||||
|
||||
// #todo: log function signature
|
||||
// File
|
||||
#define LT_FILE_INFO(...) ::Light::Logger::GetFileLogger()->log(spdlog::level::info , __VA_ARGS__)
|
||||
#define LT_FILE_WARN(...) ::Light::Logger::GetFileLogger()->log(spdlog::level::warn , __VA_ARGS__)
|
||||
|
|
|
@ -20,9 +20,6 @@ namespace Light {
|
|||
wWindow::wWindow(std::function<void(Event&)> callback)
|
||||
: m_EventCallback(callback)
|
||||
{
|
||||
LT_ENGINE_TRACE("Pressed");
|
||||
|
||||
|
||||
// init glfw
|
||||
LT_ENGINE_ASSERT(glfwInit(), "wWindow::wWindow: failed to initialize 'glfw'");
|
||||
|
||||
|
|
1
Sandbox/Logs/ProfileResults_GameLoop.json
Normal file
1
Sandbox/Logs/ProfileResults_GameLoop.json
Normal file
File diff suppressed because one or more lines are too long
1
Sandbox/Logs/ProfileResults_Startup.json
Normal file
1
Sandbox/Logs/ProfileResults_Startup.json
Normal file
|
@ -0,0 +1 @@
|
|||
{"traceEvents":[]}
|
1
Sandbox/Logs/ProfileResults_Termination.json
Normal file
1
Sandbox/Logs/ProfileResults_Termination.json
Normal file
|
@ -0,0 +1 @@
|
|||
{"traceEvents":[]}
|
Loading…
Add table
Reference in a new issue