[Mesa-dev] [PATCH 4/5] gallium/hud: add an option to sort items below graphs

Marek Olšák maraeo at gmail.com
Sun Jan 1 00:06:02 UTC 2017


From: Marek Olšák <marek.olsak at amd.com>

---
 src/gallium/auxiliary/hud/hud_context.c | 37 ++++++++++++++++++++++++++++-----
 src/gallium/auxiliary/hud/hud_private.h |  1 +
 2 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/src/gallium/auxiliary/hud/hud_context.c b/src/gallium/auxiliary/hud/hud_context.c
index eefbe60..6892289 100644
--- a/src/gallium/auxiliary/hud/hud_context.c
+++ b/src/gallium/auxiliary/hud/hud_context.c
@@ -476,21 +476,21 @@ void
 hud_draw(struct hud_context *hud, struct pipe_resource *tex)
 {
    struct cso_context *cso = hud->cso;
    struct pipe_context *pipe = hud->pipe;
    struct pipe_framebuffer_state fb;
    struct pipe_surface surf_templ, *surf;
    struct pipe_viewport_state viewport;
    const struct pipe_sampler_state *sampler_states[] =
          { &hud->font_sampler_state };
    struct hud_pane *pane;
-   struct hud_graph *gr;
+   struct hud_graph *gr, *next;
 
    if (!huds_visible)
       return;
 
    hud->fb_width = tex->width0;
    hud->fb_height = tex->height0;
    hud->constants.two_div_fb_width = 2.0f / hud->fb_width;
    hud->constants.two_div_fb_height = 2.0f / hud->fb_height;
 
    cso_save_state(cso, (CSO_BIT_FRAMEBUFFER |
@@ -569,20 +569,37 @@ hud_draw(struct hud_context *hud, struct pipe_resource *tex)
    hud_alloc_vertices(hud, &hud->text, 4 * 1024, 4 * sizeof(float));
 
    /* prepare all graphs */
    hud_batch_query_update(hud->batch_query);
 
    LIST_FOR_EACH_ENTRY(pane, &hud->pane_list, head) {
       LIST_FOR_EACH_ENTRY(gr, &pane->graph_list, head) {
          gr->query_new_value(gr);
       }
 
+      if (pane->sort_items) {
+         LIST_FOR_EACH_ENTRY_SAFE(gr, next, &pane->graph_list, head) {
+            /* ignore the last one */
+            if (&gr->head == pane->graph_list.prev)
+               continue;
+
+            /* This is an incremental bubble sort, because we only do one pass
+             * per frame. It will eventually reach an equilibrium.
+             */
+            if (gr->current_value <
+                LIST_ENTRY(struct hud_graph, next, head)->current_value) {
+               LIST_DEL(&gr->head);
+               LIST_ADD(&gr->head, &next->head);
+            }
+         }
+      }
+
       hud_pane_accumulate_vertices(hud, pane);
    }
 
    /* unmap the uploader's vertex buffer before drawing */
    u_upload_unmap(hud->uploader);
 
    /* draw accumulated vertices for background quads */
    cso_set_blend(cso, &hud->alpha_blend);
    cso_set_fragment_shader_handle(hud->cso, hud->fs_color);
 
@@ -754,21 +771,21 @@ hud_pane_update_dyn_ceiling(struct hud_graph *gr, struct hud_pane *pane)
    /*
     * Mark this adjustment run so we could avoid repeating a full update
     * again needlessly in case the pane has more than one graph.
     */
    pane->dyn_ceil_last_ran = gr->index;
 }
 
 static struct hud_pane *
 hud_pane_create(unsigned x1, unsigned y1, unsigned x2, unsigned y2,
                 unsigned period, uint64_t max_value, uint64_t ceiling,
-                boolean dyn_ceiling)
+                boolean dyn_ceiling, boolean sort_items)
 {
    struct hud_pane *pane = CALLOC_STRUCT(hud_pane);
 
    if (!pane)
       return NULL;
 
    pane->x1 = x1;
    pane->y1 = y1;
    pane->x2 = x2;
    pane->y2 = y2;
@@ -776,20 +793,21 @@ hud_pane_create(unsigned x1, unsigned y1, unsigned x2, unsigned y2,
    pane->inner_x2 = x2 - 1;
    pane->inner_y1 = y1 + 1;
    pane->inner_y2 = y2 - 1;
    pane->inner_width = pane->inner_x2 - pane->inner_x1;
    pane->inner_height = pane->inner_y2 - pane->inner_y1;
    pane->period = period;
    pane->max_num_vertices = (x2 - x1 + 2) / 2;
    pane->ceiling = ceiling;
    pane->dyn_ceiling = dyn_ceiling;
    pane->dyn_ceil_last_ran = 0;
+   pane->sort_items = sort_items;
    pane->initial_max_value = max_value;
    hud_pane_set_max_value(pane, max_value);
    LIST_INITHEAD(&pane->graph_list);
    return pane;
 }
 
 /* replace '-' with a space */
 static void
 strip_hyphens(char *s)
 {
@@ -918,21 +936,21 @@ parse_string(const char *s, char *out)
       fflush(stderr);
    }
 
    return i;
 }
 
 static char *
 read_pane_settings(char *str, unsigned * const x, unsigned * const y,
                unsigned * const width, unsigned * const height,
                uint64_t * const ceiling, boolean * const dyn_ceiling,
-               boolean *reset_colors)
+               boolean *reset_colors, boolean *sort_items)
 {
    char *ret = str;
    unsigned tmp;
 
    while (*str == '.') {
       ++str;
       switch (*str) {
       case 'x':
          ++str;
          *x = strtoul(str, &ret, 10);
@@ -975,20 +993,26 @@ read_pane_settings(char *str, unsigned * const x, unsigned * const y,
          ret = str;
          *dyn_ceiling = true;
          break;
 
       case 'r':
          ++str;
          ret = str;
          *reset_colors = true;
          break;
 
+      case 's':
+         ++str;
+         ret = str;
+         *sort_items = true;
+         break;
+
       default:
          fprintf(stderr, "gallium_hud: syntax error: unexpected '%c'\n", *str);
          fflush(stderr);
       }
 
    }
 
    return ret;
 }
 
@@ -1017,52 +1041,53 @@ hud_parse_env_var(struct hud_context *hud, const char *env)
    char name_a[256], s[256];
    char *name;
    struct hud_pane *pane = NULL;
    unsigned x = 10, y = 10;
    unsigned width = 251, height = 100;
    unsigned period = 500 * 1000;  /* default period (1/2 second) */
    uint64_t ceiling = UINT64_MAX;
    unsigned column_width = 251;
    boolean dyn_ceiling = false;
    boolean reset_colors = false;
+   boolean sort_items = false;
    const char *period_env;
 
    /*
     * The GALLIUM_HUD_PERIOD env var sets the graph update rate.
     * The env var is in seconds (a float).
     * Zero means update after every frame.
     */
    period_env = getenv("GALLIUM_HUD_PERIOD");
    if (period_env) {
       float p = (float) atof(period_env);
       if (p >= 0.0f) {
          period = (unsigned) (p * 1000 * 1000);
       }
    }
 
    while ((num = parse_string(env, name_a)) != 0) {
       env += num;
 
       /* check for explicit location, size and etc. settings */
       name = read_pane_settings(name_a, &x, &y, &width, &height, &ceiling,
-                         &dyn_ceiling, &reset_colors);
+                                &dyn_ceiling, &reset_colors, &sort_items);
 
      /*
       * Keep track of overall column width to avoid pane overlapping in case
       * later we create a new column while the bottom pane in the current
       * column is less wide than the rest of the panes in it.
       */
      column_width = width > column_width ? width : column_width;
 
       if (!pane) {
          pane = hud_pane_create(x, y, x + width, y + height, period, 10,
-                         ceiling, dyn_ceiling);
+                         ceiling, dyn_ceiling, sort_items);
          if (!pane)
             return;
       }
 
       if (reset_colors) {
          pane->next_color = 0;
          reset_colors = false;
       }
 
       /* Add a graph. */
@@ -1269,20 +1294,21 @@ hud_parse_env_var(struct hud_context *hud, const char *env)
 
       default:
          fprintf(stderr, "gallium_hud: syntax error: unexpected '%c'\n", *env);
          fflush(stderr);
       }
 
       /* Reset to defaults for the next pane in case these were modified. */
       width = 251;
       ceiling = UINT64_MAX;
       dyn_ceiling = false;
+      sort_items = false;
 
    }
 
    if (pane) {
       if (pane->num_graphs) {
          LIST_ADDTAIL(&pane->head, &hud->pane_list);
       }
       else {
          FREE(pane);
       }
@@ -1321,20 +1347,21 @@ print_help(struct pipe_screen *screen)
    puts("  'y[value]' sets the location of the pane on the y axis relative");
    puts("             to the upper-left corner of the viewport, in pixels.");
    puts("  'w[value]' sets width of the graph pixels.");
    puts("  'h[value]' sets height of the graph in pixels.");
    puts("  'c[value]' sets the ceiling of the value of the Y axis.");
    puts("             If the graph needs to draw values higher than");
    puts("             the ceiling allows, the value is clamped.");
    puts("  'd' activates dynamic Y axis readjustment to set the value of");
    puts("      the Y axis to match the highest value still visible in the graph.");
    puts("  'r' resets the color counter (the next color will be green)");
+   puts("  's' sort items below graphs in descending order");
    puts("");
    puts("  If 'c' and 'd' modifiers are used simultaneously, both are in effect:");
    puts("  the Y axis does not go above the restriction imposed by 'c' while");
    puts("  still adjusting the value of the Y axis down when appropriate.");
    puts("");
    puts("  Example: GALLIUM_HUD=\".w256.h64.x1600.y520.d.c1000fps+cpu,.datom-count\"");
    puts("");
    puts("  Available names:");
    puts("    fps");
    puts("    cpu");
diff --git a/src/gallium/auxiliary/hud/hud_private.h b/src/gallium/auxiliary/hud/hud_private.h
index 479ece5..d719e5f 100644
--- a/src/gallium/auxiliary/hud/hud_private.h
+++ b/src/gallium/auxiliary/hud/hud_private.h
@@ -61,20 +61,21 @@ struct hud_pane {
    unsigned inner_width;
    unsigned inner_height;
    float yscale;
    unsigned max_num_vertices;
    unsigned last_line; /* index of the last describing line in the graph */
    uint64_t max_value;
    uint64_t initial_max_value;
    uint64_t ceiling;
    unsigned dyn_ceil_last_ran;
    boolean dyn_ceiling;
+   boolean sort_items;
    enum pipe_driver_query_type type;
    uint64_t period; /* in microseconds */
 
    struct list_head graph_list;
    unsigned num_graphs;
    unsigned next_color;
 };
 
 
 /* core */
-- 
2.7.4



More information about the mesa-dev mailing list