Skip to content
Commits on Source (7)
......@@ -1578,7 +1578,7 @@ struct weston_buffer_viewport {
int32_t width, height;
} surface;
int changed;
bool changed;
};
struct weston_buffer_release {
......@@ -1728,9 +1728,15 @@ struct weston_view {
struct weston_log_pacer subsurface_parent_log_pacer;
};
enum weston_surface_status {
WESTON_SURFACE_CLEAN = 0,
WESTON_SURFACE_DIRTY_BUFFER = 1 << 0,
WESTON_SURFACE_DIRTY_SIZE = 1 << 1,
};
struct weston_surface_state {
/* wl_surface.attach */
int newly_attached;
bool newly_attached;
struct weston_buffer *buffer;
struct wl_listener buffer_destroy_listener;
......
......@@ -600,7 +600,7 @@ surface_state_handle_buffer_destroy(struct wl_listener *listener, void *data)
static void
weston_surface_state_init(struct weston_surface_state *state)
{
state->newly_attached = 0;
state->newly_attached = false;
state->buffer = NULL;
state->buffer_destroy_listener.notify =
surface_state_handle_buffer_destroy;
......@@ -619,7 +619,7 @@ weston_surface_state_init(struct weston_surface_state *state)
state->buffer_viewport.buffer.scale = 1;
state->buffer_viewport.buffer.src_width = wl_fixed_from_int(-1);
state->buffer_viewport.surface.width = -1;
state->buffer_viewport.changed = 0;
state->buffer_viewport.changed = false;
state->acquire_fence_fd = -1;
......@@ -1958,25 +1958,6 @@ convert_size_by_transform_scale(int32_t *width_out, int32_t *height_out,
}
}
static void
weston_surface_calculate_size_from_buffer(struct weston_surface *surface)
{
struct weston_buffer_viewport *vp = &surface->buffer_viewport;
if (!weston_surface_has_content(surface)) {
surface->width_from_buffer = 0;
surface->height_from_buffer = 0;
return;
}
convert_size_by_transform_scale(&surface->width_from_buffer,
&surface->height_from_buffer,
surface->buffer_ref.buffer->width,
surface->buffer_ref.buffer->height,
vp->buffer.transform,
vp->buffer.scale);
}
static void
weston_surface_update_size(struct weston_surface *surface)
{
......@@ -2133,8 +2114,8 @@ static void
weston_surface_reset_pending_buffer(struct weston_surface *surface)
{
weston_surface_state_set_buffer(&surface->pending, NULL);
surface->pending.newly_attached = 0;
surface->pending.buffer_viewport.changed = 0;
surface->pending.newly_attached = false;
surface->pending.buffer_viewport.changed = false;
}
WL_EXPORT void
......@@ -2660,29 +2641,56 @@ bind_single_pixel_buffer(struct wl_client *client, void *data, uint32_t version,
NULL, NULL);
}
static void
static enum weston_surface_status
weston_surface_attach(struct weston_surface *surface,
struct weston_buffer *buffer)
struct weston_surface_state *state)
{
weston_buffer_reference(&surface->buffer_ref, buffer,
buffer ? BUFFER_MAY_BE_ACCESSED :
BUFFER_WILL_NOT_BE_ACCESSED);
struct weston_buffer_viewport *vp = &state->buffer_viewport;
int32_t old_width = surface->width_from_buffer;
int32_t old_height = surface->height_from_buffer;
struct weston_buffer *buffer = state->buffer;
enum weston_surface_status status = WESTON_SURFACE_CLEAN;
if (!buffer) {
if (weston_surface_is_mapped(surface)) {
weston_surface_unmap(surface);
/* This is the unmapping commit */
surface->is_unmapping = true;
status |= WESTON_SURFACE_DIRTY_BUFFER;
status |= WESTON_SURFACE_DIRTY_SIZE;
}
weston_buffer_reference(&surface->buffer_ref, NULL,
BUFFER_WILL_NOT_BE_ACCESSED);
surface->compositor->renderer->attach(surface, buffer);
surface->width_from_buffer = 0;
surface->height_from_buffer = 0;
return status;
}
convert_size_by_transform_scale(&surface->width_from_buffer,
&surface->height_from_buffer,
buffer->width,
buffer->height,
vp->buffer.transform,
vp->buffer.scale);
if (surface->width_from_buffer != old_width ||
surface->height_from_buffer != old_height) {
status |= WESTON_SURFACE_DIRTY_SIZE;
}
status |= WESTON_SURFACE_DIRTY_BUFFER;
weston_buffer_reference(&surface->buffer_ref, buffer,
BUFFER_MAY_BE_ACCESSED);
surface->compositor->renderer->attach(surface, buffer);
weston_surface_calculate_size_from_buffer(surface);
weston_presentation_feedback_discard_list(&surface->feedback_list);
surface->is_opaque = pixel_format_is_opaque(buffer->pixel_format);
if (buffer)
surface->is_opaque = pixel_format_is_opaque(buffer->pixel_format);
return status;
}
/** weston_compositor_damage_all
......@@ -3697,7 +3705,7 @@ surface_attach(struct wl_client *client,
* wl_buffer.release. */
weston_surface_state_set_buffer(&surface->pending, buffer);
surface->pending.newly_attached = 1;
surface->pending.newly_attached = true;
}
static void
......@@ -4023,12 +4031,15 @@ weston_surface_commit_state(struct weston_surface *surface,
{
struct weston_view *view;
pixman_region32_t opaque;
enum weston_surface_status status = WESTON_SURFACE_CLEAN;
/* wl_surface.set_buffer_transform */
/* wl_surface.set_buffer_scale */
/* wp_viewport.set_source */
/* wp_viewport.set_destination */
surface->buffer_viewport = state->buffer_viewport;
if (surface->buffer_viewport.changed)
status |= WESTON_SURFACE_DIRTY_SIZE;
/* wl_surface.attach */
if (state->newly_attached) {
......@@ -4038,28 +4049,27 @@ weston_surface_commit_state(struct weston_surface *surface,
/* zwp_surface_synchronization_v1.get_release */
weston_buffer_release_move(&surface->buffer_release_ref,
&state->buffer_release_ref);
weston_surface_attach(surface, state->buffer);
/* wp_presentation.feedback */
weston_presentation_feedback_discard_list(&surface->feedback_list);
status |= weston_surface_attach(surface, state);
}
weston_surface_state_set_buffer(state, NULL);
assert(state->acquire_fence_fd == -1);
assert(state->buffer_release_ref.buffer_release == NULL);
weston_surface_build_buffer_matrix(surface,
&surface->surface_to_buffer_matrix);
weston_matrix_invert(&surface->buffer_to_surface_matrix,
&surface->surface_to_buffer_matrix);
if (status & WESTON_SURFACE_DIRTY_SIZE) {
weston_surface_build_buffer_matrix(surface,
&surface->surface_to_buffer_matrix);
weston_matrix_invert(&surface->buffer_to_surface_matrix,
&surface->surface_to_buffer_matrix);
weston_surface_dirty_paint_nodes(surface);
weston_surface_update_size(surface);
}
/* It's possible that this surface's buffer and transform changed
* at the same time in such a way that its size remains the same.
*
* That means we can't depend on view_geometry_dirty() from a
* size update to invalidate the paint node data in all relevant
* cases, so just smash it here.
*/
weston_surface_dirty_paint_nodes(surface);
if (state->newly_attached || state->buffer_viewport.changed ||
if ((status & (WESTON_SURFACE_DIRTY_BUFFER | WESTON_SURFACE_DIRTY_SIZE)) ||
state->sx != 0 || state->sy != 0) {
weston_surface_update_size(surface);
if (surface->committed) {
struct weston_coord_surface new_origin;
......@@ -4072,8 +4082,8 @@ weston_surface_commit_state(struct weston_surface *surface,
state->sx = 0;
state->sy = 0;
state->newly_attached = 0;
state->buffer_viewport.changed = 0;
state->newly_attached = false;
state->buffer_viewport.changed = false;
/* wl_surface.damage and wl_surface.damage_buffer */
if (pixman_region32_not_empty(&state->damage_surface) ||
......@@ -4241,7 +4251,7 @@ surface_set_buffer_transform(struct wl_client *client,
}
surface->pending.buffer_viewport.buffer.transform = transform;
surface->pending.buffer_viewport.changed = 1;
surface->pending.buffer_viewport.changed = true;
}
static void
......@@ -4260,7 +4270,7 @@ surface_set_buffer_scale(struct wl_client *client,
}
surface->pending.buffer_viewport.buffer.scale = scale;
surface->pending.buffer_viewport.changed = 1;
surface->pending.buffer_viewport.changed = true;
}
static void
......@@ -4431,7 +4441,7 @@ weston_subsurface_commit_to_cache(struct weston_subsurface *sub)
pixman_region32_clear(&surface->pending.damage_buffer);
if (surface->pending.newly_attached) {
sub->cached.newly_attached = 1;
sub->cached.newly_attached = true;
weston_surface_state_set_buffer(&sub->cached,
surface->pending.buffer);
weston_buffer_reference(&sub->cached_buffer_ref,
......@@ -7795,7 +7805,7 @@ destroy_viewport(struct wl_resource *resource)
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;
surface->pending.buffer_viewport.changed = true;
}
static void
......@@ -7833,7 +7843,7 @@ viewport_set_source(struct wl_client *client,
/* unset source rect */
surface->pending.buffer_viewport.buffer.src_width =
wl_fixed_from_int(-1);
surface->pending.buffer_viewport.changed = 1;
surface->pending.buffer_viewport.changed = true;
return;
}
......@@ -7854,7 +7864,7 @@ viewport_set_source(struct wl_client *client,
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;
surface->pending.buffer_viewport.changed = true;
}
static void
......@@ -7878,7 +7888,7 @@ viewport_set_destination(struct wl_client *client,
if (dst_width == -1 && dst_height == -1) {
/* unset destination size */
surface->pending.buffer_viewport.surface.width = -1;
surface->pending.buffer_viewport.changed = 1;
surface->pending.buffer_viewport.changed = true;
return;
}
......@@ -7892,7 +7902,7 @@ viewport_set_destination(struct wl_client *client,
surface->pending.buffer_viewport.surface.width = dst_width;
surface->pending.buffer_viewport.surface.height = dst_height;
surface->pending.buffer_viewport.changed = 1;
surface->pending.buffer_viewport.changed = true;
}
static const struct wp_viewport_interface viewport_interface = {
......