trace: Add namespaces to keys and use it for weston_buffer

We now track the size of the key string, as well as allow adding empty
"container" annotations that are just a name for nested storage.

When parents are present, the full key name is created by walking them
and prepending them to a string backwards.

Use this to implement a buffer annotation helper and use it in the one
place we're already logging a buffer.

Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
This commit is contained in:
Derek Foreman 2026-05-05 16:47:21 -05:00
parent b8bd3c7c8b
commit 84891c9e2f
6 changed files with 172 additions and 21 deletions

View file

@ -26,21 +26,55 @@
#include "config.h"
#include <libweston/libweston.h>
#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;
}

View file

@ -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);

View file

@ -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;

View file

@ -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

View file

@ -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) {

View file

@ -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) \