| #pragma once | |
| // RIVE_PROF_FRAME() | |
| // This function should be called at the start of the main loop | |
| // | |
| // RIVE_PROF_SCOPE() | |
| // Add to a function or scope to profile, the function name is | |
| // automatically filled in | |
| // | |
| // RIVE_PROF_SCOPENAME(name) | |
| // Same as above but manually supplied name | |
| // | |
| // RIVE_PROF_THREAD(name) | |
| // Add to new threads | |
| // | |
| // Level-gated variants: | |
| // RIVE_PROF_SCOPE_L(level) | |
| // RIVE_PROF_SCOPENAME_L(level, name) | |
| // RIVE_PROF_GPUNAME_L(level, name) | |
| // | |
| // `level` MUST be a literal integer 0..4. Lower numbers mark higher-level | |
| // functions (frame, scene, flush). Higher numbers mark hot inner-loop | |
| // functions whose per-call overhead matters. The compile-time threshold | |
| // `RIVE_PROF_LEVEL_MAX` drops every marker with `level > RIVE_PROF_LEVEL_MAX` | |
| // to nothing — no token registration, no Enter/Leave call, no stack handler. | |
| // Pass it via the build system, e.g. `-DRIVE_PROF_LEVEL_MAX=2`. | |
| // | |
| // The non-level macros (RIVE_PROF_SCOPE, RIVE_PROF_SCOPENAME, | |
| // RIVE_PROF_GPUNAME) are equivalent to level 0 and are always on whenever the | |
| // active profiler is compiled in. | |
| #ifndef RIVE_PROF_LEVEL_MAX | |
| #define RIVE_PROF_LEVEL_MAX 2 | |
| #endif | |
| // Per-level pass-through gates. Each either expands its argument (when the | |
| // level is <= RIVE_PROF_LEVEL_MAX) or drops it. | |
| #if RIVE_PROF_LEVEL_MAX >= 0 | |
| #define _RIVE_PROF_LVL_0(body) body | |
| #else | |
| #define _RIVE_PROF_LVL_0(body) | |
| #endif | |
| #if RIVE_PROF_LEVEL_MAX >= 1 | |
| #define _RIVE_PROF_LVL_1(body) body | |
| #else | |
| #define _RIVE_PROF_LVL_1(body) | |
| #endif | |
| #if RIVE_PROF_LEVEL_MAX >= 2 | |
| #define _RIVE_PROF_LVL_2(body) body | |
| #else | |
| #define _RIVE_PROF_LVL_2(body) | |
| #endif | |
| #if RIVE_PROF_LEVEL_MAX >= 3 | |
| #define _RIVE_PROF_LVL_3(body) body | |
| #else | |
| #define _RIVE_PROF_LVL_3(body) | |
| #endif | |
| #if RIVE_PROF_LEVEL_MAX >= 4 | |
| #define _RIVE_PROF_LVL_4(body) body | |
| #else | |
| #define _RIVE_PROF_LVL_4(body) | |
| #endif | |
| // Dispatch via token paste so `level` works as a literal integer. | |
| #define _RIVE_PROF_LVL_DISPATCH(level, body) _RIVE_PROF_LVL_##level(body) | |
| #define _RIVE_PROF_LVL(level, body) _RIVE_PROF_LVL_DISPATCH(level, body) | |
| #if defined(RIVE_OPTICK) // Optick integration | |
| #include "optick_core.h" | |
| #include "optick.h" | |
| #define RIVE_PROF_INIT() | |
| #define RIVE_PROF_FRAME() OPTICK_FRAME("RiveFrame") | |
| #define RIVE_PROF_SCOPE() OPTICK_EVENT() | |
| #define RIVE_PROF_SCOPENAME(name) OPTICK_EVENT(name) | |
| #define RIVE_PROF_GPUNAME(name) | |
| #define RIVE_PROF_SCOPE_L(level) _RIVE_PROF_LVL(level, OPTICK_EVENT();) | |
| #define RIVE_PROF_SCOPENAME_L(level, name) \ | |
| _RIVE_PROF_LVL(level, OPTICK_EVENT(name);) | |
| #define RIVE_PROF_GPUNAME_L(level, name) _RIVE_PROF_LVL(level, /* unused */) | |
| #define RIVE_PROF_TAG(cat, tag) OPTICK_TAG(cat, tag) | |
| #define RIVE_PROF_THREAD(name) OPTICK_THREAD(name) | |
| #define RIVE_PROF_DRAW() | |
| #define RIVE_PROF_TOGGLEDRAW() | |
| #define RIVE_PROF_GPUSUBMIT(i) | |
| #define RIVE_PROF_GPUFLIP() | |
| #define RIVE_PROF_ENDFRAME() | |
| #elif defined(RIVE_MICROPROFILE) // Microprofile integration | |
| #include "rive/profiler/microprofile_emscripten.h" | |
| #include "microprofile.h" | |
| #include "microprofiledraw.h" | |
| #include "microprofileui.h" | |
| #define MICROPROFILE_GPU_TIMERS 1 | |
| #define RIVE_PROF_INIT() \ | |
| MicroProfileSetEnableAllGroups(true); \ | |
| MicroProfileSetForceEnable(true); \ | |
| MicroProfileWebServerStart(); \ | |
| MicroProfileOnThreadCreate("MainThread"); \ | |
| MicroProfileInit(); | |
| #define RIVE_PROF_FRAME() | |
| #define RIVE_PROF_SCOPE() \ | |
| MICROPROFILE_SCOPEI(__FILE__, __FUNCTION__, 0xffffffff); | |
| #define RIVE_PROF_SCOPENAME(name) \ | |
| MICROPROFILE_SCOPEI("group", name, 0xffffffff); | |
| #define RIVE_PROF_GPUNAME(name) MICROPROFILE_SCOPEGPUI(name, 0xffffffff); | |
| #define RIVE_PROF_SCOPE_L(level) \ | |
| _RIVE_PROF_LVL(level, \ | |
| MICROPROFILE_SCOPEI(__FILE__, __FUNCTION__, 0xffffffff);) | |
| #define RIVE_PROF_SCOPENAME_L(level, name) \ | |
| _RIVE_PROF_LVL(level, MICROPROFILE_SCOPEI("group", name, 0xffffffff);) | |
| #define RIVE_PROF_GPUNAME_L(level, name) \ | |
| _RIVE_PROF_LVL(level, MICROPROFILE_SCOPEGPUI(name, 0xffffffff);) | |
| #define RIVE_PROF_TAG(cat, tag) | |
| #define RIVE_PROF_THREAD(name) | |
| #define RIVE_PROF_DRAW() MicroProfileDraw(); | |
| #define RIVE_PROF_TOGGLEDRAW() // MicroProfileToggleDisplayMode(); | |
| #define RIVE_PROF_GPUSUBMIT(i) MicroProfileGpuSubmit(i); | |
| #define RIVE_PROF_GPUFLIP() // MicroProfileGpuFlip(); | |
| #define RIVE_PROF_ENDFRAME() MicroProfileFlip(); | |
| #else // No profiler selected - fallback to no-op | |
| #define RIVE_PROF_INIT() | |
| #define RIVE_PROF_FRAME() | |
| #define RIVE_PROF_SCOPE() | |
| #define RIVE_PROF_SCOPENAME(name) | |
| #define RIVE_PROF_GPUNAME(name) | |
| #define RIVE_PROF_SCOPE_L(level) | |
| #define RIVE_PROF_SCOPENAME_L(level, name) | |
| #define RIVE_PROF_GPUNAME_L(level, name) | |
| #define RIVE_PROF_TAG(cat, tag) | |
| #define RIVE_PROF_THREAD(name) | |
| #define RIVE_PROF_DRAW() | |
| #define RIVE_PROF_TOGGLEDRAW() | |
| #define RIVE_PROF_GPUSUBMIT(i) | |
| #define RIVE_PROF_GPUFLIP() | |
| #define RIVE_PROF_ENDFRAME() | |
| #endif |