On Wed, Mar 04, 2015 at 01:16:20PM +0000, Chris Wilson wrote:
> Add a new API that allows the caller to skip any forced probing, which
> may require slow i2c to a remote display, and only report the currently
> active mode and encoder for a Connector. This is often the information
> of interest and is much, much faster than re-retrieving the link status
> and EDIDs, e.g. if the caller only wishes to count the number of active
> outputs.
> 
> v2: Fix error path to avoid double free after a failed GETCONNECTOR
> ioctl.
> 
> v3: Daniel strongly disapproved of my disjoint in behaviour between
> GetConnector and GetConnectorCurrent, and considering how best to make a
> drop in replacement for drmmode_output_init() convinced me keeping the
> API as consistent as possible was the right approach.
> 
> v4: Avoid probing on the second calls to GETCONNECTOR for unconnected
> outputs.
> 
> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> Cc: Daniel Vetter <daniel.vetter at ffwll.com>
> Cc: Damien Lespiau <damien.lespiau at intel.com>
> Cc: David Herrmann <dh.herrmann at googlemail.com>

Reviewed-by: Daniel Vetter <daniel.vetter at ffwll.ch>

> ---
>  tests/modeprint/modeprint.c | 18 ++++++++++++++++--
>  xf86drmMode.c               | 23 ++++++++++++++++++++---
>  xf86drmMode.h               | 17 +++++++++++++++--
>  3 files changed, 51 insertions(+), 7 deletions(-)
> 
> diff --git a/tests/modeprint/modeprint.c b/tests/modeprint/modeprint.c
> index 6f0d039..514d3ba 100644
> --- a/tests/modeprint/modeprint.c
> +++ b/tests/modeprint/modeprint.c
> @@ -43,6 +43,7 @@
>  
>  #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
>  
> +int current;
>  int connectors;
>  int full_props;
>  int edid;
> @@ -272,7 +273,7 @@ int printRes(int fd, drmModeResPtr res)
>  
>       if (connectors) {
>               for (i = 0; i < res->count_connectors; i++) {
> -                     connector = drmModeGetConnector(fd, res->connectors[i]);
> +                     connector = (current ? drmModeGetConnectorCurrent : 
> drmModeGetConnector) (fd, res->connectors[i]);
>  
>                       if (!connector)
>                               printf("Could not get connector %i\n", 
> res->connectors[i]);
> @@ -331,6 +332,7 @@ int printRes(int fd, drmModeResPtr res)
>  
>  void args(int argc, char **argv)
>  {
> +     int defaults = 1;
>       int i;
>  
>       fbs = 0;
> @@ -341,32 +343,41 @@ void args(int argc, char **argv)
>       full_modes = 0;
>       full_props = 0;
>       connectors = 0;
> +     current = 0;
>  
>       module_name = argv[1];
>  
>       for (i = 2; i < argc; i++) {
>               if (strcmp(argv[i], "-fb") == 0) {
>                       fbs = 1;
> +                     defaults = 0;
>               } else if (strcmp(argv[i], "-crtcs") == 0) {
>                       crtcs = 1;
> +                     defaults = 0;
>               } else if (strcmp(argv[i], "-cons") == 0) {
>                       connectors = 1;
>                       modes = 1;
> +                     defaults = 0;
>               } else if (strcmp(argv[i], "-modes") == 0) {
>                       connectors = 1;
>                       modes = 1;
> +                     defaults = 0;
>               } else if (strcmp(argv[i], "-full") == 0) {
>                       connectors = 1;
>                       modes = 1;
>                       full_modes = 1;
> +                     defaults = 0;
>               } else if (strcmp(argv[i], "-props") == 0) {
>                       connectors = 1;
>                       full_props = 1;
> +                     defaults = 0;
>               } else if (strcmp(argv[i], "-edids") == 0) {
>                       connectors = 1;
>                       edid = 1;
> +                     defaults = 0;
>               } else if (strcmp(argv[i], "-encoders") == 0) {
>                       encoders = 1;
> +                     defaults = 0;
>               } else if (strcmp(argv[i], "-v") == 0) {
>                       fbs = 1;
>                       edid = 1;
> @@ -376,10 +387,13 @@ void args(int argc, char **argv)
>                       full_modes = 1;
>                       full_props = 1;
>                       connectors = 1;
> +                     defaults = 0;
> +             } else if (strcmp(argv[i], "-current") == 0) {
> +                     current = 1;
>               }
>       }
>  
> -     if (argc == 2) {
> +     if (defaults) {
>               fbs = 1;
>               edid = 1;
>               crtcs = 1;
> diff --git a/xf86drmMode.c b/xf86drmMode.c
> index 9ea8fe7..57d1dc9 100644
> --- a/xf86drmMode.c
> +++ b/xf86drmMode.c
> @@ -476,19 +476,23 @@ drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t 
> encoder_id)
>  /*
>   * Connector manipulation
>   */
> -
> -drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id)
> +static drmModeConnectorPtr
> +_drmModeGetConnector(int fd, uint32_t connector_id, int probe)
>  {
>       struct drm_mode_get_connector conn, counts;
>       drmModeConnectorPtr r = NULL;
>  
> -retry:
>       memclear(conn);
>       conn.connector_id = connector_id;
> +     if (!probe) {
> +             conn.count_modes = 1;
> +             conn.modes_ptr = VOID2U64(drmMalloc(sizeof(struct 
> drm_mode_modeinfo)));
> +     }
>  
>       if (drmIoctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn))
>               return 0;
>  
> +retry:
>       counts = conn;
>  
>       if (conn.count_props) {
> @@ -504,6 +508,9 @@ retry:
>               conn.modes_ptr = 
> VOID2U64(drmMalloc(conn.count_modes*sizeof(struct drm_mode_modeinfo)));
>               if (!conn.modes_ptr)
>                       goto err_allocs;
> +     } else {
> +             conn.count_modes = 1;
> +             conn.modes_ptr = VOID2U64(drmMalloc(sizeof(struct 
> drm_mode_modeinfo)));
>       }
>  
>       if (conn.count_encoders) {
> @@ -572,6 +579,16 @@ err_allocs:
>       return r;
>  }
>  
> +drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id)
> +{
> +     return _drmModeGetConnector(fd, connector_id, 1);
> +}
> +
> +drmModeConnectorPtr drmModeGetConnectorCurrent(int fd, uint32_t connector_id)
> +{
> +     return _drmModeGetConnector(fd, connector_id, 0);
> +}
> +
>  int drmModeAttachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr 
> mode_info)
>  {
>       struct drm_mode_mode_cmd res;
> diff --git a/xf86drmMode.h b/xf86drmMode.h
> index 856a6bb..278da48 100644
> --- a/xf86drmMode.h
> +++ b/xf86drmMode.h
> @@ -422,10 +422,23 @@ drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t 
> encoder_id);
>   */
>  
>  /**
> - * Retrive information about the connector connectorId.
> + * Retrieve all information about the connector connectorId. This will do a
> + * forced probe on the connector to retrieve remote information such as EDIDs
> + * from the display device.
>   */
>  extern drmModeConnectorPtr drmModeGetConnector(int fd,
> -             uint32_t connectorId);
> +                                            uint32_t connectorId);
> +
> +/**
> + * Retrieve current information, i.e the currently active mode and encoder,
> + * about the connector connectorId. This will not do any probing on the
> + * connector or remote device, and only reports what is currently known.
> + * For the complete set of modes and encoders associated with the connector
> + * use drmModeGetConnector() which will do a probe to determine any display
> + * link changes first.
> + */
> +extern drmModeConnectorPtr drmModeGetConnectorCurrent(int fd,
> +                                                   uint32_t connector_id);
>  
>  /**
>   * Attaches the given mode to an connector.
> -- 
> 2.1.4
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

Reply via email to