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 "UserInterface/UserInterface.h"
|
||||||
|
|
||||||
|
#include "Debug/Instrumentor.h"
|
||||||
|
|
||||||
#include "Time/Timer.h"
|
#include "Time/Timer.h"
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
@ -20,12 +22,16 @@ namespace Light {
|
||||||
Application::Application()
|
Application::Application()
|
||||||
{
|
{
|
||||||
Logger::Initialize();
|
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)));
|
m_Window = std::unique_ptr<Light::Window>(Light::Window::Create(std::bind(&Light::Application::OnEvent, this, std::placeholders::_1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Application::~Application()
|
Application::~Application()
|
||||||
{
|
{
|
||||||
LT_ENGINE_TRACE("Application::~Application()");
|
LT_ENGINE_TRACE("Application::~Application()");
|
||||||
|
m_Instrumentor->EndSession(); // ProfileResults_Termination //
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::GameLoop()
|
void Application::GameLoop()
|
||||||
|
@ -42,29 +48,46 @@ namespace Light {
|
||||||
// reveal window
|
// reveal window
|
||||||
m_Window->SetVisibility(true);
|
m_Window->SetVisibility(true);
|
||||||
|
|
||||||
DeltaTimer deltaTimer;
|
m_Instrumentor->EndSession(); // ProfileResults_GameLoop //
|
||||||
|
m_Instrumentor->BeginSession("Logs/ProfileResults_GameLoop.json");
|
||||||
|
|
||||||
//** GAMELOOP **//
|
//** GAMELOOP **//
|
||||||
|
DeltaTimer deltaTimer;
|
||||||
while (!m_Window->IsClosed())
|
while (!m_Window->IsClosed())
|
||||||
|
{
|
||||||
{
|
{
|
||||||
// update layers
|
// update layers
|
||||||
|
LT_PROFILE_SCOPE("GameLoop::Update");
|
||||||
m_LayerStack.OnUpdate(deltaTimer.GetDeltaTime());
|
m_LayerStack.OnUpdate(deltaTimer.GetDeltaTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
// render layers
|
// render layers
|
||||||
|
LT_PROFILE_SCOPE("GameLoop::Render");
|
||||||
m_Window->GetGfxContext()->GetRenderer()->BeginFrame();
|
m_Window->GetGfxContext()->GetRenderer()->BeginFrame();
|
||||||
m_LayerStack.OnRender();
|
m_LayerStack.OnRender();
|
||||||
m_Window->GetGfxContext()->GetRenderer()->EndFrame();
|
m_Window->GetGfxContext()->GetRenderer()->EndFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
// render user interface
|
// render user interface
|
||||||
|
LT_PROFILE_SCOPE("GameLoop::UserInterface");
|
||||||
m_Window->GetGfxContext()->GetUserInterface()->Begin();
|
m_Window->GetGfxContext()->GetUserInterface()->Begin();
|
||||||
m_Window->GetGfxContext()->GetUserInterface()->End();
|
m_Window->GetGfxContext()->GetUserInterface()->End();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
// poll events
|
// poll events
|
||||||
|
LT_PROFILE_SCOPE("GameLoop::Events");
|
||||||
m_Window->PollEvents();
|
m_Window->PollEvents();
|
||||||
|
}
|
||||||
|
|
||||||
/// update delta time
|
/// update delta time
|
||||||
deltaTimer.Update();
|
deltaTimer.Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_Instrumentor->EndSession(); // ProfileResults_GameLoop //
|
||||||
|
m_Instrumentor->BeginSession("Logs/ProfileResults_Termination.json");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::OnEvent(const Event& event)
|
void Application::OnEvent(const Event& event)
|
||||||
|
|
|
@ -9,9 +9,12 @@ namespace Light {
|
||||||
class Window;
|
class Window;
|
||||||
class Event;
|
class Event;
|
||||||
|
|
||||||
|
class Instrumentor;
|
||||||
|
|
||||||
class Application
|
class Application
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
std::unique_ptr<Instrumentor> m_Instrumentor = nullptr;
|
||||||
LayerStack m_LayerStack;
|
LayerStack m_LayerStack;
|
||||||
|
|
||||||
protected:
|
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";
|
#define LT_LOG_FILE_LOCATION "Log.txt";
|
||||||
|
|
||||||
|
// #todo: log function signature
|
||||||
// File
|
// File
|
||||||
#define LT_FILE_INFO(...) ::Light::Logger::GetFileLogger()->log(spdlog::level::info , __VA_ARGS__)
|
#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__)
|
#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)
|
wWindow::wWindow(std::function<void(Event&)> callback)
|
||||||
: m_EventCallback(callback)
|
: m_EventCallback(callback)
|
||||||
{
|
{
|
||||||
LT_ENGINE_TRACE("Pressed");
|
|
||||||
|
|
||||||
|
|
||||||
// init glfw
|
// init glfw
|
||||||
LT_ENGINE_ASSERT(glfwInit(), "wWindow::wWindow: failed to initialize '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