Merge branch 'wip/mvlad/perfetto-debug-annotations' into 'main'

libweston: Introduce Perfetto debug annotations

See merge request wayland/weston!2007
This commit is contained in:
Marius Vlad 2026-05-05 16:59:27 +03:00
commit 76fdc4610e
7 changed files with 377 additions and 32 deletions

View file

@ -151,6 +151,83 @@ util_perfetto_next_id(void)
return p_atomic_inc_return(&util_perfetto_unique_id);
}
static void
util_perfetto_flush_debug_annotation(perfetto::EventContext *ctx,
unsigned int nr_entries,
struct weston_debug_annotation *annots)
{
if (nr_entries == 0)
return;
for (unsigned int idx = 0; idx < nr_entries; idx++) {
switch (annots[idx].type) {
case WESTON_DEBUG_ANNOTATION_INT_VAL:
ctx->AddDebugAnnotation(annots[idx].key, annots[idx].ivalue);
break;
case WESTON_DEBUG_ANNOTATION_FLOAT_VAL:
ctx->AddDebugAnnotation(annots[idx].key, annots[idx].fvalue);
break;
case WESTON_DEBUG_ANNOTATION_STR_VAL:
ctx->AddDebugAnnotation(annots[idx].key, annots[idx].svalue);
break;
default:
break;
}
}
}
void
util_perfetto_trace_commit_debug_annots(uint64_t id, const char *name,
unsigned int nr_entries,
struct weston_debug_annotation *annots)
{
if (id) {
TRACE_EVENT_INSTANT(UTIL_PERFETTO_CATEGORY_DEFAULT_STR,
nullptr,
perfetto::Flow::ProcessScoped(id),
[&](perfetto::EventContext ctx) {
ctx.event()->set_name(name);
util_perfetto_flush_debug_annotation(&ctx, nr_entries, annots);
});
return;
}
TRACE_EVENT_INSTANT(UTIL_PERFETTO_CATEGORY_DEFAULT_STR,
nullptr,
[&](perfetto::EventContext ctx) {
ctx.event()->set_name(name);
util_perfetto_flush_debug_annotation(&ctx, nr_entries, annots);
});
}
void
util_perfetto_trace_commit_annotate_func(const char *name, unsigned int nr_entries,
struct weston_debug_annotation *annots)
{
TRACE_EVENT_BEGIN(UTIL_PERFETTO_CATEGORY_DEFAULT_STR,
nullptr,
[&](perfetto::EventContext ctx) {
ctx.event()->set_name(name);
util_perfetto_flush_debug_annotation(&ctx, nr_entries, annots);
});
}
void
util_perfetto_trace_commit_annotate_func_flow(uint64_t id, const char *name,
unsigned int nr_entries,
struct weston_debug_annotation *annots)
{
TRACE_EVENT_BEGIN(UTIL_PERFETTO_CATEGORY_DEFAULT_STR,
nullptr,
perfetto::Flow::ProcessScoped(id),
[&](perfetto::EventContext ctx) {
ctx.event()->set_name(name);
util_perfetto_flush_debug_annotation(&ctx, nr_entries, annots);
});
}
class UtilPerfettoObserver : public perfetto::TrackEventSessionObserver {
public:
UtilPerfettoObserver() { perfetto::TrackEvent::AddSessionObserver(this); }

View file

@ -39,6 +39,22 @@
extern "C" {
#endif
enum weston_debug_annotation_type {
WESTON_DEBUG_ANNOTATION_INT_VAL,
WESTON_DEBUG_ANNOTATION_FLOAT_VAL,
WESTON_DEBUG_ANNOTATION_STR_VAL,
};
struct weston_debug_annotation {
const char *key;
enum weston_debug_annotation_type type;
union {
int ivalue;
float fvalue;
const char *svalue;
};
};
#ifdef HAVE_PERFETTO
extern int util_perfetto_tracing_state;
@ -63,6 +79,15 @@ void util_perfetto_trace_full_begin(const char *name, uint64_t track_id, uint64_
void util_perfetto_trace_full_end(const char *name, uint64_t track_id, clockid_t clock, uint64_t timestamp);
void util_perfetto_trace_commit_debug_annots(uint64_t id, const char *name,
unsigned int entries, struct weston_debug_annotation *annots);
void util_perfetto_trace_commit_annotate_func(const char *name,
unsigned int entries, struct weston_debug_annotation *annots);
void util_perfetto_trace_commit_annotate_func_flow(uint64_t id, const char *name,
unsigned int entries, struct weston_debug_annotation *annots);
uint64_t util_perfetto_next_id(void);
uint64_t util_perfetto_new_track(const char *name);
@ -104,6 +129,27 @@ util_perfetto_trace_full_end(const char *name, uint64_t track_id, clockid_t cloc
{
}
static inline void
util_perfetto_trace_commit_debug_annots(uint64_t id, const char *name,
unsigned int entries,
struct weston_debug_annotation *annots)
{
}
static inline void
util_perfetto_trace_commit_annotate_func(const char *name,
unsigned int entries,
struct weston_debug_annotation *annots)
{
}
static inline void
util_perfetto_trace_commit_annotate_func_flow(uint64_t id, const char *name,
unsigned int entries,
struct weston_debug_annotation *annots)
{
}
static inline void util_perfetto_counter_set(const char *name, double value)
{
}

View file

@ -765,7 +765,7 @@ void
gl_renderer_garbage_collect_programs(struct gl_renderer *gr);
bool
gl_renderer_use_program(struct gl_renderer *gr,
gl_renderer_use_program(struct gl_renderer *gr, struct weston_paint_node *pnode,
const struct gl_shader_config *sconf);
struct weston_log_scope *

View file

@ -58,6 +58,7 @@
#include "linux-explicit-synchronization.h"
#include "output-capture.h"
#include "pixel-formats.h"
#include "weston-trace.h"
#include "shared/fd-util.h"
#include "shared/helpers.h"
@ -412,19 +413,20 @@ gl_log_paint_node_start(struct gl_renderer *gr, struct weston_paint_node *pnode)
}
static void
gl_log_paint_node_bbox_and_region(struct gl_renderer *gr, const char *str,
pixman_region32_t *damage)
gl_log_paint_node_bbox_and_region(struct gl_renderer *gr, struct weston_paint_node *pnode,
const char *str, pixman_region32_t *damage)
{
pixman_box32_t *box;
int32_t box_x, box_y;
uint32_t box_width, box_height;
int n_rects = 0;
const pixman_box32_t *rects =
pixman_region32_rectangles(damage, &n_rects);
const pixman_box32_t *rects;
if (!weston_log_scope_is_enabled(gr->paint_node_scope))
if (!weston_log_scope_is_enabled(gr->paint_node_scope) &&
!util_perfetto_is_tracing_enabled())
return;
rects = pixman_region32_rectangles(damage, &n_rects);
box = pixman_region32_extents(damage);
box_x = box->x1;
@ -432,6 +434,20 @@ gl_log_paint_node_bbox_and_region(struct gl_renderer *gr, const char *str,
box_width = box->x2 - box->x1;
box_height = box->y2 - box->y1;
WESTON_TRACE_BEGIN_ANNOTATION();
WESTON_TRACE_ANNOTATE_ADD_STR("paint node", pnode->internal_name);
WESTON_TRACE_ANNOTATE_ADD_STR("type", str);
WESTON_TRACE_ANNOTATE_ADD_INT("x", box_x);
WESTON_TRACE_ANNOTATE_ADD_INT("y", box_y);
WESTON_TRACE_ANNOTATE_ADD_INT("box_width", box_width);
WESTON_TRACE_ANNOTATE_ADD_INT("box_height", box_height);
WESTON_TRACE_COMMIT_ANNOTATION(&pnode->flow_id);
if (!weston_log_scope_is_enabled(gr->paint_node_scope))
return;
weston_log_scope_printf(gr->paint_node_scope, "\t\t%s bounding box: ", str);
weston_log_scope_printf(gr->paint_node_scope, "x: %5d, y: %5d, width: "
"%d, height: %d\n", box_x, box_y, box_width, box_height);
@ -730,13 +746,11 @@ timeline_render_point_handler(int fd, uint32_t mask, void *data)
TLP_GPU(&end), TLP_OUTPUT(trp->output), TLP_END);
weston_log_scope_printf(gr->paint_node_scope,
"\tGPU Timeline:\n\t\tbegin: %" PRId64 ".%09ld"
" - end: %" PRId64 ".%09ld - elapsed: %.2f us\n",
"\tGPU activity:\n\t\tbegin: %" PRId64 ".%09ld"
" - end: %" PRId64 ".%09ld - active: %.2f us\n",
(int64_t) begin.tv_sec, begin.tv_nsec,
(int64_t) end.tv_sec, end.tv_nsec,
(float) (elapsed / 1000.0f));
}
timeline_render_point_destroy(trp);
@ -2340,19 +2354,30 @@ set_debug_mode(struct gl_renderer *gr,
}
static void
set_blend_state(struct gl_renderer *gr,
bool state)
set_blend_state(struct gl_renderer *gr, struct weston_paint_node *pnode, bool state)
{
if (gr->blend_state == state)
return;
WESTON_TRACE_BEGIN_ANNOTATION();
if (state) {
glEnable(GL_BLEND);
gl_log_paint_node(gr, "\t\tblending enabled\n");
WESTON_TRACE_ANNOTATE_ADD_STR("blending", "enabled");
} else {
glDisable(GL_BLEND);
gl_log_paint_node(gr, "\t\tblending disabled\n");
WESTON_TRACE_ANNOTATE_ADD_STR("blending", "disabled");
}
if (pnode) {
WESTON_TRACE_ANNOTATE_ADD_STR("paint node", pnode->internal_name);
WESTON_TRACE_COMMIT_ANNOTATION(&pnode->flow_id);
} else {
WESTON_TRACE_COMMIT_ANNOTATION(NULL);
}
gr->blend_state = state;
}
@ -2373,7 +2398,7 @@ draw_mesh(struct gl_renderer *gr,
assert(nidx > 0);
set_blend_state(gr, (!opaque || pnode->view_alpha < 1.0) && !go->shader_blender);
set_blend_state(gr, pnode, (!opaque || pnode->view_alpha < 1.0) && !go->shader_blender);
/* Prevent translucent surfaces from punching holes through the
* renderbuffer. */
@ -2389,7 +2414,7 @@ draw_mesh(struct gl_renderer *gr,
set_debug_mode(gr, sconf, barycentrics, opaque);
gl_log_paint_node(gr, "\t\tdrawing paint node mesh\n");
if (!gl_renderer_use_program(gr, sconf))
if (!gl_renderer_use_program(gr, pnode, sconf))
gl_renderer_send_shader_error(pnode); /* Use fallback shader. */
glVertexAttribPointer(SHADER_ATTRIB_LOC_POSITION, 2, GL_FLOAT, GL_FALSE,
@ -2501,7 +2526,7 @@ weston_output_cvd_type_to_str(struct weston_cvd_correction cvd)
}
static void
apply_color_effect(struct gl_renderer *gr, struct weston_output *output,
apply_color_effect(struct gl_renderer *gr, struct weston_paint_node *pnode, struct weston_output *output,
float *r, float *g, float *b, const float a)
{
struct weston_compositor *compositor = output->compositor;
@ -2518,6 +2543,11 @@ apply_color_effect(struct gl_renderer *gr, struct weston_output *output,
if (!output->color_effect || a == 0.0f) {
return;
}
WESTON_TRACE_FUNC_FLOW(&pnode->flow_id);
WESTON_TRACE_BEGIN_ANNOTATION();
WESTON_TRACE_ANNOTATE_ADD_STR("paint node", pnode->internal_name);
weston_assert_f32_eq(compositor, a, 1.0f);
switch (effect->type) {
@ -2526,12 +2556,16 @@ apply_color_effect(struct gl_renderer *gr, struct weston_output *output,
*g = 1.0f - *g;
*b = 1.0f - *b;
gl_log_paint_node(gr, "\t\tcolor effect: inversion\n");
WESTON_TRACE_ANNOTATE_ADD_STR("color effect", "inversion");
WESTON_TRACE_COMMIT_ANNOTATION(&pnode->flow_id);
return;
case WESTON_OUTPUT_COLOR_EFFECT_TYPE_GRAYSCALE:
*r = 0.2126f * (*r) + 0.7152f * (*g) + 0.0722f * (*b);
*g = *r;
*b = *r;
gl_log_paint_node(gr, "\t\tcolor effect: grayscale\n");
WESTON_TRACE_ANNOTATE_ADD_STR("color effect", "greyscale");
WESTON_TRACE_COMMIT_ANNOTATION(&pnode->flow_id);
return;
case WESTON_OUTPUT_COLOR_EFFECT_TYPE_CVD_CORRECTION:
/**
@ -2545,8 +2579,12 @@ apply_color_effect(struct gl_renderer *gr, struct weston_output *output,
weston_log_scope_printf(gr->paint_node_scope,
"\t\tcolor effect: cvd - %s\n",
weston_output_cvd_type_to_str(effect->u.cvd));
WESTON_TRACE_ANNOTATE_ADD_STR("color effect",
weston_output_cvd_type_to_str(effect->u.cvd));
WESTON_TRACE_COMMIT_ANNOTATION(&pnode->flow_id);
return;
};
weston_assert_not_reached(compositor, "unknown color effect type");
}
@ -2568,13 +2606,13 @@ clear_region(struct gl_renderer *gr, struct weston_paint_node *pnode,
/* We must be either fully transparent - punching a hole for an
* underlay - or fully opaque, to use clear rather than blending. */
assert(pnode->solid.a == 0.0f || pnode->solid.a == 1.0f);
set_blend_state(gr, false);
set_blend_state(gr, pnode, false);
r = pnode->solid.r;
g = pnode->solid.g;
b = pnode->solid.b;
a = pnode->solid.a;
apply_color_effect(gr, output, &r, &g, &b, a);
apply_color_effect(gr, pnode, output, &r, &g, &b, a);
glClearColor(r, g, b, a);
glEnable(GL_SCISSOR_TEST);
@ -2591,6 +2629,7 @@ static void
draw_paint_node(struct weston_paint_node *pnode,
pixman_region32_t *damage /* in global coordinates */)
{
WESTON_TRACE_FUNC_FLOW(&pnode->flow_id);
struct gl_renderer *gr = get_renderer(pnode->surface->compositor);
struct gl_surface_state *gs = get_surface_state(pnode->surface);
/* repaint bounding region in global coordinates: */
@ -2602,20 +2641,27 @@ draw_paint_node(struct weston_paint_node *pnode,
struct gl_shader_config sconf;
struct clipper_quad *quads = NULL;
int nquads;
WESTON_TRACE_BEGIN_ANNOTATION();
pixman_region32_init(&repaint);
pixman_region32_intersect(&repaint, &pnode->visible, damage);
WESTON_TRACE_ANNOTATE_ADD_STR("paint node", pnode->internal_name);
WESTON_TRACE_ANNOTATE_ADD_STR("label", pnode->surface->label);
WESTON_TRACE_ANNOTATE_ADD_INT("surface id", pnode->surface->s_id);
gl_log_paint_node_start(gr, pnode);
if (!pixman_region32_not_empty(&repaint)) {
gl_log_paint_node(gr, "\t\tskipped repaint: repaint region empty\n");
WESTON_TRACE_ANNOTATE_ADD_STR("skipped repaint", "repaint region empty");
goto out;
}
if (pnode->is_fully_transparent) {
gl_log_paint_node(gr, "\t\tskipped repaint: paint node transparent\n");
gs->used_in_output_repaint = true; /* sort of */
WESTON_TRACE_ANNOTATE_ADD_STR("skipped repaint", "paint node transparent");
goto out;
}
@ -2623,18 +2669,21 @@ draw_paint_node(struct weston_paint_node *pnode,
pnode->valid_transform && (pnode->surf_xform_valid &&
!pnode->surf_xform.transform)) {
gl_log_paint_node(gr, "\t\toptimize: using glClear\n");
WESTON_TRACE_ANNOTATE_ADD_STR("optimization", "using glClear");
clear_region(gr, pnode, &repaint);
gs->used_in_output_repaint = true;
goto out;
}
if (ensure_surface_buffer_is_ready(gr, gs, pnode) < 0) {
gl_log_paint_node(gr, "\t\tskip repaint: buffer not ready\n");
gl_log_paint_node(gr, "\t\tskipped repaint: buffer not ready\n");
WESTON_TRACE_ANNOTATE_ADD_STR("skipped repaint", "buffer not ready");
goto out;
}
if (!gl_shader_config_init_for_paint_node(&sconf, pnode)) {
gl_log_paint_node(gr, "\t\tskip repaint: shader config failure\n");
gl_log_paint_node(gr, "\t\tskipped repaint: shader config failure\n");
WESTON_TRACE_ANNOTATE_ADD_STR("skipped repaint", "shader config failure");
goto out;
}
@ -2661,18 +2710,18 @@ draw_paint_node(struct weston_paint_node *pnode,
pixman_region32_subtract(&surface_blend, &surface_blend,
&surface_opaque);
gl_log_paint_node_bbox_and_region(gr, "repaint region", &repaint);
gl_log_paint_node_bbox_and_region(gr, pnode, "repaint region", &repaint);
transform_damage(pnode, &repaint, &quads, &nquads);
if (pixman_region32_not_empty(&surface_opaque)) {
gl_log_paint_node_bbox_and_region(gr, "opaque region", &surface_opaque);
gl_log_paint_node_bbox_and_region(gr, pnode, "opaque region", &surface_opaque);
repaint_region(gr, pnode, quads, nquads, &surface_opaque,
&sconf, true);
gs->used_in_output_repaint = true;
}
if (pixman_region32_not_empty(&surface_blend)) {
gl_log_paint_node_bbox_and_region(gr, "blended region", &surface_blend);
gl_log_paint_node_bbox_and_region(gr, pnode, "blended region", &surface_blend);
repaint_region(gr, pnode, quads, nquads, &surface_blend, &sconf,
false);
gs->used_in_output_repaint = true;
@ -2683,6 +2732,8 @@ draw_paint_node(struct weston_paint_node *pnode,
pixman_region32_fini(&surface_blend);
pixman_region32_fini(&surface_opaque);
WESTON_TRACE_COMMIT_ANNOTATION(&pnode->flow_id);
out:
pixman_region32_fini(&repaint);
}
@ -2903,7 +2954,7 @@ draw_output_border_texture(struct gl_renderer *gr,
sconf->input_num = 1;
gl_log_paint_node(gr, "\t\tdrawing output border texture\n");
gl_renderer_use_program(gr, sconf);
gl_renderer_use_program(gr, NULL, sconf);
GLfloat texcoord[] = {
0.0f, 0.0f,
@ -2952,7 +3003,7 @@ draw_output_borders(struct weston_output *output,
return;
}
set_blend_state(gr, false);
set_blend_state(gr, NULL, false);
glViewport(0, 0, fb->width, fb->height);
weston_matrix_init(&sconf.projection);
@ -3024,8 +3075,8 @@ blit_shadow_to_output(struct weston_output *output,
pixman_region32_init(&translated_damage);
gl_log_paint_node(gr, "\t\tdrawing shadow output\n");
gl_renderer_use_program(gr, &sconf);
set_blend_state(gr, false);
gl_renderer_use_program(gr, NULL, &sconf);
set_blend_state(gr, NULL, false);
/* output_damage is in global coordinates */
pixman_region32_intersect(&translated_damage, output_damage,
@ -4506,7 +4557,7 @@ gl_renderer_surface_copy_content(struct weston_surface *surface,
}
glViewport(0, 0, cw, ch);
set_blend_state(gr, false);
set_blend_state(gr, NULL, false);
if (buffer->buffer_origin == ORIGIN_TOP_LEFT)
ARRAY_COPY(sconf.projection.M.colmaj, projmat_normal);
else
@ -4515,7 +4566,7 @@ gl_renderer_surface_copy_content(struct weston_surface *surface,
WESTON_MATRIX_TRANSFORM_TRANSLATE;
gl_log_paint_node(gr, "\t\tcopying surface\n");
if (!gl_renderer_use_program(gr, &sconf))
if (!gl_renderer_use_program(gr, NULL, &sconf))
goto use_program_error;
glEnableVertexAttribArray(SHADER_ATTRIB_LOC_POSITION);

View file

@ -46,6 +46,7 @@
#include "shared/helpers.h"
#include "shared/timespec-util.h"
#include "shared/weston-assert.h"
#include "weston-trace.h"
/* static const char vertex_shader[]; vertex.glsl */
#include "vertex-shader.h"
@ -843,7 +844,7 @@ gl_shader_texture_variant_get_target(enum gl_shader_texture_variant v)
}
static void
gl_shader_load_config(struct gl_renderer *gr,
gl_shader_load_config(struct gl_renderer *gr, struct weston_paint_node *pnode,
struct gl_shader *shader,
const struct gl_shader_config *sconf)
{
@ -853,6 +854,11 @@ gl_shader_load_config(struct gl_renderer *gr,
float swizzle_sub[4];
int i, j;
WESTON_TRACE_BEGIN_ANNOTATION();
if (pnode) {
WESTON_TRACE_ANNOTATE_ADD_STR("paint node", pnode->internal_name);
}
glUniformMatrix4fv(shader->proj_uniform,
1, GL_FALSE, sconf->projection.M.colmaj);
@ -865,6 +871,10 @@ gl_shader_load_config(struct gl_renderer *gr,
"\t\tcolor: r: %.2f, g: %.2f, b: %.2f, a: %.2f\n",
sconf->unicolor[0], sconf->unicolor[1],
sconf->unicolor[2], sconf->unicolor[3]);
WESTON_TRACE_ANNOTATE_ADD_FLOAT("color r", sconf->unicolor[0]);
WESTON_TRACE_ANNOTATE_ADD_FLOAT("color g", sconf->unicolor[1]);
WESTON_TRACE_ANNOTATE_ADD_FLOAT("color b", sconf->unicolor[2]);
WESTON_TRACE_ANNOTATE_ADD_FLOAT("color a", sconf->unicolor[3]);
glUniform4fv(shader->color_uniform, 1, sconf->unicolor);
}
if (shader->tint_uniform != -1) {
@ -872,10 +882,15 @@ gl_shader_load_config(struct gl_renderer *gr,
"\t\ttint: r: %.2f, g: %.2f, b: %.2f, a: %.2f\n",
sconf->tint[0], sconf->tint[1],
sconf->tint[2], sconf->tint[3]);
WESTON_TRACE_ANNOTATE_ADD_FLOAT("tint r", sconf->tint[0]);
WESTON_TRACE_ANNOTATE_ADD_FLOAT("tint g", sconf->tint[1]);
WESTON_TRACE_ANNOTATE_ADD_FLOAT("tint b", sconf->tint[2]);
WESTON_TRACE_ANNOTATE_ADD_FLOAT("tint a", sconf->tint[3]);
glUniform4fv(shader->tint_uniform, 1, sconf->tint);
}
weston_log_scope_printf(gr->paint_node_scope, "\t\talpha: %.2f\n", sconf->view_alpha);
WESTON_TRACE_ANNOTATE_ADD_FLOAT("alpha", sconf->view_alpha);
glUniform1f(shader->view_alpha_uniform, sconf->view_alpha);
assert(sconf->input_num <= SHADER_INPUT_TEX_MAX);
@ -920,9 +935,11 @@ gl_shader_load_config(struct gl_renderer *gr,
break;
case SHADER_COLOR_EFFECT_INVERSION:
weston_log_scope_printf(gr->paint_node_scope, "\t\tcolor effect: inversion\n");
WESTON_TRACE_ANNOTATE_ADD_STR("color effect", "inversion");
break;
case SHADER_COLOR_EFFECT_GRAYSCALE:
weston_log_scope_printf(gr->paint_node_scope, "\t\tcolor effect: grayscale\n");
WESTON_TRACE_ANNOTATE_ADD_STR("color effect", "greyscale");
break;
case SHADER_COLOR_EFFECT_CVD_CORRECTION:
weston_assert_int_ne(gr->compositor, shader->cvd_correction_uniform, -1);
@ -931,6 +948,8 @@ gl_shader_load_config(struct gl_renderer *gr,
glUniformMatrix3fv(shader->cvd_correction_uniform,
1, GL_FALSE,
sconf->color_effect.cvd.correction.colmaj);
WESTON_TRACE_ANNOTATE_ADD_STR("color effect",
weston_output_cvd_type_to_str(sconf->color_effect.cvd));
break;
}
@ -958,11 +977,17 @@ gl_shader_load_config(struct gl_renderer *gr,
TEX_UNIT_FB_STORE_CURVE);
}
if (pnode) {
WESTON_TRACE_COMMIT_ANNOTATION(&pnode->flow_id);
} else {
WESTON_TRACE_COMMIT_ANNOTATION(NULL);
}
glActiveTexture(GL_TEXTURE0);
}
bool
gl_renderer_use_program(struct gl_renderer *gr,
gl_renderer_use_program(struct gl_renderer *gr, struct weston_paint_node *pnode,
const struct gl_shader_config *sconf)
{
static const GLfloat fallback_shader_color[4] = { 0.2, 0.1, 0.0, 1.0 };
@ -1004,7 +1029,7 @@ gl_renderer_use_program(struct gl_renderer *gr,
weston_log_scope_printf(gr->paint_node_scope,
"\t\t\tshader id: %d\n", gr->current_shader->program);
gl_shader_load_config(gr, shader, sconf);
gl_shader_load_config(gr, pnode, shader, sconf);
return true;
}

View file

@ -200,11 +200,20 @@ weston_surface_attach(struct weston_surface *surface,
struct weston_surface_state *state,
enum weston_surface_status status)
{
WESTON_TRACE_FUNC_FLOW(&surface->flow_id);
struct weston_buffer *buffer = state->buffer_ref.buffer;
struct weston_buffer *old_buffer = surface->buffer_ref.buffer;
enum weston_paint_node_status pnode_changes = WESTON_PAINT_NODE_CLEAN;
WESTON_TRACE_BEGIN_ANNOTATION();
if (buffer) {
WESTON_TRACE_ANNOTATE_ADD_STR("surface", surface->internal_name);
WESTON_TRACE_ANNOTATE_ADD_STR("format", buffer->pixel_format->drm_format_name);
WESTON_TRACE_ANNOTATE_ADD_STR("modifier", buffer->format_modifier_name);
WESTON_TRACE_ANNOTATE_ADD_INT("width", buffer->width);
WESTON_TRACE_ANNOTATE_ADD_INT("height", buffer->height);
}
WESTON_TRACE_ANNOTATE_FUNC_FLOW(&surface->flow_id);
if (!buffer) {
if (weston_surface_is_mapped(surface)) {
weston_surface_unmap(surface);

View file

@ -11,6 +11,7 @@
#define WESTON_TRACE_H
#include "perfetto/u_perfetto.h"
#include <string.h>
#if defined(HAVE_PERFETTO)
@ -28,6 +29,9 @@
# endif
#endif
/* maximum allowed debug annotations */
#define WESTON_MAX_DEBUG_ANNOTS 128
/* note that util_perfetto_is_tracing_enabled always returns false until
* util_perfetto_init is called
*/
@ -69,6 +73,53 @@
clock, timestamp); \
} while (0)
#define _WESTON_TRACE_BEGIN_ANNOTATION() \
struct weston_debug_annotation __pd_annots[WESTON_MAX_DEBUG_ANNOTS]; \
unsigned int __pd_i = 0
#define _WESTON_TRACE_ANNOTATE_ADD_INT(k, v) \
weston_assert_u32_gt(NULL, WESTON_MAX_DEBUG_ANNOTS, __pd_i); \
__pd_annots[__pd_i].type = WESTON_DEBUG_ANNOTATION_INT_VAL; \
__pd_annots[__pd_i].ivalue = v; \
__pd_annots[__pd_i].key = k; \
__pd_i++
#define _WESTON_TRACE_ANNOTATE_ADD_FLOAT(k, v) \
weston_assert_u32_gt(NULL, WESTON_MAX_DEBUG_ANNOTS, __pd_i); \
__pd_annots[__pd_i].type = WESTON_DEBUG_ANNOTATION_FLOAT_VAL; \
__pd_annots[__pd_i].fvalue = v; \
__pd_annots[__pd_i].key = k; \
__pd_i++
#define _WESTON_TRACE_ANNOTATE_ADD_STR(k, v) \
weston_assert_u32_gt(NULL, WESTON_MAX_DEBUG_ANNOTS, __pd_i); \
__pd_annots[__pd_i].type = WESTON_DEBUG_ANNOTATION_STR_VAL; \
__pd_annots[__pd_i].svalue = v; \
__pd_annots[__pd_i].key = k; \
__pd_i++
#define _WESTON_TRACE_COMMIT_ANNOTATION(id, name) \
do { \
if (unlikely(util_perfetto_is_tracing_enabled())) { \
_weston_trace_scope_annotate_commit(id, name, &__pd_i, __pd_annots); \
} \
} while (0)
/* annotated funcs */
#define _WESTON_TRACE_ANNOTATE_FUNC_BEGIN(name, nr_entries, annots) \
do { \
if (unlikely(util_perfetto_is_tracing_enabled())) { \
util_perfetto_trace_commit_annotate_func(name, *nr_entries, annots); \
} \
} while (0)
#define _WESTON_TRACE_ANNOTATE_FUNC_BEGIN_FLOW(name, id, nr_entries, annots) \
do { \
if (unlikely(util_perfetto_is_tracing_enabled())) { \
util_perfetto_trace_commit_annotate_func_flow(id, name, *nr_entries, annots); \
} \
} while (0)
#if __has_attribute(cleanup) && __has_attribute(unused)
#define _WESTON_TRACE_SCOPE_VAR_CONCAT(name, suffix) name##suffix
@ -92,6 +143,16 @@
__attribute__((cleanup(_weston_trace_scope_end), unused)) = \
_weston_trace_scope_flow_begin(name, id)
#define _WESTON_TRACE_ANNOTATE_FUNC(name) \
int _WESTON_TRACE_SCOPE_VAR(__LINE__) \
__attribute__((cleanup(_weston_trace_scope_end), unused)) = \
_weston_trace_annotate_func_begin(name, &__pd_i, __pd_annots)
#define _WESTON_TRACE_ANNOTATE_FUNC_FLOW(id, name) \
int _WESTON_TRACE_SCOPE_VAR(__LINE__) \
__attribute__((cleanup(_weston_trace_scope_end), unused)) = \
_weston_trace_annotate_func_begin_flow(name, id, &__pd_i, __pd_annots)
static inline int
_weston_trace_scope_begin(const char *name)
{
@ -108,6 +169,53 @@ _weston_trace_scope_flow_begin(const char *name, uint64_t *id)
return 0;
}
static inline void
_weston_trace_scope_annotate_commit(uint64_t *id, const char *name,
unsigned int *nr_entries,
struct weston_debug_annotation *annots)
{
if (id && *id == 0) {
*id = util_perfetto_next_id();
util_perfetto_trace_commit_debug_annots(*id, name, *nr_entries, annots);
goto reset_entries;
}
util_perfetto_trace_commit_debug_annots(0, name, *nr_entries, annots);
/* reset the array and counter */
reset_entries:
memset(annots, 0, sizeof(struct weston_debug_annotation) * *nr_entries);
*nr_entries = 0;
}
static inline int
_weston_trace_annotate_func_begin(const char *name, unsigned int *nr_entries,
struct weston_debug_annotation *annots)
{
_WESTON_TRACE_ANNOTATE_FUNC_BEGIN(name, nr_entries, annots);
/* reset the array and counter */
memset(annots, 0, sizeof(struct weston_debug_annotation) * *nr_entries);
*nr_entries = 0;
return 0;
}
static inline int
_weston_trace_annotate_func_begin_flow(const char *name, uint64_t *id,
unsigned int *nr_entries,
struct weston_debug_annotation *annots)
{
if (*id == 0)
*id = util_perfetto_next_id();
_WESTON_TRACE_ANNOTATE_FUNC_BEGIN_FLOW(name, *id, nr_entries, annots);
/* reset the array and counter */
memset(annots, 0, sizeof(struct weston_debug_annotation) * *nr_entries);
*nr_entries = 0;
return 0;
}
static inline void
_weston_trace_scope_end(int *scope)
{
@ -130,6 +238,14 @@ _weston_trace_scope_end(int *scope)
#define _WESTON_TRACE_TIMESTAMP_BEGIN(name, track_id, flow_id, clock, timestamp)
#define _WESTON_TRACE_TIMESTAMP_END(name, track_id, clock, timestamp)
#define _WESTON_TRACE_BEGIN_ANNOTATION()
#define _WESTON_TRACE_COMMIT_ANNOTATION(id, name)
#define _WESTON_TRACE_ANNOTATE_ADD_INT(k, v)
#define _WESTON_TRACE_ANNOTATE_ADD_FLOAT(k, v)
#define _WESTON_TRACE_ANNOTATE_ADD_STR(k, v)
#define _WESTON_TRACE_ANNOTATE_FUNC()
#define _WESTON_TRACE_ANNOTATE_FUNC_FLOW(id, name)
#endif /* HAVE_PERFETTO */
#define WESTON_TRACE_SCOPE(name) _WESTON_TRACE_SCOPE(name)
@ -142,4 +258,25 @@ _weston_trace_scope_end(int *scope)
#define WESTON_TRACE_TIMESTAMP_END(name, track_id, clock, timestamp) \
_WESTON_TRACE_TIMESTAMP_END(name, track_id, clock, timestamp)
#define WESTON_TRACE_BEGIN_ANNOTATION() \
_WESTON_TRACE_BEGIN_ANNOTATION()
#define WESTON_TRACE_ANNOTATE_ADD_INT(k, v) \
_WESTON_TRACE_ANNOTATE_ADD_INT(k, v)
#define WESTON_TRACE_ANNOTATE_ADD_FLOAT(k, v) \
_WESTON_TRACE_ANNOTATE_ADD_FLOAT(k, v)
#define WESTON_TRACE_ANNOTATE_ADD_STR(k, v) \
_WESTON_TRACE_ANNOTATE_ADD_STR(k, v)
#define WESTON_TRACE_COMMIT_ANNOTATION(id) \
_WESTON_TRACE_COMMIT_ANNOTATION(id, __func__)
#define WESTON_TRACE_ANNOTATE_FUNC() \
_WESTON_TRACE_ANNOTATE_FUNC(__func__)
#define WESTON_TRACE_ANNOTATE_FUNC_FLOW(id) \
_WESTON_TRACE_ANNOTATE_FUNC_FLOW(id, __func__)
#endif /* WESTON_TRACE_H */