compositor: triangle fan debug
authorPekka Paalanen <ppaalanen@gmail.com>
Thu, 30 Aug 2012 21:47:21 +0000 (16:47 -0500)
committerKristian Høgsberg <krh@bitplanet.net>
Fri, 31 Aug 2012 21:52:01 +0000 (17:52 -0400)
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 <rob@ti.com>
src/compositor-android.c
src/compositor-drm.c
src/compositor-wayland.c
src/compositor-x11.c
src/compositor.c
src/compositor.h
src/shell.c

index b095262..bfa2e95 100644 (file)
@@ -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);
index bcc9a0d..c6634a0 100644 (file)
@@ -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) {
index 2f4d4a2..1f45def 100644 (file)
@@ -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);
index 5b1cdd9..d5fa0c6 100644 (file)
@@ -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);
index 52d8164..9ce44d4 100644 (file)
@@ -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;
 
@@ -1236,6 +1239,45 @@ texture_region(struct weston_surface *es, pixman_region32_t *region,
 }
 
 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);
 
index 4cdb9e4..96a0477 100644 (file)
@@ -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;
 
index 2bd23fc..45323c2 100644 (file)
@@ -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,