diff --git a/libweston/perfetto/u_perfetto.cc b/libweston/perfetto/u_perfetto.cc index 9d0a2eb99..b7a96fd2a 100644 --- a/libweston/perfetto/u_perfetto.cc +++ b/libweston/perfetto/u_perfetto.cc @@ -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); } diff --git a/libweston/perfetto/u_perfetto.h b/libweston/perfetto/u_perfetto.h index 576348fce..4c84b7250 100644 --- a/libweston/perfetto/u_perfetto.h +++ b/libweston/perfetto/u_perfetto.h @@ -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) { } diff --git a/libweston/renderer-gl/gl-renderer-internal.h b/libweston/renderer-gl/gl-renderer-internal.h index a15574f05..87bd70132 100644 --- a/libweston/renderer-gl/gl-renderer-internal.h +++ b/libweston/renderer-gl/gl-renderer-internal.h @@ -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 * diff --git a/libweston/renderer-gl/gl-renderer.c b/libweston/renderer-gl/gl-renderer.c index 50bc4c142..5eb45f6cd 100644 --- a/libweston/renderer-gl/gl-renderer.c +++ b/libweston/renderer-gl/gl-renderer.c @@ -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); diff --git a/libweston/renderer-gl/gl-shaders.c b/libweston/renderer-gl/gl-shaders.c index 02ba41c7d..8861a69b4 100644 --- a/libweston/renderer-gl/gl-shaders.c +++ b/libweston/renderer-gl/gl-shaders.c @@ -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; } diff --git a/libweston/surface-state.c b/libweston/surface-state.c index 59643dc76..1513655d4 100644 --- a/libweston/surface-state.c +++ b/libweston/surface-state.c @@ -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); diff --git a/libweston/weston-trace.h b/libweston/weston-trace.h index 154663157..b2ba55492 100644 --- a/libweston/weston-trace.h +++ b/libweston/weston-trace.h @@ -11,6 +11,7 @@ #define WESTON_TRACE_H #include "perfetto/u_perfetto.h" +#include #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 */