[weston v2 6/8] xwm: Ignore configure request while the user is resizing

2017-11-13 Thread Louis-Francis Ratté-Boulianne
We don't want the application to fight with the user when manually
resizing a window.

v2: Re-enable sync when a new resize operation is started

Signed-off-by: Louis-Francis Ratté-Boulianne 
---
 xwayland/window-manager.c | 20 +++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c
index a0ff6b62..1f3bcdac 100644
--- a/xwayland/window-manager.c
+++ b/xwayland/window-manager.c
@@ -173,6 +173,7 @@ struct weston_wm_window {
int delete_window;
int maximized_vert;
int maximized_horz;
+   int resizing;
int64_t sync_request_serial;
int configure_pending;
int sync_disabled;
@@ -701,6 +702,11 @@ weston_wm_handle_configure_request(struct weston_wm *wm, 
xcb_generic_event_t *ev
return;
}
 
+   if (window->frame && window->resizing) {
+   wm_log("Ignore configure request while resizing window\n");
+   return;
+   }
+
if (configure_request->value_mask & XCB_CONFIG_WINDOW_WIDTH)
window->width = configure_request->width;
if (configure_request->value_mask & XCB_CONFIG_WINDOW_HEIGHT)
@@ -1671,9 +1677,13 @@ weston_wm_window_handle_moveresize(struct 
weston_wm_window *window,
case _NET_WM_MOVERESIZE_SIZE_BOTTOM:
case _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT:
case _NET_WM_MOVERESIZE_SIZE_LEFT:
+   if (!window->resizing)
+   window->sync_disabled = 0;
+   window->resizing = 1;
xwayland_interface->resize(window->shsurf, pointer, 
map[detail]);
break;
case _NET_WM_MOVERESIZE_CANCEL:
+   window->resizing = 0;
break;
}
 }
@@ -2106,6 +2116,10 @@ weston_wm_handle_button(struct weston_wm *wm, 
xcb_generic_event_t *event)
WL_POINTER_BUTTON_STATE_RELEASED;
button_id = button->detail == 1 ? BTN_LEFT : BTN_RIGHT;
 
+   if (window->resizing && button_id == BTN_LEFT &&
+   button_state == WL_POINTER_BUTTON_STATE_PRESSED)
+   window->resizing = 0;
+
if (button_state == WL_POINTER_BUTTON_STATE_PRESSED) {
if (button->time - window->last_button_time <= 
DOUBLE_CLICK_PERIOD) {
double_click = 1;
@@ -2143,8 +2157,12 @@ weston_wm_handle_button(struct weston_wm *wm, 
xcb_generic_event_t *event)
}
 
if (frame_status(window->frame) & FRAME_STATUS_RESIZE) {
-   if (pointer && weston_wm_window_is_resizable(window))
+   if (pointer && weston_wm_window_is_resizable(window)) {
+   if (!window->resizing)
+   window->sync_disabled = 0;
+   window->resizing = 1;
xwayland_interface->resize(window->shsurf, pointer, 
location);
+   }
frame_status_clear(window->frame, FRAME_STATUS_RESIZE);
}
 
-- 
2.13.0

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


[weston v2 8/8] xwm: Use Pango to draw title string if available

2017-11-13 Thread Louis-Francis Ratté-Boulianne
If Weston is built with Pango, use it to render the title for
X11 applications and Weston toy toolkit clients. It allows us
to ellipsize the title when there isn't enough space to show the
whole string.

Signed-off-by: Louis-Francis Ratté-Boulianne 
---
 Makefile.am |  2 ++
 configure.ac|  3 +++
 shared/cairo-util.c | 60 -
 3 files changed, 60 insertions(+), 5 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 9d99c694..13097b73 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1136,12 +1136,14 @@ libshared_cairo_la_CFLAGS = \
$(COMPOSITOR_CFLAGS)\
$(PIXMAN_CFLAGS)\
$(CAIRO_CFLAGS) \
+   $(PANGO_CFLAGS) \
$(PNG_CFLAGS)   \
$(WEBP_CFLAGS)
 
 libshared_cairo_la_LIBADD =\
$(PIXMAN_LIBS)  \
$(CAIRO_LIBS)   \
+   $(PANGO_LIBS)   \
$(PNG_LIBS) \
$(WEBP_LIBS)\
$(JPEG_LIBS)
diff --git a/configure.ac b/configure.ac
index 77012dcc..48ab5546 100644
--- a/configure.ac
+++ b/configure.ac
@@ -447,6 +447,9 @@ if test x$enable_weston_launch = xyes; then
 fi
 
 AM_CONDITIONAL(HAVE_PANGO, test "x$have_pango" = "xyes")
+if test "x$have_pango" = "xyes"; then
+  AC_DEFINE([HAVE_PANGO], [1], [Have pango])]
+fi
 
 AM_CONDITIONAL(HAVE_CAIRO_GLESV2,
   [test "x$have_cairo_egl" = "xyes" -a "x$cairo_modules" = 
"xcairo-glesv2" -a "x$enable_egl" = "xyes"])
diff --git a/shared/cairo-util.c b/shared/cairo-util.c
index fd8cc7ce..d71e0ed4 100644
--- a/shared/cairo-util.c
+++ b/shared/cairo-util.c
@@ -39,6 +39,10 @@
 #include "image-loader.h"
 #include "config-parser.h"
 
+#ifdef HAVE_PANGO
+#include 
+#endif
+
 void
 surface_flush_device(cairo_surface_t *surface)
 {
@@ -451,14 +455,42 @@ theme_destroy(struct theme *t)
free(t);
 }
 
+#ifdef HAVE_PANGO
+static PangoLayout *
+create_layout(cairo_t *cr, const char *title)
+{
+   PangoLayout *layout;
+   PangoFontDescription *desc;
+
+   layout = pango_cairo_create_layout(cr);
+   pango_layout_set_text(layout, title, -1);
+   desc = pango_font_description_from_string("Sans Bold 10");
+   pango_layout_set_font_description(layout, desc);
+   pango_font_description_free(desc);
+   pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
+   pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT);
+   pango_layout_set_auto_dir (layout, FALSE);
+   pango_layout_set_single_paragraph_mode (layout, TRUE);
+   pango_layout_set_width (layout, -1);
+
+   return layout;
+}
+#endif
+
+#ifdef HAVE_PANGO
+#define SHOW_TEXT(cr) \
+   pango_cairo_show_layout(cr, title_layout)
+#else
+#define SHOW_TEXT(cr) \
+   cairo_show_text(cr, title)
+#endif
+
 void
 theme_render_frame(struct theme *t,
   cairo_t *cr, int width, int height,
   const char *title, cairo_rectangle_int_t *title_rect,
   struct wl_list *buttons, uint32_t flags)
 {
-   cairo_text_extents_t extents;
-   cairo_font_extents_t font_extents;
cairo_surface_t *source;
int x, y, margin, top_margin;
int text_width, text_height;
@@ -497,6 +529,23 @@ theme_render_frame(struct theme *t,
 title_rect->width, title_rect->height);
cairo_clip(cr);
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
+
+#ifdef HAVE_PANGO
+   PangoLayout *title_layout;
+   PangoRectangle logical;
+
+   title_layout = create_layout(cr, title);
+
+   pango_layout_get_pixel_extents (title_layout, NULL, &logical);
+   text_width = MIN(title_rect->width, logical.width);
+   text_height = logical.height;
+   if (text_width < logical.width)
+ pango_layout_set_width (title_layout, text_width * 
PANGO_SCALE);
+   
+#else
+   cairo_text_extents_t extents;
+   cairo_font_extents_t font_extents;
+
cairo_select_font_face(cr, "sans",
   CAIRO_FONT_SLANT_NORMAL,
   CAIRO_FONT_WEIGHT_BOLD);
@@ -505,6 +554,7 @@ theme_render_frame(struct theme *t,
cairo_font_extents (cr, &font_extents);
text_width = extents.width;
text_height = font_extents.descent - font_extents.ascent;
+#endif
 
x = (width - text_width) / 2;
y = margin + (t->titlebar_height - text_height) 

[weston v2 3/8] xwm: Don't resize windows if the application have these hints

2017-11-13 Thread Louis-Francis Ratté-Boulianne
If the minimum and maximum size hints are equal, that means the
application doesn't want the window manager to allow resizing.

Signed-off-by: Louis-Francis Ratté-Boulianne 
---
 xwayland/window-manager.c | 26 --
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c
index 4b84b24e..c70938c4 100644
--- a/xwayland/window-manager.c
+++ b/xwayland/window-manager.c
@@ -973,6 +973,15 @@ weston_wm_window_set_net_wm_state(struct weston_wm_window 
*window)
i, property);
 }
 
+static inline bool
+weston_wm_window_is_resizable(struct weston_wm_window *window)
+{
+   return (window->size_hints.min_width <= 0 ||
+   window->size_hints.min_height <= 0 ||
+   window->size_hints.min_width != window->size_hints.max_width ||
+   window->size_hints.min_height != window->size_hints.max_height);
+}
+
 static void
 weston_wm_window_create_frame(struct weston_wm_window *window)
 {
@@ -981,7 +990,8 @@ weston_wm_window_create_frame(struct weston_wm_window 
*window)
int x, y, width, height;
int buttons = FRAME_BUTTON_CLOSE;
 
-   if (window->decorate & MWM_DECOR_MAXIMIZE)
+   if (window->decorate & MWM_DECOR_MAXIMIZE &&
+   weston_wm_window_is_resizable(window))
buttons |= FRAME_BUTTON_MAXIMIZE;
 
window->frame = frame_create(window->wm->theme,
@@ -2133,7 +2143,7 @@ weston_wm_handle_button(struct weston_wm *wm, 
xcb_generic_event_t *event)
}
 
if (frame_status(window->frame) & FRAME_STATUS_RESIZE) {
-   if (pointer)
+   if (pointer && weston_wm_window_is_resizable(window))
xwayland_interface->resize(window->shsurf, pointer, 
location);
frame_status_clear(window->frame, FRAME_STATUS_RESIZE);
}
@@ -2174,8 +2184,10 @@ weston_wm_handle_motion(struct weston_wm *wm, 
xcb_generic_event_t *event)
if (frame_status(window->frame) & FRAME_STATUS_REPAINT)
weston_wm_window_schedule_repaint(window);
 
-   cursor = get_cursor_for_location(location);
-   weston_wm_window_set_cursor(wm, window->frame_id, cursor);
+   if (weston_wm_window_is_resizable(window)) {
+   cursor = get_cursor_for_location(location);
+   weston_wm_window_set_cursor(wm, window->frame_id, cursor);
+   }
 }
 
 static void
@@ -2195,8 +2207,10 @@ weston_wm_handle_enter(struct weston_wm *wm, 
xcb_generic_event_t *event)
if (frame_status(window->frame) & FRAME_STATUS_REPAINT)
weston_wm_window_schedule_repaint(window);
 
-   cursor = get_cursor_for_location(location);
-   weston_wm_window_set_cursor(wm, window->frame_id, cursor);
+   if (weston_wm_window_is_resizable(window)) {
+   cursor = get_cursor_for_location(location);
+   weston_wm_window_set_cursor(wm, window->frame_id, cursor);
+   }
 }
 
 static void
-- 
2.13.0

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


[weston v2 4/8] xwm: Only send configure a window if the new size is different

2017-11-13 Thread Louis-Francis Ratté-Boulianne
If we configure a window with the same size and wait for the
sync alarm to go off, the resizing is gonna block. The event is
only handled is the size actually changed.

Signed-off-by: Louis-Francis Ratté-Boulianne 
---
 xwayland/window-manager.c | 15 +++
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c
index c70938c4..3cc6fa24 100644
--- a/xwayland/window-manager.c
+++ b/xwayland/window-manager.c
@@ -2780,6 +2780,7 @@ send_configure(struct weston_surface *surface, int32_t 
width, int32_t height)
struct weston_wm_window *window = get_wm_window(surface);
struct weston_wm *wm = window->wm;
struct theme *t = window->wm->theme;
+   int new_width, new_height;
int vborder, hborder;
 
if (window->decorate && !window->fullscreen) {
@@ -2791,14 +2792,20 @@ send_configure(struct weston_surface *surface, int32_t 
width, int32_t height)
}
 
if (width > hborder)
-   window->width = width - hborder;
+   new_width = width - hborder;
else
-   window->width = 1;
+   new_width = 1;
 
if (height > vborder)
-   window->height = height - vborder;
+   new_height = height - vborder;
else
-   window->height = 1;
+   new_height = 1;
+
+   if (window->width == new_width && window->height == new_height)
+   return;
+
+   window->width = new_width;
+   window->height = new_height;
 
if (window->frame)
frame_resize_inside(window->frame, window->width, 
window->height);
-- 
2.13.0

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


[weston v2 7/8] xwm: Deal with title in a smarter way when there isn't enough space

2017-11-13 Thread Louis-Francis Ratté-Boulianne
The title in X11 windows and Wayland application using Weston toy
toolkit were placing the title in a very naive fashion. It was
only try to center the string in the title bar. This patch:

 * Makes sure the title isn't renderer underneath buttons;
 * Move the title to the left if the titlebar isn't large enough;
 * Clip the end of the title if needed.

Signed-off-by: Louis-Francis Ratté-Boulianne 
---
 shared/cairo-util.c | 26 +++---
 shared/cairo-util.h |  4 ++--
 shared/frame.c  | 10 +-
 3 files changed, 26 insertions(+), 14 deletions(-)

diff --git a/shared/cairo-util.c b/shared/cairo-util.c
index 21fcbea5..fd8cc7ce 100644
--- a/shared/cairo-util.c
+++ b/shared/cairo-util.c
@@ -454,13 +454,14 @@ theme_destroy(struct theme *t)
 void
 theme_render_frame(struct theme *t,
   cairo_t *cr, int width, int height,
-  const char *title, struct wl_list *buttons,
-  uint32_t flags)
+  const char *title, cairo_rectangle_int_t *title_rect,
+  struct wl_list *buttons, uint32_t flags)
 {
cairo_text_extents_t extents;
cairo_font_extents_t font_extents;
cairo_surface_t *source;
int x, y, margin, top_margin;
+   int text_width, text_height;
 
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
cairo_set_source_rgba(cr, 0, 0, 0, 0);
@@ -491,11 +492,10 @@ theme_render_frame(struct theme *t,
t->width, top_margin);
 
if (title || !wl_list_empty(buttons)) {
-   cairo_rectangle (cr, margin + t->width, margin,
-width - (margin + t->width) * 2,
-t->titlebar_height - t->width);
-   cairo_clip(cr);
 
+   cairo_rectangle (cr, title_rect->x, title_rect->y,
+title_rect->width, title_rect->height);
+   cairo_clip(cr);
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
cairo_select_font_face(cr, "sans",
   CAIRO_FONT_SLANT_NORMAL,
@@ -503,11 +503,15 @@ theme_render_frame(struct theme *t,
cairo_set_font_size(cr, 14);
cairo_text_extents(cr, title, &extents);
cairo_font_extents (cr, &font_extents);
-   x = (width - extents.width) / 2;
-   y = margin +
-   (t->titlebar_height -
-font_extents.ascent - font_extents.descent) / 2 +
-   font_extents.ascent;
+   text_width = extents.width;
+   text_height = font_extents.descent - font_extents.ascent;
+
+   x = (width - text_width) / 2;
+   y = margin + (t->titlebar_height - text_height) / 2;
+   if (x < title_rect->x)
+   x = title_rect->x;
+   else if (x + text_width > (title_rect->x + title_rect->width))
+   x = (title_rect->x + title_rect->width) - text_width;
 
if (flags & THEME_FRAME_ACTIVE) {
cairo_move_to(cr, x + 1, y  + 1);
diff --git a/shared/cairo-util.h b/shared/cairo-util.h
index 84cf005e..9481e58c 100644
--- a/shared/cairo-util.h
+++ b/shared/cairo-util.h
@@ -75,8 +75,8 @@ theme_set_background_source(struct theme *t, cairo_t *cr, 
uint32_t flags);
 void
 theme_render_frame(struct theme *t,
   cairo_t *cr, int width, int height,
-  const char *title, struct wl_list *buttons,
-  uint32_t flags);
+  const char *title, cairo_rectangle_int_t *title_rect,
+  struct wl_list *buttons, uint32_t flags);
 
 enum theme_location {
THEME_LOCATION_INTERIOR = 0,
diff --git a/shared/frame.c b/shared/frame.c
index eb0cd77a..5ca7e08b 100644
--- a/shared/frame.c
+++ b/shared/frame.c
@@ -98,6 +98,8 @@ struct frame {
int opaque_margin;
int geometry_dirty;
 
+   cairo_rectangle_int_t title_rect;
+
uint32_t status;
 
struct wl_list buttons;
@@ -532,6 +534,11 @@ frame_refresh_geometry(struct frame *frame)
}
}
 
+   frame->title_rect.x = x_l;
+   frame->title_rect.y = y;
+   frame->title_rect.width = x_r - x_l;
+   frame->title_rect.height = titlebar_height;
+
frame->geometry_dirty = 0;
 }
 
@@ -938,7 +945,8 @@ frame_repaint(struct frame *frame, cairo_t *cr)
 
cairo_save(cr);
theme_render_frame(frame->theme, cr, frame->width, frame->height,
-  frame->title, &frame->buttons, flags);
+  frame->title, &frame->title_rect,
+  &frame->buttons, flags);
cairo_restore(cr);
 
wl_list_for_each(button, &frame->buttons, link)
-- 
2

[weston v2 1/8] xwm: Implement _NET_WM_SYNC_REQUEST protocol

2017-11-13 Thread Louis-Francis Ratté-Boulianne
v2: Remove some useless checks and don't be too verbose

Signed-off-by: Louis-Francis Ratté-Boulianne 

fixup: Implement _NET_WM_SYNC_REQUEST
---
 configure.ac  |   2 +-
 xwayland/window-manager.c | 207 +++---
 xwayland/xwayland.h   |   5 ++
 3 files changed, 201 insertions(+), 13 deletions(-)

diff --git a/configure.ac b/configure.ac
index c287fac6..77012dcc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -163,7 +163,7 @@ AC_ARG_ENABLE(xwayland-test, [  --enable-xwayland-test],,
 AM_CONDITIONAL(ENABLE_XWAYLAND, test x$enable_xwayland = xyes)
 AM_CONDITIONAL(ENABLE_XWAYLAND_TEST, test x$enable_xwayland = xyes -a 
x$enable_xwayland_test = xyes)
 if test x$enable_xwayland = xyes; then
-  PKG_CHECK_MODULES([XWAYLAND], xcb xcb-xfixes xcb-composite xcursor cairo-xcb)
+  PKG_CHECK_MODULES([XWAYLAND], xcb xcb-xfixes xcb-composite xcb-sync xcursor 
cairo-xcb)
   AC_DEFINE([BUILD_XWAYLAND], [1], [Build the X server launcher])
 
   AC_ARG_WITH(xserver-path, AS_HELP_STRING([--with-xserver-path=PATH],
diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c
index 3e8c4c7c..149d7fe4 100644
--- a/xwayland/window-manager.c
+++ b/xwayland/window-manager.c
@@ -43,6 +43,7 @@
 #include "compositor.h"
 #include "xwayland.h"
 #include "xwayland-internal-interface.h"
+#include "wayland-server-core.h"
 
 #include "cairo-util.h"
 #include "hash.h"
@@ -136,6 +137,8 @@ struct weston_wm_window {
struct weston_wm *wm;
xcb_window_t id;
xcb_window_t frame_id;
+   xcb_sync_alarm_t sync_request_alarm;
+   xcb_sync_counter_t sync_request_counter;
struct frame *frame;
cairo_surface_t *cairo_surface;
uint32_t surface_id;
@@ -144,6 +147,7 @@ struct weston_wm_window {
struct wl_listener surface_destroy_listener;
struct wl_event_source *repaint_source;
struct wl_event_source *configure_source;
+   struct wl_event_source *sync_request_timer;
int properties_dirty;
int pid;
char *machine;
@@ -167,6 +171,10 @@ struct weston_wm_window {
int delete_window;
int maximized_vert;
int maximized_horz;
+   int64_t sync_request_serial;
+   int configure_pending;
+   int sync_disabled;
+   int wait_redraw;
struct wm_size_hints size_hints;
struct motif_wm_hints motif_hints;
struct wl_list link;
@@ -179,6 +187,9 @@ static void
 weston_wm_set_net_active_window(struct weston_wm *wm, xcb_window_t window);
 
 static void
+weston_wm_window_configure(void *data);
+
+static void
 weston_wm_window_schedule_repaint(struct weston_wm_window *window);
 
 static int
@@ -472,6 +483,7 @@ weston_wm_window_read_properties(struct weston_wm_window 
*window)
{ wm->atom.net_wm_window_type, XCB_ATOM_ATOM,  
F(type) },
{ wm->atom.net_wm_name,XCB_ATOM_STRING,
F(name) },
{ wm->atom.net_wm_pid, XCB_ATOM_CARDINAL,  
F(pid) },
+   { wm->atom.net_wm_sync_request_counter,XCB_SYNC_COUNTER,   
F(sync_request_counter) },
{ wm->atom.motif_wm_hints, TYPE_MOTIF_WM_HINTS,NULL 
},
{ wm->atom.wm_client_machine,  XCB_ATOM_WM_CLIENT_MACHINE, 
F(machine) },
};
@@ -482,6 +494,7 @@ weston_wm_window_read_properties(struct weston_wm_window 
*window)
void *p;
uint32_t *xid;
xcb_atom_t *atom;
+   xcb_sync_counter_t *counter;
uint32_t i;
char name[1024];
 
@@ -537,6 +550,10 @@ weston_wm_window_read_properties(struct weston_wm_window 
*window)
atom = xcb_get_property_value(reply);
*(xcb_atom_t *) p = *atom;
break;
+   case XCB_SYNC_COUNTER:
+   counter = xcb_get_property_value(reply);
+   *(xcb_sync_counter_t *) p = *counter;
+   break;
case TYPE_WM_PROTOCOLS:
atom = xcb_get_property_value(reply);
for (i = 0; i < reply->value_len; i++)
@@ -674,11 +691,6 @@ weston_wm_handle_configure_request(struct weston_wm *wm, 
xcb_generic_event_t *ev
uint32_t mask, values[16];
int x, y, width, height, i = 0;
 
-   wm_log("XCB_CONFIGURE_REQUEST (window %d) %d,%d @ %dx%d\n",
-  configure_request->window,
-  configure_request->x, configure_request->y,
-  configure_request->width, configure_request->height);
-
if (!wm_lookup_window(wm, configure_request->window, &window))
return;
 
@@ -1045,6 +1057,81 @@ weston_wm_window_set_virtual_desktop(struct 
weston_wm_window *window,
 }
 
 static void
+weston_wm_window_create_sync_alarm(struct weston_wm_window *window)
+{
+   struct west

[weston v2 5/8] xwm: Make sure we respect the window's size hints

2017-11-13 Thread Louis-Francis Ratté-Boulianne
Don't just ignore the minimal and maximal sizes requested
by the application.

Signed-off-by: Louis-Francis Ratté-Boulianne 
---
 xwayland/window-manager.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c
index 3cc6fa24..a0ff6b62 100644
--- a/xwayland/window-manager.c
+++ b/xwayland/window-manager.c
@@ -2801,6 +2801,20 @@ send_configure(struct weston_surface *surface, int32_t 
width, int32_t height)
else
new_height = 1;
 
+   /* Make sure we respect the window's size hints */
+   if (window->size_hints.min_width > 0 &&
+   new_width < window->size_hints.min_width)
+   new_width = window->size_hints.min_width;
+   if (window->size_hints.min_height > 0 &&
+   new_height < window->size_hints.min_height)
+   new_height = window->size_hints.min_height;
+   if (window->size_hints.max_width > 0 &&
+   new_width > window->size_hints.max_width)
+   new_width = window->size_hints.max_width;
+   if (window->size_hints.max_height > 0 &&
+   new_height > window->size_hints.max_height)
+   new_height = window->size_hints.max_height;
+
if (window->width == new_width && window->height == new_height)
return;
 
-- 
2.13.0

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


[weston v2 2/8] xwm: Maximize windows when double-clicking on title bar

2017-11-13 Thread Louis-Francis Ratté-Boulianne
Signed-off-by: Louis-Francis Ratté-Boulianne 
---
 xwayland/window-manager.c | 26 --
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c
index 149d7fe4..4b84b24e 100644
--- a/xwayland/window-manager.c
+++ b/xwayland/window-manager.c
@@ -165,6 +165,8 @@ struct weston_wm_window {
struct weston_output_weak_ref legacy_fullscreen_output;
int saved_width, saved_height;
int decorate;
+   uint32_t last_button_time;
+   int did_double;
int override_redirect;
int fullscreen;
int has_alpha;
@@ -2060,6 +2062,7 @@ weston_wm_window_close(struct weston_wm_window *window, 
xcb_timestamp_t time)
}
 }
 
+#define DOUBLE_CLICK_PERIOD 250
 static void
 weston_wm_handle_button(struct weston_wm *wm, xcb_generic_event_t *event)
 {
@@ -2072,6 +2075,7 @@ weston_wm_handle_button(struct weston_wm *wm, 
xcb_generic_event_t *event)
enum theme_location location;
enum wl_pointer_button_state button_state;
uint32_t button_id;
+   uint32_t double_click = 0;
 
wm_log("XCB_BUTTON_%s (detail %d)\n",
   button->response_type == XCB_BUTTON_PRESS ?
@@ -2092,6 +2096,19 @@ weston_wm_handle_button(struct weston_wm *wm, 
xcb_generic_event_t *event)
WL_POINTER_BUTTON_STATE_RELEASED;
button_id = button->detail == 1 ? BTN_LEFT : BTN_RIGHT;
 
+   if (button_state == WL_POINTER_BUTTON_STATE_PRESSED) {
+   if (button->time - window->last_button_time <= 
DOUBLE_CLICK_PERIOD) {
+   double_click = 1;
+   window->did_double = 1;
+   } else
+   window->did_double = 0;
+
+   window->last_button_time = button->time;
+   } else if (window->did_double == 1) {
+   double_click = 1;
+   window->did_double = 0;
+   }
+
/* Make sure we're looking at the right location.  The frame
 * could have received a motion event from a pointer from a
 * different wl_seat, but under X it looks like our core
@@ -2099,8 +2116,13 @@ weston_wm_handle_button(struct weston_wm *wm, 
xcb_generic_event_t *event)
 * location before deciding what to do. */
location = frame_pointer_motion(window->frame, NULL,
button->event_x, button->event_y);
-   location = frame_pointer_button(window->frame, NULL,
-   button_id, button_state);
+   if (double_click)
+   location = frame_double_click(window->frame, NULL,
+ button_id, button_state);
+   else
+   location = frame_pointer_button(window->frame, NULL,
+   button_id, button_state);
+
if (frame_status(window->frame) & FRAME_STATUS_REPAINT)
weston_wm_window_schedule_repaint(window);
 
-- 
2.13.0

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


[weston v2 0/8] Implement NET_WM_SYNC_REQUEST basic support

2017-11-13 Thread Louis-Francis Ratté-Boulianne
Hi,

This patchset implements NET_WM_SYNC_REQUEST protocol for throtting
X11 window resizes in Weston's XWM. We wait for the window to be drawn
(by setting an alarm on the sync counter) before configuring the window
again.

I also did some small fixes the Xwayland window manager as to better
respect size hints from X11 applications and to display the title
more elegantly when there isn't enough space available.

The first sumission was a while back:

https://lists.freedesktop.org/archives/wayland-devel/2017-April/033859.html

Changes compared to previous patches are:

 - Remove some useless checks
 - Be less verbose when resizing with debug log enabled
 - Re-enable the sync extension when a new resize operation is started
   instead of just disabling it forever when something times out.

Louis-Francis Ratté-Boulianne (8):
  xwm: Implement _NET_WM_SYNC_REQUEST protocol
  xwm: Maximize windows when double-clicking on title bar
  xwm: Don't resize windows if the application have these hints
  xwm: Only send configure a window if the new size is different
  xwm: Make sure we respect the window's size hints
  xwm: Ignore configure request while the user is resizing
  xwm: Deal with title in a smarter way when there isn't enough space
  xwm: Use Pango to draw title string if available

 Makefile.am   |   2 +
 configure.ac  |   5 +-
 shared/cairo-util.c   |  86 ++---
 shared/cairo-util.h   |   4 +-
 shared/frame.c|  10 +-
 xwayland/window-manager.c | 306 ++
 xwayland/xwayland.h   |   5 +
 7 files changed, 374 insertions(+), 44 deletions(-)

-- 
2.13.0

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


[weston 8/8] xwm: Use Pango to draw title string if available

2017-04-11 Thread Louis-Francis Ratté-Boulianne
If Weston is built with Pango, use it to render the title for
X11 applications and Weston toy toolkit clients. It allows us
to ellipsize the title when there isn't enough space to show the
whole string.

Signed-off-by: Louis-Francis Ratté-Boulianne 
---
 Makefile.am |  2 ++
 configure.ac|  3 +++
 shared/cairo-util.c | 60 -
 3 files changed, 60 insertions(+), 5 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 7ee613ba..44af3d19 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1122,12 +1122,14 @@ libshared_cairo_la_CFLAGS = \
$(COMPOSITOR_CFLAGS)\
$(PIXMAN_CFLAGS)\
$(CAIRO_CFLAGS) \
+   $(PANGO_CFLAGS) \
$(PNG_CFLAGS)   \
$(WEBP_CFLAGS)
 
 libshared_cairo_la_LIBADD =\
$(PIXMAN_LIBS)  \
$(CAIRO_LIBS)   \
+   $(PANGO_LIBS)   \
$(PNG_LIBS) \
$(WEBP_LIBS)\
$(JPEG_LIBS)
diff --git a/configure.ac b/configure.ac
index eebeba9d..eeadfeed 100644
--- a/configure.ac
+++ b/configure.ac
@@ -443,6 +443,9 @@ if test x$enable_weston_launch = xyes; then
 fi
 
 AM_CONDITIONAL(HAVE_PANGO, test "x$have_pango" = "xyes")
+if test "x$have_pango" = "xyes"; then
+  AC_DEFINE([HAVE_PANGO], [1], [Have pango])]
+fi
 
 AM_CONDITIONAL(HAVE_CAIRO_GLESV2,
   [test "x$have_cairo_egl" = "xyes" -a "x$cairo_modules" = 
"xcairo-glesv2" -a "x$enable_egl" = "xyes"])
diff --git a/shared/cairo-util.c b/shared/cairo-util.c
index fd8cc7ce..d71e0ed4 100644
--- a/shared/cairo-util.c
+++ b/shared/cairo-util.c
@@ -39,6 +39,10 @@
 #include "image-loader.h"
 #include "config-parser.h"
 
+#ifdef HAVE_PANGO
+#include 
+#endif
+
 void
 surface_flush_device(cairo_surface_t *surface)
 {
@@ -451,14 +455,42 @@ theme_destroy(struct theme *t)
free(t);
 }
 
+#ifdef HAVE_PANGO
+static PangoLayout *
+create_layout(cairo_t *cr, const char *title)
+{
+   PangoLayout *layout;
+   PangoFontDescription *desc;
+
+   layout = pango_cairo_create_layout(cr);
+   pango_layout_set_text(layout, title, -1);
+   desc = pango_font_description_from_string("Sans Bold 10");
+   pango_layout_set_font_description(layout, desc);
+   pango_font_description_free(desc);
+   pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
+   pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT);
+   pango_layout_set_auto_dir (layout, FALSE);
+   pango_layout_set_single_paragraph_mode (layout, TRUE);
+   pango_layout_set_width (layout, -1);
+
+   return layout;
+}
+#endif
+
+#ifdef HAVE_PANGO
+#define SHOW_TEXT(cr) \
+   pango_cairo_show_layout(cr, title_layout)
+#else
+#define SHOW_TEXT(cr) \
+   cairo_show_text(cr, title)
+#endif
+
 void
 theme_render_frame(struct theme *t,
   cairo_t *cr, int width, int height,
   const char *title, cairo_rectangle_int_t *title_rect,
   struct wl_list *buttons, uint32_t flags)
 {
-   cairo_text_extents_t extents;
-   cairo_font_extents_t font_extents;
cairo_surface_t *source;
int x, y, margin, top_margin;
int text_width, text_height;
@@ -497,6 +529,23 @@ theme_render_frame(struct theme *t,
 title_rect->width, title_rect->height);
cairo_clip(cr);
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
+
+#ifdef HAVE_PANGO
+   PangoLayout *title_layout;
+   PangoRectangle logical;
+
+   title_layout = create_layout(cr, title);
+
+   pango_layout_get_pixel_extents (title_layout, NULL, &logical);
+   text_width = MIN(title_rect->width, logical.width);
+   text_height = logical.height;
+   if (text_width < logical.width)
+ pango_layout_set_width (title_layout, text_width * 
PANGO_SCALE);
+   
+#else
+   cairo_text_extents_t extents;
+   cairo_font_extents_t font_extents;
+
cairo_select_font_face(cr, "sans",
   CAIRO_FONT_SLANT_NORMAL,
   CAIRO_FONT_WEIGHT_BOLD);
@@ -505,6 +554,7 @@ theme_render_frame(struct theme *t,
cairo_font_extents (cr, &font_extents);
text_width = extents.width;
text_height = font_extents.descent - font_extents.ascent;
+#endif
 
x = (width - text_width) / 2;
y = margin + (t->titlebar_height - text_height) 

[weston 7/8] xwm: Deal with title in a smarter way when there isn't enough space

2017-04-11 Thread Louis-Francis Ratté-Boulianne
The title in X11 windows and Wayland application using Weston toy
toolkit were placing the title in a very naive fashion. It was
only try to center the string in the title bar. This patch:

 * Makes sure the title isn't renderer underneath buttons;
 * Move the title to the left if the titlebar isn't large enough;
 * Clip the end of the title if needed.

Signed-off-by: Louis-Francis Ratté-Boulianne 
---
 shared/cairo-util.c | 26 +++---
 shared/cairo-util.h |  4 ++--
 shared/frame.c  | 10 +-
 3 files changed, 26 insertions(+), 14 deletions(-)

diff --git a/shared/cairo-util.c b/shared/cairo-util.c
index 21fcbea5..fd8cc7ce 100644
--- a/shared/cairo-util.c
+++ b/shared/cairo-util.c
@@ -454,13 +454,14 @@ theme_destroy(struct theme *t)
 void
 theme_render_frame(struct theme *t,
   cairo_t *cr, int width, int height,
-  const char *title, struct wl_list *buttons,
-  uint32_t flags)
+  const char *title, cairo_rectangle_int_t *title_rect,
+  struct wl_list *buttons, uint32_t flags)
 {
cairo_text_extents_t extents;
cairo_font_extents_t font_extents;
cairo_surface_t *source;
int x, y, margin, top_margin;
+   int text_width, text_height;
 
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
cairo_set_source_rgba(cr, 0, 0, 0, 0);
@@ -491,11 +492,10 @@ theme_render_frame(struct theme *t,
t->width, top_margin);
 
if (title || !wl_list_empty(buttons)) {
-   cairo_rectangle (cr, margin + t->width, margin,
-width - (margin + t->width) * 2,
-t->titlebar_height - t->width);
-   cairo_clip(cr);
 
+   cairo_rectangle (cr, title_rect->x, title_rect->y,
+title_rect->width, title_rect->height);
+   cairo_clip(cr);
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
cairo_select_font_face(cr, "sans",
   CAIRO_FONT_SLANT_NORMAL,
@@ -503,11 +503,15 @@ theme_render_frame(struct theme *t,
cairo_set_font_size(cr, 14);
cairo_text_extents(cr, title, &extents);
cairo_font_extents (cr, &font_extents);
-   x = (width - extents.width) / 2;
-   y = margin +
-   (t->titlebar_height -
-font_extents.ascent - font_extents.descent) / 2 +
-   font_extents.ascent;
+   text_width = extents.width;
+   text_height = font_extents.descent - font_extents.ascent;
+
+   x = (width - text_width) / 2;
+   y = margin + (t->titlebar_height - text_height) / 2;
+   if (x < title_rect->x)
+   x = title_rect->x;
+   else if (x + text_width > (title_rect->x + title_rect->width))
+   x = (title_rect->x + title_rect->width) - text_width;
 
if (flags & THEME_FRAME_ACTIVE) {
cairo_move_to(cr, x + 1, y  + 1);
diff --git a/shared/cairo-util.h b/shared/cairo-util.h
index 84cf005e..9481e58c 100644
--- a/shared/cairo-util.h
+++ b/shared/cairo-util.h
@@ -75,8 +75,8 @@ theme_set_background_source(struct theme *t, cairo_t *cr, 
uint32_t flags);
 void
 theme_render_frame(struct theme *t,
   cairo_t *cr, int width, int height,
-  const char *title, struct wl_list *buttons,
-  uint32_t flags);
+  const char *title, cairo_rectangle_int_t *title_rect,
+  struct wl_list *buttons, uint32_t flags);
 
 enum theme_location {
THEME_LOCATION_INTERIOR = 0,
diff --git a/shared/frame.c b/shared/frame.c
index eb0cd77a..5ca7e08b 100644
--- a/shared/frame.c
+++ b/shared/frame.c
@@ -98,6 +98,8 @@ struct frame {
int opaque_margin;
int geometry_dirty;
 
+   cairo_rectangle_int_t title_rect;
+
uint32_t status;
 
struct wl_list buttons;
@@ -532,6 +534,11 @@ frame_refresh_geometry(struct frame *frame)
}
}
 
+   frame->title_rect.x = x_l;
+   frame->title_rect.y = y;
+   frame->title_rect.width = x_r - x_l;
+   frame->title_rect.height = titlebar_height;
+
frame->geometry_dirty = 0;
 }
 
@@ -938,7 +945,8 @@ frame_repaint(struct frame *frame, cairo_t *cr)
 
cairo_save(cr);
theme_render_frame(frame->theme, cr, frame->width, frame->height,
-  frame->title, &frame->buttons, flags);
+  frame->title, &frame->title_rect,
+  &frame->buttons, flags);
cairo_restore(cr);
 
wl_list_for_each(button, &frame->buttons, link)
-- 
2

[weston 6/8] xwm: Ignore configure request while the user is resizing

2017-04-11 Thread Louis-Francis Ratté-Boulianne
We don't want the application to fight with the user when manually
resizing a window.

Signed-off-by: Louis-Francis Ratté-Boulianne 
---
 xwayland/window-manager.c | 16 +++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c
index bea3cc68..3ee76027 100644
--- a/xwayland/window-manager.c
+++ b/xwayland/window-manager.c
@@ -173,6 +173,7 @@ struct weston_wm_window {
int delete_window;
int maximized_vert;
int maximized_horz;
+   int resizing;
int64_t sync_request_serial;
int configure_pending;
int sync_disabled;
@@ -701,6 +702,11 @@ weston_wm_handle_configure_request(struct weston_wm *wm, 
xcb_generic_event_t *ev
return;
}
 
+   if (window->frame && window->resizing) {
+   wm_log("Ignore configure request while resizing window\n");
+   return;
+   }
+
if (configure_request->value_mask & XCB_CONFIG_WINDOW_WIDTH)
window->width = configure_request->width;
if (configure_request->value_mask & XCB_CONFIG_WINDOW_HEIGHT)
@@ -1672,9 +1678,11 @@ weston_wm_window_handle_moveresize(struct 
weston_wm_window *window,
case _NET_WM_MOVERESIZE_SIZE_BOTTOM:
case _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT:
case _NET_WM_MOVERESIZE_SIZE_LEFT:
+   window->resizing = 1;
xwayland_interface->resize(window->shsurf, pointer, 
map[detail]);
break;
case _NET_WM_MOVERESIZE_CANCEL:
+   window->resizing = 0;
break;
}
 }
@@ -2110,6 +2118,10 @@ weston_wm_handle_button(struct weston_wm *wm, 
xcb_generic_event_t *event)
WL_POINTER_BUTTON_STATE_RELEASED;
button_id = button->detail == 1 ? BTN_LEFT : BTN_RIGHT;
 
+   if (window->resizing && button_id == BTN_LEFT &&
+   button_state == WL_POINTER_BUTTON_STATE_PRESSED)
+   window->resizing = 0;
+
if (button_state == WL_POINTER_BUTTON_STATE_PRESSED) {
if (button->time - window->last_button_time <= 
DOUBLE_CLICK_PERIOD) {
double_click = 1;
@@ -2147,8 +2159,10 @@ weston_wm_handle_button(struct weston_wm *wm, 
xcb_generic_event_t *event)
}
 
if (frame_status(window->frame) & FRAME_STATUS_RESIZE) {
-   if (pointer && weston_wm_window_is_resizable(window))
+   if (pointer && weston_wm_window_is_resizable(window)) {
+   window->resizing = 1;
xwayland_interface->resize(window->shsurf, pointer, 
location);
+   }
frame_status_clear(window->frame, FRAME_STATUS_RESIZE);
}
 
-- 
2.12.2

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


[weston 1/8] xwm: Implement _NET_WM_SYNC_REQUEST protocol

2017-04-11 Thread Louis-Francis Ratté-Boulianne
Implement NET_WM_SYNC_REQUEST protocol for throtting X11 window resizes
in Weston's XWM. We wait for the window to be drawn (by setting an
alarm on the sync counter) before configuring the window again.

Signed-off-by: Louis-Francis Ratté-Boulianne 
---
 configure.ac  |   2 +-
 xwayland/window-manager.c | 220 +++---
 xwayland/xwayland.h   |   5 ++
 3 files changed, 214 insertions(+), 13 deletions(-)

diff --git a/configure.ac b/configure.ac
index 6cc9f26e..eebeba9d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -165,7 +165,7 @@ AC_ARG_ENABLE(xwayland-test, [  --enable-xwayland-test],,
 AM_CONDITIONAL(ENABLE_XWAYLAND, test x$enable_xwayland = xyes)
 AM_CONDITIONAL(ENABLE_XWAYLAND_TEST, test x$enable_xwayland = xyes -a 
x$enable_xwayland_test = xyes)
 if test x$enable_xwayland = xyes; then
-  PKG_CHECK_MODULES([XWAYLAND], xcb xcb-xfixes xcb-composite xcursor cairo-xcb)
+  PKG_CHECK_MODULES([XWAYLAND], xcb xcb-xfixes xcb-composite xcb-sync xcursor 
cairo-xcb)
   AC_DEFINE([BUILD_XWAYLAND], [1], [Build the X server launcher])
 
   AC_ARG_WITH(xserver-path, AS_HELP_STRING([--with-xserver-path=PATH],
diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c
index 26080759..a067f741 100644
--- a/xwayland/window-manager.c
+++ b/xwayland/window-manager.c
@@ -43,6 +43,7 @@
 #include "compositor.h"
 #include "xwayland.h"
 #include "xwayland-internal-interface.h"
+#include "wayland-server-core.h"
 
 #include "cairo-util.h"
 #include "hash.h"
@@ -136,6 +137,8 @@ struct weston_wm_window {
struct weston_wm *wm;
xcb_window_t id;
xcb_window_t frame_id;
+   xcb_sync_alarm_t sync_request_alarm;
+   xcb_sync_counter_t sync_request_counter;
struct frame *frame;
cairo_surface_t *cairo_surface;
uint32_t surface_id;
@@ -144,6 +147,7 @@ struct weston_wm_window {
struct wl_listener surface_destroy_listener;
struct wl_event_source *repaint_source;
struct wl_event_source *configure_source;
+   struct wl_event_source *sync_request_timer;
int properties_dirty;
int pid;
char *machine;
@@ -167,6 +171,10 @@ struct weston_wm_window {
int delete_window;
int maximized_vert;
int maximized_horz;
+   int64_t sync_request_serial;
+   int configure_pending;
+   int sync_disabled;
+   int wait_redraw;
struct wm_size_hints size_hints;
struct motif_wm_hints motif_hints;
struct wl_list link;
@@ -179,6 +187,9 @@ static void
 weston_wm_set_net_active_window(struct weston_wm *wm, xcb_window_t window);
 
 static void
+weston_wm_window_configure(void *data);
+
+static void
 weston_wm_window_schedule_repaint(struct weston_wm_window *window);
 
 static int
@@ -472,6 +483,7 @@ weston_wm_window_read_properties(struct weston_wm_window 
*window)
{ wm->atom.net_wm_window_type, XCB_ATOM_ATOM,  
F(type) },
{ wm->atom.net_wm_name,XCB_ATOM_STRING,
F(name) },
{ wm->atom.net_wm_pid, XCB_ATOM_CARDINAL,  
F(pid) },
+   { wm->atom.net_wm_sync_request_counter,XCB_SYNC_COUNTER,   
F(sync_request_counter) },
{ wm->atom.motif_wm_hints, TYPE_MOTIF_WM_HINTS,NULL 
},
{ wm->atom.wm_client_machine,  XCB_ATOM_WM_CLIENT_MACHINE, 
F(machine) },
};
@@ -482,6 +494,7 @@ weston_wm_window_read_properties(struct weston_wm_window 
*window)
void *p;
uint32_t *xid;
xcb_atom_t *atom;
+   xcb_sync_counter_t *counter;
uint32_t i;
char name[1024];
 
@@ -537,6 +550,10 @@ weston_wm_window_read_properties(struct weston_wm_window 
*window)
atom = xcb_get_property_value(reply);
*(xcb_atom_t *) p = *atom;
break;
+   case XCB_SYNC_COUNTER:
+   counter = xcb_get_property_value(reply);
+   *(xcb_sync_counter_t *) p = *counter;
+   break;
case TYPE_WM_PROTOCOLS:
atom = xcb_get_property_value(reply);
for (i = 0; i < reply->value_len; i++)
@@ -674,11 +691,6 @@ weston_wm_handle_configure_request(struct weston_wm *wm, 
xcb_generic_event_t *ev
uint32_t mask, values[16];
int x, y, width, height, i = 0;
 
-   wm_log("XCB_CONFIGURE_REQUEST (window %d) %d,%d @ %dx%d\n",
-  configure_request->window,
-  configure_request->x, configure_request->y,
-  configure_request->width, configure_request->height);
-
if (!wm_lookup_window(wm, configure_request->window, &window))
return;
 
@@ -1036,6 +1048,91 @@ weston_wm_window_set_virtual_desktop(struct 
weston_wm_window *window,
 }
 
 stat

[weston 3/8] xwm: Don't resize windows if the application have these hints

2017-04-11 Thread Louis-Francis Ratté-Boulianne
If the minimum and maximum size hints are equal, that means the
application doesn't want the window manager to allow resizing.

Signed-off-by: Louis-Francis Ratté-Boulianne 
---
 xwayland/window-manager.c | 26 --
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c
index 02a7c252..b78175b3 100644
--- a/xwayland/window-manager.c
+++ b/xwayland/window-manager.c
@@ -964,6 +964,15 @@ weston_wm_window_set_net_wm_state(struct weston_wm_window 
*window)
i, property);
 }
 
+static inline bool
+weston_wm_window_is_resizable(struct weston_wm_window *window)
+{
+   return (window->size_hints.min_width <= 0 ||
+   window->size_hints.min_height <= 0 ||
+   window->size_hints.min_width != window->size_hints.max_width ||
+   window->size_hints.min_height != window->size_hints.max_height);
+}
+
 static void
 weston_wm_window_create_frame(struct weston_wm_window *window)
 {
@@ -972,7 +981,8 @@ weston_wm_window_create_frame(struct weston_wm_window 
*window)
int x, y, width, height;
int buttons = FRAME_BUTTON_CLOSE;
 
-   if (window->decorate & MWM_DECOR_MAXIMIZE)
+   if (window->decorate & MWM_DECOR_MAXIMIZE &&
+   weston_wm_window_is_resizable(window))
buttons |= FRAME_BUTTON_MAXIMIZE;
 
window->frame = frame_create(window->wm->theme,
@@ -2137,7 +2147,7 @@ weston_wm_handle_button(struct weston_wm *wm, 
xcb_generic_event_t *event)
}
 
if (frame_status(window->frame) & FRAME_STATUS_RESIZE) {
-   if (pointer)
+   if (pointer && weston_wm_window_is_resizable(window))
xwayland_interface->resize(window->shsurf, pointer, 
location);
frame_status_clear(window->frame, FRAME_STATUS_RESIZE);
}
@@ -2178,8 +2188,10 @@ weston_wm_handle_motion(struct weston_wm *wm, 
xcb_generic_event_t *event)
if (frame_status(window->frame) & FRAME_STATUS_REPAINT)
weston_wm_window_schedule_repaint(window);
 
-   cursor = get_cursor_for_location(location);
-   weston_wm_window_set_cursor(wm, window->frame_id, cursor);
+   if (weston_wm_window_is_resizable(window)) {
+   cursor = get_cursor_for_location(location);
+   weston_wm_window_set_cursor(wm, window->frame_id, cursor);
+   }
 }
 
 static void
@@ -2199,8 +2211,10 @@ weston_wm_handle_enter(struct weston_wm *wm, 
xcb_generic_event_t *event)
if (frame_status(window->frame) & FRAME_STATUS_REPAINT)
weston_wm_window_schedule_repaint(window);
 
-   cursor = get_cursor_for_location(location);
-   weston_wm_window_set_cursor(wm, window->frame_id, cursor);
+   if (weston_wm_window_is_resizable(window)) {
+   cursor = get_cursor_for_location(location);
+   weston_wm_window_set_cursor(wm, window->frame_id, cursor);
+   }
 }
 
 static void
-- 
2.12.2

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


[weston 4/8] xwm: Only send configure a window if the new size is different

2017-04-11 Thread Louis-Francis Ratté-Boulianne
If we configure a window with the same size and wait for the
sync alarm to go off, the resizing is gonna block. The event is
only handled is the size actually changed.

Signed-off-by: Louis-Francis Ratté-Boulianne 
---
 xwayland/window-manager.c | 15 +++
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c
index b78175b3..8048594e 100644
--- a/xwayland/window-manager.c
+++ b/xwayland/window-manager.c
@@ -2778,6 +2778,7 @@ send_configure(struct weston_surface *surface, int32_t 
width, int32_t height)
struct weston_wm_window *window = get_wm_window(surface);
struct weston_wm *wm = window->wm;
struct theme *t = window->wm->theme;
+   int new_width, new_height;
int vborder, hborder;
 
if (window->decorate && !window->fullscreen) {
@@ -2789,14 +2790,20 @@ send_configure(struct weston_surface *surface, int32_t 
width, int32_t height)
}
 
if (width > hborder)
-   window->width = width - hborder;
+   new_width = width - hborder;
else
-   window->width = 1;
+   new_width = 1;
 
if (height > vborder)
-   window->height = height - vborder;
+   new_height = height - vborder;
else
-   window->height = 1;
+   new_height = 1;
+
+   if (window->width == new_width && window->height == new_height)
+   return;
+
+   window->width = new_width;
+   window->height = new_height;
 
if (window->frame)
frame_resize_inside(window->frame, window->width, 
window->height);
-- 
2.12.2

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


[weston 5/8] xwm: Make sure we respect the window's size hints

2017-04-11 Thread Louis-Francis Ratté-Boulianne
Don't just ignore the minimal and maximal sizes requested
by the application.

Signed-off-by: Louis-Francis Ratté-Boulianne 
---
 xwayland/window-manager.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c
index 8048594e..bea3cc68 100644
--- a/xwayland/window-manager.c
+++ b/xwayland/window-manager.c
@@ -2799,6 +2799,20 @@ send_configure(struct weston_surface *surface, int32_t 
width, int32_t height)
else
new_height = 1;
 
+   /* Make sure we respect the window's size hints */
+   if (window->size_hints.min_width > 0 &&
+   new_width < window->size_hints.min_width)
+   new_width = window->size_hints.min_width;
+   if (window->size_hints.min_height > 0 &&
+   new_height < window->size_hints.min_height)
+   new_height = window->size_hints.min_height;
+   if (window->size_hints.max_width > 0 &&
+   new_width > window->size_hints.max_width)
+   new_width = window->size_hints.max_width;
+   if (window->size_hints.max_height > 0 &&
+   new_height > window->size_hints.max_height)
+   new_height = window->size_hints.max_height;
+
if (window->width == new_width && window->height == new_height)
return;
 
-- 
2.12.2

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


[weston 0/8] Implement NET_WM_SYNC_REQUEST basic support

2017-04-11 Thread Louis-Francis Ratté-Boulianne
Implement NET_WM_SYNC_REQUEST protocol for throtting X11 window resizes
in Weston's XWM. We wait for the window to be drawn (by setting an
alarm on the sync counter) before configuring the window again.

I also did some small fixes the Xwayland window manager as to better
respect size hints from X11 applications and to display the title
more elegantly when there isn't enough space available.

Louis-Francis Ratté-Boulianne (8):
   xwm: Implement _NET_WM_SYNC_REQUEST protocol
   xwm: Maximize windows when double-clicking on title bar
   xwm: Don't resize windows if the application have these
   xwm: Only send configure a window if the new size is
   xwm: Make sure we respect the window's size hints
   xwm: Ignore configure request while the user is resizing
   xwm: Deal with title in a smarter way when there isn't
   xwm: Use Pango to draw title string if available
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


[weston 2/8] xwm: Maximize windows when double-clicking on title bar

2017-04-11 Thread Louis-Francis Ratté-Boulianne
Signed-off-by: Louis-Francis Ratté-Boulianne 
---
 xwayland/window-manager.c | 26 --
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c
index a067f741..02a7c252 100644
--- a/xwayland/window-manager.c
+++ b/xwayland/window-manager.c
@@ -165,6 +165,8 @@ struct weston_wm_window {
struct weston_output_weak_ref legacy_fullscreen_output;
int saved_width, saved_height;
int decorate;
+   uint32_t last_button_time;
+   int did_double;
int override_redirect;
int fullscreen;
int has_alpha;
@@ -2064,6 +2066,7 @@ weston_wm_window_close(struct weston_wm_window *window, 
xcb_timestamp_t time)
}
 }
 
+#define DOUBLE_CLICK_PERIOD 250
 static void
 weston_wm_handle_button(struct weston_wm *wm, xcb_generic_event_t *event)
 {
@@ -2076,6 +2079,7 @@ weston_wm_handle_button(struct weston_wm *wm, 
xcb_generic_event_t *event)
enum theme_location location;
enum wl_pointer_button_state button_state;
uint32_t button_id;
+   uint32_t double_click = 0;
 
wm_log("XCB_BUTTON_%s (detail %d)\n",
   button->response_type == XCB_BUTTON_PRESS ?
@@ -2096,6 +2100,19 @@ weston_wm_handle_button(struct weston_wm *wm, 
xcb_generic_event_t *event)
WL_POINTER_BUTTON_STATE_RELEASED;
button_id = button->detail == 1 ? BTN_LEFT : BTN_RIGHT;
 
+   if (button_state == WL_POINTER_BUTTON_STATE_PRESSED) {
+   if (button->time - window->last_button_time <= 
DOUBLE_CLICK_PERIOD) {
+   double_click = 1;
+   window->did_double = 1;
+   } else
+   window->did_double = 0;
+
+   window->last_button_time = button->time;
+   } else if (window->did_double == 1) {
+   double_click = 1;
+   window->did_double = 0;
+   }
+
/* Make sure we're looking at the right location.  The frame
 * could have received a motion event from a pointer from a
 * different wl_seat, but under X it looks like our core
@@ -2103,8 +2120,13 @@ weston_wm_handle_button(struct weston_wm *wm, 
xcb_generic_event_t *event)
 * location before deciding what to do. */
location = frame_pointer_motion(window->frame, NULL,
button->event_x, button->event_y);
-   location = frame_pointer_button(window->frame, NULL,
-   button_id, button_state);
+   if (double_click)
+   location = frame_double_click(window->frame, NULL,
+ button_id, button_state);
+   else
+   location = frame_pointer_button(window->frame, NULL,
+   button_id, button_state);
+
if (frame_status(window->frame) & FRAME_STATUS_REPAINT)
weston_wm_window_schedule_repaint(window);
 
-- 
2.12.2

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [weston, v3, 3/3] libweston-desktop/xwayland: react to geometry changes

2017-04-11 Thread Louis-Francis Ratté-Boulianne
On Wed, 2017-01-18 at 15:37 +0200, Pekka Paalanen wrote:
> From: Pekka Paalanen 
> 
> Fix up the window position whenever the geometry info changes.
> 
> If the window geometry changes, we want to keep the input-responding
> content anchored to top-left. It is done by manipulating the dx,dy
> arguments originating from a wl_surface.attach request.
> 
> Signed-off-by: Pekka Paalanen 

Reviewed-by: Louis-Francis Ratté-Boulianne 

> ---
>  libweston-desktop/xwayland.c | 7 +++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/libweston-desktop/xwayland.c b/libweston-
> desktop/xwayland.c
> index b984385..4f4b453 100644
> --- a/libweston-desktop/xwayland.c
> +++ b/libweston-desktop/xwayland.c
> @@ -131,12 +131,19 @@
> weston_desktop_xwayland_surface_committed(struct
> weston_desktop_surface *dsurfac
>     int32_t sx, int32_t sy)
>  {
>   struct weston_desktop_xwayland_surface *surface = user_data;
> + struct weston_geometry oldgeom;
> +
> + assert(dsurface == surface->surface);
>  
>  #ifdef WM_DEBUG
>   weston_log("%s: xwayland surface %p\n", __func__, surface);
>  #endif
>  
>   if (surface->has_next_geometry) {
> + oldgeom =
> weston_desktop_surface_get_geometry(surface->surface);
> + sx -= surface->next_geometry.x - oldgeom.x;
> + sy -= surface->next_geometry.y - oldgeom.x;
> +
>   surface->has_next_geometry = false;
>   weston_desktop_surface_set_geometry(surface-
> >surface,
>   surface-
> >next_geometry);
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [weston,v3,2/3] xwm: use _XWAYLAND_ALLOW_COMMITS

2017-04-11 Thread Louis-Francis Ratté-Boulianne
On Wed, 2017-01-18 at 15:37 +0200, Pekka Paalanen wrote:
> From: Pekka Paalanen 
> 
> This patch uses the new feature proposed for Xwayland in the patch
> series https://patchwork.freedesktop.org/series/16610/ .
> 
> When the frame window is created, immediately forbid Xwayland commits
> on
> it. This prevents commits before the decorations have been drawn and
> the
> initial pending state has been set. Commits are enabled right after
> drawing and setting.
> 
> This ensures that the decorations are fully drawn when a window is
> mapped. This also solves the initial commit/pending race, but the
> race
> is on again after mapping.
> 
> If Xwayland does not implement the needed support, we are just
> setting a
> window property with no effect.
> 
> This patch is the final piece for solving T7622, excluding the
> _NET_WM_SYNC_REQUEST handling.
> 
> Task: https://phabricator.freedesktop.org/T7622
> Signed-off-by: Pekka Paalanen 

It seems to fix the race just fine.

Reviewed-by: Louis-Francis Ratté-Boulianne 

> ---
>  xwayland/window-manager.c | 40
> ++--
>  xwayland/xwayland.h   |  1 +
>  2 files changed, 39 insertions(+), 2 deletions(-)
> 
> diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c
> index ac875a3..2608075 100644
> --- a/xwayland/window-manager.c
> +++ b/xwayland/window-manager.c
> @@ -873,6 +873,37 @@ weston_wm_window_activate(struct wl_listener
> *listener, void *data)
>  
>  }
>  
> +/** Control Xwayland wl_surface.commit behaviour
> + *
> + * This function sets the "_XWAYLAND_ALLOW_COMMITS" property of the
> frame window
> + * (not the content window!) to \p allow.
> + *
> + * If the property is set to \c true, Xwayland will commit whenever
> it likes.
> + * If the property is set to \c false, Xwayland will not commit.
> + * If the property is not set at all, Xwayland assumes it is \c
> true.
> + *
> + * \param window The XWM window to control.
> + * \param allow Whether Xwayland is allowed to wl_surface.commit for
> the window.
> + */
> +static void
> +weston_wm_window_set_allow_commits(struct weston_wm_window *window,
> bool allow)
> +{
> + struct weston_wm *wm = window->wm;
> + uint32_t property[1];
> +
> + assert(window->frame_id != XCB_WINDOW_NONE);
> +
> + property[0] = allow ? 1 : 0;
> +
> + xcb_change_property(wm->conn,
> + XCB_PROP_MODE_REPLACE,
> + window->frame_id,
> + wm->atom.allow_commits,
> + XCB_ATOM_CARDINAL,
> + 32, /* format */
> + 1, property);
> +}
> +
>  #define ICCCM_WITHDRAWN_STATE0
>  #define ICCCM_NORMAL_STATE   1
>  #define ICCCM_ICONIC_STATE   3
> @@ -1048,6 +1079,7 @@ weston_wm_handle_map_request(struct weston_wm
> *wm, xcb_generic_event_t *event)
>      window->width, window->height,
>      window->map_request_x, window->map_request_y);
>  
> + weston_wm_window_set_allow_commits(window, false);
>   weston_wm_window_set_wm_state(window, ICCCM_NORMAL_STATE);
>   weston_wm_window_set_net_wm_state(window);
>   weston_wm_window_set_virtual_desktop(window, 0);
> @@ -2220,6 +2252,7 @@ weston_wm_get_resources(struct weston_wm *wm)
>   { "XdndFinished",   F(atom.xdnd_finished) },
>   { "XdndTypeList",   F(atom.xdnd_type_list) },
>   { "XdndActionCopy", F(atom.xdnd_action_copy)
> },
> + { "_XWAYLAND_ALLOW_COMMITS",F(atom.allow_com
> mits) },
>   { "WL_SURFACE_ID",  F(atom.wl_surface_id) }
>   };
>  #undef F
> @@ -2741,10 +2774,13 @@ xserver_map_shell_surface(struct
> weston_wm_window *window,
>   }
>   }
>  
> - if (window->frame_id == XCB_WINDOW_NONE)
> + if (window->frame_id == XCB_WINDOW_NONE) {
>   weston_wm_window_set_pending_state_OR(window);
> - else
> + } else {
>   weston_wm_window_set_pending_state(window);
> + weston_wm_window_set_allow_commits(window, true);
> + xcb_flush(wm->conn);
> + }
>  }
>  
>  const struct weston_xwayland_surface_api surface_api = {
> diff --git a/xwayland/xwayland.h b/xwayland/xwayland.h
> index b1225f5..ca75f5b 100644
> --- a/xwayland/xwayland.h
> +++ b/xwayland/xwayland.h
> @@ -154,6 +154,7 @@ struct weston_wm {
>   xcb_atom_t   xdnd_type_list;
>   xcb_atom_t   xdnd_action_copy;
>   xcb_atom_t   wl_surface_id;
> + xcb_atom_t   allow_commits;
>   } atom;
>  };
>  
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [weston,v3,1/3] xwm: do not draw decor twice on map

2017-04-11 Thread Louis-Francis Ratté-Boulianne
On Wed, 2017-01-18 at 15:37 +0200, Pekka Paalanen wrote:
> From: Pekka Paalanen 
> 
> Normal windows enter the MapRequest handler, which schedules drawing
> the
> decorations. Then Xwayland realizes the window, which ends with a
> call
> to xserver_map_shell_surface(). The decorations are already drawn, no
> need to draw them a second time. However, MapRequest handler could
> not
> set the pending state because the weston_surface did not exist at the
> time, because it gets created only when Xwayland realizes the window,
> which happens after XWM has forwarded the MapWindow in MapRequest
> handler. Therefore set the pending state explicitly at the end.
> Scheduling had it done much later anyway.
> 
> Now that the pending state is set much earlier, it seems to be more
> likely that it gets set before Xwayland's first commit is handled.
> This
> means that -geometry command line option of X11 apps already takes
> the
> geometry (decorations) into account. I do not think it is reliable
> yet,
> though.
> 
> There is still the race between Xwayland committing and XWM setting
> the
> pending state assuming the very next commit latches it in
> appropriately.
> The race exists not because of Wayland, but because WL_SURFACE_ID
> comes
> via X11, and could be processed after wl_compositor.create_surface
> and
> wl_surface.commit. That commit/pending race is solved by a following
> patch.
> 
> For override-redirect windows weston_wm_window_schedule_repaint()
> reduced into a call to weston_wm_window_set_pending_state_OR(), so we
> can just call that directly. It should not matter that the call is
> moved
> to the end of the function.
> 
> Signed-off-by: Pekka Paalanen 

Reviewed-by: Louis-Francis Ratté-Boulianne 

> ---
>  xwayland/window-manager.c | 7 +--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c
> index d40d56e..ac875a3 100644
> --- a/xwayland/window-manager.c
> +++ b/xwayland/window-manager.c
> @@ -2681,8 +2681,6 @@ xserver_map_shell_surface(struct
> weston_wm_window *window,
>   wl_signal_add(&window->surface->destroy_signal,
>     &window->surface_destroy_listener);
>  
> - weston_wm_window_schedule_repaint(window);
> -
>   if (!xwayland_interface)
>   return;
>  
> @@ -2742,6 +2740,11 @@ xserver_map_shell_surface(struct
> weston_wm_window *window,
>   xwayland_interface->set_toplevel(window-
> >shsurf);
>   }
>   }
> +
> + if (window->frame_id == XCB_WINDOW_NONE)
> + weston_wm_window_set_pending_state_OR(window);
> + else
> + weston_wm_window_set_pending_state(window);
>  }
>  
>  const struct weston_xwayland_surface_api surface_api = {
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 7/7] clients: add simple-dmabuf client

2014-12-12 Thread Louis-Francis Ratté-Boulianne
From: George Kiagiadakis 

Signed-off-by: George Kiagiadakis 
Signed-off-by: Louis-Francis Ratté-Boulianne 
---
 .gitignore  |   1 +
 Makefile.am |  15 ++
 clients/simple-dmabuf.c | 578 
 configure.ac|   9 +
 4 files changed, 603 insertions(+)
 create mode 100644 clients/simple-dmabuf.c

diff --git a/.gitignore b/.gitignore
index 2aaeac9..9dbfb9f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -48,6 +48,7 @@ weston-nested-client
 weston-presentation-shm
 weston-resizor
 weston-scaler
+weston-simple-dmabuf
 weston-simple-egl
 weston-simple-shm
 weston-simple-touch
diff --git a/Makefile.am b/Makefile.am
index 16f5d13..06f6ec6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -453,6 +453,21 @@ weston_simple_egl_CFLAGS = $(AM_CFLAGS) 
$(SIMPLE_EGL_CLIENT_CFLAGS)
 weston_simple_egl_LDADD = $(SIMPLE_EGL_CLIENT_LIBS) -lm
 endif
 
+if BUILD_SIMPLE_INTEL_DMABUF_CLIENT
+demo_clients += weston-simple-dmabuf
+weston_simple_dmabuf_SOURCES = clients/simple-dmabuf.c
+nodist_weston_simple_dmabuf_SOURCES =  \
+   protocol/xdg-shell-protocol.c   \
+   protocol/xdg-shell-client-protocol.h\
+   protocol/fullscreen-shell-protocol.c\
+   protocol/fullscreen-shell-client-protocol.h \
+   protocol/linux-dmabuf-protocol.c \
+   protocol/linux-dmabuf-client-protocol.h
+weston_simple_dmabuf_CFLAGS = $(AM_CFLAGS) $(SIMPLE_DMABUF_CLIENT_CFLAGS)
+weston_simple_dmabuf_LDADD = $(SIMPLE_DMABUF_CLIENT_LIBS) libshared.la
+BUILT_SOURCES += protocol/linux-dmabuf-client-protocol.h
+endif
+
 noinst_LTLIBRARIES += libtoytoolkit.la
 
 libtoytoolkit_la_SOURCES = \
diff --git a/clients/simple-dmabuf.c b/clients/simple-dmabuf.c
new file mode 100644
index 000..4635d47
--- /dev/null
+++ b/clients/simple-dmabuf.c
@@ -0,0 +1,578 @@
+/*
+ * Copyright © 2011 Benjamin Franzke
+ * Copyright © 2010 Intel Corporation
+ * Copyright © 2014 Collabora Ltd.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#include 
+#include "xdg-shell-client-protocol.h"
+#include "fullscreen-shell-client-protocol.h"
+#include "linux-dmabuf-client-protocol.h"
+
+struct display {
+   struct wl_display *display;
+   struct wl_registry *registry;
+   struct wl_compositor *compositor;
+   struct xdg_shell *shell;
+   struct _wl_fullscreen_shell *fshell;
+   struct zlinux_dmabuf *dmabuf;
+   int xrgb_format_found;
+};
+
+struct buffer {
+   struct wl_buffer *buffer;
+   struct zlinux_dmabuf_create_feedback *feedback;
+   int busy;
+
+   int drm_fd;
+
+   drm_intel_bufmgr *bufmgr;
+   drm_intel_bo *bo;
+
+   uint32_t gem_handle;
+   int dmabuf_fd;
+   uint8_t *mmap;
+
+   int width;
+   int height;
+   int bpp;
+   unsigned long stride;
+};
+
+struct window {
+   struct display *display;
+   int width, height;
+   struct wl_surface *surface;
+   struct xdg_surface *xdg_surface;
+   struct buffer buffers[2];
+   struct buffer *prev_buffer;
+   struct wl_callback *callback;
+};
+
+static int running = 1;
+
+static void
+buffer_release(void *data, struct wl_buffer *buffer)
+{
+   struct buffer *mybuf = data;
+
+   mybuf->busy = 0;
+}
+
+static const struct wl_buffer_listener buffer_listener = {
+   buffer_release
+};
+
+static int
+drm_connect(struct buffer *my_buf)
+{
+   /* This won't work with card0 as we need to be authenticated; instead,
+* boot with drm.rnodes=1 and use that. */
+   my_buf->drm_fd = open("/dev/dri/renderD128", O_RDWR);
+   if (my_buf-&g

[PATCH 4/7] compositor-x11: init linux_dmabuf support

2014-12-12 Thread Louis-Francis Ratté-Boulianne
From: Pekka Paalanen 

---
 src/compositor-x11.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/src/compositor-x11.c b/src/compositor-x11.c
index a760f33..7b15ba9 100644
--- a/src/compositor-x11.c
+++ b/src/compositor-x11.c
@@ -51,6 +51,7 @@
 #include "pixman-renderer.h"
 #include "../shared/config-parser.h"
 #include "../shared/image-loader.h"
+#include "linux-dmabuf.h"
 
 #define DEFAULT_AXIS_STEP_DISTANCE wl_fixed_from_int(10)
 
@@ -1587,6 +1588,10 @@ x11_compositor_create(struct wl_display *display,
 x11_compositor_handle_event, c);
wl_event_source_check(c->xcb_source);
 
+   /* XXX: check that dmabuf import is available in renderer */
+   if (linux_dmabuf_setup(&c->base) < 0)
+   weston_log("Error: initializing dmabuf support failed.\n");
+
return &c->base;
 
 err_x11_input:
-- 
2.1.0

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 1/7] protocol: add linux_dmabuf extension RFCv1

2014-12-12 Thread Louis-Francis Ratté-Boulianne
From: Pekka Paalanen 

An experimental (hence the 'z' prefix) linux_dmabuf Wayland protocol
extension for creating dmabuf-based wl_buffers in a generic manner.

This does not include proper dmabuf metadata negotiation because
there is no way to communicate all dmabuf constraints from the
compositor to a client before-hand. The client has to create a
wl_buffer wrapping one or more dmabuf buffers and then listen at
the feedback object returned to know if the operation was successful.

Signed-off-by: Pekka Paalanen 
Signed-off-by: Louis-Francis Ratté-Boulianne 
---
 Makefile.am   |   7 +-
 protocol/linux-dmabuf.xml | 224 ++
 2 files changed, 229 insertions(+), 2 deletions(-)
 create mode 100644 protocol/linux-dmabuf.xml

diff --git a/Makefile.am b/Makefile.am
index 494266d..0462fdd 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -91,7 +91,9 @@ nodist_weston_SOURCES =   
\
protocol/presentation_timing-protocol.c \
protocol/presentation_timing-server-protocol.h  \
protocol/scaler-protocol.c  \
-   protocol/scaler-server-protocol.h
+   protocol/scaler-server-protocol.h   \
+   protocol/linux-dmabuf-protocol.c\
+   protocol/linux-dmabuf-server-protocol.h
 
 BUILT_SOURCES += $(nodist_weston_SOURCES)
 
@@ -1101,7 +1103,8 @@ EXTRA_DIST += \
protocol/presentation_timing.xml\
protocol/scaler.xml \
protocol/ivi-application.xml\
-   protocol/ivi-hmi-controller.xml
+   protocol/ivi-hmi-controller.xml \
+   protocol/linux-dmabuf.xml
 
 man_MANS = weston.1 weston.ini.5
 
diff --git a/protocol/linux-dmabuf.xml b/protocol/linux-dmabuf.xml
new file mode 100644
index 000..c48121c
--- /dev/null
+++ b/protocol/linux-dmabuf.xml
@@ -0,0 +1,224 @@
+
+
+
+  
+Copyright © 2014 Collabora, Ltd.
+
+Permission to use, copy, modify, distribute, and sell this
+software and its documentation for any purpose is hereby granted
+without fee, provided that the above copyright notice appear in
+all copies and that both that copyright notice and this permission
+notice appear in supporting documentation, and that the name of
+the copyright holders not be used in advertising or publicity
+pertaining to distribution of the software without specific,
+written prior permission.  The copyright holders make no
+representations about the suitability of this software for any
+purpose.  It is provided "as is" without express or implied
+warranty.
+
+THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+  
+
+  
+
+  Following the interfaces from:
+  
https://www.khronos.org/registry/egl/extensions/EXT/EGL_EXT_image_dma_buf_import.txt
+
+  This interface offers a way to create generic dmabuf-based
+  wl_buffers. Immediately after a client binds to this interface,
+  the set of supported formats is sent with 'format' events.
+
+
+
+  
+  
+  
+  
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
+
+
+  
+  
+
+
+
+  
+This temporary object is used to collect multiple dmabuf handles
+into a single batch.
+  
+  
+
+
+
+  
+The result of the operation will be returned via the provided
+zlinux_dmabuf_create_feedback object.
+
+The dmabuf_batch object must be destroyed immediately after
+after this request.
+
+Any errors in importing the set of dmabufs can be delivered as
+protocol errors immediately or later.
+  
+  
+  
+  
+  
+  
+
+
+
+  
+This event advertises one buffer format that the server support.
+All the supported formats advertised once when the client
+binds to this interface. A roundtrip after binding guarantees,
+that the client has 

[PATCH 5/7] compositor-drm: init linux_dmabuf support

2014-12-12 Thread Louis-Francis Ratté-Boulianne
From: Pekka Paalanen 

---
 src/compositor-drm.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 9b4d4dc..44fc912 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -50,6 +50,7 @@
 #include "libinput-seat.h"
 #include "launcher-util.h"
 #include "vaapi-recorder.h"
+#include "linux-dmabuf.h"
 
 #ifndef DRM_CAP_TIMESTAMP_MONOTONIC
 #define DRM_CAP_TIMESTAMP_MONOTONIC 0x6
@@ -2881,6 +2882,10 @@ drm_compositor_create(struct wl_display *display,
weston_compositor_add_debug_binding(&ec->base, KEY_W,
renderer_switch_binding, ec);
 
+   /* XXX: check that dmabuf import is available in renderer */
+   if (linux_dmabuf_setup(&ec->base) < 0)
+   weston_log("Error: initializing dmabuf support failed.\n");
+
return &ec->base;
 
 err_udev_monitor:
-- 
2.1.0

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 0/7] Generic dmabuf protocol RFCv1

2014-12-12 Thread Louis-Francis Ratté-Boulianne
This serie of patches by Pekka and George contains an experimental
implementation of "zlinux_dmabuf" protocol.

See these links for more information about the design and failed previous
attempts:

http://lists.freedesktop.org/archives/wayland-devel/2014-June/015362.html
https://bugs.freedesktop.org/show_bug.cgi?id=83881

This protocol allows clients to wrap a dmabuf into a wl_buffer, and push that
into the compositor for display. The compositor then uses GBM to import that
wl_buffer as a bo for compositing with GL (via EGLImage) or direct scanout as a
DRM FB object.

Note that a round-trip is needed when creating the buffer because there is no
way to communicate all dmabuf constraints from the compositor to a client
before-hand. They are simply too complicated and changing to be described in
a Wayland protocol extension. In fact, there are existing APIs like EGL (the
dmabuf import extension) that are based on trial-and-error rather than knowing
the constraints before-hand.

However, the protocol design is far far away from complete. Even the kernel
developers are still discussing, how cross-device support for dmabufs should
work, and what is the proper information split between the kernel and the user
space. How do you communicate, or even describe, things like tiling formats.

But, we should start from somewhere, and this patch is pushing the user space
part forward a bit.

The extension is especially useful for video players and this pipeline has been
demonstrated to work with GStreamer:

http://cgit.collabora.com/git/user/gkiagia/gst-plugins-bad.git/commit/?h=inteldmabufupload&id=727732c6de87949278cd53436ba2c430956cd8f9


George Kiagiadakis (1):
  clients: add simple-dmabuf client

Pekka Paalanen (6):
  protocol: add linux_dmabuf extension RFCv1
  dmabuf: implement linux_dmabuf extension
  gl-renderer: add dmabuf import
  compositor-x11: init linux_dmabuf support
  compositor-drm: init linux_dmabuf support
  compositor-drm: dmabuf GBM import

 .gitignore|   1 +
 Makefile.am   |  24 +-
 clients/simple-dmabuf.c   | 578 ++
 configure.ac  |   9 +
 protocol/linux-dmabuf.xml | 224 ++
 src/compositor-drm.c  |  31 ++-
 src/compositor-x11.c  |   5 +
 src/gl-renderer.c | 103 +
 src/linux-dmabuf.c| 322 ++
 src/linux-dmabuf.h|  45 
 10 files changed, 1336 insertions(+), 6 deletions(-)
 create mode 100644 clients/simple-dmabuf.c
 create mode 100644 protocol/linux-dmabuf.xml
 create mode 100644 src/linux-dmabuf.c
 create mode 100644 src/linux-dmabuf.h

-- 
2.1.0

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 6/7] compositor-drm: dmabuf GBM import

2014-12-12 Thread Louis-Francis Ratté-Boulianne
From: Pekka Paalanen 

---
 src/compositor-drm.c | 26 ++
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 44fc912..d3e8b34 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -839,7 +839,9 @@ drm_output_prepare_overlay_view(struct weston_output 
*output_base,
struct weston_compositor *ec = output_base->compositor;
struct drm_compositor *c =(struct drm_compositor *) ec;
struct weston_buffer_viewport *viewport = &ev->surface->buffer_viewport;
+   struct wl_resource *buffer_resource;
struct drm_sprite *s;
+   struct linux_dmabuf_buffer *dmabuf;
int found = 0;
struct gbm_bo *bo;
pixman_region32_t dest_rect, src_rect;
@@ -864,11 +866,12 @@ drm_output_prepare_overlay_view(struct weston_output 
*output_base,
 
if (ev->surface->buffer_ref.buffer == NULL)
return NULL;
+   buffer_resource = ev->surface->buffer_ref.buffer->resource;
 
if (ev->alpha != 1.0f)
return NULL;
 
-   if (wl_shm_buffer_get(ev->surface->buffer_ref.buffer->resource))
+   if (wl_shm_buffer_get(buffer_resource))
return NULL;
 
if (!drm_view_transform_supported(ev))
@@ -888,9 +891,24 @@ drm_output_prepare_overlay_view(struct weston_output 
*output_base,
if (!found)
return NULL;
 
-   bo = gbm_bo_import(c->gbm, GBM_BO_IMPORT_WL_BUFFER,
-  ev->surface->buffer_ref.buffer->resource,
-  GBM_BO_USE_SCANOUT);
+   if ((dmabuf = linux_dmabuf_buffer_get(buffer_resource))) {
+   struct gbm_import_fd_data gbm_dmabuf = {
+   .fd = dmabuf->dmabuf_fd[0],
+   .width  = dmabuf->width,
+   .height = dmabuf->height,
+   .stride = dmabuf->stride[0],
+   .format = dmabuf->format
+   };
+
+   if (dmabuf->n_planes != 1 || dmabuf->offset[0] != 0)
+   return NULL;
+
+   bo = gbm_bo_import(c->gbm, GBM_BO_IMPORT_FD, &gbm_dmabuf,
+  GBM_BO_USE_SCANOUT);
+   } else {
+   bo = gbm_bo_import(c->gbm, GBM_BO_IMPORT_WL_BUFFER,
+  buffer_resource, GBM_BO_USE_SCANOUT);
+   }
if (!bo)
return NULL;
 
-- 
2.1.0

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 3/7] gl-renderer: add dmabuf import

2014-12-12 Thread Louis-Francis Ratté-Boulianne
From: Pekka Paalanen 

Squashed with:
 gl-renderer: error if dmabuf exposed unsupported
 gl_renderer: always use GL_TEXTURE_EXTERNAL_OES with dmabuf
---
 src/gl-renderer.c | 103 ++
 1 file changed, 103 insertions(+)

diff --git a/src/gl-renderer.c b/src/gl-renderer.c
index bb46acd..bb4e409 100644
--- a/src/gl-renderer.c
+++ b/src/gl-renderer.c
@@ -35,6 +35,8 @@
 
 #include "gl-renderer.h"
 #include "vertex-clipping.h"
+#include "linux-dmabuf.h"
+#include "linux-dmabuf-server-protocol.h"
 
 #include 
 #include "weston-egl-ext.h"
@@ -149,6 +151,8 @@ struct gl_renderer {
 
int has_configless_context;
 
+   int has_dmabuf_import;
+
struct gl_shader texture_shader_rgba;
struct gl_shader texture_shader_rgbx;
struct gl_shader texture_shader_egl_external;
@@ -1305,12 +1309,104 @@ gl_renderer_attach_egl(struct weston_surface *es, 
struct weston_buffer *buffer,
 }
 
 static void
+gl_renderer_attach_dmabuf(struct weston_surface *surface,
+ struct weston_buffer *buffer,
+ struct linux_dmabuf_buffer *dmabuf)
+{
+#ifdef EGL_EXT_image_dma_buf_import
+   struct gl_renderer *gr = get_renderer(surface->compositor);
+   struct gl_surface_state *gs = get_surface_state(surface);
+   EGLint attribs[30];
+   int atti = 0;
+   int i;
+
+   assert(gr->has_dmabuf_import);
+
+   buffer->width = dmabuf->width;
+   buffer->height = dmabuf->height;
+   buffer->y_inverted = 1; /* XXX: readlly? */
+
+   attribs[atti++] = EGL_WIDTH;
+   attribs[atti++] = dmabuf->width;
+   attribs[atti++] = EGL_HEIGHT;
+   attribs[atti++] = dmabuf->height;
+   attribs[atti++] = EGL_LINUX_DRM_FOURCC_EXT;
+   attribs[atti++] = dmabuf->format;
+
+   if (dmabuf->n_planes > 0) {
+   attribs[atti++] = EGL_DMA_BUF_PLANE0_FD_EXT;
+   attribs[atti++] = dmabuf->dmabuf_fd[0];
+   attribs[atti++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT;
+   attribs[atti++] = dmabuf->offset[0];
+   attribs[atti++] = EGL_DMA_BUF_PLANE0_PITCH_EXT;
+   attribs[atti++] = dmabuf->stride[0];
+   }
+
+   if (dmabuf->n_planes > 1) {
+   attribs[atti++] = EGL_DMA_BUF_PLANE1_FD_EXT;
+   attribs[atti++] = dmabuf->dmabuf_fd[1];
+   attribs[atti++] = EGL_DMA_BUF_PLANE1_OFFSET_EXT;
+   attribs[atti++] = dmabuf->offset[1];
+   attribs[atti++] = EGL_DMA_BUF_PLANE1_PITCH_EXT;
+   attribs[atti++] = dmabuf->stride[1];
+   }
+
+   if (dmabuf->n_planes > 2) {
+   attribs[atti++] = EGL_DMA_BUF_PLANE2_FD_EXT;
+   attribs[atti++] = dmabuf->dmabuf_fd[2];
+   attribs[atti++] = EGL_DMA_BUF_PLANE2_OFFSET_EXT;
+   attribs[atti++] = dmabuf->offset[2];
+   attribs[atti++] = EGL_DMA_BUF_PLANE2_PITCH_EXT;
+   attribs[atti++] = dmabuf->stride[2];
+   }
+
+   attribs[atti++] = EGL_NONE;
+
+   for (i = 0; i < gs->num_images; i++)
+   gr->destroy_image(gr->egl_display, gs->images[i]);
+   gs->num_images = 0;
+   gs->target = GL_TEXTURE_EXTERNAL_OES;
+   gs->shader = &gr->texture_shader_egl_external;
+
+   ensure_textures(gs, 1);
+
+   gs->images[0] = gr->create_image(gr->egl_display, EGL_NO_CONTEXT,
+EGL_LINUX_DMA_BUF_EXT, NULL,
+attribs);
+   if (!gs->images[0]) {
+   /* XXX: wrong resource for error code */
+   wl_resource_post_error(dmabuf->resource,
+  ZLINUX_DMABUF_ERROR_INVALID_DMABUF,
+  "dmabuf import to EGL failed");
+   return;
+   }
+   gs->num_images = 1;
+
+   glActiveTexture(GL_TEXTURE0);
+   glBindTexture(gs->target, gs->textures[0]);
+   gr->image_target_texture_2d(gs->target, gs->images[0]);
+
+   gs->pitch = buffer->width;
+   gs->height = buffer->height;
+   gs->buffer_type = BUFFER_TYPE_EGL;
+   gs->y_inverted = buffer->y_inverted;
+
+#else
+   /* XXX: wrong resource for error code */
+   wl_resource_post_error(dmabuf->resource,
+  ZLINUX_DMABUF_ERROR_INVALID_DMABUF,
+  "implementation error: EGL dmabuf import");
+#endif /* EGL_EXT_image_dma_buf_import */
+}
+
+static void
 gl_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
 {
struct weston_compositor *ec = es->compositor;
struct gl_renderer *gr = get_renderer(ec);
struct gl_surface_state *gs = get_surface_state(es);
struct wl_shm_buffer *shm_buffer;
+   struct linux_dmabuf_buffer *dmabuf;
EGLint format;
int i;
 
@@ -1336,6 +1432,8 @@ gl_renderer_attach(struct weston_surface *es, struct 
weston_buffer *buffer)
else if (gr-

[PATCH 2/7] dmabuf: implement linux_dmabuf extension

2014-12-12 Thread Louis-Francis Ratté-Boulianne
From: Pekka Paalanen 

Signed-off-by: Pekka Paalanen 
Signed-off-by: Louis-Francis Ratté-Boulianne 
---
 Makefile.am|   2 +
 src/linux-dmabuf.c | 322 +
 src/linux-dmabuf.h |  45 
 3 files changed, 369 insertions(+)
 create mode 100644 src/linux-dmabuf.c
 create mode 100644 src/linux-dmabuf.h

diff --git a/Makefile.am b/Makefile.am
index 0462fdd..16f5d13 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -72,6 +72,8 @@ weston_SOURCES =  \
src/timeline.c  \
src/timeline.h  \
src/timeline-object.h   \
+   src/linux-dmabuf.c  \
+   src/linux-dmabuf.h  \
shared/matrix.c \
shared/matrix.h \
shared/zalloc.h \
diff --git a/src/linux-dmabuf.c b/src/linux-dmabuf.c
new file mode 100644
index 000..769bf60
--- /dev/null
+++ b/src/linux-dmabuf.c
@@ -0,0 +1,322 @@
+/*
+ * Copyright © 2014 Collabora, Ltd.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holders not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  The copyright holders make
+ * no representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "config.h"
+
+#include 
+
+#include "compositor.h"
+#include "linux-dmabuf.h"
+#include "linux-dmabuf-server-protocol.h"
+
+struct dmabuf_item {
+   int fd;
+   int n_planes;
+   int32_t offset[3];
+   int32_t stride[3];
+};
+
+struct dmabuf_batch {
+   struct wl_resource *resource;
+   int n_bufs;
+   struct wl_array bufs; /* struct dmabuf_item */
+};
+
+static void
+destroy_dmabuf_batch(struct wl_resource *dmabuf_batch_resource)
+{
+   struct dmabuf_batch *batch;
+   struct dmabuf_item *buf;
+
+   batch = wl_resource_get_user_data(dmabuf_batch_resource);
+
+   wl_array_for_each(buf, &batch->bufs)
+   close(buf->fd);
+   wl_array_release(&batch->bufs);
+
+   free(batch);
+}
+
+static void
+dmabuf_batch_destroy(struct wl_client *client, struct wl_resource *resource)
+{
+   wl_resource_destroy(resource);
+}
+
+static void
+dmabuf_batch_add(struct wl_client *client,
+struct wl_resource *resource,
+int32_t name,
+int32_t offset0,
+int32_t stride0,
+int32_t offset1,
+int32_t stride1,
+int32_t offset2,
+int32_t stride2)
+{
+   struct dmabuf_batch *batch = wl_resource_get_user_data(resource);
+   struct dmabuf_item *buf;
+
+   buf = wl_array_add(&batch->bufs, sizeof *buf);
+   if (!buf) {
+   wl_client_post_no_memory(client);
+   return;
+   }
+
+   buf->fd = name;
+   buf->n_planes = 1;
+   buf->offset[0] = offset0;
+   buf->stride[0] = stride0;
+
+   if (offset1 && stride1) {
+   buf->offset[buf->n_planes] = offset1;
+   buf->stride[buf->n_planes] = stride1;
+   buf->n_planes++;
+   }
+
+   if (offset2 && stride2) {
+   buf->offset[buf->n_planes] = offset2;
+   buf->stride[buf->n_planes] = stride2;
+   buf->n_planes++;
+   }
+}
+
+static const struct dmabuf_batch_interface dmabuf_batch_implementation = {
+   dmabuf_batch_destroy,
+   dmabuf_batch_add
+};
+
+static void
+linux_dmabuf_destroy(struct wl_client *client, struct wl_resource *resource)
+{
+   wl_resource_destroy(resource);
+}
+
+static void
+linux_dmabuf_create_batch(struct wl_client *client,
+ struct wl_resource *linux_dmabuf_resource,
+ uint32_t batch_id)
+{
+   struct dm

[PATCH 3/8] weston-info: report presentation clock

2014-09-23 Thread Louis-Francis Ratté-Boulianne
From: Pekka Paalanen 

Signed-off-by: Pekka Paalanen 
v3 Reviewed-by: Mario Kleiner 
---
 Makefile.am   |  3 ++
 clients/weston-info.c | 81 +++
 2 files changed, 84 insertions(+)

diff --git a/Makefile.am b/Makefile.am
index b1dcc21..6a91a8f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -582,6 +582,9 @@ weston_simple_im_LDADD = $(CLIENT_LIBS)
 weston_simple_im_CFLAGS = $(AM_CFLAGS) $(CLIENT_CFLAGS)
 
 weston_info_SOURCES = clients/weston-info.c
+nodist_weston_info_SOURCES =   \
+   protocol/presentation_timing-protocol.c \
+   protocol/presentation_timing-client-protocol.h
 weston_info_LDADD = $(WESTON_INFO_LIBS) libshared.la
 weston_info_CFLAGS = $(AM_CFLAGS) $(CLIENT_CFLAGS)
 
diff --git a/clients/weston-info.c b/clients/weston-info.c
index c53ac74..f777982 100644
--- a/clients/weston-info.c
+++ b/clients/weston-info.c
@@ -27,10 +27,14 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
 #include "../shared/os-compatibility.h"
+#include "presentation_timing-client-protocol.h"
+
+#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
 
 #define MIN(x,y) (((x) < (y)) ? (x) : (y))
 
@@ -98,6 +102,13 @@ struct seat_info {
int32_t repeat_delay;
 };
 
+struct presentation_info {
+   struct global_info global;
+   struct presentation *presentation;
+
+   clockid_t clk_id;
+};
+
 struct weston_info {
struct wl_display *display;
struct wl_registry *registry;
@@ -554,6 +565,74 @@ add_output_info(struct weston_info *info, uint32_t id, 
uint32_t version)
 }
 
 static void
+destroy_presentation_info(void *info)
+{
+   struct presentation_info *prinfo = info;
+
+   presentation_destroy(prinfo->presentation);
+}
+
+static const char *
+clock_name(clockid_t clk_id)
+{
+   static const char *names[] = {
+   [CLOCK_REALTIME] =  "CLOCK_REALTIME",
+   [CLOCK_MONOTONIC] = "CLOCK_MONOTONIC",
+   [CLOCK_MONOTONIC_RAW] = "CLOCK_MONOTONIC_RAW",
+   [CLOCK_REALTIME_COARSE] =   "CLOCK_REALTIME_COARSE",
+   [CLOCK_MONOTONIC_COARSE] =  "CLOCK_MONOTONIC_COARSE",
+   [CLOCK_BOOTTIME] =  "CLOCK_BOOTTIME",
+   };
+
+   if (clk_id < 0 || (unsigned)clk_id >= ARRAY_LENGTH(names))
+   return "unknown";
+
+   return names[clk_id];
+}
+
+static void
+print_presentation_info(void *info)
+{
+   struct presentation_info *prinfo = info;
+
+   print_global_info(info);
+
+   printf("\tpresentation clock id: %d (%s)\n",
+   prinfo->clk_id, clock_name(prinfo->clk_id));
+}
+
+static void
+presentation_handle_clock_id(void *data, struct presentation *presentation,
+uint32_t clk_id)
+{
+   struct presentation_info *prinfo = data;
+
+   prinfo->clk_id = clk_id;
+}
+
+static const struct presentation_listener presentation_listener = {
+   presentation_handle_clock_id
+};
+
+static void
+add_presentation_info(struct weston_info *info, uint32_t id, uint32_t version)
+{
+   struct presentation_info *prinfo = xzalloc(sizeof *prinfo);
+
+   init_global_info(info, &prinfo->global, id, "presentation", version);
+   prinfo->global.print = print_presentation_info;
+   prinfo->global.destroy = destroy_presentation_info;
+
+   prinfo->clk_id = -1;
+   prinfo->presentation = wl_registry_bind(info->registry, id,
+   &presentation_interface, 1);
+   presentation_add_listener(prinfo->presentation, &presentation_listener,
+ prinfo);
+
+   info->roundtrip_needed = true;
+}
+
+static void
 destroy_global_info(void *data)
 {
 }
@@ -581,6 +660,8 @@ global_handler(void *data, struct wl_registry *registry, 
uint32_t id,
add_shm_info(info, id, version);
else if (!strcmp(interface, "wl_output"))
add_output_info(info, id, version);
+   else if (!strcmp(interface, "presentation"))
+   add_presentation_info(info, id, version);
else
add_global_info(info, id, interface, version);
 }
-- 
1.9.3

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 6/8] compositor-drm: deliver frame seq for feedback

2014-09-23 Thread Louis-Francis Ratté-Boulianne
From: Pekka Paalanen 

Add 'msc' field to weston_output to maintain the refresh counter, and
use it in presentation_feedback.presented.

Make compositor-drm update the per-output refresh counter with the
values reported by DRM. If the DRM reported value jumps backwards,
assume it wrapped around once.

Other backends do not update weston_output::msc, and there
presentation_feedback will always deliver refresh counter as zero.

Signed-off-by: Pekka Paalanen 
v3 Reviewed-by: Mario Kleiner 
---
 src/compositor-drm.c | 14 ++
 src/compositor.c |  2 +-
 src/compositor.h |  1 +
 3 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 626a2de..07b83a7 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -726,6 +726,17 @@ finish_frame:
 }
 
 static void
+drm_output_update_msc(struct drm_output *output, unsigned int seq)
+{
+   uint64_t msc_hi = output->base.msc >> 32;
+
+   if (seq < (output->base.msc & 0x))
+   msc_hi++;
+
+   output->base.msc = (msc_hi << 32) + seq;
+}
+
+static void
 vblank_handler(int fd, unsigned int frame, unsigned int sec, unsigned int usec,
   void *data)
 {
@@ -733,6 +744,7 @@ vblank_handler(int fd, unsigned int frame, unsigned int 
sec, unsigned int usec,
struct drm_output *output = s->output;
struct timespec ts;
 
+   drm_output_update_msc(output, frame);
output->vblank_pending = 0;
 
drm_output_release_fb(output, s->current);
@@ -756,6 +768,8 @@ page_flip_handler(int fd, unsigned int frame,
struct drm_output *output = (struct drm_output *) data;
struct timespec ts;
 
+   drm_output_update_msc(output, frame);
+
/* We don't set page_flip_pending on start_repaint_loop, in that case
 * we just want to page flip to the current buffer to get an accurate
 * timestamp */
diff --git a/src/compositor.c b/src/compositor.c
index 462f922..48e5cc4 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -2069,7 +2069,7 @@ weston_output_finish_frame(struct weston_output *output,
refresh_nsec = 1UL / output->current_mode->refresh;
weston_presentation_feedback_present_list(&output->feedback_list,
  output, refresh_nsec, stamp,
- 0);
+ output->msc);
 
output->frame_time = stamp->tv_sec * 1000 + stamp->tv_nsec / 100;
 
diff --git a/src/compositor.h b/src/compositor.h
index 548ffe5..a1ab9d5 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -203,6 +203,7 @@ struct weston_output {
struct wl_signal destroy_signal;
int move_x, move_y;
uint32_t frame_time; /* presentation timestamp in milliseconds */
+   uint64_t msc;/* media stream counter */
int disable_planes;
int destroying;
struct wl_list feedback_list;
-- 
1.9.3

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 5/8] compositor: implement presentation_feedback

2014-09-23 Thread Louis-Francis Ratté-Boulianne
From: Pekka Paalanen 

Implement the presentation.feedback request, and the
presentation_feedback protocol interface. Feedback information is
delivered to clients as the backend reports it, except the refresh
counter (MSC) which is always reported as zero.

Changes in v4:

* add 'flags' argument to 'presented' event without implementation

Changes in v5:

* remove the 'destroy' method implementation for feedback objects

v5 Signed-off-by: Pekka Paalanen 
v3 Reviewed-by: Mario Kleiner 
---
 src/compositor.c | 149 +--
 src/compositor.h |   5 ++
 2 files changed, 150 insertions(+), 4 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index f34d712..462f922 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -439,6 +439,78 @@ struct weston_frame_callback {
struct wl_list link;
 };
 
+struct weston_presentation_feedback {
+   struct wl_resource *resource;
+
+   /* XXX: could use just wl_resource_get_link() instead */
+   struct wl_list link;
+};
+
+static void
+weston_presentation_feedback_discard(
+   struct weston_presentation_feedback *feedback)
+{
+   presentation_feedback_send_discarded(feedback->resource);
+   wl_list_remove(&feedback->link);
+   wl_list_init(&feedback->link);
+   wl_resource_destroy(feedback->resource);
+}
+
+static void
+weston_presentation_feedback_discard_list(struct wl_list *list)
+{
+   struct weston_presentation_feedback *feedback, *tmp;
+
+   wl_list_for_each_safe(feedback, tmp, list, link)
+   weston_presentation_feedback_discard(feedback);
+}
+
+static void
+weston_presentation_feedback_present(
+   struct weston_presentation_feedback *feedback,
+   struct weston_output *output,
+   uint32_t refresh_nsec,
+   const struct timespec *ts,
+   uint64_t seq)
+{
+   struct wl_client *client = wl_resource_get_client(feedback->resource);
+   struct wl_resource *o;
+   uint64_t secs;
+   uint32_t flags = 0;
+
+   wl_resource_for_each(o, &output->resource_list) {
+   if (wl_resource_get_client(o) != client)
+   continue;
+
+   presentation_feedback_send_sync_output(feedback->resource, o);
+   }
+
+   secs = ts->tv_sec;
+   presentation_feedback_send_presented(feedback->resource,
+secs >> 32, secs & 0x,
+ts->tv_nsec,
+refresh_nsec,
+seq >> 32, seq & 0x,
+flags);
+   wl_list_remove(&feedback->link);
+   wl_list_init(&feedback->link);
+   wl_resource_destroy(feedback->resource);
+}
+
+static void
+weston_presentation_feedback_present_list(struct wl_list *list,
+ struct weston_output *output,
+ uint32_t refresh_nsec,
+ const struct timespec *ts,
+ uint64_t seq)
+{
+   struct weston_presentation_feedback *feedback, *tmp;
+
+   wl_list_for_each_safe(feedback, tmp, list, link)
+   weston_presentation_feedback_present(feedback, output,
+refresh_nsec, ts, seq);
+}
+
 static void
 surface_state_handle_buffer_destroy(struct wl_listener *listener, void *data)
 {
@@ -464,6 +536,7 @@ weston_surface_state_init(struct weston_surface_state 
*state)
region_init_infinite(&state->input);
 
wl_list_init(&state->frame_callback_list);
+   wl_list_init(&state->feedback_list);
 
state->buffer_viewport.buffer.transform = WL_OUTPUT_TRANSFORM_NORMAL;
state->buffer_viewport.buffer.scale = 1;
@@ -481,6 +554,8 @@ weston_surface_state_fini(struct weston_surface_state 
*state)
  &state->frame_callback_list, link)
wl_resource_destroy(cb->resource);
 
+   weston_presentation_feedback_discard_list(&state->feedback_list);
+
pixman_region32_fini(&state->input);
pixman_region32_fini(&state->opaque);
pixman_region32_fini(&state->damage);
@@ -539,6 +614,7 @@ weston_surface_create(struct weston_compositor *compositor)
wl_list_init(&surface->views);
 
wl_list_init(&surface->frame_callback_list);
+   wl_list_init(&surface->feedback_list);
 
wl_list_init(&surface->subsurface_list);
wl_list_init(&surface->subsurface_list_pending);
@@ -1555,6 +1631,8 @@ weston_surface_destroy(struct weston_surface *surface)
wl_list_for_each_safe(cb, next, &surface->frame_callback_list, link)
wl_resource_destroy(cb->resource);
 
+   weston_presentation_feedback_discard_list(&surface->feedback_list);
+
free(surface);
 }
 
@@ -1656,6 +1734,

[PATCH 2/8] compositor: add stub implementation of presentation interface

2014-09-23 Thread Louis-Francis Ratté-Boulianne
From: Pekka Paalanen 

You can bind to the global interface, and it delivers a fake clock id.
All requests on it raise an error.

Changes in v4:

* queuing methods were extractracted for a later series

[Louis-Francis Ratté-Boulianne: split queuing feature]

Signed-off-by: Pekka Paalanen 
Signed-off-by: Louis-Francis Ratté-Boulianne 
Reviewed-by: Mario Kleiner 
---
 src/compositor.c | 47 ++-
 1 file changed, 46 insertions(+), 1 deletion(-)

diff --git a/src/compositor.c b/src/compositor.c
index a219766..d789508 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -1,7 +1,7 @@
 /*
  * Copyright © 2010-2011 Intel Corporation
  * Copyright © 2008-2011 Kristian Høgsberg
- * Copyright © 2012 Collabora, Ltd.
+ * Copyright © 2012-2014 Collabora, Ltd.
  *
  * Permission to use, copy, modify, distribute, and sell this software and
  * its documentation for any purpose is hereby granted without fee, provided
@@ -55,6 +55,7 @@
 
 #include "compositor.h"
 #include "scaler-server-protocol.h"
+#include "presentation_timing-server-protocol.h"
 #include "../shared/os-compatibility.h"
 #include "git-version.h"
 #include "version.h"
@@ -3736,6 +3737,46 @@ bind_scaler(struct wl_client *client,
 }
 
 static void
+presentation_destroy(struct wl_client *client, struct wl_resource *resource)
+{
+   wl_resource_destroy(resource);
+}
+
+static void
+presentation_feedback(struct wl_client *client,
+ struct wl_resource *resource,
+ struct wl_resource *surface,
+ uint32_t callback)
+{
+   wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_METHOD,
+  "presentation_feedback unimplemented");
+}
+
+static const struct presentation_interface presentation_implementation = {
+   presentation_destroy,
+   presentation_feedback
+};
+
+static void
+bind_presentation(struct wl_client *client,
+ void *data, uint32_t version, uint32_t id)
+{
+   struct weston_compositor *compositor = data;
+   struct wl_resource *resource;
+
+   resource = wl_resource_create(client, &presentation_interface,
+ MIN(version, 1), id);
+   if (resource == NULL) {
+   wl_client_post_no_memory(client);
+   return;
+   }
+
+   wl_resource_set_implementation(resource, &presentation_implementation,
+  compositor, NULL);
+   presentation_send_clock_id(resource, CLOCK_MONOTONIC);
+}
+
+static void
 compositor_bind(struct wl_client *client,
void *data, uint32_t version, uint32_t id)
 {
@@ -3830,6 +3871,10 @@ weston_compositor_init(struct weston_compositor *ec,
  ec, bind_scaler))
return -1;
 
+   if (!wl_global_create(ec->wl_display, &presentation_interface, 1,
+ ec, bind_presentation))
+   return -1;
+
wl_list_init(&ec->view_list);
wl_list_init(&ec->plane_list);
wl_list_init(&ec->layer_list);
-- 
1.9.3

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 7/8] tests: presentation test, simple

2014-09-23 Thread Louis-Francis Ratté-Boulianne
From: Pekka Paalanen 

---
 Makefile.am   |   8 ++
 tests/presentation-test.c | 246 ++
 2 files changed, 254 insertions(+)
 create mode 100644 tests/presentation-test.c

diff --git a/Makefile.am b/Makefile.am
index 6a91a8f..87204a6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -842,6 +842,7 @@ weston_tests =  \
event.weston\
button.weston   \
text.weston \
+   presentation.weston \
subsurface.weston
 
 
@@ -944,6 +945,13 @@ subsurface_weston_SOURCES = tests/subsurface-test.c
 subsurface_weston_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS)
 subsurface_weston_LDADD = libtest-client.la
 
+presentation_weston_SOURCES = tests/presentation-test.c
+nodist_presentation_weston_SOURCES =   \
+   protocol/presentation_timing-protocol.c \
+   protocol/presentation_timing-client-protocol.h
+presentation_weston_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS)
+presentation_weston_LDADD = libtest-client.la
+
 if ENABLE_EGL
 weston_tests += buffer-count.weston
 buffer_count_weston_SOURCES = tests/buffer-count-test.c
diff --git a/tests/presentation-test.c b/tests/presentation-test.c
new file mode 100644
index 000..57012fa
--- /dev/null
+++ b/tests/presentation-test.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright © 2014 Collabora, Ltd.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holders not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  The copyright holders make
+ * no representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "config.h"
+
+#include 
+#include 
+#include 
+#include 
+
+#include "weston-test-client-helper.h"
+#include "presentation_timing-client-protocol.h"
+
+#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
+
+static inline void *
+xzalloc(size_t size)
+{
+   void *p;
+
+   p = calloc(1, size);
+   assert(p);
+
+   return p;
+}
+
+static struct presentation *
+get_presentation(struct client *client)
+{
+   struct global *g;
+   struct global *global_pres = NULL;
+   static struct presentation *pres;
+
+   if (pres)
+   return pres;
+
+   wl_list_for_each(g, &client->global_list, link) {
+   if (strcmp(g->interface, "presentation"))
+   continue;
+
+   if (global_pres)
+   assert(0 && "multiple presentation objects");
+
+   global_pres = g;
+   }
+
+   assert(global_pres && "no presentation found");
+
+   assert(global_pres->version == 1);
+
+   pres = wl_registry_bind(client->wl_registry, global_pres->name,
+   &presentation_interface, 1);
+   assert(pres);
+
+   return pres;
+}
+
+struct feedback {
+   struct client *client;
+   struct presentation_feedback *obj;
+
+   enum {
+   FB_PENDING = 0,
+   FB_PRESENTED,
+   FB_DISCARDED
+   } result;
+
+   struct wl_output *sync_output;
+   uint64_t seq;
+   struct timespec time;
+   uint32_t refresh_nsec;
+   uint32_t flags;
+};
+
+static void
+timespec_from_proto(struct timespec *tm, uint32_t tv_sec_hi,
+   uint32_t tv_sec_lo, uint32_t tv_nsec)
+{
+   tm->tv_sec = ((uint64_t)tv_sec_hi << 32) + tv_sec_lo;
+   tm->tv_nsec = tv_nsec;
+}
+
+static void
+feedback_sync_output(void *data,
+struct presentation_feedback *presentation_feedback,
+struct wl_output *output)
+{
+   struct feedback *fb = data;
+
+   assert(fb->result == FB_PENDING);
+
+   if (output)
+   fb->sync_output = output;
+}
+
+static void
+feedback_presented(void *data,
+  struct presentation_feedback *presentation_feedback,
+  uint32_t tv_sec_hi,
+  uint32_t tv_sec_lo,
+  uint32_t tv_nsec,
+ 

[PATCH 8/8] clients: add presentation-shm demo

2014-09-23 Thread Louis-Francis Ratté-Boulianne
From: Pekka Paalanen 

This started as a copy of simple-shm.c before it was converted to
xdg_shell.

This demo excercises the presentation feedback interface in five
different modes:

- A continuous repaint loop triggered by frame callbacks, and using
  immediate commits, just gathering presentation feedback and computing
  some time intervals for statistics.

- The same as above, except with 1s sleep before actually repainting as
  a response to frame callback. This tests how well the compositor can
  do a repaint from idle state (not continuously repainting), assuming
  nothing else is causing repaints.

- A continuous repaint loop triggered by 'presented' events rather than
  by frame callbacks. If Weston uses an appropriate scheduling
  algorithm, this mode achieves the smallest possible frame latency
  (below one output refresh period).

In all modes, all frames are pre-rendered at startup, so no rendering
happens during the animation.

[Louis-Francis Ratté-Boulianne: split queuing feature]

Signed-off-by: Pekka Paalanen 
Signed-off-by: Louis-Francis Ratté-Boulianne 
---
 .gitignore |   1 +
 Makefile.am|   8 +
 clients/presentation-shm.c | 866 +
 3 files changed, 875 insertions(+)
 create mode 100644 clients/presentation-shm.c

diff --git a/.gitignore b/.gitignore
index fbffaa5..d521bcc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -45,6 +45,7 @@ weston-gears
 weston-image
 weston-nested
 weston-nested-client
+weston-presentation-shm
 weston-resizor
 weston-scaler
 weston-simple-egl
diff --git a/Makefile.am b/Makefile.am
index 87204a6..10be920 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -393,6 +393,7 @@ demo_clients += \
weston-simple-shm   \
weston-simple-damage\
weston-simple-touch \
+   weston-presentation-shm \
weston-multi-resource
 
 weston_simple_shm_SOURCES = clients/simple-shm.c
@@ -419,6 +420,13 @@ weston_simple_touch_SOURCES = clients/simple-touch.c
 weston_simple_touch_CFLAGS = $(AM_CFLAGS) $(SIMPLE_CLIENT_CFLAGS)
 weston_simple_touch_LDADD = $(SIMPLE_CLIENT_LIBS) libshared.la
 
+weston_presentation_shm_SOURCES = clients/presentation-shm.c
+nodist_weston_presentation_shm_SOURCES =   \
+   protocol/presentation_timing-protocol.c \
+   protocol/presentation_timing-client-protocol.h
+weston_presentation_shm_CFLAGS = $(AM_CFLAGS) $(SIMPLE_CLIENT_CFLAGS)
+weston_presentation_shm_LDADD = $(SIMPLE_CLIENT_LIBS) libshared.la -lm
+
 weston_multi_resource_SOURCES = clients/multi-resource.c
 weston_multi_resource_CFLAGS = $(AM_CFLAGS) $(SIMPLE_CLIENT_CFLAGS)
 weston_multi_resource_LDADD = $(SIMPLE_CLIENT_LIBS) libshared.la -lm
diff --git a/clients/presentation-shm.c b/clients/presentation-shm.c
new file mode 100644
index 000..2976b49
--- /dev/null
+++ b/clients/presentation-shm.c
@@ -0,0 +1,866 @@
+/*
+ * Copyright © 2011 Benjamin Franzke
+ * Copyright © 2010 Intel Corporation
+ * Copyright © 2014 Collabora, Ltd.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include "../shared/os-compatibility.h"
+#include "presentation_timing-client-protocol.h"
+
+#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
+
+enum run_mode {
+   RUN_MODE_FEEDBACK,
+   RUN_MODE_FEEDBACK_IDLE,
+   RUN_MODE_PRESENT,
+};
+
+struct output {
+   struct wl_output *output;
+   uint32_t name;
+   struct wl_list link;
+};
+
+struct display {
+   struct wl_display *display;
+   struct wl_registry *registry;
+   struct wl_compositor *compositor;
+   struct wl_sh

[PATCH 1/8] protocol: add presentation extension v5

2014-09-23 Thread Louis-Francis Ratté-Boulianne
From: Pekka Paalanen 

Add accurate presentation timing features to Wayland: queueing and
feedback.

This specification is based on the draft written by Frederic Plourde
 and redesigned by Pekka Paalanen.

The RFC v2 version is from
http://lists.freedesktop.org/archives/wayland-devel/2014-January/012988.html

Changes in v3:

* associate presentation time to current surface contents

This implements the suggestion from
http://lists.freedesktop.org/archives/wayland-devel/2014-February/013066.html

which prevents surface content from jumping backwards in time if a
client retroactively queues an update with a target time in the past.

* use 64-bit tv_sec in presentation

The time_t type used in struct timespec could be almost anything. POSIX
probably defines it to be an integer, but not the size. Apparently it is
usually 'long', which makes it 64-bit on x86_64.

To be able to fully represent timespec values returned by clock_gettime,
change the protocol to use 64 bits for the tv_sec part.

* define an error for invalid tv_nsec

This allow us to rely on the normalized timestamp form.

* define some interactions with sub-surfaces

Sub-surface cached state updates (synchronized mode) are designed
especially for resizing. As queued updates are not meant to produce any
resizing-like effects, they also do not trigger any sub-surface
operations.

* add sub-headings as xml comments

* queued update cannot map

Because before mapping, the surface has no main output assigned. An
immediate commit is needed anyway, to be able to set all the surface
state, which a queued update cannot touch.

* frame callbacks are not queued

It is not known when queueing frame callbacks would be useful.

Changes in v4:

* remove mentions of the queuing feature

The specification has been split and the queuing feature will be added
back in another version of the extension.

* add flags argument to 'presented' event

Describe the nature of how the update was presented to screen and the
characteristics of the feedback information. No flags have been
defined for now.

* add a protocol error code for invalid flags

Changes in v5:

* remove the destroy method for the feedback object

The protocol object should instead be automatically destroyed after
a 'presented' or 'discarded' event has been triggered.

* some grammatical corrections to the specification

[Louis-Francis Ratté-Boulianne: split the spec in two parts]

Signed-off-by: Pekka Paalanen 
Signed-off-by: Louis-Francis Ratté-Boulianne 
Reviewed-by: Mario Kleiner 
---
 Makefile.am  |   5 +
 protocol/presentation_timing.xml | 238 +++
 2 files changed, 243 insertions(+)
 create mode 100644 protocol/presentation_timing.xml

diff --git a/Makefile.am b/Makefile.am
index b2d6893..b1dcc21 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -78,6 +78,8 @@ nodist_weston_SOURCES =   
\
protocol/input-method-server-protocol.h \
protocol/workspaces-protocol.c  \
protocol/workspaces-server-protocol.h   \
+   protocol/presentation_timing-protocol.c \
+   protocol/presentation_timing-server-protocol.h  \
protocol/scaler-protocol.c  \
protocol/scaler-server-protocol.h
 
@@ -445,6 +447,8 @@ nodist_libtoytoolkit_la_SOURCES =   \
protocol/scaler-client-protocol.h   \
protocol/workspaces-protocol.c  \
protocol/workspaces-client-protocol.h   \
+   protocol/presentation_timing-protocol.c \
+   protocol/presentation_timing-client-protocol.h  \
protocol/xdg-shell-protocol.c   \
protocol/xdg-shell-client-protocol.h
 
@@ -987,6 +991,7 @@ EXTRA_DIST +=   \
protocol/wayland-test.xml   \
protocol/xdg-shell.xml  \
protocol/fullscreen-shell.xml   \
+   protocol/presentation_timing.xml\
protocol/scaler.xml
 
 man_MANS = weston.1 weston.ini.5
diff --git a/protocol/presentation_timing.xml b/protocol/presentation_timing.xml
new file mode 100644
index 000..9158434
--- /dev/null
+++ b/protocol/presentation_timing.xml
@@ -0,0 +1,238 @@
+
+
+
+
+  
+Copyright © 2013-2014 Collabora, Ltd.
+
+Permission to use, copy, modify, distribute, and sell this
+software and its documentation for any purpose is hereby granted
+without fee, provided that the above copyright notice appear in
+all copies and that both that copyright notice and this permission
+notice appear in supporting documentation, and that the name of
+the copyright holders not be used in advertising or publicity
+pertaining to distribution of the software without specific,
+written prior permission.  The copyright holders make no
+representations about 

[PATCH 4/8] compositor: set and use the presentation clock everywhere

2014-09-23 Thread Louis-Francis Ratté-Boulianne
From: Pekka Paalanen 

Add presentation clock setters that verify the given clock actually
works. Offer an automatic choice of a software fallback clock, when a
backend has to always use clock_gettime() to approximate the
presentation time.

The DRM backend already queried the DRM about the clock id, just let the
DRM backend set the presentation clock from that.

For all other backends which do not get a timestamp from the driver,
call the software clock setter to choose a suitable clock.

Report the chosen clock via presentation.clock_id event to clients.

In finish_frame(), upgrade the argument from uint32_t milliseconds to
struct timespec which can accurately hold the presentation clock values.
This will be needed when weston_output_finish_frame() starts to send out
presentation_feedback.presented events.

While at it, replace gettimeofday() calls with clock_gettime() using the
chosen presentation clock, so we manufacture presentation timestamps
from the presentation clock when the gfx drivers cannot give us a proper
timestamp.

Rpi patch is more verbose due to not having the compositor pointer
available in rpi_flippipe_update_complete(). Explicitly carry the clock
id with flippipe so it is available in the thread.

Changes in v4:

* rpi debug build fix

v4 Signed-off-by: Pekka Paalanen 
v3 Reviewed-by: Mario Kleiner 
---
 src/compositor-drm.c  | 32 +++
 src/compositor-fbdev.c| 12 ---
 src/compositor-headless.c | 11 ---
 src/compositor-rdp.c  | 11 ---
 src/compositor-rpi.c  | 49 ++---
 src/compositor-wayland.c  | 11 +--
 src/compositor-x11.c  | 11 ---
 src/compositor.c  | 79 ++-
 src/compositor.h  | 14 +++--
 9 files changed, 161 insertions(+), 69 deletions(-)

diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index e4496e7..626a2de 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -118,7 +118,6 @@ struct drm_compositor {
 
uint32_t prev_state;
 
-   clockid_t clock;
struct udev_input input;
 
uint32_t cursor_width;
@@ -700,7 +699,6 @@ drm_output_start_repaint_loop(struct weston_output 
*output_base)
struct drm_compositor *compositor = (struct drm_compositor *)
output_base->compositor;
uint32_t fb_id;
-   uint32_t msec;
struct timespec ts;
 
if (output->destroy_pending)
@@ -723,9 +721,8 @@ drm_output_start_repaint_loop(struct weston_output 
*output_base)
 
 finish_frame:
/* if we cannot page-flip, immediately finish frame */
-   clock_gettime(compositor->clock, &ts);
-   msec = ts.tv_sec * 1000 + ts.tv_nsec / 100;
-   weston_output_finish_frame(output_base, msec);
+   clock_gettime(compositor->base.presentation_clock, &ts);
+   weston_output_finish_frame(output_base, &ts);
 }
 
 static void
@@ -734,7 +731,7 @@ vblank_handler(int fd, unsigned int frame, unsigned int 
sec, unsigned int usec,
 {
struct drm_sprite *s = (struct drm_sprite *)data;
struct drm_output *output = s->output;
-   uint32_t msecs;
+   struct timespec ts;
 
output->vblank_pending = 0;
 
@@ -743,8 +740,9 @@ vblank_handler(int fd, unsigned int frame, unsigned int 
sec, unsigned int usec,
s->next = NULL;
 
if (!output->page_flip_pending) {
-   msecs = sec * 1000 + usec / 1000;
-   weston_output_finish_frame(&output->base, msecs);
+   ts.tv_sec = sec;
+   ts.tv_nsec = usec * 1000;
+   weston_output_finish_frame(&output->base, &ts);
}
 }
 
@@ -756,7 +754,7 @@ page_flip_handler(int fd, unsigned int frame,
  unsigned int sec, unsigned int usec, void *data)
 {
struct drm_output *output = (struct drm_output *) data;
-   uint32_t msecs;
+   struct timespec ts;
 
/* We don't set page_flip_pending on start_repaint_loop, in that case
 * we just want to page flip to the current buffer to get an accurate
@@ -772,8 +770,9 @@ page_flip_handler(int fd, unsigned int frame,
if (output->destroy_pending)
drm_output_destroy(&output->base);
else if (!output->vblank_pending) {
-   msecs = sec * 1000 + usec / 1000;
-   weston_output_finish_frame(&output->base, msecs);
+   ts.tv_sec = sec;
+   ts.tv_nsec = usec * 1000;
+   weston_output_finish_frame(&output->base, &ts);
 
/* We can't call this from frame_notify, because the output's
 * repaint needed flag is cleared just after that */
@@ -1282,6 +1281,7 @@ init_drm(struct drm_compositor *ec, struct udev_device 
*device)
const char *filename, *sysnum;
uint64_t cap;
int fd, ret;
+   clockid_t clk_id;
 
sysnum = udev_device_get_sysnum(device);
if (sysnum)
@@ -1307,9 +1307,15 @@ init_drm(struct drm_compositor *ec, stru

[PATCH 0/8] Wayland Presentation Extension v5

2014-09-23 Thread Louis-Francis Ratté-Boulianne
Hi,

Here is an update to the Wayland Presentation Extension.

For context, please refer to the last thread about the extension:
http://lists.freedesktop.org/archives/wayland-devel/2014-September/017278.html

Differences compared to the last proposal (v4) are:

 * Remove the 'destroy' method from the feedback object.

 * Some grammatical corrections to the protocol specification.
   Thanks to Bryce Harrington.

Pekka Paalanen (8):
  protocol: add presentation extension v5
  compositor: add stub implementation of presentation interface
  weston-info: report presentation clock
  compositor: set and use the presentation clock everywhere
  compositor: implement presentation_feedback
  compositor-drm: deliver frame seq for feedback
  tests: presentation test, simple
  clients: add presentation-shm demo

 .gitignore   |   1 +
 Makefile.am  |  24 ++
 clients/presentation-shm.c   | 866 +++
 clients/weston-info.c|  81 
 protocol/presentation_timing.xml | 238 +++
 src/compositor-drm.c |  46 ++-
 src/compositor-fbdev.c   |  12 +-
 src/compositor-headless.c|  11 +-
 src/compositor-rdp.c |  11 +-
 src/compositor-rpi.c |  49 ++-
 src/compositor-wayland.c |  11 +-
 src/compositor-x11.c |  11 +-
 src/compositor.c | 265 +++-
 src/compositor.h |  20 +-
 tests/presentation-test.c| 246 +++
 15 files changed, 1823 insertions(+), 69 deletions(-)
 create mode 100644 clients/presentation-shm.c
 create mode 100644 protocol/presentation_timing.xml
 create mode 100644 tests/presentation-test.c

Thanks,
Louis-Francis Ratté-Boulianne

-- 
1.9.3

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 0/8] Wayland Presentation Extension v4

2014-09-15 Thread Louis-Francis Ratté-Boulianne
Hi!

To accelerate the merge of the Wayland Presentation extension, it was
decided to split it into two parts: feedback and queuing. I've done
the work of cleaning up the patches for the first one on behalf of
Pekka Paalanen.

For context, please refer to the last thread about the extension:
http://lists.freedesktop.org/archives/wayland-devel/2014-March/013580.html

Differences compared to the last proposal (RFC v3) are:

 * Remove the queuing feature.

 * Add flags argument to the 'presented' event.

 * Add a protocol error code for invalid flags.

 * Fix the RPI debug build.

 * Add simple presentation test.

Patch 1 adds the protocol. See the commit message to have more details
about the changes since RFC v2.

More details about the addition of flags are available there:
http://lists.freedesktop.org/archives/wayland-devel/2014-March/013857.html

The whole patch set is available at
http://cgit.collabora.com/git/user/lfrb/weston.git/log/?h=presentation-feedback

Pekka Paalanen (8):
  protocol: add presentation extension v4
  compositor: add stub implementation of presentation interface
  weston-info: report presentation clock
  compositor: set and use the presentation clock everywhere
  compositor: implement presentation_feedback
  compositor-drm: deliver frame seq for feedback
  tests: presentation test, simple
  clients: add presentation-shm demo

 .gitignore   |   1 +
 Makefile.am  |  24 ++
 clients/presentation-shm.c   | 866 +++
 clients/weston-info.c|  81 
 protocol/presentation_timing.xml | 247 +++
 src/compositor-drm.c |  46 ++-
 src/compositor-fbdev.c   |  12 +-
 src/compositor-headless.c|  11 +-
 src/compositor-rdp.c |  11 +-
 src/compositor-rpi.c |  49 ++-
 src/compositor-wayland.c |  11 +-
 src/compositor-x11.c |  11 +-
 src/compositor.c | 279 -
 src/compositor.h |  20 +-
 tests/presentation-test.c| 246 +++
 15 files changed, 1846 insertions(+), 69 deletions(-)
 create mode 100644 clients/presentation-shm.c
 create mode 100644 protocol/presentation_timing.xml
 create mode 100644 tests/presentation-test.c

The next step will be to finish the implementation of feedback flags.
Hopefully, it will happen in time for 1.7.0.

Afterwards, the second part of the extension (queuing) will have to be
cleaned up and merged. However, it will probably not happen before
release 1.7.0 given these two bugs must be closed first:

https://bugs.freedesktop.org/show_bug.cgi?id=75303
https://bugs.freedesktop.org/show_bug.cgi?id=78190

According to Pekka, it's high time we get the feedback basics into
Weston for everyone to try out. Let's hope it's ready to be merged.

Thanks,
Louis-Francis Ratté-Boulianne

-- 
1.9.3

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 4/8] compositor: set and use the presentation clock everywhere

2014-09-15 Thread Louis-Francis Ratté-Boulianne
From: Pekka Paalanen 

Add presentation clock setters that verify the given clock actually
works. Offer an automatic choice of a software fallback clock, when a
backend has to always use clock_gettime() to approximate the
presentation time.

The DRM backend already queried the DRM about the clock id, just let the
DRM backend set the presentation clock from that.

For all other backends which do not get a timestamp from the driver,
call the software clock setter to choose a suitable clock.

Report the chosen clock via presentation.clock_id event to clients.

In finish_frame(), upgrade the argument from uint32_t milliseconds to
struct timespec which can accurately hold the presentation clock values.
This will be needed when weston_output_finish_frame() starts to send out
presentation_feedback.presented events.

While at it, replace gettimeofday() calls with clock_gettime() using the
chosen presentation clock, so we manufacture presentation timestamps
from the presentation clock when the gfx drivers cannot give us a proper
timestamp.

Rpi patch is more verbose due to not having the compositor pointer
available in rpi_flippipe_update_complete(). Explicitly carry the clock
id with flippipe so it is available in the thread.

Changes in v4:

* rpi debug build fix

v4 Signed-off-by: Pekka Paalanen 
v3 Reviewed-by: Mario Kleiner 
---
 src/compositor-drm.c  | 32 +++
 src/compositor-fbdev.c| 12 ---
 src/compositor-headless.c | 11 ---
 src/compositor-rdp.c  | 11 ---
 src/compositor-rpi.c  | 49 ++---
 src/compositor-wayland.c  | 11 +--
 src/compositor-x11.c  | 11 ---
 src/compositor.c  | 79 ++-
 src/compositor.h  | 14 +++--
 9 files changed, 161 insertions(+), 69 deletions(-)

diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index e4496e7..626a2de 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -118,7 +118,6 @@ struct drm_compositor {
 
uint32_t prev_state;
 
-   clockid_t clock;
struct udev_input input;
 
uint32_t cursor_width;
@@ -700,7 +699,6 @@ drm_output_start_repaint_loop(struct weston_output 
*output_base)
struct drm_compositor *compositor = (struct drm_compositor *)
output_base->compositor;
uint32_t fb_id;
-   uint32_t msec;
struct timespec ts;
 
if (output->destroy_pending)
@@ -723,9 +721,8 @@ drm_output_start_repaint_loop(struct weston_output 
*output_base)
 
 finish_frame:
/* if we cannot page-flip, immediately finish frame */
-   clock_gettime(compositor->clock, &ts);
-   msec = ts.tv_sec * 1000 + ts.tv_nsec / 100;
-   weston_output_finish_frame(output_base, msec);
+   clock_gettime(compositor->base.presentation_clock, &ts);
+   weston_output_finish_frame(output_base, &ts);
 }
 
 static void
@@ -734,7 +731,7 @@ vblank_handler(int fd, unsigned int frame, unsigned int 
sec, unsigned int usec,
 {
struct drm_sprite *s = (struct drm_sprite *)data;
struct drm_output *output = s->output;
-   uint32_t msecs;
+   struct timespec ts;
 
output->vblank_pending = 0;
 
@@ -743,8 +740,9 @@ vblank_handler(int fd, unsigned int frame, unsigned int 
sec, unsigned int usec,
s->next = NULL;
 
if (!output->page_flip_pending) {
-   msecs = sec * 1000 + usec / 1000;
-   weston_output_finish_frame(&output->base, msecs);
+   ts.tv_sec = sec;
+   ts.tv_nsec = usec * 1000;
+   weston_output_finish_frame(&output->base, &ts);
}
 }
 
@@ -756,7 +754,7 @@ page_flip_handler(int fd, unsigned int frame,
  unsigned int sec, unsigned int usec, void *data)
 {
struct drm_output *output = (struct drm_output *) data;
-   uint32_t msecs;
+   struct timespec ts;
 
/* We don't set page_flip_pending on start_repaint_loop, in that case
 * we just want to page flip to the current buffer to get an accurate
@@ -772,8 +770,9 @@ page_flip_handler(int fd, unsigned int frame,
if (output->destroy_pending)
drm_output_destroy(&output->base);
else if (!output->vblank_pending) {
-   msecs = sec * 1000 + usec / 1000;
-   weston_output_finish_frame(&output->base, msecs);
+   ts.tv_sec = sec;
+   ts.tv_nsec = usec * 1000;
+   weston_output_finish_frame(&output->base, &ts);
 
/* We can't call this from frame_notify, because the output's
 * repaint needed flag is cleared just after that */
@@ -1282,6 +1281,7 @@ init_drm(struct drm_compositor *ec, struct udev_device 
*device)
const char *filename, *sysnum;
uint64_t cap;
int fd, ret;
+   clockid_t clk_id;
 
sysnum = udev_device_get_sysnum(device);
if (sysnum)
@@ -1307,9 +1307,15 @@ init_drm(struct drm_compositor *ec, stru

[PATCH 7/8] tests: presentation test, simple

2014-09-15 Thread Louis-Francis Ratté-Boulianne
From: Pekka Paalanen 

Added in v4.

Signed-off-by: Pekka Paalanen 
---
 Makefile.am   |   8 ++
 tests/presentation-test.c | 246 ++
 2 files changed, 254 insertions(+)
 create mode 100644 tests/presentation-test.c

diff --git a/Makefile.am b/Makefile.am
index 6a91a8f..87204a6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -842,6 +842,7 @@ weston_tests =  \
event.weston\
button.weston   \
text.weston \
+   presentation.weston \
subsurface.weston
 
 
@@ -944,6 +945,13 @@ subsurface_weston_SOURCES = tests/subsurface-test.c
 subsurface_weston_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS)
 subsurface_weston_LDADD = libtest-client.la
 
+presentation_weston_SOURCES = tests/presentation-test.c
+nodist_presentation_weston_SOURCES =   \
+   protocol/presentation_timing-protocol.c \
+   protocol/presentation_timing-client-protocol.h
+presentation_weston_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS)
+presentation_weston_LDADD = libtest-client.la
+
 if ENABLE_EGL
 weston_tests += buffer-count.weston
 buffer_count_weston_SOURCES = tests/buffer-count-test.c
diff --git a/tests/presentation-test.c b/tests/presentation-test.c
new file mode 100644
index 000..57012fa
--- /dev/null
+++ b/tests/presentation-test.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright © 2014 Collabora, Ltd.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holders not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  The copyright holders make
+ * no representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "config.h"
+
+#include 
+#include 
+#include 
+#include 
+
+#include "weston-test-client-helper.h"
+#include "presentation_timing-client-protocol.h"
+
+#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
+
+static inline void *
+xzalloc(size_t size)
+{
+   void *p;
+
+   p = calloc(1, size);
+   assert(p);
+
+   return p;
+}
+
+static struct presentation *
+get_presentation(struct client *client)
+{
+   struct global *g;
+   struct global *global_pres = NULL;
+   static struct presentation *pres;
+
+   if (pres)
+   return pres;
+
+   wl_list_for_each(g, &client->global_list, link) {
+   if (strcmp(g->interface, "presentation"))
+   continue;
+
+   if (global_pres)
+   assert(0 && "multiple presentation objects");
+
+   global_pres = g;
+   }
+
+   assert(global_pres && "no presentation found");
+
+   assert(global_pres->version == 1);
+
+   pres = wl_registry_bind(client->wl_registry, global_pres->name,
+   &presentation_interface, 1);
+   assert(pres);
+
+   return pres;
+}
+
+struct feedback {
+   struct client *client;
+   struct presentation_feedback *obj;
+
+   enum {
+   FB_PENDING = 0,
+   FB_PRESENTED,
+   FB_DISCARDED
+   } result;
+
+   struct wl_output *sync_output;
+   uint64_t seq;
+   struct timespec time;
+   uint32_t refresh_nsec;
+   uint32_t flags;
+};
+
+static void
+timespec_from_proto(struct timespec *tm, uint32_t tv_sec_hi,
+   uint32_t tv_sec_lo, uint32_t tv_nsec)
+{
+   tm->tv_sec = ((uint64_t)tv_sec_hi << 32) + tv_sec_lo;
+   tm->tv_nsec = tv_nsec;
+}
+
+static void
+feedback_sync_output(void *data,
+struct presentation_feedback *presentation_feedback,
+struct wl_output *output)
+{
+   struct feedback *fb = data;
+
+   assert(fb->result == FB_PENDING);
+
+   if (output)
+   fb->sync_output = output;
+}
+
+static void
+feedback_presented(void *data,
+  struct presentation_feedback *presentation_feedback,
+  uint32_t tv_sec_hi,
+  uint32_t tv_sec_lo,
+ 

[PATCH 3/8] weston-info: report presentation clock

2014-09-15 Thread Louis-Francis Ratté-Boulianne
From: Pekka Paalanen 

Signed-off-by: Pekka Paalanen 
v3 Reviewed-by: Mario Kleiner 
---
 Makefile.am   |  3 ++
 clients/weston-info.c | 81 +++
 2 files changed, 84 insertions(+)

diff --git a/Makefile.am b/Makefile.am
index b1dcc21..6a91a8f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -582,6 +582,9 @@ weston_simple_im_LDADD = $(CLIENT_LIBS)
 weston_simple_im_CFLAGS = $(AM_CFLAGS) $(CLIENT_CFLAGS)
 
 weston_info_SOURCES = clients/weston-info.c
+nodist_weston_info_SOURCES =   \
+   protocol/presentation_timing-protocol.c \
+   protocol/presentation_timing-client-protocol.h
 weston_info_LDADD = $(WESTON_INFO_LIBS) libshared.la
 weston_info_CFLAGS = $(AM_CFLAGS) $(CLIENT_CFLAGS)
 
diff --git a/clients/weston-info.c b/clients/weston-info.c
index c53ac74..f777982 100644
--- a/clients/weston-info.c
+++ b/clients/weston-info.c
@@ -27,10 +27,14 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
 #include "../shared/os-compatibility.h"
+#include "presentation_timing-client-protocol.h"
+
+#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
 
 #define MIN(x,y) (((x) < (y)) ? (x) : (y))
 
@@ -98,6 +102,13 @@ struct seat_info {
int32_t repeat_delay;
 };
 
+struct presentation_info {
+   struct global_info global;
+   struct presentation *presentation;
+
+   clockid_t clk_id;
+};
+
 struct weston_info {
struct wl_display *display;
struct wl_registry *registry;
@@ -554,6 +565,74 @@ add_output_info(struct weston_info *info, uint32_t id, 
uint32_t version)
 }
 
 static void
+destroy_presentation_info(void *info)
+{
+   struct presentation_info *prinfo = info;
+
+   presentation_destroy(prinfo->presentation);
+}
+
+static const char *
+clock_name(clockid_t clk_id)
+{
+   static const char *names[] = {
+   [CLOCK_REALTIME] =  "CLOCK_REALTIME",
+   [CLOCK_MONOTONIC] = "CLOCK_MONOTONIC",
+   [CLOCK_MONOTONIC_RAW] = "CLOCK_MONOTONIC_RAW",
+   [CLOCK_REALTIME_COARSE] =   "CLOCK_REALTIME_COARSE",
+   [CLOCK_MONOTONIC_COARSE] =  "CLOCK_MONOTONIC_COARSE",
+   [CLOCK_BOOTTIME] =  "CLOCK_BOOTTIME",
+   };
+
+   if (clk_id < 0 || (unsigned)clk_id >= ARRAY_LENGTH(names))
+   return "unknown";
+
+   return names[clk_id];
+}
+
+static void
+print_presentation_info(void *info)
+{
+   struct presentation_info *prinfo = info;
+
+   print_global_info(info);
+
+   printf("\tpresentation clock id: %d (%s)\n",
+   prinfo->clk_id, clock_name(prinfo->clk_id));
+}
+
+static void
+presentation_handle_clock_id(void *data, struct presentation *presentation,
+uint32_t clk_id)
+{
+   struct presentation_info *prinfo = data;
+
+   prinfo->clk_id = clk_id;
+}
+
+static const struct presentation_listener presentation_listener = {
+   presentation_handle_clock_id
+};
+
+static void
+add_presentation_info(struct weston_info *info, uint32_t id, uint32_t version)
+{
+   struct presentation_info *prinfo = xzalloc(sizeof *prinfo);
+
+   init_global_info(info, &prinfo->global, id, "presentation", version);
+   prinfo->global.print = print_presentation_info;
+   prinfo->global.destroy = destroy_presentation_info;
+
+   prinfo->clk_id = -1;
+   prinfo->presentation = wl_registry_bind(info->registry, id,
+   &presentation_interface, 1);
+   presentation_add_listener(prinfo->presentation, &presentation_listener,
+ prinfo);
+
+   info->roundtrip_needed = true;
+}
+
+static void
 destroy_global_info(void *data)
 {
 }
@@ -581,6 +660,8 @@ global_handler(void *data, struct wl_registry *registry, 
uint32_t id,
add_shm_info(info, id, version);
else if (!strcmp(interface, "wl_output"))
add_output_info(info, id, version);
+   else if (!strcmp(interface, "presentation"))
+   add_presentation_info(info, id, version);
else
add_global_info(info, id, interface, version);
 }
-- 
1.9.3

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 6/8] compositor-drm: deliver frame seq for feedback

2014-09-15 Thread Louis-Francis Ratté-Boulianne
From: Pekka Paalanen 

Add 'msc' field to weston_output to maintain the refresh counter, and
use it in presentation_feedback.presented.

Make compositor-drm update the per-output refresh counter with the
values reported by DRM. If the DRM reported value jumps backwards,
assume it wrapped around once.

Other backends do not update weston_output::msc, and there
presentation_feedback will always deliver refresh counter as zero.

Signed-off-by: Pekka Paalanen 
v3 Reviewed-by: Mario Kleiner 
---
 src/compositor-drm.c | 14 ++
 src/compositor.c |  2 +-
 src/compositor.h |  1 +
 3 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 626a2de..07b83a7 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -726,6 +726,17 @@ finish_frame:
 }
 
 static void
+drm_output_update_msc(struct drm_output *output, unsigned int seq)
+{
+   uint64_t msc_hi = output->base.msc >> 32;
+
+   if (seq < (output->base.msc & 0x))
+   msc_hi++;
+
+   output->base.msc = (msc_hi << 32) + seq;
+}
+
+static void
 vblank_handler(int fd, unsigned int frame, unsigned int sec, unsigned int usec,
   void *data)
 {
@@ -733,6 +744,7 @@ vblank_handler(int fd, unsigned int frame, unsigned int 
sec, unsigned int usec,
struct drm_output *output = s->output;
struct timespec ts;
 
+   drm_output_update_msc(output, frame);
output->vblank_pending = 0;
 
drm_output_release_fb(output, s->current);
@@ -756,6 +768,8 @@ page_flip_handler(int fd, unsigned int frame,
struct drm_output *output = (struct drm_output *) data;
struct timespec ts;
 
+   drm_output_update_msc(output, frame);
+
/* We don't set page_flip_pending on start_repaint_loop, in that case
 * we just want to page flip to the current buffer to get an accurate
 * timestamp */
diff --git a/src/compositor.c b/src/compositor.c
index 805a677..d61e287 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -2067,7 +2067,7 @@ weston_output_finish_frame(struct weston_output *output,
refresh_nsec = 1UL / output->current_mode->refresh;
weston_presentation_feedback_present_list(&output->feedback_list,
  output, refresh_nsec, stamp,
- 0);
+ output->msc);
 
output->frame_time = stamp->tv_sec * 1000 + stamp->tv_nsec / 100;
 
diff --git a/src/compositor.h b/src/compositor.h
index 548ffe5..a1ab9d5 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -203,6 +203,7 @@ struct weston_output {
struct wl_signal destroy_signal;
int move_x, move_y;
uint32_t frame_time; /* presentation timestamp in milliseconds */
+   uint64_t msc;/* media stream counter */
int disable_planes;
int destroying;
struct wl_list feedback_list;
-- 
1.9.3

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 2/8] compositor: add stub implementation of presentation interface

2014-09-15 Thread Louis-Francis Ratté-Boulianne
From: Pekka Paalanen 

You can bind to the global interface, and it delivers a fake clock id.
All requests on it raise an error.

Changes in v4:

* queuing methods were extractracted for a later series

[Louis-Francis Ratté-Boulianne: split queuing feature]

Signed-off-by: Pekka Paalanen 
Signed-off-by: Louis-Francis Ratté-Boulianne 
v3 Reviewed-by: Mario Kleiner 
---
 src/compositor.c | 47 ++-
 1 file changed, 46 insertions(+), 1 deletion(-)

diff --git a/src/compositor.c b/src/compositor.c
index a219766..d789508 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -1,7 +1,7 @@
 /*
  * Copyright © 2010-2011 Intel Corporation
  * Copyright © 2008-2011 Kristian Høgsberg
- * Copyright © 2012 Collabora, Ltd.
+ * Copyright © 2012-2014 Collabora, Ltd.
  *
  * Permission to use, copy, modify, distribute, and sell this software and
  * its documentation for any purpose is hereby granted without fee, provided
@@ -55,6 +55,7 @@
 
 #include "compositor.h"
 #include "scaler-server-protocol.h"
+#include "presentation_timing-server-protocol.h"
 #include "../shared/os-compatibility.h"
 #include "git-version.h"
 #include "version.h"
@@ -3736,6 +3737,46 @@ bind_scaler(struct wl_client *client,
 }
 
 static void
+presentation_destroy(struct wl_client *client, struct wl_resource *resource)
+{
+   wl_resource_destroy(resource);
+}
+
+static void
+presentation_feedback(struct wl_client *client,
+ struct wl_resource *resource,
+ struct wl_resource *surface,
+ uint32_t callback)
+{
+   wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_METHOD,
+  "presentation_feedback unimplemented");
+}
+
+static const struct presentation_interface presentation_implementation = {
+   presentation_destroy,
+   presentation_feedback
+};
+
+static void
+bind_presentation(struct wl_client *client,
+ void *data, uint32_t version, uint32_t id)
+{
+   struct weston_compositor *compositor = data;
+   struct wl_resource *resource;
+
+   resource = wl_resource_create(client, &presentation_interface,
+ MIN(version, 1), id);
+   if (resource == NULL) {
+   wl_client_post_no_memory(client);
+   return;
+   }
+
+   wl_resource_set_implementation(resource, &presentation_implementation,
+  compositor, NULL);
+   presentation_send_clock_id(resource, CLOCK_MONOTONIC);
+}
+
+static void
 compositor_bind(struct wl_client *client,
void *data, uint32_t version, uint32_t id)
 {
@@ -3830,6 +3871,10 @@ weston_compositor_init(struct weston_compositor *ec,
  ec, bind_scaler))
return -1;
 
+   if (!wl_global_create(ec->wl_display, &presentation_interface, 1,
+ ec, bind_presentation))
+   return -1;
+
wl_list_init(&ec->view_list);
wl_list_init(&ec->plane_list);
wl_list_init(&ec->layer_list);
-- 
1.9.3

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 1/8] protocol: add presentation extension v4

2014-09-15 Thread Louis-Francis Ratté-Boulianne
From: Pekka Paalanen 

Add accurate presentation timing features to Wayland: queueing and
feedback.

This specification is based on the draft written by Frederic Plourde
 and redesigned by Pekka Paalanen.

The RFC v2 version is from
http://lists.freedesktop.org/archives/wayland-devel/2014-January/012988.html

Changes in v3:

* associate presentation time to current surface contents

This implements the suggestion from
http://lists.freedesktop.org/archives/wayland-devel/2014-February/013066.html

which prevents surface content from jumping backwards in time if a
client retroactively queues an update with a target time in the past.

* use 64-bit tv_sec in presentation

The time_t type used in struct timespec could be almost anything. POSIX
probably defines it to be an integer, but not the size. Apparently it is
usually 'long', which makes it 64-bit on x86_64.

To be able to fully represent timespec values returned by clock_gettime,
change the protocol to use 64 bits for the tv_sec part.

* define an error for invalid tv_nsec

This allow us to rely on the normalized timestamp form.

* define some interactions with sub-surfaces

Sub-surface cached state updates (synchronized mode) are designed
especially for resizing. As queued updates are not meant to produce any
resizing-like effects, they also do not trigger any sub-surface
operations.

* add sub-headings as xml comments

* queued update cannot map

Because before mapping, the surface has no main output assigned. An
immediate commit is needed anyway, to be able to set all the surface
state, which a queued update cannot touch.

* frame callbacks are not queued

It is not known when queueing frame callbacks would be useful.

Changes in v4:

* remove mentions of the queuing feature

The specification has been split and the queuing feature will be added
back in another version of the extension.

* add flags argument to 'presented' event

Describe the nature of how the update was presented to screen and the
characteristics of the feedback information. No flags have been
defined for now.

* add a protocol error code for invalid flags

[Louis-Francis Ratté-Boulianne: split the spec in two parts]

Signed-off-by: Pekka Paalanen 
Signed-off-by: Louis-Francis Ratté-Boulianne 
v3 Reviewed-by: Mario Kleiner 
---
 Makefile.am  |   5 +
 protocol/presentation_timing.xml | 247 +++
 2 files changed, 252 insertions(+)
 create mode 100644 protocol/presentation_timing.xml

diff --git a/Makefile.am b/Makefile.am
index b2d6893..b1dcc21 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -78,6 +78,8 @@ nodist_weston_SOURCES =   
\
protocol/input-method-server-protocol.h \
protocol/workspaces-protocol.c  \
protocol/workspaces-server-protocol.h   \
+   protocol/presentation_timing-protocol.c \
+   protocol/presentation_timing-server-protocol.h  \
protocol/scaler-protocol.c  \
protocol/scaler-server-protocol.h
 
@@ -445,6 +447,8 @@ nodist_libtoytoolkit_la_SOURCES =   \
protocol/scaler-client-protocol.h   \
protocol/workspaces-protocol.c  \
protocol/workspaces-client-protocol.h   \
+   protocol/presentation_timing-protocol.c \
+   protocol/presentation_timing-client-protocol.h  \
protocol/xdg-shell-protocol.c   \
protocol/xdg-shell-client-protocol.h
 
@@ -987,6 +991,7 @@ EXTRA_DIST +=   \
protocol/wayland-test.xml   \
protocol/xdg-shell.xml  \
protocol/fullscreen-shell.xml   \
+   protocol/presentation_timing.xml\
protocol/scaler.xml
 
 man_MANS = weston.1 weston.ini.5
diff --git a/protocol/presentation_timing.xml b/protocol/presentation_timing.xml
new file mode 100644
index 000..8aadff0
--- /dev/null
+++ b/protocol/presentation_timing.xml
@@ -0,0 +1,247 @@
+
+
+
+
+  
+Copyright © 2013-2014 Collabora, Ltd.
+
+Permission to use, copy, modify, distribute, and sell this
+software and its documentation for any purpose is hereby granted
+without fee, provided that the above copyright notice appear in
+all copies and that both that copyright notice and this permission
+notice appear in supporting documentation, and that the name of
+the copyright holders not be used in advertising or publicity
+pertaining to distribution of the software without specific,
+written prior permission.  The copyright holders make no
+representations about the suitability of this software for any
+purpose.  It is provided "as is" without express or implied
+warranty.
+
+THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY

[PATCH 5/8] compositor: implement presentation_feedback

2014-09-15 Thread Louis-Francis Ratté-Boulianne
From: Pekka Paalanen 

Implement the presentation.feedback request, and the
presentation_feedback protocol interface. Feedback information is
delivered to clients as the backend reports it, except the refresh
counter (MSC) which is always reported as zero.

Changes in v4:

* add 'flags' argument to 'presented' event without implementation

v4 Signed-off-by: Pekka Paalanen 
v3 Reviewed-by: Mario Kleiner 
---
 src/compositor.c | 163 +--
 src/compositor.h |   5 ++
 2 files changed, 164 insertions(+), 4 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index f34d712..805a677 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -439,6 +439,76 @@ struct weston_frame_callback {
struct wl_list link;
 };
 
+struct weston_presentation_feedback {
+   struct wl_resource *resource;
+
+   /* XXX: could use just wl_resource_get_link() instead */
+   struct wl_list link;
+};
+
+static void
+weston_presentation_feedback_discard(
+   struct weston_presentation_feedback *feedback)
+{
+   presentation_feedback_send_discarded(feedback->resource);
+   wl_list_remove(&feedback->link);
+   wl_list_init(&feedback->link);
+}
+
+static void
+weston_presentation_feedback_discard_list(struct wl_list *list)
+{
+   struct weston_presentation_feedback *feedback, *tmp;
+
+   wl_list_for_each_safe(feedback, tmp, list, link)
+   weston_presentation_feedback_discard(feedback);
+}
+
+static void
+weston_presentation_feedback_present(
+   struct weston_presentation_feedback *feedback,
+   struct weston_output *output,
+   uint32_t refresh_nsec,
+   const struct timespec *ts,
+   uint64_t seq)
+{
+   struct wl_client *client = wl_resource_get_client(feedback->resource);
+   struct wl_resource *o;
+   uint64_t secs;
+   uint32_t flags = 0;
+
+   wl_resource_for_each(o, &output->resource_list) {
+   if (wl_resource_get_client(o) != client)
+   continue;
+
+   presentation_feedback_send_sync_output(feedback->resource, o);
+   }
+
+   secs = ts->tv_sec;
+   presentation_feedback_send_presented(feedback->resource,
+secs >> 32, secs & 0x,
+ts->tv_nsec,
+refresh_nsec,
+seq >> 32, seq & 0x,
+flags);
+   wl_list_remove(&feedback->link);
+   wl_list_init(&feedback->link);
+}
+
+static void
+weston_presentation_feedback_present_list(struct wl_list *list,
+ struct weston_output *output,
+ uint32_t refresh_nsec,
+ const struct timespec *ts,
+ uint64_t seq)
+{
+   struct weston_presentation_feedback *feedback, *tmp;
+
+   wl_list_for_each_safe(feedback, tmp, list, link)
+   weston_presentation_feedback_present(feedback, output,
+refresh_nsec, ts, seq);
+}
+
 static void
 surface_state_handle_buffer_destroy(struct wl_listener *listener, void *data)
 {
@@ -464,6 +534,7 @@ weston_surface_state_init(struct weston_surface_state 
*state)
region_init_infinite(&state->input);
 
wl_list_init(&state->frame_callback_list);
+   wl_list_init(&state->feedback_list);
 
state->buffer_viewport.buffer.transform = WL_OUTPUT_TRANSFORM_NORMAL;
state->buffer_viewport.buffer.scale = 1;
@@ -481,6 +552,8 @@ weston_surface_state_fini(struct weston_surface_state 
*state)
  &state->frame_callback_list, link)
wl_resource_destroy(cb->resource);
 
+   weston_presentation_feedback_discard_list(&state->feedback_list);
+
pixman_region32_fini(&state->input);
pixman_region32_fini(&state->opaque);
pixman_region32_fini(&state->damage);
@@ -539,6 +612,7 @@ weston_surface_create(struct weston_compositor *compositor)
wl_list_init(&surface->views);
 
wl_list_init(&surface->frame_callback_list);
+   wl_list_init(&surface->feedback_list);
 
wl_list_init(&surface->subsurface_list);
wl_list_init(&surface->subsurface_list_pending);
@@ -1555,6 +1629,8 @@ weston_surface_destroy(struct weston_surface *surface)
wl_list_for_each_safe(cb, next, &surface->frame_callback_list, link)
wl_resource_destroy(cb->resource);
 
+   weston_presentation_feedback_discard_list(&surface->feedback_list);
+
free(surface);
 }
 
@@ -1656,6 +1732,7 @@ weston_surface_attach(struct weston_surface *surface,
surface->compositor->renderer->attach(surface, buffer);
 
weston_surface_calculate_size_from_buffer(surfac

[PATCH 8/8] clients: add presentation-shm demo

2014-09-15 Thread Louis-Francis Ratté-Boulianne
From: Pekka Paalanen 

This started as a copy of simple-shm.c before it was converted to
xdg_shell.

This demo excercises the presentation feedback interface in five
different modes:

- A continuous repaint loop triggered by frame callbacks, and using
  immediate commits, just gathering presentation feedback and computing
  some time intervals for statistics.

- The same as above, except with 1s sleep before actually repainting as
  a response to frame callback. This tests how well the compositor can
  do a repaint from idle state (not continuously repainting), assuming
  nothing else is causing repaints.

- A continuous repaint loop triggered by 'presented' events rather than
  by frame callbacks. If Weston uses an appropriate scheduling
  algorithm, this mode achieves the smallest possible frame latency
  (below one output refresh period).

In all modes, all frames are pre-rendered at startup, so no rendering
happens during the animation.

[Louis-Francis Ratté-Boulianne: split queuing feature]

Signed-off-by: Pekka Paalanen 
Signed-off-by: Louis-Francis Ratté-Boulianne 
---
 .gitignore |   1 +
 Makefile.am|   8 +
 clients/presentation-shm.c | 866 +
 3 files changed, 875 insertions(+)
 create mode 100644 clients/presentation-shm.c

diff --git a/.gitignore b/.gitignore
index fbffaa5..d521bcc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -45,6 +45,7 @@ weston-gears
 weston-image
 weston-nested
 weston-nested-client
+weston-presentation-shm
 weston-resizor
 weston-scaler
 weston-simple-egl
diff --git a/Makefile.am b/Makefile.am
index 87204a6..10be920 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -393,6 +393,7 @@ demo_clients += \
weston-simple-shm   \
weston-simple-damage\
weston-simple-touch \
+   weston-presentation-shm \
weston-multi-resource
 
 weston_simple_shm_SOURCES = clients/simple-shm.c
@@ -419,6 +420,13 @@ weston_simple_touch_SOURCES = clients/simple-touch.c
 weston_simple_touch_CFLAGS = $(AM_CFLAGS) $(SIMPLE_CLIENT_CFLAGS)
 weston_simple_touch_LDADD = $(SIMPLE_CLIENT_LIBS) libshared.la
 
+weston_presentation_shm_SOURCES = clients/presentation-shm.c
+nodist_weston_presentation_shm_SOURCES =   \
+   protocol/presentation_timing-protocol.c \
+   protocol/presentation_timing-client-protocol.h
+weston_presentation_shm_CFLAGS = $(AM_CFLAGS) $(SIMPLE_CLIENT_CFLAGS)
+weston_presentation_shm_LDADD = $(SIMPLE_CLIENT_LIBS) libshared.la -lm
+
 weston_multi_resource_SOURCES = clients/multi-resource.c
 weston_multi_resource_CFLAGS = $(AM_CFLAGS) $(SIMPLE_CLIENT_CFLAGS)
 weston_multi_resource_LDADD = $(SIMPLE_CLIENT_LIBS) libshared.la -lm
diff --git a/clients/presentation-shm.c b/clients/presentation-shm.c
new file mode 100644
index 000..2976b49
--- /dev/null
+++ b/clients/presentation-shm.c
@@ -0,0 +1,866 @@
+/*
+ * Copyright © 2011 Benjamin Franzke
+ * Copyright © 2010 Intel Corporation
+ * Copyright © 2014 Collabora, Ltd.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include "../shared/os-compatibility.h"
+#include "presentation_timing-client-protocol.h"
+
+#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
+
+enum run_mode {
+   RUN_MODE_FEEDBACK,
+   RUN_MODE_FEEDBACK_IDLE,
+   RUN_MODE_PRESENT,
+};
+
+struct output {
+   struct wl_output *output;
+   uint32_t name;
+   struct wl_list link;
+};
+
+struct display {
+   struct wl_display *display;
+   struct wl_registry *registry;
+   struct wl_compositor *compositor;
+   struct wl_sh

Re: [PATCH 3/4 v2] xwayland: Draw decoration on window manager side

2013-08-05 Thread Louis-Francis Ratté-Boulianne
Draw everything in a cairo image surface before copying it to the XCB
surface. That removes the flickering visible on rpi whenever the
decoration were redrawn.
---
 src/xwayland/window-manager.c | 26 --
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/src/xwayland/window-manager.c b/src/xwayland/window-manager.c
index 15cb2ed..594c64f 100644
--- a/src/xwayland/window-manager.c
+++ b/src/xwayland/window-manager.c
@@ -97,6 +97,7 @@ struct weston_wm_window {
xcb_window_t id;
xcb_window_t frame_id;
cairo_surface_t *cairo_surface;
+   cairo_surface_t *cairo_xcb_surface;
struct weston_surface *surface;
struct shell_surface *shsurf;
struct wl_listener surface_destroy_listener;
@@ -900,12 +901,16 @@ weston_wm_handle_map_request(struct weston_wm *wm, 
xcb_generic_event_t *event)
xcb_map_window(wm->conn, map_request->window);
xcb_map_window(wm->conn, window->frame_id);
 
-   window->cairo_surface =
+   window->cairo_xcb_surface =
cairo_xcb_surface_create_with_xrender_format(wm->conn,
 wm->screen,
 window->frame_id,
 &wm->format_rgba,
 width, height);
+   window->cairo_surface =
+   cairo_surface_create_similar_image(window->cairo_xcb_surface,
+  CAIRO_FORMAT_ARGB32,
+  width, height);
 
hash_table_insert(wm->window_hash, window->frame_id, window);
 
@@ -967,6 +972,8 @@ weston_wm_handle_unmap_notify(struct weston_wm *wm, 
xcb_generic_event_t *event)
wl_event_source_remove(window->repaint_source);
if (window->cairo_surface)
cairo_surface_destroy(window->cairo_surface);
+   if (window->cairo_xcb_surface)
+   cairo_surface_destroy(window->cairo_xcb_surface);
 
if (window->frame_id) {
xcb_reparent_window(wm->conn, window->id, wm->wm_window, 0, 0);
@@ -1009,7 +1016,16 @@ weston_wm_window_draw_decoration(void *data)
weston_wm_window_get_frame_size(window, &width, &height);
weston_wm_window_get_child_position(window, &x, &y);
 
-   cairo_xcb_surface_set_size(window->cairo_surface, width, height);
+   if (cairo_image_surface_get_width(window->cairo_surface) != width ||
+   cairo_image_surface_get_height(window->cairo_surface) != height) {
+   cairo_surface_destroy(window->cairo_surface);
+   window->cairo_surface =
+   
cairo_surface_create_similar_image(window->cairo_xcb_surface,
+  CAIRO_FORMAT_ARGB32,
+  width, height);
+   cairo_xcb_surface_set_size(window->cairo_xcb_surface, width, 
height);
+   }
+
cr = cairo_create(window->cairo_surface);
 
if (window->fullscreen) {
@@ -1036,6 +1052,12 @@ weston_wm_window_draw_decoration(void *data)
 
cairo_destroy(cr);
 
+   cr = cairo_create(window->cairo_xcb_surface);
+   cairo_set_source_surface(cr, window->cairo_surface, 0, 0);
+   cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);  
+   cairo_paint(cr);
+   cairo_destroy(cr);
+
if (window->surface) {
pixman_region32_fini(&window->surface->pending.opaque);
if(window->has_alpha) {
-- 
1.8.1.4

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH 3/4] xwayland: Draw decoration on window manager side

2013-08-05 Thread Louis-Francis Ratté-Boulianne
 
On Wednesday, July 31, 2013 10:41 EDT, Uli Schlachter  wrote: 
 
> Hi,
> 
> On 30.07.2013 18:13, Louis-Francis Ratté-Boulianne wrote:
> > Draw everything in a cairo image surface before copying it to the XCB
> > surface. That removes the flickering visible on rpi whenever the
> > decoration were redrawn.
> > ---
> >  src/xwayland/window-manager.c | 22 --
> >  1 file changed, 20 insertions(+), 2 deletions(-)
> > 
> > diff --git a/src/xwayland/window-manager.c b/src/xwayland/window-manager.c
> > index b3c9251..57a5d99 100644
> > --- a/src/xwayland/window-manager.c
> > +++ b/src/xwayland/window-manager.c
> > @@ -97,6 +97,7 @@ struct weston_wm_window {
> > xcb_window_t id;
> > xcb_window_t frame_id;
> > cairo_surface_t *cairo_surface;
> > +   cairo_surface_t *cairo_xcb_surface;
> > struct weston_surface *surface;
> > struct shell_surface *shsurf;
> > struct wl_listener surface_destroy_listener;
> > @@ -900,12 +901,14 @@ weston_wm_handle_map_request(struct weston_wm *wm, 
> > xcb_generic_event_t *event)
> > xcb_map_window(wm->conn, map_request->window);
> > xcb_map_window(wm->conn, window->frame_id);
> >  
> > -   window->cairo_surface =
> > +   window->cairo_xcb_surface =
> > cairo_xcb_surface_create_with_xrender_format(wm->conn,
> >  wm->screen,
> >  window->frame_id,
> >  &wm->format_rgba,
> >  width, height);
> > +   window->cairo_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
> > +   width, height);
> [...]
> 
> Why do you use an image surface for this? I would suggest to use
> cairo_surface_create_similar() instead. This might then give you an XCB 
> surface
> drawing to a temporary pixmap (but it could also be an image surface or
> something completely different).

I tried this way, but it still flickers between a black surface and the drawn 
decoration when the decorations are updated or the window is resized. It's 
still better than having each element showing up one after the other, but still 
really ugly.

Also, I was wondering..if the similar surface that has been created is a XCB 
one, is the rendering on the server side? The objective of my patch was to move 
the drawing on client side (wm) so we know when it's done and we can push it to 
the screen.

> If there is some reason for forcing image surfaces and if depending on cairo
> 1.12 is no problem, I would suggest to use 
> cairo_surface_create_similar_image()
> at least. This would make it possible for cairo to use shared memory instead 
> of
> sending all the pixels over the X11 socket.

That's seem to be the only solution that avoids any flickering while drawing 
the decoration on slow hardware (Raspberry Pi in my case). Unfortunately, there 
is a bug in Cairo < 1.12.6. So if you feel confident that we can update the 
dependency, that's the patch you should push. If not, the old patch still seems 
to be the only working solution for me.

Related cairo commit: "xcb: Clear the result of create_similar_image"
 
> And a third idea would be to use cairo_push_group(); /
> cairo_pop_group_to_source(); cairo_paint();. This would need to be done around
> the drawing code. I don't know this code and I am too lazy to look it up, but 
> if
> this works and could be done easily, this would avoid the memory usage for
> keeping the double-buffering surface around always.

That solution would have been really great to avoid the memory usage, but a 
similar problem occurs (flickering). I guess it's because the decorations are 
still rendered on server side.

Thanks for the review. If you want to see the patches I came up with to test 
the other solutions, let me know.

--
Louis-Francis

> Cheers,
> Uli
> -- 
> - He made himself, me nothing, you nothing out of the dust
> - Er machte sich mir nichts, dir nichts aus dem Staub
 
 
 
 

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 1/4] xwayland: Fix the race condition when mapping a surface

2013-07-30 Thread Louis-Francis Ratté-Boulianne
From: Louis-Francis Ratté-Boulianne 

Make sure XCB_MAP_NOTIFY has been received and the window id has been set 
before mapping the shell surface. It fixes race condition making the surface 
appears at wrong coordinates or with wrong size.
---
 src/xwayland/window-manager.c | 29 +++--
 1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/src/xwayland/window-manager.c b/src/xwayland/window-manager.c
index 257c108..76294fa 100644
--- a/src/xwayland/window-manager.c
+++ b/src/xwayland/window-manager.c
@@ -117,6 +117,8 @@ struct weston_wm_window {
int override_redirect;
int fullscreen;
int has_alpha;
+   int map_notified;
+   int mapped;
 };
 
 static struct weston_wm_window *
@@ -125,6 +127,9 @@ get_wm_window(struct weston_surface *surface);
 static void
 weston_wm_window_schedule_repaint(struct weston_wm_window *window);
 
+static void
+xserver_map_shell_surface(struct weston_wm *wm, struct weston_wm_window 
*window);
+
 static int __attribute__ ((format (printf, 1, 2)))
 wm_log(const char *fmt, ...)
 {
@@ -159,7 +164,6 @@ wm_log_continue(const char *fmt, ...)
 #endif
 }
 
-
 const char *
 get_atom_name(xcb_connection_t *c, xcb_atom_t atom)
 {
@@ -585,6 +589,8 @@ weston_wm_handle_configure_notify(struct weston_wm *wm, 
xcb_generic_event_t *eve
weston_wm_window_get_child_position(window, &x, &y);
window->x = configure_notify->x - x;
window->y = configure_notify->y - y;
+
+   weston_log("handle_configure_notify: (%d, %d)\n", window->x, window->y);
 }
 
 static void
@@ -805,6 +811,14 @@ static void
 weston_wm_handle_map_notify(struct weston_wm *wm, xcb_generic_event_t *event)
 {
xcb_map_notify_event_t *map_notify = (xcb_map_notify_event_t *) event;
+   struct weston_wm_window *window;
+
+   window = hash_table_lookup(wm->window_hash, map_notify->window);
+   weston_log("MAP SURFACE %d, %p\n", map_notify->window, window);
+
+   window->map_notified = 1;
+   if (window->surface != NULL)
+   xserver_map_shell_surface(wm, window);
 
if (our_resource(wm, map_notify->window)) {
wm_log("XCB_MAP_NOTIFY (window %d, ours)\n",
@@ -853,6 +867,7 @@ weston_wm_handle_unmap_notify(struct weston_wm *wm, 
xcb_generic_event_t *event)
wm->focus_window = NULL;
if (window->surface)
wl_list_remove(&window->surface_destroy_listener.link);
+   window->mapped = 0;
window->surface = NULL;
 }
 
@@ -1008,6 +1023,9 @@ weston_wm_window_create(struct weston_wm *wm,
window->override_redirect = override;
window->width = width;
window->height = height;
+   window->surface = NULL;
+   window->map_notified = 0;
+   window->mapped = 0;
 
geometry_reply = xcb_get_geometry_reply(wm->conn, geometry_cookie, 
NULL);
/* technically we should use XRender and check the visual format's
@@ -1914,9 +1932,14 @@ xserver_map_shell_surface(struct weston_wm *wm,
&wm->server->compositor->shell_interface;
struct theme *t = window->wm->theme;
 
+   if (window->mapped)
+   return;
+
if (!shell_interface->create_shell_surface)
return;
 
+   weston_log("MAPPING SURFACE %p\n", window->surface);
+   window->mapped = 1;
window->shsurf = 
shell_interface->create_shell_surface(shell_interface->shell,
  window->surface,
@@ -1969,7 +1992,9 @@ xserver_set_window_id(struct wl_client *client, struct 
wl_resource *resource,
  &window->surface_destroy_listener);
 
weston_wm_window_schedule_repaint(window);
-   xserver_map_shell_surface(wm, window);
+
+   if (window->map_notified)
+   xserver_map_shell_surface(wm, window);
 }
 
 const struct xserver_interface xserver_implementation = {
-- 
1.8.3.1

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH] xwayland: Check surface is not null when handling enter events

2013-07-30 Thread Louis-Francis Ratté-Boulianne
---
 hw/xfree86/xwayland/xwayland-input.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/hw/xfree86/xwayland/xwayland-input.c 
b/hw/xfree86/xwayland/xwayland-input.c
index c550d77..e1858f2 100644
--- a/hw/xfree86/xwayland/xwayland-input.c
+++ b/hw/xfree86/xwayland/xwayland-input.c
@@ -278,6 +278,9 @@ pointer_handle_enter(void *data, struct wl_pointer *pointer,
 int sy = wl_fixed_to_int(sy_w);
 ScreenPtr pScreen = xwl_seat->xwl_screen->screen;
 
+if (surface == NULL)
+return;
+
 xwl_seat->xwl_screen->serial = serial;
 xwl_seat->pointer_enter_serial = serial;
 
-- 
1.8.3.1

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 4/4] xwayland: Implement extended version of _NET_WM_SYNC_REQUEST protocol

2013-07-30 Thread Louis-Francis Ratté-Boulianne
"Extended synchronization provides a more general framework for redraw
coordination, including spontaneous application updates as well as resizing."

See documentation http://fishsoup.net/misc/wm-spec-synchronization.html
---
 src/compositor.c  |   3 +
 src/compositor.h  |   1 +
 src/xwayland/window-manager.c | 219 ++
 src/xwayland/xwayland.h   |   2 +
 4 files changed, 206 insertions(+), 19 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index e9ba0fd..8138f71 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -1323,6 +1323,8 @@ weston_output_repaint(struct weston_output *output, 
uint32_t msecs)
if (output->dirty)
weston_output_update_matrix(output);
 
+   wl_signal_emit(&output->repaint_signal, msecs);
+
output->repaint(output, &output_damage);
 
pixman_region32_fini(&output_damage);
@@ -2741,6 +2743,7 @@ weston_output_init(struct weston_output *output, struct 
weston_compositor *c,
 
wl_signal_init(&output->frame_signal);
wl_signal_init(&output->destroy_signal);
+   wl_signal_init(&output->repaint_signal);
wl_list_init(&output->animation_list);
wl_list_init(&output->resource_list);
 
diff --git a/src/compositor.h b/src/compositor.h
index 57b206e..dccbbff 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -192,6 +192,7 @@ struct weston_output {
int dirty;
struct wl_signal frame_signal;
struct wl_signal destroy_signal;
+   struct wl_signal repaint_signal;
uint32_t frame_time;
int disable_planes;
 
diff --git a/src/xwayland/window-manager.c b/src/xwayland/window-manager.c
index 57a5d99..f083c8b 100644
--- a/src/xwayland/window-manager.c
+++ b/src/xwayland/window-manager.c
@@ -122,9 +122,15 @@ struct weston_wm_window {
int mapped;
xcb_sync_alarm_t sync_request_alarm;
xcb_sync_counter_t sync_request_counter;
+   int sync_request_counter_extended;
struct wl_event_source *sync_request_timer;
+   struct wl_listener frame_listener;
+   struct wl_listener repaint_listener;
int64_t sync_request_serial;
+   int64_t sync_request_wait_serial;
+   uint64_t frame_time;
int configure_pending;
+   int needs_frame_drawn;
int sync_disabled;
int wait_redraw;
 };
@@ -431,7 +437,12 @@ weston_wm_window_read_properties(struct weston_wm_window 
*window)
break;
case XCB_SYNC_COUNTER:
counter = xcb_get_property_value(reply);
-   *(xcb_sync_counter_t *) p = *counter;
+   if (reply->value_len == 2) {
+   *(xcb_sync_counter_t *) p = counter[1];
+   window->sync_request_counter_extended = 1;
+   } else {
+   *(xcb_sync_counter_t *) p = *counter;
+   }
break;
case TYPE_WM_PROTOCOLS:
break;
@@ -746,12 +757,34 @@ weston_wm_window_set_net_wm_state(struct weston_wm_window 
*window)
32, /* format */
i, property);
 }
+ 
+static void
+weston_wm_window_update_frozen(struct weston_wm_window *window)
+{
+   int frozen = 0;
+
+   if (!window->sync_disabled) {
+   if (window->sync_request_counter_extended &&
+   window->sync_request_serial % 2 == 1)
+   frozen = 1;
+
+   if (window->sync_request_serial < 
window->sync_request_wait_serial)
+   frozen = 1;
+
+   if (window->repaint_source)
+   frozen = 1;
+   }
+
+   window->wait_redraw = frozen;
+   /*if (window->surface)
+   window->surface->frozen = frozen;*/
+   weston_log("UPDATE FROZEN %i\n", frozen);
+}
 
 static void
 weston_wm_window_create_sync_alarm(struct weston_wm_window *window)
 {
struct weston_wm *wm = window->wm;
-   xcb_sync_int64_t value;
uint32_t mask;
xcb_sync_create_alarm_value_list_t value_list;
 
@@ -765,16 +798,29 @@ weston_wm_window_create_sync_alarm(struct 
weston_wm_window *window)
return;
}
 
-   value.hi = 0;
-   value.lo = 0;
-   window->sync_request_serial = 0;
-   xcb_sync_set_counter(wm->conn, window->sync_request_counter, value);
+   if (window->sync_request_counter_extended) {
+   xcb_sync_query_counter_cookie_t cookie;
+   xcb_sync_query_counter_reply_t *reply;
+
+   cookie = xcb_sync_query_counter(wm->conn, 
window->sync_request_counter);
+   reply = xcb_sync_query_counter_reply(wm->conn, cookie, NULL);
+   window->sync_request_serial = reply->counter_value.lo;
+   window->sync_request_serial += (int64_t) 
reply->counter_value.hi << 3

[PATCH 3/4] xwayland: Draw decoration on window manager side

2013-07-30 Thread Louis-Francis Ratté-Boulianne
Draw everything in a cairo image surface before copying it to the XCB
surface. That removes the flickering visible on rpi whenever the
decoration were redrawn.
---
 src/xwayland/window-manager.c | 22 --
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/src/xwayland/window-manager.c b/src/xwayland/window-manager.c
index b3c9251..57a5d99 100644
--- a/src/xwayland/window-manager.c
+++ b/src/xwayland/window-manager.c
@@ -97,6 +97,7 @@ struct weston_wm_window {
xcb_window_t id;
xcb_window_t frame_id;
cairo_surface_t *cairo_surface;
+   cairo_surface_t *cairo_xcb_surface;
struct weston_surface *surface;
struct shell_surface *shsurf;
struct wl_listener surface_destroy_listener;
@@ -900,12 +901,14 @@ weston_wm_handle_map_request(struct weston_wm *wm, 
xcb_generic_event_t *event)
xcb_map_window(wm->conn, map_request->window);
xcb_map_window(wm->conn, window->frame_id);
 
-   window->cairo_surface =
+   window->cairo_xcb_surface =
cairo_xcb_surface_create_with_xrender_format(wm->conn,
 wm->screen,
 window->frame_id,
 &wm->format_rgba,
 width, height);
+   window->cairo_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+   width, height);
 
hash_table_insert(wm->window_hash, window->frame_id, window);
 
@@ -967,6 +970,8 @@ weston_wm_handle_unmap_notify(struct weston_wm *wm, 
xcb_generic_event_t *event)
wl_event_source_remove(window->repaint_source);
if (window->cairo_surface)
cairo_surface_destroy(window->cairo_surface);
+   if (window->cairo_xcb_surface)
+   cairo_surface_destroy(window->cairo_xcb_surface);
 
if (window->frame_id) {
xcb_reparent_window(wm->conn, window->id, wm->wm_window, 0, 0);
@@ -1009,7 +1014,14 @@ weston_wm_window_draw_decoration(void *data)
weston_wm_window_get_frame_size(window, &width, &height);
weston_wm_window_get_child_position(window, &x, &y);
 
-   cairo_xcb_surface_set_size(window->cairo_surface, width, height);
+   if (cairo_image_surface_get_width(window->cairo_surface) != width ||
+   cairo_image_surface_get_height(window->cairo_surface) != height) {
+   cairo_surface_destroy(window->cairo_surface);
+   window->cairo_surface = cairo_image_surface_create 
(CAIRO_FORMAT_ARGB32,
+   width, 
height);
+   cairo_xcb_surface_set_size(window->cairo_xcb_surface, width, 
height);
+   }
+
cr = cairo_create(window->cairo_surface);
 
if (window->fullscreen) {
@@ -1036,6 +1048,12 @@ weston_wm_window_draw_decoration(void *data)
 
cairo_destroy(cr);
 
+   cr = cairo_create(window->cairo_xcb_surface);
+   cairo_set_source_surface(cr, window->cairo_surface, 0, 0);
+   cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);  
+   cairo_paint(cr);
+   cairo_destroy(cr);
+
if (window->surface) {
pixman_region32_fini(&window->surface->pending.opaque);
if(window->has_alpha) {
-- 
1.8.3.1

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 2/4] xwayland: Implement _NET_WM_SYNC_REQUEST protocol

2013-07-30 Thread Louis-Francis Ratté-Boulianne
>From the documentation:

"This protocol uses the XSync extension to let client and window manager
synchronize the repaint of the window manager frame and the client window"

 * It makes sure the window manager doesn't send configure events faster
than the application can handle them.
 * If an sync request hasn't been replied after 1 second, the wm switches
back to unsync'd resizing until the sync request counter is updated.
 * Only supported with application/toolkits implementing the protocol.
---
 configure.ac  |   2 +-
 src/xwayland/window-manager.c | 231 --
 src/xwayland/xwayland.h   |   5 +
 3 files changed, 230 insertions(+), 8 deletions(-)

diff --git a/configure.ac b/configure.ac
index f9f1c53..4edd283 100644
--- a/configure.ac
+++ b/configure.ac
@@ -91,7 +91,7 @@ AC_ARG_ENABLE(xwayland-test, [  --enable-xwayland-test],,
 AM_CONDITIONAL(ENABLE_XWAYLAND, test x$enable_xwayland = xyes)
 AM_CONDITIONAL(ENABLE_XWAYLAND_TEST, test x$enable_xwayland = xyes -a 
x$enable_xwayland_test = xyes)
 if test x$enable_xwayland = xyes; then
-  PKG_CHECK_MODULES([XWAYLAND], xcb xcb-xfixes xcursor cairo-xcb)
+  PKG_CHECK_MODULES([XWAYLAND], xcb xcb-sync xcb-xfixes xcursor cairo-xcb)
   AC_DEFINE([BUILD_XWAYLAND], [1], [Build the X server launcher])
 
   AC_ARG_WITH(xserver-path, AS_HELP_STRING([--with-xserver-path=PATH],
diff --git a/src/xwayland/window-manager.c b/src/xwayland/window-manager.c
index 76294fa..b3c9251 100644
--- a/src/xwayland/window-manager.c
+++ b/src/xwayland/window-manager.c
@@ -119,12 +119,22 @@ struct weston_wm_window {
int has_alpha;
int map_notified;
int mapped;
+   xcb_sync_alarm_t sync_request_alarm;
+   xcb_sync_counter_t sync_request_counter;
+   struct wl_event_source *sync_request_timer;
+   int64_t sync_request_serial;
+   int configure_pending;
+   int sync_disabled;
+   int wait_redraw;
 };
 
 static struct weston_wm_window *
 get_wm_window(struct weston_surface *surface);
 
 static void
+weston_wm_window_configure(void *data);
+
+static void
 weston_wm_window_schedule_repaint(struct weston_wm_window *window);
 
 static void
@@ -356,6 +366,7 @@ weston_wm_window_read_properties(struct weston_wm_window 
*window)
{ wm->atom.net_wm_window_type, XCB_ATOM_ATOM, F(type) },
{ wm->atom.net_wm_name, XCB_ATOM_STRING, F(name) },
{ wm->atom.net_wm_pid, XCB_ATOM_CARDINAL, F(pid) },
+   { wm->atom.net_wm_sync_request_counter, XCB_SYNC_COUNTER, 
F(sync_request_counter) },
{ wm->atom.motif_wm_hints, TYPE_MOTIF_WM_HINTS, 0 },
{ wm->atom.wm_client_machine, XCB_ATOM_WM_CLIENT_MACHINE, 
F(machine) },
};
@@ -366,6 +377,7 @@ weston_wm_window_read_properties(struct weston_wm_window 
*window)
void *p;
uint32_t *xid;
xcb_atom_t *atom;
+   xcb_sync_counter_t *counter;
uint32_t i;
struct motif_wm_hints *hints;
 
@@ -416,6 +428,10 @@ weston_wm_window_read_properties(struct weston_wm_window 
*window)
atom = xcb_get_property_value(reply);
*(xcb_atom_t *) p = *atom;
break;
+   case XCB_SYNC_COUNTER:
+   counter = xcb_get_property_value(reply);
+   *(xcb_sync_counter_t *) p = *counter;
+   break;
case TYPE_WM_PROTOCOLS:
break;
case TYPE_NET_WM_STATE:
@@ -731,6 +747,93 @@ weston_wm_window_set_net_wm_state(struct weston_wm_window 
*window)
 }
 
 static void
+weston_wm_window_create_sync_alarm(struct weston_wm_window *window)
+{
+   struct weston_wm *wm = window->wm;
+   xcb_sync_int64_t value;
+   uint32_t mask;
+   xcb_sync_create_alarm_value_list_t value_list;
+
+   if (window->sync_request_counter == 0) {
+   weston_log("NET_WM_SYNC_REQUEST isn't supported by the 
client\n");
+   return;
+   }
+
+   if (window->sync_request_alarm != 0) {
+   weston_log("Sync request alarm has already been created\n");
+   return;
+   }
+
+   value.hi = 0;
+   value.lo = 0;
+   window->sync_request_serial = 0;
+   xcb_sync_set_counter(wm->conn, window->sync_request_counter, value);
+
+   mask = (XCB_SYNC_CA_COUNTER | XCB_SYNC_CA_VALUE_TYPE |
+   XCB_SYNC_CA_VALUE | XCB_SYNC_CA_TEST_TYPE |
+   XCB_SYNC_CA_DELTA | XCB_SYNC_CA_EVENTS);
+   value_list.counter = window->sync_request_counter;
+   value_list.valueType = XCB_SYNC_VALUETYPE_ABSOLUTE;
+   value_list.value.hi = 0;
+   value_list.value.lo = 1;
+   value_list.testType = XCB_SYNC_TESTTYPE_POSITIVE_COMPARISON;
+   value_list.delta.hi = 0;
+   value_list.delta.lo = 1;
+   value_list.events = 1;
+
+   window->sync_request_alarm = xcb_generate_id(wm->conn);
+   xcb_sync_create

[PATCH weston] xwayland: Remove transform listener when destroying the wm

2013-07-19 Thread Louis-Francis Ratté-Boulianne
Fix a segfault occuring after the last X window was closed.
---
 src/xwayland/window-manager.c |1 +
 1 file changed, 1 insertion(+)

diff --git a/src/xwayland/window-manager.c b/src/xwayland/window-manager.c
index fd91004..57a5d99 100644
--- a/src/xwayland/window-manager.c
+++ b/src/xwayland/window-manager.c
@@ -2043,6 +2043,7 @@ weston_wm_destroy(struct weston_wm *wm)
wl_list_remove(&wm->selection_listener.link);
wl_list_remove(&wm->activate_listener.link);
wl_list_remove(&wm->kill_listener.link);
+   wl_list_remove(&wm->transform_listener.link);
 
free(wm);
 }
-- 
1.7.10.4

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH weston 17/18] xwayland: Fix the race condition when mapping a surface

2013-06-14 Thread Louis-Francis Ratté-Boulianne
 Hi,

On Monday, June 10, 2013 14:11 EDT, "MoD"  wrote: 
 
> I've been poking at XWayland+Weston's XWM recently and wanted to find this
> behavior and check that this patch is effective so I could vouch for it, but
> I haven't seen something that looks like windows being mapped with the wrong
> coordinates or size. Louis-Francis, could you explain how to reproduce this
> behavior?

I reproduced it by running LibreOffice on a RaspberryPi. A race condition made 
the menus (sometimes) appears at the wrong spot. The race might be easier to 
reproduce on slowest hardware (rpi) though.

I also found it weird to map the surface without being sure we received 
MAP_NOTIFY first.

> Thanks.
> 
> On 22 de mayo de 2013 at 10:27 AM, ppaala...@gmail.com wrote:
> >
> >From: Louis-Francis Ratté-Boulianne 
> >
> >Make sure XCB_MAP_NOTIFY has been received and the window id has 
> >been
> >set before mapping the shell surface. It fixes race condition 
> >making the
> >surface appears at wrong coordinates or with wrong size.
> >---
> > src/xwayland/window-manager.c | 18 +-
> > 1 file changed, 17 insertions(+), 1 deletion(-)
> >
> >diff --git a/src/xwayland/window-manager.c b/src/xwayland/window-
> >manager.c
> >index 366f2e0..c2e680b 100644
> >--- a/src/xwayland/window-manager.c
> >+++ b/src/xwayland/window-manager.c
> >@@ -113,6 +113,7 @@ struct weston_wm_window {
> > int decorate;
> > int override_redirect;
> > int fullscreen;
> >+int mapped;
> > };
> > 
> > static struct weston_wm_window *
> >@@ -121,6 +122,9 @@ get_wm_window(struct weston_surface *surface);
> > static void
> > weston_wm_window_schedule_repaint(struct weston_wm_window 
> >*window);
> > 
> >+static void
> >+xserver_map_shell_surface(struct weston_wm *wm, struct 
> >weston_wm_window *window);
> >+
> > const char *
> > get_atom_name(xcb_connection_t *c, xcb_atom_t atom)
> > {
> >@@ -723,6 +727,14 @@ static void
> > weston_wm_handle_map_notify(struct weston_wm *wm, 
> >xcb_generic_event_t *event)
> > {
> > xcb_map_notify_event_t *map_notify = (xcb_map_notify_event_t *) 
> >event;
> >+struct weston_wm_window *window;
> >+
> >+window = hash_table_lookup(wm->window_hash, map_notify->window);
> >+
> >+if (window->surface != NULL)
> >+xserver_map_shell_surface(wm, window);
> >+else
> >+window->mapped = 1;
> > 
> > if (our_resource(wm, map_notify->window)) {
> > weston_log("XCB_MAP_NOTIFY (window %d, ours)\n",
> >@@ -915,6 +927,8 @@ weston_wm_window_create(struct weston_wm *wm,
> > window->override_redirect = override;
> > window->width = width;
> > window->height = height;
> >+window->surface = NULL;
> >+window->mapped = 0;
> > 
> > hash_table_insert(wm->window_hash, id, window);
> > }
> >@@ -1874,7 +1888,9 @@ xserver_set_window_id(struct wl_client 
> >*client, struct wl_resource *resource,
> >   &window->surface_destroy_listener);
> > 
> > weston_wm_window_schedule_repaint(window);
> >-xserver_map_shell_surface(wm, window);
> >+
> >+if (window->mapped)
> >+xserver_map_shell_surface(wm, window);
> > }
> > 
> > const struct xserver_interface xserver_implementation = {
> >-- 
> >1.8.1.5
> >
> >___
> >wayland-devel mailing list
> >wayland-devel@lists.freedesktop.org
> >http://lists.freedesktop.org/mailman/listinfo/wayland-devel
> 
 
 
 
 

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel