mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-27 07:03:36 -04:00
pstats: optimize method that searches for frame at given time
This method is called a lot in the strip chart code and the current implementation can be very slow with a large frame rate
This commit is contained in:
parent
9fd9e2868e
commit
07902429b8
@ -136,10 +136,11 @@ get_frame_at_time(double time) const {
|
||||
|
||||
/**
|
||||
* Returns the frame number of the latest frame not later than the indicated
|
||||
* time.
|
||||
* time. If no frames were found, returns get_oldest_frame_number() - 1.
|
||||
*
|
||||
* If the hint is nonnegative, it represents a frame number that we believe
|
||||
* the correct answer to be near, which may speed the search for the frame.
|
||||
* If the hint is nonnegative, it represents a frame number (for which
|
||||
* has_frame() must return true) we believe the correct answer to be after and
|
||||
* close by, which may speed the search for the frame.
|
||||
*/
|
||||
int PStatThreadData::
|
||||
get_frame_number_at_time(double time, int hint) const {
|
||||
@ -161,18 +162,66 @@ get_frame_number_at_time(double time, int hint) const {
|
||||
}
|
||||
}
|
||||
|
||||
// The hint is totally wrong. Start from the end and work backwards.
|
||||
|
||||
int i = _frames.size() - 1;
|
||||
while (i >= 0) {
|
||||
const PStatFrameData *frame = _frames[i];
|
||||
if (frame != nullptr && frame->get_start() <= time) {
|
||||
break;
|
||||
}
|
||||
--i;
|
||||
// The hint is wrong, we have to search the entire set.
|
||||
int first_i = 0;
|
||||
int last_i = _frames.size() - 1;
|
||||
while (first_i < last_i && _frames[first_i] == nullptr) {
|
||||
++first_i;
|
||||
}
|
||||
while (first_i < last_i && _frames[last_i] == nullptr) {
|
||||
--last_i;
|
||||
}
|
||||
|
||||
return _first_frame_number + i;
|
||||
if (first_i >= last_i) {
|
||||
// There are no frames.
|
||||
return _first_frame_number - 1;
|
||||
}
|
||||
|
||||
// Take a guess by interpolating based on the first and last frame times.
|
||||
double first = _frames[first_i]->get_start();
|
||||
if (time < first) {
|
||||
return _first_frame_number - 1;
|
||||
}
|
||||
|
||||
double last = _frames[last_i]->get_start();
|
||||
double t = (time - first) / (last - first);
|
||||
hint = std::max(0, (int)(t * (last_i - first_i))) + first_i;
|
||||
|
||||
// Find a frame around the guess that has data.
|
||||
if (_frames[hint] == nullptr) {
|
||||
if (hint <= first_i) {
|
||||
hint = first_i;
|
||||
}
|
||||
else do {
|
||||
// Skip backward until we find a frame with data.
|
||||
--hint;
|
||||
} while (_frames[hint] == nullptr);
|
||||
}
|
||||
|
||||
if (_frames[hint]->get_start() <= time) {
|
||||
// Search forward.
|
||||
for (int i = hint + 1; i < (int)_frames.size(); ++i) {
|
||||
const PStatFrameData *frame = _frames[i];
|
||||
if (frame != nullptr) {
|
||||
if (frame->get_start() <= time) {
|
||||
hint = i;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return _first_frame_number + hint;
|
||||
}
|
||||
|
||||
// Search backward.
|
||||
for (int i = hint - 1; i >= 0; --i) {
|
||||
const PStatFrameData *frame = _frames[i];
|
||||
if (frame != nullptr && frame->get_start() <= time) {
|
||||
return _first_frame_number + i;
|
||||
}
|
||||
}
|
||||
|
||||
return _first_frame_number - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user