]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
drm: Keep hw-rotation on devices with upside down LCD panels
authorHans de Goede <hdegoede@redhat.com>
Sun, 13 Oct 2019 21:46:31 +0000 (23:46 +0200)
committerHans de Goede <hdegoede@redhat.com>
Sun, 13 Oct 2019 22:09:25 +0000 (00:09 +0200)
On devices with an upside down LCD panel and where the hw is capable of
rotating the image to correct this the firmware will program the primary
plane to use hw rotation. When we reset this, this may lead to a small
flicker, where the vendor logo is briefly shown upside down.

A bigger problem is the transition to gdm/mutter. We leave the splash
on screen when mutter loads for a smooth transition,  when mutter turns
hw-rotation back on, the splash turns upside down! And mutter then fades
from the upside-down splash to the login screen, which looks kinda bad.

Keeping the hw-rotation (and disabling our sw rotation) on devices like
this fixes both issues.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
src/plugins/renderers/drm/plugin.c

index c80cc13b9c99b86f16f061d1917daec042b63f7c..32ed4d114e3ae0b32c31042cd980778fd74fa334 100644 (file)
@@ -83,7 +83,8 @@ struct _ply_renderer_head
         uint32_t                controller_id;
         uint32_t                console_buffer_id;
         uint32_t                scan_out_buffer_id;
-        bool                   scan_out_buffer_needs_reset;
+        bool                    scan_out_buffer_needs_reset;
+        bool                    uses_hw_rotation;
 
         int                     gamma_size;
         uint16_t                *gamma;
@@ -128,6 +129,7 @@ typedef struct
         ply_pixel_buffer_rotation_t rotation;
         bool tiled;
         bool connected;
+        bool uses_hw_rotation;
 } ply_output_t;
 
 struct _ply_renderer_backend
@@ -526,8 +528,9 @@ ply_renderer_connector_get_rotation_and_tiled (ply_renderer_backend_t      *back
                                                drmModeConnector            *connector,
                                                ply_output_t                *output)
 {
+        int i, primary_id, rotation_prop_id;
         drmModePropertyPtr prop;
-        int i;
+        uint64_t rotation;
 
         output->rotation = PLY_PIXEL_BUFFER_ROTATE_UPRIGHT;
         output->tiled = false;
@@ -554,6 +557,21 @@ ply_renderer_connector_get_rotation_and_tiled (ply_renderer_backend_t      *back
 
                 drmModeFreeProperty (prop);
         }
+
+        /* If the firmware setup the plane to use hw 180° rotation, then we keep
+         * the hw rotation. This avoids a flicker and avoids the splash turning
+         * upside-down when mutter turns hw-rotation back on and then fades from
+         * the splash to the login screen.
+         */
+        if (output->rotation == PLY_PIXEL_BUFFER_ROTATE_UPSIDE_DOWN &&
+            get_primary_plane_rotation (backend, output->controller_id,
+                                        &primary_id, &rotation_prop_id,
+                                        &rotation) &&
+            rotation == DRM_MODE_ROTATE_180) {
+                ply_trace("Keeping hw 180° rotation");
+                output->rotation = PLY_PIXEL_BUFFER_ROTATE_UPRIGHT;
+                output->uses_hw_rotation = true;
+        }
 }
 
 static bool
@@ -598,6 +616,7 @@ ply_renderer_head_new (ply_renderer_backend_t     *backend,
         head->controller_id = output->controller_id;
         head->console_buffer_id = console_buffer_id;
         head->connector0_mode = output->mode;
+        head->uses_hw_rotation = output->uses_hw_rotation;
 
         head->area.x = 0;
         head->area.y = 0;
@@ -660,6 +679,9 @@ ply_renderer_head_clear_plane_rotation (ply_renderer_backend_t *backend,
         int primary_id, rotation_prop_id, err;
         uint64_t rotation;
 
+        if (head->uses_hw_rotation)
+                return;
+
         if (get_primary_plane_rotation (backend, head->controller_id,
                                         &primary_id, &rotation_prop_id,
                                         &rotation) &&
@@ -1412,8 +1434,11 @@ create_heads_for_active_connectors (ply_renderer_backend_t *backend, bool change
          */
         if (!change && number_of_setup_outputs != backend->connected_count) {
                 ply_trace ("Some outputs still don't have controllers, re-assigning controllers for all outputs");
-                for (i = 0; i < outputs_len; i++)
+                for (i = 0; i < outputs_len; i++) {
+                        if (outputs[i].uses_hw_rotation)
+                                continue; /* Do not re-assign hw-rotated outputs */
                         outputs[i].controller_id = 0;
+                }
                 outputs = setup_outputs (backend, outputs, outputs_len);
         }
         for (i = 0; i < outputs_len; i++)