mirror of
https://gitlab.freedesktop.org/wayland/weston.git
synced 2026-05-07 13:08:04 +02:00
compositor: Store the output desination and buffer source rects in pnode
Instead of having the drm backend calculate these per frame, let's store them in the paint node when they change. Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
This commit is contained in:
parent
0024857086
commit
efbbc0fd58
3 changed files with 84 additions and 57 deletions
|
|
@ -224,13 +224,8 @@ drm_plane_state_coords_for_paint_node(struct drm_plane_state *state,
|
|||
struct weston_paint_node *pnode,
|
||||
uint64_t zpos)
|
||||
{
|
||||
struct drm_output *output = state->handle->output;
|
||||
struct weston_view *ev = pnode->view;
|
||||
struct weston_buffer *buffer = ev->surface->buffer_ref.buffer;
|
||||
pixman_region32_t dest_rect;
|
||||
pixman_box32_t *box;
|
||||
struct weston_coord corners[2];
|
||||
float sxf1, syf1, sxf2, syf2;
|
||||
struct weston_surface *surface = pnode->surface;
|
||||
struct weston_buffer *buffer = surface->buffer_ref.buffer;
|
||||
uint16_t min_alpha = state->plane->alpha_min;
|
||||
uint16_t max_alpha = state->plane->alpha_max;
|
||||
|
||||
|
|
@ -243,58 +238,16 @@ drm_plane_state_coords_for_paint_node(struct drm_plane_state *state,
|
|||
assert(pnode->valid_transform);
|
||||
state->rotation = drm_rotation_from_output_transform(state->plane, pnode->transform);
|
||||
|
||||
box = pixman_region32_extents(&ev->transform.boundingbox);
|
||||
|
||||
/* First calculate the destination co-ordinates by taking the
|
||||
* area of the view which is visible on this output, performing any
|
||||
* transforms to account for output rotation and scale as necessary. */
|
||||
pixman_region32_init(&dest_rect);
|
||||
pixman_region32_intersect(&dest_rect, &ev->transform.boundingbox,
|
||||
&output->base.region);
|
||||
weston_region_global_to_output(&dest_rect, &output->base, &dest_rect);
|
||||
|
||||
box = pixman_region32_extents(&dest_rect);
|
||||
|
||||
state->dest_x = box->x1;
|
||||
state->dest_y = box->y1;
|
||||
state->dest_w = box->x2 - box->x1;
|
||||
state->dest_h = box->y2 - box->y1;
|
||||
|
||||
/* Now calculate the source rectangle, by transforming the destination
|
||||
* rectangle by the output to buffer matrix. */
|
||||
corners[0] = weston_matrix_transform_coord(
|
||||
&pnode->output_to_buffer_matrix,
|
||||
weston_coord(box->x1, box->y1));
|
||||
corners[1] = weston_matrix_transform_coord(
|
||||
&pnode->output_to_buffer_matrix,
|
||||
weston_coord(box->x2, box->y2));
|
||||
sxf1 = corners[0].x;
|
||||
syf1 = corners[0].y;
|
||||
sxf2 = corners[1].x;
|
||||
syf2 = corners[1].y;
|
||||
pixman_region32_fini(&dest_rect);
|
||||
|
||||
/* Make sure that our post-transform coordinates are in the
|
||||
* right order.
|
||||
*/
|
||||
if (sxf1 > sxf2) {
|
||||
float temp = sxf1;
|
||||
|
||||
sxf1 = sxf2;
|
||||
sxf2 = temp;
|
||||
}
|
||||
if (syf1 > syf2) {
|
||||
float temp = syf1;
|
||||
|
||||
syf1 = syf2;
|
||||
syf2 = temp;
|
||||
}
|
||||
state->dest_x = pnode->output_dest.x;
|
||||
state->dest_y = pnode->output_dest.y;
|
||||
state->dest_w = pnode->output_dest.width;
|
||||
state->dest_h = pnode->output_dest.height;
|
||||
|
||||
/* Shift from S23.8 wl_fixed to U16.16 KMS fixed-point encoding. */
|
||||
state->src_x = wl_fixed_from_double(sxf1) << 8;
|
||||
state->src_y = wl_fixed_from_double(syf1) << 8;
|
||||
state->src_w = wl_fixed_from_double(sxf2 - sxf1) << 8;
|
||||
state->src_h = wl_fixed_from_double(syf2 - syf1) << 8;
|
||||
state->src_x = wl_fixed_from_double(pnode->buffer_source_x) << 8;
|
||||
state->src_y = wl_fixed_from_double(pnode->buffer_source_y) << 8;
|
||||
state->src_w = wl_fixed_from_double(pnode->buffer_source_width) << 8;
|
||||
state->src_h = wl_fixed_from_double(pnode->buffer_source_height) << 8;
|
||||
|
||||
/* Clamp our source co-ordinates to surface bounds; it's possible
|
||||
* for intermediate translations to give us slightly incorrect
|
||||
|
|
|
|||
|
|
@ -195,6 +195,69 @@ get_placeholder_color(struct weston_paint_node *pnode,
|
|||
color->a = 1.0;
|
||||
}
|
||||
|
||||
/* If we have a valid transform, we can compute an output destination
|
||||
* rectangle and a buffer source rectangle that backends can use for plane
|
||||
* setup.
|
||||
*/
|
||||
static void
|
||||
paint_node_update_rectangles(struct weston_paint_node *pnode)
|
||||
{
|
||||
struct weston_view *view = pnode->view;
|
||||
struct weston_output *output = pnode->output;
|
||||
pixman_region32_t dest_rect;
|
||||
pixman_box32_t *box;
|
||||
struct weston_coord corners[2];
|
||||
float sxf1, syf1, sxf2, syf2;
|
||||
|
||||
box = pixman_region32_extents(&view->transform.boundingbox);
|
||||
|
||||
/* First calculate the destination co-ordinates by taking the
|
||||
* area of the view which is visible on this output, performing any
|
||||
* transforms to account for output rotation and scale as necessary. */
|
||||
pixman_region32_init(&dest_rect);
|
||||
pixman_region32_intersect(&dest_rect, &view->transform.boundingbox,
|
||||
&output->region);
|
||||
weston_region_global_to_output(&dest_rect, output, &dest_rect);
|
||||
|
||||
box = pixman_region32_extents(&dest_rect);
|
||||
pnode->output_dest.x = box->x1;
|
||||
pnode->output_dest.y = box->y1;
|
||||
pnode->output_dest.width = box->x2 - box->x1;
|
||||
pnode->output_dest.height = box->y2 - box->y1;
|
||||
|
||||
/* Now calculate the source rectangle, by transforming the destination
|
||||
* rectangle by the output to buffer matrix. */
|
||||
corners[0] = weston_matrix_transform_coord(&pnode->output_to_buffer_matrix,
|
||||
weston_coord(box->x1, box->y1));
|
||||
corners[1] = weston_matrix_transform_coord(&pnode->output_to_buffer_matrix,
|
||||
weston_coord(box->x2, box->y2));
|
||||
sxf1 = corners[0].x;
|
||||
syf1 = corners[0].y;
|
||||
sxf2 = corners[1].x;
|
||||
syf2 = corners[1].y;
|
||||
pixman_region32_fini(&dest_rect);
|
||||
|
||||
/* Make sure that our post-transform coordinates are in the
|
||||
* right order.
|
||||
*/
|
||||
if (sxf1 > sxf2) {
|
||||
float temp = sxf1;
|
||||
|
||||
sxf1 = sxf2;
|
||||
sxf2 = temp;
|
||||
}
|
||||
if (syf1 > syf2) {
|
||||
float temp = syf1;
|
||||
|
||||
syf1 = syf2;
|
||||
syf2 = temp;
|
||||
}
|
||||
pnode->buffer_source_x = sxf1;
|
||||
pnode->buffer_source_y = syf1;
|
||||
pnode->buffer_source_width = sxf2 - sxf1;
|
||||
pnode->buffer_source_height = syf2 - syf1;
|
||||
}
|
||||
|
||||
/* Paint nodes contain filter and transform information that needs to be
|
||||
* up to date before assign_planes() is called. But there are also
|
||||
* damage related bits that must be updated after assign_planes()
|
||||
|
|
@ -224,6 +287,8 @@ paint_node_update_early(struct weston_paint_node *pnode)
|
|||
|
||||
pnode->valid_transform = weston_matrix_to_transform(mat,
|
||||
&pnode->transform);
|
||||
if (pnode->valid_transform)
|
||||
paint_node_update_rectangles(pnode);
|
||||
}
|
||||
|
||||
buffer = pnode->surface->buffer_ref.buffer;
|
||||
|
|
|
|||
|
|
@ -703,6 +703,15 @@ struct weston_paint_node {
|
|||
|
||||
bool valid_transform;
|
||||
enum wl_output_transform transform;
|
||||
/* The paint node's output destination rectangle, only valid if valid_transform
|
||||
* is true */
|
||||
struct weston_geometry output_dest;
|
||||
/* The paint node's buffer source rectangle, only valid if valid_transform
|
||||
* is true */
|
||||
float buffer_source_x;
|
||||
float buffer_source_y;
|
||||
float buffer_source_width;
|
||||
float buffer_source_height;
|
||||
|
||||
/* struct weston_output::paint_node_z_order_list */
|
||||
struct wl_list z_order_link;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue