diff --git a/src/plugins/renderers/drm/plugin.c b/src/plugins/renderers/drm/plugin.c index f4958545..fb79aa6d 100644 --- a/src/plugins/renderers/drm/plugin.c +++ b/src/plugins/renderers/drm/plugin.c @@ -43,6 +43,7 @@ #include #include +#include #include #include @@ -62,6 +63,11 @@ #define BYTES_PER_PIXEL (4) +/* For builds with libdrm < 2.4.89 */ +#ifndef DRM_MODE_ROTATE_0 +#define DRM_MODE_ROTATE_0 (1<<0) +#endif + struct _ply_renderer_head { ply_renderer_backend_t *backend; @@ -499,6 +505,85 @@ ply_renderer_head_free (ply_renderer_head_t *head) free (head); } +static void +ply_renderer_head_clear_plane_rotation (ply_renderer_backend_t *backend, + ply_renderer_head_t *head) +{ + drmModeObjectPropertiesPtr plane_props; + drmModePlaneResPtr plane_resources; + drmModePropertyPtr prop; + drmModePlanePtr plane; + uint64_t rotation; + uint32_t i, j; + int rotation_prop_id = -1; + int primary_id = -1; + int err; + + err = drmSetClientCap (backend->device_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); + if (err) + return; + + plane_resources = drmModeGetPlaneResources (backend->device_fd); + if (!plane_resources) + return; + + for (i = 0; i < plane_resources->count_planes; i++) { + plane = drmModeGetPlane (backend->device_fd, + plane_resources->planes[i]); + if (!plane) + continue; + + if (plane->crtc_id != head->controller_id) { + drmModeFreePlane (plane); + continue; + } + + plane_props = drmModeObjectGetProperties (backend->device_fd, + plane->plane_id, + DRM_MODE_OBJECT_PLANE); + + for (j = 0; plane_props && (j < plane_props->count_props); j++) { + prop = drmModeGetProperty (backend->device_fd, + plane_props->props[j]); + if (!prop) + continue; + + if (strcmp (prop->name, "type") == 0 && + plane_props->prop_values[j] == DRM_PLANE_TYPE_PRIMARY) { + primary_id = plane->plane_id; + } + + if (strcmp (prop->name, "rotation") == 0) { + rotation_prop_id = plane_props->props[j]; + rotation = plane_props->prop_values[j]; + } + + drmModeFreeProperty (prop); + } + + drmModeFreeObjectProperties (plane_props); + drmModeFreePlane (plane); + + if (primary_id != -1) + break; + + /* Not primary -> clear any found rotation property */ + rotation_prop_id = -1; + } + + if (primary_id != -1 && rotation_prop_id != -1 && rotation != DRM_MODE_ROTATE_0) { + err = drmModeObjectSetProperty (backend->device_fd, + primary_id, + DRM_MODE_OBJECT_PLANE, + rotation_prop_id, + DRM_MODE_ROTATE_0); + ply_trace ("Cleared rotation on primary plane %d result %d", + primary_id, err); + } + + drmModeFreePlaneResources (plane_resources); +} + static bool ply_renderer_head_set_scan_out_buffer (ply_renderer_backend_t *backend, ply_renderer_head_t *head, @@ -525,6 +610,7 @@ ply_renderer_head_set_scan_out_buffer (ply_renderer_backend_t *backend, return false; } + ply_renderer_head_clear_plane_rotation (backend, head); return true; }