backend-drm: Set rotation property on planes when possible

For now we just always set the plane up to have a "normal" rotation, so
no new features are added with this commit.

Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
This commit is contained in:
Derek Foreman 2023-01-19 16:16:40 -06:00
parent f89f440735
commit b0f23dc09d
3 changed files with 80 additions and 0 deletions

View File

@ -469,6 +469,8 @@ struct drm_plane_state {
int32_t dest_x, dest_y;
uint32_t dest_w, dest_h;
uint32_t rotation;
uint64_t zpos;
bool complete;
@ -688,6 +690,10 @@ drm_crtc_find(struct drm_device *device, uint32_t crtc_id);
struct drm_head *
drm_head_find_by_connector(struct drm_backend *backend, uint32_t connector_id);
uint64_t
drm_rotation_from_output_transform(struct drm_plane *plane,
enum wl_output_transform ot);
static inline bool
drm_paint_node_transform_supported(struct weston_paint_node *node, struct weston_output *output)
{

View File

@ -300,6 +300,73 @@ drm_property_get_range_values(struct drm_property_info *info,
return NULL;
}
/* We use the fact that 0 is not a valid rotation here - if we return 0,
* the plane doesn't support the rotation requested. Otherwise the correct
* value to achieve the requested rotation on this plane is returned.
*/
uint64_t
drm_rotation_from_output_transform(struct drm_plane *plane,
enum wl_output_transform ot)
{
struct drm_property_info *info = &plane->props[WDRM_PLANE_ROTATION];
enum wdrm_plane_rotation drm_rotation;
enum wdrm_plane_rotation drm_reflection = 0;
uint64_t out = 0;
if (info->prop_id == 0) {
if (ot == WL_OUTPUT_TRANSFORM_NORMAL)
return 1;
return 0;
}
switch (ot) {
case WL_OUTPUT_TRANSFORM_NORMAL:
drm_rotation = WDRM_PLANE_ROTATION_0;
break;
case WL_OUTPUT_TRANSFORM_90:
drm_rotation = WDRM_PLANE_ROTATION_90;
break;
case WL_OUTPUT_TRANSFORM_180:
drm_rotation = WDRM_PLANE_ROTATION_180;
break;
case WL_OUTPUT_TRANSFORM_270:
drm_rotation = WDRM_PLANE_ROTATION_270;
break;
case WL_OUTPUT_TRANSFORM_FLIPPED:
drm_rotation = WDRM_PLANE_ROTATION_0;
drm_reflection = WDRM_PLANE_ROTATION_REFLECT_X;
break;
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
drm_rotation = WDRM_PLANE_ROTATION_90;
drm_reflection = WDRM_PLANE_ROTATION_REFLECT_X;
break;
case WL_OUTPUT_TRANSFORM_FLIPPED_180:
drm_rotation = WDRM_PLANE_ROTATION_180;
drm_reflection = WDRM_PLANE_ROTATION_REFLECT_X;
break;
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
drm_rotation = WDRM_PLANE_ROTATION_270;
drm_reflection = WDRM_PLANE_ROTATION_REFLECT_X;
break;
default:
assert(0 && "bad output transform");
}
if (!info->enum_values[drm_rotation].valid)
return 0;
out |= 1 << info->enum_values[drm_rotation].value;
if (drm_reflection) {
if (!info->enum_values[drm_reflection].valid)
return 0;
out |= 1 << info->enum_values[drm_reflection].value;
}
return out;
}
/**
* Cache DRM property values
*
@ -1201,6 +1268,10 @@ drm_output_apply_state_atomic(struct drm_output_state *state,
plane_state->in_fence_fd);
}
if (plane->props[WDRM_PLANE_ROTATION].prop_id != 0)
ret |= plane_add_prop(req, plane, WDRM_PLANE_ROTATION,
plane_state->rotation);
/* do note, that 'invented' zpos values are set as immutable */
if (plane_state->zpos != DRM_PLANE_ZPOS_INVALID_PLANE &&
plane_state->plane->zpos_min != plane_state->plane->zpos_max)

View File

@ -48,6 +48,9 @@ drm_plane_state_alloc(struct drm_output_state *state_output,
state->output_state = state_output;
state->plane = plane;
state->in_fence_fd = -1;
state->rotation = drm_rotation_from_output_transform(plane,
WL_OUTPUT_TRANSFORM_NORMAL);
assert(state->rotation);
state->zpos = DRM_PLANE_ZPOS_INVALID_PLANE;
/* Here we only add the plane state to the desired link, and not