[Spice-devel] [PATCH spice-server 2/3] reds: Factor out a function to build VDAgentGraphicsDeviceInfo message

Christophe Fergeau cfergeau at redhat.com
Mon Feb 4 17:56:47 UTC 2019


Hey,

On Mon, Feb 04, 2019 at 02:27:52PM +0000, Frediano Ziglio wrote:
> Instead of scanning the monitor twice (one to compute the size
> and another to build the message) use a single function.

I'm not sure I'm sold on this approach as this makes everything more
complex ;) If you want to split reds_send_device_display_info(), you can
have 2 distinct helper functions, one to compute the size, the other to
fill the needed data. Or maybe you can have a generic reds_xxx_iterate()
which will call a callback for each qxl and streaming device? And I'd
add a helper to fill a VDAgentDeviceDisplayInfo as some very similar
code is duplicated twice. A few more comments below.


> 
> Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
> ---
>  server/reds.c | 137 ++++++++++++++++++++++++--------------------------
>  1 file changed, 65 insertions(+), 72 deletions(-)
> 
> diff --git a/server/reds.c b/server/reds.c
> index 24047bda..d681d8a9 100644
> --- a/server/reds.c
> +++ b/server/reds.c
> @@ -899,82 +899,48 @@ static RedPipeItem *vdi_port_read_one_msg_from_device(RedCharDevice *self,
>      return NULL;
>  }
>  
> -void reds_send_device_display_info(RedsState *reds)
> +static size_t
> +reds_compute_device_display_info(RedsState *reds, VDAgentGraphicsDeviceInfo *graphics_device_info)
>  {
> -    if (!reds->agent_dev->priv->agent_attached) {
> -        return;
> -    }
> -    g_debug("Sending device display info to the agent:");
> -
> -    QXLInstance *qxl;
> -    RedCharDevice *dev;
> -
> -    size_t message_size = sizeof(VDAgentGraphicsDeviceInfo);
> -
> -    // size for the qxl device info
> -    FOREACH_QXL_INSTANCE(reds, qxl) {
> -        message_size +=
> -            (sizeof(VDAgentDeviceDisplayInfo) + strlen(red_qxl_get_device_address(qxl)) + 1) *
> -            red_qxl_get_monitors_count(qxl);
> -    }
> -
> -    // size for the stream device info
> -    GLIST_FOREACH(reds->char_devices, RedCharDevice, dev) {
> -        if (IS_STREAM_DEVICE(dev)) {
> -            size_t device_address_len =
> -                strlen(stream_device_get_device_display_info(STREAM_DEVICE(dev))->device_address);
> -
> -            if (device_address_len == 0) {
> -                // the device info wasn't set (yet), don't send it
> -                continue;
> -            }
> -
> -            message_size += (sizeof(VDAgentDeviceDisplayInfo) + device_address_len + 1);
> -        }
> -    }
> -
> -    RedCharDeviceWriteBuffer *char_dev_buf = vdagent_new_write_buffer(reds->agent_dev,
> -                                         VD_AGENT_GRAPHICS_DEVICE_INFO,
> -                                         message_size,
> -                                         true);
> -
> -    if (!char_dev_buf) {
> -        reds->pending_device_display_info_message = true;
> -        return;
> +    const bool write = (graphics_device_info != NULL);

I would not introduce that boolean, and use "if
(graphics_device_info != NULL)" the few times it's needed.

> +    if (write) {
> +        graphics_device_info->count = 0;
>      }
>  
> -    VDInternalBuf *internal_buf = (VDInternalBuf *)char_dev_buf->buf;
> -    VDAgentGraphicsDeviceInfo *graphics_device_info = &internal_buf->u.graphics_device_info;
> -    graphics_device_info->count = 0;
> -
>      VDAgentDeviceDisplayInfo *device_display_info = graphics_device_info->display_info;

This method starts with "write = (graphics_device_info != NULL)" so this
looks wrong.


>  
>      // add the qxl devices to the message
> +    QXLInstance *qxl;
>      FOREACH_QXL_INSTANCE(reds, qxl) {
>          for (size_t i = 0; i < red_qxl_get_monitors_count(qxl); ++i) {
> -            device_display_info->channel_id = qxl->id;
> -            device_display_info->monitor_id = i;
> -            device_display_info->device_display_id = red_qxl_get_device_display_ids(qxl)[i];
> +            size_t device_address_len = strlen(red_qxl_get_device_address(qxl));

Probably less confusing as "size_t device_address_len = strlen(red_qxl_get_device_address(qxl)) + 1;"

Christophe

> +            if (write) {
> +                device_display_info->channel_id = qxl->id;
> +                device_display_info->monitor_id = i;
> +                device_display_info->device_display_id = red_qxl_get_device_display_ids(qxl)[i];
>  
> -            strcpy((char*) device_display_info->device_address, red_qxl_get_device_address(qxl));
> +                strcpy((char*) device_display_info->device_address,
> +                       red_qxl_get_device_address(qxl));
>  
> -            device_display_info->device_address_len =
> -                strlen((char*) device_display_info->device_address) + 1;
> +                device_display_info->device_address_len = device_address_len + 1;
>  
> -            g_debug("   (qxl)    channel_id: %u monitor_id: %u, device_address: %s, device_display_id: %u",
> -                    device_display_info->channel_id,
> -                    device_display_info->monitor_id,
> -                    device_display_info->device_address,
> -                    device_display_info->device_display_id);
> +                g_debug("   (qxl)    channel_id: %u monitor_id: %u, device_address: %s, "
> +                        "device_display_id: %u",
> +                        device_display_info->channel_id,
> +                        device_display_info->monitor_id,
> +                        device_display_info->device_address,
> +                        device_display_info->device_display_id);
>  
> -            device_display_info = (VDAgentDeviceDisplayInfo*) ((char*) device_display_info +
> -                    sizeof(VDAgentDeviceDisplayInfo) + device_display_info->device_address_len);
> +                graphics_device_info->count++;
> +            }
>  
> -            graphics_device_info->count++;
> +            device_display_info = (VDAgentDeviceDisplayInfo*) ((char*) device_display_info +
> +                    sizeof(VDAgentDeviceDisplayInfo) + device_address_len + 1);
>          }
>      }
>  
>      // add the stream devices to the message
> +    RedCharDevice *dev;
>      GLIST_FOREACH(reds->char_devices, RedCharDevice, dev) {
>          if (IS_STREAM_DEVICE(dev)) {
>              StreamDevice *stream_dev = STREAM_DEVICE(dev);
> @@ -992,25 +958,52 @@ void reds_send_device_display_info(RedsState *reds)
>                  continue;
>              }
>  
> -            device_display_info->channel_id = channel_id;
> -            device_display_info->monitor_id = info->stream_id;
> -            device_display_info->device_display_id = info->device_display_id;
> +            if (write) {
> +                device_display_info->channel_id = channel_id;
> +                device_display_info->monitor_id = info->stream_id;
> +                device_display_info->device_display_id = info->device_display_id;
>  
> -            strcpy((char*) device_display_info->device_address, info->device_address);
> -            device_display_info->device_address_len = device_address_len + 1;
> +                strcpy((char*) device_display_info->device_address, info->device_address);
> +                device_display_info->device_address_len = device_address_len + 1;
>  
> -            g_debug("   (stream) channel_id: %u monitor_id: %u, device_address: %s, device_display_id: %u",
> -                    device_display_info->channel_id,
> -                    device_display_info->monitor_id,
> -                    device_display_info->device_address,
> -                    device_display_info->device_display_id);
> +                g_debug("   (stream) channel_id: %u monitor_id: %u, device_address: %s, "
> +                        "device_display_id: %u",
> +                        device_display_info->channel_id,
> +                        device_display_info->monitor_id,
> +                        device_display_info->device_address,
> +                        device_display_info->device_display_id);
>  
> -            device_display_info = (VDAgentDeviceDisplayInfo*) ((char*) device_display_info +
> -                    sizeof(VDAgentDeviceDisplayInfo) + device_display_info->device_address_len);
> +                graphics_device_info->count++;
> +            }
>  
> -            graphics_device_info->count++;
> +            device_display_info = (VDAgentDeviceDisplayInfo*) ((char*) device_display_info +
> +                    sizeof(VDAgentDeviceDisplayInfo) + device_address_len + 1);
>          }
>      }
> +    return (char*) device_display_info - (char*) graphics_device_info;
> +}
> +
> +void reds_send_device_display_info(RedsState *reds)
> +{
> +    if (!reds->agent_dev->priv->agent_attached) {
> +        return;
> +    }
> +    g_debug("Sending device display info to the agent:");
> +
> +    size_t message_size = reds_compute_device_display_info(reds, NULL);
> +
> +    RedCharDeviceWriteBuffer *char_dev_buf = vdagent_new_write_buffer(reds->agent_dev,
> +                                         VD_AGENT_GRAPHICS_DEVICE_INFO,
> +                                         message_size,
> +                                         true);
> +
> +    if (!char_dev_buf) {
> +        reds->pending_device_display_info_message = true;
> +        return;
> +    }
> +
> +    VDInternalBuf *internal_buf = (VDInternalBuf *)char_dev_buf->buf;
> +    reds_compute_device_display_info(reds, &internal_buf->u.graphics_device_info);
>  
>      reds->pending_device_display_info_message = false;
>  
> -- 
> 2.20.1
> 
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/spice-devel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/spice-devel/attachments/20190204/ecd6ca5b/attachment.sig>


More information about the Spice-devel mailing list