qxl: Add red_update_cmd_{new, ref, unref} helpers

Currently, RedUpdateCmd are allocated on the stack, and then
initialized/uninitialized with red_{get,put}_update_cmd
This makes the API inconsistent with what is being done for RedDrawable,
RedCursor and RedMessage. QXLUpdateCmd are not occurring very often,
we can dynamically allocate them instead, and get a consistent API.

Signed-off-by: Christophe Fergeau <cfergeau@redhat.com>
Acked-by: Frediano Ziglio <fziglio@redhat.com>
This commit is contained in:
Christophe Fergeau 2018-11-29 13:50:10 +01:00 committed by Frediano Ziglio
parent 74663be7fc
commit decfe65d73
3 changed files with 48 additions and 14 deletions

View File

@ -1268,9 +1268,8 @@ void red_drawable_unref(RedDrawable *red_drawable)
g_free(red_drawable);
}
bool red_get_update_cmd(QXLInstance *qxl_instance, RedMemSlotInfo *slots,
int group_id, RedUpdateCmd *red,
QXLPHYSICAL addr)
static bool red_get_update_cmd(QXLInstance *qxl_instance, RedMemSlotInfo *slots, int group_id,
RedUpdateCmd *red, QXLPHYSICAL addr)
{
QXLUpdateCmd *qxl;
@ -1288,13 +1287,45 @@ bool red_get_update_cmd(QXLInstance *qxl_instance, RedMemSlotInfo *slots,
return true;
}
void red_put_update_cmd(RedUpdateCmd *red)
static void red_put_update_cmd(RedUpdateCmd *red)
{
if (red->qxl != NULL) {
red_qxl_release_resource(red->qxl, red->release_info_ext);
}
}
RedUpdateCmd *red_update_cmd_new(QXLInstance *qxl, RedMemSlotInfo *slots,
int group_id, QXLPHYSICAL addr)
{
RedUpdateCmd *red;
red = g_new0(RedUpdateCmd, 1);
red->refs = 1;
if (!red_get_update_cmd(qxl, slots, group_id, red, addr)) {
red_update_cmd_unref(red);
return NULL;
}
return red;
}
RedUpdateCmd *red_update_cmd_ref(RedUpdateCmd *red)
{
red->refs++;
return red;
}
void red_update_cmd_unref(RedUpdateCmd *red)
{
if (--red->refs) {
return;
}
red_put_update_cmd(red);
g_free(red);
}
static bool red_get_message(QXLInstance *qxl_instance, RedMemSlotInfo *slots, int group_id,
RedMessage *red, QXLPHYSICAL addr)
{

View File

@ -62,6 +62,7 @@ typedef struct RedDrawable {
typedef struct RedUpdateCmd {
QXLInstance *qxl;
QXLReleaseInfoExt release_info_ext;
int refs;
SpiceRect area;
uint32_t update_id;
uint32_t surface_id;
@ -120,9 +121,10 @@ RedDrawable *red_drawable_new(QXLInstance *qxl, RedMemSlotInfo *slots,
RedDrawable *red_drawable_ref(RedDrawable *drawable);
void red_drawable_unref(RedDrawable *red_drawable);
bool red_get_update_cmd(QXLInstance *qxl, RedMemSlotInfo *slots, int group_id,
RedUpdateCmd *red, QXLPHYSICAL addr);
void red_put_update_cmd(RedUpdateCmd *red);
RedUpdateCmd *red_update_cmd_new(QXLInstance *qxl, RedMemSlotInfo *slots,
int group_id, QXLPHYSICAL addr);
RedUpdateCmd *red_update_cmd_ref(RedUpdateCmd *red);
void red_update_cmd_unref(RedUpdateCmd *red);
RedMessage *red_message_new(QXLInstance *qxl, RedMemSlotInfo *slots,
int group_id, QXLPHYSICAL addr);

View File

@ -213,19 +213,20 @@ static int red_process_display(RedWorker *worker, int *ring_is_empty)
break;
}
case QXL_CMD_UPDATE: {
RedUpdateCmd update;
RedUpdateCmd *update;
if (!red_get_update_cmd(worker->qxl, &worker->mem_slots, ext_cmd.group_id,
&update, ext_cmd.cmd.data)) {
update = red_update_cmd_new(worker->qxl, &worker->mem_slots,
ext_cmd.group_id, ext_cmd.cmd.data);
if (update == NULL) {
break;
}
if (!display_channel_validate_surface(worker->display_channel, update.surface_id)) {
if (!display_channel_validate_surface(worker->display_channel, update->surface_id)) {
spice_warning("Invalid surface in QXL_CMD_UPDATE");
} else {
display_channel_draw(worker->display_channel, &update.area, update.surface_id);
red_qxl_notify_update(worker->qxl, update.update_id);
display_channel_draw(worker->display_channel, &update->area, update->surface_id);
red_qxl_notify_update(worker->qxl, update->update_id);
}
red_put_update_cmd(&update);
red_update_cmd_unref(update);
break;
}
case QXL_CMD_MESSAGE: {