spice/server/red-parse-qxl.h
Christophe Fergeau b547919190 cursor: Delay release of QXL guest cursor resources
There's an implicit API/ABI contract between QEMU and SPICE that SPICE
will keep the guest QXL resources alive as long as QEMU can hold a
pointer to them. This implicit contract was broken in 1c6e7cf7 "Release
cursor as soon as possible", causing crashes at migration time.
While the proper fix would be in QEMU so that spice-server does not need
to have that kind of knowledge regarding QEMU internal implementation,
this commit reverts to the pre-1c6e7cf7 behaviour to avoid a regression
while QEMU is being fixed.

This version of the fix is based on a suggestion from Frediano Ziglio.

https://bugzilla.redhat.com/show_bug.cgi?id=1540919

Signed-off-by: Christophe Fergeau <cfergeau@redhat.com>
Acked-by: Frediano Ziglio <fziglio@redhat.com>
2018-04-16 11:46:01 +02:00

145 lines
3.9 KiB
C

/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
Copyright (C) 2009,2010 Red Hat, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef RED_PARSE_QXL_H_
#define RED_PARSE_QXL_H_
#include <spice/qxl_dev.h>
#include "red-common.h"
#include "memslot.h"
typedef struct RedDrawable {
int refs;
QXLInstance *qxl;
QXLReleaseInfoExt release_info_ext;
uint32_t surface_id;
uint8_t effect;
uint8_t type;
uint8_t self_bitmap;
SpiceRect self_bitmap_area;
SpiceImage *self_bitmap_image;
SpiceRect bbox;
SpiceClip clip;
uint32_t mm_time;
int32_t surface_deps[3];
SpiceRect surfaces_rects[3];
union {
SpiceFill fill;
SpiceOpaque opaque;
SpiceCopy copy;
SpiceTransparent transparent;
SpiceAlphaBlend alpha_blend;
struct {
SpicePoint src_pos;
} copy_bits;
SpiceBlend blend;
SpiceRop3 rop3;
SpiceStroke stroke;
SpiceText text;
SpiceBlackness blackness;
SpiceInvers invers;
SpiceWhiteness whiteness;
SpiceComposite composite;
} u;
} RedDrawable;
static inline RedDrawable *red_drawable_ref(RedDrawable *drawable)
{
drawable->refs++;
return drawable;
}
void red_drawable_unref(RedDrawable *red_drawable);
typedef struct RedUpdateCmd {
QXLReleaseInfoExt release_info_ext;
SpiceRect area;
uint32_t update_id;
uint32_t surface_id;
} RedUpdateCmd;
typedef struct RedMessage {
QXLReleaseInfoExt release_info_ext;
int len;
uint8_t *data;
} RedMessage;
typedef struct RedSurfaceCreate {
uint32_t format;
uint32_t width;
uint32_t height;
int32_t stride;
uint8_t *data;
} RedSurfaceCreate;
typedef struct RedSurfaceCmd {
QXLReleaseInfoExt release_info_ext;
uint32_t surface_id;
uint8_t type;
uint32_t flags;
union {
RedSurfaceCreate surface_create;
} u;
} RedSurfaceCmd;
typedef struct RedCursorCmd {
QXLInstance *qxl;
QXLReleaseInfoExt release_info_ext;
uint8_t type;
union {
struct {
SpicePoint16 position;
uint8_t visible;
SpiceCursor shape;
} set;
struct {
uint16_t length;
uint16_t frequency;
} trail;
SpicePoint16 position;
} u;
} RedCursorCmd;
void red_get_rect_ptr(SpiceRect *red, const QXLRect *qxl);
bool red_get_drawable(RedMemSlotInfo *slots, int group_id,
RedDrawable *red, QXLPHYSICAL addr, uint32_t flags);
void red_put_drawable(RedDrawable *red);
bool red_get_update_cmd(RedMemSlotInfo *slots, int group_id,
RedUpdateCmd *red, QXLPHYSICAL addr);
void red_put_update_cmd(RedUpdateCmd *red);
bool red_get_message(RedMemSlotInfo *slots, int group_id,
RedMessage *red, QXLPHYSICAL addr);
void red_put_message(RedMessage *red);
bool red_validate_surface(uint32_t width, uint32_t height,
int32_t stride, uint32_t format);
bool red_get_surface_cmd(RedMemSlotInfo *slots, int group_id,
RedSurfaceCmd *red, QXLPHYSICAL addr);
void red_put_surface_cmd(RedSurfaceCmd *red);
bool red_get_cursor_cmd(RedMemSlotInfo *slots, int group_id,
RedCursorCmd *red, QXLPHYSICAL addr);
void red_put_cursor_cmd(RedCursorCmd *red);
#endif /* RED_PARSE_QXL_H_ */