overlay: Graph per-process requests over time
authorChris Wilson <chris@chris-wilson.co.uk>
Sat, 17 Aug 2013 19:32:58 +0000 (20:32 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Sat, 17 Aug 2013 19:32:58 +0000 (20:32 +0100)
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
overlay/chart.c
overlay/chart.h
overlay/gpu-perf.h
overlay/overlay.c

index f98ba91..185eaf0 100644 (file)
@@ -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);
+}
index 72e19af..9ede8de 100644 (file)
@@ -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);
index 95debc9..557e501 100644 (file)
@@ -17,6 +17,7 @@ struct gpu_perf {
                char name[256];
                pid_t pid;
                int nr_requests[4];
+               void *user_data;
        } *comm;
 };
 
index 0bd5792..6297e5e 100644 (file)
@@ -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 =&gt->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)