From f9a50de3dcc501e930de6c60983a4feb57121e7e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 17 Aug 2013 11:12:07 +0100 Subject: Introduce intel-gpu-overlay A realtime display of GPU activity. Note, this is just at the point of minimum usability... Signed-off-by: Chris Wilson --- overlay/chart.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 overlay/chart.c (limited to 'overlay/chart.c') diff --git a/overlay/chart.c b/overlay/chart.c new file mode 100644 index 00000000..89b3f414 --- /dev/null +++ b/overlay/chart.c @@ -0,0 +1,135 @@ +#include +#include +#include +#include + +#include + +#include "chart.h" + +int chart_init(struct chart *chart, const char *name, int num_samples) +{ + memset(chart, 0, sizeof(*chart)); + chart->name = name; + chart->samples = malloc(sizeof(*chart->samples)*num_samples); + if (chart->samples == NULL) + return ENOMEM; + + chart->num_samples = num_samples; + chart->range_automatic = 1; + return 0; +} + +void chart_set_rgba(struct chart *chart, float red, float green, float blue, float alpha) +{ + chart->rgb[0] = red; + chart->rgb[1] = green; + chart->rgb[2] = blue; + chart->rgb[3] = alpha; +} + +void chart_set_position(struct chart *chart, int x, int y) +{ + chart->x = x; + chart->y = y; +} + +void chart_set_size(struct chart *chart, int w, int h) +{ + chart->w = w; + chart->h = h; +} + +void chart_set_range(struct chart *chart, double min, double max) +{ + chart->range[0] = min; + chart->range[1] = max; + chart->range_automatic = 0; +} + +void chart_add_sample(struct chart *chart, double value) +{ + int pos; + + pos = chart->current_sample % chart->num_samples; + chart->samples[pos] = value; + chart->current_sample++; +} + +static void chart_update_range(struct chart *chart) +{ + int n, max = chart->current_sample; + if (max > chart->num_samples) + max = chart->num_samples; + chart->range[0] = chart->range[1] = chart->samples[0]; + for (n = 1; n < max; n++) { + if (chart->samples[n] < chart->range[0]) + chart->range[0] = chart->samples[n]; + else if (chart->samples[n] > chart->range[1]) + chart->range[1] = chart->samples[n]; + } +} + +static double value_at(struct chart *chart, int n) +{ + if (n <= chart->current_sample - chart->num_samples) + n = chart->current_sample; + else if (n >= chart->current_sample) + n = chart->current_sample - 1; + + return chart->samples[n % chart->num_samples]; +} + +static double gradient_at(struct chart *chart, int n) +{ + double y0, y1; + + y0 = value_at(chart, n-1); + y1 = value_at(chart, n+1); + + return (y1 - y0) / 2.; +} + +void chart_draw(struct chart *chart, cairo_t *cr) +{ + int i, n, max, x; + + if (chart->current_sample == 0) + return; + + if (chart->range_automatic) + chart_update_range(chart); + + cairo_save(cr); + + cairo_translate(cr, chart->x, chart->y + chart->h); + cairo_scale(cr, + chart->w / (double)chart->num_samples, + -chart->h / (chart->range[1] - chart->range[0])); + + x = 0; + max = chart->current_sample; + if (max >= chart->num_samples) { + max = chart->num_samples; + i = chart->current_sample - max; + } else { + i = 0; + x = chart->num_samples - max; + } + cairo_translate(cr, x, -chart->range[0]); + + cairo_new_path(cr); + for (n = 0; n < max; n++) { + cairo_curve_to(cr, + n-2/3., value_at(chart, i + n -1) + gradient_at(chart, i + n - 1)/3., + n-1/3., value_at(chart, i + n) - gradient_at(chart, i + n)/3., + n, value_at(chart, i + n)); + } + + cairo_identity_matrix(cr); + cairo_set_line_width(cr, 1); + cairo_set_source_rgba(cr, chart->rgb[0], chart->rgb[1], chart->rgb[2], chart->rgb[3]); + cairo_stroke(cr); + + cairo_restore(cr); +} -- cgit v1.2.3