mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2026-01-02 14:28:32 +00:00
spice: server: add memslots support.
Signed-off-by: Izik Eidus <ieidus@redhat.com>
This commit is contained in:
parent
f20e0d3200
commit
a70110c4e5
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
@ -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(); \
|
||||
}
|
||||
|
||||
|
||||
@ -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
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user