diff options
Diffstat (limited to 'libs/cairo-1.16.0/perf/cairo-perf-graph-files.c')
-rw-r--r-- | libs/cairo-1.16.0/perf/cairo-perf-graph-files.c | 604 |
1 files changed, 0 insertions, 604 deletions
diff --git a/libs/cairo-1.16.0/perf/cairo-perf-graph-files.c b/libs/cairo-1.16.0/perf/cairo-perf-graph-files.c deleted file mode 100644 index 1fd99e4..0000000 --- a/libs/cairo-1.16.0/perf/cairo-perf-graph-files.c +++ /dev/null @@ -1,604 +0,0 @@ -/* - * Copyright © 2008 Chris Wilson - * - * Permission to use, copy, modify, distribute, and sell this software - * and its documentation for any purpose is hereby granted without - * fee, provided that the above copyright notice appear in all copies - * and that both that copyright notice and this permission notice - * appear in supporting documentation, and that the name of the - * copyright holders not be used in advertising or publicity - * pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied - * warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - * Authors: Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairo-perf.h" -#include "cairo-perf-graph.h" - -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> -#include <fcntl.h> - -#include <cairo.h> - -static void -usage (const char *argv0) -{ - char const *basename = strrchr (argv0, '/'); - basename = basename ? basename+1 : argv0; - g_printerr ("Usage: %s [options] file1 file2 [...]\n\n", basename); - g_printerr ("Draws a graph illustrating the change in performance over a series.\n"); - exit(1); -} - -enum { - CASE_SHOWN, - CASE_INCONSISTENT, - CASE_BACKEND, - CASE_CONTENT, - CASE_NAME, - CASE_SIZE, - CASE_FG_COLOR, - CASE_DATA, - CASE_NCOLS -}; - -static GtkTreeStore * -cases_to_store (test_case_t *cases) -{ - GtkTreeStore *store; - GtkTreeIter backend_iter; - GtkTreeIter content_iter; - const char *backend = NULL; - const char *content = NULL; - - store = gtk_tree_store_new (CASE_NCOLS, - G_TYPE_BOOLEAN, /* shown */ - G_TYPE_BOOLEAN, /* inconsistent */ - G_TYPE_STRING, /* backend */ - G_TYPE_STRING, /* content */ - G_TYPE_STRING, /* name */ - G_TYPE_INT, /* size */ - GDK_TYPE_COLOR, /* fg color */ - G_TYPE_POINTER); /* data */ - while (cases->backend != NULL) { - GtkTreeIter iter; - - if (backend == NULL || strcmp (backend, cases->backend)) { - gtk_tree_store_append (store, &backend_iter, NULL); - gtk_tree_store_set (store, &backend_iter, - CASE_SHOWN, TRUE, - CASE_BACKEND, cases->backend, - -1); - backend = cases->backend; - content = NULL; - } - if (content == NULL || strcmp (content, cases->content)) { - gtk_tree_store_append (store, &content_iter, &backend_iter); - gtk_tree_store_set (store, &content_iter, - CASE_SHOWN, TRUE, - CASE_BACKEND, cases->backend, - CASE_CONTENT, cases->content, - -1); - content = cases->content; - } - - gtk_tree_store_append (store, &iter, &content_iter); - gtk_tree_store_set (store, &iter, - CASE_SHOWN, TRUE, - CASE_BACKEND, cases->backend, - CASE_CONTENT, cases->content, - CASE_NAME, cases->name, - CASE_SIZE, cases->size, - CASE_FG_COLOR, &cases->color, - CASE_DATA, cases, - -1); - cases++; - } - - return store; -} - -struct _app_data { - GtkWidget *window; - - test_case_t *cases; - cairo_perf_report_t *reports; - int num_reports; - - GtkTreeStore *case_store; - - GIOChannel *git_io; - GtkTextBuffer *git_buffer; - - GtkWidget *gv; -}; - -static void -recurse_set_shown (GtkTreeModel *model, - GtkTreeIter *parent, - gboolean shown) -{ - GtkTreeIter iter; - - if (gtk_tree_model_iter_children (model, &iter, parent)) do { - test_case_t *c; - - gtk_tree_model_get (model, &iter, CASE_DATA, &c, -1); - if (c == NULL) { - recurse_set_shown (model, &iter, shown); - } else if (shown != c->shown) { - c->shown = shown; - gtk_tree_store_set (GTK_TREE_STORE (model), &iter, - CASE_SHOWN, shown, - CASE_INCONSISTENT, FALSE, - -1); - } - } while (gtk_tree_model_iter_next (model, &iter)); -} - -static gboolean -children_consistent (GtkTreeModel *model, - GtkTreeIter *parent) -{ - GtkTreeIter iter; - gboolean first = TRUE; - gboolean first_active; - - if (gtk_tree_model_iter_children (model, &iter, parent)) do { - gboolean active, inconsistent; - - gtk_tree_model_get (model, &iter, - CASE_INCONSISTENT, &inconsistent, - CASE_SHOWN, &active, - -1); - if (inconsistent) - return FALSE; - - if (first) { - first_active = active; - first = FALSE; - } else if (active != first_active) - return FALSE; - } while (gtk_tree_model_iter_next (model, &iter)); - - return TRUE; -} - -static void -check_consistent (GtkTreeModel *model, - GtkTreeIter *child) -{ - GtkTreeIter parent; - - if (gtk_tree_model_iter_parent (model, &parent, child)) { - gtk_tree_store_set (GTK_TREE_STORE (model), &parent, - CASE_INCONSISTENT, - ! children_consistent (model, &parent), - -1); - check_consistent (model, &parent); - } -} - -static void -show_case_toggled (GtkCellRendererToggle *cell, - gchar *str, - struct _app_data *app) -{ - GtkTreeModel *model; - GtkTreePath *path; - GtkTreeIter iter; - test_case_t *c; - gboolean active; - - active = ! gtk_cell_renderer_toggle_get_active (cell); - - model = GTK_TREE_MODEL (app->case_store); - - path = gtk_tree_path_new_from_string (str); - gtk_tree_model_get_iter (model, &iter, path); - gtk_tree_path_free (path); - - gtk_tree_store_set (app->case_store, &iter, - CASE_SHOWN, active, - CASE_INCONSISTENT, FALSE, - -1); - gtk_tree_model_get (model, &iter, CASE_DATA, &c, -1); - if (c != NULL) { - if (active == c->shown) - return; - - c->shown = active; - } else { - recurse_set_shown (model, &iter, active); - } - check_consistent (model, &iter); - - graph_view_update_visible ((GraphView *) app->gv); -} - -static gboolean -git_read (GIOChannel *io, - GIOCondition cond, - struct _app_data *app) -{ - int fd; - - fd = g_io_channel_unix_get_fd (io); - do { - char buf[4096]; - int len; - GtkTextIter end; - - len = read (fd, buf, sizeof (buf)); - if (len <= 0) { - int err = len ? errno : 0; - switch (err) { - case EAGAIN: - case EINTR: - return TRUE; - default: - g_io_channel_unref (app->git_io); - app->git_io = NULL; - return FALSE; - } - } - - gtk_text_buffer_get_end_iter (app->git_buffer, &end); - gtk_text_buffer_insert (app->git_buffer, &end, buf, len); - } while (TRUE); -} - -static void -do_git (struct _app_data *app, - char **argv) -{ - gint output; - GError *error = NULL; - GtkTextIter start, stop; - long flags; - - if (! g_spawn_async_with_pipes (NULL, argv, NULL, - G_SPAWN_SEARCH_PATH | - G_SPAWN_STDERR_TO_DEV_NULL | - G_SPAWN_FILE_AND_ARGV_ZERO, - NULL, NULL, NULL, - NULL, &output, NULL, - &error)) - { - g_error ("spawn failed: %s", error->message); - } - - if (app->git_io) { - g_io_channel_shutdown (app->git_io, FALSE, NULL); - g_io_channel_unref (app->git_io); - } - - gtk_text_buffer_get_bounds (app->git_buffer, &start, &stop); - gtk_text_buffer_delete (app->git_buffer, &start, &stop); - - flags = fcntl (output, F_GETFL); - if ((flags & O_NONBLOCK) == 0) - fcntl (output, F_SETFL, flags | O_NONBLOCK); - - app->git_io = g_io_channel_unix_new (output); - g_io_add_watch (app->git_io, G_IO_IN | G_IO_HUP, (GIOFunc) git_read, app); -} - -static void -gv_report_selected (GraphView *gv, - int i, - struct _app_data *app) -{ - cairo_perf_report_t *report; - char *hyphen; - - if (i == -1) - return; - - report = &app->reports[i]; - hyphen = strchr (report->configuration, '-'); - if (hyphen != NULL) { - int len = hyphen - report->configuration; - char *id = g_malloc (len + 1); - char *argv[5]; - - memcpy (id, report->configuration, len); - id[len] = '\0'; - - argv[0] = (char *) "git"; - argv[1] = (char *) "git"; - argv[2] = (char *) "show"; - argv[3] = id; - argv[4] = NULL; - - do_git (app, argv); - g_free (id); - } -} - -static GtkWidget * -window_create (test_case_t *cases, - cairo_perf_report_t *reports, - int num_reports) -{ - GtkWidget *window, *table, *w; - GtkWidget *tv, *sw; - GtkTreeStore *store; - GtkTreeViewColumn *column; - GtkCellRenderer *renderer; - struct _app_data *data; - - - data = g_new0 (struct _app_data, 1); - data->cases = cases; - data->reports = reports; - data->num_reports = num_reports; - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_title (GTK_WINDOW (window), "Cairo Performance Graph"); - g_object_set_data_full (G_OBJECT (window), - "app-data", data, (GDestroyNotify)g_free); - - data->window = window; - - table = gtk_table_new (2, 2, FALSE); - - /* legend & show/hide lines (categorised) */ - tv = gtk_tree_view_new (); - store = cases_to_store (cases); - data->case_store = store; - gtk_tree_view_set_model (GTK_TREE_VIEW (tv), GTK_TREE_MODEL (store)); - - renderer = gtk_cell_renderer_toggle_new (); - column = gtk_tree_view_column_new_with_attributes (NULL, - renderer, - "active", CASE_SHOWN, - "inconsistent", CASE_INCONSISTENT, - NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (tv), column); - g_signal_connect (renderer, "toggled", - G_CALLBACK (show_case_toggled), data); - - renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes ("Backend", - renderer, - "text", CASE_BACKEND, - NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (tv), column); - - renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes ("Content", - renderer, - "text", CASE_CONTENT, - NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (tv), column); - - renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes ("Test", - renderer, - "text", CASE_NAME, - "foreground-gdk", CASE_FG_COLOR, - NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (tv), column); - - renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes ("Size", - renderer, - "text", CASE_SIZE, - NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (tv), column); - - gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (tv), TRUE); - g_object_unref (store); - - sw = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), - GTK_POLICY_NEVER, - GTK_POLICY_AUTOMATIC); - gtk_container_add (GTK_CONTAINER (sw), tv); - gtk_widget_show (tv); - gtk_table_attach (GTK_TABLE (table), sw, - 0, 1, 0, 2, - GTK_FILL, GTK_FILL, - 4, 4); - gtk_widget_show (sw); - - /* the performance chart */ - w = graph_view_new (); - data->gv = w; - g_signal_connect (w, "report-selected", - G_CALLBACK (gv_report_selected), data); - graph_view_set_reports ((GraphView *)w, cases, reports, num_reports); - gtk_table_attach (GTK_TABLE (table), w, - 1, 2, 0, 1, - GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, - 4, 4); - gtk_widget_show (w); - - /* interesting information - presumably the commit log */ - w = gtk_text_view_new (); - data->git_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (w)); - sw = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), - GTK_POLICY_NEVER, - GTK_POLICY_AUTOMATIC); - gtk_container_add (GTK_CONTAINER (sw), w); - gtk_widget_show (w); - gtk_table_attach (GTK_TABLE (table), sw, - 1, 2, 1, 2, - GTK_FILL, GTK_FILL | GTK_EXPAND, - 4, 4); - gtk_widget_show (sw); - - gtk_container_add (GTK_CONTAINER (window), table); - gtk_widget_show (table); - - return window; -} - -static void -name_to_color (const char *name, - GdkColor *color) -{ - gint v = g_str_hash (name); - - color->red = ((v >> 0) & 0xff) / 384. * 0xffff; - color->green = ((v >> 8) & 0xff) / 384. * 0xffff; - color->blue = ((v >> 16) & 0xff) / 384. * 0xffff; -} - -static test_case_t * -test_cases_from_reports (cairo_perf_report_t *reports, - int num_reports) -{ - test_case_t *cases, *c; - test_report_t **tests; - int i, j; - int num_tests; - - num_tests = 0; - for (i = 0; i < num_reports; i++) { - for (j = 0; reports[i].tests[j].name != NULL; j++) - ; - if (j > num_tests) - num_tests = j; - } - - cases = xcalloc (num_tests+1, sizeof (test_case_t)); - tests = xmalloc (num_reports * sizeof (test_report_t *)); - for (i = 0; i < num_reports; i++) - tests[i] = reports[i].tests; - - c = cases; - while (1) { - int seen_non_null; - test_report_t *min_test; - - /* We expect iterations values of 0 when multiple raw reports - * for the same test have been condensed into the stats of the - * first. So we just skip these later reports that have no - * stats. */ - seen_non_null = 0; - for (i = 0; i < num_reports; i++) { - while (tests[i]->name && tests[i]->stats.iterations == 0) - tests[i]++; - if (tests[i]->name) - seen_non_null++; - } - - if (seen_non_null < 2) - break; - - /* Find the minimum of all current tests, (we have to do this - * in case some reports don't have a particular test). */ - for (i = 0; i < num_reports; i++) { - if (tests[i]->name) { - min_test = tests[i]; - break; - } - } - for (++i; i < num_reports; i++) { - if (tests[i]->name && - test_report_cmp_backend_then_name (tests[i], min_test) < 0) - { - min_test = tests[i]; - } - } - - c->min_test = min_test; - c->backend = min_test->backend; - c->content = min_test->content; - c->name = min_test->name; - c->size = min_test->size; - c->baseline = min_test->stats.min_ticks; - c->min = c->max = 1.; - c->shown = TRUE; - name_to_color (c->name, &c->color); - - for (i = 0; i < num_reports; i++) { - if (tests[i]->name && - test_report_cmp_backend_then_name (tests[i], min_test) == 0) - { - tests[i]++; - break; - } - } - - for (++i; i < num_reports; i++) { - if (tests[i]->name && - test_report_cmp_backend_then_name (tests[i], min_test) == 0) - { - double v = tests[i]->stats.min_ticks / c->baseline; - if (v < c->min) - c->min = v; - if (v > c->max) - c->max = v; - tests[i]++; - } - } - - c++; - } - free (tests); - - return cases; -} -int -main (int argc, - char *argv[]) -{ - cairo_perf_report_t *reports; - test_case_t *cases; - test_report_t *t; - int i; - GtkWidget *window; - - gtk_init (&argc, &argv); - - if (argc < 3) - usage (argv[0]); - - reports = xmalloc ((argc-1) * sizeof (cairo_perf_report_t)); - for (i = 1; i < argc; i++ ) - cairo_perf_report_load (&reports[i-1], argv[i], i, NULL); - - cases = test_cases_from_reports (reports, argc-1); - - window = window_create (cases, reports, argc-1); - g_signal_connect (window, "delete-event", - G_CALLBACK (gtk_main_quit), NULL); - gtk_widget_show (window); - - gtk_main (); - - /* Pointless memory cleanup, (would be a great place for talloc) */ - free (cases); - for (i = 0; i < argc-1; i++) { - for (t = reports[i].tests; t->name; t++) { - free (t->samples); - free (t->backend); - free (t->name); - } - free (reports[i].tests); - free (reports[i].configuration); - } - free (reports); - - return 0; -} |