forked from Minki/linux
drm: Allow userspace to ask for universal plane list (v2)
Userspace clients which wish to receive all DRM planes (primary and cursor planes in addition to the traditional overlay planes) may set the DRM_CLIENT_CAP_UNIVERSAL_PLANES capability. v2: Hide behind drm.universal_planes module option [suggested by Daniel Vetter] Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Rob Clark <robdclark@gmail.com>
This commit is contained in:
parent
780f598471
commit
681e7ec730
@ -1959,6 +1959,7 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data,
|
|||||||
struct drm_plane *plane;
|
struct drm_plane *plane;
|
||||||
uint32_t __user *plane_ptr;
|
uint32_t __user *plane_ptr;
|
||||||
int copied = 0, ret = 0;
|
int copied = 0, ret = 0;
|
||||||
|
unsigned num_planes;
|
||||||
|
|
||||||
if (!drm_core_check_feature(dev, DRIVER_MODESET))
|
if (!drm_core_check_feature(dev, DRIVER_MODESET))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -1966,17 +1967,26 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data,
|
|||||||
drm_modeset_lock_all(dev);
|
drm_modeset_lock_all(dev);
|
||||||
config = &dev->mode_config;
|
config = &dev->mode_config;
|
||||||
|
|
||||||
|
if (file_priv->universal_planes)
|
||||||
|
num_planes = config->num_total_plane;
|
||||||
|
else
|
||||||
|
num_planes = config->num_overlay_plane;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This ioctl is called twice, once to determine how much space is
|
* This ioctl is called twice, once to determine how much space is
|
||||||
* needed, and the 2nd time to fill it.
|
* needed, and the 2nd time to fill it.
|
||||||
*/
|
*/
|
||||||
if (config->num_overlay_plane &&
|
if (num_planes &&
|
||||||
(plane_resp->count_planes >= config->num_overlay_plane)) {
|
(plane_resp->count_planes >= num_planes)) {
|
||||||
plane_ptr = (uint32_t __user *)(unsigned long)plane_resp->plane_id_ptr;
|
plane_ptr = (uint32_t __user *)(unsigned long)plane_resp->plane_id_ptr;
|
||||||
|
|
||||||
list_for_each_entry(plane, &config->plane_list, head) {
|
list_for_each_entry(plane, &config->plane_list, head) {
|
||||||
/* Only advertise overlays to userspace for now. */
|
/*
|
||||||
if (plane->type != DRM_PLANE_TYPE_OVERLAY)
|
* Unless userspace set the 'universal planes'
|
||||||
|
* capability bit, only advertise overlays.
|
||||||
|
*/
|
||||||
|
if (plane->type != DRM_PLANE_TYPE_OVERLAY &&
|
||||||
|
!file_priv->universal_planes)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (put_user(plane->base.id, plane_ptr + copied)) {
|
if (put_user(plane->base.id, plane_ptr + copied)) {
|
||||||
@ -1986,7 +1996,7 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data,
|
|||||||
copied++;
|
copied++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
plane_resp->count_planes = config->num_overlay_plane;
|
plane_resp->count_planes = num_planes;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
drm_modeset_unlock_all(dev);
|
drm_modeset_unlock_all(dev);
|
||||||
|
@ -328,6 +328,13 @@ drm_setclientcap(struct drm_device *dev, void *data, struct drm_file *file_priv)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
file_priv->stereo_allowed = req->value;
|
file_priv->stereo_allowed = req->value;
|
||||||
break;
|
break;
|
||||||
|
case DRM_CLIENT_CAP_UNIVERSAL_PLANES:
|
||||||
|
if (!drm_universal_planes)
|
||||||
|
return -EINVAL;
|
||||||
|
if (req->value > 1)
|
||||||
|
return -EINVAL;
|
||||||
|
file_priv->universal_planes = req->value;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,10 @@ EXPORT_SYMBOL(drm_debug);
|
|||||||
unsigned int drm_rnodes = 0; /* 1 to enable experimental render nodes API */
|
unsigned int drm_rnodes = 0; /* 1 to enable experimental render nodes API */
|
||||||
EXPORT_SYMBOL(drm_rnodes);
|
EXPORT_SYMBOL(drm_rnodes);
|
||||||
|
|
||||||
|
/* 1 to allow user space to request universal planes (experimental) */
|
||||||
|
unsigned int drm_universal_planes = 0;
|
||||||
|
EXPORT_SYMBOL(drm_universal_planes);
|
||||||
|
|
||||||
unsigned int drm_vblank_offdelay = 5000; /* Default to 5000 msecs. */
|
unsigned int drm_vblank_offdelay = 5000; /* Default to 5000 msecs. */
|
||||||
EXPORT_SYMBOL(drm_vblank_offdelay);
|
EXPORT_SYMBOL(drm_vblank_offdelay);
|
||||||
|
|
||||||
@ -68,6 +72,7 @@ MODULE_PARM_DESC(timestamp_monotonic, "Use monotonic timestamps");
|
|||||||
|
|
||||||
module_param_named(debug, drm_debug, int, 0600);
|
module_param_named(debug, drm_debug, int, 0600);
|
||||||
module_param_named(rnodes, drm_rnodes, int, 0600);
|
module_param_named(rnodes, drm_rnodes, int, 0600);
|
||||||
|
module_param_named(universal_planes, drm_universal_planes, int, 0600);
|
||||||
module_param_named(vblankoffdelay, drm_vblank_offdelay, int, 0600);
|
module_param_named(vblankoffdelay, drm_vblank_offdelay, int, 0600);
|
||||||
module_param_named(timestamp_precision_usec, drm_timestamp_precision, int, 0600);
|
module_param_named(timestamp_precision_usec, drm_timestamp_precision, int, 0600);
|
||||||
module_param_named(timestamp_monotonic, drm_timestamp_monotonic, int, 0600);
|
module_param_named(timestamp_monotonic, drm_timestamp_monotonic, int, 0600);
|
||||||
|
@ -409,6 +409,11 @@ struct drm_file {
|
|||||||
unsigned is_master :1;
|
unsigned is_master :1;
|
||||||
/* true when the client has asked us to expose stereo 3D mode flags */
|
/* true when the client has asked us to expose stereo 3D mode flags */
|
||||||
unsigned stereo_allowed :1;
|
unsigned stereo_allowed :1;
|
||||||
|
/*
|
||||||
|
* true if client understands CRTC primary planes and cursor planes
|
||||||
|
* in the plane list
|
||||||
|
*/
|
||||||
|
unsigned universal_planes:1;
|
||||||
|
|
||||||
struct pid *pid;
|
struct pid *pid;
|
||||||
kuid_t uid;
|
kuid_t uid;
|
||||||
@ -1409,6 +1414,7 @@ extern void drm_put_dev(struct drm_device *dev);
|
|||||||
extern void drm_unplug_dev(struct drm_device *dev);
|
extern void drm_unplug_dev(struct drm_device *dev);
|
||||||
extern unsigned int drm_debug;
|
extern unsigned int drm_debug;
|
||||||
extern unsigned int drm_rnodes;
|
extern unsigned int drm_rnodes;
|
||||||
|
extern unsigned int drm_universal_planes;
|
||||||
|
|
||||||
extern unsigned int drm_vblank_offdelay;
|
extern unsigned int drm_vblank_offdelay;
|
||||||
extern unsigned int drm_timestamp_precision;
|
extern unsigned int drm_timestamp_precision;
|
||||||
|
@ -637,6 +637,14 @@ struct drm_get_cap {
|
|||||||
*/
|
*/
|
||||||
#define DRM_CLIENT_CAP_STEREO_3D 1
|
#define DRM_CLIENT_CAP_STEREO_3D 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DRM_CLIENT_CAP_UNIVERSAL_PLANES
|
||||||
|
*
|
||||||
|
* If set to 1, the DRM core will expose all planes (overlay, primary, and
|
||||||
|
* cursor) to userspace.
|
||||||
|
*/
|
||||||
|
#define DRM_CLIENT_CAP_UNIVERSAL_PLANES 2
|
||||||
|
|
||||||
/** DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */
|
/** DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */
|
||||||
struct drm_set_client_cap {
|
struct drm_set_client_cap {
|
||||||
__u64 capability;
|
__u64 capability;
|
||||||
|
Loading…
Reference in New Issue
Block a user