From d2a00cafedc711ec4c0d0cc17799ca3377214d01 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 17 Apr 2018 14:57:44 +0200 Subject: [PATCH] Add patches from upstream git for devices with non upright mounted LCD panels https://bugs.freedesktop.org/show_bug.cgi?id=104714 --- ...rop-superfluous-create_pixel_display.patch | 32 +++ ...te-the-display-on-backspace-when-the.patch | 45 ++++ ...r-Add-the-concept-of-device-rotation.patch | 249 ++++++++++++++++++ ...panel-orientation-connector-property.patch | 102 +++++++ ...y-plane-rotation-to-DRM_MODE_ROTATE_.patch | 148 +++++++++++ ...er-switch-device-rotation-to-an-enum.patch | 80 ++++++ plymouth.spec | 18 +- 7 files changed, 672 insertions(+), 2 deletions(-) create mode 100644 0001-device-manager-drop-superfluous-create_pixel_display.patch create mode 100644 0002-main-Do-not-update-the-display-on-backspace-when-the.patch create mode 100644 0003-pixel-buffer-Add-the-concept-of-device-rotation.patch create mode 100644 0004-drm-Check-for-panel-orientation-connector-property.patch create mode 100644 0005-drm-Reset-primary-plane-rotation-to-DRM_MODE_ROTATE_.patch create mode 100644 0006-pixel-buffer-switch-device-rotation-to-an-enum.patch diff --git a/0001-device-manager-drop-superfluous-create_pixel_display.patch b/0001-device-manager-drop-superfluous-create_pixel_display.patch new file mode 100644 index 0000000..92ec6ce --- /dev/null +++ b/0001-device-manager-drop-superfluous-create_pixel_display.patch @@ -0,0 +1,32 @@ +From 6e9e95dc0fe89a3c52f50e44ff0096a6e65e46a6 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Wed, 20 Dec 2017 10:49:19 -0500 +Subject: [PATCH 1/6] device-manager: drop superfluous + create_pixel_displays_for_renderer call + +commit 29e27637694eefc962d53333c729e6cac1c66518 tried to move +create_pixel_displays_for_renderer down a couple of lines, but it +inadvertently copied it instead of moved it. + +This commit fixes that. + +https://bugs.freedesktop.org/show_bug.cgi?id=104353 +--- + src/libply-splash-core/ply-device-manager.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c +index cf56f4e..fbf4723 100644 +--- a/src/libply-splash-core/ply-device-manager.c ++++ b/src/libply-splash-core/ply-device-manager.c +@@ -713,7 +713,6 @@ create_devices_for_terminal_and_renderer_type (ply_device_manager_t *manager, + if (manager->keyboard_added_handler != NULL) + manager->keyboard_added_handler (manager->event_handler_data, keyboard); + +- create_pixel_displays_for_renderer (manager, renderer); + ply_hashtable_insert (manager->renderers, strdup (ply_renderer_get_device_name (renderer)), renderer); + create_pixel_displays_for_renderer (manager, renderer); + +-- +2.17.0 + diff --git a/0002-main-Do-not-update-the-display-on-backspace-when-the.patch b/0002-main-Do-not-update-the-display-on-backspace-when-the.patch new file mode 100644 index 0000000..d92621a --- /dev/null +++ b/0002-main-Do-not-update-the-display-on-backspace-when-the.patch @@ -0,0 +1,45 @@ +From da27e42316962be6f6b8ba2afb49760d9704d070 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Sun, 21 Jan 2018 14:07:39 +0100 +Subject: [PATCH 2/6] main: Do not update the display on backspace when there + is no input to remove + +On machines with a slow CPU (Atom) and a highres screen drawing the +diskcrypt dialog may take longer then the keyrepeat speed, this leads to +a long delay before showing keypresses when doing the following: + +1) Type long password +2) Realize it is wrong, press + hold backspace + the key-repeat will now generate backspace key presses faster then we + process them as main.c does an update_display for each press +3) Users releases backspace when we've processed input-length backspace + key-presses, but since we were drawing slower then key-presses were + coming in many more backspace keypresses are in the keyboard buffer +4) User types first character of the right password, this shows up up to + a couple of seconds later because first we are still processing all + the queued up backspace presses and doing a redraw for each. + +This commit fixes this by skipping the redraws in on_backspace when there +is no more input left in the input buffer. + +https://bugs.freedesktop.org/show_bug.cgi?id=104714 +--- + src/main.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/main.c b/src/main.c +index 08c7fe1..f1e0fa7 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -1570,6 +1570,8 @@ on_backspace (state_t *state) + + bytes = ply_buffer_get_bytes (state->entry_buffer); + size = ply_buffer_get_size (state->entry_buffer); ++ if (size == 0) ++ return; + + bytes_to_remove = MIN (size, PLY_UTF8_CHARACTER_SIZE_MAX); + while ((previous_character_size = ply_utf8_character_get_size (bytes + size - bytes_to_remove, bytes_to_remove)) < bytes_to_remove) { +-- +2.17.0 + diff --git a/0003-pixel-buffer-Add-the-concept-of-device-rotation.patch b/0003-pixel-buffer-Add-the-concept-of-device-rotation.patch new file mode 100644 index 0000000..0317509 --- /dev/null +++ b/0003-pixel-buffer-Add-the-concept-of-device-rotation.patch @@ -0,0 +1,249 @@ +From 0e4e268844ea38075535eb5b233dda325da4481d Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Wed, 6 Dec 2017 17:37:12 +0100 +Subject: [PATCH 3/6] pixel-buffer: Add the concept of device rotation + +On some devices the LCD panel is mounted in the casing in such a way +that the up/top side of the panel does not match with the top side of +the device (e.g. it is mounted upside-down). + +This commit adds support to the ply-pixel-buffer code to create +buffers which take device rotation into account and which will rotate +the picture to compensate. + +https://bugs.freedesktop.org/show_bug.cgi?id=104714 +--- + src/libply-splash-core/ply-pixel-buffer.c | 109 ++++++++++++++++++++-- + src/libply-splash-core/ply-pixel-buffer.h | 9 ++ + 2 files changed, 110 insertions(+), 8 deletions(-) + +diff --git a/src/libply-splash-core/ply-pixel-buffer.c b/src/libply-splash-core/ply-pixel-buffer.c +index 52a3f86..a337407 100644 +--- a/src/libply-splash-core/ply-pixel-buffer.c ++++ b/src/libply-splash-core/ply-pixel-buffer.c +@@ -50,6 +50,7 @@ struct _ply_pixel_buffer + ply_region_t *updated_areas; /* in device pixels */ + uint32_t is_opaque : 1; + int device_scale; ++ int device_rotation; + }; + + static inline void ply_pixel_buffer_blend_value_at_pixel (ply_pixel_buffer_t *buffer, +@@ -153,6 +154,52 @@ make_pixel_value_translucent (uint32_t pixel_value, + return (alpha << 24) | (red << 16) | (green << 8) | blue; + } + ++static inline void ply_pixel_buffer_set_pixel (ply_pixel_buffer_t *buffer, ++ int x, ++ int y, ++ uint32_t pixel_value) ++{ ++ switch (buffer->device_rotation) { ++ case PLY_PIXEL_BUFFER_ROTATE_UPRIGHT: ++ buffer->bytes[y * buffer->area.width + x] = pixel_value; ++ break; ++ case PLY_PIXEL_BUFFER_ROTATE_UPSIDE_DOWN: ++ x = (buffer->area.width - 1) - x; ++ y = (buffer->area.height - 1) - y; ++ buffer->bytes[y * buffer->area.width + x] = pixel_value; ++ break; ++ case PLY_PIXEL_BUFFER_ROTATE_CLOCKWISE: ++ y = (buffer->area.height - 1) - y; ++ buffer->bytes[x * buffer->area.height + y] = pixel_value; ++ break; ++ case PLY_PIXEL_BUFFER_ROTATE_COUNTER_CLOCKWISE: ++ x = (buffer->area.width - 1) - x; ++ buffer->bytes[x * buffer->area.height + y] = pixel_value; ++ break; ++ } ++} ++ ++static inline uint32_t ply_pixel_buffer_get_pixel (ply_pixel_buffer_t *buffer, ++ int x, ++ int y) ++{ ++ switch (buffer->device_rotation) { ++ case PLY_PIXEL_BUFFER_ROTATE_UPRIGHT: ++ return buffer->bytes[y * buffer->area.width + x]; ++ case PLY_PIXEL_BUFFER_ROTATE_UPSIDE_DOWN: ++ x = (buffer->area.width - 1) - x; ++ y = (buffer->area.height - 1) - y; ++ return buffer->bytes[y * buffer->area.width + x]; ++ case PLY_PIXEL_BUFFER_ROTATE_CLOCKWISE: ++ y = (buffer->area.height - 1) - y; ++ return buffer->bytes[x * buffer->area.height + y]; ++ case PLY_PIXEL_BUFFER_ROTATE_COUNTER_CLOCKWISE: ++ x = (buffer->area.width - 1) - x; ++ return buffer->bytes[x * buffer->area.height + y]; ++ } ++ return 0; ++} ++ + static inline void + ply_pixel_buffer_blend_value_at_pixel (ply_pixel_buffer_t *buffer, + int x, +@@ -162,12 +209,12 @@ ply_pixel_buffer_blend_value_at_pixel (ply_pixel_buffer_t *buffer, + uint32_t old_pixel_value; + + if ((pixel_value >> 24) != 0xff) { +- old_pixel_value = buffer->bytes[y * buffer->area.width + x]; ++ old_pixel_value = ply_pixel_buffer_get_pixel (buffer, x, y); + + pixel_value = blend_two_pixel_values (pixel_value, old_pixel_value); + } + +- buffer->bytes[y * buffer->area.width + x] = pixel_value; ++ ply_pixel_buffer_set_pixel (buffer, x, y, pixel_value); + } + + static void +@@ -222,6 +269,35 @@ ply_pixel_buffer_crop_area_to_clip_area (ply_pixel_buffer_t *buffer, + } + } + ++static void ply_pixel_buffer_add_updated_area (ply_pixel_buffer_t *buffer, ++ ply_rectangle_t *area) ++{ ++ ply_rectangle_t updated_area = *area; ++ ++ switch (buffer->device_rotation) { ++ case PLY_PIXEL_BUFFER_ROTATE_UPRIGHT: ++ break; ++ case PLY_PIXEL_BUFFER_ROTATE_UPSIDE_DOWN: ++ updated_area.x = buffer->area.width - area->width - area->x; ++ updated_area.y = buffer->area.height - area->height - area->y; ++ break; ++ case PLY_PIXEL_BUFFER_ROTATE_CLOCKWISE: ++ updated_area.x = buffer->area.height - area->height - area->y; ++ updated_area.y = area->x; ++ updated_area.height = area->width; ++ updated_area.width = area->height; ++ break; ++ case PLY_PIXEL_BUFFER_ROTATE_COUNTER_CLOCKWISE: ++ updated_area.x = area->y; ++ updated_area.y = buffer->area.width - area->width - area->x; ++ updated_area.height = area->width; ++ updated_area.width = area->height; ++ break; ++ } ++ ++ ply_region_add_rectangle (buffer->updated_areas, &updated_area); ++} ++ + static void + ply_pixel_buffer_fill_area_with_pixel_value (ply_pixel_buffer_t *buffer, + ply_rectangle_t *fill_area, +@@ -251,7 +327,7 @@ ply_pixel_buffer_fill_area_with_pixel_value (ply_pixel_buffer_t *buffer, + } + } + +- ply_region_add_rectangle (buffer->updated_areas, &cropped_area); ++ ply_pixel_buffer_add_updated_area (buffer, &cropped_area); + } + + void +@@ -281,9 +357,24 @@ ply_pixel_buffer_pop_clip_area (ply_pixel_buffer_t *buffer) + ply_pixel_buffer_t * + ply_pixel_buffer_new (unsigned long width, + unsigned long height) ++{ ++ return ply_pixel_buffer_new_with_device_rotation ( ++ width, height, PLY_PIXEL_BUFFER_ROTATE_UPRIGHT); ++} ++ ++ply_pixel_buffer_t * ++ply_pixel_buffer_new_with_device_rotation (unsigned long width, ++ unsigned long height, ++ int device_rotation) + { + ply_pixel_buffer_t *buffer; + ++ if (device_rotation >= PLY_PIXEL_BUFFER_ROTATE_CLOCKWISE) { ++ unsigned long tmp = width; ++ width = height; ++ height = tmp; ++ } ++ + buffer = calloc (1, sizeof(ply_pixel_buffer_t)); + + buffer->updated_areas = ply_region_new (); +@@ -292,6 +383,7 @@ ply_pixel_buffer_new (unsigned long width, + buffer->area.height = height; + buffer->logical_area = buffer->area; + buffer->device_scale = 1; ++ buffer->device_rotation = device_rotation; + + buffer->clip_areas = ply_list_new (); + ply_pixel_buffer_push_clip_area (buffer, &buffer->area); +@@ -447,7 +539,7 @@ ply_pixel_buffer_fill_with_gradient (ply_pixel_buffer_t *buffer, + + for (y = buffer->area.y; y < buffer->area.y + buffer->area.height; y++) { + if (cropped_area.y <= y && y < cropped_area.y + cropped_area.height) { +- if (cropped_area.width < UNROLLED_PIXEL_COUNT) { ++ if (cropped_area.width < UNROLLED_PIXEL_COUNT || buffer->device_rotation) { + for (x = cropped_area.x; x < cropped_area.x + cropped_area.width; x++) { + pixel = 0xff000000; + RANDOMIZE (noise); +@@ -457,7 +549,7 @@ ply_pixel_buffer_fill_with_gradient (ply_pixel_buffer_t *buffer, + RANDOMIZE (noise); + pixel |= (((blue + noise) & COLOR_MASK) >> BLUE_SHIFT); + +- buffer->bytes[y * buffer->area.width + x] = pixel; ++ ply_pixel_buffer_set_pixel (buffer, x, y, pixel); + } + } else { + uint32_t shaded_set[UNROLLED_PIXEL_COUNT]; +@@ -485,7 +577,7 @@ ply_pixel_buffer_fill_with_gradient (ply_pixel_buffer_t *buffer, + blue += blue_step; + } + +- ply_region_add_rectangle (buffer->updated_areas, &cropped_area); ++ ply_pixel_buffer_add_updated_area (buffer, &cropped_area); + } + + void +@@ -671,7 +763,7 @@ ply_pixel_buffer_fill_with_argb32_data_at_opacity_with_clip_and_scale (ply_pixel + } + } + +- ply_region_add_rectangle (buffer->updated_areas, &cropped_area); ++ ply_pixel_buffer_add_updated_area (buffer, &cropped_area); + } + + void +@@ -756,7 +848,8 @@ ply_pixel_buffer_fill_with_buffer_at_opacity_with_clip (ply_pixel_buffer_t *canv + + /* Fast path to memcpy if we need no blending or scaling */ + if (opacity == 1.0 && ply_pixel_buffer_is_opaque (source) && +- canvas->device_scale == source->device_scale) { ++ canvas->device_scale == source->device_scale && ++ canvas->device_rotation == PLY_PIXEL_BUFFER_ROTATE_UPRIGHT) { + ply_rectangle_t cropped_area; + + cropped_area.x = x_offset; +diff --git a/src/libply-splash-core/ply-pixel-buffer.h b/src/libply-splash-core/ply-pixel-buffer.h +index 595e9bd..7736dd3 100644 +--- a/src/libply-splash-core/ply-pixel-buffer.h ++++ b/src/libply-splash-core/ply-pixel-buffer.h +@@ -37,9 +37,18 @@ typedef struct _ply_pixel_buffer ply_pixel_buffer_t; + | ((uint8_t) (CLAMP (g * 255.0, 0.0, 255.0)) << 8) \ + | ((uint8_t) (CLAMP (b * 255.0, 0.0, 255.0)))) + ++#define PLY_PIXEL_BUFFER_ROTATE_UPRIGHT 0 ++#define PLY_PIXEL_BUFFER_ROTATE_UPSIDE_DOWN 1 ++#define PLY_PIXEL_BUFFER_ROTATE_CLOCKWISE 2 ++#define PLY_PIXEL_BUFFER_ROTATE_COUNTER_CLOCKWISE 3 ++ + #ifndef PLY_HIDE_FUNCTION_DECLARATIONS + ply_pixel_buffer_t *ply_pixel_buffer_new (unsigned long width, + unsigned long height); ++ply_pixel_buffer_t * ++ply_pixel_buffer_new_with_device_rotation (unsigned long width, ++ unsigned long height, ++ int device_rotation); + void ply_pixel_buffer_free (ply_pixel_buffer_t *buffer); + void ply_pixel_buffer_get_size (ply_pixel_buffer_t *buffer, + ply_rectangle_t *size); +-- +2.17.0 + diff --git a/0004-drm-Check-for-panel-orientation-connector-property.patch b/0004-drm-Check-for-panel-orientation-connector-property.patch new file mode 100644 index 0000000..f953c8b --- /dev/null +++ b/0004-drm-Check-for-panel-orientation-connector-property.patch @@ -0,0 +1,102 @@ +From a6f25b727698a2382e332ab566ed39ee30f8efdc Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 12 Dec 2017 19:47:26 +0100 +Subject: [PATCH 4/6] drm: Check for "panel orientation" connector property + +On some devices the LCD panel is mounted in the casing in such a way +that the up/top side of the panel does not match with the top side of +the device (e.g. it is mounted upside-down). + +Kernel 4.16 introduces a new "panel-orientation" property on the drm +connector which allows modesetting applications / code to check for +such LCD panels. + +This commit adds support for this new property and passes this to the +pixel_buffer code using the new ply_pixel_buffer_new_with_device_rotation +method, so that the pixel_buffer code will automatically rotate the +image to correct for the panel orientation. + +https://bugs.freedesktop.org/show_bug.cgi?id=104714 +--- + src/plugins/renderers/drm/plugin.c | 51 +++++++++++++++++++++++++++++- + 1 file changed, 50 insertions(+), 1 deletion(-) + +diff --git a/src/plugins/renderers/drm/plugin.c b/src/plugins/renderers/drm/plugin.c +index b93e8e4..f495854 100644 +--- a/src/plugins/renderers/drm/plugin.c ++++ b/src/plugins/renderers/drm/plugin.c +@@ -367,6 +367,53 @@ destroy_output_buffer (ply_renderer_backend_t *backend, + ply_renderer_buffer_free (backend, buffer); + } + ++static int ++connector_orientation_prop_to_rotation (drmModePropertyPtr prop, ++ int orientation) ++{ ++ const char *name = prop->enums[orientation].name; ++ ++ if (strcmp (name, "Upside Down") == 0) ++ return PLY_PIXEL_BUFFER_ROTATE_UPSIDE_DOWN; ++ ++ if (strcmp (name, "Left Side Up") == 0) { ++ /* Left side up, rotate counter clockwise to correct */ ++ return PLY_PIXEL_BUFFER_ROTATE_COUNTER_CLOCKWISE; ++ } ++ ++ if (strcmp (name, "Right Side Up") == 0) { ++ /* Left side up, rotate clockwise to correct */ ++ return PLY_PIXEL_BUFFER_ROTATE_CLOCKWISE; ++ } ++ ++ return PLY_PIXEL_BUFFER_ROTATE_UPRIGHT; ++} ++ ++static int ++ply_renderer_connector_get_rotation (ply_renderer_backend_t *backend, ++ drmModeConnector *connector) ++{ ++ drmModePropertyPtr prop; ++ int i, rotation; ++ ++ for (i = 0; i < connector->count_props; i++) { ++ prop = drmModeGetProperty (backend->device_fd, connector->props[i]); ++ if (!prop) ++ continue; ++ ++ if ((prop->flags & DRM_MODE_PROP_ENUM) && ++ strcmp (prop->name, "panel orientation") == 0) { ++ rotation = connector_orientation_prop_to_rotation (prop, connector->prop_values[i]); ++ drmModeFreeProperty (prop); ++ return rotation; ++ } ++ ++ drmModeFreeProperty (prop); ++ } ++ ++ return PLY_PIXEL_BUFFER_ROTATE_UPRIGHT; ++} ++ + static bool + ply_renderer_head_add_connector (ply_renderer_head_t *head, + drmModeConnector *connector, +@@ -402,6 +449,7 @@ ply_renderer_head_new (ply_renderer_backend_t *backend, + { + ply_renderer_head_t *head; + drmModeModeInfo *mode; ++ int rotation; + + head = calloc (1, sizeof(ply_renderer_head_t)); + +@@ -425,7 +473,8 @@ ply_renderer_head_new (ply_renderer_backend_t *backend, + ply_renderer_head_add_connector (head, connector, connector_mode_index); + assert (ply_array_get_size (head->connector_ids) > 0); + +- head->pixel_buffer = ply_pixel_buffer_new (head->area.width, head->area.height); ++ rotation = ply_renderer_connector_get_rotation (backend, connector); ++ head->pixel_buffer = ply_pixel_buffer_new_with_device_rotation (head->area.width, head->area.height, rotation); + ply_pixel_buffer_set_device_scale (head->pixel_buffer, + ply_get_device_scale (head->area.width, + head->area.height, +-- +2.17.0 + diff --git a/0005-drm-Reset-primary-plane-rotation-to-DRM_MODE_ROTATE_.patch b/0005-drm-Reset-primary-plane-rotation-to-DRM_MODE_ROTATE_.patch new file mode 100644 index 0000000..0602bad --- /dev/null +++ b/0005-drm-Reset-primary-plane-rotation-to-DRM_MODE_ROTATE_.patch @@ -0,0 +1,148 @@ +From d769f1194c934ed4ff7ce6bfc502ba485d461c12 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +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 + + #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; + } + +-- +2.17.0 + diff --git a/0006-pixel-buffer-switch-device-rotation-to-an-enum.patch b/0006-pixel-buffer-switch-device-rotation-to-an-enum.patch new file mode 100644 index 0000000..bd94acc --- /dev/null +++ b/0006-pixel-buffer-switch-device-rotation-to-an-enum.patch @@ -0,0 +1,80 @@ +From 555257c74f75bbb1086155fca52c29d71399b305 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Tue, 10 Apr 2018 16:40:06 -0400 +Subject: [PATCH 6/6] pixel-buffer: switch device rotation to an enum + +Right now device rotation is stored in a bare integer. + +For clarity, switch that to an enum. +--- + src/libply-splash-core/ply-pixel-buffer.c | 12 +++++++----- + src/libply-splash-core/ply-pixel-buffer.h | 13 ++++++++----- + 2 files changed, 15 insertions(+), 10 deletions(-) + +diff --git a/src/libply-splash-core/ply-pixel-buffer.c b/src/libply-splash-core/ply-pixel-buffer.c +index a337407..de3b107 100644 +--- a/src/libply-splash-core/ply-pixel-buffer.c ++++ b/src/libply-splash-core/ply-pixel-buffer.c +@@ -50,7 +50,8 @@ struct _ply_pixel_buffer + ply_region_t *updated_areas; /* in device pixels */ + uint32_t is_opaque : 1; + int device_scale; +- int device_rotation; ++ ++ ply_pixel_buffer_rotation_t device_rotation; + }; + + static inline void ply_pixel_buffer_blend_value_at_pixel (ply_pixel_buffer_t *buffer, +@@ -363,13 +364,14 @@ ply_pixel_buffer_new (unsigned long width, + } + + ply_pixel_buffer_t * +-ply_pixel_buffer_new_with_device_rotation (unsigned long width, +- unsigned long height, +- int device_rotation) ++ply_pixel_buffer_new_with_device_rotation (unsigned long width, ++ unsigned long height, ++ ply_pixel_buffer_rotation_t device_rotation) + { + ply_pixel_buffer_t *buffer; + +- if (device_rotation >= PLY_PIXEL_BUFFER_ROTATE_CLOCKWISE) { ++ if (device_rotation == PLY_PIXEL_BUFFER_ROTATE_CLOCKWISE || ++ device_rotation == PLY_PIXEL_BUFFER_ROTATE_COUNTER_CLOCKWISE) { + unsigned long tmp = width; + width = height; + height = tmp; +diff --git a/src/libply-splash-core/ply-pixel-buffer.h b/src/libply-splash-core/ply-pixel-buffer.h +index 7736dd3..ea7f833 100644 +--- a/src/libply-splash-core/ply-pixel-buffer.h ++++ b/src/libply-splash-core/ply-pixel-buffer.h +@@ -37,10 +37,13 @@ typedef struct _ply_pixel_buffer ply_pixel_buffer_t; + | ((uint8_t) (CLAMP (g * 255.0, 0.0, 255.0)) << 8) \ + | ((uint8_t) (CLAMP (b * 255.0, 0.0, 255.0)))) + +-#define PLY_PIXEL_BUFFER_ROTATE_UPRIGHT 0 +-#define PLY_PIXEL_BUFFER_ROTATE_UPSIDE_DOWN 1 +-#define PLY_PIXEL_BUFFER_ROTATE_CLOCKWISE 2 +-#define PLY_PIXEL_BUFFER_ROTATE_COUNTER_CLOCKWISE 3 ++typedef enum ++{ ++ PLY_PIXEL_BUFFER_ROTATE_UPRIGHT = 0, ++ PLY_PIXEL_BUFFER_ROTATE_UPSIDE_DOWN, ++ PLY_PIXEL_BUFFER_ROTATE_CLOCKWISE, ++ PLY_PIXEL_BUFFER_ROTATE_COUNTER_CLOCKWISE ++} ply_pixel_buffer_rotation_t; + + #ifndef PLY_HIDE_FUNCTION_DECLARATIONS + ply_pixel_buffer_t *ply_pixel_buffer_new (unsigned long width, +@@ -48,7 +51,7 @@ ply_pixel_buffer_t *ply_pixel_buffer_new (unsigned long width, + ply_pixel_buffer_t * + ply_pixel_buffer_new_with_device_rotation (unsigned long width, + unsigned long height, +- int device_rotation); ++ ply_pixel_buffer_rotation_t device_rotation); + void ply_pixel_buffer_free (ply_pixel_buffer_t *buffer); + void ply_pixel_buffer_get_size (ply_pixel_buffer_t *buffer, + ply_rectangle_t *size); +-- +2.17.0 + diff --git a/plymouth.spec b/plymouth.spec index ce1a029..e8d35e1 100644 --- a/plymouth.spec +++ b/plymouth.spec @@ -16,7 +16,7 @@ Summary: Graphical Boot Animation and Logger Name: plymouth Version: 0.9.3 -Release: 4%{?snapshot_rel}%{?dist} +Release: 5%{?snapshot_rel}%{?dist} License: GPLv2+ URL: http://www.freedesktop.org/wiki/Software/Plymouth Group: System Environment/Base @@ -26,6 +26,16 @@ Source1: boot-duration Source2: charge.plymouth Source3: plymouth-update-initrd +# Patches from upstream git for rotated-display support +# https://bugs.freedesktop.org/show_bug.cgi?id=104714 +# These can all be dropped on the next rebase +Patch1: 0001-device-manager-drop-superfluous-create_pixel_display.patch +Patch2: 0002-main-Do-not-update-the-display-on-backspace-when-the.patch +Patch3: 0003-pixel-buffer-Add-the-concept-of-device-rotation.patch +Patch4: 0004-drm-Check-for-panel-orientation-connector-property.patch +Patch5: 0005-drm-Reset-primary-plane-rotation-to-DRM_MODE_ROTATE_.patch +Patch6: 0006-pixel-buffer-switch-device-rotation-to-an-enum.patch + BuildRequires: pkgconfig(libdrm) BuildRequires: pkgconfig(libudev) BuildRequires: kernel-headers @@ -226,7 +236,7 @@ This package contains the "spinner" boot splash theme for Plymouth. It features a small spinner on a dark background. %prep -%setup -q +%autosetup -p1 # Change the default theme sed -i -e 's/spinner/charge/g' src/plymouthd.defaults @@ -447,6 +457,10 @@ fi %files system-theme %changelog +* Sun Apr 15 2018 Hans de Goede - 0.9.3-5 +- Add patches from upstream git for devices with non upright mounted LCD panels + https://bugs.freedesktop.org/show_bug.cgi?id=104714 + * Fri Feb 09 2018 Igor Gnatenko - 0.9.3-4 - Escape macros in %%changelog