surface->buffer_viewport.buffer.scale = 1;
surface->buffer_viewport.buffer.src_width = wl_fixed_from_int(-1);
surface->buffer_viewport.surface.width = -1;
+ surface->pending.buffer_viewport.changed = 0;
surface->pending.buffer_viewport = surface->buffer_viewport;
surface->output = NULL;
surface->pending.newly_attached = 0;
}
static void
-weston_surface_set_size_from_buffer(struct weston_surface *surface)
+weston_surface_calculate_size_from_buffer(struct weston_surface *surface)
{
struct weston_buffer_viewport *vp = &surface->buffer_viewport;
int32_t width, height;
if (!surface->buffer_ref.buffer) {
- surface_set_size(surface, 0, 0);
surface->width_from_buffer = 0;
surface->height_from_buffer = 0;
return;
surface->width_from_buffer = width;
surface->height_from_buffer = height;
+}
+
+static void
+weston_surface_update_size(struct weston_surface *surface)
+{
+ struct weston_buffer_viewport *vp = &surface->buffer_viewport;
+ int32_t width, height;
+
+ width = surface->width_from_buffer;
+ height = surface->height_from_buffer;
- if (vp->surface.width != -1) {
+ if (width != 0 && vp->surface.width != -1) {
surface_set_size(surface,
vp->surface.width, vp->surface.height);
return;
}
- if (vp->buffer.src_width != wl_fixed_from_int(-1)) {
+ if (width != 0 && vp->buffer.src_width != wl_fixed_from_int(-1)) {
int32_t w = fixed_round_up_to_int(vp->buffer.src_width);
int32_t h = fixed_round_up_to_int(vp->buffer.src_height);
surface->pending.sx = 0;
surface->pending.sy = 0;
surface->pending.newly_attached = 0;
+ surface->pending.buffer_viewport.changed = 0;
}
struct weston_frame_callback {
surface->compositor->renderer->attach(surface, buffer);
- weston_surface_set_size_from_buffer(surface);
+ weston_surface_calculate_size_from_buffer(surface);
}
WL_EXPORT void
struct weston_view *view;
pixman_region32_t opaque;
- /* XXX: wl_viewport.set without an attach should call configure */
-
/* wl_surface.set_buffer_transform */
/* wl_surface.set_buffer_scale */
/* wl_viewport.set */
if (surface->pending.newly_attached)
weston_surface_attach(surface, surface->pending.buffer);
- if (surface->configure && surface->pending.newly_attached)
- surface->configure(surface,
- surface->pending.sx, surface->pending.sy);
+ if (surface->pending.newly_attached ||
+ surface->pending.buffer_viewport.changed) {
+ weston_surface_update_size(surface);
+ if (surface->configure)
+ surface->configure(surface, surface->pending.sx,
+ surface->pending.sy);
+ }
weston_surface_reset_pending_buffer(surface);
}
surface->pending.buffer_viewport.buffer.transform = transform;
+ surface->pending.buffer_viewport.changed = 1;
}
static void
}
surface->pending.buffer_viewport.buffer.scale = scale;
+ surface->pending.buffer_viewport.changed = 1;
}
static const struct wl_surface_interface surface_interface = {
weston_surface_attach(surface, sub->cached.buffer_ref.buffer);
weston_buffer_reference(&sub->cached.buffer_ref, NULL);
- if (surface->configure && sub->cached.newly_attached)
- surface->configure(surface, sub->cached.sx, sub->cached.sy);
+ if (sub->cached.newly_attached || sub->cached.buffer_viewport.changed) {
+ weston_surface_update_size(surface);
+ if (surface->configure)
+ surface->configure(surface, sub->cached.sx,
+ sub->cached.sy);
+ }
+
sub->cached.sx = 0;
sub->cached.sy = 0;
sub->cached.newly_attached = 0;
+ sub->cached.buffer_viewport.changed = 0;
/* wl_surface.damage */
pixman_region32_union(&surface->damage, &surface->damage,
sub->cached.sx += surface->pending.sx;
sub->cached.sy += surface->pending.sy;
- weston_surface_reset_pending_buffer(surface);
+ sub->cached.buffer_viewport.changed |=
+ surface->pending.buffer_viewport.changed;
+ sub->cached.buffer_viewport.buffer =
+ surface->pending.buffer_viewport.buffer;
+ sub->cached.buffer_viewport.surface =
+ surface->pending.buffer_viewport.surface;
- sub->cached.buffer_viewport = surface->pending.buffer_viewport;
+ weston_surface_reset_pending_buffer(surface);
pixman_region32_copy(&sub->cached.opaque, &surface->pending.opaque);
surface->pending.buffer_viewport.buffer.src_width =
wl_fixed_from_int(-1);
surface->pending.buffer_viewport.surface.width = -1;
+ surface->pending.buffer_viewport.changed = 1;
}
static void
surface->pending.buffer_viewport.buffer.src_height = src_height;
surface->pending.buffer_viewport.surface.width = dst_width;
surface->pending.buffer_viewport.surface.height = dst_height;
+ surface->pending.buffer_viewport.changed = 1;
}
static void
/* unset source size */
surface->pending.buffer_viewport.buffer.src_width =
wl_fixed_from_int(-1);
+ surface->pending.buffer_viewport.changed = 1;
return;
}
surface->pending.buffer_viewport.buffer.src_y = src_y;
surface->pending.buffer_viewport.buffer.src_width = src_width;
surface->pending.buffer_viewport.buffer.src_height = src_height;
+ surface->pending.buffer_viewport.changed = 1;
}
static void
if (dst_width == -1 && dst_height == -1) {
/* unset destination size */
surface->pending.buffer_viewport.surface.width = -1;
+ surface->pending.buffer_viewport.changed = 1;
return;
}
surface->pending.buffer_viewport.surface.width = dst_width;
surface->pending.buffer_viewport.surface.height = dst_height;
+ surface->pending.buffer_viewport.changed = 1;
}
static const struct wl_viewport_interface viewport_interface = {