From 71078b404483ce638f766ab82646189e57eabb41 Mon Sep 17 00:00:00 2001 From: Harish Krupo Date: Thu, 18 Apr 2019 21:45:48 +0530 Subject: [PATCH] gl-renderer: Add debug scope for shader generator This helps accounting how many shaders live in the cache, what the shader source code is, and when shaders are compiled. Signed-off-by: Harish Krupo v2: Resolved rebase conflicts. Put shader_scope in struct gl_renderer, remove struct gl_shader_generator. Wrote commit message. Rebased for "gl-renderer: rewrite fragment shaders" which completely changed how shader sources are generated. Added cache statistics to debug output on subscribe. Signed-off-by: Pekka Paalanen --- libweston/renderer-gl/gl-renderer-internal.h | 5 ++ libweston/renderer-gl/gl-renderer.c | 6 ++ libweston/renderer-gl/gl-shaders.c | 70 +++++++++++++++++++- 3 files changed, 80 insertions(+), 1 deletion(-) diff --git a/libweston/renderer-gl/gl-renderer-internal.h b/libweston/renderer-gl/gl-renderer-internal.h index 9404d8e6..1795a2f2 100644 --- a/libweston/renderer-gl/gl-renderer-internal.h +++ b/libweston/renderer-gl/gl-renderer-internal.h @@ -159,6 +159,7 @@ struct gl_renderer { * List constains cached shaders built from struct gl_shader_requirements */ struct wl_list shader_list; + struct weston_log_scope *shader_scope; }; static inline struct gl_renderer * @@ -202,4 +203,8 @@ int gl_shader_requirements_cmp(const struct gl_shader_requirements *a, const struct gl_shader_requirements *b); +struct weston_log_scope * +gl_shader_scope_create(struct weston_compositor *compositor, + struct gl_renderer *gr); + #endif /* GL_RENDERER_INTERNAL_H */ diff --git a/libweston/renderer-gl/gl-renderer.c b/libweston/renderer-gl/gl-renderer.c index 0ef6552c..e56dadda 100644 --- a/libweston/renderer-gl/gl-renderer.c +++ b/libweston/renderer-gl/gl-renderer.c @@ -3340,6 +3340,7 @@ gl_renderer_destroy(struct weston_compositor *ec) if (gr->fan_binding) weston_binding_destroy(gr->fan_binding); + weston_log_scope_destroy(gr->shader_scope); free(gr); } @@ -3402,6 +3403,10 @@ gl_renderer_display_create(struct weston_compositor *ec, wl_list_init(&gr->shader_list); gr->platform = options->egl_platform; + gr->shader_scope = gl_shader_scope_create(ec, gr); + if (!gr->shader_scope) + goto fail; + if (gl_renderer_setup_egl_client_extensions(gr) < 0) goto fail; @@ -3490,6 +3495,7 @@ fail_with_error: fail_terminate: eglTerminate(gr->egl_display); fail: + weston_log_scope_destroy(gr->shader_scope); free(gr); ec->renderer = NULL; return -1; diff --git a/libweston/renderer-gl/gl-shaders.c b/libweston/renderer-gl/gl-shaders.c index 86490fba..91ee307c 100644 --- a/libweston/renderer-gl/gl-shaders.c +++ b/libweston/renderer-gl/gl-shaders.c @@ -34,6 +34,7 @@ #include #include +#include #include #include @@ -113,7 +114,7 @@ gl_shader_destroy(struct gl_shader *shader) free(shader); } -static int +static GLuint compile_shader(GLenum type, int count, const char **sources) { GLuint s; @@ -135,6 +136,20 @@ compile_shader(GLenum type, int count, const char **sources) return s; } +static char * +create_shader_description_string(const struct gl_shader_requirements *req) +{ + int size; + char *str; + + size = asprintf(&str, "%s %cgreen", + gl_shader_texture_variant_to_string(req->variant), + req->green_tint ? '+' : '-'); + if (size < 0) + return NULL; + return str; +} + static char * create_shader_config_string(const struct gl_shader_requirements *req) { @@ -155,6 +170,7 @@ struct gl_shader * gl_shader_create(struct gl_renderer *gr, const struct gl_shader_requirements *requirements) { + bool verbose = weston_log_scope_is_enabled(gr->shader_scope); struct gl_shader *shader = NULL; char msg[512]; GLint status; @@ -170,6 +186,16 @@ gl_shader_create(struct gl_renderer *gr, wl_list_init(&shader->link); shader->key = *requirements; + if (verbose) { + char *desc; + + desc = create_shader_description_string(requirements); + weston_log_scope_printf(gr->shader_scope, + "Compiling shader program for: %s\n", + desc); + free(desc); + } + sources[0] = vertex_shader; shader->vertex_shader = compile_shader(GL_VERTEX_SHADER, 1, sources); if (shader->vertex_shader == GL_NONE) @@ -236,3 +262,45 @@ gl_shader_requirements_cmp(const struct gl_shader_requirements *a, { return memcmp(a, b, sizeof(*a)); } + +static void +gl_shader_scope_new_subscription(struct weston_log_subscription *subs, + void *data) +{ + static const char bar[] = "-----------------------------------------------------------------------------"; + struct gl_renderer *gr = data; + struct gl_shader *shader; + int count = 0; + char *desc; + + weston_log_subscription_printf(subs, + "Vertex shader body:\n" + "%s\n%s\n" + "Fragment shader body:\n" + "%s\n%s\n%s\n", + bar, vertex_shader, + bar, fragment_shader, bar); + + weston_log_subscription_printf(subs, "Cached GLSL programs:\n"); + wl_list_for_each(shader, &gr->shader_list, link) { + count++; + desc = create_shader_description_string(&shader->key); + weston_log_subscription_printf(subs, + "%6u: %s\n", + shader->program, desc); + } + weston_log_subscription_printf(subs, "Total: %d programs.\n", count); +} + +struct weston_log_scope * +gl_shader_scope_create(struct weston_compositor *compositor, + struct gl_renderer *gr) +{ + + return weston_compositor_add_log_scope(compositor, + "gl-shader-generator", + "GL renderer shader compilation and cache.\n", + gl_shader_scope_new_subscription, + NULL, + gr); +}