mirror of
https://github.com/open-goal/jak-project.git
synced 2024-10-20 11:26:18 -04:00
1cc20508e9
While trying to narrow down why sometimes SDL takes 20-40seconds to initialize I built up some more profiling features. TLDR - I still don't know why SDL is taking a long time but I've narrowed it down to it initializing the `GAME_CONTROLLER` subsystem. This isn't unprecedented, I found numerous github issues and articles suggesting this is the problem: ![image](https://github.com/open-goal/jak-project/assets/13153231/1853326b-7a40-458e-87a0-f7a9f44781e3) I imagine it is hardware/OS related on some level, there are even some recent commits in SDL that have made it worse on certain platforms. I've had this problem myself so I will hope to get it again soon so i can debug where in the SDL code the delay occurs and make a proper bug report. Hopefully this helps but it's not yet confirmed - https://github.com/open-goal/jak-project/pull/3384
57 lines
1.5 KiB
C++
57 lines
1.5 KiB
C++
#pragma once
|
|
|
|
#include <atomic>
|
|
#include <optional>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "common/common_types.h"
|
|
|
|
struct ProfNode {
|
|
u64 ts;
|
|
u64 tid;
|
|
char name[128];
|
|
enum Kind : u8 { BEGIN, END, INSTANT, UNUSED } kind = UNUSED;
|
|
};
|
|
|
|
class GlobalProfiler {
|
|
public:
|
|
GlobalProfiler();
|
|
void set_max_events(size_t event_count);
|
|
void set_waiting_for_event(const std::string& event_name);
|
|
void instant_event(const char* name);
|
|
void begin_event(const char* name);
|
|
void event(const char* name, ProfNode::Kind kind);
|
|
void end_event();
|
|
void clear();
|
|
void set_enable(bool en);
|
|
void dump_to_json(const std::string& path);
|
|
void root_event();
|
|
|
|
private:
|
|
std::atomic_bool m_enabled = false;
|
|
u64 m_t0 = 0;
|
|
std::atomic_size_t m_next_idx = 0;
|
|
std::vector<ProfNode> m_nodes;
|
|
// this is very niche, but sometimes you want to capture up to a given event (ie. long startup)
|
|
// instead of having to make the user quit and record as fast as possible, we can instead just
|
|
// stop capturing events once we have received what we are looking for
|
|
std::optional<std::string> m_waiting_for_event = {};
|
|
bool m_ignore_events = false;
|
|
};
|
|
|
|
struct ScopedEvent {
|
|
ScopedEvent(GlobalProfiler* _prof) : prof(_prof){};
|
|
ScopedEvent(const ScopedEvent&) = delete;
|
|
ScopedEvent& operator=(const ScopedEvent&) = delete;
|
|
GlobalProfiler* prof = nullptr;
|
|
~ScopedEvent() {
|
|
if (prof) {
|
|
prof->end_event();
|
|
}
|
|
}
|
|
};
|
|
|
|
GlobalProfiler& prof();
|
|
ScopedEvent scoped_prof(const char* name);
|