Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm: Introduce plane SIZE_HINTS property

Add a new immutable plane property by which a plane can advertise
a handful of recommended plane sizes. This would be mostly exposed
by cursor planes as a slightly more capable replacement for
the DRM_CAP_CURSOR_WIDTH/HEIGHT caps, which can only declare
a one size fits all limit for the whole device.

Currently eg. amdgpu/i915/nouveau just advertize the max cursor
size via the cursor size caps. But always using the max sized
cursor can waste a surprising amount of power, so a better
strategy is desirable.

Most other drivers don't specify any cursor size at all, in
which case the ioctl code just claims that 64x64 is a great
choice. Whether that is actually true is debatable.

A poll of various compositor developers informs us that
blindly probing with setcursor/atomic ioctl to determine
suitable cursor sizes is not acceptable, thus the
introduction of the new property to supplant the cursor
size caps. The compositor will now be free to select a
more optimal cursor size from the short list of options.

Note that the reported sizes (either via the property or the
caps) make no claims about things such as plane scaling. So
these things should only really be consulted for simple
"cursor like" use cases.

Userspace consumer in the form of mutter seems ready:
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3165

v2: Try to add some docs
v3: Specify that value 0 is reserved for future use (basic idea from Jonas)
Drop the note about typical hardware (Pekka)
v4: Update the docs to indicate the list is "in order of preference"
Add a a link to the mutter MR
v5: Limit to cursors only for now (Simon)

Cc: Jonas Ådahl <jadahl@redhat.com>
Cc: Sameer Lattannavar <sameer.lattannavar@intel.com>
Reviewed-by: Sebastian Wick <sebastian.wick@redhat.com>
Reviewed-by: Simon Ser <contact@emersion.fr>
Acked-by: Daniel Stone <daniels@collabora.com>
Acked-by: Harry Wentland <harry.wentland@amd.com>
Acked-by: Pekka Paalanen <pekka.paalanen@collabora.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240318204408.9687-2-ville.syrjala@linux.intel.com

+83
+7
drivers/gpu/drm/drm_mode_config.c
··· 372 372 return -ENOMEM; 373 373 dev->mode_config.modifiers_property = prop; 374 374 375 + prop = drm_property_create(dev, 376 + DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_BLOB, 377 + "SIZE_HINTS", 0); 378 + if (!prop) 379 + return -ENOMEM; 380 + dev->mode_config.size_hints_property = prop; 381 + 375 382 return 0; 376 383 } 377 384
+56
drivers/gpu/drm/drm_plane.c
··· 140 140 * DRM_FORMAT_MOD_LINEAR. Before linux kernel release v5.1 there have been 141 141 * various bugs in this area with inconsistencies between the capability 142 142 * flag and per-plane properties. 143 + * 144 + * SIZE_HINTS: 145 + * Blob property which contains the set of recommended plane size 146 + * which can used for simple "cursor like" use cases (eg. no scaling). 147 + * Using these hints frees userspace from extensive probing of 148 + * supported plane sizes through atomic/setcursor ioctls. 149 + * 150 + * The blob contains an array of struct drm_plane_size_hint, in 151 + * order of preference. For optimal usage userspace should pick 152 + * the first size that satisfies its own requirements. 153 + * 154 + * Drivers should only attach this property to planes that 155 + * support a very limited set of sizes. 156 + * 157 + * Note that property value 0 (ie. no blob) is reserved for potential 158 + * future use. Current userspace is expected to ignore the property 159 + * if the value is 0, and fall back to some other means (eg. 160 + * &DRM_CAP_CURSOR_WIDTH and &DRM_CAP_CURSOR_HEIGHT) to determine 161 + * the appropriate plane size to use. 143 162 */ 144 163 145 164 static unsigned int drm_num_planes(struct drm_device *dev) ··· 1748 1729 return 0; 1749 1730 } 1750 1731 EXPORT_SYMBOL(drm_plane_create_scaling_filter_property); 1732 + 1733 + /** 1734 + * drm_plane_add_size_hint_property - create a size hint property 1735 + * 1736 + * @plane: drm plane 1737 + * @hints: size hints 1738 + * @num_hints: number of size hints 1739 + * 1740 + * Create a size hints property for the plane. 1741 + * 1742 + * RETURNS: 1743 + * Zero for success or -errno 1744 + */ 1745 + int drm_plane_add_size_hints_property(struct drm_plane *plane, 1746 + const struct drm_plane_size_hint *hints, 1747 + int num_hints) 1748 + { 1749 + struct drm_device *dev = plane->dev; 1750 + struct drm_mode_config *config = &dev->mode_config; 1751 + struct drm_property_blob *blob; 1752 + 1753 + /* extending to other plane types needs actual thought */ 1754 + if (drm_WARN_ON(dev, plane->type != DRM_PLANE_TYPE_CURSOR)) 1755 + return -EINVAL; 1756 + 1757 + blob = drm_property_create_blob(dev, 1758 + array_size(sizeof(hints[0]), num_hints), 1759 + hints); 1760 + if (IS_ERR(blob)) 1761 + return PTR_ERR(blob); 1762 + 1763 + drm_object_attach_property(&plane->base, config->size_hints_property, 1764 + blob->base.id); 1765 + 1766 + return 0; 1767 + } 1768 + EXPORT_SYMBOL(drm_plane_add_size_hints_property);
+5
include/drm/drm_mode_config.h
··· 942 942 */ 943 943 struct drm_property *modifiers_property; 944 944 945 + /** 946 + * @size_hints_propertty: Plane SIZE_HINTS property. 947 + */ 948 + struct drm_property *size_hints_property; 949 + 945 950 /* cursor size */ 946 951 uint32_t cursor_width, cursor_height; 947 952
+4
include/drm/drm_plane.h
··· 32 32 #include <drm/drm_util.h> 33 33 34 34 struct drm_crtc; 35 + struct drm_plane_size_hint; 35 36 struct drm_printer; 36 37 struct drm_modeset_acquire_ctx; 37 38 ··· 977 976 978 977 int drm_plane_create_scaling_filter_property(struct drm_plane *plane, 979 978 unsigned int supported_filters); 979 + int drm_plane_add_size_hints_property(struct drm_plane *plane, 980 + const struct drm_plane_size_hint *hints, 981 + int num_hints); 980 982 981 983 #endif
+11
include/uapi/drm/drm_mode.h
··· 866 866 }; 867 867 868 868 /** 869 + * struct drm_plane_size_hint - Plane size hints 870 + * 871 + * The plane SIZE_HINTS property blob contains an 872 + * array of struct drm_plane_size_hint. 873 + */ 874 + struct drm_plane_size_hint { 875 + __u16 width; 876 + __u16 height; 877 + }; 878 + 879 + /** 869 880 * struct hdr_metadata_infoframe - HDR Metadata Infoframe Data. 870 881 * 871 882 * HDR Metadata Infoframe as per CTA 861.G spec. This is expected