Instrumentpr

- Added Instrumentor
      * Instrumentor (class)
      * InstrumentorTimer (class, used statically)
      * ScopeProfileResult (struct)

- Tidy
      * wWindow::wWindow
This commit is contained in:
Light 2021-07-12 15:20:47 +04:30
parent 3363239c8d
commit cd30d0bba1
9 changed files with 171 additions and 15 deletions

View file

@ -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)

View file

@ -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:

View 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);
}
}

View 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()

View file

@ -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__)

View file

@ -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'");

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
{"traceEvents":[]}

View file

@ -0,0 +1 @@
{"traceEvents":[]}