spice: server: add memslots support.

Signed-off-by: Izik Eidus <ieidus@redhat.com>
This commit is contained in:
Izik Eidus 2009-11-21 22:42:38 +02:00 committed by Yaniv Kamay
parent f20e0d3200
commit a70110c4e5
24 changed files with 741 additions and 344 deletions

View File

@ -107,7 +107,7 @@ void Canvas::begin_draw(RedDrawBase& base, int size, size_t min_size)
{
_base = (unsigned long)&base;
_max = _base + size;
set_access_params(_base, _base, _max);
set_access_params(_base, _max);
access_test(&base, min_size);
localalize_ptr(&base.clip.data);
}

View File

@ -213,7 +213,7 @@ public:
virtual CanvasType get_pixmap_type() { return CANVAS_TYPE_INVALID; }
protected:
virtual void set_access_params(ADDRESS delta, unsigned long base, unsigned long max) = 0;
virtual void set_access_params(unsigned long base, unsigned long max) = 0;
virtual void draw_fill(Rect *bbox, Clip *clip, Fill *fill) = 0;
virtual void draw_copy(Rect *bbox, Clip *clip, Copy *copy) = 0;
virtual void draw_opaque(Rect *bbox, Clip *clip, Opaque *opaque) = 0;

View File

@ -108,9 +108,9 @@ void CCanvas::set_mode(int width, int height, int depth, RedWindow *win)
}
}
void CCanvas::set_access_params(ADDRESS delta, unsigned long base, unsigned long max)
void CCanvas::set_access_params(unsigned long base, unsigned long max)
{
canvas_set_access_params(_canvas, delta, base, max);
canvas_set_access_params(_canvas, base, max);
}
void CCanvas::draw_fill(Rect *bbox, Clip *clip, Fill *fill)

View File

@ -46,7 +46,7 @@ public:
virtual CanvasType get_pixmap_type();
protected:
virtual void set_access_params(ADDRESS delta, unsigned long base, unsigned long max);
virtual void set_access_params(unsigned long base, unsigned long max);
virtual void draw_fill(Rect *bbox, Clip *clip, Fill *fill);
virtual void draw_copy(Rect *bbox, Clip *clip, Copy *copy);
virtual void draw_opaque(Rect *bbox, Clip *clip, Opaque *opaque);

View File

@ -91,9 +91,9 @@ void GDICanvas::set_mode(int width, int height, int depth)
}
}
void GDICanvas::set_access_params(ADDRESS delta, unsigned long base, unsigned long max)
void GDICanvas::set_access_params(unsigned long base, unsigned long max)
{
gdi_canvas_set_access_params(_canvas, delta, base, max);
gdi_canvas_set_access_params(_canvas, base, max);
}
void GDICanvas::draw_fill(Rect *bbox, Clip *clip, Fill *fill)

View File

@ -43,7 +43,7 @@ public:
virtual CanvasType get_pixmap_type();
protected:
virtual void set_access_params(ADDRESS delta, unsigned long base, unsigned long max);
virtual void set_access_params(unsigned long base, unsigned long max);
virtual void draw_fill(Rect *bbox, Clip *clip, Fill *fill);
virtual void draw_copy(Rect *bbox, Clip *clip, Copy *copy);
virtual void draw_opaque(Rect *bbox, Clip *clip, Opaque *opaque);

View File

@ -100,9 +100,9 @@ void GCanvas::set_mode(int width, int height, int depth, RedWindow *win,
}
}
void GCanvas::set_access_params(ADDRESS delta, unsigned long base, unsigned long max)
void GCanvas::set_access_params(unsigned long base, unsigned long max)
{
gl_canvas_set_access_params(_canvas, delta, base, max);
gl_canvas_set_access_params(_canvas, base, max);
}
void GCanvas::draw_fill(Rect *bbox, Clip *clip, Fill *fill)

View File

@ -42,7 +42,7 @@ public:
void put_image(const PixmapHeader& image, const Rect& dest,
const QRegion* clip);
void set_access_params(ADDRESS delta, unsigned long base, unsigned long max);
void set_access_params(unsigned long base, unsigned long max);
void draw_fill(Rect *bbox, Clip *clip, Fill *fill);
void draw_copy(Rect *bbox, Clip *clip, Copy *copy);
void draw_opaque(Rect *bbox, Clip *clip, Opaque *opaque);

View File

@ -1569,18 +1569,10 @@ cairo_t *canvas_get_cairo(CairoCanvas *canvas)
}
#ifdef CAIRO_CANVAS_ACCESS_TEST
void canvas_set_access_params(CairoCanvas *canvas, ADDRESS delta, unsigned long base,
unsigned long max)
void canvas_set_access_params(CairoCanvas *canvas, unsigned long base, unsigned long max)
{
__canvas_set_access_params(&canvas->base, delta, base, max);
__canvas_set_access_params(&canvas->base, base, max);
}
#else
void canvas_set_access_params(CairoCanvas *canvas, ADDRESS delta)
{
__canvas_set_access_params(&canvas->base, delta);
}
#endif
void canvas_destroy(CairoCanvas *canvas)
@ -1613,6 +1605,10 @@ CairoCanvas *canvas_create(cairo_t *cairo, int bits
#endif
#ifdef USE_GLZ
, void *glz_decoder_opaque, glz_decode_fn_t glz_decode
#endif
#ifndef CAIRO_CANVAS_NO_CHUNKS
, void *get_virt_opaque, get_virt_fn_t get_virt,
void *validate_virt_opaque, validate_virt_fn_t validate_virt
#endif
)
{
@ -1644,6 +1640,13 @@ CairoCanvas *canvas_create(cairo_t *cairo, int bits
,
glz_decoder_opaque,
glz_decode
#endif
#ifndef CAIRO_CANVAS_NO_CHUNKS
,
get_virt_opaque,
get_virt,
validate_virt_opaque,
validate_virt
#endif
);
canvas->cairo = cairo;

View File

@ -55,10 +55,7 @@ void canvas_group_start(CairoCanvas *canvas, int n_clip_rects, Rect *clip_rects)
void canvas_group_end(CairoCanvas *canvas);
void canvas_set_addr_delta(CairoCanvas *canvas, ADDRESS delta);
#ifdef CAIRO_CANVAS_ACCESS_TEST
void canvas_set_access_params(CairoCanvas *canvas, ADDRESS delta, unsigned long base,
unsigned long max);
#else
void canvas_set_access_params(CairoCanvas *canvas, ADDRESS delta);
void canvas_set_access_params(CairoCanvas *canvas, unsigned long base, unsigned long max);
#endif
cairo_t *canvas_get_cairo(CairoCanvas *canvas);
@ -77,6 +74,10 @@ CairoCanvas *canvas_create(cairo_t *cairo, int bits
#endif
#ifdef USE_GLZ
, void *glz_decoder_opaque, glz_decode_fn_t glz_decode
#endif
#ifndef CAIRO_CANVAS_NO_CHUNKS
, void *get_virt_opaque, get_virt_fn_t get_virt,
void *validate_virt_opaque, validate_virt_fn_t validate_virt
#endif
);
void canvas_destroy(CairoCanvas *canvas);

View File

@ -151,7 +151,10 @@ typedef struct QuicData {
jmp_buf jmp_env;
#ifndef CAIRO_CANVAS_NO_CHUNKS
ADDRESS next;
ADDRESS address_delta;
get_virt_fn_t get_virt;
void *get_virt_opaque;
validate_virt_fn_t validate_virt;
void *validate_virt_opaque;
#endif
char message_buf[512];
} QuicData;
@ -160,7 +163,6 @@ typedef struct CanvasBase {
uint32_t color_shift;
uint32_t color_mask;
QuicData quic_data;
ADDRESS address_delta;
#ifdef CAIRO_CANVAS_ACCESS_TEST
unsigned long base;
unsigned long max;
@ -256,7 +258,6 @@ static cairo_surface_t *canvas_get_quic(CanvasBase *canvas, QUICImage *image, in
tmp = (DataChunk **)image->quic.data;
chunk = *tmp;
quic_data->next = chunk->next;
quic_data->address_delta = canvas->address_delta;
if (quic_decode_begin(quic_data->quic, (uint32_t *)chunk->data, chunk->size >> 2,
&type, &width, &height) == QUIC_ERROR) {
CANVAS_ERROR("quic decode begin failed");
@ -1486,14 +1487,20 @@ static int quic_usr_more_space(QuicUsrContext *usr, uint32_t **io_ptr, int rows_
{
QuicData *quic_data = (QuicData *)usr;
DataChunk *chunk;
uint32_t size;
if (!quic_data->next) {
return 0;
}
chunk = (DataChunk *)GET_ADDRESS(quic_data->next + quic_data->address_delta);
chunk = (DataChunk *)quic_data->get_virt(quic_data->get_virt_opaque, quic_data->next,
sizeof(DataChunk));
size = chunk->size;
quic_data->validate_virt(quic_data->validate_virt_opaque, (unsigned long)chunk->data,
quic_data->next, size);
quic_data->next = chunk->next;
*io_ptr = (uint32_t *)chunk->data;
return chunk->size >> 2;
return size >> 2;
}
#endif
@ -1504,20 +1511,11 @@ static int quic_usr_more_lines(QuicUsrContext *usr, uint8_t **lines)
}
#ifdef CAIRO_CANVAS_ACCESS_TEST
static void __canvas_set_access_params(CanvasBase *canvas, ADDRESS delta, unsigned long base,
unsigned long max)
static void __canvas_set_access_params(CanvasBase *canvas, unsigned long base, unsigned long max)
{
canvas->address_delta = delta;
canvas->base = base;
canvas->max = max;
}
#else
static void __canvas_set_access_params(CanvasBase *canvas, ADDRESS delta)
{
canvas->address_delta = delta;
}
#endif
static void canvas_base_destroy(CanvasBase *canvas)
@ -1550,6 +1548,10 @@ static int canvas_base_init(CanvasBase *canvas, int depth
#endif
#ifdef USE_GLZ
, void *glz_decoder_opaque, glz_decode_fn_t glz_decode
#endif
#ifndef CAIRO_CANVAS_NO_CHUNKS
, void *get_virt_opaque, get_virt_fn_t get_virt,
void *validate_virt_opaque, validate_virt_fn_t validate_virt
#endif
)
{
@ -1560,6 +1562,12 @@ static int canvas_base_init(CanvasBase *canvas, int depth
canvas->quic_data.usr.free = quic_usr_free;
canvas->quic_data.usr.more_space = quic_usr_more_space;
canvas->quic_data.usr.more_lines = quic_usr_more_lines;
#ifndef CAIRO_CANVAS_NO_CHUNKS
canvas->quic_data.get_virt_opaque = get_virt_opaque;
canvas->quic_data.get_virt = get_virt;
canvas->quic_data.validate_virt_opaque = validate_virt_opaque;
canvas->quic_data.validate_virt = validate_virt;
#endif
if (!(canvas->quic_data.quic = quic_create(&canvas->quic_data.usr))) {
return 0;
}

View File

@ -35,6 +35,11 @@ typedef void (*palette_cache_release_fn_t)(Palette *palette);
typedef void (*glz_decode_fn_t)(void *glz_decoder_opaque, uint8_t *data,
Palette *plt, void *usr_data);
#ifndef CAIRO_CANVAS_NO_CHUNKS
typedef void *(*get_virt_fn_t)(void *get_virt_opaque, unsigned long addr, uint32_t add_size);
typedef void (*validate_virt_fn_t)(void *validate_virt_opaque, unsigned long virt,
unsigned long from_addr, uint32_t add_size);
#endif
#endif

View File

@ -1668,18 +1668,10 @@ void gdi_canvas_clear(GdiCanvas *canvas)
}
#ifdef CAIRO_CANVAS_ACCESS_TEST
void gdi_canvas_set_access_params(GdiCanvas *canvas, ADDRESS delta, unsigned long base,
unsigned long max)
void gdi_canvas_set_access_params(GdiCanvas *canvas, unsigned long base, unsigned long max)
{
__canvas_set_access_params(&canvas->base, delta, base, max);
__canvas_set_access_params(&canvas->base, base, max);
}
#else
void gdi_canvas_set_access_params(GdiCanvas *canvas, ADDRESS delta)
{
__gdi_canvas_set_access_params(&canvas->base, delta);
}
#endif
void gdi_canvas_destroy(GdiCanvas *canvas)

View File

@ -54,10 +54,7 @@ void gdi_canvas_put_image(GdiCanvas *canvas, HDC dc, const Rect *dest, const uin
void gdi_canvas_clear(GdiCanvas *canvas);
#ifdef CAIRO_CANVAS_ACCESS_TEST
void gdi_canvas_set_access_params(GdiCanvas *canvas, ADDRESS delta, unsigned long base,
unsigned long max);
#else
void gdi_canvas_set_access_params(GdiCanvas *canvas, ADDRESS delta);
void gdi_canvas_set_access_params(GdiCanvas *canvas, unsigned long base, unsigned long max);
#endif

View File

@ -770,16 +770,9 @@ void gl_canvas_clear_top_mask(GLCanvas *canvas)
}
#ifdef CAIRO_CANVAS_ACCESS_TEST
void gl_canvas_set_access_params(GLCanvas *canvas, ADDRESS delta, unsigned long base,
unsigned long max)
void gl_canvas_set_access_params(GLCanvas *canvas, unsigned long base, unsigned long max)
{
__canvas_set_access_params(&canvas->base, delta, base, max);
}
#else
void gl_canvas_set_access_params(GLCanvas *canvas, ADDRESS delta)
{
__canvas_set_access_params(&canvas->base, delta);
__canvas_set_access_params(&canvas->base, base, max);
}
#endif
@ -810,6 +803,10 @@ GLCanvas *gl_canvas_create(void *usr_data, int width, int height, int depth
#endif
#ifdef USE_GLZ
, void *glz_decoder_opaque, glz_decode_fn_t glz_decode
#endif
#ifndef CAIRO_CANVAS_NO_CHUNKS
, void *get_virt_opaque, get_virt_fn_t get_virt,
void *validate_virt_opaque, validate_virt_fn_t validate_virt
#endif
)
{
@ -847,6 +844,13 @@ GLCanvas *gl_canvas_create(void *usr_data, int width, int height, int depth
,
glz_decoder_opaque,
glz_decode
#endif
#ifndef CAIRO_CANVAS_NO_CHUNKS
,
get_virt_opaque,
get_virt,
validate_virt_opaque,
validate_virt
#endif
);
if (!init_ok) {
@ -882,5 +886,5 @@ void gl_canvas_init() //unsafe global function
return;
}
need_init = 0;
rop3_init();
rop3_init();
}

View File

@ -48,10 +48,7 @@ void gl_canvas_set_top_mask(GLCanvas *canvas, int num_rect, const Rect *rects);
void gl_canvas_clear_top_mask(GLCanvas *canvas);
#ifdef CAIRO_CANVAS_ACCESS_TEST
void gl_canvas_set_access_params(GLCanvas *canvas, ADDRESS delta, unsigned long base,
unsigned long max);
#else
void gl_canvas_set_access_params(GLCanvas *canvas, ADDRESS delta);
void gl_canvas_set_access_params(GLCanvas *canvas, unsigned long base, unsigned long max);
#endif
void *gl_canvas_get_usr_data(GLCanvas *canvas);
@ -75,6 +72,10 @@ GLCanvas *gl_canvas_create(void *usr_data, int width, int height, int depth
#endif
#ifdef USE_GLZ
, void *glz_decoder_opaque, glz_decode_fn_t glz_decode
#endif
#ifndef CAIRO_CANVAS_NO_CHUNKS
, void *get_virt_opaque, get_virt_fn_t get_virt,
void *validate_virt_opaque, validate_virt_fn_t validate_virt
#endif
);
void gl_canvas_destroy(GLCanvas *, int);

View File

@ -52,7 +52,7 @@
#define REDHAT_PCI_VENDOR_ID 0x1b36
#define QXL_DEVICE_ID 0x0100 /* 0x100-0x11f reserved for spice */
#define QXL_REVISION 0x01
#define QXL_REVISION 0x02
#define QXL_ROM_MAGIC (*(UINT32*)"QXRO")
#define QXL_RAM_MAGIC (*(UINT32*)"QXRA")
@ -75,6 +75,8 @@ enum {
QXL_IO_RESET,
QXL_IO_SET_MODE,
QXL_IO_LOG,
QXL_IO_MEMSLOT_ADD,
QXL_IO_MEMSLOT_DEL,
QXL_IO_RANGE_SIZE
};
@ -93,6 +95,12 @@ typedef struct ATTR_PACKED QXLRom {
UINT32 draw_area_size;
UINT32 ram_header_offset;
UINT32 mm_clock;
UINT64 flags;
UINT8 slots_start;
UINT8 slots_end;
UINT8 slot_gen_bits;
UINT8 slot_id_bits;
UINT8 slot_generation;
} QXLRom;
typedef struct ATTR_PACKED QXLMode {
@ -129,6 +137,11 @@ typedef struct ATTR_PACKED QXLCommand {
} QXLCommand;
typedef struct ATTR_PACKED QXLMemSlot {
UINT64 mem_start;
UINT64 mem_end;
} QXLMemSlot;
RING_DECLARE(QXLCommandRing, QXLCommand, 32);
RING_DECLARE(QXLCursorRing, QXLCommand, 32);
@ -148,6 +161,8 @@ typedef struct ATTR_PACKED QXLRam {
QXLCursorRing cursor_ring;
QXLReleaseRing release_ring;
Rect update_area;
QXLMemSlot mem_slot;
UINT64 flags;
} QXLRam;
typedef union QXLReleaseInfo {

View File

@ -2,7 +2,7 @@ AC_PREREQ([2.57])
m4_define([SPICE_MAJOR], 0)
m4_define([SPICE_MINOR], 5)
m4_define([SPICE_MICRO], 0)
m4_define([SPICE_MICRO], 1)
AC_INIT(spice, [SPICE_MAJOR.SPICE_MINOR.SPICE_MICRO], [], spice)

View File

@ -38,13 +38,13 @@
#define ALIGN(a, b) (((a) + ((b) - 1)) & ~((b) - 1))
#endif
#define ASSERT(x) if (!(x)) { \
printf("%s: ASSERT %s failed\n", __FUNCTION__, #x); \
abort(); \
#define ASSERT(x) if (!(x)) { \
printf("%s: ASSERT %s failed\n", __FUNCTION__, #x); \
abort(); \
}
#define PANIC(str) { \
printf("%s: panic: %s\n", __FUNCTION__, str); \
#define PANIC(format, ...) { \
printf("%s: panic: " format "\n", __FUNCTION__, ## __VA_ARGS__ ); \
abort(); \
}

View File

@ -247,6 +247,34 @@ static void qxl_worker_update_area(QXLWorker *qxl_worker)
ASSERT(message == RED_WORKER_MESSAGE_READY);
}
static void qxl_worker_add_memslot(QXLWorker *qxl_worker, QXLDevMemSlot *mem_slot)
{
RedDispatcher *dispatcher = (RedDispatcher *)qxl_worker;
RedWorkeMessage message = RED_WORKER_MESSAGE_ADD_MEMSLOT;
write_message(dispatcher->channel, &message);
send_data(dispatcher->channel, mem_slot, sizeof(QXLDevMemSlot));
read_message(dispatcher->channel, &message);
ASSERT(message == RED_WORKER_MESSAGE_READY);
}
static void qxl_worker_del_memslot(QXLWorker *qxl_worker, uint32_t slot_id)
{
RedDispatcher *dispatcher = (RedDispatcher *)qxl_worker;
RedWorkeMessage message = RED_WORKER_MESSAGE_DEL_MEMSLOT;
write_message(dispatcher->channel, &message);
send_data(dispatcher->channel, &slot_id, sizeof(uint32_t));
}
static void qxl_worker_reset_memslots(QXLWorker *qxl_worker)
{
RedDispatcher *dispatcher = (RedDispatcher *)qxl_worker;
RedWorkeMessage message = RED_WORKER_MESSAGE_RESET_MEMSLOTS;
write_message(dispatcher->channel, &message);
}
static void qxl_worker_wakeup(QXLWorker *qxl_worker)
{
RedDispatcher *dispatcher = (RedDispatcher *)qxl_worker;
@ -386,6 +414,7 @@ RedDispatcher *red_dispatcher_init(QXLInterface *qxl_interface)
int channels[2];
RedWorkeMessage message;
WorkerInitData init_data;
QXLDevInitInfo init_info;
int r;
Channel *reds_channel;
Channel *cursor_channel;
@ -433,6 +462,15 @@ RedDispatcher *red_dispatcher_init(QXLInterface *qxl_interface)
dispatcher->base.start = qxl_worker_start;
dispatcher->base.stop = qxl_worker_stop;
dispatcher->base.update_area = qxl_worker_update_area;
dispatcher->base.add_memslot = qxl_worker_add_memslot;
dispatcher->base.del_memslot = qxl_worker_del_memslot;
dispatcher->base.reset_memslots = qxl_worker_reset_memslots;
qxl_interface->get_init_info(qxl_interface, &init_info);
init_data.memslot_id_bits = init_info.memslot_id_bits;
init_data.memslot_gen_bits = init_info.memslot_gen_bits;
init_data.num_memslots = init_info.num_memslots;
sigfillset(&thread_sig_mask);
sigdelset(&thread_sig_mask, SIGILL);

File diff suppressed because it is too large Load Diff

View File

@ -62,6 +62,9 @@ enum {
RED_WORKER_MESSAGE_SET_COMPRESSION,
RED_WORKER_MESSAGE_SET_STREAMING_VIDEO,
RED_WORKER_MESSAGE_SET_MOUSE_MODE,
RED_WORKER_MESSAGE_ADD_MEMSLOT,
RED_WORKER_MESSAGE_DEL_MEMSLOT,
RED_WORKER_MESSAGE_RESET_MEMSLOTS,
};
typedef uint32_t RedWorkeMessage;
@ -84,6 +87,9 @@ typedef struct WorkerInitData {
uint32_t renderers[RED_MAX_RENDERERS];
image_compression_t image_compression;
int streaming_video;
uint32_t num_memslots;
uint8_t memslot_gen_bits;
uint8_t memslot_id_bits;
} WorkerInitData;
void *red_worker_main(void *arg);

View File

@ -83,8 +83,9 @@ static inline void FUNC_NAME(red_rgb_to_yuv420_line)(const uint8_t* line0, const
}
}
static inline int FUNC_NAME(red_rgb_to_yuv420)(const Rect *src, const Bitmap *image,
AVFrame *frame, long phys_delta, int id,
static inline int FUNC_NAME(red_rgb_to_yuv420)(RedWorker *worker, const Rect *src,
const Bitmap *image, AVFrame *frame,
long phys_delta, int memslot_id, int id,
Stream *stream)
{
QXLDataChunk *chunk;
@ -107,14 +108,16 @@ static inline int FUNC_NAME(red_rgb_to_yuv420)(const Rect *src, const Bitmap *im
const int skip_lines = stream->top_down ? src->top : image->y - (src->bottom - 0);
for (i = 0; i < skip_lines; i++) {
red_get_image_line(&chunk, &offset, image_stride, phys_delta);
red_get_image_line(worker, &chunk, &offset, image_stride, phys_delta, memslot_id);
}
const int image_hight = src->bottom - src->top;
const int image_width = src->right - src->left;
for (i = 0; i < image_hight / 2; i++) {
uint8_t* line0 = red_get_image_line(&chunk, &offset, image_stride, phys_delta);
uint8_t* line1 = red_get_image_line(&chunk, &offset, image_stride, phys_delta);
uint8_t* line0 = red_get_image_line(worker, &chunk, &offset, image_stride, phys_delta,
memslot_id);
uint8_t* line1 = red_get_image_line(worker, &chunk, &offset, image_stride, phys_delta,
memslot_id);
if (!line0 || !line1) {
return FALSE;
@ -131,7 +134,8 @@ static inline int FUNC_NAME(red_rgb_to_yuv420)(const Rect *src, const Bitmap *im
}
if ((image_hight & 1)) {
uint8_t* line = red_get_image_line(&chunk, &offset, image_stride, phys_delta);
uint8_t* line = red_get_image_line(worker, &chunk, &offset, image_stride, phys_delta,
memslot_id);
if (!line) {
return FALSE;
}

View File

@ -93,11 +93,12 @@ struct CoreInterface {
};
#define VD_INTERFACE_QXL "qxl"
#define VD_INTERFACE_QXL_MAJOR 1
#define VD_INTERFACE_QXL_MINOR 2
#define VD_INTERFACE_QXL_MAJOR 2
#define VD_INTERFACE_QXL_MINOR 0
typedef struct QXLInterface QXLInterface;
typedef void (*qxl_mode_change_notifier_t)(void *opaque);
typedef struct QXLWorker QXLWorker;
typedef struct QXLDevMemSlot QXLDevMemSlot;
union QXLReleaseInfo;
struct QXLCommand;
struct QXLWorker {
@ -112,6 +113,9 @@ struct QXLWorker {
void (*start)(QXLWorker *worker);
void (*stop)(QXLWorker *worker);
void (*update_area)(QXLWorker *worker);
void (*add_memslot)(QXLWorker *worker, QXLDevMemSlot *slot);
void (*del_memslot)(QXLWorker *worker, uint32_t slot_id);
void (*reset_memslots)(QXLWorker *worker);
};
typedef struct DrawArea {
@ -124,10 +128,6 @@ typedef struct DrawArea {
} DrawArea;
typedef struct QXLDevInfo {
long phys_delta;
unsigned long phys_start;
unsigned long phys_end;
uint32_t x_res;
uint32_t y_res;
uint32_t bits;
@ -138,6 +138,20 @@ typedef struct QXLDevInfo {
uint32_t ram_size;
} QXLDevInfo;
typedef struct QXLDevInitInfo {
uint32_t num_memslots;
uint8_t memslot_gen_bits;
uint8_t memslot_id_bits;
} QXLDevInitInfo;
struct QXLDevMemSlot {
uint32_t slot_id;
uint32_t generation;
unsigned long virt_start;
unsigned long virt_end;
uint64_t addr_delta;
};
struct QXLInterface {
VDInterface base;
@ -152,6 +166,7 @@ struct QXLInterface {
void *opaque);
void (*unregister_mode_change)(QXLInterface *qxl, VDObjectRef notifier);
void (*get_init_info)(QXLInterface *qxl, QXLDevInitInfo *info);
void (*get_info)(QXLInterface *qxl, QXLDevInfo *info);
int (*get_command)(QXLInterface *qxl, struct QXLCommand *cmd);
int (*req_cmd_notification)(QXLInterface *qxl);