149 lines
5.3 KiB
Diff
149 lines
5.3 KiB
Diff
|
From d769f1194c934ed4ff7ce6bfc502ba485d461c12 Mon Sep 17 00:00:00 2001
|
||
|
From: Hans de Goede <hdegoede@redhat.com>
|
||
|
Date: Sat, 20 Jan 2018 12:20:29 +0100
|
||
|
Subject: [PATCH 5/6] drm: Reset primary plane rotation to DRM_MODE_ROTATE_0
|
||
|
|
||
|
On devices where the (LCD) panel is mounted upside-down in the case
|
||
|
the kernel's drm_fb_helper code may have set up rotation on the primary
|
||
|
plane to make the text-console (and other fbdev using apps) show the right
|
||
|
way up.
|
||
|
|
||
|
We inherit this rotation from the text-mode and since we do our own rotation
|
||
|
where necessary we end up rotating twice and showing the boot-splash
|
||
|
upside-down again.
|
||
|
|
||
|
Dealing with hardware rotation may require using a specific framebuffer
|
||
|
tiling which we do not support, so we should just disable the hardware
|
||
|
rotation and keep using our own software rotation.
|
||
|
|
||
|
This commit adds code to find the primary plane and its rotation property
|
||
|
and if it is not DRM_MODE_ROTATE_0 then sets it to DRM_MODE_ROTATE_0. fixing
|
||
|
the double rotation issue.
|
||
|
|
||
|
https://bugs.freedesktop.org/show_bug.cgi?id=104714
|
||
|
---
|
||
|
src/plugins/renderers/drm/plugin.c | 86 ++++++++++++++++++++++++++++++
|
||
|
1 file changed, 86 insertions(+)
|
||
|
|
||
|
diff --git a/src/plugins/renderers/drm/plugin.c b/src/plugins/renderers/drm/plugin.c
|
||
|
index f495854..fb79aa6 100644
|
||
|
--- a/src/plugins/renderers/drm/plugin.c
|
||
|
+++ b/src/plugins/renderers/drm/plugin.c
|
||
|
@@ -43,6 +43,7 @@
|
||
|
#include <unistd.h>
|
||
|
|
||
|
#include <drm.h>
|
||
|
+#include <drm_mode.h>
|
||
|
#include <xf86drm.h>
|
||
|
#include <xf86drmMode.h>
|
||
|
|
||
|
@@ -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;
|
||
|
}
|
||
|
|
||
|
--
|
||
|
2.17.0
|
||
|
|