mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2026-05-10 19:01:46 +00:00
Revamp Djui Profilers (#381)
This commit is contained in:
parent
e99d600bf7
commit
a0ae1cdc02
10 changed files with 356 additions and 133 deletions
|
|
@ -666,18 +666,5 @@ void render_hud(void) {
|
||||||
if (hudDisplayFlags & HUD_DISPLAY_FLAG_TIMER && showHud) {
|
if (hudDisplayFlags & HUD_DISPLAY_FLAG_TIMER && showHud) {
|
||||||
render_hud_timer();
|
render_hud_timer();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern bool configLuaProfiler;
|
|
||||||
if (configLuaProfiler) {
|
|
||||||
extern void lua_profiler_update_counters();
|
|
||||||
lua_profiler_update_counters();
|
|
||||||
}
|
|
||||||
#ifdef DEVELOPMENT
|
|
||||||
extern bool configCtxProfiler;
|
|
||||||
if (configCtxProfiler) {
|
|
||||||
extern void ctx_profiler_update_counters();
|
|
||||||
ctx_profiler_update_counters();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,6 @@
|
||||||
#include "utils/misc.h"
|
#include "utils/misc.h"
|
||||||
#include "debug_context.h"
|
#include "debug_context.h"
|
||||||
#include "debuglog.h"
|
#include "debuglog.h"
|
||||||
#include "game/print.h"
|
|
||||||
#include "game/hud.h"
|
|
||||||
#include "gfx_dimensions.h"
|
#include "gfx_dimensions.h"
|
||||||
|
|
||||||
static u32 sCtxDepth[CTX_MAX] = { 0 };
|
static u32 sCtxDepth[CTX_MAX] = { 0 };
|
||||||
|
|
@ -16,20 +14,6 @@ static f64 sCtxTime[CTX_MAX] = { 0 };
|
||||||
static f64 sCtxStartTimeStack[MAX_TIME_STACK] = { 0 };
|
static f64 sCtxStartTimeStack[MAX_TIME_STACK] = { 0 };
|
||||||
static u32 sCtxStackIndex = 0;
|
static u32 sCtxStackIndex = 0;
|
||||||
|
|
||||||
static char* sDebugContextNames[] = {
|
|
||||||
"NONE",
|
|
||||||
"FRAME",
|
|
||||||
"NET",
|
|
||||||
"INTERP",
|
|
||||||
"GAME",
|
|
||||||
"SMLUA",
|
|
||||||
"AUDIO",
|
|
||||||
"RENDER",
|
|
||||||
"LEVEL",
|
|
||||||
"HOOK",
|
|
||||||
"MAX",
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void debug_context_begin(enum DebugContext ctx) {
|
void debug_context_begin(enum DebugContext ctx) {
|
||||||
|
|
@ -71,29 +55,16 @@ void debug_context_reset(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool debug_context_within(enum DebugContext ctx) {
|
bool debug_context_within(enum DebugContext ctx) {
|
||||||
if (ctx > CTX_MAX) { return false; }
|
if (ctx >= CTX_MAX) { return false; }
|
||||||
return sCtxDepth[ctx] > 0;
|
return sCtxDepth[ctx] > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEVELOPMENT
|
void debug_context_set_time(enum DebugContext ctx, f64 time) {
|
||||||
|
if (ctx >= CTX_MAX) { return; }
|
||||||
void ctx_profiler_update_counters(void) {
|
sCtxTime[ctx] = time;
|
||||||
s32 y = SCREEN_HEIGHT - 60;
|
|
||||||
for (s32 i = 1; i < CTX_MAX; i++) {
|
|
||||||
const char *name = sDebugContextNames[i];
|
|
||||||
s32 counterUs = (s32) (sCtxTime[i] * 1000000.0);
|
|
||||||
char text[256];
|
|
||||||
snprintf(text, 256, " %05d", counterUs);
|
|
||||||
memcpy(text, name, MIN(12, strlen(name)));
|
|
||||||
for (s32 j = 0; j != 12; ++j) {
|
|
||||||
char c = text[j];
|
|
||||||
if (c >= 'a' && c <= 'z') c -= ('a' - 'A');
|
|
||||||
if ((c < '0' || c > '9') && (c < 'A' || c > 'Z')) c = ' ';
|
|
||||||
text[j] = c;
|
|
||||||
}
|
|
||||||
print_text(GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(4), y, text);
|
|
||||||
y -= 18;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
f64 debug_context_get_time(enum DebugContext ctx) {
|
||||||
|
if (ctx >= CTX_MAX) { return 0.0; }
|
||||||
|
return sCtxTime[ctx];
|
||||||
|
}
|
||||||
|
|
@ -1,15 +1,17 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <PR/ultratypes.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#define CTX_BEGIN(_ctx) debug_context_begin(_ctx)
|
#define CTX_BEGIN(_ctx) debug_context_begin(_ctx)
|
||||||
#define CTX_END(_ctx) debug_context_end(_ctx)
|
#define CTX_END(_ctx) debug_context_end(_ctx)
|
||||||
#define CTX_WITHIN(_ctx) debug_context_within(_ctx)
|
#define CTX_WITHIN(_ctx) debug_context_within(_ctx)
|
||||||
|
#define CTX_TIME(_ctx, time) debug_context_set_time(_ctx, time)
|
||||||
#define CTX_EXTENT(_ctx, _f) { CTX_BEGIN(_ctx); _f(); CTX_END(_ctx); }
|
#define CTX_EXTENT(_ctx, _f) { CTX_BEGIN(_ctx); _f(); CTX_END(_ctx); }
|
||||||
|
|
||||||
enum DebugContext {
|
enum DebugContext {
|
||||||
CTX_NONE,
|
CTX_NONE,
|
||||||
CTX_FRAME,
|
CTX_TOTAL,
|
||||||
CTX_NETWORK,
|
CTX_NETWORK,
|
||||||
CTX_INTERP,
|
CTX_INTERP,
|
||||||
CTX_GAME_LOOP,
|
CTX_GAME_LOOP,
|
||||||
|
|
@ -26,3 +28,5 @@ void debug_context_begin(enum DebugContext ctx);
|
||||||
void debug_context_end(enum DebugContext ctx);
|
void debug_context_end(enum DebugContext ctx);
|
||||||
void debug_context_reset(void);
|
void debug_context_reset(void);
|
||||||
bool debug_context_within(enum DebugContext ctx);
|
bool debug_context_within(enum DebugContext ctx);
|
||||||
|
void debug_context_set_time(enum DebugContext ctx, f64 time);
|
||||||
|
f64 debug_context_get_time(enum DebugContext ctx);
|
||||||
|
|
@ -5,7 +5,9 @@
|
||||||
#include "djui_panel_pause.h"
|
#include "djui_panel_pause.h"
|
||||||
#include "djui_panel_join.h"
|
#include "djui_panel_join.h"
|
||||||
#include "djui_panel_join_message.h"
|
#include "djui_panel_join_message.h"
|
||||||
|
#include "djui_ctx_display.h"
|
||||||
#include "djui_fps_display.h"
|
#include "djui_fps_display.h"
|
||||||
|
#include "djui_lua_profiler.h"
|
||||||
#include "../debuglog.h"
|
#include "../debuglog.h"
|
||||||
#include "pc/cliopts.h"
|
#include "pc/cliopts.h"
|
||||||
#include "game/level_update.h"
|
#include "game/level_update.h"
|
||||||
|
|
@ -52,6 +54,8 @@ void djui_shutdown(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
djui_fps_display_destroy();
|
djui_fps_display_destroy();
|
||||||
|
djui_ctx_display_destroy();
|
||||||
|
djui_lua_profiler_destroy();
|
||||||
|
|
||||||
gDjuiShuttingDown = false;
|
gDjuiShuttingDown = false;
|
||||||
sDjuiInited = false;
|
sDjuiInited = false;
|
||||||
|
|
@ -97,6 +101,8 @@ void djui_init(void) {
|
||||||
djui_console_create();
|
djui_console_create();
|
||||||
|
|
||||||
djui_fps_display_create();
|
djui_fps_display_create();
|
||||||
|
djui_ctx_display_create();
|
||||||
|
djui_lua_profiler_create();
|
||||||
|
|
||||||
sDjuiInited = true;
|
sDjuiInited = true;
|
||||||
}
|
}
|
||||||
|
|
@ -158,6 +164,8 @@ void djui_render(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
djui_fps_display_render();
|
djui_fps_display_render();
|
||||||
|
djui_ctx_display_render();
|
||||||
|
djui_lua_profiler_render();
|
||||||
|
|
||||||
if (sDjuiLuaErrorTimeout > 0) {
|
if (sDjuiLuaErrorTimeout > 0) {
|
||||||
sDjuiLuaErrorTimeout--;
|
sDjuiLuaErrorTimeout--;
|
||||||
|
|
|
||||||
139
src/pc/djui/djui_ctx_display.c
Normal file
139
src/pc/djui/djui_ctx_display.c
Normal file
|
|
@ -0,0 +1,139 @@
|
||||||
|
#include "djui_ctx_display.h"
|
||||||
|
|
||||||
|
#include "djui.h"
|
||||||
|
#include "pc/pc_main.h"
|
||||||
|
#include "pc/debug_context.h"
|
||||||
|
|
||||||
|
#ifdef DEVELOPMENT
|
||||||
|
|
||||||
|
static char* sDebugContextNames[] = {
|
||||||
|
"NONE",
|
||||||
|
"TOTAL",
|
||||||
|
"NET",
|
||||||
|
"INTERP",
|
||||||
|
"GAME",
|
||||||
|
"SMLUA",
|
||||||
|
"AUDIO",
|
||||||
|
"RENDER",
|
||||||
|
"LEVEL",
|
||||||
|
"HOOK",
|
||||||
|
"OTHER",
|
||||||
|
"MAX",
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct DjuiCtxEntry {
|
||||||
|
struct DjuiText *name;
|
||||||
|
struct DjuiText *timing;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DjuiCtxDisplay {
|
||||||
|
struct DjuiCtxEntry topEntry;
|
||||||
|
struct DjuiCtxEntry entries[CTX_MAX];
|
||||||
|
struct DjuiBase base;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct DjuiCtxDisplay *sCtxDisplay = NULL;
|
||||||
|
|
||||||
|
void djui_ctx_display_update(void) {
|
||||||
|
if (!configCtxProfiler || sCtxDisplay == NULL) { return; }
|
||||||
|
|
||||||
|
#ifdef DEVELOPMENT
|
||||||
|
// Time we have for a indivdual frame. If we exceed it. We are in the red.
|
||||||
|
f64 frameTime = 1.0 / 30.0;
|
||||||
|
s32 frameTimeMs = (s32)(frameTime * 1000000.0);
|
||||||
|
|
||||||
|
struct DjuiCtxEntry *topEntry = &sCtxDisplay->topEntry;
|
||||||
|
|
||||||
|
// If we've exceeded our available frame time. Make the top entry timing red - For dramatic effect.
|
||||||
|
// Otherwise. It's green!
|
||||||
|
if (debug_context_get_time(CTX_TOTAL) > frameTime) {
|
||||||
|
djui_base_set_color(&topEntry->timing->base, 255, 69, 0, 240);
|
||||||
|
} else {
|
||||||
|
djui_base_set_color(&topEntry->timing->base, 124, 252, 0, 240);
|
||||||
|
}
|
||||||
|
|
||||||
|
djui_text_set_text(topEntry->name, "FRAME");
|
||||||
|
char timing[32];
|
||||||
|
snprintf(timing, 32, "%05d", frameTimeMs);
|
||||||
|
djui_text_set_text(topEntry->timing, timing);
|
||||||
|
|
||||||
|
// Draw the counters.
|
||||||
|
for (s32 i = CTX_TOTAL; i < CTX_MAX; i++) {
|
||||||
|
struct DjuiCtxEntry *entry = &sCtxDisplay->entries[i];
|
||||||
|
|
||||||
|
const char *name = sDebugContextNames[i];
|
||||||
|
djui_text_set_text(entry->name, name);
|
||||||
|
|
||||||
|
// The timing is in microseconds.
|
||||||
|
s32 counterMs = (s32)(debug_context_get_time(i) * 1000000.0);
|
||||||
|
char timing[32];
|
||||||
|
snprintf(timing, 32, "%05d", counterMs);
|
||||||
|
djui_text_set_text(entry->timing, timing);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void djui_ctx_display_render(void) {
|
||||||
|
if (!configCtxProfiler || sCtxDisplay == NULL) { return; }
|
||||||
|
|
||||||
|
djui_rect_render(&sCtxDisplay->base);
|
||||||
|
djui_base_render(&sCtxDisplay->base);
|
||||||
|
}
|
||||||
|
|
||||||
|
void djui_ctx_display_on_destroy(UNUSED struct DjuiBase* base) {
|
||||||
|
free(sCtxDisplay);
|
||||||
|
}
|
||||||
|
|
||||||
|
void djui_ctx_display_initialize_entry(struct DjuiBase *base, struct DjuiCtxEntry *entry, f64 offset) {
|
||||||
|
struct DjuiText *name = djui_text_create(base, "");
|
||||||
|
djui_text_set_alignment(name, DJUI_HALIGN_LEFT, DJUI_VALIGN_TOP);
|
||||||
|
djui_base_set_size_type(&name->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||||
|
djui_base_set_size(&name->base, 1.0f, name->fontScale * 2);
|
||||||
|
djui_base_set_location(&name->base, 0, -name->fontScale / 3.0f + offset);
|
||||||
|
djui_base_set_color(&name->base, 255, 255, 255, 240);
|
||||||
|
|
||||||
|
struct DjuiText *timing = djui_text_create(base, "");
|
||||||
|
djui_text_set_alignment(timing, DJUI_HALIGN_RIGHT, DJUI_VALIGN_TOP);
|
||||||
|
djui_base_set_size_type(&timing->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||||
|
djui_base_set_size(&timing->base, 1.0f, timing->fontScale * 2);
|
||||||
|
djui_base_set_location(&timing->base, 0, -timing->fontScale / 3.0f + offset);
|
||||||
|
djui_base_set_color(&timing->base, 255, 255, 255, 240);
|
||||||
|
|
||||||
|
entry->name = name;
|
||||||
|
entry->timing = timing;
|
||||||
|
}
|
||||||
|
|
||||||
|
void djui_ctx_display_create(void) {
|
||||||
|
struct DjuiCtxDisplay *ctxDisplay = calloc(1, sizeof(struct DjuiCtxDisplay));
|
||||||
|
struct DjuiBase *base = &ctxDisplay->base;
|
||||||
|
djui_base_init(NULL, base, NULL, djui_ctx_display_on_destroy);
|
||||||
|
djui_base_set_size(base, 220.0f, 39.0f + ((CTX_MAX - 2) * 26.0f));
|
||||||
|
djui_base_set_color(base, 0, 0, 0, 240);
|
||||||
|
djui_base_set_border_color(base, 0, 0, 0, 200);
|
||||||
|
djui_base_set_border_width(base, 4);
|
||||||
|
djui_base_set_padding(base, 4, 4, 4, 4);
|
||||||
|
djui_base_set_location(base, 0, 52.0f);
|
||||||
|
|
||||||
|
{
|
||||||
|
f64 offset = 4.0;
|
||||||
|
|
||||||
|
djui_ctx_display_initialize_entry(base, &ctxDisplay->topEntry, offset);
|
||||||
|
offset += 35.0;
|
||||||
|
|
||||||
|
for (s32 i = CTX_TOTAL; i < CTX_MAX; i++) {
|
||||||
|
djui_ctx_display_initialize_entry(base, &ctxDisplay->entries[i], offset);
|
||||||
|
offset += 22.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sCtxDisplay = ctxDisplay;
|
||||||
|
}
|
||||||
|
|
||||||
|
void djui_ctx_display_destroy(void) {
|
||||||
|
if (sCtxDisplay) {
|
||||||
|
djui_base_destroy(&sCtxDisplay->base);
|
||||||
|
}
|
||||||
|
}
|
||||||
7
src/pc/djui/djui_ctx_display.h
Normal file
7
src/pc/djui/djui_ctx_display.h
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
#pragma once
|
||||||
|
#include "djui.h"
|
||||||
|
|
||||||
|
void djui_ctx_display_update(void);
|
||||||
|
void djui_ctx_display_render(void);
|
||||||
|
void djui_ctx_display_create(void);
|
||||||
|
void djui_ctx_display_destroy(void);
|
||||||
150
src/pc/djui/djui_lua_profiler.c
Normal file
150
src/pc/djui/djui_lua_profiler.c
Normal file
|
|
@ -0,0 +1,150 @@
|
||||||
|
#include "djui_lua_profiler.h"
|
||||||
|
|
||||||
|
#include "djui.h"
|
||||||
|
#include "pc/pc_main.h"
|
||||||
|
#include "pc/mods/mod.h"
|
||||||
|
#include "pc/mods/mods.h"
|
||||||
|
|
||||||
|
#define MAX_PROFILED_MODS 16
|
||||||
|
#define REFRESH_RATE 30
|
||||||
|
|
||||||
|
struct DjuiPrfCounter {
|
||||||
|
f64 start;
|
||||||
|
f64 end;
|
||||||
|
f64 sum;
|
||||||
|
f64 display;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DjuiPrfEntry {
|
||||||
|
struct DjuiText *name;
|
||||||
|
struct DjuiText *timing;
|
||||||
|
struct DjuiPrfCounter counter;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DjuiPrfDisplay {
|
||||||
|
struct DjuiPrfEntry entries[MAX_PROFILED_MODS];
|
||||||
|
struct DjuiBase base;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DjuiPrfDisplay *sPrfDisplay = NULL;
|
||||||
|
|
||||||
|
void lua_profiler_start_counter(UNUSED struct Mod *mod) {
|
||||||
|
if (!configLuaProfiler || sPrfDisplay == NULL) { return; }
|
||||||
|
|
||||||
|
#ifndef WAPI_DUMMY
|
||||||
|
for (s32 i = 0; i != MIN(MAX_PROFILED_MODS, gActiveMods.entryCount); ++i) {
|
||||||
|
if (gActiveMods.entries[i] == mod) {
|
||||||
|
f64 freq = SDL_GetPerformanceFrequency();
|
||||||
|
f64 curr = SDL_GetPerformanceCounter();
|
||||||
|
sPrfDisplay->entries[i].counter.start = curr / freq;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void lua_profiler_stop_counter(UNUSED struct Mod *mod) {
|
||||||
|
if (!configLuaProfiler || sPrfDisplay == NULL) { return; }
|
||||||
|
|
||||||
|
#ifndef WAPI_DUMMY
|
||||||
|
for (s32 i = 0; i != MIN(MAX_PROFILED_MODS, gActiveMods.entryCount); ++i) {
|
||||||
|
if (gActiveMods.entries[i] == mod) {
|
||||||
|
f64 freq = SDL_GetPerformanceFrequency();
|
||||||
|
f64 curr = SDL_GetPerformanceCounter();
|
||||||
|
|
||||||
|
struct DjuiPrfCounter *counter = &sPrfDisplay->entries[i].counter;
|
||||||
|
counter->end = curr / freq;
|
||||||
|
counter->sum += counter->end - counter->start;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void djui_lua_profiler_update(void) {
|
||||||
|
if (!configLuaProfiler || sPrfDisplay == NULL) { return; }
|
||||||
|
|
||||||
|
// Draw the counters.
|
||||||
|
for (s32 i = 0; i < MIN(MAX_PROFILED_MODS, gActiveMods.entryCount); i++) {
|
||||||
|
struct DjuiPrfEntry *entry = &sPrfDisplay->entries[i];
|
||||||
|
struct DjuiPrfCounter *counter = &entry->counter;
|
||||||
|
|
||||||
|
if (gGlobalTimer % REFRESH_RATE == 0) {
|
||||||
|
counter->display = counter->sum / (f64) REFRESH_RATE;
|
||||||
|
counter->sum = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char name[256];
|
||||||
|
memset(name, 0, 256);
|
||||||
|
const char *modName = gActiveMods.entries[i]->relativePath;
|
||||||
|
memcpy(name, modName, MIN(16, strlen(modName) - (gActiveMods.entries[i]->isDirectory ? 0 : 4)));
|
||||||
|
for (s32 j = 0; j != 16; ++j) {
|
||||||
|
char c = name[j];
|
||||||
|
if (c >= 'a' && c <= 'z') c -= ('a' - 'A');
|
||||||
|
if ((c < '0' || c > '9') && (c < 'A' || c > 'Z')) c = ' ';
|
||||||
|
name[j] = c;
|
||||||
|
}
|
||||||
|
djui_text_set_text(entry->name, name);
|
||||||
|
|
||||||
|
// The timing is in microseconds.
|
||||||
|
s32 counterMs = (s32)(counter->display * 1000000.0);
|
||||||
|
char timing[32];
|
||||||
|
snprintf(timing, 32, "%05d", counterMs);
|
||||||
|
djui_text_set_text(entry->timing, timing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void djui_lua_profiler_render(void) {
|
||||||
|
if (!configLuaProfiler || sPrfDisplay == NULL) { return; }
|
||||||
|
|
||||||
|
djui_rect_render(&sPrfDisplay->base);
|
||||||
|
djui_base_render(&sPrfDisplay->base);
|
||||||
|
}
|
||||||
|
|
||||||
|
void djui_lua_profiler_on_destroy(UNUSED struct DjuiBase* base) {
|
||||||
|
free(sPrfDisplay);
|
||||||
|
}
|
||||||
|
|
||||||
|
void djui_lua_profiler_initialize_entry(struct DjuiBase *base, struct DjuiPrfEntry *entry, f64 offset) {
|
||||||
|
struct DjuiText *name = djui_text_create(base, "");
|
||||||
|
djui_text_set_alignment(name, DJUI_HALIGN_LEFT, DJUI_VALIGN_TOP);
|
||||||
|
djui_base_set_size_type(&name->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||||
|
djui_base_set_size(&name->base, 1.0f, name->fontScale * 2);
|
||||||
|
djui_base_set_location(&name->base, 0, -name->fontScale / 3.0f + offset);
|
||||||
|
djui_base_set_color(&name->base, 255, 255, 255, 240);
|
||||||
|
|
||||||
|
struct DjuiText *timing = djui_text_create(base, "");
|
||||||
|
djui_text_set_alignment(timing, DJUI_HALIGN_RIGHT, DJUI_VALIGN_TOP);
|
||||||
|
djui_base_set_size_type(&timing->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||||
|
djui_base_set_size(&timing->base, 1.0f, timing->fontScale * 2);
|
||||||
|
djui_base_set_location(&timing->base, 0, -timing->fontScale / 3.0f + offset);
|
||||||
|
djui_base_set_color(&timing->base, 255, 255, 255, 240);
|
||||||
|
|
||||||
|
entry->name = name;
|
||||||
|
entry->timing = timing;
|
||||||
|
}
|
||||||
|
|
||||||
|
void djui_lua_profiler_create(void) {
|
||||||
|
struct DjuiPrfDisplay *prfDisplay = calloc(1, sizeof(struct DjuiPrfDisplay));
|
||||||
|
struct DjuiBase *base = &prfDisplay->base;
|
||||||
|
djui_base_init(NULL, base, NULL, djui_lua_profiler_on_destroy);
|
||||||
|
djui_base_set_size(base, 290.0f, MAX_PROFILED_MODS * 26.0f);
|
||||||
|
djui_base_set_color(base, 0, 0, 0, 240);
|
||||||
|
djui_base_set_border_color(base, 0, 0, 0, 200);
|
||||||
|
djui_base_set_border_width(base, 4);
|
||||||
|
djui_base_set_padding(base, 4, 4, 4, 4);
|
||||||
|
djui_base_set_location(base, 0, 300.0f);
|
||||||
|
|
||||||
|
f64 offset = 4.0;
|
||||||
|
for (s32 i = 0; i < MAX_PROFILED_MODS; ++i, offset += 22.0) {
|
||||||
|
djui_lua_profiler_initialize_entry(base, &prfDisplay->entries[i], offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
sPrfDisplay = prfDisplay;
|
||||||
|
}
|
||||||
|
|
||||||
|
void djui_lua_profiler_destroy(void) {
|
||||||
|
if (sPrfDisplay) {
|
||||||
|
djui_base_destroy(&sPrfDisplay->base);
|
||||||
|
}
|
||||||
|
}
|
||||||
11
src/pc/djui/djui_lua_profiler.h
Normal file
11
src/pc/djui/djui_lua_profiler.h
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
#pragma once
|
||||||
|
#include "djui.h"
|
||||||
|
#include "pc/mods/mod.h"
|
||||||
|
|
||||||
|
void lua_profiler_start_counter(UNUSED struct Mod *mod);
|
||||||
|
void lua_profiler_stop_counter(UNUSED struct Mod *mod);
|
||||||
|
|
||||||
|
void djui_lua_profiler_update(void);
|
||||||
|
void djui_lua_profiler_render(void);
|
||||||
|
void djui_lua_profiler_create(void);
|
||||||
|
void djui_lua_profiler_destroy(void);
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
#include "pc/network/socket/socket.h"
|
#include "pc/network/socket/socket.h"
|
||||||
#include "pc/chat_commands.h"
|
#include "pc/chat_commands.h"
|
||||||
#include "pc/pc_main.h"
|
#include "pc/pc_main.h"
|
||||||
|
#include "pc/djui/djui_lua_profiler.h"
|
||||||
#include "pc/djui/djui_panel.h"
|
#include "pc/djui/djui_panel.h"
|
||||||
#include "pc/configfile.h"
|
#include "pc/configfile.h"
|
||||||
|
|
||||||
|
|
@ -22,66 +23,6 @@
|
||||||
#include "game/print.h"
|
#include "game/print.h"
|
||||||
#include "gfx_dimensions.h"
|
#include "gfx_dimensions.h"
|
||||||
|
|
||||||
#define MAX_PROFILED_MODS 16
|
|
||||||
#define REFRESH_RATE 15
|
|
||||||
|
|
||||||
static struct {
|
|
||||||
f64 start;
|
|
||||||
f64 end;
|
|
||||||
f64 sum;
|
|
||||||
f64 disp;
|
|
||||||
} sLuaProfilerCounters[MAX_PROFILED_MODS];
|
|
||||||
|
|
||||||
static void lua_profiler_start_counter(UNUSED struct Mod *mod) {
|
|
||||||
#ifndef WAPI_DUMMY
|
|
||||||
for (s32 i = 0; i != MIN(MAX_PROFILED_MODS, gActiveMods.entryCount); ++i) {
|
|
||||||
if (gActiveMods.entries[i] == mod) {
|
|
||||||
f64 freq = SDL_GetPerformanceFrequency();
|
|
||||||
f64 curr = SDL_GetPerformanceCounter();
|
|
||||||
sLuaProfilerCounters[i].start = curr / freq;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void lua_profiler_stop_counter(UNUSED struct Mod *mod) {
|
|
||||||
#ifndef WAPI_DUMMY
|
|
||||||
for (s32 i = 0; i != MIN(MAX_PROFILED_MODS, gActiveMods.entryCount); ++i) {
|
|
||||||
if (gActiveMods.entries[i] == mod) {
|
|
||||||
f64 freq = SDL_GetPerformanceFrequency();
|
|
||||||
f64 curr = SDL_GetPerformanceCounter();
|
|
||||||
sLuaProfilerCounters[i].end = curr / freq;
|
|
||||||
sLuaProfilerCounters[i].sum += sLuaProfilerCounters[i].end - sLuaProfilerCounters[i].start;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void lua_profiler_update_counters(void) {
|
|
||||||
if (gGlobalTimer % REFRESH_RATE == 0) {
|
|
||||||
for (s32 i = 0; i != MIN(MAX_PROFILED_MODS, gActiveMods.entryCount); ++i) {
|
|
||||||
sLuaProfilerCounters[i].disp = sLuaProfilerCounters[i].sum / (f64) REFRESH_RATE;
|
|
||||||
sLuaProfilerCounters[i].sum = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (s32 i = 0, y = SCREEN_HEIGHT - 60; i != MIN(MAX_PROFILED_MODS, gActiveMods.entryCount); ++i, y -= 18) {
|
|
||||||
const char *modName = gActiveMods.entries[i]->relativePath;
|
|
||||||
s32 modCounterUs = (s32) (sLuaProfilerCounters[i].disp * 1000000.0);
|
|
||||||
char text[256];
|
|
||||||
snprintf(text, 256, " %05d", modCounterUs);
|
|
||||||
memcpy(text, modName, MIN(12, strlen(modName) - (gActiveMods.entries[i]->isDirectory ? 0 : 4)));
|
|
||||||
for (s32 j = 0; j != 12; ++j) {
|
|
||||||
char c = text[j];
|
|
||||||
if (c >= 'a' && c <= 'z') c -= ('a' - 'A');
|
|
||||||
if ((c < '0' || c > '9') && (c < 'A' || c > 'Z')) c = ' ';
|
|
||||||
text[j] = c;
|
|
||||||
}
|
|
||||||
print_text(GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(4), y, text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MAX_HOOKED_REFERENCES 64
|
#define MAX_HOOKED_REFERENCES 64
|
||||||
#define LUA_BEHAVIOR_FLAG (1 << 15)
|
#define LUA_BEHAVIOR_FLAG (1 << 15)
|
||||||
|
|
||||||
|
|
@ -102,18 +43,13 @@ int smlua_call_hook(lua_State* L, int nargs, int nresults, int errfunc, struct M
|
||||||
gLuaActiveMod = activeMod;
|
gLuaActiveMod = activeMod;
|
||||||
gLuaLastHookMod = activeMod;
|
gLuaLastHookMod = activeMod;
|
||||||
|
|
||||||
extern bool configLuaProfiler;
|
lua_profiler_start_counter(activeMod);
|
||||||
if (configLuaProfiler) {
|
|
||||||
lua_profiler_start_counter(activeMod);
|
|
||||||
}
|
|
||||||
|
|
||||||
CTX_BEGIN(CTX_HOOK);
|
CTX_BEGIN(CTX_HOOK);
|
||||||
int rc = smlua_pcall(L, nargs, nresults, errfunc);
|
int rc = smlua_pcall(L, nargs, nresults, errfunc);
|
||||||
CTX_END(CTX_HOOK);
|
CTX_END(CTX_HOOK);
|
||||||
|
|
||||||
if (configLuaProfiler) {
|
lua_profiler_stop_counter(activeMod);
|
||||||
lua_profiler_stop_counter(activeMod);
|
|
||||||
}
|
|
||||||
|
|
||||||
gLuaActiveMod = prev;
|
gLuaActiveMod = prev;
|
||||||
return rc;
|
return rc;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
@ -43,7 +44,9 @@
|
||||||
#include "pc/djui/djui_unicode.h"
|
#include "pc/djui/djui_unicode.h"
|
||||||
#include "pc/djui/djui_panel.h"
|
#include "pc/djui/djui_panel.h"
|
||||||
#include "pc/djui/djui_panel_modlist.h"
|
#include "pc/djui/djui_panel_modlist.h"
|
||||||
|
#include "pc/djui/djui_ctx_display.h"
|
||||||
#include "pc/djui/djui_fps_display.h"
|
#include "pc/djui/djui_fps_display.h"
|
||||||
|
#include "pc/djui/djui_lua_profiler.h"
|
||||||
#include "pc/debuglog.h"
|
#include "pc/debuglog.h"
|
||||||
#include "pc/utils/misc.h"
|
#include "pc/utils/misc.h"
|
||||||
|
|
||||||
|
|
@ -182,28 +185,30 @@ void produce_interpolation_frames_and_delay(void) {
|
||||||
|
|
||||||
// interpolate and render
|
// interpolate and render
|
||||||
while ((curTime = clock_elapsed_f64()) < sFrameTargetTime) {
|
while ((curTime = clock_elapsed_f64()) < sFrameTargetTime) {
|
||||||
gfx_start_frame();
|
|
||||||
f32 delta = ((!configUncappedFramerate && configFrameLimit == FRAMERATE)
|
f32 delta = ((!configUncappedFramerate && configFrameLimit == FRAMERATE)
|
||||||
? 1.0f
|
? 1.0f
|
||||||
: MAX(MIN((curTime - sFrameTimeStart) / (sFrameTargetTime - sFrameTimeStart), 1.0f), 0.0f)
|
: MAX(MIN((curTime - sFrameTimeStart) / (sFrameTargetTime - sFrameTimeStart), 1.0f), 0.0f)
|
||||||
);
|
);
|
||||||
gRenderingDelta = delta;
|
gRenderingDelta = delta;
|
||||||
|
|
||||||
|
gfx_start_frame();
|
||||||
if (!gSkipInterpolationTitleScreen) { patch_interpolations(delta); }
|
if (!gSkipInterpolationTitleScreen) { patch_interpolations(delta); }
|
||||||
send_display_list(gGfxSPTask);
|
send_display_list(gGfxSPTask);
|
||||||
gfx_end_frame();
|
gfx_end_frame();
|
||||||
|
|
||||||
// delay
|
|
||||||
if (!configUncappedFramerate) {
|
|
||||||
f64 targetDelta = 1.0 / (f64) configFrameLimit;
|
|
||||||
f64 now = clock_elapsed_f64();
|
|
||||||
f64 actualDelta = now - curTime;
|
|
||||||
if (actualDelta < targetDelta) {
|
|
||||||
f64 delay = ((targetDelta - actualDelta) * 1000.0);
|
|
||||||
if (delay > 0.0f) { WAPI.delay((u32) delay); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
frames++;
|
frames++;
|
||||||
|
|
||||||
|
if (configUncappedFramerate) { continue; }
|
||||||
|
|
||||||
|
// Delay if our framerate is capped.
|
||||||
|
f64 targetDelta = 1.0 / (f64) configFrameLimit;
|
||||||
|
f64 now = clock_elapsed_f64();
|
||||||
|
f64 actualDelta = now - curTime;
|
||||||
|
if (actualDelta >= targetDelta) { continue; }
|
||||||
|
f64 delay = ((targetDelta - actualDelta) * 1000.0) - 1.0;
|
||||||
|
if (delay > 0.0f) {
|
||||||
|
WAPI.delay((u32)delay);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static u64 sFramesSinceFpsUpdate = 0;
|
static u64 sFramesSinceFpsUpdate = 0;
|
||||||
|
|
@ -465,7 +470,7 @@ int main(int argc, char *argv[]) {
|
||||||
// main loop
|
// main loop
|
||||||
while (true) {
|
while (true) {
|
||||||
debug_context_reset();
|
debug_context_reset();
|
||||||
CTX_BEGIN(CTX_FRAME);
|
CTX_BEGIN(CTX_TOTAL);
|
||||||
WAPI.main_loop(produce_one_frame);
|
WAPI.main_loop(produce_one_frame);
|
||||||
#ifdef DISCORD_SDK
|
#ifdef DISCORD_SDK
|
||||||
discord_update();
|
discord_update();
|
||||||
|
|
@ -475,7 +480,12 @@ int main(int argc, char *argv[]) {
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
#endif
|
#endif
|
||||||
CTX_END(CTX_FRAME);
|
CTX_END(CTX_TOTAL);
|
||||||
|
|
||||||
|
#ifdef DEVELOPMENT
|
||||||
|
djui_ctx_display_update();
|
||||||
|
#endif
|
||||||
|
djui_lua_profiler_update();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue