-
Notifications
You must be signed in to change notification settings - Fork 0
/
0005-drm-Reset-primary-plane-rotation-to-DRM_MODE_ROTATE_.patch
148 lines (134 loc) · 5.29 KB
/
0005-drm-Reset-primary-plane-rotation-to-DRM_MODE_ROTATE_.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
From d769f1194c934ed4ff7ce6bfc502ba485d461c12 Mon Sep 17 00:00:00 2001
From: Hans de Goede <[email protected]>
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