From 41201ed885f6ca7206d151a66407cf9f8da0ff85 Mon Sep 17 00:00:00 2001 From: David Rose Date: Wed, 14 Jan 2004 19:29:06 +0000 Subject: [PATCH] resolve discrepencies between overall frame rate and individual average collector rate --- pandatool/src/pstatserver/pStatStripChart.cxx | 39 ++++-- pandatool/src/pstatserver/pStatStripChart.h | 4 +- pandatool/src/pstatserver/pStatThreadData.cxx | 124 +++++++++++------- pandatool/src/pstatserver/pStatThreadData.h | 10 +- pandatool/src/pstatserver/pStatViewLevel.cxx | 4 +- 5 files changed, 118 insertions(+), 63 deletions(-) diff --git a/pandatool/src/pstatserver/pStatStripChart.cxx b/pandatool/src/pstatserver/pStatStripChart.cxx index 9dffc78572..57d8e4f46b 100644 --- a/pandatool/src/pstatserver/pStatStripChart.cxx +++ b/pandatool/src/pstatserver/pStatStripChart.cxx @@ -347,7 +347,7 @@ get_frame_data(int frame_number) { // Function: PStatStripChart::get_net_value // Access: Protected // Description: Returns the net value of the chart's collector for -// the indicated fraem number. +// the indicated frame number. //////////////////////////////////////////////////////////////////// float PStatStripChart:: get_net_value(int frame_number) const { @@ -368,22 +368,43 @@ get_net_value(int frame_number) const { // Function: PStatStripChart::get_average_net_value // Access: Protected // Description: Computes the average value of the chart's collector -// over the past indicated number of seconds. +// over the past pstats_average_time number of seconds. //////////////////////////////////////////////////////////////////// float PStatStripChart:: -get_average_net_value(float time) const { +get_average_net_value() const { const PStatThreadData *thread_data = _view.get_thread_data(); int now_i, then_i; - if (!thread_data->get_elapsed_frames(then_i, now_i, time)) { + if (!thread_data->get_elapsed_frames(then_i, now_i)) { return 0.0f; } - float net_value = 0.0f; - for (int frame_number = then_i; frame_number <= now_i; frame_number++) { - net_value += get_net_value(frame_number); - } int num_frames = now_i - then_i + 1; - return net_value / (float)num_frames; + + if (_collector_index == 0 && !_view.get_show_level()) { + // If we're showing the time for the whole frame, compute this + // from the total elapsed time, rather than summing up individual + // frames. This is more accurate and exactly matches what is + // reported by thread_data->get_frame_rate(). + + const PStatFrameData &now_frame_data = thread_data->get_frame(now_i); + const PStatFrameData &then_frame_data = thread_data->get_frame(then_i); + float now = now_frame_data.get_end(); + float elapsed_time = (now - then_frame_data.get_start()); + return elapsed_time / (float)num_frames; + + } else { + // On the other hand, if we're showing the time for some + // sub-frame, we have to do it the less-accurate way of summing up + // individual frames, which might introduce errors if we are + // missing data for some frames, but what can you do? + + float net_value = 0.0f; + for (int frame_number = then_i; frame_number <= now_i; frame_number++) { + net_value += get_net_value(frame_number); + } + + return net_value / (float)num_frames; + } } //////////////////////////////////////////////////////////////////// diff --git a/pandatool/src/pstatserver/pStatStripChart.h b/pandatool/src/pstatserver/pStatStripChart.h index d6c844c608..87ec25bcf9 100644 --- a/pandatool/src/pstatserver/pStatStripChart.h +++ b/pandatool/src/pstatserver/pStatStripChart.h @@ -26,7 +26,7 @@ #include "pStatClientData.h" #include "luse.h" -#include +#include "vector_int.h" #include "pmap.h" @@ -87,7 +87,7 @@ protected: const FrameData &get_frame_data(int frame_number); float get_net_value(int frame_number) const; - float get_average_net_value(float time = 3.0) const; + float get_average_net_value() const; void changed_size(int xsize, int ysize); void force_redraw(); diff --git a/pandatool/src/pstatserver/pStatThreadData.cxx b/pandatool/src/pstatserver/pStatThreadData.cxx index 22a5ae6e40..dba8d6c781 100644 --- a/pandatool/src/pstatserver/pStatThreadData.cxx +++ b/pandatool/src/pstatserver/pStatThreadData.cxx @@ -36,6 +36,7 @@ PStatThreadData(const PStatClientData *client_data) : { _first_frame_number = 0; _history = pstats_history; + _computed_elapsed_frames = false; } //////////////////////////////////////////////////////////////////// @@ -232,70 +233,41 @@ get_latest_frame() const { //////////////////////////////////////////////////////////////////// // Function: PStatThreadData::get_elapsed_frames // Access: Public -// Description: Computes the oldest frame number not older than time -// seconds, and the newest frame number. Handy for -// computing average frame rate over a time. Returns -// true if there is any data in that range, false -// otherwise. +// Description: Computes the oldest frame number not older than +// pstats_average_time seconds, and the newest frame +// number. Handy for computing average frame rate over +// a time. Returns true if there is any data in that +// range, false otherwise. //////////////////////////////////////////////////////////////////// bool PStatThreadData:: -get_elapsed_frames(int &then_i, int &now_i, float time) const { - if (_frames.empty()) { - // No frames in the data at all. - return false; +get_elapsed_frames(int &then_i, int &now_i) const { + if (!_computed_elapsed_frames) { + ((PStatThreadData *)this)->compute_elapsed_frames(); } - now_i = _frames.size() - 1; - while (now_i > 0 && _frames[now_i] == (PStatFrameData *)NULL) { - now_i--; - } - if (now_i < 0) { - // No frames have any real data. - return false; - } - nassertr(_frames[now_i] != (PStatFrameData *)NULL, false); - - float now = _frames[now_i]->get_end(); - float then = now - time; - - int old_i = now_i; - then_i = now_i; - - while (old_i >= 0) { - const PStatFrameData *frame = _frames[old_i]; - if (frame != (PStatFrameData *)NULL) { - if (frame->get_start() > then) { - then_i = old_i; - } else { - break; - } - } - old_i--; - } - - nassertr(then_i >= 0, false); - nassertr(_frames[then_i] != (PStatFrameData *)NULL, false); - - return true; + now_i = _now_i; + then_i = _then_i; + return _got_elapsed_frames; } //////////////////////////////////////////////////////////////////// // Function: PStatThreadData::get_frame_rate // Access: Public -// Description: Computes the average frame rate over the past number -// of seconds, by counting up the number of frames -// elapsed in that time interval. +// Description: Computes the average frame rate over the past +// pstats_average_time seconds, by counting up the +// number of frames elapsed in that time interval. //////////////////////////////////////////////////////////////////// float PStatThreadData:: -get_frame_rate(float time) const { +get_frame_rate() const { int then_i, now_i; - if (!get_elapsed_frames(then_i, now_i, time)) { + if (!get_elapsed_frames(then_i, now_i)) { return 0.0f; } int num_frames = now_i - then_i + 1; - float now = _frames[now_i]->get_end(); - return (float)num_frames / (now - _frames[then_i]->get_start()); + float now = _frames[now_i - _first_frame_number]->get_end(); + float elapsed_time = (now - _frames[then_i - _first_frame_number]->get_start()); + return (float)num_frames / elapsed_time; } @@ -379,5 +351,61 @@ record_new_frame(int frame_number, PStatFrameData *frame_data) { } _frames[index] = frame_data; + _computed_elapsed_frames = false; } +//////////////////////////////////////////////////////////////////// +// Function: PStatThreadData::compute_elapsed_frames +// Access: Private +// Description: Computes the frame numbers returned by +// get_elapsed_frames(). This is non-const, but only +// updates cached values, so may safely be called from a +// const method. +//////////////////////////////////////////////////////////////////// +void PStatThreadData:: +compute_elapsed_frames() { + if (_frames.empty()) { + // No frames in the data at all. + _got_elapsed_frames = false; + + } else { + _now_i = _frames.size() - 1; + while (_now_i > 0 && _frames[_now_i] == (PStatFrameData *)NULL) { + _now_i--; + } + if (_now_i < 0) { + // No frames have any real data. + _got_elapsed_frames = false; + + } else { + nassertv(_frames[_now_i] != (PStatFrameData *)NULL); + + float now = _frames[_now_i]->get_end(); + float then = now - pstats_average_time; + + int old_i = _now_i; + _then_i = _now_i; + + while (old_i >= 0) { + const PStatFrameData *frame = _frames[old_i]; + if (frame != (PStatFrameData *)NULL) { + if (frame->get_start() > then) { + _then_i = old_i; + } else { + break; + } + } + old_i--; + } + + nassertv(_then_i >= 0); + nassertv(_frames[_then_i] != (PStatFrameData *)NULL); + _got_elapsed_frames = true; + + _now_i += _first_frame_number; + _then_i += _first_frame_number; + } + } + + _computed_elapsed_frames = true; +} diff --git a/pandatool/src/pstatserver/pStatThreadData.h b/pandatool/src/pstatserver/pStatThreadData.h index 756593be91..a8c6cc4efd 100644 --- a/pandatool/src/pstatserver/pStatThreadData.h +++ b/pandatool/src/pstatserver/pStatThreadData.h @@ -60,8 +60,8 @@ public: const PStatFrameData &get_latest_frame() const; - bool get_elapsed_frames(int &then_i, int &now_i, float time) const; - float get_frame_rate(float time = 3.0) const; + bool get_elapsed_frames(int &then_i, int &now_i) const; + float get_frame_rate() const; void set_history(float time); @@ -70,6 +70,7 @@ public: void record_new_frame(int frame_number, PStatFrameData *frame_data); private: + void compute_elapsed_frames(); const PStatClientData *_client_data; typedef pdeque Frames; @@ -77,6 +78,11 @@ private: int _first_frame_number; float _history; + bool _computed_elapsed_frames; + bool _got_elapsed_frames; + int _then_i; + int _now_i; + static PStatFrameData _null_frame; }; diff --git a/pandatool/src/pstatserver/pStatViewLevel.cxx b/pandatool/src/pstatserver/pStatViewLevel.cxx index 9687cc5752..5c45fd7063 100644 --- a/pandatool/src/pstatserver/pStatViewLevel.cxx +++ b/pandatool/src/pstatserver/pStatViewLevel.cxx @@ -19,8 +19,8 @@ #include "pStatViewLevel.h" #include "pStatClientData.h" -#include -#include +#include "pStatCollectorDef.h" +#include "notify.h" #include