mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-04 10:15:27 +02:00
Initial profiler work
This commit is contained in:
1 parent
dfa3a93d02
commit
eefcf86027
3 files changed
+91
-81
No files matched your search
+57
-57
@@ -1,4 +1,4 @@
|
||||
// UNFINISHED but kinda working
|
||||
// Ultra-lightweight category profiler with history.
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
@@ -7,78 +7,78 @@
|
||||
#include <string.h>
|
||||
|
||||
#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<Section> 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;
|
||||
}
|
||||
+33
-23
@@ -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
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user