|
18 | 18 | #include <xf86drmMode.h> |
19 | 19 |
|
20 | 20 | #include "pixel_format.h" |
| 21 | +#include "util/asserts.h" |
21 | 22 | #include "util/bitset.h" |
22 | 23 | #include "util/list.h" |
23 | 24 | #include "util/lock_ops.h" |
@@ -2450,6 +2451,24 @@ int kms_req_builder_push_fb_layer( |
2450 | 2451 | /* id_range */ false, 0 |
2451 | 2452 | // clang-format on |
2452 | 2453 | ); |
| 2454 | + |
| 2455 | + // If allocation failed due to rotation and rotation is not enforced, retry without rotation |
| 2456 | + if (plane == NULL && layer->has_rotation && !layer->enforce_rotation) { |
| 2457 | + plane = allocate_plane( |
| 2458 | + // clang-format off |
| 2459 | + builder, |
| 2460 | + /* allow_primary */ false, |
| 2461 | + /* allow_overlay */ false, |
| 2462 | + /* allow_cursor */ true, |
| 2463 | + /* format */ layer->format, |
| 2464 | + /* modifier */ layer->has_modifier, layer->modifier, |
| 2465 | + /* zpos */ false, 0, 0, |
| 2466 | + /* rotation */ false, PLANE_TRANSFORM_NONE, |
| 2467 | + /* id_range */ false, 0 |
| 2468 | + // clang-format on |
| 2469 | + ); |
| 2470 | + } |
| 2471 | + |
2453 | 2472 | if (plane == NULL) { |
2454 | 2473 | if (allocated_cursor_plane) *allocated_cursor_plane = false; |
2455 | 2474 | LOG_DEBUG("Couldn't find a fitting cursor plane.\n"); |
@@ -2494,6 +2513,39 @@ int kms_req_builder_push_fb_layer( |
2494 | 2513 | // clang-format on |
2495 | 2514 | ); |
2496 | 2515 | } |
| 2516 | + |
| 2517 | + // If allocation failed due to rotation and rotation is not enforced, retry without rotation |
| 2518 | + if (plane == NULL && layer->has_rotation && !layer->enforce_rotation) { |
| 2519 | + plane = allocate_plane( |
| 2520 | + // clang-format off |
| 2521 | + builder, |
| 2522 | + /* allow_primary */ true, |
| 2523 | + /* allow_overlay */ false, |
| 2524 | + /* allow_cursor */ false, |
| 2525 | + /* format */ layer->format, |
| 2526 | + /* modifier */ layer->has_modifier, layer->modifier, |
| 2527 | + /* zpos */ false, 0, 0, |
| 2528 | + /* rotation */ false, PLANE_TRANSFORM_NONE, |
| 2529 | + /* id_range */ false, 0 |
| 2530 | + // clang-format on |
| 2531 | + ); |
| 2532 | + |
| 2533 | + if (plane == NULL && !get_pixfmt_info(layer->format)->is_opaque) { |
| 2534 | + plane = allocate_plane( |
| 2535 | + // clang-format off |
| 2536 | + builder, |
| 2537 | + /* allow_primary */ true, |
| 2538 | + /* allow_overlay */ false, |
| 2539 | + /* allow_cursor */ false, |
| 2540 | + /* format */ pixfmt_opaque(layer->format), |
| 2541 | + /* modifier */ layer->has_modifier, layer->modifier, |
| 2542 | + /* zpos */ false, 0, 0, |
| 2543 | + /* rotation */ false, PLANE_TRANSFORM_NONE, |
| 2544 | + /* id_range */ false, 0 |
| 2545 | + // clang-format on |
| 2546 | + ); |
| 2547 | + } |
| 2548 | + } |
2497 | 2549 | } else if (plane == NULL) { |
2498 | 2550 | // First try to find an overlay plane with a higher zpos. |
2499 | 2551 | plane = allocate_plane( |
@@ -2529,6 +2581,39 @@ int kms_req_builder_push_fb_layer( |
2529 | 2581 | // clang-format on |
2530 | 2582 | ); |
2531 | 2583 | } |
| 2584 | + |
| 2585 | + // If allocation failed due to rotation and rotation is not enforced, retry without rotation |
| 2586 | + if (plane == NULL && layer->has_rotation && !layer->enforce_rotation) { |
| 2587 | + plane = allocate_plane( |
| 2588 | + // clang-format off |
| 2589 | + builder, |
| 2590 | + /* allow_primary */ false, |
| 2591 | + /* allow_overlay */ true, |
| 2592 | + /* allow_cursor */ false, |
| 2593 | + /* format */ layer->format, |
| 2594 | + /* modifier */ layer->has_modifier, layer->modifier, |
| 2595 | + /* zpos */ true, builder->next_zpos, INT64_MAX, |
| 2596 | + /* rotation */ false, PLANE_TRANSFORM_NONE, |
| 2597 | + /* id_range */ false, 0 |
| 2598 | + // clang-format on |
| 2599 | + ); |
| 2600 | + |
| 2601 | + if (plane == NULL) { |
| 2602 | + plane = allocate_plane( |
| 2603 | + // clang-format off |
| 2604 | + builder, |
| 2605 | + /* allow_primary */ false, |
| 2606 | + /* allow_overlay */ true, |
| 2607 | + /* allow_cursor */ false, |
| 2608 | + /* format */ layer->format, |
| 2609 | + /* modifier */ layer->has_modifier, layer->modifier, |
| 2610 | + /* zpos */ false, 0, 0, |
| 2611 | + /* rotation */ false, PLANE_TRANSFORM_NONE, |
| 2612 | + /* id_range */ true, builder->layers[index - 1].plane_id + 1 |
| 2613 | + // clang-format on |
| 2614 | + ); |
| 2615 | + } |
| 2616 | + } |
2532 | 2617 | } |
2533 | 2618 |
|
2534 | 2619 | if (plane == NULL) { |
@@ -2572,8 +2657,24 @@ int kms_req_builder_push_fb_layer( |
2572 | 2657 | drmModeAtomicAddProperty(builder->req, plane_id, plane->ids.zpos, zpos); |
2573 | 2658 | } |
2574 | 2659 |
|
2575 | | - if (layer->has_rotation && plane->has_rotation && !plane->has_hardcoded_rotation) { |
2576 | | - drmModeAtomicAddProperty(builder->req, plane_id, plane->ids.rotation, layer->rotation.u64); |
| 2660 | + if (layer->has_rotation) { |
| 2661 | + // Check if the plane can apply the requested rotation: |
| 2662 | + // 1. Plane must have a rotation property |
| 2663 | + // 2. If hardcoded, it must match the requested rotation |
| 2664 | + // 3. The requested rotation bits must be supported by the plane |
| 2665 | + bool can_apply_rotation = plane->has_rotation && |
| 2666 | + (!plane->has_hardcoded_rotation || plane->hardcoded_rotation.u32 == layer->rotation.u32) && |
| 2667 | + !(layer->rotation.u32 & ~plane->supported_rotations.u32); |
| 2668 | + |
| 2669 | + if (can_apply_rotation && !plane->has_hardcoded_rotation) { |
| 2670 | + drmModeAtomicAddProperty(builder->req, plane_id, plane->ids.rotation, layer->rotation.u64); |
| 2671 | + } else if (!can_apply_rotation && layer->enforce_rotation) { |
| 2672 | + // Rotation was requested and must be enforced, but plane can't apply it |
| 2673 | + LOG_ERROR("Rotation requested with enforce_rotation=true, but plane %" PRIu32 " cannot apply it.\n", plane_id); |
| 2674 | + ok = EINVAL; |
| 2675 | + goto fail_release_plane; |
| 2676 | + } |
| 2677 | + // else: rotation requested but not enforced, or hardcoded rotation matches - silently skip setting property |
2577 | 2678 | } |
2578 | 2679 |
|
2579 | 2680 | if (index == 0) { |
|
0 commit comments