diff --git a/libweston/perfetto/annotations.c b/libweston/perfetto/annotations.c index f383a699f..8eccf79f8 100644 --- a/libweston/perfetto/annotations.c +++ b/libweston/perfetto/annotations.c @@ -26,21 +26,55 @@ #include "config.h" #include +#include "libweston/pixel-formats.h" #include "perfetto/annotations.h" #include "shared/weston-assert.h" #include "weston-trace.h" -WL_EXPORT int -perfetto_annotate_int(struct weston_debug_annotation *annots, - unsigned int count, - const char *key, - int value) + +static int +do_perfetto_annotate_int(struct weston_debug_annotation *annots, + unsigned int count, + unsigned int parent, + const char *key, + unsigned int key_size, + int value) { weston_assert_u32_gt(NULL, WESTON_MAX_DEBUG_ANNOTS, count); annots[count].type = WESTON_DEBUG_ANNOTATION_INT_VAL; annots[count].ivalue = value; + annots[count].parent = parent; annots[count].key = key; + annots[count].key_size = key_size; + return 1; +} + +WL_EXPORT int +perfetto_annotate_int(struct weston_debug_annotation *annots, + unsigned int count, + const char *key, + unsigned int key_size, + int value) +{ + return do_perfetto_annotate_int(annots, count, count, key, key_size, value); +} + +static int +do_perfetto_annotate_float(struct weston_debug_annotation *annots, + unsigned int count, + unsigned int parent, + const char *key, + unsigned int key_size, + float value) +{ + weston_assert_u32_gt(NULL, WESTON_MAX_DEBUG_ANNOTS, count); + + annots[count].type = WESTON_DEBUG_ANNOTATION_FLOAT_VAL; + annots[count].fvalue = value; + annots[count].parent = parent; + annots[count].key = key; + annots[count].key_size = key_size; return 1; } @@ -49,13 +83,27 @@ WL_EXPORT int perfetto_annotate_float(struct weston_debug_annotation *annots, unsigned int count, const char *key, + unsigned int key_size, float value) +{ + return do_perfetto_annotate_float(annots, count, count, key, key_size, value); +} + +static int +do_perfetto_annotate_string(struct weston_debug_annotation *annots, + unsigned int count, + unsigned int parent, + const char *key, + unsigned int key_size, + const char *value) { weston_assert_u32_gt(NULL, WESTON_MAX_DEBUG_ANNOTS, count); - annots[count].type = WESTON_DEBUG_ANNOTATION_FLOAT_VAL; - annots[count].fvalue = value; + annots[count].type = WESTON_DEBUG_ANNOTATION_STR_VAL; + annots[count].svalue = value; + annots[count].parent = parent; annots[count].key = key; + annots[count].key_size = key_size; return 1; } @@ -64,13 +112,58 @@ WL_EXPORT int perfetto_annotate_string(struct weston_debug_annotation *annots, unsigned int count, const char *key, + unsigned int key_size, const char *value) +{ + return do_perfetto_annotate_string(annots, count, count, key, key_size, value); +} + +static int +perfetto_annotate_container(struct weston_debug_annotation *annots, + unsigned int count, + unsigned int parent, + const char *key, + unsigned int key_size) { weston_assert_u32_gt(NULL, WESTON_MAX_DEBUG_ANNOTS, count); - annots[count].type = WESTON_DEBUG_ANNOTATION_STR_VAL; - annots[count].svalue = value; + annots[count].type = WESTON_DEBUG_ANNOTATION_CONTAINER; annots[count].key = key; + annots[count].key_size = key_size; + annots[count].parent = parent; return 1; } + +/* Helper macros for the complex annotations */ +#define ADD_STRING(parent, key, value) \ + do_perfetto_annotate_string(annots, count + new_items, parent, key, sizeof(key), value) + +#define ADD_INT(parent, key, value) \ + do_perfetto_annotate_int(annots, count + new_items, parent, key, sizeof(key), value) + +#define ADD_FLOAT(parent, key, value) \ + do_perfetto_annotate_float(annots, count + new_items, parent, key, sizeof(key), value) + +WL_EXPORT int +perfetto_annotate_buffer(struct weston_debug_annotation *annots, + unsigned int count, + const char *key, + unsigned int key_size, + const struct weston_buffer *buffer) +{ + int new_items = 0; + int parent = count; + + if (!buffer) + return perfetto_annotate_string(annots, count, key, key_size, "None"); + + new_items += perfetto_annotate_container(annots, count, count, key, key_size); + + new_items += ADD_STRING(parent, "format", buffer->pixel_format->drm_format_name); + new_items += ADD_STRING(parent, "modifier", buffer->format_modifier_name); + new_items += ADD_INT(parent, "width", buffer->width); + new_items += ADD_INT(parent, "height", buffer->height); + + return new_items; +} diff --git a/libweston/perfetto/annotations.h b/libweston/perfetto/annotations.h index 17a90db4b..aaa64e1e0 100644 --- a/libweston/perfetto/annotations.h +++ b/libweston/perfetto/annotations.h @@ -33,16 +33,26 @@ int perfetto_annotate_int(struct weston_debug_annotation *annots, unsigned int count, const char *key, + unsigned int key_size, int value); int perfetto_annotate_float(struct weston_debug_annotation *annots, unsigned int count, const char *key, + unsigned int key_size, float value); int perfetto_annotate_string(struct weston_debug_annotation *annots, unsigned int count, const char *key, + unsigned int key_size, const char *value); + +int +perfetto_annotate_buffer(struct weston_debug_annotation *annots, + unsigned int count, + const char *key, + unsigned int key_size, + const struct weston_buffer *buffer); diff --git a/libweston/perfetto/u_perfetto.cc b/libweston/perfetto/u_perfetto.cc index 6a472dcc4..168060e4d 100644 --- a/libweston/perfetto/u_perfetto.cc +++ b/libweston/perfetto/u_perfetto.cc @@ -151,6 +151,29 @@ util_perfetto_next_id(void) return p_atomic_inc_return(&util_perfetto_unique_id); } +static char * +build_key(char *space, size_t size, struct weston_debug_annotation *annots, unsigned int idx) +{ + char *cur = space + size; + + cur -= annots[idx].key_size; + memcpy(cur, annots[idx].key, annots[idx].key_size); + + do { + idx = annots[idx].parent; + + if (space + 2 + annots[idx].key_size - 1 >= cur) + return NULL; + + *(--cur) = ':'; + *(--cur) = ':'; + cur -= annots[idx].key_size - 1; + memcpy(cur, annots[idx].key, annots[idx].key_size - 1); + } while (idx != annots[idx].parent); + + return cur; +} + static void util_perfetto_flush_debug_annotation(perfetto::EventContext *ctx, unsigned int nr_entries, @@ -160,15 +183,40 @@ util_perfetto_flush_debug_annotation(perfetto::EventContext *ctx, return; for (unsigned int idx = 0; idx < nr_entries; idx++) { + const char *key = annots[idx].key; + char keyspace[400]; + bool use_built_key; + + if (annots[idx].type == WESTON_DEBUG_ANNOTATION_CONTAINER) + continue; + + use_built_key = false; + if (annots[idx].parent != idx) { + key = build_key(keyspace, sizeof(keyspace), annots, idx); + if (!key) + continue; + + use_built_key = true; + } + switch (annots[idx].type) { case WESTON_DEBUG_ANNOTATION_INT_VAL: - ctx->AddDebugAnnotation(annots[idx].key, annots[idx].ivalue); + if (use_built_key) + ctx->AddDebugAnnotation(perfetto::DynamicString(key), annots[idx].ivalue); + else + ctx->AddDebugAnnotation(key, annots[idx].ivalue); break; case WESTON_DEBUG_ANNOTATION_FLOAT_VAL: - ctx->AddDebugAnnotation(annots[idx].key, annots[idx].fvalue); + if (use_built_key) + ctx->AddDebugAnnotation(perfetto::DynamicString(key), annots[idx].fvalue); + else + ctx->AddDebugAnnotation(key, annots[idx].fvalue); break; case WESTON_DEBUG_ANNOTATION_STR_VAL: - ctx->AddDebugAnnotation(annots[idx].key, annots[idx].svalue); + if (use_built_key) + ctx->AddDebugAnnotation(perfetto::DynamicString(key), annots[idx].svalue); + else + ctx->AddDebugAnnotation(key, annots[idx].svalue); break; default: break; diff --git a/libweston/perfetto/u_perfetto.h b/libweston/perfetto/u_perfetto.h index 4c84b7250..1ac50124b 100644 --- a/libweston/perfetto/u_perfetto.h +++ b/libweston/perfetto/u_perfetto.h @@ -43,16 +43,19 @@ enum weston_debug_annotation_type { WESTON_DEBUG_ANNOTATION_INT_VAL, WESTON_DEBUG_ANNOTATION_FLOAT_VAL, WESTON_DEBUG_ANNOTATION_STR_VAL, + WESTON_DEBUG_ANNOTATION_CONTAINER, }; struct weston_debug_annotation { const char *key; + size_t key_size; enum weston_debug_annotation_type type; union { int ivalue; float fvalue; const char *svalue; }; + unsigned int parent; }; #ifdef HAVE_PERFETTO diff --git a/libweston/surface-state.c b/libweston/surface-state.c index c1dc3ac29..3e8765841 100644 --- a/libweston/surface-state.c +++ b/libweston/surface-state.c @@ -205,13 +205,8 @@ weston_surface_attach(struct weston_surface *surface, enum weston_paint_node_status pnode_changes = WESTON_PAINT_NODE_CLEAN; WESTON_TRACE_BEGIN_ANNOTATION(); - if (buffer) { - WESTON_TRACE_ANNOTATE(("surface", surface->internal_name), - ("format", buffer->pixel_format->drm_format_name), - ("modifier", buffer->format_modifier_name), - ("width", buffer->width), - ("height", buffer->height)); - } + WESTON_TRACE_ANNOTATE(("surface", surface->internal_name), + ("new buffer", buffer)); WESTON_TRACE_ANNOTATE_FUNC_FLOW(&surface->flow_id); if (!buffer) { diff --git a/libweston/weston-trace.h b/libweston/weston-trace.h index db0b72512..031cb8327 100644 --- a/libweston/weston-trace.h +++ b/libweston/weston-trace.h @@ -89,8 +89,10 @@ unsigned int: perfetto_annotate_int, \ float: perfetto_annotate_float, \ char *: perfetto_annotate_string, \ - const char *: perfetto_annotate_string \ - ) (__pd_annots, __pd_i, k, v); \ + const char *: perfetto_annotate_string, \ + struct weston_buffer *: perfetto_annotate_buffer, \ + const struct weston_buffer *: perfetto_annotate_buffer \ + ) (__pd_annots, __pd_i, k, sizeof(k), v); \ } #define _WESTON_TRACE_COMMIT_ANNOTATION(id, name) \