removed microprofile

This commit is contained in:
Anthony Pesch 2017-09-10 20:56:03 -04:00
parent aaa58d7142
commit 2e629ab64d
20 changed files with 80 additions and 9636 deletions

View File

@ -135,9 +135,6 @@ add_library(imgui-static STATIC
list(APPEND RELIB_INCLUDES deps/cimgui)
list(APPEND IMGUI_LIBS imgui-static)
# microprofile
list(APPEND RELIB_INCLUDES deps/microprofile)
# sdl2
set(DIRECTX OFF CACHE BOOL "")
set(RENDER_D3D OFF CACHE BOOL "")
@ -188,7 +185,7 @@ set(RELIB_SOURCES
src/core/md5.c
src/core/memory.c
src/core/option.c
src/core/profiler.cc
src/core/profiler.c
src/core/ringbuf.cc
src/core/rb_tree.c
src/core/sort.c
@ -249,8 +246,7 @@ set(RELIB_SOURCES
src/jit/jit.c
src/jit/pass_stats.c
src/render/gl_backend.c
src/imgui.cc
src/microprofile.cc)
src/imgui.cc)
if(PLATFORM_ANDROID)
list(APPEND RELIB_DEFS PLATFORM_ANDROID=1)
@ -357,7 +353,7 @@ else()
set(REDREAM_SOURCES ${RELIB_SOURCES} src/host/sdl_host.c src/emulator.c src/tracer.c)
set(REDREAM_INCLUDES ${RELIB_INCLUDES})
set(REDREAM_LIBS ${RELIB_LIBS} ${IMGUI_LIBS} ${SDL_LIBS})
set(REDREAM_DEFS ${RELIB_DEFS} HAVE_GDBSERVER HAVE_IMGUI HAVE_MICROPROFILE)
set(REDREAM_DEFS ${RELIB_DEFS} HAVE_GDBSERVER HAVE_IMGUI)
set(REDREAM_FLAGS ${RELIB_FLAGS})
endif()

View File

@ -84,8 +84,7 @@ SOURCES_C := $(CORE_DIR)/src/core/assert.c \
$(CORE_DIR)/src/host/retro_host.c \
$(CORE_DIR)/src/render/gl_backend.c
SOURCES_CXX += $(CORE_DIR)/src/render/imgui.cc \
$(CORE_DIR)/src/render/microprofile.cc
SOURCES_CXX += $(CORE_DIR)/src/imgui.cc
#==--------------------------------------------------------------------------==#
# capstone

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

75
src/core/profiler.c Normal file
View File

@ -0,0 +1,75 @@
#include "core/profiler.h"
#include "core/assert.h"
#include "core/time.h"
#define PROFILER_MAX_COUNTERS 32
struct counter {
int aggregate;
int64_t value[2];
};
static struct {
struct counter counters[PROFILER_MAX_COUNTERS];
int num_counters;
int64_t last_aggregation;
} prof;
prof_token_t prof_get_next_token() {
prof_token_t tok = prof.num_counters++;
CHECK_LT(tok, PROFILER_MAX_COUNTERS);
return tok;
}
prof_token_t prof_get_counter_token(const char *name) {
prof_token_t tok = prof_get_next_token();
struct counter *c = &prof.counters[tok];
c->aggregate = 0;
return tok;
}
prof_token_t prof_get_aggregate_token(const char *name) {
prof_token_t tok = prof_get_next_token();
struct counter *c = &prof.counters[tok];
c->aggregate = 1;
return tok;
}
void prof_flip(int64_t now) {
/* update time-based aggregate counters every second */
int64_t next_aggregation = prof.last_aggregation + NS_PER_SEC;
if (now > next_aggregation) {
for (int i = 0; i < PROFILER_MAX_COUNTERS; i++) {
struct counter *c = &prof.counters[i];
if (c->aggregate) {
c->value[0] = c->value[1];
c->value[1] = 0;
}
}
prof.last_aggregation = now;
}
}
void prof_counter_set(prof_token_t tok, int64_t count) {
struct counter *c = &prof.counters[tok];
c->value[1] = count;
}
void prof_counter_add(prof_token_t tok, int64_t count) {
struct counter *c = &prof.counters[tok];
c->value[1] += count;
}
int64_t prof_counter_load(prof_token_t tok) {
struct counter *c = &prof.counters[tok];
if (c->aggregate) {
/* return the last aggregated value */
return c->value[0];
} else {
return c->value[1];
}
}

View File

@ -1,190 +0,0 @@
#include <atomic>
#ifdef HAVE_MICROPROFILE
#include <microprofile/microprofile.h>
#endif
extern "C" {
#include "core/profiler.h"
#include "core/time.h"
static struct {
#ifdef HAVE_MICROPROFILE
std::atomic<int64_t> counters[MICROPROFILE_MAX_COUNTERS];
int aggregate[MICROPROFILE_MAX_COUNTERS];
int64_t last_aggregation;
#else
/* avoid having an empty struct in c (only valid through GCC extension) */
int dummy;
#endif
} prof;
static inline float hue_to_rgb(float p, float q, float t) {
if (t < 0.0f) {
t += 1.0f;
}
if (t > 1.0f) {
t -= 1.0f;
}
if (t < 1.0f / 6.0f) {
return p + (q - p) * 6.0f * t;
}
if (t < 1.0f / 2.0f) {
return q;
}
if (t < 2.0f / 3.0f) {
return p + (q - p) * (2.0f / 3.0f - t) * 6.0f;
}
return p;
}
static inline void hsl_to_rgb(float h, float s, float l, uint8_t *r, uint8_t *g,
uint8_t *b) {
float fr, fg, fb;
if (s == 0.0f) {
fr = fg = fb = l;
} else {
float q = l < 0.5f ? l * (1.0f + s) : l + s - l * s;
float p = 2.0f * l - q;
fr = hue_to_rgb(p, q, h + 1.0f / 3.0f);
fg = hue_to_rgb(p, q, h);
fb = hue_to_rgb(p, q, h - 1.0f / 3.0f);
}
*r = (uint8_t)(fr * 255);
*g = (uint8_t)(fg * 255);
*b = (uint8_t)(fb * 255);
}
static unsigned prof_hash(const char *name) {
unsigned hash = 5381;
char c;
while ((c = *name++)) {
hash = ((hash << 5) + hash) + c;
}
return hash;
}
static uint32_t prof_scope_color(const char *name) {
unsigned name_hash = prof_hash(name);
float h = (name_hash % 360) / 360.0f;
float s = 0.7f;
float l = 0.6f;
uint8_t r, g, b;
hsl_to_rgb(h, s, l, &r, &g, &b);
return (r << 16) | (g << 8) | b;
}
prof_token_t prof_get_token(const char *group, const char *name) {
prof_init();
#ifdef HAVE_MICROPROFILE
uint32_t color = prof_scope_color(name);
return MicroProfileGetToken(group, name, color, MicroProfileTokenTypeCpu);
#else
return 0;
#endif
}
prof_token_t prof_get_counter_token(const char *name) {
prof_init();
#ifdef HAVE_MICROPROFILE
prof_token_t tok = MicroProfileGetCounterToken(name);
prof.aggregate[tok] = 0;
return tok;
#else
return 0;
#endif
}
prof_token_t prof_get_aggregate_token(const char *name) {
prof_init();
#ifdef HAVE_MICROPROFILE
prof_token_t tok = MicroProfileGetCounterToken(name);
prof.aggregate[tok] = 1;
return tok;
#else
return 0;
#endif
}
void prof_flip(int64_t now) {
#ifdef HAVE_MICROPROFILE
/* update time-based aggregate counters every second */
int64_t next_aggregation = prof.last_aggregation + NS_PER_SEC;
if (now > next_aggregation) {
for (int i = 0; i < MICROPROFILE_MAX_COUNTERS; i++) {
if (!prof.aggregate[i]) {
continue;
}
MicroProfileCounterSet(i, prof.counters[i].load());
prof.counters[i].store(0);
}
prof.last_aggregation = now;
}
/* flip frame-based profile zones at the end of every frame */
MicroProfileFlip();
#endif
}
void prof_counter_set(prof_token_t tok, int64_t count) {
#ifdef HAVE_MICROPROFILE
if (prof.aggregate[tok]) {
prof.counters[tok].store(count);
} else {
MicroProfileCounterSet(tok, count);
}
#endif
}
void prof_counter_add(prof_token_t tok, int64_t count) {
#ifdef HAVE_MICROPROFILE
if (prof.aggregate[tok]) {
prof.counters[tok].fetch_add(count);
} else {
MicroProfileCounterAdd(tok, count);
}
#endif
}
int64_t prof_counter_load(prof_token_t tok) {
#ifdef HAVE_MICROPROFILE
return MicroProfileCounterLoad(tok);
#else
return 0;
#endif
}
void prof_leave(prof_token_t tok, uint64_t tick) {
#ifdef HAVE_MICROPROFILE
MicroProfileLeave(tok, tick);
#endif
}
uint64_t prof_enter(prof_token_t tok) {
#ifdef HAVE_MICROPROFILE
return MicroProfileEnter(tok);
#else
return 0;
#endif
}
void prof_shutdown() {
#ifdef HAVE_MICROPROFILE
MicroProfileShutdown();
#endif
}
void prof_init() {
#ifdef HAVE_MICROPROFILE
MicroProfileInit();
#endif
}
}

View File

@ -5,7 +5,7 @@
#include "core/constructor.h"
#include "core/list.h"
typedef uint64_t prof_token_t;
typedef int prof_token_t;
#define DECLARE_COUNTER(name) extern prof_token_t COUNTER_##name;
@ -22,27 +22,10 @@ typedef uint64_t prof_token_t;
COUNTER_##name = prof_get_aggregate_token(#name); \
}
#define PROF_ENTER(group, name) \
static int prof_init = 0; \
static prof_token_t prof_tok; \
if (!prof_init) { \
prof_tok = prof_get_token(group, name); \
prof_init = 1; \
} \
uint64_t prof_tick = prof_enter(prof_tok)
#define PROF_LEAVE() prof_leave(prof_tok, prof_tick)
prof_token_t prof_get_token(const char *group, const char *name);
prof_token_t prof_get_counter_token(const char *name);
prof_token_t prof_get_aggregate_token(const char *name);
void prof_init();
void prof_shutdown();
uint64_t prof_enter(prof_token_t tok);
void prof_leave(prof_token_t tok, uint64_t tick);
int64_t prof_counter_load(prof_token_t tok);
void prof_counter_add(prof_token_t tok, int64_t count);
void prof_counter_set(prof_token_t tok, int64_t count);

View File

@ -155,8 +155,6 @@ void arm7_suspend(struct arm7 *arm) {
}
static void arm7_run(struct device *dev, int64_t ns) {
PROF_ENTER("cpu", "arm7_run");
struct arm7 *arm = (struct arm7 *)dev;
struct armv3_context *ctx = &arm->ctx;
struct jit *jit = arm->jit;
@ -167,8 +165,6 @@ static void arm7_run(struct device *dev, int64_t ns) {
jit_run(arm->jit, cycles);
prof_counter_add(COUNTER_arm7_instrs, arm->ctx.ran_instrs);
PROF_LEAVE();
}
static void arm7_guest_destroy(struct jit_guest *guest) {

View File

@ -29,7 +29,6 @@
#include "guest/scheduler.h"
#include "guest/sh4/sh4.h"
DEFINE_AGGREGATE_COUNTER(ta_data);
DEFINE_AGGREGATE_COUNTER(ta_renders);
struct ta {
@ -410,9 +409,6 @@ static void ta_write_context(struct ta *ta, struct ta_context *ctx, void *ptr,
memcpy(&ctx->params[ctx->size], ptr, size);
ctx->size += size;
/* track how much TA data is written per second */
prof_counter_add(COUNTER_ta_data, size);
/* each TA command is either 32 or 64 bytes, with the pcw being in the first
32 bytes always. check every 32 bytes to see if the command has been
completely received or not */
@ -731,8 +727,6 @@ static void ta_yuv_process_macroblock(struct ta *ta, void *data) {
* 3.) texture data - data that is written directly to vram
*/
static void ta_poly_write(struct ta *ta, uint32_t dst, void *ptr, int size) {
PROF_ENTER("cpu", "ta_poly_write");
CHECK(size % 32 == 0);
uint8_t *src = ptr;
@ -741,13 +735,9 @@ static void ta_poly_write(struct ta *ta, uint32_t dst, void *ptr, int size) {
ta_write_context(ta, ta->curr_context, src, 32);
src += 32;
}
PROF_LEAVE();
}
static void ta_yuv_write(struct ta *ta, uint32_t dst, void *ptr, int size) {
PROF_ENTER("cpu", "ta_yuv_write");
struct holly *holly = ta->holly;
struct pvr *pvr = ta->pvr;
@ -759,18 +749,12 @@ static void ta_yuv_write(struct ta *ta, uint32_t dst, void *ptr, int size) {
ta_yuv_process_macroblock(ta, src);
src += ta->yuv_macroblock_size;
}
PROF_LEAVE();
}
static void ta_texture_write(struct ta *ta, uint32_t dst, void *ptr, int size) {
PROF_ENTER("cpu", "ta_texture_write");
uint8_t *src = ptr;
dst &= 0xeeffffff;
memcpy(&ta->video_ram[dst], src, size);
PROF_LEAVE();
}
/*

View File

@ -127,8 +127,6 @@ static inline uint32_t float_to_rgba(float r, float g, float b, float a) {
static texture_handle_t tr_convert_texture(struct tr *tr,
const struct ta_context *ctx,
union tsp tsp, union tcw tcw) {
PROF_ENTER("gpu", "tr_convert_texture");
/* TODO it's bad that textures are only cached based off tsp / tcw yet the
TEXT_CONTROL registers and PAL_RAM_CTRL registers are used here to control
texture generation */
@ -138,7 +136,6 @@ static texture_handle_t tr_convert_texture(struct tr *tr,
/* if there's a non-dirty handle, return it */
if (entry->handle && !entry->dirty) {
PROF_LEAVE();
return entry->handle;
}
@ -183,8 +180,6 @@ static texture_handle_t tr_convert_texture(struct tr *tr,
entry->height = height;
entry->dirty = 0;
PROF_LEAVE();
return entry->handle;
}
@ -712,8 +707,6 @@ static int tr_compare_surf(const void *a, const void *b) {
static void tr_sort_render_list(struct tr *tr, struct tr_context *rc,
int list_type) {
PROF_ENTER("gpu", "tr_sort_render_list");
/* sort each surface from back to front based on its minz */
struct tr_list *list = &rc->lists[list_type];
@ -735,8 +728,6 @@ static void tr_sort_render_list(struct tr *tr, struct tr_context *rc,
msort_noalloc(list->surfs, sort_tmp, list->num_surfs, sizeof(int),
&tr_compare_surf);
PROF_LEAVE();
}
static void tr_parse_eol(struct tr *tr, const struct ta_context *ctx,
@ -791,8 +782,6 @@ static void tr_render_list(struct render_backend *r,
void tr_render_context_until(struct render_backend *r,
const struct tr_context *rc, int end_surf) {
PROF_ENTER("gpu", "tr_render_context_until");
int stopped = 0;
r_begin_ta_surfaces(r, rc->width, rc->height, rc->verts, rc->num_verts,
@ -803,8 +792,6 @@ void tr_render_context_until(struct render_backend *r,
tr_render_list(r, rc, TA_LIST_TRANSLUCENT, end_surf, &stopped);
r_end_ta_surfaces(r);
PROF_LEAVE();
}
void tr_render_context(struct render_backend *r, const struct tr_context *rc) {
@ -814,8 +801,6 @@ void tr_render_context(struct render_backend *r, const struct tr_context *rc) {
void tr_convert_context(struct render_backend *r, void *userdata,
tr_find_texture_cb find_texture,
const struct ta_context *ctx, struct tr_context *rc) {
PROF_ENTER("gpu", "tr_convert_context");
struct tr tr;
tr.r = r;
tr.userdata = userdata;
@ -886,6 +871,4 @@ void tr_convert_context(struct render_backend *r, void *userdata,
LOG_INFO("tr_convert_convext merged %d / %d surfaces", tr.merged_surfs,
tr.merged_surfs + rc->num_surfs);
#endif
PROF_LEAVE();
}

View File

@ -25,7 +25,6 @@
#endif
DEFINE_AGGREGATE_COUNTER(sh4_instrs);
DEFINE_AGGREGATE_COUNTER(sh4_sr_updates);
/* callbacks to service sh4_reg_read / sh4_reg_write calls */
struct reg_cb sh4_cb[SH4_NUM_REGS];
@ -47,8 +46,6 @@ struct sh4_interrupt_info sh4_interrupts[SH4_NUM_INTERRUPTS] = {
static void sh4_sr_updated(struct sh4 *sh4, uint32_t old_sr) {
struct sh4_context *ctx = &sh4->ctx;
prof_counter_add(COUNTER_sh4_sr_updates, 1);
if ((ctx->sr & RB_MASK) != (old_sr & RB_MASK)) {
sh4_swap_gpr_bank(ctx);
}
@ -166,8 +163,6 @@ static void sh4_invalid_instr(struct sh4 *sh4) {
}
static void sh4_run(struct device *dev, int64_t ns) {
PROF_ENTER("cpu", "sh4_run");
struct sh4 *sh4 = (struct sh4 *)dev;
struct sh4_context *ctx = &sh4->ctx;
struct jit *jit = sh4->jit;
@ -178,8 +173,6 @@ static void sh4_run(struct device *dev, int64_t ns) {
jit_run(sh4->jit, cycles);
prof_counter_add(COUNTER_sh4_instrs, sh4->ctx.ran_instrs);
PROF_LEAVE();
}
static void sh4_guest_destroy(struct jit_guest *guest) {

View File

@ -29,8 +29,6 @@ static void sh4_ccn_reset(struct sh4 *sh4) {
}
void sh4_ccn_pref(struct sh4 *sh4, uint32_t addr) {
PROF_ENTER("cpu", "sh4_ccn_pref");
/* make sure this is a sq related prefetch */
DCHECK(addr >= 0xe0000000 && addr <= 0xe3ffffff);
@ -57,8 +55,6 @@ void sh4_ccn_pref(struct sh4 *sh4, uint32_t addr) {
}
as_memcpy_to_guest(sh4->memory_if->space, dst, sh4->ctx.sq[sqi], 32);
PROF_LEAVE();
}
uint32_t sh4_ccn_cache_read(struct sh4 *sh4, uint32_t addr,

View File

@ -10,7 +10,6 @@
#include "emulator.h"
#include "host/host.h"
#include "imgui.h"
#include "microprofile.h"
#include "render/render_backend.h"
#include "tracer.h"
@ -50,7 +49,6 @@ struct sdl_host {
int video_width;
int video_height;
struct imgui *imgui;
struct microprofile *mp;
/* input */
int key_map[K_NUM_KEYS];
@ -265,7 +263,6 @@ int video_can_fullscreen(struct host *base) {
}
static void video_shutdown(struct sdl_host *host) {
mp_destroy(host->mp);
imgui_destroy(host->imgui);
r_destroy(host->video_rb);
video_destroy_context(host, host->video_ctx);
@ -275,7 +272,6 @@ static int video_init(struct sdl_host *host) {
host->video_ctx = video_create_context(host);
host->video_rb = r_create();
host->imgui = imgui_create(host->video_rb);
host->mp = mp_create(host->video_rb);
return 1;
}
@ -452,7 +448,6 @@ static void input_handle_mousemove(struct sdl_host *host, int port, int x,
}
imgui_mousemove(host->imgui, x, y);
mp_mousemove(host->mp, x, y);
}
static void input_handle_keydown(struct sdl_host *host, int port,
@ -469,7 +464,6 @@ static void input_handle_keydown(struct sdl_host *host, int port,
}
imgui_keydown(host->imgui, key, value);
mp_keydown(host->mp, key, value);
}
static void input_handle_controller_removed(struct sdl_host *host, int port) {
@ -847,7 +841,6 @@ int main(int argc, char **argv) {
emu_render_frame(emu, host->video_width, host->video_height);
/* overlay user interface */
mp_render_frame(host->mp, host->video_width, host->video_height);
imgui_end_frame(host->imgui);
/* flip profiler at end of frame */

View File

@ -663,8 +663,6 @@ static void x64_backend_emit(struct x64_backend *backend, struct ir *ir,
static int x64_backend_assemble_code(struct jit_backend *base, struct ir *ir,
uint8_t **addr, int *size,
jit_emit_cb emit_cb, void *emit_data) {
PROF_ENTER("cpu", "x64_backend_assemble_code");
struct x64_backend *backend = container_of(base, struct x64_backend, base);
auto &e = *backend->codegen;
@ -686,8 +684,6 @@ static int x64_backend_assemble_code(struct jit_backend *base, struct ir *ir,
*addr = code;
*size = (int)(e.getCurr<uint8_t *>() - code);
PROF_LEAVE();
return res;
}

View File

@ -2,14 +2,10 @@
extern "C" {
#include "core/assert.h"
#include "core/profiler.h"
#include "jit/jit.h"
#include "jit/jit_guest.h"
}
DEFINE_COUNTER(edges_patched);
DEFINE_COUNTER(edges_restored);
/* log out pc each time dispatch is entered for debugging */
#define LOG_DISPATCH_EVERY_N 0
@ -39,8 +35,6 @@ void x64_dispatch_restore_edge(struct jit_backend *base, void *code,
uint32_t dst) {
struct x64_backend *backend = container_of(base, struct x64_backend, base);
prof_counter_add(COUNTER_edges_restored, 1);
Xbyak::CodeGenerator e(32, code);
e.call(backend->dispatch_static);
}
@ -48,8 +42,6 @@ void x64_dispatch_restore_edge(struct jit_backend *base, void *code,
void x64_dispatch_patch_edge(struct jit_backend *base, void *code, void *dst) {
struct x64_backend *backend = container_of(base, struct x64_backend, base);
prof_counter_add(COUNTER_edges_patched, 1);
Xbyak::CodeGenerator e(32, code);
e.jmp(dst);
}

View File

@ -133,8 +133,6 @@ static void sh4_frontend_translate_code(struct jit_frontend *base,
struct sh4_guest *guest = (struct sh4_guest *)frontend->guest;
struct sh4_context *ctx = (struct sh4_context *)guest->ctx;
PROF_ENTER("cpu", "sh4_frontend_translate_code");
int offset = 0;
int use_fpscr = 0;
int was_delay = 0;
@ -271,8 +269,6 @@ static void sh4_frontend_translate_code(struct jit_frontend *base,
ir_alloc_i32(ir, ctx->fpscr & (PR_MASK | SZ_MASK));
ir_assert_eq(ir, actual, expected);
}
PROF_LEAVE();
}
static void sh4_frontend_analyze_code(struct jit_frontend *base,

View File

@ -100,8 +100,6 @@ static int jit_is_stale(struct jit *jit, struct jit_block *block) {
}
static void jit_patch_edges(struct jit *jit, struct jit_block *block) {
PROF_ENTER("cpu", "jit_patch_edges");
/* patch incoming edges to this block to directly jump to it instead of
going through dispatch */
list_for_each_entry(edge, &block->in_edges, struct jit_edge, in_it) {
@ -120,13 +118,9 @@ static void jit_patch_edges(struct jit *jit, struct jit_block *block) {
edge->dst->host_addr);
}
}
PROF_LEAVE();
}
static void jit_restore_edges(struct jit *jit, struct jit_block *block) {
PROF_ENTER("cpu", "jit_restore_edges");
/* restore any patched branches to go back through dispatch */
list_for_each_entry(edge, &block->in_edges, struct jit_edge, in_it) {
if (edge->patched) {
@ -135,8 +129,6 @@ static void jit_restore_edges(struct jit *jit, struct jit_block *block) {
edge->dst->guest_addr);
}
}
PROF_LEAVE();
}
static void jit_invalidate_block(struct jit *jit, struct jit_block *block,
@ -338,8 +330,6 @@ static void jit_promote_fastmem(struct jit *jit, struct jit_block *block,
}
void jit_compile_code(struct jit *jit, uint32_t guest_addr) {
PROF_ENTER("cpu", "jit_compile_block");
#if 0
LOG_INFO("jit_compile_block %s 0x%08x", jit->tag, guest_addr);
#endif
@ -397,7 +387,6 @@ void jit_compile_code(struct jit *jit, uint32_t guest_addr) {
try to compile again */
LOG_INFO("backend overflow, resetting code cache");
jit_free_code(jit);
PROF_LEAVE();
return;
}
@ -415,8 +404,6 @@ void jit_compile_code(struct jit *jit, uint32_t guest_addr) {
(uintptr_t)block->host_addr, block->host_size, jit->tag,
block->guest_addr);
}
PROF_LEAVE();
}
static int jit_handle_exception(void *data, struct exception_state *ex) {

View File

@ -1,349 +0,0 @@
#ifdef HAVE_MICROPROFILE
#define MICROPROFILE_WEBSERVER 0
#define MICROPROFILE_GPU_TIMERS 0
#define MICROPROFILE_ENABLED 1
#define MICROPROFILEUI_ENABLED 1
#define MICROPROFILE_IMPL 1
#define MICROPROFILEUI_IMPL 1
#define MICROPROFILE_PER_THREAD_BUFFER_SIZE (1024 * 1024 * 20)
#define MICROPROFILE_CONTEXT_SWITCH_TRACE 0
#include <microprofile/microprofile.h>
#include <microprofile/microprofileui.h>
#endif
extern "C" {
#include "core/assert.h"
#include "core/math.h"
#include "microprofile.h"
#include "render/render_backend.h"
}
static const int FONT_WIDTH = 1024;
static const int FONT_HEIGHT = 9;
#include "microprofile_font.inc"
static const int MAX_2D_VERTICES = 32768;
static const int MAX_2D_SURFACES = 256;
struct microprofile {
struct render_backend *r;
texture_handle_t font_texture;
struct ui_surface surfs[MAX_2D_SURFACES];
int num_surfs;
struct ui_vertex verts[MAX_2D_VERTICES];
int num_verts;
};
static struct microprofile *s_mp;
#define Q0(d, member, v) d[0].member = v
#define Q1(d, member, v) \
d[1].member = v; \
d[3].member = v
#define Q2(d, member, v) d[4].member = v
#define Q3(d, member, v) \
d[2].member = v; \
d[5].member = v
static struct ui_vertex *mp_alloc_verts(struct microprofile *mp,
const struct ui_surface &desc,
int count) {
#ifdef HAVE_MICROPROFILE
CHECK(mp->num_verts + count <= MAX_2D_VERTICES);
uint32_t first_vert = mp->num_verts;
mp->num_verts += count;
/* try to batch with the last surface if possible */
if (mp->num_surfs) {
struct ui_surface &last_surf = mp->surfs[mp->num_surfs - 1];
if (last_surf.prim_type == desc.prim_type &&
last_surf.texture == desc.texture &&
last_surf.src_blend == desc.src_blend &&
last_surf.dst_blend == desc.dst_blend) {
last_surf.num_verts += count;
return &mp->verts[first_vert];
}
}
/* else, allocate a new surface */
CHECK(mp->num_surfs < MAX_2D_SURFACES);
struct ui_surface &next_surf = mp->surfs[mp->num_surfs];
next_surf.prim_type = desc.prim_type;
next_surf.texture = desc.texture;
next_surf.src_blend = desc.src_blend;
next_surf.dst_blend = desc.dst_blend;
next_surf.scissor = false;
next_surf.first_vert = first_vert;
next_surf.num_verts = count;
mp->num_surfs++;
return &mp->verts[first_vert];
#endif
return NULL;
}
static void mp_draw_text(struct microprofile *mp, int x, int y, uint32_t color,
const char *text) {
#ifdef HAVE_MICROPROFILE
float fx = static_cast<float>(x);
float fy = static_cast<float>(y);
float fy2 = fy + (MICROPROFILE_TEXT_HEIGHT + 1);
int text_len = static_cast<int>(strlen(text));
struct ui_vertex *vertex = mp_alloc_verts(mp, {PRIM_TRIANGLES,
mp->font_texture,
BLEND_SRC_ALPHA,
BLEND_ONE_MINUS_SRC_ALPHA,
false,
{0.0f, 0.0f, 0.0f, 0.0f},
0,
0},
6 * text_len);
for (int i = 0; i < text_len; i++) {
float fx2 = fx + MICROPROFILE_TEXT_WIDTH;
float fu = s_font_offsets[static_cast<int>(text[i])] /
static_cast<float>(FONT_WIDTH);
float fu2 = fu + MICROPROFILE_TEXT_WIDTH / static_cast<float>(FONT_WIDTH);
Q0(vertex, xy[0], fx);
Q0(vertex, xy[1], fy);
Q0(vertex, color, color);
Q0(vertex, uv[0], fu);
Q0(vertex, uv[1], 0.0f);
Q1(vertex, xy[0], fx2);
Q1(vertex, xy[1], fy);
Q1(vertex, color, color);
Q1(vertex, uv[0], fu2);
Q1(vertex, uv[1], 0.0f);
Q2(vertex, xy[0], fx2);
Q2(vertex, xy[1], fy2);
Q2(vertex, color, color);
Q2(vertex, uv[0], fu2);
Q2(vertex, uv[1], 1.0f);
Q3(vertex, xy[0], fx);
Q3(vertex, xy[1], fy2);
Q3(vertex, color, color);
Q3(vertex, uv[0], fu);
Q3(vertex, uv[1], 1.0f);
fx = fx2 + 1.0f;
vertex += 6;
}
#endif
}
static void mp_draw_box(struct microprofile *mp, int x0, int y0, int x1, int y1,
uint32_t color, enum box_type type) {
#ifdef HAVE_MICROPROFILE
struct ui_vertex *vertex = mp_alloc_verts(mp, {PRIM_TRIANGLES,
0,
BLEND_SRC_ALPHA,
BLEND_ONE_MINUS_SRC_ALPHA,
false,
{0.0f, 0.0f, 0.0f, 0.0f},
0,
0},
6);
if (type == BOX_FLAT) {
Q0(vertex, xy[0], (float)x0);
Q0(vertex, xy[1], (float)y0);
Q0(vertex, color, color);
Q1(vertex, xy[0], (float)x1);
Q1(vertex, xy[1], (float)y0);
Q1(vertex, color, color);
Q2(vertex, xy[0], (float)x1);
Q2(vertex, xy[1], (float)y1);
Q2(vertex, color, color);
Q3(vertex, xy[0], (float)x0);
Q3(vertex, xy[1], (float)y1);
Q3(vertex, color, color);
} else {
uint32_t a = (color & 0xff000000) >> 24;
uint32_t r = (color & 0xff0000) >> 16;
uint32_t g = (color & 0xff00) >> 8;
uint32_t b = color & 0xff;
uint32_t max = MAX(MAX(MAX(r, g), b), 30u);
uint32_t min = MIN(MIN(MIN(r, g), b), 180u);
uint32_t r0 = 0xff & ((r + max) / 2);
uint32_t g0 = 0xff & ((g + max) / 2);
uint32_t b0 = 0xff & ((b + max) / 2);
uint32_t r1 = 0xff & ((r + min) / 2);
uint32_t g1 = 0xff & ((g + min) / 2);
uint32_t b1 = 0xff & ((b + min) / 2);
uint32_t color0 = (a << 24) | (b0 << 16) | (g0 << 8) | r0;
uint32_t color1 = (a << 24) | (b1 << 16) | (g1 << 8) | r1;
Q0(vertex, xy[0], (float)x0);
Q0(vertex, xy[1], (float)y0);
Q0(vertex, color, color0);
Q1(vertex, xy[0], (float)x1);
Q1(vertex, xy[1], (float)y0);
Q1(vertex, color, color0);
Q2(vertex, xy[0], (float)x1);
Q2(vertex, xy[1], (float)y1);
Q2(vertex, color, color1);
Q3(vertex, xy[0], (float)x0);
Q3(vertex, xy[1], (float)y1);
Q3(vertex, color, color1);
}
#endif
}
static void mp_draw_line(struct microprofile *mp, float *verts, int num_verts,
uint32_t color) {
#ifdef HAVE_MICROPROFILE
CHECK(num_verts);
struct ui_vertex *vertex = mp_alloc_verts(mp, {PRIM_LINES,
0,
BLEND_SRC_ALPHA,
BLEND_ONE_MINUS_SRC_ALPHA,
false,
{0.0f, 0.0f, 0.0f, 0.0f},
0,
0},
2 * (num_verts - 1));
for (int i = 0; i < num_verts - 1; ++i) {
vertex[0].xy[0] = verts[i * 2];
vertex[0].xy[1] = verts[i * 2 + 1];
vertex[0].color = color;
vertex[1].xy[0] = verts[(i + 1) * 2];
vertex[1].xy[1] = verts[(i + 1) * 2 + 1];
vertex[1].color = color;
vertex += 2;
}
#endif
}
void mp_render_frame(struct microprofile *mp, int width, int height) {
#ifdef HAVE_MICROPROFILE
s_mp = mp;
/* update draw surfaces */
MicroProfileDraw(width, height);
/* render the surfaces */
r_viewport(mp->r, 0, 0, width, height);
r_begin_ui_surfaces(mp->r, mp->verts, mp->num_verts, nullptr, 0);
for (int i = 0; i < mp->num_surfs; i++) {
struct ui_surface *surf = &mp->surfs[i];
r_draw_ui_surface(mp->r, surf);
}
r_end_ui_surfaces(mp->r);
/* reset surfaces */
mp->num_surfs = 0;
mp->num_verts = 0;
#endif
}
void mp_mousemove(struct microprofile *mp, int x, int y) {
#ifdef HAVE_MICROPROFILE
MicroProfileMousePosition(x, y, 0);
#endif
}
void mp_keydown(struct microprofile *mp, enum keycode key, int16_t value) {
#ifdef HAVE_MICROPROFILE
if (key == K_F2) {
if (value > 0) {
MicroProfileToggleDisplayMode();
}
} else if (key == K_MOUSE1) {
int down = value > 0;
MicroProfileMouseButton(down, 0);
} else if (key == K_MOUSE2) {
int down = value > 0;
MicroProfileMouseButton(0, down);
}
#endif
}
void mp_destroy(struct microprofile *mp) {
#ifdef HAVE_MICROPROFILE
r_destroy_texture(mp->r, mp->font_texture);
free(mp);
#endif
}
struct microprofile *mp_create(struct render_backend *r) {
#ifdef HAVE_MICROPROFILE
struct microprofile *mp = reinterpret_cast<struct microprofile *>(
calloc(1, sizeof(struct microprofile)));
mp->r = r;
/* register and enable cpu and gpu groups by default */
uint16_t cpu_group = MicroProfileGetGroup("cpu", MicroProfileTokenTypeCpu);
g_MicroProfile.nActiveGroupWanted |= 1ll << cpu_group;
uint16_t gpu_group = MicroProfileGetGroup("gpu", MicroProfileTokenTypeCpu);
g_MicroProfile.nActiveGroupWanted |= 1ll << gpu_group;
/* render time / average time bars by default */
g_MicroProfile.nBars |= MP_DRAW_TIMERS | MP_DRAW_AVERAGE | MP_DRAW_CALL_COUNT;
/* aggregate stats every 120 frames by default */
g_MicroProfile.nAggregateFlip = 120;
/* register the font texture */
mp->font_texture =
r_create_texture(mp->r, PXL_RGBA, FILTER_NEAREST, WRAP_CLAMP_TO_EDGE,
WRAP_CLAMP_TO_EDGE, 0, FONT_WIDTH, FONT_HEIGHT,
reinterpret_cast<const uint8_t *>(s_font_data));
return mp;
#else
return NULL;
#endif
}
/* microprofile expects the following three functions to be defined, they're
called during MicroProfileDraw */
#ifdef HAVE_MICROPROFILE
void MicroProfileDrawText(int x, int y, uint32_t color, const char *text,
uint32_t len) {
/* microprofile provides 24-bit rgb values for text color */
color = 0xff000000 | color;
/* convert color from argb -> abgr */
color = (color & 0xff000000) | ((color & 0xff) << 16) | (color & 0xff00) |
((color & 0xff0000) >> 16);
mp_draw_text(s_mp, x, y, color, text);
}
void MicroProfileDrawBox(int x0, int y0, int x1, int y1, uint32_t color,
MicroProfileBoxType type) {
/* convert color from argb -> abgr */
color = (color & 0xff000000) | ((color & 0xff) << 16) | (color & 0xff00) |
((color & 0xff0000) >> 16);
mp_draw_box(s_mp, x0, y0, x1, y1, color, (enum box_type)type);
}
void MicroProfileDrawLine2D(uint32_t num_vertices, float *vertices,
uint32_t color) {
/* microprofile provides 24-bit rgb values for line color */
color = 0xff000000 | color;
/* convert color from argb -> abgr */
color = (color & 0xff000000) | ((color & 0xff) << 16) | (color & 0xff00) |
((color & 0xff0000) >> 16);
mp_draw_line(s_mp, vertices, num_vertices, color);
}
#endif

View File

@ -1,17 +0,0 @@
#ifndef MICROPROFILE_IMPL_H
#define MICROPROFILE_IMPL_H
#include "host/keycode.h"
struct microprofile;
struct render_backend;
struct microprofile *mp_create(struct render_backend *r);
void mp_destroy(struct microprofile *mp);
void mp_keydown(struct microprofile *mp, enum keycode key, int16_t value);
void mp_mousemove(struct microprofile *mp, int x, int y);
void mp_render_frame(struct microprofile *mp, int width, int height);
#endif

File diff suppressed because it is too large Load Diff