From eefcf860271cdcb4658b8db37cb13f6639fa6ba9 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Tue, 12 May 2015 19:50:56 +0200 Subject: [PATCH] Initial profiler work --- profiler/profiler.cpp | 114 +++++++++++++++++++++--------------------- profiler/profiler.h | 56 ++++++++++++--------- ui/virtual_input.cpp | 2 +- 3 files changed, 91 insertions(+), 81 deletions(-) diff --git a/profiler/profiler.cpp b/profiler/profiler.cpp index a8f84befae..9ec8b89149 100644 --- a/profiler/profiler.cpp +++ b/profiler/profiler.cpp @@ -1,4 +1,4 @@ -// UNFINISHED but kinda working +// Ultra-lightweight category profiler with history. #include #include @@ -7,78 +7,78 @@ #include #include "base/logging.h" -#include "gfx_es2/draw_buffer.h" #include "base/timeutil.h" +#include "gfx_es2/draw_buffer.h" +#include "profiler/profiler.h" -using namespace std; +#define MAX_CATEGORIES 16 // Can be any number +#define HISTORY_SIZE 256 // Must be power of 2 +#ifndef _DEBUG +// If the compiler can collapse identical strings, we don't even need the strcmp. +#define UNIFIED_CONST_STR +#endif -struct Section { - const char *name; - int level; - double start; - double end; +struct CategoryFrame { + float time_taken[MAX_CATEGORIES]; }; -static vector
current_frame; -static double frame_start; -#define NUM_LEVELS 16 -static Section cur_section[NUM_LEVELS]; +struct Profiler { + int frameCount; + int historyPos; + double eventStart; + double curFrameStart; +}; -static int level; +static Profiler profiler; +static Category categories[MAX_CATEGORIES]; +static CategoryFrame *history; -void _profiler_init() { - level = 0; +void internal_profiler_init() { + history = new CategoryFrame[HISTORY_SIZE]; + for (int i = 0; i < MAX_CATEGORIES; i++) { + categories[i].color = 0x358236 * i; + } } -void _profiler_enter(const char *section_name) { - cur_section[level].name = section_name; - cur_section[level].start = real_time_now(); - level++; +int internal_profiler_enter(const char *section_name) { + for (int i = 0; i < MAX_CATEGORIES; i++) { + const char *catname = categories[i].name; + if (!catname) + break; +#ifdef UNIFIED_CONST_STR + if (catname == section_name) { +#else + if (!strcmp(catname, section_name)) { +#endif + profiler.eventStart = time_now_d(); + return i; + } + } + return -1; } -void _profiler_leave(const char *section_name) { - --level; - cur_section[level].end = real_time_now(); - if (strcmp(section_name, cur_section[level].name)) { - FLOG("Can't enter %s when %s is active, only one at a time!", - section_name, cur_section[level].name); - } - cur_section[level].level = level; - current_frame.push_back(cur_section[level]); +void internal_profiler_leave(int category) { + if (category < 0) + return; + double diff = time_now_d() - profiler.eventStart; + history[profiler.historyPos].time_taken[category] += (float)diff; } -void _profiler_begin_frame() { - frame_start = real_time_now(); +void internal_profiler_end_frame() { + profiler.curFrameStart = real_time_now(); + profiler.historyPos++; + profiler.historyPos &= ~HISTORY_SIZE; } -void _profiler_end_frame() { - current_frame.clear(); +const char *GetSectionName(int i) { + return i >= 0 ? categories[i].name : "N/A"; } -void _profiler_log() { - const char *spaces = " "; - ILOG("Profiler output ===================="); - for (int i = 0; i < (int)current_frame.size(); i++) { - double start = current_frame[i].start - frame_start; - double elapsed = current_frame[i].end - current_frame[i].start; - double start_ms = (start*1000); - double elapsed_ms = (elapsed*1000); - ILOG("%s%s: %0.3f ms", spaces + 15-current_frame[i].level, current_frame[i].name, elapsed_ms); - } -} - -void _profiler_draw(DrawBuffer *draw2d, int font) { - uint32_t colors[4] = { 0xFFc0a030, 0xFF30a0c0, 0xFF30C050, 0xFFc02080 }; - for (int i = 0; i < (int)current_frame.size(); i++) { - const Section §ion = current_frame[i]; - double start = section.start - frame_start; - double elapsed = section.end - current_frame[i].start; - - uint32_t color = colors[i&3]; - float y1 = i * 32, y2 = (i+1)*32; - float x1 = start / 0.0166666; - float x2 = (start + elapsed) / 0.01666666; - draw2d->Rect(x1, y1, x2, y2, color); - } +int GetNumSections() { + for (int i = 0; i < MAX_CATEGORIES; i++) { + if (!categories[i].name) + return i; + } + return 0; } diff --git a/profiler/profiler.h b/profiler/profiler.h index a1ed0bd2c0..e61ffbe194 100644 --- a/profiler/profiler.h +++ b/profiler/profiler.h @@ -1,38 +1,48 @@ #pragma once -// WIP - very preliminary. -// #define USE_PROFILER +#define USE_PROFILER #ifdef USE_PROFILER class DrawBuffer; -void _profiler_init(); -void _profiler_begin_frame(); -void _profiler_end_frame(); +struct Category { + const char *name; + uint32_t color; +}; -void _profiler_log(); -void _profiler_draw(DrawBuffer *draw2d, int font); +void internal_profiler_init(); +void internal_profiler_end_frame(); -void _profiler_enter(const char *section); -void _profiler_leave(const char *section); +int internal_profiler_enter(const char *section); // Returns the category number. +void internal_profiler_leave(int category); -#define PROFILER_INIT() _profiler_init(); -#define PROFILER_ENTER(section) _profiler_enter(section); -#define PROFILER_LEAVE(section) _profiler_leave(section); -#define PROFILER_LOG() _profiler_log(); -#define PROFILER_DRAW(draw, font) _profiler_draw(draw, font); -#define PROFILER_BEGIN_FRAME() _profiler_begin_frame(); -#define PROFILER_END_FRAME() _profiler_end_frame(); +float internal_profiler_gethistory(const char *section, float *data, int count); +const char *GetSectionName(int i); +int GetNumSections(); + +class ProfileThis { +public: + ProfileThis(const char *category) { + cat_ = internal_profiler_enter(category); + } + ~ProfileThis() { + internal_profiler_leave(cat_); + } +private: + int cat_; +}; + +#define PROFILE_INIT() internal_profiler_init(); +#define PROFILE_THIS_SCOPE(cat) ProfileThis _profile_scoped(cat); +#define PROFILE_END_FRAME() internal_profiler_end_frame(); +#define PROFILE_GET_HISTORY(section, data, count) internal_profiler_gethistory(section, data, count); #else -#define PROFILER_INIT() -#define PROFILER_ENTER(section) -#define PROFILER_LEAVE(section) -#define PROFILER_LOG() -#define PROFILER_DRAW(draw, font) -#define PROFILER_BEGIN_FRAME() -#define PROFILER_END_FRAME() +#define PROFILE_INIT() +#define PROFILE_THIS_SCOPE(cat) ProfileThis _profile_scoped(cat); +#define PROFILE_END_FRAME() +#define PROFILE_GET_HISTORY(section, data, count) internal_profiler_gethistory(section, data, count); #endif diff --git a/ui/virtual_input.cpp b/ui/virtual_input.cpp index f27a81993e..dc12940543 100644 --- a/ui/virtual_input.cpp +++ b/ui/virtual_input.cpp @@ -47,7 +47,7 @@ void TouchButton::draw(DrawBuffer &db, uint32_t color, uint32_t colorOverlay) } TouchCrossPad::TouchCrossPad(const Atlas *atlas, int arrowIndex, int overlayIndex) - : atlas_(atlas), arrowIndex_(arrowIndex), overlayIndex_(overlayIndex) + : atlas_(atlas), arrowIndex_(arrowIndex), overlayIndex_(overlayIndex), down_(0) { }