From cc9de398cf5232e547e9131d72782732a552fc56 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 17 Aug 2013 20:32:58 +0100 Subject: [PATCH] overlay: Graph per-process requests over time Signed-off-by: Chris Wilson --- overlay/chart.c | 26 ++++++++++++++++++- overlay/chart.h | 9 +++++-- overlay/gpu-perf.h | 1 + overlay/overlay.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 102 insertions(+), 7 deletions(-) diff --git a/overlay/chart.c b/overlay/chart.c index f98ba91..185eaf0 100644 --- a/overlay/chart.c +++ b/overlay/chart.c @@ -17,6 +17,7 @@ int chart_init(struct chart *chart, const char *name, int num_samples) chart->num_samples = num_samples; chart->range_automatic = 1; + chart->stroke_width = 2; return 0; } @@ -25,6 +26,11 @@ void chart_set_mode(struct chart *chart, enum chart_mode mode) chart->mode = mode; } +void chart_set_stroke_width(struct chart *chart, float width) +{ + chart->stroke_width = width; +} + void chart_set_stroke_rgba(struct chart *chart, float red, float green, float blue, float alpha) { chart->stroke_rgb[0] = red; @@ -60,6 +66,19 @@ void chart_set_range(struct chart *chart, double min, double max) chart->range_automatic = 0; } +void chart_get_range(struct chart *chart, double *range) +{ + int n, max = chart->current_sample; + if (max > chart->num_samples) + max = chart->num_samples; + for (n = 0; n < max; n++) { + if (chart->samples[n] < range[0]) + range[0] = chart->samples[n]; + else if (chart->samples[n] > range[1]) + range[1] = chart->samples[n]; + } +} + void chart_add_sample(struct chart *chart, double value) { int pos; @@ -144,7 +163,7 @@ void chart_draw(struct chart *chart, cairo_t *cr) cairo_line_to(cr, max, 0); cairo_identity_matrix(cr); - cairo_set_line_width(cr, 2); + cairo_set_line_width(cr, chart->stroke_width); switch (chart->mode) { case CHART_STROKE: cairo_set_source_rgba(cr, chart->stroke_rgb[0], chart->stroke_rgb[1], chart->stroke_rgb[2], chart->stroke_rgb[3]); @@ -165,3 +184,8 @@ void chart_draw(struct chart *chart, cairo_t *cr) } cairo_restore(cr); } + +void chart_fini(struct chart *chart) +{ + free(chart->samples); +} diff --git a/overlay/chart.h b/overlay/chart.h index 72e19af..9ede8de 100644 --- a/overlay/chart.h +++ b/overlay/chart.h @@ -4,13 +4,14 @@ struct chart { int num_samples; int current_sample; int range_automatic; - float fill_rgb[4]; - float stroke_rgb[4]; enum chart_mode { CHART_STROKE = 0, CHART_FILL, CHART_FILL_STROKE, } mode; + float fill_rgb[4]; + float stroke_rgb[4]; + double stroke_width; double range[2]; double *samples; }; @@ -18,9 +19,13 @@ struct chart { int chart_init(struct chart *chart, const char *name, int num_samples); void chart_set_mode(struct chart *chart, enum chart_mode mode); void chart_set_fill_rgba(struct chart *chart, float red, float green, float blue, float alpha); +void chart_set_stroke_width(struct chart *chart, float width); void chart_set_stroke_rgba(struct chart *chart, float red, float green, float blue, float alpha); void chart_set_position(struct chart *chart, int x, int y); void chart_set_size(struct chart *chart, int w, int h); void chart_set_range(struct chart *chart, double min, double max); void chart_add_sample(struct chart *chart, double value); void chart_draw(struct chart *chart, cairo_t *cr); +void chart_fini(struct chart *chart); + +void chart_get_range(struct chart *chart, double *range); diff --git a/overlay/gpu-perf.h b/overlay/gpu-perf.h index 95debc9..557e501 100644 --- a/overlay/gpu-perf.h +++ b/overlay/gpu-perf.h @@ -17,6 +17,7 @@ struct gpu_perf { char name[256]; pid_t pid; int nr_requests[4]; + void *user_data; } *comm; }; diff --git a/overlay/overlay.c b/overlay/overlay.c index 0bd5792..6297e5e 100644 --- a/overlay/overlay.c +++ b/overlay/overlay.c @@ -67,9 +67,9 @@ static void init_gpu_top(struct overlay_gpu_top *gt, cairo_surface_t *surface) { const double rgba[][4] = { - { 1, 0, 0, 1 }, - { 0, 1, 0, 1 }, - { 0, 0, 1, 1 }, + { 1, 0.25, 0.25, 1 }, + { 0.25, 1, 0.25, 1 }, + { 0.25, 0.25, 1, 1 }, { 1, 1, 1, 1 }, }; int n; @@ -127,6 +127,7 @@ static void show_gpu_top(struct overlay_context *ctx, struct overlay_gpu_top *gt y = 12; for (n = 0; n < gt->gpu_top.num_rings; n++) { + struct chart *c =>->busy[n]; char txt[160]; int len; @@ -140,6 +141,11 @@ static void show_gpu_top(struct overlay_context *ctx, struct overlay_gpu_top *gt len += sprintf(txt + len, ", %d%% sema", gt->gpu_top.ring[n].u.u.sema); + cairo_set_source_rgba(ctx->cr, + c->stroke_rgb[0], + c->stroke_rgb[1], + c->stroke_rgb[2], + c->stroke_rgb[3]); cairo_move_to(ctx->cr, 12, y); cairo_show_text(ctx->cr, txt); y += 14; @@ -179,12 +185,20 @@ static char *get_comm(pid_t pid, char *comm, int len) static void show_gpu_perf(struct overlay_context *ctx, struct overlay_gpu_perf *gp) { + static int last_color; + const double rgba[][4] = { + { 1, 0.25, 0.25, 1 }, + { 0.25, 1, 0.25, 1 }, + { 0.25, 0.25, 1, 1 }, + { 1, 1, 1, 1 }, + }; struct gpu_perf_comm *comm, **prev; const char *ring_name[] = { "render", "video", "blt", }; + double range[2]; char buf[1024]; int y, n; @@ -192,7 +206,53 @@ static void show_gpu_perf(struct overlay_context *ctx, struct overlay_gpu_perf * y = ctx->last_y + 18; + for (comm = gp->gpu_perf.comm; comm; comm = comm->next) { + int total; + + if (comm->user_data == NULL) { + comm->user_data = malloc(sizeof(struct chart)); + if (comm->user_data == NULL) + continue; + + chart_init(comm->user_data, comm->name, 120); + chart_set_position(comm->user_data, 12, y); + chart_set_size(comm->user_data, + cairo_image_surface_get_width(cairo_get_target(ctx->cr))-24, + 100); + chart_set_mode(comm->user_data, CHART_STROKE); + chart_set_stroke_rgba(comm->user_data, + rgba[last_color][0], + rgba[last_color][1], + rgba[last_color][2], + rgba[last_color][3]); + last_color++; + chart_set_stroke_width(comm->user_data, 1); + } + + total = 0; + for (n = 0; n < 3; n++) + total += comm->nr_requests[n]; + chart_add_sample(comm->user_data, total); + } + + range[0] = range[1] = 0; + for (comm = gp->gpu_perf.comm; comm; comm = comm->next) + chart_get_range(comm->user_data, range); + for (comm = gp->gpu_perf.comm; comm; comm = comm->next) { + chart_set_range(comm->user_data, range[0], range[1]); + chart_draw(comm->user_data, ctx->cr); + } + for (prev = &gp->gpu_perf.comm; (comm = *prev) != NULL; ) { + if (comm->user_data) { + struct chart *c = comm->user_data; + cairo_set_source_rgba(ctx->cr, + c->stroke_rgb[0], + c->stroke_rgb[1], + c->stroke_rgb[2], + c->stroke_rgb[3]); + } else + cairo_set_source_rgba(ctx->cr, 1, 1, 1, 1); cairo_move_to(ctx->cr, 12, y); sprintf(buf, "%s:", comm->name); cairo_show_text(ctx->cr, buf); @@ -207,6 +267,10 @@ static void show_gpu_perf(struct overlay_context *ctx, struct overlay_gpu_perf * memset(comm->nr_requests, 0, sizeof(comm->nr_requests)); if (strcmp(comm->name, get_comm(comm->pid, buf, sizeof(buf)))) { *prev = comm->next; + if (comm->user_data) { + chart_fini(comm->user_data); + free(comm->user_data); + } free(comm); } else prev = &comm->next; @@ -214,11 +278,12 @@ static void show_gpu_perf(struct overlay_context *ctx, struct overlay_gpu_perf * sprintf(buf, "Flips: %d", gp->gpu_perf.flip_complete); gp->gpu_perf.flip_complete = 0; + cairo_set_source_rgba(ctx->cr, 1, 1, 1, 1); cairo_move_to(ctx->cr, 12, y); cairo_show_text(ctx->cr, buf); y += 14; - ctx->last_y = y; + ctx->last_y += 118; } static void show_gem_objects(struct overlay_context *ctx) -- 2.7.4