forked from 0ad/0ad
Rough support for profiling replay mode and scripts
This was SVN commit r10634.
This commit is contained in:
parent
4da8bf001f
commit
8492426a14
@ -524,3 +524,28 @@ const char* CProfiler2::ConstructJSONResponse(std::ostream& stream, const std::s
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CProfiler2::SaveToFile()
|
||||
{
|
||||
OsPath path = psLogDir()/"profile2.jsonp";
|
||||
std::ofstream stream(OsString(path).c_str(), std::ofstream::out | std::ofstream::trunc);
|
||||
|
||||
std::vector<ThreadStorage*> threads;
|
||||
|
||||
{
|
||||
CScopeLock lock(m_Mutex);
|
||||
threads = m_Threads;
|
||||
}
|
||||
|
||||
stream << "profileDataCB({\"threads\": [\n";
|
||||
for (size_t i = 0; i < threads.size(); ++i)
|
||||
{
|
||||
if (i != 0)
|
||||
stream << ",\n";
|
||||
stream << "{\"name\":\"" << CStr(threads[i]->GetName()).EscapeToPrintableASCII() << "\",\n";
|
||||
stream << "\"data\": ";
|
||||
ConstructJSONResponse(stream, threads[i]->GetName());
|
||||
stream << "\n}";
|
||||
}
|
||||
stream << "\n]});\n";
|
||||
}
|
||||
|
@ -347,6 +347,12 @@ public:
|
||||
*/
|
||||
const char* ConstructJSONResponse(std::ostream& stream, const std::string& thread);
|
||||
|
||||
/**
|
||||
* Call in any thread to save a JSONP representation of the buffers
|
||||
* for all threads, to a file named profile2.jsonp in the logs directory.
|
||||
*/
|
||||
void SaveToFile();
|
||||
|
||||
double GetTime()
|
||||
{
|
||||
return timer_Time();
|
||||
|
@ -203,8 +203,15 @@ void CReplayPlayer::Replay()
|
||||
}
|
||||
else if (type == "end")
|
||||
{
|
||||
game.GetSimulation2()->Update(turnLength, commands);
|
||||
commands.clear();
|
||||
{
|
||||
g_Profiler2.RecordFrameStart();
|
||||
PROFILE2("frame");
|
||||
g_Profiler2.IncrementFrameNumber();
|
||||
PROFILE2_ATTR("%d", g_Profiler2.GetFrameNumber());
|
||||
|
||||
game.GetSimulation2()->Update(turnLength, commands);
|
||||
commands.clear();
|
||||
}
|
||||
|
||||
// std::string hash;
|
||||
// bool ok = game.GetSimulation2()->ComputeStateHash(hash, true);
|
||||
@ -227,6 +234,8 @@ void CReplayPlayer::Replay()
|
||||
}
|
||||
}
|
||||
|
||||
g_Profiler2.SaveToFile();
|
||||
|
||||
std::string hash;
|
||||
bool ok = game.GetSimulation2()->ComputeStateHash(hash, false);
|
||||
ENSURE(ok);
|
||||
|
@ -384,28 +384,28 @@ JSBool deepcopy(JSContext* cx, uintN argc, jsval* vp)
|
||||
|
||||
JSBool ProfileStart(JSContext* cx, uintN argc, jsval* vp)
|
||||
{
|
||||
if (CProfileManager::IsInitialised() && ThreadUtil::IsMainThread())
|
||||
const char* name = "(ProfileStart)";
|
||||
|
||||
if (argc >= 1)
|
||||
{
|
||||
const char* name = "(ProfileStart)";
|
||||
std::string str;
|
||||
if (!ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[0], str))
|
||||
return JS_FALSE;
|
||||
|
||||
if (argc >= 1)
|
||||
{
|
||||
std::string str;
|
||||
if (!ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[0], str))
|
||||
return JS_FALSE;
|
||||
typedef boost::flyweight<
|
||||
std::string,
|
||||
boost::flyweights::no_tracking,
|
||||
boost::flyweights::no_locking
|
||||
> StringFlyweight;
|
||||
|
||||
typedef boost::flyweight<
|
||||
std::string,
|
||||
boost::flyweights::no_tracking,
|
||||
boost::flyweights::no_locking
|
||||
> StringFlyweight;
|
||||
|
||||
name = StringFlyweight(str).get().c_str();
|
||||
}
|
||||
|
||||
g_Profiler.StartScript(name);
|
||||
name = StringFlyweight(str).get().c_str();
|
||||
}
|
||||
|
||||
if (CProfileManager::IsInitialised() && ThreadUtil::IsMainThread())
|
||||
g_Profiler.StartScript(name);
|
||||
|
||||
g_Profiler2.RecordRegionEnter(name);
|
||||
|
||||
JS_SET_RVAL(cx, vp, JSVAL_VOID);
|
||||
return JS_TRUE;
|
||||
}
|
||||
@ -413,9 +413,9 @@ JSBool ProfileStart(JSContext* cx, uintN argc, jsval* vp)
|
||||
JSBool ProfileStop(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* vp)
|
||||
{
|
||||
if (CProfileManager::IsInitialised() && ThreadUtil::IsMainThread())
|
||||
{
|
||||
g_Profiler.Stop();
|
||||
}
|
||||
|
||||
g_Profiler2.RecordRegionLeave("(ProfileStop)");
|
||||
|
||||
JS_SET_RVAL(cx, vp, JSVAL_VOID);
|
||||
return JS_TRUE;
|
||||
|
@ -52,6 +52,40 @@ var g_used_colours = {};
|
||||
var g_data;
|
||||
|
||||
function refresh()
|
||||
{
|
||||
if (1)
|
||||
refresh_live();
|
||||
else
|
||||
refresh_jsonp('../../../binaries/system/profile2.jsonp');
|
||||
}
|
||||
|
||||
function refresh_jsonp(url)
|
||||
{
|
||||
var script = document.createElement('script');
|
||||
|
||||
window.profileDataCB = function(data)
|
||||
{
|
||||
script.parentNode.removeChild(script);
|
||||
|
||||
var threads = [];
|
||||
data.threads.forEach(function(thread) {
|
||||
var canvas = $('<canvas width="1600" height="160"></canvas>');
|
||||
thread.data.events.pop();
|
||||
threads.push({'name': thread.name, 'data': thread.data, 'canvas': canvas.get(0)});
|
||||
});
|
||||
g_data = { 'threads': threads };
|
||||
|
||||
var range = {'seconds': 0.05};
|
||||
|
||||
rebuild_canvases();
|
||||
update_display(range);
|
||||
};
|
||||
|
||||
script.src = url;
|
||||
document.body.appendChild(script);
|
||||
}
|
||||
|
||||
function refresh_live()
|
||||
{
|
||||
$.ajax({
|
||||
url: 'http://127.0.0.1:8000/overview',
|
||||
@ -59,7 +93,7 @@ function refresh()
|
||||
success: function (data) {
|
||||
var threads = [];
|
||||
data.threads.forEach(function(thread) {
|
||||
var canvas = $('<canvas width="1600" height="128"></canvas>');
|
||||
var canvas = $('<canvas width="1600" height="160"></canvas>');
|
||||
threads.push({'name': thread.name, 'canvas': canvas.get(0)});
|
||||
});
|
||||
var callback_data = { 'threads': threads, 'completed': 0 };
|
||||
@ -93,7 +127,7 @@ function refresh_thread(thread, callback_data)
|
||||
|
||||
rebuild_canvases();
|
||||
update_display(range);
|
||||
}
|
||||
}
|
||||
},
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
alert('Failed to connect to server ("'+textStatus+'")');
|
||||
@ -349,7 +383,7 @@ function compute_intervals(data, range)
|
||||
continue;
|
||||
var interval = stack.pop();
|
||||
|
||||
if (data[i][2] != interval.id)
|
||||
if (data[i][2] != interval.id && data[i][2] != '(ProfileStop)')
|
||||
alert('inconsistent interval ids ('+interval.id+' / '+data[i][2]+')');
|
||||
|
||||
if (!g_used_colours[interval.id])
|
||||
@ -411,6 +445,23 @@ function display_frames(data, canvas)
|
||||
}
|
||||
};
|
||||
|
||||
// var y_per_second = 1000;
|
||||
var y_per_second = 100;
|
||||
|
||||
[16, 33, 200, 500].forEach(function(t) {
|
||||
var y1 = canvas.height;
|
||||
var y0 = y1 - t/1000*y_per_second;
|
||||
var y = Math.floor(y0) + 0.5;
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(xpadding, y);
|
||||
ctx.lineTo(canvas.width - xpadding, y);
|
||||
ctx.strokeStyle = 'rgb(255, 0, 0)';
|
||||
ctx.stroke();
|
||||
ctx.fillStyle = 'rgb(255, 0, 0)';
|
||||
ctx.fillText(t+'ms', 0, y-2);
|
||||
});
|
||||
|
||||
ctx.strokeStyle = 'rgb(0, 0, 0)';
|
||||
ctx.fillStyle = 'rgb(255, 255, 255)';
|
||||
for (var i = 0; i < data.frames.length; ++i)
|
||||
@ -421,7 +472,7 @@ function display_frames(data, canvas)
|
||||
var x0 = xpadding + dx*(frame.t0 - tmin);
|
||||
var x1 = x0 + dx*duration;
|
||||
var y1 = canvas.height;
|
||||
var y0 = y1 - duration*1000;
|
||||
var y0 = y1 - duration*y_per_second;
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.rect(x0, y0, x1-x0, y1-y0);
|
||||
@ -662,7 +713,8 @@ function set_frames_zoom_handlers(canvas0)
|
||||
var relativeX = event.pageX - this.offsetLeft;
|
||||
var relativeY = event.pageY - this.offsetTop;
|
||||
|
||||
var width = 0.001 + 0.5 * relativeY / canvas0.height;
|
||||
// var width = 0.001 + 0.5 * relativeY / canvas0.height;
|
||||
var width = 0.001 + 5 * relativeY / canvas0.height;
|
||||
|
||||
var tavg = zdata.x_to_t(relativeX);
|
||||
var tmax = tavg + width/2;
|
||||
|
Loading…
Reference in New Issue
Block a user