<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Jun 13, 2014 at 9:14 AM, George Kiagiadakis <span dir="ltr"><<a href="mailto:george.kiagiadakis@collabora.com" target="_blank">george.kiagiadakis@collabora.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This fixes at least the case where you want to do wl_viewport.set_destination<br>
to resize the surface but without attaching new content in it.<br>
---<br>
src/compositor.c | 60 +++++++++++++++++++++++++++++++++++++++++++-------------<br>
src/compositor.h | 2 ++<br>
2 files changed, 48 insertions(+), 14 deletions(-)<br>
<br>
diff --git a/src/compositor.c b/src/compositor.c<br>
index 2fbfdbf..973c7e4 100644<br>
--- a/src/compositor.c<br>
+++ b/src/compositor.c<br>
@@ -404,6 +404,7 @@ weston_surface_create(struct weston_compositor *compositor)<br>
surface->buffer_viewport.buffer.scale = 1;<br>
surface->buffer_viewport.buffer.src_width = wl_fixed_from_int(-1);<br>
surface->buffer_viewport.surface.width = -1;<br>
+ surface->pending.buffer_viewport.changed = 0;<br>
surface->pending.buffer_viewport = surface->buffer_viewport;<br>
surface->output = NULL;<br>
surface->pending.newly_attached = 0;<br>
@@ -1211,13 +1212,12 @@ fixed_round_up_to_int(wl_fixed_t f)<br>
}<br>
<br>
static void<br>
-weston_surface_set_size_from_buffer(struct weston_surface *surface)<br>
+weston_surface_calculate_size_from_buffer(struct weston_surface *surface)<br>
{<br>
struct weston_buffer_viewport *vp = &surface->buffer_viewport;<br>
int32_t width, height;<br>
<br>
if (!surface->buffer_ref.buffer) {<br>
- surface_set_size(surface, 0, 0);<br>
surface->width_from_buffer = 0;<br>
surface->height_from_buffer = 0;<br>
return;<br>
@@ -1239,14 +1239,24 @@ weston_surface_set_size_from_buffer(struct weston_surface *surface)<br>
<br>
surface->width_from_buffer = width;<br>
surface->height_from_buffer = height;<br>
+}<br>
+<br>
+static void<br>
+weston_surface_update_size(struct weston_surface *surface)<br>
+{<br>
+ struct weston_buffer_viewport *vp = &surface->buffer_viewport;<br>
+ int32_t width, height;<br>
+<br>
+ width = surface->width_from_buffer;<br>
+ height = surface->height_from_buffer;<br>
<br>
- if (vp->surface.width != -1) {<br>
+ if (width != 0 && vp->surface.width != -1) {<br>
surface_set_size(surface,<br>
vp->surface.width, vp->surface.height);<br>
return;<br>
}<br>
<br>
- if (vp->buffer.src_width != wl_fixed_from_int(-1)) {<br>
+ if (width != 0 && vp->buffer.src_width != wl_fixed_from_int(-1)) {<br>
int32_t w = fixed_round_up_to_int(vp->buffer.src_width);<br>
int32_t h = fixed_round_up_to_int(vp->buffer.src_height);<br>
<br>
@@ -1351,6 +1361,7 @@ weston_surface_reset_pending_buffer(struct weston_surface *surface)<br>
surface->pending.sx = 0;<br>
surface-><a href="http://pending.sy" target="_blank">pending.sy</a> = 0;<br>
surface->pending.newly_attached = 0;<br>
+ surface->pending.buffer_viewport.changed = 0;<br>
}<br>
<br>
struct weston_frame_callback {<br>
@@ -1520,7 +1531,7 @@ weston_surface_attach(struct weston_surface *surface,<br>
<br>
surface->compositor->renderer->attach(surface, buffer);<br>
<br>
- weston_surface_set_size_from_buffer(surface);<br>
+ weston_surface_calculate_size_from_buffer(surface);<br>
}<br></blockquote><div><br></div><div>I think we have an issue here. If a client attaches a new buffer but does not commit for a while, the width/height_from_buffer and width/height will be out of sync. That said, I think having surface_set_size_from_buffer here was wrong in the first place. The new surface size should only take over after the commit. Other than that, the patch looks fine to me.<br>
</div><div>--Jason Ekstrand<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
WL_EXPORT void<br>
@@ -2049,8 +2060,6 @@ weston_surface_commit(struct weston_surface *surface)<br>
struct weston_view *view;<br>
pixman_region32_t opaque;<br>
<br>
- /* XXX: wl_viewport.set without an attach should call configure */<br>
-<br>
/* wl_surface.set_buffer_transform */<br>
/* wl_surface.set_buffer_scale */<br>
/* wl_viewport.set */<br>
@@ -2060,9 +2069,13 @@ weston_surface_commit(struct weston_surface *surface)<br>
if (surface->pending.newly_attached)<br>
weston_surface_attach(surface, surface->pending.buffer);<br>
<br>
- if (surface->configure && surface->pending.newly_attached)<br>
- surface->configure(surface,<br>
- surface->pending.sx, surface-><a href="http://pending.sy" target="_blank">pending.sy</a>);<br>
+ if (surface->pending.newly_attached ||<br>
+ surface->pending.buffer_viewport.changed) {<br>
+ weston_surface_update_size(surface);<br>
+ if (surface->configure)<br>
+ surface->configure(surface, surface->pending.sx,<br>
+ surface-><a href="http://pending.sy" target="_blank">pending.sy</a>);<br>
+ }<br>
<br>
weston_surface_reset_pending_buffer(surface);<br>
<br>
@@ -2151,6 +2164,7 @@ surface_set_buffer_transform(struct wl_client *client,<br>
}<br>
<br>
surface->pending.buffer_viewport.buffer.transform = transform;<br>
+ surface->pending.buffer_viewport.changed = 1;<br>
}<br>
<br>
static void<br>
@@ -2169,6 +2183,7 @@ surface_set_buffer_scale(struct wl_client *client,<br>
}<br>
<br>
surface->pending.buffer_viewport.buffer.scale = scale;<br>
+ surface->pending.buffer_viewport.changed = 1;<br>
}<br>
<br>
static const struct wl_surface_interface surface_interface = {<br>
@@ -2300,11 +2315,17 @@ weston_subsurface_commit_from_cache(struct weston_subsurface *sub)<br>
weston_surface_attach(surface, sub->cached.buffer_ref.buffer);<br>
weston_buffer_reference(&sub->cached.buffer_ref, NULL);<br>
<br>
- if (surface->configure && sub->cached.newly_attached)<br>
- surface->configure(surface, sub->cached.sx, sub-><a href="http://cached.sy" target="_blank">cached.sy</a>);<br>
+ if (sub->cached.newly_attached || sub->cached.buffer_viewport.changed) {<br>
+ weston_surface_update_size(surface);<br>
+ if (surface->configure)<br>
+ surface->configure(surface, sub->cached.sx,<br>
+ sub-><a href="http://cached.sy" target="_blank">cached.sy</a>);<br>
+ }<br>
+<br>
sub->cached.sx = 0;<br>
sub-><a href="http://cached.sy" target="_blank">cached.sy</a> = 0;<br>
sub->cached.newly_attached = 0;<br>
+ sub->cached.buffer_viewport.changed = 0;<br>
<br>
/* wl_surface.damage */<br>
pixman_region32_union(&surface->damage, &surface->damage,<br>
@@ -2375,9 +2396,14 @@ weston_subsurface_commit_to_cache(struct weston_subsurface *sub)<br>
sub->cached.sx += surface->pending.sx;<br>
sub-><a href="http://cached.sy" target="_blank">cached.sy</a> += surface-><a href="http://pending.sy" target="_blank">pending.sy</a>;<br>
<br>
- weston_surface_reset_pending_buffer(surface);<br>
+ sub->cached.buffer_viewport.changed |=<br>
+ surface->pending.buffer_viewport.changed;<br>
+ sub->cached.buffer_viewport.buffer =<br>
+ surface->pending.buffer_viewport.buffer;<br>
+ sub->cached.buffer_viewport.surface =<br>
+ surface->pending.buffer_viewport.surface;<br>
<br>
- sub->cached.buffer_viewport = surface->pending.buffer_viewport;<br>
+ weston_surface_reset_pending_buffer(surface);<br>
<br>
pixman_region32_copy(&sub->cached.opaque, &surface->pending.opaque);<br>
<br>
@@ -3425,6 +3451,7 @@ destroy_viewport(struct wl_resource *resource)<br>
surface->pending.buffer_viewport.buffer.src_width =<br>
wl_fixed_from_int(-1);<br>
surface->pending.buffer_viewport.surface.width = -1;<br>
+ surface->pending.buffer_viewport.changed = 1;<br>
}<br>
<br>
static void<br>
@@ -3473,6 +3500,7 @@ viewport_set(struct wl_client *client,<br>
surface->pending.buffer_viewport.buffer.src_height = src_height;<br>
surface->pending.buffer_viewport.surface.width = dst_width;<br>
surface->pending.buffer_viewport.surface.height = dst_height;<br>
+ surface->pending.buffer_viewport.changed = 1;<br>
}<br>
<br>
static void<br>
@@ -3493,6 +3521,7 @@ viewport_set_source(struct wl_client *client,<br>
/* unset source size */<br>
surface->pending.buffer_viewport.buffer.src_width =<br>
wl_fixed_from_int(-1);<br>
+ surface->pending.buffer_viewport.changed = 1;<br>
return;<br>
}<br>
<br>
@@ -3509,6 +3538,7 @@ viewport_set_source(struct wl_client *client,<br>
surface->pending.buffer_viewport.buffer.src_y = src_y;<br>
surface->pending.buffer_viewport.buffer.src_width = src_width;<br>
surface->pending.buffer_viewport.buffer.src_height = src_height;<br>
+ surface->pending.buffer_viewport.changed = 1;<br>
}<br>
<br>
static void<br>
@@ -3525,6 +3555,7 @@ viewport_set_destination(struct wl_client *client,<br>
if (dst_width == -1 && dst_height == -1) {<br>
/* unset destination size */<br>
surface->pending.buffer_viewport.surface.width = -1;<br>
+ surface->pending.buffer_viewport.changed = 1;<br>
return;<br>
}<br>
<br>
@@ -3538,6 +3569,7 @@ viewport_set_destination(struct wl_client *client,<br>
<br>
surface->pending.buffer_viewport.surface.width = dst_width;<br>
surface->pending.buffer_viewport.surface.height = dst_height;<br>
+ surface->pending.buffer_viewport.changed = 1;<br>
}<br>
<br>
static const struct wl_viewport_interface viewport_interface = {<br>
diff --git a/src/compositor.h b/src/compositor.h<br>
index 057f8be..eae1b20 100644<br>
--- a/src/compositor.h<br>
+++ b/src/compositor.h<br>
@@ -686,6 +686,8 @@ struct weston_buffer_viewport {<br>
*/<br>
int32_t width, height;<br>
} surface;<br>
+<br>
+ int changed;<br>
};<br>
<br>
struct weston_region {<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.0.0<br>
<br>
_______________________________________________<br>
wayland-devel mailing list<br>
<a href="mailto:wayland-devel@lists.freedesktop.org">wayland-devel@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/wayland-devel" target="_blank">http://lists.freedesktop.org/mailman/listinfo/wayland-devel</a><br>
</font></span></blockquote></div><br></div></div>