From 07c91f8371aba6002a2211834f770bbb3c0abff3 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Thu, 30 Aug 2012 16:47:21 -0500 Subject: [PATCH] compositor: triangle fan debug Draw the borders of all the triangles. v1: original v2: add keybinding to enable/disable fan debug (super-alt-space), cycle colors to make it easier to see individual draws, and redraw undamaged region to clean up previous frames debug lines Signed-off-by: Rob Clark --- src/compositor-android.c | 6 +++- src/compositor-drm.c | 11 ++++++-- src/compositor-wayland.c | 5 +++- src/compositor-x11.c | 5 +++- src/compositor.c | 60 +++++++++++++++++++++++++++++++++++++++- src/compositor.h | 3 +- src/shell.c | 13 +++++++++ 7 files changed, 95 insertions(+), 8 deletions(-) diff --git a/src/compositor-android.c b/src/compositor-android.c index b0952621..bfa2e955 100644 --- a/src/compositor-android.c +++ b/src/compositor-android.c @@ -146,7 +146,8 @@ android_finish_frame(void *data) } static void -android_output_repaint(struct weston_output *base, pixman_region32_t *damage) +android_output_repaint(struct weston_output *base, pixman_region32_t *damage, + int flip) { struct android_output *output = to_android_output(base); struct android_compositor *compositor = output->compositor; @@ -161,6 +162,9 @@ android_output_repaint(struct weston_output *base, pixman_region32_t *damage) wl_list_for_each_reverse(surface, &compositor->base.surface_list, link) weston_surface_draw(surface, &output->base, damage); + if (!flip) + return; + wl_signal_emit(&output->base.frame_signal, output); ret = eglSwapBuffers(compositor->base.egl_display, output->egl_surface); diff --git a/src/compositor-drm.c b/src/compositor-drm.c index bcc9a0da..c6634a0b 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -322,7 +322,7 @@ drm_output_prepare_scanout_surface(struct weston_output *_output, } static void -drm_output_render(struct drm_output *output, pixman_region32_t *damage) +drm_output_render(struct drm_output *output, pixman_region32_t *damage, int flip) { struct drm_compositor *compositor = (struct drm_compositor *) output->base.compositor; @@ -340,6 +340,9 @@ drm_output_render(struct drm_output *output, pixman_region32_t *damage) if (surface->plane == &compositor->base.primary_plane) weston_surface_draw(surface, &output->base, damage); + if (!flip) + return; + wl_signal_emit(&output->base.frame_signal, output); eglSwapBuffers(compositor->base.egl_display, output->egl_surface); @@ -359,7 +362,7 @@ drm_output_render(struct drm_output *output, pixman_region32_t *damage) static void drm_output_repaint(struct weston_output *output_base, - pixman_region32_t *damage) + pixman_region32_t *damage, int flip) { struct drm_output *output = (struct drm_output *) output_base; struct drm_compositor *compositor = @@ -369,9 +372,11 @@ drm_output_repaint(struct weston_output *output_base, int ret = 0; if (!output->next) - drm_output_render(output, damage); + drm_output_render(output, damage, flip); if (!output->next) return; + if (!flip) + return; mode = container_of(output->base.current, struct drm_mode, base); if (!output->current) { diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c index 2f4d4a2c..1f45def9 100644 --- a/src/compositor-wayland.c +++ b/src/compositor-wayland.c @@ -330,7 +330,7 @@ static const struct wl_callback_listener frame_listener = { static void wayland_output_repaint(struct weston_output *output_base, - pixman_region32_t *damage) + pixman_region32_t *damage, int flip) { struct wayland_output *output = (struct wayland_output *) output_base; struct wayland_compositor *compositor = @@ -348,6 +348,9 @@ wayland_output_repaint(struct weston_output *output_base, wl_list_for_each_reverse(surface, &compositor->base.surface_list, link) weston_surface_draw(surface, &output->base, damage); + if (!flip) + return; + draw_border(output); wl_signal_emit(&output->base.frame_signal, output); diff --git a/src/compositor-x11.c b/src/compositor-x11.c index 5b1cdd99..d5fa0c66 100644 --- a/src/compositor-x11.c +++ b/src/compositor-x11.c @@ -322,7 +322,7 @@ x11_compositor_fini_egl(struct x11_compositor *compositor) static void x11_output_repaint(struct weston_output *output_base, - pixman_region32_t *damage) + pixman_region32_t *damage, int flip) { struct x11_output *output = (struct x11_output *)output_base; struct x11_compositor *compositor = @@ -339,6 +339,9 @@ x11_output_repaint(struct weston_output *output_base, wl_list_for_each_reverse(surface, &compositor->base.surface_list, link) weston_surface_draw(surface, &output->base, damage); + if (!flip) + return; + wl_signal_emit(&output->base.frame_signal, output); eglSwapBuffers(compositor->base.egl_display, output->egl_surface); diff --git a/src/compositor.c b/src/compositor.c index 52d81647..9ce44d49 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -55,6 +55,9 @@ #include "../shared/os-compatibility.h" #include "git-version.h" +#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0])) + + static struct wl_list child_process_list; static struct weston_compositor *segv_compositor; @@ -1235,6 +1238,45 @@ texture_region(struct weston_surface *es, pixman_region32_t *region, return nvtx; } +static void +triangle_fan_debug(struct weston_surface *surface, int first, int count) +{ + struct weston_compositor *compositor = surface->compositor; + int i; + GLushort *buffer; + GLushort *index; + int nelems; + static int color_idx = 0; + static const GLfloat color[][4] = { + { 1.0, 0.0, 0.0, 1.0 }, + { 0.0, 1.0, 0.0, 1.0 }, + { 0.0, 0.0, 1.0, 1.0 }, + { 1.0, 1.0, 1.0, 1.0 }, + }; + + nelems = (count - 1 + count - 2) * 2; + + buffer = malloc(sizeof(GLushort) * nelems); + index = buffer; + + for (i = 1; i < count; i++) { + *index++ = first; + *index++ = first + i; + } + + for (i = 2; i < count; i++) { + *index++ = first + i - 1; + *index++ = first + i; + } + + glUseProgram(compositor->solid_shader.program); + glUniform4fv(compositor->solid_shader.color_uniform, 1, + color[color_idx++ % ARRAY_SIZE(color)]); + glDrawElements(GL_LINES, nelems, GL_UNSIGNED_SHORT, buffer); + glUseProgram(surface->shader->program); + free(buffer); +} + static void repaint_region(struct weston_surface *es, pixman_region32_t *region, pixman_region32_t *surf_region) @@ -1267,6 +1309,8 @@ repaint_region(struct weston_surface *es, pixman_region32_t *region, for (i = 0, first = 0; i < nfans; i++) { glDrawArrays(GL_TRIANGLE_FAN, first, vtxcnt[i]); + if (ec->fan_debug) + triangle_fan_debug(es, first, vtxcnt[i]); first += vtxcnt[i]; } @@ -1561,7 +1605,21 @@ weston_output_repaint(struct weston_output *output, uint32_t msecs) if (output->dirty) weston_output_update_matrix(output); - output->repaint(output, &output_damage); + /* if debugging, redraw everything outside the damage to clean up + * debug lines from the previous draw on this buffer: + */ + if (ec->fan_debug) { + pixman_region32_t undamaged; + pixman_region32_init(&undamaged); + pixman_region32_subtract(&undamaged, &output->region, + &output_damage); + ec->fan_debug = 0; + output->repaint(output, &undamaged, 0); + ec->fan_debug = 1; + pixman_region32_fini(&undamaged); + } + + output->repaint(output, &output_damage, 1); pixman_region32_fini(&output_damage); diff --git a/src/compositor.h b/src/compositor.h index 4cdb9e46..96a04772 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -177,7 +177,7 @@ struct weston_output { struct wl_list mode_list; void (*repaint)(struct weston_output *output, - pixman_region32_t *damage); + pixman_region32_t *damage, int flip); void (*destroy)(struct weston_output *output); void (*assign_planes)(struct weston_output *output); int (*switch_mode)(struct weston_output *output, struct weston_mode *mode); @@ -322,6 +322,7 @@ struct weston_compositor { struct wl_array indices; /* only used in compositor-wayland */ struct wl_array vtxcnt; struct weston_plane primary_plane; + int fan_debug; uint32_t focus; diff --git a/src/shell.c b/src/shell.c index 2bd23fc6..45323c20 100644 --- a/src/shell.c +++ b/src/shell.c @@ -3266,6 +3266,17 @@ debug_repaint_binding(struct wl_seat *seat, uint32_t time, uint32_t key, } } + +static void +fan_debug_repaint_binding(struct wl_seat *seat, uint32_t time, uint32_t key, + void *data) +{ + struct desktop_shell *shell = data; + struct weston_compositor *compositor = shell->compositor; + compositor->fan_debug = !compositor->fan_debug; + weston_compositor_damage_all(compositor); +} + static void force_kill_binding(struct wl_seat *seat, uint32_t time, uint32_t key, void *data) @@ -3400,6 +3411,8 @@ shell_add_bindings(struct weston_compositor *ec, struct desktop_shell *shell) backlight_binding, ec); weston_compositor_add_key_binding(ec, KEY_SPACE, mod | MODIFIER_SHIFT, debug_repaint_binding, shell); + weston_compositor_add_key_binding(ec, KEY_SPACE, mod | MODIFIER_ALT, + fan_debug_repaint_binding, shell); weston_compositor_add_key_binding(ec, KEY_K, mod, force_kill_binding, shell); weston_compositor_add_key_binding(ec, KEY_UP, mod,