00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pStatStripChart.h"
00020 #include "pStatClientData.h"
00021 #include "pStatMonitor.h"
00022
00023 #include <pStatFrameData.h>
00024 #include <pStatCollectorDef.h>
00025 #include <string_utils.h>
00026 #include <config_pstats.h>
00027
00028 #include <algorithm>
00029
00030
00031
00032
00033
00034
00035 PStatStripChart::
00036 PStatStripChart(PStatMonitor *monitor, PStatView &view,
00037 int collector_index, int xsize, int ysize) :
00038 PStatGraph(monitor, xsize, ysize),
00039 _view(view),
00040 _collector_index(collector_index)
00041 {
00042 _scroll_mode = pstats_scroll_mode;
00043
00044 _next_frame = 0;
00045 _first_data = true;
00046 _cursor_pixel = 0;
00047
00048 _time_width = 20.0;
00049 _value_height = 1.0/10.0;
00050 _start_time = 0.0;
00051
00052 _level_index = 0;
00053
00054 const PStatClientData *client_data = _monitor->get_client_data();
00055 if (client_data->has_collector(_collector_index)) {
00056 const PStatCollectorDef &def = client_data->get_collector_def(_collector_index);
00057 _unit_name = def._level_units;
00058 if (!_unit_name.empty()) {
00059 _guide_bar_units = GBU_named;
00060 }
00061 }
00062
00063 set_default_vertical_scale();
00064 }
00065
00066
00067
00068
00069
00070
00071 PStatStripChart::
00072 ~PStatStripChart() {
00073 }
00074
00075
00076
00077
00078
00079
00080 void PStatStripChart::
00081 new_data(int frame_number) {
00082
00083
00084
00085 _next_frame = min(frame_number, _next_frame);
00086 }
00087
00088
00089
00090
00091
00092
00093 void PStatStripChart::
00094 update() {
00095 const PStatClientData *client_data = get_monitor()->get_client_data();
00096
00097
00098
00099 if (client_data->get_num_collectors() != 0 &&
00100 client_data->get_num_threads() != 0) {
00101 const PStatThreadData *thread_data = _view.get_thread_data();
00102 if (!thread_data->is_empty()) {
00103 int latest = thread_data->get_latest_frame_number();
00104
00105 if (latest > _next_frame) {
00106 draw_frames(_next_frame, latest);
00107 }
00108 _next_frame = latest;
00109
00110
00111 float oldest_time =
00112 thread_data->get_frame(latest).get_start() - _time_width;
00113
00114 Data::iterator di;
00115 di = _data.begin();
00116 while (di != _data.end() &&
00117 thread_data->get_frame((*di).first).get_start() < oldest_time) {
00118 _data.erase(di);
00119 di = _data.begin();
00120 }
00121 }
00122 }
00123
00124 if (_level_index != _view.get_level_index()) {
00125 update_labels();
00126 }
00127
00128 idle();
00129 }
00130
00131
00132
00133
00134
00135
00136
00137 bool PStatStripChart::
00138 first_data() const {
00139 return _first_data;
00140 }
00141
00142
00143
00144
00145
00146
00147
00148
00149 void PStatStripChart::
00150 set_default_vertical_scale() {
00151 const PStatClientData *client_data = _monitor->get_client_data();
00152 if (client_data->has_collector(_collector_index)) {
00153 const PStatCollectorDef &def =
00154 client_data->get_collector_def(_collector_index);
00155 if (def._suggested_scale != 0.0) {
00156 set_vertical_scale(def._suggested_scale);
00157 return;
00158 }
00159 }
00160
00161 set_vertical_scale(2.0 / get_target_frame_rate());
00162 }
00163
00164
00165
00166
00167
00168
00169 void PStatStripChart::
00170 set_auto_vertical_scale() {
00171 const PStatThreadData *thread_data = _view.get_thread_data();
00172
00173 float max_value = 0.0;
00174
00175 int frame_number = -1;
00176 for (int x = 0; x <= _xsize; x++) {
00177 float time = pixel_to_timestamp(x);
00178 frame_number =
00179 thread_data->get_frame_number_at_time(time, frame_number);
00180
00181 if (thread_data->has_frame(frame_number)) {
00182 const FrameData &frame = get_frame_data(frame_number);
00183
00184 float overall_value = 0.0;
00185 FrameData::const_iterator fi;
00186 for (fi = frame.begin(); fi != frame.end(); ++fi) {
00187 const ColorData &cd = (*fi);
00188 overall_value += cd._net_value;
00189 }
00190 max_value = max(max_value, overall_value);
00191 }
00192 }
00193
00194
00195
00196 if (max_value == 0.0) {
00197 set_vertical_scale(1.0);
00198 } else {
00199 set_vertical_scale(max_value * 1.1);
00200 }
00201 }
00202
00203
00204
00205
00206
00207
00208
00209
00210 int PStatStripChart::
00211 get_collector_under_pixel(int xpoint, int ypoint) {
00212
00213
00214 float time = pixel_to_timestamp(xpoint);
00215
00216
00217 const PStatThreadData *thread_data = _view.get_thread_data();
00218 int frame_number = thread_data->get_frame_number_at_time(time);
00219
00220
00221
00222 const FrameData &frame = get_frame_data(frame_number);
00223 float overall_value = 0.0;
00224 int y = get_ysize();
00225
00226 FrameData::const_iterator fi;
00227 for (fi = frame.begin(); fi != frame.end(); ++fi) {
00228 const ColorData &cd = (*fi);
00229 overall_value += cd._net_value;
00230 y = height_to_pixel(overall_value);
00231 if (y <= ypoint) {
00232 return cd._collector_index;
00233 }
00234 }
00235
00236 return -1;
00237 }
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 const PStatStripChart::FrameData &PStatStripChart::
00248 get_frame_data(int frame_number) {
00249 Data::const_iterator di;
00250 di = _data.find(frame_number);
00251 if (di != _data.end()) {
00252 return (*di).second;
00253 }
00254
00255 const PStatThreadData *thread_data = _view.get_thread_data();
00256 _view.set_to_frame(thread_data->get_frame(frame_number));
00257
00258 FrameData &data = _data[frame_number];
00259
00260 const PStatViewLevel *level = _view.get_level(_collector_index);
00261 int num_children = level->get_num_children();
00262 for (int i = 0; i < num_children; i++) {
00263 const PStatViewLevel *child = level->get_child(i);
00264 ColorData cd;
00265 cd._collector_index = child->get_collector();
00266 cd._net_value = child->get_net_value();
00267 if (cd._net_value != 0.0) {
00268 data.push_back(cd);
00269 }
00270 }
00271
00272
00273
00274 ColorData cd;
00275 cd._collector_index = level->get_collector();
00276 cd._net_value = level->get_value_alone();
00277 if (cd._net_value != 0.0) {
00278 data.push_back(cd);
00279 }
00280
00281 return data;
00282 }
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292 void PStatStripChart::
00293 changed_size(int xsize, int ysize) {
00294 if (xsize != _xsize || ysize != _ysize) {
00295 _cursor_pixel = xsize * _cursor_pixel / _xsize;
00296 _xsize = xsize;
00297 _ysize = ysize;
00298
00299 if (!_first_data) {
00300 if (_scroll_mode) {
00301 draw_pixels(0, _xsize);
00302
00303 } else {
00304
00305 float old_start_time = _start_time;
00306
00307
00308 _start_time -= _time_width;
00309 draw_pixels(_cursor_pixel, _xsize);
00310
00311
00312 _start_time = old_start_time;
00313 draw_pixels(0, _cursor_pixel);
00314 }
00315 }
00316 }
00317 }
00318
00319
00320
00321
00322
00323
00324
00325 void PStatStripChart::
00326 force_redraw() {
00327 if (!_first_data) {
00328 draw_pixels(0, _xsize);
00329 }
00330 }
00331
00332
00333
00334
00335
00336
00337
00338 void PStatStripChart::
00339 force_reset() {
00340 clear_region();
00341 _first_data = true;
00342 }
00343
00344
00345
00346
00347
00348
00349
00350
00351 void PStatStripChart::
00352 clear_region() {
00353 }
00354
00355
00356
00357
00358
00359
00360
00361
00362 void PStatStripChart::
00363 copy_region(int, int, int) {
00364 }
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374 void PStatStripChart::
00375 begin_draw(int, int) {
00376 }
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389 void PStatStripChart::
00390 draw_slice(int, int) {
00391 }
00392
00393
00394
00395
00396
00397
00398
00399
00400 void PStatStripChart::
00401 draw_empty(int) {
00402 }
00403
00404
00405
00406
00407
00408
00409
00410
00411 void PStatStripChart::
00412 draw_cursor(int) {
00413 }
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423 void PStatStripChart::
00424 end_draw(int, int) {
00425 }
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436 void PStatStripChart::
00437 idle() {
00438 }
00439
00440
00441
00442
00443 class SortCollectorLabels2 {
00444 public:
00445 SortCollectorLabels2(const PStatClientData *client_data) :
00446 _client_data(client_data) {
00447 }
00448 bool operator () (int a, int b) const {
00449 return
00450 _client_data->get_collector_def(a)._sort >
00451 _client_data->get_collector_def(b)._sort;
00452 }
00453 const PStatClientData *_client_data;
00454 };
00455
00456
00457
00458
00459
00460
00461 void PStatStripChart::
00462 update_labels() {
00463 const PStatViewLevel *level = _view.get_level(_collector_index);
00464 _labels.clear();
00465
00466 int num_children = level->get_num_children();
00467 for (int i = 0; i < num_children; i++) {
00468 const PStatViewLevel *child = level->get_child(i);
00469 int collector = child->get_collector();
00470 _labels.push_back(collector);
00471 }
00472
00473 SortCollectorLabels2 sort_labels(get_monitor()->get_client_data());
00474 sort(_labels.begin(), _labels.end(), sort_labels);
00475
00476 int collector = level->get_collector();
00477 _labels.push_back(collector);
00478
00479 _labels_changed = true;
00480 _level_index = _view.get_level_index();
00481 }
00482
00483
00484
00485
00486
00487
00488
00489 void PStatStripChart::
00490 normal_guide_bars() {
00491 update_guide_bars(4, _value_height);
00492 }
00493
00494
00495
00496
00497
00498
00499
00500 void PStatStripChart::
00501 draw_frames(int first_frame, int last_frame) {
00502 const PStatThreadData *thread_data = _view.get_thread_data();
00503
00504 last_frame = min(last_frame, thread_data->get_latest_frame_number());
00505
00506 if (_first_data) {
00507 if (_scroll_mode) {
00508 _start_time =
00509 thread_data->get_frame(last_frame).get_start() - _time_width;
00510 } else {
00511 _start_time = thread_data->get_frame(first_frame).get_start();
00512 _cursor_pixel = 0;
00513 }
00514 }
00515
00516 int first_pixel;
00517 if (thread_data->has_frame(first_frame)) {
00518 first_pixel =
00519 timestamp_to_pixel(thread_data->get_frame(first_frame).get_start());
00520 } else {
00521 first_pixel = 0;
00522 }
00523
00524 int last_pixel =
00525 timestamp_to_pixel(thread_data->get_frame(last_frame).get_start());
00526
00527 if (_first_data && !_scroll_mode) {
00528 first_pixel = min(_cursor_pixel, first_pixel);
00529 }
00530 _first_data = false;
00531
00532 if (last_pixel - first_pixel >= _xsize) {
00533
00534
00535 _start_time = thread_data->get_frame(last_frame).get_start() - _time_width;
00536 first_pixel = 0;
00537 last_pixel = _xsize;
00538 }
00539
00540 if (last_pixel <= _xsize) {
00541
00542 _cursor_pixel = last_pixel;
00543 draw_pixels(first_pixel, last_pixel);
00544
00545 } else {
00546 if (_scroll_mode) {
00547
00548 int slide_pixels = last_pixel - _xsize;
00549 copy_region(slide_pixels, first_pixel, 0);
00550 first_pixel -= slide_pixels;
00551 last_pixel -= slide_pixels;
00552 _start_time += (float)slide_pixels / (float)_xsize * _time_width;
00553 draw_pixels(first_pixel, last_pixel);
00554
00555 } else {
00556
00557 _cursor_pixel = -1;
00558 draw_pixels(first_pixel, _xsize);
00559 _start_time = pixel_to_timestamp(_xsize);
00560 last_pixel -= _xsize;
00561 _cursor_pixel = last_pixel;
00562 draw_pixels(0, last_pixel);
00563 }
00564 }
00565 }
00566
00567
00568
00569
00570
00571
00572 void PStatStripChart::
00573 draw_pixels(int first_pixel, int last_pixel) {
00574 begin_draw(first_pixel, last_pixel);
00575 const PStatThreadData *thread_data = _view.get_thread_data();
00576
00577 int frame_number = -1;
00578 for (int x = first_pixel; x <= last_pixel; x++) {
00579 if (x == _cursor_pixel && !_scroll_mode) {
00580 draw_cursor(x);
00581
00582 } else {
00583 float time = pixel_to_timestamp(x);
00584 frame_number = thread_data->get_frame_number_at_time(time, frame_number);
00585
00586 if (thread_data->has_frame(frame_number)) {
00587 draw_slice(x, frame_number);
00588 } else {
00589 draw_empty(x);
00590 }
00591 }
00592 }
00593 end_draw(first_pixel, last_pixel);
00594 }