Add support for pixel_source property to drm_plane and related documentation. In addition, force pixel_source to DRM_PLANE_PIXEL_SOURCE_FB in DRM_IOCTL_MODE_SETPLANE as to not break legacy userspace. This enum property will allow user to specify a pixel source for the plane. Possible pixel sources will be defined in the drm_plane_pixel_source enum. Currently, the only pixel sources are DRM_PLANE_PIXEL_SOURCE_FB (the default value) and DRM_PLANE_PIXEL_SOURCE_NONE.
Unified · Split
| @@ -252,6 +252,7 @@ void __drm_atomic_helper_plane_state_reset(struct drm_plane_state *plane_state, · 251 unmodified lines | ||
| 252 | 252 | |
| 253 | 253 | plane_state->alpha = DRM_BLEND_ALPHA_OPAQUE; |
| 254 | 254 | plane_state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI; |
| 255 | + plane_state->pixel_source = DRM_PLANE_PIXEL_SOURCE_FB; | |
| 255 | 256 | |
| 256 | 257 | if (plane->color_encoding_property) { |
| 257 | 258 | if (!drm_object_property_get_default_value(&plane->base, |
| @@ -562,6 +562,8 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane, · 561 unmodified lines | ||
| 562 | 562 | state->src_w = val; |
| 563 | 563 | } else if (property == config->prop_src_h) { |
| 564 | 564 | state->src_h = val; |
| 565 | + } else if (property == plane->pixel_source_property) { | |
| 566 | + state->pixel_source = val; | |
| 565 | 567 | } else if (property == plane->alpha_property) { |
| 566 | 568 | state->alpha = val; |
| 567 | 569 | } else if (property == plane->blend_mode_property) { |
| @@ -650,6 +652,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane, · 82 unmodified lines | ||
| 650 | 652 | *val = state->src_w; |
| 651 | 653 | } else if (property == config->prop_src_h) { |
| 652 | 654 | *val = state->src_h; |
| 655 | + } else if (property == plane->pixel_source_property) { | |
| 656 | + *val = state->pixel_source; | |
| 653 | 657 | } else if (property == plane->alpha_property) { |
| 654 | 658 | *val = state->alpha; |
| 655 | 659 | } else if (property == plane->blend_mode_property) { |
| @@ -185,6 +185,25 @@ · 184 unmodified lines | ||
| 185 | 185 | * plane does not expose the "alpha" property, then this is |
| 186 | 186 | * assumed to be 1.0 |
| 187 | 187 | * |
| 188 | + * pixel_source: | |
| 189 | + * pixel_source is set up with drm_plane_create_pixel_source_property(). | |
| 190 | + * It is used to toggle the active source of pixel data for the plane. | |
| 191 | + * The plane will only display data from the set pixel_source -- any | |
| 192 | + * data from other sources will be ignored. | |
| 193 | + * | |
| 194 | + * For non-framebuffer sources, if pixel_source is set to a non-framebuffer | |
| 195 | + * and non-NONE source, and the corresponding source property is NULL, then | |
| 196 | + * the atomic commit should return an error. | |
| 197 | + * | |
| 198 | + * Possible values: | |
| 199 | + * | |
| 200 | + * "NONE": | |
| 201 | + * No active pixel source. | |
| 202 | + * Committing with a NONE pixel source will disable the plane. | |
| 203 | + * | |
| 204 | + * "FB": | |
| 205 | + * Framebuffer source set by the "FB_ID" property. | |
| 206 | + * | |
| 188 | 207 | * Note that all the property extensions described here apply either to the |
| 189 | 208 | * plane or the CRTC (e.g. for the background color, which currently is not |
| 190 | 209 | * exposed and assumed to be black). |
| @@ -615,3 +634,78 @@ int drm_plane_create_blend_mode_property(struct drm_plane *plane, · 424 unmodified lines | ||
| 615 | 634 | return 0; |
| 616 | 635 | } |
| 617 | 636 | EXPORT_SYMBOL(drm_plane_create_blend_mode_property); |
| 637 | + | |
| 638 | +static const struct drm_prop_enum_list drm_pixel_source_enum_list[] = { | |
| 639 | + { DRM_PLANE_PIXEL_SOURCE_NONE, "NONE" }, | |
| 640 | + { DRM_PLANE_PIXEL_SOURCE_FB, "FB" }, | |
| 641 | +}; | |
| 642 | + | |
| 643 | +/** | |
| 644 | + * drm_plane_create_pixel_source_property - create a new pixel source property | |
| 645 | + * @plane: DRM plane | |
| 646 | + * @extra_sources: Bitmask of additional supported pixel_sources for the driver. | |
| 647 | + * DRM_PLANE_PIXEL_SOURCE_FB and DRM_PLANE_PIXEL_SOURCE_NONE will | |
| 648 | + * always be enabled as supported sources. | |
| 649 | + * | |
| 650 | + * This creates a new property describing the current source of pixel data for the | |
| 651 | + * plane. The pixel_source will be initialized as DRM_PLANE_PIXEL_SOURCE_FB by default. | |
| 652 | + * | |
| 653 | + * Drivers can set a custom default source by overriding the pixel_source value in | |
| 654 | + * drm_plane_funcs.reset() | |
| 655 | + * | |
| 656 | + * The property is exposed to userspace as an enumeration property called | |
| 657 | + * "pixel_source" and has the following enumeration values: | |
| 658 | + * | |
| 659 | + * "NONE": | |
| 660 | + * No active pixel source | |
| 661 | + * | |
| 662 | + * "FB": | |
| 663 | + * Framebuffer pixel source | |
| 664 | + * | |
| 665 | + * Returns: | |
| 666 | + * Zero on success, negative errno on failure. | |
| 667 | + */ | |
| 668 | +int drm_plane_create_pixel_source_property(struct drm_plane *plane, | |
| 669 | + unsigned long extra_sources) | |
| 670 | +{ | |
| 671 | + struct drm_device *dev = plane->dev; | |
| 672 | + struct drm_property *prop; | |
| 673 | + static const unsigned int valid_source_mask = BIT(DRM_PLANE_PIXEL_SOURCE_FB) | | |
| 674 | + BIT(DRM_PLANE_PIXEL_SOURCE_NONE); | |
| 675 | + int i; | |
| 676 | + | |
| 677 | + /* FB is supported by default */ | |
| 678 | + unsigned long supported_sources = extra_sources | | |
| 679 | + BIT(DRM_PLANE_PIXEL_SOURCE_FB) | | |
| 680 | + BIT(DRM_PLANE_PIXEL_SOURCE_NONE); | |
| 681 | + | |
| 682 | + if (WARN_ON(supported_sources & ~valid_source_mask)) | |
| 683 | + return -EINVAL; | |
| 684 | + | |
| 685 | + prop = drm_property_create(dev, DRM_MODE_PROP_ENUM | DRM_MODE_PROP_ATOMIC, "pixel_source", | |
| 686 | + hweight32(supported_sources)); | |
| 687 | + | |
| 688 | + if (!prop) | |
| 689 | + return -ENOMEM; | |
| 690 | + | |
| 691 | + for (i = 0; i < ARRAY_SIZE(drm_pixel_source_enum_list); i++) { | |
| 692 | + int ret; | |
| 693 | + | |
| 694 | + if (!test_bit(drm_pixel_source_enum_list[i].type, &supported_sources)) | |
| 695 | + continue; | |
| 696 | + | |
| 697 | + ret = drm_property_add_enum(prop, drm_pixel_source_enum_list[i].type, | |
| 698 | + drm_pixel_source_enum_list[i].name); | |
| 699 | + if (ret) { | |
| 700 | + drm_property_destroy(dev, prop); | |
| 701 | + | |
| 702 | + return ret; | |
| 703 | + } | |
| 704 | + } | |
| 705 | + | |
| 706 | + drm_object_attach_property(&plane->base, prop, DRM_PLANE_PIXEL_SOURCE_FB); | |
| 707 | + plane->pixel_source_property = prop; | |
| 708 | + | |
| 709 | + return 0; | |
| 710 | +} | |
| 711 | +EXPORT_SYMBOL(drm_plane_create_pixel_source_property); | |
| @@ -953,6 +953,14 @@ bool drm_any_plane_has_format(struct drm_device *dev, · 952 unmodified lines | ||
| 953 | 953 | } |
| 954 | 954 | EXPORT_SYMBOL(drm_any_plane_has_format); |
| 955 | 955 | |
| 956 | +static bool drm_plane_needs_disable(struct drm_plane_state *state, struct drm_framebuffer *fb) | |
| 957 | +{ | |
| 958 | + if (state->pixel_source == DRM_PLANE_PIXEL_SOURCE_NONE) | |
| 959 | + return true; | |
| 960 | + | |
| 961 | + return state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb == NULL; | |
| 962 | +} | |
| 963 | + | |
| 956 | 964 | /* |
| 957 | 965 | * __setplane_internal - setplane handler for internal callers |
| 958 | 966 | * |
| @@ -975,8 +983,8 @@ static int __setplane_internal(struct drm_plane *plane, · 16 unmodified lines | ||
| 975 | 983 | |
| 976 | 984 | WARN_ON(drm_drv_uses_atomic_modeset(plane->dev)); |
| 977 | 985 | |
| 978 | − /* No fb means shut it down */ | |
| 979 | − if (!fb) { | |
| 986 | + /* No visible data means shut it down */ | |
| 987 | + if (drm_plane_needs_disable(plane->state, fb)) { | |
| 980 | 988 | plane->old_fb = plane->fb; |
| 981 | 989 | ret = plane->funcs->disable_plane(plane, ctx); |
| 982 | 990 | if (!ret) { |
| @@ -1027,8 +1035,8 @@ static int __setplane_atomic(struct drm_plane *plane, · 44 unmodified lines | ||
| 1027 | 1035 | |
| 1028 | 1036 | WARN_ON(!drm_drv_uses_atomic_modeset(plane->dev)); |
| 1029 | 1037 | |
| 1030 | − /* No fb means shut it down */ | |
| 1031 | − if (!fb) | |
| 1038 | + /* No visible data means shut it down */ | |
| 1039 | + if (drm_plane_needs_disable(plane->state, fb)) | |
| 1032 | 1040 | return plane->funcs->disable_plane(plane, ctx); |
| 1033 | 1041 | |
| 1034 | 1042 | /* |
| @@ -1101,6 +1109,9 @@ int drm_mode_setplane(struct drm_device *dev, void *data, · 66 unmodified lines | ||
| 1101 | 1109 | return -ENOENT; |
| 1102 | 1110 | } |
| 1103 | 1111 | |
| 1112 | + if (plane->state) | |
| 1113 | + plane->state->pixel_source = DRM_PLANE_PIXEL_SOURCE_FB; | |
| 1114 | + | |
| 1104 | 1115 | if (plane_req->fb_id) { |
| 1105 | 1116 | fb = drm_framebuffer_lookup(dev, file_priv, plane_req->fb_id); |
| 1106 | 1117 | if (!fb) { |
| @@ -58,4 +58,6 @@ int drm_atomic_normalize_zpos(struct drm_device *dev, · 57 unmodified lines | ||
| 58 | 58 | struct drm_atomic_state *state); |
| 59 | 59 | int drm_plane_create_blend_mode_property(struct drm_plane *plane, |
| 60 | 60 | unsigned int supported_modes); |
| 61 | +int drm_plane_create_pixel_source_property(struct drm_plane *plane, | |
| 62 | + unsigned long extra_sources); | |
| 61 | 63 | #endif |
| @@ -40,6 +40,12 @@ enum drm_scaling_filter { · 39 unmodified lines | ||
| 40 | 40 | DRM_SCALING_FILTER_NEAREST_NEIGHBOR, |
| 41 | 41 | }; |
| 42 | 42 | |
| 43 | +enum drm_plane_pixel_source { | |
| 44 | + DRM_PLANE_PIXEL_SOURCE_NONE, | |
| 45 | + DRM_PLANE_PIXEL_SOURCE_FB, | |
| 46 | + DRM_PLANE_PIXEL_SOURCE_MAX | |
| 47 | +}; | |
| 48 | + | |
| 43 | 49 | /** |
| 44 | 50 | * struct drm_plane_state - mutable plane state |
| 45 | 51 | * |
| @@ -120,6 +126,14 @@ struct drm_plane_state { · 74 unmodified lines | ||
| 120 | 126 | /** @hotspot_y: y offset to mouse cursor hotspot */ |
| 121 | 127 | int32_t hotspot_x, hotspot_y; |
| 122 | 128 | |
| 129 | + /** | |
| 130 | + * @pixel_source: | |
| 131 | + * | |
| 132 | + * Source of pixel information for the plane. See | |
| 133 | + * drm_plane_create_pixel_source_property() for more details. | |
| 134 | + */ | |
| 135 | + enum drm_plane_pixel_source pixel_source; | |
| 136 | + | |
| 123 | 137 | /** |
| 124 | 138 | * @alpha: |
| 125 | 139 | * Opacity of the plane with 0 as completely transparent and 0xffff as |
| @@ -713,6 +727,13 @@ struct drm_plane { · 587 unmodified lines | ||
| 713 | 727 | */ |
| 714 | 728 | struct drm_plane_state *state; |
| 715 | 729 | |
| 730 | + /* | |
| 731 | + * @pixel_source_property: | |
| 732 | + * Optional pixel_source property for this plane. See | |
| 733 | + * drm_plane_create_pixel_source_property(). | |
| 734 | + */ | |
| 735 | + struct drm_property *pixel_source_property; | |
| 736 | + | |
| 716 | 737 | /** |
| 717 | 738 | * @alpha_property: |
| 718 | 739 | * Optional alpha property for this plane. See |