From ieidus@redhat.com Tue May 18 11:07:41 2010 Return-Path: ieidus@redhat.com Received: from zmta03.collab.prod.int.phx2.redhat.com (LHLO zmta03.collab.prod.int.phx2.redhat.com) (10.5.5.33) by mail04.corp.redhat.com with LMTP; Tue, 18 May 2010 11:07:41 -0400 (EDT) Received: from localhost (localhost.localdomain [127.0.0.1]) by zmta03.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id CAF6CD8005 for ; Tue, 18 May 2010 11:07:41 -0400 (EDT) Received: from zmta03.collab.prod.int.phx2.redhat.com ([127.0.0.1]) by localhost (zmta03.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 9Mxku8nHh4aR for ; Tue, 18 May 2010 11:07:41 -0400 (EDT) Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by zmta03.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id B7231D8003 for ; Tue, 18 May 2010 11:07:41 -0400 (EDT) Received: from localhost (vpn-6-56.tlv.redhat.com [10.35.6.56]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o4IF7ZHk031049 for ; Tue, 18 May 2010 11:07:36 -0400 Date: Tue, 18 May 2010 21:07:26 +0300 From: Izik Eidus To: alexl@redhat.com Subject: abi patch Message-ID: <20100518210726.4e27899b@redhat.com> Organization: RedHat Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 X-Evolution-Source: imap://alexl@mail.corp.redhat.com/ Content-Transfer-Encoding: 8bit diff --git a/server/Makefile.am b/server/Makefile.am index f121168..8777cbd 100644 --- a/server/Makefile.am +++ b/server/Makefile.am @@ -76,6 +76,8 @@ libspice_server_la_SOURCES = \ red_dispatcher.h \ red_memslots.c \ red_memslots.h \ + red_abi_translate.c \ + red_abi_translate.h \ reds.c \ reds.h \ stat.h \ diff --git a/server/red_abi_translate.c b/server/red_abi_translate.c new file mode 100644 index 0000000..e1892cf --- /dev/null +++ b/server/red_abi_translate.c @@ -0,0 +1,238 @@ +/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* + Copyright (C) 2009,2010 Red Hat, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "red_common.h" +#include "red_memslots.h" +#include "red_abi_translate.h" + +inline void get_red_data_chunk_from_qxl(RedMemSlotInfo *memslots_info, + RedDataChunk *head_red_chunk, QXLDataChunk *chunk, + int memslot_id, int group_id) +{ + RedDataChunk *red_chunk; + + red_chunk = head_red_chunk; + red_chunk->data_size = chunk->data_size; + + validate_virt(memslots_info, (unsigned long)chunk->data, memslot_id, red_chunk->data_size, + group_id); + + red_chunk->prev_chunk = NULL; + red_chunk->data = (uint8_t *)chunk->data; + + while (chunk->next_chunk) { + chunk = (QXLDataChunk *)get_virt(memslots_info, chunk->next_chunk, sizeof(QXLDataChunk), + group_id); + + red_chunk->next_chunk = spice_malloc(sizeof(RedDataChunk)); + red_chunk->next_chunk->data_size = chunk->data_size; + + validate_virt(memslots_info, (unsigned long)chunk->data, memslot_id, red_chunk->data_size, + group_id); + + red_chunk->next_chunk->prev_chunk = red_chunk; + red_chunk = red_chunk->next_chunk; + red_chunk->data = (uint8_t *)chunk->data; + } + + red_chunk->next_chunk = NULL; +} + +inline void get_red_data_chunk_from_address(RedMemSlotInfo *memslots_info, RedDataChunk *red_chunk, + SPICE_ADDRESS chunk_addr, int group_id) +{ + QXLDataChunk *chunk; + + chunk = (QXLDataChunk *)get_virt(memslots_info, chunk_addr, sizeof(QXLDataChunk), + group_id); + get_red_data_chunk_from_qxl(memslots_info, red_chunk, chunk, + get_memslot_id(memslots_info, chunk_addr), group_id); +} + +inline void release_red_data_chunk(RedMemSlotInfo *memslots_info, RedDataChunk *head_red_chunk) +{ + RedDataChunk *red_chunk; + + red_chunk = head_red_chunk->next_chunk; + while (red_chunk) { + RedDataChunk *tmp_chunk; + + tmp_chunk = red_chunk; + red_chunk = red_chunk->next_chunk; + free(tmp_chunk); + } +} + +inline void get_red_cursor_from_qxl(RedMemSlotInfo *memslots_info, RedCursor *red_cursor, + QXLCursor *cursor, int memslot_id, int group_id) +{ + red_cursor->header = cursor->header; + red_cursor->data_size = cursor->data_size; + + get_red_data_chunk_from_qxl(memslots_info, &red_cursor->chunk, &cursor->chunk, + memslot_id, group_id); + +} + + +inline void get_red_cursor_from_address(RedMemSlotInfo *memslots_info, RedCursor *red_cursor, + SPICE_ADDRESS cursor_addr, int group_id) +{ + QXLCursor *cursor; + + cursor = (QXLCursor *)get_virt(memslots_info, cursor_addr, sizeof(QXLCursor), + group_id); + get_red_cursor_from_qxl(memslots_info, red_cursor, cursor, + get_memslot_id(memslots_info, cursor_addr), group_id); +} + +inline void get_red_string_from_qxl(RedMemSlotInfo *memslots_info, RedString *red_string, + QXLString *qstring, int memslot_id, int group_id) +{ + red_string->data_size = qstring->data_size; + red_string->length = qstring->length; + red_string->flags = qstring->flags; + get_red_data_chunk_from_qxl(memslots_info, &red_string->chunk, &qstring->chunk, + memslot_id, group_id); +} + +inline void get_red_string_from_address(RedMemSlotInfo *memslots_info, RedString *red_string, + SPICE_ADDRESS string_addr, int group_id) +{ + QXLString *qstring; + + qstring = (QXLString *)get_virt(memslots_info, string_addr, sizeof(QXLString), + group_id); + get_red_string_from_qxl(memslots_info, red_string, qstring, + get_memslot_id(memslots_info, string_addr), group_id); +} + +inline void get_red_copybits_from_qxl(RedMemSlotInfo *memslots_info, RedCopyBits *red_copybits, + QXLCopyBits *copybits, int memslot_id, int group_id) +{ + red_copybits->src_pos = copybits->src_pos; +} + +inline void get_red_copybits_from_address(RedMemSlotInfo *memslots_info, RedCopyBits *red_copybits, + SPICE_ADDRESS copybits_addr, int group_id) +{ + QXLCopyBits *copybits; + + copybits = (QXLCopyBits *)get_virt(memslots_info, copybits_addr, sizeof(QXLCopyBits), + group_id); + get_red_copybits_from_qxl(memslots_info, red_copybits, copybits, + get_memslot_id(memslots_info, copybits_addr), group_id); +} + +inline void get_red_cliprects_from_qxl(RedMemSlotInfo *memslots_info, RedClipRects *red_cliprects, + QXLClipRects *cliprects, int memslot_id, int group_id) +{ + red_cliprects->num_rects = cliprects->num_rects; + get_red_data_chunk_from_qxl(memslots_info, &red_cliprects->chunk, &cliprects->chunk, + memslot_id, group_id); +} + +inline void get_red_cliprects_from_address(RedMemSlotInfo *memslots_info, RedClipRects *red_cliprects, + SPICE_ADDRESS cliprects_addr, int group_id) +{ + QXLClipRects *cliprects; + + cliprects = (QXLClipRects *)get_virt(memslots_info, cliprects_addr, sizeof(QXLClipRects), + group_id); + get_red_cliprects_from_qxl(memslots_info, red_cliprects, cliprects, + get_memslot_id(memslots_info, cliprects_addr), group_id); +} + + +inline void get_red_path_from_qxl(RedMemSlotInfo *memslots_info, RedPath *red_path, + QXLPath *path, int memslot_id, int group_id) +{ + red_path->data_size = path->data_size; + get_red_data_chunk_from_qxl(memslots_info, &red_path->chunk, &path->chunk, + memslot_id, group_id); +} + +inline void get_red_path_from_address(RedMemSlotInfo *memslots_info, RedPath *red_path, + SPICE_ADDRESS path_addr, int group_id) +{ + QXLPath *path; + + path = (QXLPath *)get_virt(memslots_info, path_addr, sizeof(QXLPath), group_id); + get_red_path_from_qxl(memslots_info, red_path, path, + get_memslot_id(memslots_info, path_addr), group_id); +} + + +inline void get_red_drawable_from_qxl(RedMemSlotInfo *memslots_info, RedDrawable *red_drawable, + QXLDrawable *drawable, int group_id) +{ + int x; + + red_drawable->bbox = drawable->bbox; + red_drawable->clip = drawable->clip; + red_drawable->effect = drawable->effect; + red_drawable->mm_time = drawable->mm_time; + red_drawable->release_info = drawable->release_info; + red_drawable->self_bitmap = drawable->self_bitmap; + red_drawable->self_bitmap_area = drawable->self_bitmap_area; + red_drawable->surface_id = drawable->surface_id; + + for (x = 0; x < 3; ++x) { + red_drawable->surfaces_dest[x] = drawable->surfaces_dest[x]; + red_drawable->surfaces_rects[x] = drawable->surfaces_rects[x]; + } + + red_drawable->type = drawable->type; + switch (red_drawable->type) { + case QXL_DRAW_ALPHA_BLEND: + red_drawable->u.alpha_blend = drawable->u.alpha_blend; + break; + case QXL_DRAW_BLACKNESS: + red_drawable->u.blackness = drawable->u.blackness; + break; + case QXL_DRAW_BLEND: + red_drawable->u.blend = drawable->u.blend; + break; + case QXL_DRAW_COPY: + red_drawable->u.copy = drawable->u.copy; + break; + case QXL_DRAW_FILL: + red_drawable->u.fill = drawable->u.fill; + break; + case QXL_DRAW_INVERS: + red_drawable->u.invers = drawable->u.invers; + break; + case QXL_DRAW_NOP: + break; + case QXL_DRAW_ROP3: + red_drawable->u.rop3 = drawable->u.rop3; + break; + case QXL_DRAW_STROKE: + red_drawable->u.stroke = drawable->u.stroke; + break; + case QXL_DRAW_TEXT: + red_drawable->u.text = drawable->u.text; + break; + case QXL_DRAW_TRANSPARENT: + red_drawable->u.transparent = drawable->u.transparent; + break; + case QXL_DRAW_WHITENESS: + red_drawable->u.whiteness = drawable->u.whiteness; + break; + }; +} diff --git a/server/red_abi_translate.h b/server/red_abi_translate.h new file mode 100644 index 0000000..e38382a --- /dev/null +++ b/server/red_abi_translate.h @@ -0,0 +1,130 @@ +/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* + Copyright (C) 2009,2010 Red Hat, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef RED_ABI_TRANSLATE_H +#define RED_ABI_TRANSLATE_H + +#include +#include +#include "red_common.h" +#include "red_memslots.h" + + +typedef struct RedDataChunk { + uint32_t data_size; + struct RedDataChunk *prev_chunk; + struct RedDataChunk *next_chunk; + uint8_t *data; +} RedDataChunk; + +typedef struct RedCursor { + SpiceCursorHeader header; + uint32_t data_size; + RedDataChunk chunk; +} RedCursor; + +typedef struct RedString { + uint32_t data_size; + uint16_t length; + uint16_t flags; + RedDataChunk chunk; +} RedString; + +typedef struct RedCopyBits { + SpicePoint src_pos; +} RedCopyBits; + +typedef struct SPICE_ATTR_PACKED RedDrawable { + QXLReleaseInfo release_info; + uint32_t surface_id; + uint8_t effect; + uint8_t type; + uint8_t self_bitmap; + SpiceRect self_bitmap_area; + SpiceRect bbox; + SpiceClip clip; + uint32_t mm_time; + int32_t surfaces_dest[3]; + SpiceRect surfaces_rects[3]; + union { + SpiceFill fill; + SpiceOpaque opaque; + SpiceCopy copy; + SpiceTransparent transparent; + SpiceAlphaBlnd alpha_blend; + QXLCopyBits copy_bits; + SpiceBlend blend; + SpiceRop3 rop3; + SpiceStroke stroke; + SpiceText text; + SpiceBlackness blackness; + SpiceInvers invers; + SpiceWhiteness whiteness; + } u; +} RedDrawable; + +typedef struct RedClipRects { + uint32_t num_rects; + RedDataChunk chunk; +} RedClipRects; + +typedef struct RedPath { + uint32_t data_size; + RedDataChunk chunk; +} RedPath; + +inline void get_red_data_chunk_from_qxl(RedMemSlotInfo *memslots_info, + RedDataChunk *head_red_chunk, QXLDataChunk *chunk, + int memslot_id, int group_id); + +inline void get_red_data_chunk_from_address(RedMemSlotInfo *memslots_info, RedDataChunk *red_chunk, + SPICE_ADDRESS chunck_addr, int group_id); + +inline void release_red_data_chunk(RedMemSlotInfo *memslots_info, RedDataChunk *head_red_chunk); + +inline void get_red_cursor_from_qxl(RedMemSlotInfo *memslots_info, RedCursor *red_cursor, + QXLCursor *cursor, int memslot_id, int group_id); + +inline void get_red_cursor_from_address(RedMemSlotInfo *memslots_info, RedCursor *red_cursor, + SPICE_ADDRESS cursor_addr, int group_id); + +inline void get_red_string_from_qxl(RedMemSlotInfo *memslots_info, RedString *red_string, + QXLString *qstring, int memslot_id, int group_id); + +inline void get_red_copybits_from_qxl(RedMemSlotInfo *memslots_info, RedCopyBits *red_copybits, + QXLCopyBits *copybits, int memslot_id, int group_id); + +inline void get_red_string_from_address(RedMemSlotInfo *memslots_info, RedString *red_string, + SPICE_ADDRESS string_addr, int group_id); + +inline void get_red_cliprects_from_qxl(RedMemSlotInfo *memslots_info, RedClipRects *red_cliprects, + QXLClipRects *cliprects, int memslot_id, int group_id); + +inline void get_red_cliprects_from_address(RedMemSlotInfo *memslots_info, RedClipRects *red_cliprects, + SPICE_ADDRESS cliprects_addr, int group_id); + +inline void get_red_path_from_qxl(RedMemSlotInfo *memslots_info, RedPath *red_path, + QXLPath *path, int memslot_id, int group_id); + +inline void get_red_path_from_address(RedMemSlotInfo *memslots_info, RedPath *red_path, + SPICE_ADDRESS path_addr, int group_id); + +inline void get_red_drawable_from_qxl(RedMemSlotInfo *memslots_info, RedDrawable *red_drawable, + QXLDrawable *drawable, int group_id); + +#endif diff --git a/server/red_worker.c b/server/red_worker.c index 6f72419..327af2c 100644 --- a/server/red_worker.c +++ b/server/red_worker.c @@ -48,6 +48,7 @@ #include "ring.h" #include "mjpeg_encoder.h" #include "red_memslots.h" +#include "red_abi_translate.h" //#define COMPRESS_STAT //#define DUMP_BITMAP @@ -213,12 +214,16 @@ enum { BUF_TYPE_CHUNK, }; +struct RedWorker; + +typedef void (*release_buf_opaque_proc)(struct RedWorker *worker, void *opaque); + typedef struct BufDescriptor { uint32_t type; uint32_t size; uint8_t *data; - uint32_t slot_id; - uint32_t group_id; + release_buf_opaque_proc release_function; + void *release_opaque; } BufDescriptor; enum { @@ -592,7 +597,7 @@ typedef struct GlzDrawableInstanceItem { struct RedGlzDrawable { RingItem link; // ordered by the time it was encoded RingItem surface_link; - QXLDrawable *qxl_drawable; + RedDrawable *red_drawable; Drawable *drawable; uint32_t group_id; int32_t surface_id; @@ -817,7 +822,7 @@ struct Drawable { #ifdef UPDATE_AREA_BY_TREE RingItem collect_link; #endif - QXLDrawable *qxl_drawable; + RedDrawable *red_drawable; RedGlzDrawable *red_glz_drawable; @@ -1150,7 +1155,7 @@ char *draw_type_to_str(uint8_t type) } } -static void show_qxl_drawable(RedWorker *worker, QXLDrawable *drawable, const char *prefix) +static void show_qxl_drawable(RedWorker *worker, RedDrawable *drawable, const char *prefix) { if (prefix) { printf("%s: ", prefix); @@ -1524,7 +1529,7 @@ static inline void set_surface_release_info(RedWorker *worker, uint32_t surface_ surface->release_group_id = group_id; } -static inline void free_qxl_drawable(RedWorker *worker, QXLDrawable *drawable, uint32_t group_id, +static inline void free_qxl_drawable(RedWorker *worker, RedDrawable *drawable, uint32_t group_id, uint8_t *self_bitmap, int surface_id) { QXLReleaseInfoExt release_info_ext; @@ -1536,6 +1541,7 @@ static inline void free_qxl_drawable(RedWorker *worker, QXLDrawable *drawable, u release_info_ext.group_id = group_id; release_info_ext.info = &drawable->release_info; worker->qxl->release_resource(worker->qxl, release_info_ext); + free(drawable); } static void remove_depended_item(DependItem *item) @@ -1592,7 +1598,7 @@ static inline void release_drawable(RedWorker *worker, Drawable *item) if (item->red_glz_drawable) { item->red_glz_drawable->drawable = NULL; } else { // no refernce to the qxl drawable left - free_qxl_drawable(worker, item->qxl_drawable, item->group_id, item->self_bitmap, + free_qxl_drawable(worker, item->red_drawable, item->group_id, item->self_bitmap, item->surface_id); } free_drawable(worker, item); @@ -1653,10 +1659,10 @@ static inline void red_add_item_trace(RedWorker *worker, Drawable *item) trace->frames_count = item->frames_count; trace->gradual_frames_count = item->gradual_frames_count; trace->last_gradual_frame = item->last_gradual_frame; - SpiceRect* src_area = &item->qxl_drawable->u.copy.src_area; + SpiceRect* src_area = &item->red_drawable->u.copy.src_area; trace->width = src_area->right - src_area->left; trace->height = src_area->bottom - src_area->top; - trace->dest_area = item->qxl_drawable->bbox; + trace->dest_area = item->red_drawable->bbox; } #endif @@ -1675,7 +1681,7 @@ static void red_flush_source_surfaces(RedWorker *worker, Drawable *drawable) surface_id = drawable->surfaces_dest[x]; if (surface_id != -1 && drawable->depend_items[x].drawable) { remove_depended_item(&drawable->depend_items[x]); - surface_flush(worker, surface_id, &drawable->qxl_drawable->surfaces_rects[x]); + surface_flush(worker, surface_id, &drawable->red_drawable->surfaces_rects[x]); } } } @@ -2211,10 +2217,10 @@ static inline void __current_add_drawable(RedWorker *worker, Drawable *drawable, static int is_equal_path(RedWorker *worker, SPICE_ADDRESS p1, SPICE_ADDRESS p2, uint32_t group_id1, uint32_t group_id2) { - QXLPath *path1; - QXLPath *path2; - QXLDataChunk *chunk1; - QXLDataChunk *chunk2; + RedPath path1; + RedPath path2; + RedDataChunk *chunk1; + RedDataChunk *chunk2; uint8_t *data1; uint8_t *data2; int size; @@ -2223,19 +2229,21 @@ static int is_equal_path(RedWorker *worker, SPICE_ADDRESS p1, SPICE_ADDRESS p2, ASSERT(p1 && p2); - path1 = (QXLPath *)get_virt(&worker->mem_slots, p1, sizeof(QXLPath), group_id1); - path2 = (QXLPath *)get_virt(&worker->mem_slots, p2, sizeof(QXLPath), group_id2); + get_red_path_from_address(&worker->mem_slots, &path1, p1, group_id1); + get_red_path_from_address(&worker->mem_slots, &path2, p2, group_id2); - if ((size = path1->data_size) != path2->data_size) { + if ((size = path1.data_size) != path2.data_size) { + release_red_data_chunk(&worker->mem_slots, &path1.chunk); + release_red_data_chunk(&worker->mem_slots, &path2.chunk); return FALSE; } ASSERT(size); - chunk1 = &path1->chunk; + chunk1 = &path1.chunk; size1 = chunk1->data_size; data1 = chunk1->data; - chunk2 = &path2->chunk; + chunk2 = &path2.chunk; size2 = chunk2->data_size; data2 = chunk2->data; @@ -2243,15 +2251,18 @@ static int is_equal_path(RedWorker *worker, SPICE_ADDRESS p1, SPICE_ADDRESS p2, int now = MIN(size1, size2); ASSERT(now); if (memcmp(data1, data2, now)) { + release_red_data_chunk(&worker->mem_slots, &path1.chunk); + release_red_data_chunk(&worker->mem_slots, &path2.chunk); return FALSE; } if (!(size -= now)) { + release_red_data_chunk(&worker->mem_slots, &path1.chunk); + release_red_data_chunk(&worker->mem_slots, &path2.chunk); return TRUE; } if ((size1 -= now) == 0) { ASSERT(chunk1->next_chunk) - chunk1 = (QXLDataChunk *)get_virt(&worker->mem_slots, chunk1->next_chunk, sizeof(QXLDataChunk), - group_id1); + chunk1 = chunk1->next_chunk; size1 = chunk1->data_size; data1 = chunk1->data; } else { @@ -2260,14 +2271,15 @@ static int is_equal_path(RedWorker *worker, SPICE_ADDRESS p1, SPICE_ADDRESS p2, if ((size2 -= now) == 0) { ASSERT(chunk2->next_chunk) - chunk2 = (QXLDataChunk *)get_virt(&worker->mem_slots, chunk2->next_chunk, sizeof(QXLDataChunk), - group_id2); + chunk2 = chunk2->next_chunk; size2 = chunk2->data_size; data2 = chunk2->data; } else { data2 += now; } } + release_red_data_chunk(&worker->mem_slots, &path1.chunk); + release_red_data_chunk(&worker->mem_slots, &path2.chunk); } // partial imp @@ -2294,19 +2306,19 @@ static inline int rect_is_equal(const SpiceRect *r1, const SpiceRect *r2) // partial imp static int is_same_geometry(RedWorker *worker, Drawable *d1, Drawable *d2) { - if (d1->qxl_drawable->type != d2->qxl_drawable->type) { + if (d1->red_drawable->type != d2->red_drawable->type) { return FALSE; } - switch (d1->qxl_drawable->type) { + switch (d1->red_drawable->type) { case QXL_DRAW_STROKE: - return is_equal_line_attr(&d1->qxl_drawable->u.stroke.attr, - &d2->qxl_drawable->u.stroke.attr) && - is_equal_path(worker, d1->qxl_drawable->u.stroke.path, - d2->qxl_drawable->u.stroke.path, d1->group_id, + return is_equal_line_attr(&d1->red_drawable->u.stroke.attr, + &d2->red_drawable->u.stroke.attr) && + is_equal_path(worker, d1->red_drawable->u.stroke.path, + d2->red_drawable->u.stroke.path, d1->group_id, d2->group_id); case QXL_DRAW_FILL: - return rect_is_equal(&d1->qxl_drawable->bbox, &d2->qxl_drawable->bbox); + return rect_is_equal(&d1->red_drawable->bbox, &d2->red_drawable->bbox); default: return FALSE; } @@ -2318,11 +2330,11 @@ static int is_same_drawable(RedWorker *worker, Drawable *d1, Drawable *d2) return FALSE; } - switch (d1->qxl_drawable->type) { + switch (d1->red_drawable->type) { case QXL_DRAW_STROKE: - return is_equal_brush(&d1->qxl_drawable->u.stroke.brush, &d2->qxl_drawable->u.stroke.brush); + return is_equal_brush(&d1->red_drawable->u.stroke.brush, &d2->red_drawable->u.stroke.brush); case QXL_DRAW_FILL: - return is_equal_brush(&d1->qxl_drawable->u.fill.brush, &d2->qxl_drawable->u.fill.brush); + return is_equal_brush(&d1->red_drawable->u.fill.brush, &d2->red_drawable->u.fill.brush); default: return FALSE; } @@ -2377,7 +2389,7 @@ static void push_stream_clip_by_drawable(DisplayChannel* channel, StreamAgent *a PANIC("alloc failed"); } - if (drawable->qxl_drawable->clip.type == SPICE_CLIP_TYPE_NONE) { + if (drawable->red_drawable->clip.type == SPICE_CLIP_TYPE_NONE) { item->n_rects = 0; item->rects = NULL; item->clip_type = SPICE_CLIP_TYPE_NONE; @@ -2697,8 +2709,8 @@ static void red_create_stream(RedWorker *worker, Drawable *drawable) return; } - ASSERT(drawable->qxl_drawable->type == QXL_DRAW_COPY); - src_rect = &drawable->qxl_drawable->u.copy.src_area; + ASSERT(drawable->red_drawable->type == QXL_DRAW_COPY); + src_rect = &drawable->red_drawable->u.copy.src_area; stream_width = SPICE_ALIGN(src_rect->right - src_rect->left, 2); stream_height = SPICE_ALIGN(src_rect->bottom - src_rect->top, 2); @@ -2710,11 +2722,11 @@ static void red_create_stream(RedWorker *worker, Drawable *drawable) stream->last_time = drawable->creation_time; stream->width = src_rect->right - src_rect->left; stream->height = src_rect->bottom - src_rect->top; - stream->dest_area = drawable->qxl_drawable->bbox; + stream->dest_area = drawable->red_drawable->bbox; #endif stream->refs = 1; stream->bit_rate = get_bit_rate(stream_width, stream_height); - QXLImage *qxl_image = (QXLImage *)get_virt(&worker->mem_slots, drawable->qxl_drawable->u.copy.src_bitmap, + QXLImage *qxl_image = (QXLImage *)get_virt(&worker->mem_slots, drawable->red_drawable->u.copy.src_bitmap, sizeof(QXLImage), drawable->group_id); stream->top_down = !!(qxl_image->bitmap.flags & SPICE_BITMAP_FLAGS_TOP_DOWN); drawable->stream = stream; @@ -2781,14 +2793,14 @@ static inline int __red_is_next_stream_frame(RedWorker *worker, const red_time_t other_time, const Stream *stream) { - QXLDrawable *qxl_drawable; + RedDrawable *qxl_drawable; if (candidate->creation_time - other_time > (stream ? RED_STREAM_CONTINUS_MAX_DELTA : RED_STREAM_DETACTION_MAX_DELTA)) { return FALSE; } - qxl_drawable = candidate->qxl_drawable; + qxl_drawable = candidate->red_drawable; if (!rect_is_equal(&qxl_drawable->bbox, other_dest)) { return FALSE; @@ -2817,10 +2829,10 @@ static inline int red_is_next_stream_frame(RedWorker *worker, const Drawable *ca return FALSE; } - SpiceRect* prev_src = &prev->qxl_drawable->u.copy.src_area; + SpiceRect* prev_src = &prev->red_drawable->u.copy.src_area; return __red_is_next_stream_frame(worker, candidate, prev_src->right - prev_src->left, prev_src->bottom - prev_src->top, - &prev->qxl_drawable->bbox, prev->creation_time, + &prev->red_drawable->bbox, prev->creation_time, prev->stream); } @@ -2829,16 +2841,16 @@ static inline int red_is_next_stream_frame(RedWorker *worker, const Drawable *ca static inline int red_is_next_stream_frame(RedWorker *worker, Drawable *candidate, Drawable *prev) { QXLImage *qxl_image; - QXLDrawable *qxl_drawable; - QXLDrawable *prev_qxl_drawable; + RedDrawable *qxl_drawable; + RedDrawable *prev_qxl_drawable; if (candidate->creation_time - prev->creation_time > ((prev->stream) ? RED_STREAM_CONTINUS_MAX_DELTA : RED_STREAM_DETACTION_MAX_DELTA)) { return FALSE; } - qxl_drawable = candidate->qxl_drawable; - prev_qxl_drawable = prev->qxl_drawable; + qxl_drawable = candidate->red_drawable; + prev_qxl_drawable = prev->red_drawable; if (qxl_drawable->type != QXL_DRAW_COPY || prev_qxl_drawable->type != QXL_DRAW_COPY) { return FALSE; } @@ -2923,7 +2935,7 @@ static inline void pre_stream_item_swap(RedWorker *worker, Stream *stream) static inline void red_update_copy_graduality(RedWorker* worker, Drawable *drawable) { QXLImage *qxl_image; - ASSERT(drawable->qxl_drawable->type == QXL_DRAW_COPY); + ASSERT(drawable->red_drawable->type == QXL_DRAW_COPY); if (worker->streaming_video != STREAM_VIDEO_FILTER) { drawable->copy_bitmap_graduality = BITMAP_GRADUAL_INVALID; @@ -2934,7 +2946,7 @@ static inline void red_update_copy_graduality(RedWorker* worker, Drawable *drawa return; // already set } - qxl_image = (QXLImage *)get_virt(&worker->mem_slots, drawable->qxl_drawable->u.copy.src_bitmap, + qxl_image = (QXLImage *)get_virt(&worker->mem_slots, drawable->red_drawable->u.copy.src_bitmap, sizeof(QXLImage), drawable->group_id); if (!BITMAP_FMT_IS_RGB[qxl_image->bitmap.format] || _stride_is_extra(&qxl_image->bitmap) || @@ -3458,14 +3470,14 @@ static inline int red_current_add_with_shadow(RedWorker *worker, Ring *ring, Dra return TRUE; } -static inline int has_shadow(QXLDrawable *drawable) +static inline int has_shadow(RedDrawable *drawable) { return drawable->type == QXL_COPY_BITS; } #ifdef STREAM_TRACE static inline void red_update_streamable(RedWorker *worker, Drawable *drawable, - QXLDrawable *qxl_drawable) + RedDrawable *qxl_drawable) { QXLImage *qxl_image; @@ -3489,7 +3501,7 @@ static inline void red_update_streamable(RedWorker *worker, Drawable *drawable, SpiceRect* rect; int size; - rect = &drawable->qxl_drawable->u.copy.src_area; + rect = &drawable->red_drawable->u.copy.src_area; size = (rect->right - rect->left) * (rect->bottom - rect->top); if (size < RED_STREAM_MIN_SIZE) { return; @@ -3502,7 +3514,7 @@ static inline void red_update_streamable(RedWorker *worker, Drawable *drawable, #endif static inline int red_current_add_qxl(RedWorker *worker, Ring *ring, Drawable *drawable, - QXLDrawable *qxl_drawable) + RedDrawable *qxl_drawable) { int ret; @@ -3572,15 +3584,15 @@ static inline int red_handle_self_bitmap(RedWorker *worker, Drawable *drawable) int dest_stride; RedSurface *surface; - if (!drawable->qxl_drawable->self_bitmap) { + if (!drawable->red_drawable->self_bitmap) { return TRUE; } surface = &worker->surfaces[drawable->surface_id]; - width = drawable->qxl_drawable->bbox.right - drawable->qxl_drawable->bbox.left; - height = drawable->qxl_drawable->bbox.bottom - drawable->qxl_drawable->bbox.top; + width = drawable->red_drawable->bbox.right - drawable->red_drawable->bbox.left; + height = drawable->red_drawable->bbox.bottom - drawable->red_drawable->bbox.top; dest_stride = width * sizeof(uint32_t); image = spice_malloc_n_m(height, dest_stride, sizeof(QXLImage)); @@ -3600,7 +3612,7 @@ static inline int red_handle_self_bitmap(RedWorker *worker, Drawable *drawable) image->bitmap.palette = 0; red_get_area(worker, drawable->surface_id, - &drawable->qxl_drawable->self_bitmap_area, dest, dest_stride, TRUE); + &drawable->red_drawable->self_bitmap_area, dest, dest_stride, TRUE); drawable->self_bitmap = (uint8_t *)image; return TRUE; @@ -3651,7 +3663,10 @@ static Drawable *get_drawable(RedWorker *worker, uint8_t effect, QXLDrawable *qx region_init(&drawable->tree_item.base.rgn); drawable->tree_item.effect = effect; red_pipe_item_init(&drawable->pipe_item, PIPE_ITEM_TYPE_DRAW); - drawable->qxl_drawable = qxl_drawable; + + drawable->red_drawable = spice_malloc(sizeof(RedDrawable)); + + get_red_drawable_from_qxl(&worker->mem_slots, drawable->red_drawable, qxl_drawable, group_id); drawable->group_id = group_id; drawable->surface_id = qxl_drawable->surface_id; @@ -3677,7 +3692,7 @@ static inline int red_handle_depends_on_target_surface(RedWorker *worker, uint32 Drawable *drawable; DependItem *depended_item = SPICE_CONTAINEROF(ring_item, DependItem, ring_item); drawable = depended_item->drawable; - surface_flush(worker, drawable->surface_id, &drawable->qxl_drawable->bbox); + surface_flush(worker, drawable->surface_id, &drawable->red_drawable->bbox); } return TRUE; @@ -3738,24 +3753,25 @@ static inline void red_process_drawable(RedWorker *worker, QXLDrawable *drawable worker->surfaces[surface_id].refs++; - region_add(&item->tree_item.base.rgn, &drawable->bbox); + region_add(&item->tree_item.base.rgn, &item->red_drawable->bbox); #ifdef PIPE_DEBUG printf("TEST: DRAWABLE: id %u type %s effect %u bbox %u %u %u %u\n", item->tree_item.base.id, - draw_type_to_str(drawable->type), + draw_type_to_str(item->red_drawable->type), item->tree_item.effect, - drawable->bbox.top, drawable->bbox.left, drawable->bbox.bottom, drawable->bbox.right); + item->red_drawable->bbox.top, item->red_drawable->bbox.left, + item->rad_drawable->bbox.bottom, item->red_drawable->bbox.right); #endif - if (drawable->clip.type == SPICE_CLIP_TYPE_RECTS) { + if (item->red_drawable->clip.type == SPICE_CLIP_TYPE_RECTS) { QRegion rgn; region_init(& rgn); - add_clip_rects(worker, &rgn, drawable->clip.data + SPICE_OFFSETOF(QXLClipRects, chunk), group_id); + add_clip_rects(worker, &rgn, item->red_drawable->clip.data + SPICE_OFFSETOF(QXLClipRects, chunk), group_id); region_and(&item->tree_item.base.rgn, &rgn); region_destroy(&rgn); - } else if (drawable->clip.type == SPICE_CLIP_TYPE_PATH) { + } else if (item->red_drawable->clip.type == SPICE_CLIP_TYPE_PATH) { item->tree_item.effect = QXL_EFFECT_BLEND; #ifdef PIPE_DEBUG printf("TEST: DRAWABLE: QXL_CLIP_TYPE_PATH\n"); @@ -3785,7 +3801,7 @@ static inline void red_process_drawable(RedWorker *worker, QXLDrawable *drawable } if (red_current_add_qxl(worker, &worker->surfaces[surface_id].current, item, - drawable)) { + item->red_drawable)) { worker->drawable_count++; if (item->tree_item.effect != QXL_EFFECT_OPAQUE) { worker->transparent_count++; @@ -3846,27 +3862,26 @@ static inline void red_process_surface(RedWorker *worker, QXLSurfaceCmd *surface static void localize_path(RedWorker *worker, QXLPHYSICAL *in_path, uint32_t group_id) { - QXLPath *path; + RedPath path; uint8_t *data; uint32_t data_size; - QXLDataChunk *chunk; - int memslot_id = get_memslot_id(&worker->mem_slots, *in_path); + RedDataChunk *chunk; ASSERT(in_path && *in_path); - path = (QXLPath *)get_virt(&worker->mem_slots, *in_path, sizeof(QXLPath), group_id); - data = spice_malloc_n_m(1, path->data_size, sizeof(uint32_t)); + get_red_path_from_address(&worker->mem_slots, &path, *in_path, group_id); + data = spice_malloc_n_m(1, path.data_size, sizeof(uint32_t)); *in_path = (QXLPHYSICAL)data; - *(uint32_t *)data = path->data_size; + *(uint32_t *)data = path.data_size; data += sizeof(uint32_t); - chunk = &path->chunk; + chunk = &path.chunk; do { data_size = chunk->data_size; - validate_virt(&worker->mem_slots, (unsigned long)chunk->data, memslot_id, data_size, group_id); memcpy(data, chunk->data, data_size); data += data_size; - chunk = chunk->next_chunk ? (QXLDataChunk *)get_virt(&worker->mem_slots, chunk->next_chunk, - sizeof(QXLDataChunk), group_id) : NULL; + chunk = chunk->next_chunk; } while (chunk); + + release_red_data_chunk(&worker->mem_slots, &path.chunk); } static void unlocalize_path(QXLPHYSICAL *path) @@ -3878,34 +3893,31 @@ static void unlocalize_path(QXLPHYSICAL *path) static void localize_str(RedWorker *worker, QXLPHYSICAL *in_str, uint32_t group_id) { - QXLString *qxl_str = (QXLString *)get_virt(&worker->mem_slots, *in_str, sizeof(QXLString), group_id); - QXLDataChunk *chunk; + RedString red_str; + RedDataChunk *chunk; SpiceString *str; uint8_t *dest; uint32_t data_size; - int memslot_id = get_memslot_id(&worker->mem_slots, *in_str); + get_red_string_from_address(&worker->mem_slots, &red_str, *in_str, group_id); ASSERT(in_str); - str = spice_malloc_n_m(1, qxl_str->data_size, sizeof(uint32_t)); + str = spice_malloc_n_m(1, red_str.data_size, sizeof(uint32_t)); *in_str = (QXLPHYSICAL)str; - str->length = qxl_str->length; - str->flags = qxl_str->flags; + str->length = red_str.length; + str->flags = red_str.flags; dest = str->data; - chunk = &qxl_str->chunk; + chunk = &red_str.chunk; for (;;) { - QXLPHYSICAL next_chunk; - data_size = chunk->data_size; - validate_virt(&worker->mem_slots, (unsigned long)chunk->data, memslot_id, data_size, group_id); memcpy(dest, chunk->data, data_size); if (!chunk->next_chunk) { return; } dest += data_size; - next_chunk = chunk->next_chunk; - memslot_id = get_memslot_id(&worker->mem_slots, next_chunk); - chunk = (QXLDataChunk *)get_virt(&worker->mem_slots, next_chunk, sizeof(QXLDataChunk), group_id); + chunk = chunk->next_chunk; } + + release_red_data_chunk(&worker->mem_slots, &red_str.chunk); } static void unlocalize_str(QXLPHYSICAL *str) @@ -3921,27 +3933,27 @@ static void localize_clip(RedWorker *worker, SpiceClip *clip, uint32_t group_id) case SPICE_CLIP_TYPE_NONE: return; case SPICE_CLIP_TYPE_RECTS: { - QXLClipRects *clip_rects; - QXLDataChunk *chunk; - int memslot_id = get_memslot_id(&worker->mem_slots, clip->data); + RedClipRects clip_rects; + RedDataChunk *chunk; uint8_t *data; uint32_t data_size; - clip_rects = (QXLClipRects *)get_virt(&worker->mem_slots, clip->data, sizeof(QXLClipRects), group_id); - chunk = &clip_rects->chunk; + + get_red_cliprects_from_address(&worker->mem_slots, &clip_rects, clip->data, group_id); + chunk = &clip_rects.chunk; ASSERT(clip->data); - data = spice_malloc_n_m(clip_rects->num_rects, sizeof(SpiceRect), sizeof(uint32_t)); + data = spice_malloc_n_m(clip_rects.num_rects, sizeof(SpiceRect), sizeof(uint32_t)); clip->data = (QXLPHYSICAL)data; - *(uint32_t *)(data) = clip_rects->num_rects; + *(uint32_t *)(data) = clip_rects.num_rects; data += sizeof(uint32_t); do { data_size = chunk->data_size; - validate_virt(&worker->mem_slots, (unsigned long)chunk->data, memslot_id, data_size, group_id); memcpy(data, chunk->data, data_size); data += data_size; - chunk = chunk->next_chunk ? (QXLDataChunk *)get_virt(&worker->mem_slots, chunk->next_chunk, - sizeof(QXLDataChunk), group_id) : - NULL; + chunk = chunk->next_chunk; } while (chunk); + + release_red_data_chunk(&worker->mem_slots, &clip_rects.chunk); + break; } case SPICE_CLIP_TYPE_PATH: @@ -4163,30 +4175,31 @@ static void localize_bitmap(RedWorker *worker, QXLPHYSICAL *in_bitmap, uint32_t case SPICE_IMAGE_TYPE_BITMAP: if (image->bitmap.flags & QXL_BITMAP_DIRECT) { local_image->bitmap.data = (QXLPHYSICAL)get_virt(&worker->mem_slots, image->bitmap.data, - image->bitmap.stride * image->bitmap.y, - group_id); + image->bitmap.stride * image->bitmap.y, + group_id); } else { QXLPHYSICAL src_data; + RedDataChunk red_chunk; + RedDataChunk *chunk; int size = image->bitmap.y * image->bitmap.stride; uint8_t *data = spice_malloc_n(image->bitmap.y, image->bitmap.stride); local_image->bitmap.data = (QXLPHYSICAL)data; src_data = image->bitmap.data; + ASSERT(src_data); + get_red_data_chunk_from_address(&worker->mem_slots, &red_chunk, src_data, group_id); + chunk = &red_chunk; while (size) { - QXLDataChunk *chunk; uint32_t data_size; int cp_size; - ASSERT(src_data); - chunk = (QXLDataChunk *)get_virt(&worker->mem_slots, src_data, sizeof(QXLDataChunk), group_id); + PANIC_ON(!chunk); data_size = chunk->data_size; - validate_virt(&worker->mem_slots, (unsigned long)chunk->data, get_memslot_id(&worker->mem_slots, src_data), - data_size, group_id); cp_size = MIN(data_size, size); memcpy(data, chunk->data, cp_size); data += cp_size; size -= cp_size; - src_data = chunk->next_chunk; + chunk = chunk->next_chunk; } } @@ -4305,7 +4318,7 @@ static void red_draw_qxl_drawable(RedWorker *worker, Drawable *drawable) { RedSurface *surface; SpiceCanvas *canvas; - SpiceClip clip = drawable->qxl_drawable->clip; + SpiceClip clip = drawable->red_drawable->clip; surface = &worker->surfaces[drawable->surface_id]; canvas = surface->context.canvas; @@ -4316,121 +4329,121 @@ static void red_draw_qxl_drawable(RedWorker *worker, Drawable *drawable) worker->preload_group_id = drawable->group_id; localize_clip(worker, &clip, drawable->group_id); - switch (drawable->qxl_drawable->type) { + switch (drawable->red_drawable->type) { case QXL_DRAW_FILL: { - SpiceFill fill = drawable->qxl_drawable->u.fill; + SpiceFill fill = drawable->red_drawable->u.fill; localize_brush(worker, &fill.brush, drawable->group_id); localize_mask(worker, &fill.mask, drawable->group_id); - canvas->ops->draw_fill(canvas, &drawable->qxl_drawable->bbox, + canvas->ops->draw_fill(canvas, &drawable->red_drawable->bbox, &clip, &fill); unlocalize_mask(&fill.mask); unlocalize_brush(&fill.brush); break; } case QXL_DRAW_OPAQUE: { - SpiceOpaque opaque = drawable->qxl_drawable->u.opaque; + SpiceOpaque opaque = drawable->red_drawable->u.opaque; localize_brush(worker, &opaque.brush, drawable->group_id); localize_bitmap(worker, &opaque.src_bitmap, drawable->group_id); localize_mask(worker, &opaque.mask, drawable->group_id); - canvas->ops->draw_opaque(canvas, &drawable->qxl_drawable->bbox, &clip, &opaque); + canvas->ops->draw_opaque(canvas, &drawable->red_drawable->bbox, &clip, &opaque); unlocalize_mask(&opaque.mask); unlocalize_bitmap(&opaque.src_bitmap); unlocalize_brush(&opaque.brush); break; } case QXL_DRAW_COPY: { - SpiceCopy copy = drawable->qxl_drawable->u.copy; + SpiceCopy copy = drawable->red_drawable->u.copy; localize_bitmap(worker, ©.src_bitmap, drawable->group_id); localize_mask(worker, ©.mask, drawable->group_id); - canvas->ops->draw_copy(canvas, &drawable->qxl_drawable->bbox, + canvas->ops->draw_copy(canvas, &drawable->red_drawable->bbox, &clip, ©); unlocalize_mask(©.mask); unlocalize_bitmap(©.src_bitmap); break; } case QXL_DRAW_TRANSPARENT: { - SpiceTransparent transparent = drawable->qxl_drawable->u.transparent; + SpiceTransparent transparent = drawable->red_drawable->u.transparent; localize_bitmap(worker, &transparent.src_bitmap, drawable->group_id); canvas->ops->draw_transparent(canvas, - &drawable->qxl_drawable->bbox, &clip, &transparent); + &drawable->red_drawable->bbox, &clip, &transparent); unlocalize_bitmap(&transparent.src_bitmap); break; } case QXL_DRAW_ALPHA_BLEND: { - SpiceAlphaBlnd alpha_blend = drawable->qxl_drawable->u.alpha_blend; + SpiceAlphaBlnd alpha_blend = drawable->red_drawable->u.alpha_blend; localize_bitmap(worker, &alpha_blend.src_bitmap, drawable->group_id); canvas->ops->draw_alpha_blend(canvas, - &drawable->qxl_drawable->bbox, &clip, &alpha_blend); + &drawable->red_drawable->bbox, &clip, &alpha_blend); unlocalize_bitmap(&alpha_blend.src_bitmap); break; } case QXL_COPY_BITS: { - canvas->ops->copy_bits(canvas, &drawable->qxl_drawable->bbox, - &clip, &drawable->qxl_drawable->u.copy_bits.src_pos); + canvas->ops->copy_bits(canvas, &drawable->red_drawable->bbox, + &clip, &drawable->red_drawable->u.copy_bits.src_pos); break; } case QXL_DRAW_BLEND: { - SpiceBlend blend = drawable->qxl_drawable->u.blend; + SpiceBlend blend = drawable->red_drawable->u.blend; localize_bitmap(worker, &blend.src_bitmap, drawable->group_id); localize_mask(worker, &blend.mask, drawable->group_id); - canvas->ops->draw_blend(canvas, &drawable->qxl_drawable->bbox, + canvas->ops->draw_blend(canvas, &drawable->red_drawable->bbox, &clip, &blend); unlocalize_mask(&blend.mask); unlocalize_bitmap(&blend.src_bitmap); break; } case QXL_DRAW_BLACKNESS: { - SpiceBlackness blackness = drawable->qxl_drawable->u.blackness; + SpiceBlackness blackness = drawable->red_drawable->u.blackness; localize_mask(worker, &blackness.mask, drawable->group_id); canvas->ops->draw_blackness(canvas, - &drawable->qxl_drawable->bbox, &clip, &blackness); + &drawable->red_drawable->bbox, &clip, &blackness); unlocalize_mask(&blackness.mask); break; } case QXL_DRAW_WHITENESS: { - SpiceWhiteness whiteness = drawable->qxl_drawable->u.whiteness; + SpiceWhiteness whiteness = drawable->red_drawable->u.whiteness; localize_mask(worker, &whiteness.mask, drawable->group_id); canvas->ops->draw_whiteness(canvas, - &drawable->qxl_drawable->bbox, &clip, &whiteness); + &drawable->red_drawable->bbox, &clip, &whiteness); unlocalize_mask(&whiteness.mask); break; } case QXL_DRAW_INVERS: { - SpiceInvers invers = drawable->qxl_drawable->u.invers; + SpiceInvers invers = drawable->red_drawable->u.invers; localize_mask(worker, &invers.mask, drawable->group_id); canvas->ops->draw_invers(canvas, - &drawable->qxl_drawable->bbox, &clip, &invers); + &drawable->red_drawable->bbox, &clip, &invers); unlocalize_mask(&invers.mask); break; } case QXL_DRAW_ROP3: { - SpiceRop3 rop3 = drawable->qxl_drawable->u.rop3; + SpiceRop3 rop3 = drawable->red_drawable->u.rop3; localize_brush(worker, &rop3.brush, drawable->group_id); localize_bitmap(worker, &rop3.src_bitmap, drawable->group_id); localize_mask(worker, &rop3.mask, drawable->group_id); - canvas->ops->draw_rop3(canvas, &drawable->qxl_drawable->bbox, + canvas->ops->draw_rop3(canvas, &drawable->red_drawable->bbox, &clip, &rop3); unlocalize_mask(&rop3.mask); unlocalize_bitmap(&rop3.src_bitmap); unlocalize_brush(&rop3.brush); break; } case QXL_DRAW_STROKE: { - SpiceStroke stroke = drawable->qxl_drawable->u.stroke; + SpiceStroke stroke = drawable->red_drawable->u.stroke; localize_brush(worker, &stroke.brush, drawable->group_id); localize_path(worker, &stroke.path, drawable->group_id); localize_attr(worker, &stroke.attr, drawable->group_id); canvas->ops->draw_stroke(canvas, - &drawable->qxl_drawable->bbox, &clip, &stroke); + &drawable->red_drawable->bbox, &clip, &stroke); unlocalize_attr(&stroke.attr); unlocalize_path(&stroke.path); unlocalize_brush(&stroke.brush); break; } case QXL_DRAW_TEXT: { - SpiceText text = drawable->qxl_drawable->u.text; + SpiceText text = drawable->red_drawable->u.text; localize_brush(worker, &text.fore_brush, drawable->group_id); localize_brush(worker, &text.back_brush, drawable->group_id); localize_str(worker, &text.str, drawable->group_id); - canvas->ops->draw_text(canvas, &drawable->qxl_drawable->bbox, + canvas->ops->draw_text(canvas, &drawable->red_drawable->bbox, &clip, &text); unlocalize_str(&text.str); unlocalize_brush(&text.back_brush); @@ -4918,74 +4931,98 @@ static void red_add_surface_image(RedWorker *worker, int surface_id) } static void inline __add_buf(RedChannel *channel, uint32_t type, void *data, uint32_t size, - uint32_t slot_id, uint32_t group_id) -{ + void *release_opaque, release_buf_opaque_proc release_function) +{ int pos = channel->send_data.n_bufs++; ASSERT(pos < MAX_SEND_BUFS); channel->send_data.bufs[pos].type = type; channel->send_data.bufs[pos].size = size; channel->send_data.bufs[pos].data = data; - channel->send_data.bufs[pos].slot_id = slot_id; - channel->send_data.bufs[pos].group_id = group_id; + channel->send_data.bufs[pos].release_opaque = release_opaque; + channel->send_data.bufs[pos].release_function = release_function; } static void add_buf(RedChannel *channel, uint32_t type, void *data, uint32_t size, - uint32_t slot_id, uint32_t group_id) + void *release_opaque, release_buf_opaque_proc release_function) { - __add_buf(channel, type, data, size, slot_id, group_id); + __add_buf(channel, type, data, size, release_opaque, release_function); channel->send_data.header.size += size; } +static void release_red_path(RedWorker *worker, void *opaque) +{ + RedPath *path = (RedPath *)opaque; + + release_red_data_chunk(&worker->mem_slots, &path->chunk); + free(path); +} + static void fill_path(DisplayChannel *display_channel, QXLPHYSICAL *in_path, uint32_t group_id) { RedWorker *worker; RedChannel *channel = &display_channel->base; - int memslot_id; + RedPath *path; + path = spice_malloc(sizeof(RedPath)); worker = channel->worker; ASSERT(in_path && *in_path); - memslot_id = get_memslot_id(&worker->mem_slots, *in_path); - QXLPath *path = (QXLPath *)get_virt(&worker->mem_slots, *in_path, sizeof(QXLPath), group_id); + get_red_path_from_address(&worker->mem_slots, path, *in_path, group_id); *in_path = channel->send_data.header.size; - add_buf(channel, BUF_TYPE_RAW, &path->data_size, sizeof(uint32_t), 0, 0); - add_buf(channel, BUF_TYPE_CHUNK, &path->chunk, path->data_size, memslot_id, group_id); + add_buf(channel, BUF_TYPE_RAW, &path->data_size, sizeof(uint32_t), NULL, NULL); + add_buf(channel, BUF_TYPE_CHUNK, &path->chunk, path->data_size, path, release_red_path); +} + +static void release_red_str(RedWorker *worker, void *opaque) +{ + RedString *str = (RedString *)opaque; + + release_red_data_chunk(&worker->mem_slots, &str->chunk); + free(str); } static void fill_str(DisplayChannel *display_channel, QXLPHYSICAL *in_str, uint32_t group_id) { RedWorker *worker; RedChannel *channel = &display_channel->base; - int memslot_id; + RedString *str; worker = channel->worker; ASSERT(in_str && *in_str); - memslot_id = get_memslot_id(&worker->mem_slots, *in_str); - QXLString *str = (QXLString *)get_virt(&worker->mem_slots, *in_str, sizeof(QXLString), group_id); + str = spice_malloc(sizeof(RedString)); + get_red_string_from_address(&worker->mem_slots, str, *in_str, group_id); *in_str = channel->send_data.header.size; - add_buf(channel, BUF_TYPE_RAW, &str->length, sizeof(uint32_t), 0, 0); - add_buf(channel, BUF_TYPE_CHUNK, &str->chunk, str->data_size, memslot_id, group_id); + add_buf(channel, BUF_TYPE_RAW, &str->length, sizeof(uint32_t), NULL, NULL); + add_buf(channel, BUF_TYPE_CHUNK, &str->chunk, str->data_size, str, release_red_str); +} + +static void release_red_rects_clip(RedWorker *worker, void *opaque) +{ + RedClipRects *clip = (RedClipRects *)opaque; + + release_red_data_chunk(&worker->mem_slots, &clip->chunk); + free(clip); } static inline void fill_rects_clip(RedChannel *channel, QXLPHYSICAL *in_clip, uint32_t group_id) { RedWorker *worker = channel->worker; - QXLClipRects *clip; - int memslot_id = get_memslot_id(&worker->mem_slots, *in_clip); + RedClipRects *clip; + clip = spice_malloc(sizeof(RedClipRects)); ASSERT(in_clip && *in_clip); - clip = (QXLClipRects *)get_virt(&worker->mem_slots, *in_clip, sizeof(QXLClipRects), group_id); + get_red_cliprects_from_address(&worker->mem_slots, clip, *in_clip, group_id); *in_clip = channel->send_data.header.size; - add_buf(channel, BUF_TYPE_RAW, &clip->num_rects, sizeof(uint32_t), 0, 0); - add_buf(channel, BUF_TYPE_CHUNK, &clip->chunk, clip->num_rects * sizeof(SpiceRect), memslot_id, - group_id); + add_buf(channel, BUF_TYPE_RAW, &clip->num_rects, sizeof(uint32_t), NULL, NULL); + add_buf(channel, BUF_TYPE_CHUNK, &clip->chunk, clip->num_rects * sizeof(SpiceRect), clip, + release_red_rects_clip); } static void fill_base(DisplayChannel *display_channel, SpiceMsgDisplayBase *base, Drawable *drawable, uint32_t size, uint32_t surface_id) { RedChannel *channel = &display_channel->base; - add_buf(channel, BUF_TYPE_RAW, base, size, 0, 0); + add_buf(channel, BUF_TYPE_RAW, base, size, NULL, NULL); base->surface_id = surface_id; - base->box = drawable->qxl_drawable->bbox; - base->clip = drawable->qxl_drawable->clip; + base->box = drawable->red_drawable->bbox; + base->clip = drawable->red_drawable->clip; if (base->clip.type == SPICE_CLIP_TYPE_RECTS) { fill_rects_clip(channel, &base->clip.data, drawable->group_id); @@ -5024,7 +5061,7 @@ static inline void fill_palette(DisplayChannel *display_channel, SPICE_ADDRESS * } *io_palette = channel->send_data.header.size; add_buf(channel, BUF_TYPE_RAW, palette, - sizeof(SpicePalette) + palette->num_ents * sizeof(uint32_t), 0, 0); + sizeof(SpicePalette) + palette->num_ents * sizeof(uint32_t), NULL, NULL); } static inline RedCompressBuf *red_display_alloc_compress_buf(DisplayChannel *display_channel) @@ -5095,7 +5132,7 @@ static RedGlzDrawable *red_display_get_glz_drawable(DisplayChannel *channel, Dra ret = spice_new(RedGlzDrawable, 1); ret->display_channel = channel; - ret->qxl_drawable = drawable->qxl_drawable; + ret->red_drawable = drawable->red_drawable; ret->drawable = drawable; ret->group_id = drawable->group_id; ret->surface_id = drawable->surface_id; @@ -5164,7 +5201,7 @@ static void red_display_free_glz_drawable_instance(DisplayChannel *channel, if (drawable) { drawable->red_glz_drawable = NULL; } else { // no reference to the qxl drawable left - free_qxl_drawable(channel->base.worker, glz_drawable->qxl_drawable, + free_qxl_drawable(channel->base.worker, glz_drawable->red_drawable, glz_drawable->group_id, glz_drawable->self_bitmap, glz_drawable->surface_id); } @@ -6203,6 +6240,14 @@ static inline void red_display_add_image_to_pixmap_cache(DisplayChannel *display } } +static void release_data_chunk(RedWorker *worker, void *opaque) +{ + RedDataChunk *chunk = (RedDataChunk *)opaque; + + release_red_data_chunk(&worker->mem_slots, chunk); + free(chunk); +} + /* if the number of times fill_bits can be called per one qxl_drawable increases - MAX_LZ_DRAWABLE_INSTANCES must be increased as well */ static void fill_bits(DisplayChannel *display_channel, QXLPHYSICAL *in_bitmap, Drawable *drawable) @@ -6237,7 +6282,7 @@ static void fill_bits(DisplayChannel *display_channel, QXLPHYSICAL *in_bitmap, D if (pixmap_cache_hit(display_channel->pixmap_cache, image->descriptor.id, display_channel)) { image->descriptor.type = SPICE_IMAGE_TYPE_FROM_CACHE; - add_buf(channel, BUF_TYPE_RAW, image, sizeof(SpiceImageDescriptor), 0, 0); + add_buf(channel, BUF_TYPE_RAW, image, sizeof(SpiceImageDescriptor), NULL, NULL); stat_inc_counter(display_channel->cache_hits_counter, 1); return; } @@ -6258,7 +6303,7 @@ static void fill_bits(DisplayChannel *display_channel, QXLPHYSICAL *in_bitmap, D image->descriptor.height = surface->context.height; image->surface.surface_id = surface_id; - add_buf(channel, BUF_TYPE_RAW, image, sizeof(SpiceSurfaceImage), 0, 0); + add_buf(channel, BUF_TYPE_RAW, image, sizeof(SpiceSurfaceImage), NULL, NULL); break; } case SPICE_IMAGE_TYPE_BITMAP: @@ -6282,25 +6327,28 @@ static void fill_bits(DisplayChannel *display_channel, QXLPHYSICAL *in_bitmap, D image_data = image->bitmap.data; image->bitmap.flags = image->bitmap.flags & SPICE_BITMAP_FLAGS_TOP_DOWN; - add_buf(channel, BUF_TYPE_RAW, image, sizeof(SpiceBitmapImage), 0, 0); + add_buf(channel, BUF_TYPE_RAW, image, sizeof(SpiceBitmapImage), NULL, NULL); fill_palette(display_channel, &(image->bitmap.palette), &(image->bitmap.flags), drawable->group_id); image->bitmap.data = channel->send_data.header.size; if (qxl_image->bitmap.flags & QXL_BITMAP_DIRECT) { data = (uint8_t *)get_virt(&worker->mem_slots, image_data, stride * y, drawable->group_id); - add_buf(channel, BUF_TYPE_RAW, data, y * stride, 0, 0); + add_buf(channel, BUF_TYPE_RAW, data, y * stride, NULL, NULL); } else { - data = (uint8_t *)get_virt(&worker->mem_slots, image_data, sizeof(QXLDataChunk), - drawable->group_id); - add_buf(channel, BUF_TYPE_CHUNK, data, y * stride, memslot_id, drawable->group_id); + RedDataChunk *chunk; + chunk = spice_malloc(sizeof(RedDataChunk)); + get_red_data_chunk_from_address(&worker->mem_slots, chunk, image_data, + drawable->group_id); + add_buf(channel, BUF_TYPE_CHUNK, (uint8_t *)chunk, y * stride, chunk, + release_data_chunk); } } else { red_display_add_image_to_pixmap_cache(display_channel, qxl_image, image); add_buf((RedChannel *)display_channel, BUF_TYPE_RAW, image, comp_send_data.raw_size, - 0, 0); + NULL, NULL); add_buf((RedChannel *)display_channel, BUF_TYPE_COMPRESS_BUF, - comp_send_data.comp_buf, comp_send_data.comp_buf_size, 0, 0); + comp_send_data.comp_buf, comp_send_data.comp_buf_size, NULL, NULL); if (comp_send_data.plt_ptr != NULL) { fill_palette(display_channel, comp_send_data.plt_ptr, comp_send_data.flags_ptr, @@ -6308,13 +6356,18 @@ static void fill_bits(DisplayChannel *display_channel, QXLPHYSICAL *in_bitmap, D } } break; - case SPICE_IMAGE_TYPE_QUIC: + case SPICE_IMAGE_TYPE_QUIC: { + RedDataChunk *chunk; + chunk = spice_malloc(sizeof(RedDataChunk)); red_display_add_image_to_pixmap_cache(display_channel, qxl_image, image); image->quic = qxl_image->quic; - add_buf(channel, BUF_TYPE_RAW, image, sizeof(SpiceQUICImage), 0, 0); - add_buf(channel, BUF_TYPE_CHUNK, qxl_image->quic.data, qxl_image->quic.data_size, - memslot_id, drawable->group_id); + add_buf(channel, BUF_TYPE_RAW, image, sizeof(SpiceQUICImage), NULL, NULL); + get_red_data_chunk_from_qxl(&worker->mem_slots, chunk, (QXLDataChunk *)qxl_image->quic.data, + memslot_id, drawable->group_id); + add_buf(channel, BUF_TYPE_CHUNK, chunk, qxl_image->quic.data_size, + chunk, release_data_chunk); break; + } default: red_error("invalid image type %u", image->descriptor.type); } @@ -6350,10 +6403,18 @@ static void fill_attr(DisplayChannel *display_channel, SpiceLineAttr *attr, uint attr->style_nseg * sizeof(uint32_t), group_id); ASSERT(attr->style); attr->style = channel->send_data.header.size; - add_buf(channel, BUF_TYPE_RAW, buf, attr->style_nseg * sizeof(uint32_t), 0, 0); + add_buf(channel, BUF_TYPE_RAW, buf, attr->style_nseg * sizeof(uint32_t), NULL, NULL); } } +static void release_red_cursor(RedWorker *worker, void *opaque) +{ + RedCursor *cursor = (RedCursor *)opaque; + + release_red_data_chunk(&worker->mem_slots, &cursor->chunk); + free(cursor); +} + static void fill_cursor(CursorChannel *cursor_channel, SpiceCursor *red_cursor, CursorItem *cursor) { RedChannel *channel = &cursor_channel->base; @@ -6365,13 +6426,15 @@ static void fill_cursor(CursorChannel *cursor_channel, SpiceCursor *red_cursor, if (cursor->type == CURSOR_TYPE_DEV) { QXLCursorCmd *cursor_cmd; - QXLCursor *qxl_cursor; + RedCursor *_red_cursor; cursor_cmd = cursor->qxl_cursor; - qxl_cursor = (QXLCursor *)get_virt(&channel->worker->mem_slots, cursor_cmd->u.set.shape, - sizeof(QXLCursor), cursor->group_id); + _red_cursor = spice_malloc(sizeof(RedCursor)); + get_red_cursor_from_address(&channel->worker->mem_slots, _red_cursor, cursor_cmd->u.set.shape, + cursor->group_id); + red_cursor->flags = 0; - red_cursor->header = qxl_cursor->header; + red_cursor->header = _red_cursor->header; if (red_cursor->header.unique) { if (red_cursor_cache_find(cursor_channel, red_cursor->header.unique)) { @@ -6383,17 +6446,20 @@ static void fill_cursor(CursorChannel *cursor_channel, SpiceCursor *red_cursor, } } - if (qxl_cursor->data_size) { - add_buf(channel, BUF_TYPE_CHUNK, &qxl_cursor->chunk, qxl_cursor->data_size, - get_memslot_id(&channel->worker->mem_slots, cursor_cmd->u.set.shape), cursor->group_id); + if (_red_cursor->data_size) { + add_buf(channel, BUF_TYPE_CHUNK, &_red_cursor->chunk, _red_cursor->data_size, + _red_cursor, release_red_cursor); + } else { + release_red_data_chunk(&channel->worker->mem_slots, &_red_cursor->chunk); + free(_red_cursor); } } else { LocalCursor *local_cursor; ASSERT(cursor->type == CURSOR_TYPE_LOCAL); local_cursor = (LocalCursor *)cursor; *red_cursor = local_cursor->red_cursor; - add_buf(channel, BUF_TYPE_RAW, local_cursor->red_cursor.data, local_cursor->data_size, 0, - 0); + add_buf(channel, BUF_TYPE_RAW, local_cursor->red_cursor.data, local_cursor->data_size, NULL, + NULL); } } @@ -6421,7 +6487,7 @@ static inline void red_display_reset_send_data(DisplayChannel *channel) static inline void red_send_qxl_drawable(RedWorker *worker, DisplayChannel *display_channel, Drawable *item) { - QXLDrawable *drawable = item->qxl_drawable; + RedDrawable *drawable = item->red_drawable; RedChannel *channel = &display_channel->base; switch (drawable->type) { @@ -6581,7 +6647,7 @@ static inline uint32_t __fill_iovec(RedWorker *worker, BufDescriptor *buf, int s break; } case BUF_TYPE_CHUNK: { - QXLDataChunk *chunk = (QXLDataChunk *)buf->data; + RedDataChunk *chunk = (RedDataChunk *)buf->data; do { int data_size = chunk->data_size; int skip_now = MIN(data_size, skip); @@ -6589,18 +6655,14 @@ static inline uint32_t __fill_iovec(RedWorker *worker, BufDescriptor *buf, int s data_size -= skip_now; if (data_size) { - validate_virt(&worker->mem_slots, (unsigned long)chunk->data, buf->slot_id, data_size, - buf->group_id); size += data_size; vec[*vec_index].iov_base = chunk->data + skip_now; vec[*vec_index].iov_len = data_size; (*vec_index)++; } - chunk = chunk->next_chunk ? - (QXLDataChunk *)get_virt(&worker->mem_slots, chunk->next_chunk, sizeof(QXLDataChunk), - buf->group_id) : - NULL; + chunk = chunk->next_chunk; } while (chunk && *vec_index < MAX_SEND_VEC); + buf->release_function(worker, buf->release_opaque); break; } default: @@ -6732,31 +6794,32 @@ static inline void display_begin_send_massage(DisplayChannel *channel, void *ite if (sync_count) { sub_list->size = 2; add_buf((RedChannel*)channel, BUF_TYPE_RAW, sub_list, - sizeof(*sub_list) + 2 * sizeof(sub_list->sub_messages[0]), 0, 0); + sizeof(*sub_list) + 2 * sizeof(sub_list->sub_messages[0]), NULL, NULL); sub_list->sub_messages[0] = channel->base.send_data.header.size; sub_header[0].type = SPICE_MSG_WAIT_FOR_CHANNELS; sub_header[0].size = sizeof(free_list->wait.header) + sync_count * sizeof(free_list->wait.buf[0]); - add_buf((RedChannel*)channel, BUF_TYPE_RAW, sub_header, sizeof(*sub_header), 0, 0); + add_buf((RedChannel*)channel, BUF_TYPE_RAW, sub_header, sizeof(*sub_header), NULL, + NULL); free_list->wait.header.wait_count = sync_count; add_buf((RedChannel*)channel, BUF_TYPE_RAW, &free_list->wait.header, - sub_header[0].size, 0, 0); + sub_header[0].size, NULL, NULL); sub_list->sub_messages[1] = channel->base.send_data.header.size; sub_index = 1; } else { sub_list->size = 1; add_buf((RedChannel*)channel, BUF_TYPE_RAW, sub_list, - sizeof(*sub_list) + sizeof(sub_list->sub_messages[0]), 0, 0); + sizeof(*sub_list) + sizeof(sub_list->sub_messages[0]), NULL, NULL); sub_list->sub_messages[0] = channel->base.send_data.header.size; sub_index = 0; } sub_header[sub_index].type = SPICE_MSG_DISPLAY_INVAL_LIST; sub_header[sub_index].size = sizeof(*free_list->res) + free_list->res->count * sizeof(free_list->res->resorces[0]); - add_buf((RedChannel*)channel, BUF_TYPE_RAW, &sub_header[sub_index], sizeof(*sub_header), 0, - 0); - add_buf((RedChannel*)channel, BUF_TYPE_RAW, free_list->res, sub_header[sub_index].size, 0, - 0); + add_buf((RedChannel*)channel, BUF_TYPE_RAW, &sub_header[sub_index], sizeof(*sub_header), NULL, + NULL); + add_buf((RedChannel*)channel, BUF_TYPE_RAW, free_list->res, sub_header[sub_index].size, NULL, + NULL); } red_begin_send_massage((RedChannel *)channel, item); } @@ -6970,11 +7033,11 @@ static inline int red_send_stream_data(DisplayChannel *display_channel, Drawable int n; ASSERT(stream); - ASSERT(drawable->qxl_drawable->type == QXL_DRAW_COPY); + ASSERT(drawable->red_drawable->type == QXL_DRAW_COPY); channel = &display_channel->base; worker = channel->worker; - qxl_image = (QXLImage *)get_virt(&worker->mem_slots, drawable->qxl_drawable->u.copy.src_bitmap, + qxl_image = (QXLImage *)get_virt(&worker->mem_slots, drawable->red_drawable->u.copy.src_bitmap, sizeof(QXLImage), drawable->group_id); if (qxl_image->descriptor.type != SPICE_IMAGE_TYPE_BITMAP || @@ -6995,7 +7058,7 @@ static inline int red_send_stream_data(DisplayChannel *display_channel, Drawable switch (qxl_image->bitmap.format) { case SPICE_BITMAP_FMT_32BIT: - if (!red_rgb32bpp_to_24(worker, &drawable->qxl_drawable->u.copy.src_area, + if (!red_rgb32bpp_to_24(worker, &drawable->red_drawable->u.copy.src_area, &qxl_image->bitmap, frame, frame_stride, get_virt_delta(&worker->mem_slots, data, drawable->group_id), get_memslot_id(&worker->mem_slots, data), @@ -7004,7 +7067,7 @@ static inline int red_send_stream_data(DisplayChannel *display_channel, Drawable } break; case SPICE_BITMAP_FMT_16BIT: - if (!red_rgb16bpp_to_24(worker, &drawable->qxl_drawable->u.copy.src_area, + if (!red_rgb16bpp_to_24(worker, &drawable->red_drawable->u.copy.src_area, &qxl_image->bitmap, frame, frame_stride, get_virt_delta(&worker->mem_slots, data, drawable->group_id), get_memslot_id(&worker->mem_slots, data), @@ -7013,7 +7076,7 @@ static inline int red_send_stream_data(DisplayChannel *display_channel, Drawable } break; case SPICE_BITMAP_FMT_24BIT: - if (!red_rgb24bpp_to_24(worker, &drawable->qxl_drawable->u.copy.src_area, + if (!red_rgb24bpp_to_24(worker, &drawable->red_drawable->u.copy.src_area, &qxl_image->bitmap, frame, frame_stride, get_virt_delta(&worker->mem_slots, data, drawable->group_id), get_memslot_id(&worker->mem_slots, data), @@ -7045,12 +7108,12 @@ static inline int red_send_stream_data(DisplayChannel *display_channel, Drawable channel->send_data.header.type = SPICE_MSG_DISPLAY_STREAM_DATA; SpiceMsgDisplayStreamData* stream_data = &display_channel->send_data.u.stream_data; - add_buf(channel, BUF_TYPE_RAW, stream_data, sizeof(SpiceMsgDisplayStreamData), 0, 0); + add_buf(channel, BUF_TYPE_RAW, stream_data, sizeof(SpiceMsgDisplayStreamData), NULL, NULL); add_buf(channel, BUF_TYPE_RAW, display_channel->send_data.stream_outbuf, - n + PADDING, 0, 0); + n + PADDING, NULL, NULL); stream_data->id = stream - worker->streams_buf; - stream_data->multi_media_time = drawable->qxl_drawable->mm_time; + stream_data->multi_media_time = drawable->red_drawable->mm_time; stream_data->data_size = n; stream_data->ped_size = PADDING; display_begin_send_massage(display_channel, NULL); @@ -7079,7 +7142,7 @@ static void red_send_set_ack(RedChannel *channel) channel->send_data.u.ack.window = channel->client_ack_window; channel->messages_window = 0; - add_buf(channel, BUF_TYPE_RAW, &channel->send_data.u.ack, sizeof(SpiceMsgSetAck), 0, 0); + add_buf(channel, BUF_TYPE_RAW, &channel->send_data.u.ack, sizeof(SpiceMsgSetAck), NULL, NULL); red_begin_send_massage(channel, NULL); } @@ -7102,7 +7165,7 @@ static inline void __red_send_inval(RedChannel *channel, CacheItem *cach_item, { channel->send_data.header.type = cach_item->inval_type; inval_one->id = *(uint64_t *)&cach_item->id; - add_buf(channel, BUF_TYPE_RAW, inval_one, sizeof(*inval_one), 0, 0); + add_buf(channel, BUF_TYPE_RAW, inval_one, sizeof(*inval_one), NULL, NULL); } static void red_send_inval(RedChannel *channel, CacheItem *cach_item, SpiceMsgDisplayInvalOne *inval_one) @@ -7124,7 +7187,7 @@ static void display_channel_send_migrate(DisplayChannel *display_channel) display_channel->send_data.u.migrate.flags = SPICE_MIGRATE_NEED_FLUSH | SPICE_MIGRATE_NEED_DATA_TRANSFER; add_buf((RedChannel*)display_channel, BUF_TYPE_RAW, &display_channel->send_data.u.migrate, - sizeof(display_channel->send_data.u.migrate), 0, 0); + sizeof(display_channel->send_data.u.migrate), NULL, NULL); display_channel->expect_migrate_mark = TRUE; display_begin_send_massage(display_channel, NULL); } @@ -7156,7 +7219,7 @@ static void display_channel_send_migrate_data(DisplayChannel *display_channel) &display_channel->glz_data.usr); add_buf((RedChannel *)display_channel, BUF_TYPE_RAW, &display_channel->send_data.u.migrate_data, - sizeof(display_channel->send_data.u.migrate_data), 0, 0); + sizeof(display_channel->send_data.u.migrate_data), NULL, NULL); display_begin_send_massage(display_channel, NULL); } @@ -7183,7 +7246,7 @@ static void display_channel_pixmap_sync(DisplayChannel *display_channel) pthread_mutex_unlock(&pixmap_cache->lock); add_buf((RedChannel *)display_channel, BUF_TYPE_RAW, wait, - sizeof(*wait) + sizeof(wait->wait_list[0]), 0, 0); + sizeof(*wait) + sizeof(wait->wait_list[0]), NULL, NULL); display_begin_send_massage(display_channel, NULL); } @@ -7230,7 +7293,8 @@ static void red_send_image(DisplayChannel *display_channel, ImageItem *item) channel->send_data.header.type = SPICE_MSG_DISPLAY_DRAW_COPY; - add_buf(channel, BUF_TYPE_RAW, &display_channel->send_data.u.copy, sizeof(SpiceMsgDisplayDrawCopy), 0, 0); + add_buf(channel, BUF_TYPE_RAW, &display_channel->send_data.u.copy, + sizeof(SpiceMsgDisplayDrawCopy), NULL, NULL); display_channel->send_data.u.copy.base.surface_id = item->surface_id; display_channel->send_data.u.copy.base.box.left = item->pos.x; display_channel->send_data.u.copy.base.box.top = item->pos.y; @@ -7251,16 +7315,16 @@ static void red_send_image(DisplayChannel *display_channel, ImageItem *item) if (red_quic_compress_image(display_channel, red_image, &bitmap, &comp_send_data, worker->mem_slots.internal_groupslot_id)) { - add_buf(channel, BUF_TYPE_RAW, red_image, comp_send_data.raw_size, 0, 0); + add_buf(channel, BUF_TYPE_RAW, red_image, comp_send_data.raw_size, NULL, NULL); add_buf(channel, BUF_TYPE_COMPRESS_BUF, comp_send_data.comp_buf, - comp_send_data.comp_buf_size, 0, 0); + comp_send_data.comp_buf_size, NULL, NULL); } else { red_image->descriptor.type = SPICE_IMAGE_TYPE_BITMAP; red_image->bitmap = bitmap; red_image->bitmap.flags &= ~QXL_BITMAP_DIRECT; - add_buf(channel, BUF_TYPE_RAW, red_image, sizeof(SpiceBitmapImage), 0, 0); + add_buf(channel, BUF_TYPE_RAW, red_image, sizeof(SpiceBitmapImage), NULL, NULL); red_image->bitmap.data = channel->send_data.header.size; - add_buf(channel, BUF_TYPE_RAW, item->data, bitmap.y * bitmap.stride, 0, 0); + add_buf(channel, BUF_TYPE_RAW, item->data, bitmap.y * bitmap.stride, NULL, NULL); } display_begin_send_massage(display_channel, &item->link); } @@ -7268,7 +7332,7 @@ static void red_send_image(DisplayChannel *display_channel, ImageItem *item) static void red_display_send_upgrade(DisplayChannel *display_channel, UpgradeItem *item) { RedChannel *channel; - QXLDrawable *qxl_drawable; + RedDrawable *qxl_drawable; SpiceMsgDisplayDrawCopy *copy = &display_channel->send_data.u.copy; ASSERT(display_channel && item && item->drawable); @@ -7276,18 +7340,18 @@ static void red_display_send_upgrade(DisplayChannel *display_channel, UpgradeIte channel->send_data.header.type = SPICE_MSG_DISPLAY_DRAW_COPY; - qxl_drawable = item->drawable->qxl_drawable; + qxl_drawable = item->drawable->red_drawable; ASSERT(qxl_drawable->type == QXL_DRAW_COPY); ASSERT(qxl_drawable->u.copy.rop_decriptor == SPICE_ROPD_OP_PUT); ASSERT(qxl_drawable->u.copy.mask.bitmap == 0); - add_buf(channel, BUF_TYPE_RAW, copy, sizeof(SpiceMsgDisplayDrawCopy), 0, 0); + add_buf(channel, BUF_TYPE_RAW, copy, sizeof(SpiceMsgDisplayDrawCopy), NULL, NULL); copy->base.surface_id = 0; copy->base.box = qxl_drawable->bbox; copy->base.clip.type = SPICE_CLIP_TYPE_RECTS; copy->base.clip.data = channel->send_data.header.size; - add_buf(channel, BUF_TYPE_RAW, &item->n_rects, sizeof(uint32_t), 0, 0); - add_buf(channel, BUF_TYPE_RAW, item->rects, sizeof(SpiceRect) * item->n_rects, 0, 0); + add_buf(channel, BUF_TYPE_RAW, &item->n_rects, sizeof(uint32_t), NULL, NULL); + add_buf(channel, BUF_TYPE_RAW, item->rects, sizeof(SpiceRect) * item->n_rects, NULL, NULL); copy->data = qxl_drawable->u.copy; fill_bits(display_channel, ©->data.src_bitmap, item->drawable); @@ -7314,9 +7378,9 @@ static void red_display_send_stream_start(DisplayChannel *display_channel, Strea stream_create->stream_height = SPICE_ALIGN(stream_create->src_height, 2); stream_create->dest = stream->dest_area; - add_buf(channel, BUF_TYPE_RAW, stream_create, sizeof(*stream_create), 0, 0); + add_buf(channel, BUF_TYPE_RAW, stream_create, sizeof(*stream_create), NULL, NULL); if (stream->current) { - QXLDrawable *qxl_drawable = stream->current->qxl_drawable; + RedDrawable *qxl_drawable = stream->current->red_drawable; stream_create->clip = qxl_drawable->clip; if (qxl_drawable->clip.type == SPICE_CLIP_TYPE_RECTS) { fill_rects_clip(channel, &stream_create->clip.data, stream->current->group_id); @@ -7329,7 +7393,7 @@ static void red_display_send_stream_start(DisplayChannel *display_channel, Strea stream_create->clip.data = channel->send_data.header.size; display_channel->send_data.u.stream_create.num_rects = 0; add_buf(channel, BUF_TYPE_RAW, &display_channel->send_data.u.stream_create.num_rects, - sizeof(uint32_t), 0, 0); + sizeof(uint32_t), NULL, NULL); display_begin_send_massage(display_channel, NULL); } } @@ -7346,15 +7410,15 @@ static void red_display_send_stream_clip(DisplayChannel *display_channel, channel->send_data.header.type = SPICE_MSG_DISPLAY_STREAM_CLIP; SpiceMsgDisplayStreamClip *stream_clip = &display_channel->send_data.u.stream_clip; - add_buf(channel, BUF_TYPE_RAW, stream_clip, sizeof(*stream_clip), 0, 0); + add_buf(channel, BUF_TYPE_RAW, stream_clip, sizeof(*stream_clip), NULL, NULL); stream_clip->id = agent - display_channel->stream_agents; if ((stream_clip->clip.type = item->clip_type) == SPICE_CLIP_TYPE_NONE) { stream_clip->clip.data = 0; } else { ASSERT(stream_clip->clip.type == SPICE_CLIP_TYPE_RECTS); stream_clip->clip.data = channel->send_data.header.size; - add_buf(channel, BUF_TYPE_RAW, &item->n_rects, sizeof(uint32_t), 0, 0); - add_buf(channel, BUF_TYPE_RAW, item->rects, item->n_rects * sizeof(SpiceRect), 0, 0); + add_buf(channel, BUF_TYPE_RAW, &item->n_rects, sizeof(uint32_t), NULL, NULL); + add_buf(channel, BUF_TYPE_RAW, item->rects, item->n_rects * sizeof(SpiceRect), NULL, NULL); } display_begin_send_massage(display_channel, item); } @@ -7365,7 +7429,7 @@ static void red_display_send_stream_end(DisplayChannel *display_channel, StreamA channel->send_data.header.type = SPICE_MSG_DISPLAY_STREAM_DESTROY; display_channel->send_data.u.stream_destroy.id = agent - display_channel->stream_agents; add_buf(channel, BUF_TYPE_RAW, &display_channel->send_data.u.stream_destroy, - sizeof(SpiceMsgDisplayStreamDestroy), 0, 0); + sizeof(SpiceMsgDisplayStreamDestroy), NULL, NULL); display_begin_send_massage(display_channel, NULL); } @@ -7387,8 +7451,8 @@ static void red_send_cursor_init(CursorChannel *channel) channel->send_data.u.cursor_init.position = worker->cursor_position; channel->send_data.u.cursor_init.trail_length = worker->cursor_trail_length; channel->send_data.u.cursor_init.trail_frequency = worker->cursor_trail_frequency; - add_buf(&channel->base, BUF_TYPE_RAW, &channel->send_data.u.cursor_init, sizeof(SpiceMsgCursorInit), - 0, 0); + add_buf(&channel->base, BUF_TYPE_RAW, &channel->send_data.u.cursor_init, + sizeof(SpiceMsgCursorInit), NULL, NULL); fill_cursor(channel, &channel->send_data.u.cursor_init.cursor, worker->cursor); @@ -7406,7 +7470,7 @@ static void red_send_local_cursor(CursorChannel *cursor_channel, LocalCursor *cu cursor_channel->send_data.u.cursor_set.postition = cursor->position; cursor_channel->send_data.u.cursor_set.visible = channel->worker->cursor_visible; add_buf(channel, BUF_TYPE_RAW, &cursor_channel->send_data.u.cursor_set, - sizeof(SpiceMsgCursorSet), 0, 0); + sizeof(SpiceMsgCursorSet), NULL, NULL); fill_cursor(cursor_channel, &cursor_channel->send_data.u.cursor_set.cursor, &cursor->base); red_begin_send_massage(channel, cursor); @@ -7419,7 +7483,7 @@ static void cursor_channel_send_migrate(CursorChannel *cursor_channel) cursor_channel->base.send_data.header.type = SPICE_MSG_MIGRATE; cursor_channel->send_data.u.migrate.flags = 0; add_buf((RedChannel*)cursor_channel, BUF_TYPE_RAW, &cursor_channel->send_data.u.migrate, - sizeof(cursor_channel->send_data.u.migrate), 0, 0); + sizeof(cursor_channel->send_data.u.migrate), NULL, NULL); red_begin_send_massage((RedChannel*)cursor_channel, NULL); } @@ -7438,14 +7502,14 @@ static void red_send_cursor(CursorChannel *cursor_channel, CursorItem *cursor) channel->send_data.header.type = SPICE_MSG_CURSOR_MOVE; cursor_channel->send_data.u.cursor_move.postition = cmd->u.position; add_buf(channel, BUF_TYPE_RAW, &cursor_channel->send_data.u.cursor_move, - sizeof(SpiceMsgCursorMove), 0, 0); + sizeof(SpiceMsgCursorMove), NULL, NULL); break; case QXL_CURSOR_SET: channel->send_data.header.type = SPICE_MSG_CURSOR_SET; cursor_channel->send_data.u.cursor_set.postition = cmd->u.set.position; cursor_channel->send_data.u.cursor_set.visible = channel->worker->cursor_visible; add_buf(channel, BUF_TYPE_RAW, &cursor_channel->send_data.u.cursor_set, - sizeof(SpiceMsgCursorSet), 0, 0); + sizeof(SpiceMsgCursorSet), NULL, NULL); fill_cursor(cursor_channel, &cursor_channel->send_data.u.cursor_set.cursor, cursor); break; case QXL_CURSOR_HIDE: @@ -7456,7 +7520,7 @@ static void red_send_cursor(CursorChannel *cursor_channel, CursorItem *cursor) cursor_channel->send_data.u.cursor_trail.length = cmd->u.trail.length; cursor_channel->send_data.u.cursor_trail.frequency = cmd->u.trail.frequency; add_buf(channel, BUF_TYPE_RAW, &cursor_channel->send_data.u.cursor_trail, - sizeof(SpiceMsgCursorTrail), 0, 0); + sizeof(SpiceMsgCursorTrail), NULL, NULL); break; default: red_error("bad cursor command %d", cmd->type); @@ -7478,7 +7542,7 @@ static void red_send_surface_create(DisplayChannel *display, SpiceMsgSurfaceCrea display->send_data.u.surface_create = *surface_create; add_buf(channel, BUF_TYPE_RAW, &display->send_data.u.surface_create, - sizeof(SpiceMsgSurfaceCreate), 0, 0); + sizeof(SpiceMsgSurfaceCreate), NULL, NULL); red_begin_send_massage(channel, NULL); } @@ -7494,7 +7558,7 @@ static void red_send_surface_destroy(DisplayChannel *display, uint32_t surface_i display->send_data.u.surface_destroy.surface_id = surface_id; add_buf(channel, BUF_TYPE_RAW, &display->send_data.u.surface_destroy, - sizeof(SpiceMsgSurfaceDestroy), 0, 0); + sizeof(SpiceMsgSurfaceDestroy), NULL, NULL); red_begin_send_massage(channel, NULL); } @@ -7697,7 +7761,7 @@ static void __show_tree_call(TreeItem *item, void *data) printf(" "); } printf(item_prefix, 0); - show_qxl_drawable(tree_data->worker, drawable->qxl_drawable, NULL); + show_qxl_drawable(tree_data->worker, drawable->red_drawable, NULL); for (i = 0; i < tree_data->level; i++) { printf(" "); }