Skip to content
Commits on Source (22)
......@@ -440,6 +440,13 @@ enum weston_output_power_state {
WESTON_OUTPUT_POWER_NORMAL
};
struct weston_plane {
struct weston_compositor *compositor;
pixman_region32_t clip;
int32_t x, y;
struct wl_list link;
};
/** Content producer for heads
*
* \rst
......@@ -455,6 +462,7 @@ struct weston_output {
struct wl_signal user_destroy_signal;
void *renderer_state;
struct weston_plane primary_plane;
struct wl_list link;
struct weston_compositor *compositor;
......@@ -484,6 +492,9 @@ struct weston_output {
* if set, a repaint will eventually occur. */
bool repaint_needed;
/** True if the entire contents of the output should be redrawn */
bool full_repaint_needed;
/** Used only between repaint_begin and repaint_cancel. */
bool repainted;
......@@ -1262,14 +1273,6 @@ struct weston_layer {
struct weston_layer_entry view_list;
};
struct weston_plane {
struct weston_compositor *compositor;
pixman_region32_t damage; /**< in global coords */
pixman_region32_t clip;
int32_t x, y;
struct wl_list link;
};
struct weston_drm_format_array;
enum weston_capability {
......@@ -1428,7 +1431,6 @@ struct weston_compositor {
const struct weston_pointer_grab_interface *default_pointer_grab;
/* Repaint state. */
struct weston_plane primary_plane;
uint32_t capabilities; /* combination of enum weston_capability */
struct weston_color_manager *color_manager;
......@@ -1646,14 +1648,13 @@ struct weston_view {
struct wl_list link; /* weston_compositor::view_list */
struct weston_layer_entry layer_link; /* part of geometry */
struct weston_plane *plane;
/* For weston_layer inheritance from another view */
struct weston_view *parent_view;
unsigned int click_to_activate_serial;
pixman_region32_t clip; /* See weston_view_damage_below() */
pixman_region32_t visible; /* Unoccluded region in global space */
float alpha; /* part of geometry, see below */
/* Surface geometry state, mutable.
......
......@@ -324,7 +324,7 @@ drm_virtual_output_enable(struct weston_output *output_base)
weston_compositor_stack_plane(b->compositor,
&output->scanout_plane->base,
&b->compositor->primary_plane);
&output->base.primary_plane);
return 0;
err:
......
......@@ -415,9 +415,6 @@ drm_output_render(struct drm_output_state *state, pixman_region32_t *damage)
scanout_state->zpos = scanout_plane->zpos_min;
pixman_region32_subtract(&c->primary_plane.damage,
&c->primary_plane.damage, damage);
/* Don't bother calculating plane damage if the plane doesn't support it */
if (damage_info->prop_id == 0)
return;
......@@ -1209,7 +1206,7 @@ create_sprites(struct drm_device *device)
if (drm_plane->type == WDRM_PLANE_TYPE_OVERLAY)
weston_compositor_stack_plane(b->compositor,
&drm_plane->base,
&b->compositor->primary_plane);
NULL);
}
wl_list_for_each (drm_plane, &device->plane_list, link)
......@@ -1941,7 +1938,7 @@ drm_output_init_planes(struct drm_output *output)
weston_compositor_stack_plane(b->compositor,
&output->scanout_plane->base,
&b->compositor->primary_plane);
&output->base.primary_plane);
/* Failing to find a cursor plane is not fatal, as we'll fall back
* to software cursor. */
......
......@@ -708,8 +708,6 @@ drm_output_set_cursor(struct drm_output_state *output_state)
return;
if (!state->fb) {
pixman_region32_fini(&plane->base.damage);
pixman_region32_init(&plane->base.damage);
drmModeSetCursor(device->drm.fd, crtc->crtc_id, 0, 0, 0);
return;
}
......@@ -727,9 +725,6 @@ drm_output_set_cursor(struct drm_output_state *output_state)
}
}
pixman_region32_fini(&plane->base.damage);
pixman_region32_init(&plane->base.damage);
if (drmModeMoveCursor(device->drm.fd, crtc->crtc_id,
state->dest_x, state->dest_y)) {
weston_log("failed to move cursor: %s\n", strerror(errno));
......
......@@ -767,14 +767,7 @@ drm_output_propose_state(struct weston_output *output_base,
ev, output->base.name,
(unsigned long) output->base.id);
/* If this view doesn't touch our output at all, there's no
* reason to do anything with it. */
/* TODO: turn this into assert once z_order_list is pruned. */
if (!(ev->output_mask & (1u << output->base.id))) {
drm_debug(b, "\t\t\t\t[view] ignoring view %p "
"(not on our output)\n", ev);
continue;
}
assert(ev->output_mask & (1u << output->base.id));
/* Cannot show anything without a color transform. */
if (!pnode->surf_xform_valid) {
......@@ -804,14 +797,6 @@ drm_output_propose_state(struct weston_output *output_base,
continue;
}
/* We only assign planes to views which are exclusively present
* on our output. */
if (ev->output_mask != (1u << output->base.id)) {
drm_debug(b, "\t\t\t\t[view] not assigning view %p to plane "
"(on multiple outputs)\n", ev);
force_renderer = true;
}
if (!b->gbm) {
drm_debug(b, "\t\t\t\t[view] not assigning view %p to plane "
"(GBM not available)\n", ev);
......@@ -969,7 +954,7 @@ drm_assign_planes(struct weston_output *output_base)
struct drm_plane_state *plane_state;
struct drm_writeback_state *wb_state = output->wb_state;
struct weston_paint_node *pnode;
struct weston_plane *primary = &output_base->compositor->primary_plane;
struct weston_plane *primary = &output_base->primary_plane;
enum drm_output_propose_state_mode mode = DRM_OUTPUT_PROPOSE_STATE_PLANES_ONLY;
assert(output);
......@@ -1022,11 +1007,7 @@ drm_assign_planes(struct weston_output *output_base)
struct weston_view *ev = pnode->view;
struct drm_plane *target_plane = NULL;
/* If this view doesn't touch our output at all, there's no
* reason to do anything with it. */
/* TODO: turn this into assert once z_order_list is pruned. */
if (!(ev->output_mask & (1u << output->base.id)))
continue;
assert(ev->output_mask & (1u << output->base.id));
/* Update dmabuf-feedback if needed */
if (ev->surface->dmabuf_feedback)
......@@ -1066,11 +1047,11 @@ drm_assign_planes(struct weston_output *output_base)
drm_debug(b, "\t[repaint] view %p on %s plane %lu\n",
ev, plane_type_enums[target_plane->type].name,
(unsigned long) target_plane->plane_id);
weston_view_move_to_plane(ev, &target_plane->base);
weston_paint_node_move_to_plane(pnode, &target_plane->base);
} else {
drm_debug(b, "\t[repaint] view %p using renderer "
"composition\n", ev);
weston_view_move_to_plane(ev, primary);
weston_paint_node_move_to_plane(pnode, primary);
}
if (!target_plane ||
......
......@@ -167,9 +167,6 @@ headless_output_repaint(struct weston_output *output_base,
ec->renderer->repaint_output(&output->base, damage,
output->renderbuffer);
pixman_region32_subtract(&ec->primary_plane.damage,
&ec->primary_plane.damage, damage);
wl_event_source_timer_update(output->finish_frame_timer, 16);
return 0;
......
......@@ -789,8 +789,6 @@ pipewire_output_repaint(struct weston_output *base, pixman_region32_t *damage)
pipewire_submit_buffer(output, buffer);
pixman_region32_subtract(&ec->primary_plane.damage,
&ec->primary_plane.damage, damage);
out:
pipewire_output_arm_timer(output);
......
......@@ -317,9 +317,6 @@ rdp_output_repaint(struct weston_output *output_base, pixman_region32_t *damage)
pixman_region32_fini(&transformed_damage);
}
pixman_region32_subtract(&ec->primary_plane.damage,
&ec->primary_plane.damage, damage);
wl_event_source_timer_update(output->finish_frame_timer, next_frame_delta);
return 0;
}
......
......@@ -449,7 +449,8 @@ vnc_client_cleanup(struct nvnc_client *client)
}
static struct weston_pointer *
vnc_output_get_pointer(struct vnc_output *output)
vnc_output_get_pointer(struct vnc_output *output,
struct weston_paint_node **pointer_pnode)
{
struct weston_pointer *pointer = NULL;
struct weston_paint_node *pnode;
......@@ -464,8 +465,10 @@ vnc_output_get_pointer(struct vnc_output *output)
return NULL;
wl_list_for_each(pnode, &output->base.paint_node_z_order_list, z_order_link) {
if (pnode->view == pointer->sprite)
if (pnode->view == pointer->sprite) {
*pointer_pnode = pnode;
return pointer;
}
}
return NULL;
......@@ -476,6 +479,7 @@ vnc_output_update_cursor(struct vnc_output *output)
{
struct vnc_backend *backend = output->backend;
struct weston_pointer *pointer;
struct weston_paint_node *pointer_pnode = NULL;
struct weston_view *view;
struct weston_buffer *buffer;
struct nvnc_fb *fb;
......@@ -484,7 +488,7 @@ vnc_output_update_cursor(struct vnc_output *output)
uint8_t *src, *dst;
int i;
pointer = vnc_output_get_pointer(output);
pointer = vnc_output_get_pointer(output, &pointer_pnode);
if (!pointer)
return;
......@@ -500,7 +504,9 @@ vnc_output_update_cursor(struct vnc_output *output)
if (format != WL_SHM_FORMAT_ARGB8888)
return;
weston_view_move_to_plane(view, &output->cursor_plane);
assert(pointer_pnode);
weston_paint_node_move_to_plane(pointer_pnode, &output->cursor_plane);
if (view->surface == output->cursor_surface &&
!pixman_region32_not_empty(&view->surface->damage))
......@@ -957,8 +963,6 @@ vnc_output_repaint(struct weston_output *base, pixman_region32_t *damage)
if (pixman_region32_not_empty(damage)) {
vnc_update_buffer(output->display, damage);
pixman_region32_subtract(&ec->primary_plane.damage,
&ec->primary_plane.damage, damage);
}
/*
......@@ -1031,7 +1035,7 @@ vnc_fb_get_from_view(struct weston_view *view)
static void
vnc_output_assign_planes(struct weston_output *base)
{
struct weston_plane *primary = &base->compositor->primary_plane;
struct weston_plane *primary = &base->primary_plane;
struct vnc_output *output = to_vnc_output(base);
struct weston_paint_node *pnode;
bool topmost = true;
......@@ -1049,14 +1053,10 @@ vnc_output_assign_planes(struct weston_output *base)
struct weston_view *view = pnode->view;
struct nvnc_fb *fb = NULL;
/* If this view doesn't touch our output at all, there's no
* reason to do anything with it. */
/* TODO: turn this into assert once z_order_list is pruned. */
if (!(view->output_mask & (1u << output->base.id)))
continue;
assert(view->output_mask & (1u << output->base.id));
/* Skip cursor view */
if (view->plane == &output->cursor_plane)
if (pnode->plane == &output->cursor_plane)
continue;
if (topmost &&
......@@ -1067,7 +1067,7 @@ vnc_output_assign_planes(struct weston_output *base)
pixman_region32_t local_damage;
pixman_region16_t nvnc_damage;
weston_view_move_to_plane(view, &output->scanout_plane);
weston_paint_node_move_to_plane(pnode, &output->scanout_plane);
/* Convert to local coordinates */
pixman_region32_init(&local_damage);
......@@ -1089,7 +1089,7 @@ vnc_output_assign_planes(struct weston_output *base)
nvnc_fb_unref(fb);
} else {
weston_view_move_to_plane(view, primary);
weston_paint_node_move_to_plane(pnode, primary);
}
topmost = false;
......
......@@ -515,8 +515,6 @@ wayland_output_repaint_gl(struct weston_output *output_base,
ec->renderer->repaint_output(&output->base, damage, NULL);
pixman_region32_subtract(&ec->primary_plane.damage,
&ec->primary_plane.damage, damage);
return 0;
}
#endif
......@@ -638,8 +636,6 @@ wayland_output_repaint_pixman(struct weston_output *output_base,
sb->frame_damaged = 0;
pixman_region32_subtract(&b->compositor->primary_plane.damage,
&b->compositor->primary_plane.damage, damage);
return 0;
}
......
......@@ -441,9 +441,6 @@ x11_output_repaint_gl(struct weston_output *output_base,
ec->renderer->repaint_output(output_base, damage, NULL);
pixman_region32_subtract(&ec->primary_plane.damage,
&ec->primary_plane.damage, damage);
wl_event_source_timer_update(output->finish_frame_timer, 10);
return 0;
}
......@@ -522,8 +519,6 @@ x11_output_repaint_shm(struct weston_output *output_base,
ec->renderer->repaint_output(output_base, damage, output->renderbuffer);
pixman_region32_subtract(&ec->primary_plane.damage,
&ec->primary_plane.damage, damage);
set_clip_for_output(output_base, damage);
cookie = xcb_shm_put_image_checked(b->conn, output->window, output->gc,
pixman_image_get_width(image),
......
This diff is collapsed.
......@@ -418,8 +418,8 @@ weston_view_takes_input_at_point(struct weston_view *view,
struct weston_coord_surface surf_pos);
void
weston_view_move_to_plane(struct weston_view *view,
struct weston_plane *plane);
weston_paint_node_move_to_plane(struct weston_paint_node *pnode,
struct weston_plane *plane);
void
weston_view_buffer_to_output_matrix(const struct weston_view *view,
const struct weston_output *output,
......@@ -506,9 +506,12 @@ weston_compositor_destroy_touch_calibrator(struct weston_compositor *compositor)
enum paint_node_status {
PAINT_NODE_CLEAN = 0,
PAINT_NODE_OUTPUT_DIRTY = 1 << 1,
PAINT_NODE_VIEW_DIRTY = 1 << 2,
PAINT_NODE_ALL_DIRTY = 0xf,
PAINT_NODE_OUTPUT_DIRTY = 1 << 0,
PAINT_NODE_VIEW_DIRTY = 1 << 1,
PAINT_NODE_VISIBILITY_DIRTY = 1 << 2,
PAINT_NODE_PLANE_DIRTY = 1 << 3,
PAINT_NODE_CONTENT_DIRTY = 1 << 4,
PAINT_NODE_ALL_DIRTY = (1 << 5) - 1,
};
/**
......@@ -544,6 +547,11 @@ struct weston_paint_node {
/* struct weston_output::paint_node_z_order_list */
struct wl_list z_order_link;
pixman_region32_t visible;
pixman_region32_t damage; /* In global coordinates */
struct weston_plane *plane;
struct weston_plane *plane_next;
struct weston_surface_color_transform surf_xform;
bool surf_xform_valid;
......
......@@ -514,8 +514,7 @@ draw_paint_node(struct weston_paint_node *pnode,
pixman_region32_init(&repaint);
pixman_region32_intersect(&repaint,
&pnode->view->transform.boundingbox, damage);
pixman_region32_subtract(&repaint, &repaint, &pnode->view->clip);
&pnode->visible, damage);
if (!pixman_region32_not_empty(&repaint))
goto out;
......@@ -546,12 +545,11 @@ out:
static void
repaint_surfaces(struct weston_output *output, pixman_region32_t *damage)
{
struct weston_compositor *compositor = output->compositor;
struct weston_paint_node *pnode;
wl_list_for_each_reverse(pnode, &output->paint_node_z_order_list,
z_order_link) {
if (pnode->view->plane == &compositor->primary_plane)
if (pnode->plane == &output->primary_plane)
draw_paint_node(pnode, damage);
}
}
......
......@@ -1257,9 +1257,7 @@ draw_paint_node(struct weston_paint_node *pnode,
return;
pixman_region32_init(&repaint);
pixman_region32_intersect(&repaint,
&pnode->view->transform.boundingbox, damage);
pixman_region32_subtract(&repaint, &repaint, &pnode->view->clip);
pixman_region32_intersect(&repaint, &pnode->visible, damage);
if (!pixman_region32_not_empty(&repaint))
goto out;
......@@ -1332,7 +1330,6 @@ out:
static void
repaint_views(struct weston_output *output, pixman_region32_t *damage)
{
struct weston_compositor *compositor = output->compositor;
struct weston_paint_node *pnode;
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
......@@ -1340,7 +1337,7 @@ repaint_views(struct weston_output *output, pixman_region32_t *damage)
wl_list_for_each_reverse(pnode, &output->paint_node_z_order_list,
z_order_link) {
if (pnode->view->plane == &compositor->primary_plane)
if (pnode->plane == &output->primary_plane)
draw_paint_node(pnode, damage);
}
......@@ -1367,7 +1364,7 @@ update_buffer_release_fences(struct weston_compositor *compositor,
struct weston_buffer_release *buffer_release;
int fence_fd;
if (view->plane != &compositor->primary_plane)
if (pnode->plane != &output->primary_plane)
continue;
gs = get_surface_state(view->surface);
......@@ -1863,7 +1860,7 @@ gl_renderer_repaint_output(struct weston_output *output,
* which surfaces were used in this output repaint. */
wl_list_for_each_reverse(pnode, &output->paint_node_z_order_list,
z_order_link) {
if (pnode->view->plane == &compositor->primary_plane) {
if (pnode->plane == &output->primary_plane) {
struct gl_surface_state *gs =
get_surface_state(pnode->view->surface);
gs->used_in_output_repaint = false;
......@@ -2077,7 +2074,7 @@ gl_renderer_flush_damage(struct weston_surface *surface,
&surface->compositor->test_data.test_quirks;
struct gl_surface_state *gs = get_surface_state(surface);
struct gl_buffer_state *gb = gs->buffer;
struct weston_view *view;
struct weston_paint_node *pnode;
bool texture_used;
pixman_box32_t *rectangles;
uint8_t *data;
......@@ -2100,8 +2097,8 @@ gl_renderer_flush_damage(struct weston_surface *surface,
* migrates back to the primary plane.
*/
texture_used = false;
wl_list_for_each(view, &surface->views, surface_link) {
if (view->plane == &surface->compositor->primary_plane) {
wl_list_for_each(pnode, &surface->paint_node_list, surface_link) {
if (pnode->plane == &pnode->output->primary_plane) {
texture_used = true;
break;
}
......
......@@ -290,6 +290,7 @@ TEST_P(hdr_metadata_type1_errors, value_cases)
weston_log_set_handler(no_logger, no_logger);
wl_list_init(&mock_compositor.plane_list);
weston_output_init(&mock_output, &mock_compositor, "mockoutput");
assert(t->field_index < ARRAY_LENGTH(fields));
......@@ -326,6 +327,7 @@ TEST(hdr_metadata_type1_ignore_unflagged)
struct weston_output mock_output = {};
bool ret;
wl_list_init(&mock_compositor.plane_list);
weston_log_set_handler(no_logger, no_logger);
weston_output_init(&mock_output, &mock_compositor, "mockoutput");
......