[PATCH] Add weston profile plugin.

ning.tang at intel.com ning.tang at intel.com
Mon Dec 3 18:48:47 PST 2012


From: Ning Tang <ning.tang at intel.com>

This plugin is used to record some key time points.
You can use option --enable-weston-profile to enable it.
The recorded time point information would be printed to stdout
and FPS information would be shown in stderr.
The output format would be:
Time point name		time(millisecond)	sequence/id number

Key time points recorded are:
1. when client received input event such as motion and button.
2. when client has already handled input event.
3. when client commit surface.
4. when server received and handled client's commit.
5. when compositor start drm repaint.
6. when page flip done.

Also, drm repaint and page flip done are corresponding so add a
sequence number for better reading. And surface commit has an object id
to identify which surface committed.

Signed-off-by: Ning Tang <ning.tang at intel.com>
---
 clients/Makefile.am     |  5 +++
 clients/window.c        | 16 ++++++++++
 configure.ac            |  7 +++++
 shared/Makefile.am      |  4 ++-
 shared/weston_profile.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++
 shared/weston_profile.h | 13 ++++++++
 src/Makefile.am         |  7 +++++
 src/compositor-drm.c    | 11 +++++++
 src/compositor.c        |  7 +++++
 src/compositor.h        |  1 +
 src/gl-renderer.c       |  9 ++++++
 11 files changed, 160 insertions(+), 1 deletion(-)
 create mode 100644 shared/weston_profile.c
 create mode 100644 shared/weston_profile.h

diff --git a/clients/Makefile.am b/clients/Makefile.am
index 5034aa6..f407d9e 100644
--- a/clients/Makefile.am
+++ b/clients/Makefile.am
@@ -88,6 +88,11 @@ toolkit_libs =						\
 	../shared/libshared-cairo.la			\
 	$(CLIENT_LIBS) $(CAIRO_EGL_LIBS) -lrt -lm
 
+if ENABLE_WESTON_PROFILE
+libtoytoolkit_a_CFLAGS = -D WESTON_PROFILE
+toolkit_libs += ../shared/libshared.la
+endif
+
 flower_SOURCES = flower.c
 flower_LDADD = $(toolkit_libs)
 
diff --git a/clients/window.c b/clients/window.c
index 20d09d5..133bfa9 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -74,6 +74,12 @@ typedef void *EGLContext;
 
 #include "window.h"
 
+#ifdef WESTON_PROFILE
+#include <wayland-util.h>
+#include <wayland-server.h>
+#include "../shared/weston_profile.h"
+#endif
+
 struct shm_pool;
 
 struct global {
@@ -439,6 +445,10 @@ egl_window_surface_swap(struct toysurface *base,
 	wl_egl_window_get_attached_size(surface->egl_window,
 					&server_allocation->width,
 					&server_allocation->height);
+#ifdef WESTON_PROFILE
+	client_surface_commit(
+		((struct wl_resource *)surface->surface)->object.id);
+#endif
 }
 
 static int
@@ -2390,6 +2400,9 @@ pointer_handle_motion(void *data, struct wl_pointer *pointer,
 	else
 		cursor = input->focus_widget->default_cursor;
 
+#ifdef WESTON_PROFILE
+	client_receive_motion(time);
+#endif
 	input_set_pointer_image(input, cursor);
 }
 
@@ -2416,6 +2429,9 @@ pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
 	if (input->grab && input->grab_button == button &&
 	    state == WL_POINTER_BUTTON_STATE_RELEASED)
 		input_ungrab(input);
+#ifdef WESTON_PROFILE
+	client_receive_button(time);
+#endif
 }
 
 static void
diff --git a/configure.ac b/configure.ac
index 8cff8dc..959aa1c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -235,6 +235,13 @@ AM_CONDITIONAL(BUILD_FULL_GL_CLIENTS,
 
 AM_CONDITIONAL(ENABLE_DESKTOP_SHELL, true)
 
+AC_ARG_ENABLE(weston_profile,
+	      AS_HELP_STRING([--enable-weston-profile],
+			     [print profile information on weston side]),
+	      enable_weston_profile=yes,)
+AM_CONDITIONAL(ENABLE_WESTON_PROFILE,
+	       test "x$enable_weston_profile" = "xyes")
+
 AC_ARG_ENABLE(tablet-shell,
               AS_HELP_STRING([--disable-tablet-shell],
                              [do not build tablet-shell server plugin and client]),,
diff --git a/shared/Makefile.am b/shared/Makefile.am
index b38cb95..54ef322 100644
--- a/shared/Makefile.am
+++ b/shared/Makefile.am
@@ -7,7 +7,9 @@ libshared_la_SOURCES =				\
 	option-parser.c				\
 	config-parser.h				\
 	os-compatibility.c			\
-	os-compatibility.h
+	os-compatibility.h			\
+	weston_profile.c			\
+	weston_profile.h
 
 libshared_cairo_la_CFLAGS =			\
 	$(GCC_CFLAGS)				\
diff --git a/shared/weston_profile.c b/shared/weston_profile.c
new file mode 100644
index 0000000..200bccf
--- /dev/null
+++ b/shared/weston_profile.c
@@ -0,0 +1,81 @@
+#include <stdio.h>
+#include "weston_profile.h"
+
+uint32_t drm_seq = 0;
+int weston_frames = 0;
+uint32_t weston_last_fps = 0;
+
+uint32_t get_time(void)
+{
+	struct timeval tv;
+
+	gettimeofday(&tv, NULL);
+
+	return tv.tv_sec * 1000 + tv.tv_usec / 1000;
+}
+
+void compositor_fps_update()
+{
+	uint32_t time = get_time();
+	long diff_ms;
+
+	weston_frames++;
+
+	diff_ms = time - weston_last_fps;
+
+	if (diff_ms > 200) {
+		float seconds = diff_ms / 1000.0;
+		float fps = weston_frames / seconds;
+
+		fprintf(stderr,
+			"compositor: %d frames in %6.3f seconds = %6.3f FPS\n",
+			weston_frames, seconds, fps);
+
+		weston_frames = 0;
+		weston_last_fps = time;
+	}
+}
+
+void client_receive_motion(uint32_t time)
+{
+	uint32_t time_now = get_time();
+	fprintf(stdout, "motion happened:\t\t%u\n", time);
+	fprintf(stdout, "client receive motion:\t\t%u\n", time_now);
+	fflush(stdout);
+}
+
+void client_receive_button(uint32_t time)
+{
+	uint32_t time_now = get_time();
+	fprintf(stdout, "button happened:\t\t%u\n", time);
+	fprintf(stdout, "client receive button:\t\t%u\n", time_now);
+	fflush(stdout);
+}
+
+void client_surface_commit(uint32_t id)
+{
+	uint32_t time = get_time();
+	fprintf(stdout, "client commit\t\t\t%u\t%u\n", time, id);
+	fflush(stdout);
+}
+
+void server_handle_surface_commit(uint32_t id)
+{
+	uint32_t time = get_time();
+	fprintf(stdout, "server receive commit\t\t%u\t%u\n", time, id);
+	fflush(stdout);
+}
+
+void drm_repaint_record()
+{
+	uint32_t time = get_time();
+	fprintf(stdout, "drm repaint\t\t\t%u\t%u\n", time, drm_seq);
+	fflush(stdout);
+}
+
+void page_flip_done()
+{
+	uint32_t time = get_time();
+	fprintf(stdout, "page flip done\t\t\t%u\t%u\n", time, drm_seq++);
+	fflush(stdout);
+}
diff --git a/shared/weston_profile.h b/shared/weston_profile.h
new file mode 100644
index 0000000..de0db03
--- /dev/null
+++ b/shared/weston_profile.h
@@ -0,0 +1,13 @@
+#include <stdint.h>
+#include <time.h>
+#include <sys/time.h>
+
+uint32_t get_time(void);
+void compositor_fps_update(void);
+
+void client_receive_motion(uint32_t time);
+void client_receive_button(uint32_t time);
+void client_surface_commit(uint32_t id);
+void server_handle_surface_commit(uint32_t id);
+void drm_repaint_record(void);
+void page_flip_done(void);
diff --git a/src/Makefile.am b/src/Makefile.am
index e8315ca..4c70a1e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -10,6 +10,10 @@ weston_LDFLAGS = -export-dynamic
 weston_CFLAGS = $(GCC_CFLAGS) $(COMPOSITOR_CFLAGS)
 weston_LDADD = $(COMPOSITOR_LIBS) $(DLOPEN_LIBS) -lm ../shared/libshared.la
 
+if ENABLE_WESTON_PROFILE
+weston_CFLAGS += -D WESTON_PROFILE
+endif
+
 weston_SOURCES =				\
 	git-version.h				\
 	log.c					\
@@ -122,6 +126,9 @@ drm_backend_la_SOURCES =			\
 	launcher-util.h				\
 	libbacklight.c				\
 	libbacklight.h
+if ENABLE_WESTON_PROFILE
+drm_backend_la_CFLAGS += -D WESTON_PROFILE
+endif
 endif
 
 if ENABLE_WAYLAND_COMPOSITOR
diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 24a71f1..b2bbea7 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -43,6 +43,9 @@
 #include "gl-renderer.h"
 #include "evdev.h"
 #include "launcher-util.h"
+#ifdef WESTON_PROFILE
+#include "../shared/weston_profile.h"
+#endif
 
 static int option_current_mode = 0;
 static char *output_name;
@@ -382,6 +385,8 @@ drm_output_render(struct drm_output *output, pixman_region32_t *damage)
 	struct gbm_bo *bo;
 
 	c->base.renderer->repaint_output(&output->base, damage);
+	if (c->base.renderer->compositor_fps_update != NULL)
+		c->base.renderer->compositor_fps_update();
 
 	pixman_region32_subtract(&c->base.primary_plane.damage,
 				 &c->base.primary_plane.damage, damage);
@@ -411,6 +416,9 @@ drm_output_repaint(struct weston_output *output_base,
 	struct drm_mode *mode;
 	int ret = 0;
 
+#ifdef WESTON_PROFILE
+	drm_repaint_record();
+#endif
 	if (!output->next)
 		drm_output_render(output, damage);
 	if (!output->next)
@@ -516,6 +524,9 @@ page_flip_handler(int fd, unsigned int frame,
 	struct drm_output *output = (struct drm_output *) data;
 	uint32_t msecs;
 
+#ifdef WESTON_PROFILE
+	page_flip_done();
+#endif
 	output->page_flip_pending = 0;
 
 	if (output->current) {
diff --git a/src/compositor.c b/src/compositor.c
index 565212d..2b9c3a5 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -53,6 +53,10 @@
 #include "compositor.h"
 #include "../shared/os-compatibility.h"
 #include "git-version.h"
+#ifdef WESTON_PROFILE
+#include "../shared/weston_profile.h"
+#include <wayland-util.h>
+#endif
 
 static struct wl_list child_process_list;
 static struct weston_compositor *segv_compositor;
@@ -1423,6 +1427,9 @@ surface_commit(struct wl_client *client, struct wl_resource *resource)
 			    &surface->pending.frame_callback_list);
 	wl_list_init(&surface->pending.frame_callback_list);
 
+#ifdef WESTON_PROFILE
+	server_handle_surface_commit(resource->object.id);
+#endif
 	weston_surface_schedule_repaint(surface);
 }
 
diff --git a/src/compositor.h b/src/compositor.h
index 2547da1..44d0c19 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -273,6 +273,7 @@ struct weston_renderer {
 			       float red, float green,
 			       float blue, float alpha);
 	void (*destroy_surface)(struct weston_surface *surface);
+	void (*compositor_fps_update)(void);
 };
 
 struct weston_compositor {
diff --git a/src/gl-renderer.c b/src/gl-renderer.c
index d459c21..17d7b6c 100644
--- a/src/gl-renderer.c
+++ b/src/gl-renderer.c
@@ -37,6 +37,10 @@
 #include <EGL/eglext.h>
 #include "weston-egl-ext.h"
 
+#ifdef WESTON_PROFILE
+#include "../shared/weston_profile.h"
+#endif
+
 struct gl_shader {
 	GLuint program;
 	GLuint vertex_shader, fragment_shader;
@@ -1724,6 +1728,11 @@ gl_renderer_create(struct weston_compositor *ec, EGLNativeDisplayType display,
 	gr->base.create_surface = gl_renderer_create_surface;
 	gr->base.surface_set_color = gl_renderer_surface_set_color;
 	gr->base.destroy_surface = gl_renderer_destroy_surface;
+#ifdef WESTON_PROFILE
+	gr->base.compositor_fps_update = compositor_fps_update;
+#else
+	gr->base.compositor_fps_update = NULL;
+#endif
 
 	gr->egl_display = eglGetDisplay(display);
 	if (gr->egl_display == EGL_NO_DISPLAY) {
-- 
1.8.0.1



More information about the wayland-devel mailing list