[weston,5/5] compositor: triangle fan debug

Message ID 1346363241-29219-6-git-send-email-rob.clark@linaro.org
State New
Headers show

Commit Message

Rob Clark Aug. 30, 2012, 9:47 p.m.
From: Pekka Paalanen <ppaalanen@gmail.com>

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 |    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(-)

Patch

diff --git a/src/compositor-android.c b/src/compositor-android.c
index a9c45d2..a8dec31 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 00b7502..00656dd 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -326,7 +326,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;
@@ -344,6 +344,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);
@@ -363,7 +366,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 =
@@ -373,9 +376,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 131fa32..f62eb92 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 c02911d..bf00d6f 100644
--- a/src/compositor-x11.c
+++ b/src/compositor-x11.c
@@ -320,7 +320,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 =
@@ -337,6 +337,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 e9fa56e..05315ed 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;
 
@@ -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];
 	}
 
@@ -1560,7 +1604,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 74b154a..b826862 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -176,7 +176,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);
@@ -321,6 +321,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 4d6bc4f..e5a6ab3 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -3267,6 +3267,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)
@@ -3401,6 +3412,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,