QXL: redesign.

This commit is contained in:
Gerd Hoffmann 2010-03-30 12:55:32 +02:00
parent 58273e3a32
commit d3735feea6
8 changed files with 81 additions and 68 deletions

View File

@ -40,7 +40,7 @@ static int num_active_workers = 0;
typedef struct RedDispatcher RedDispatcher;
struct RedDispatcher {
QXLWorker base;
QXLInterface *qxl_interface;
QXLInstance *qxl;
int channel;
pthread_t worker_thread;
uint32_t pending;
@ -387,7 +387,7 @@ void red_dispatcher_set_mm_time(uint32_t mm_time)
{
RedDispatcher *now = dispatchers;
while (now) {
now->qxl_interface->set_mm_time(now->qxl_interface, mm_time);
now->qxl->st->qif->set_mm_time(now->qxl, mm_time);
now = now->next;
}
}
@ -409,7 +409,7 @@ void red_dispatcher_on_ic_change()
RedDispatcher *now = dispatchers;
while (now) {
RedWorkeMessage message = RED_WORKER_MESSAGE_SET_COMPRESSION;
now->qxl_interface->set_compression_level(now->qxl_interface, compression_level);
now->qxl->st->qif->set_compression_level(now->qxl, compression_level);
write_message(now->channel, &message);
send_data(now->channel, &image_compression, sizeof(spice_image_compression_t));
now = now->next;
@ -422,7 +422,7 @@ void red_dispatcher_on_sv_change()
RedDispatcher *now = dispatchers;
while (now) {
RedWorkeMessage message = RED_WORKER_MESSAGE_SET_STREAMING_VIDEO;
now->qxl_interface->set_compression_level(now->qxl_interface, compression_level);
now->qxl->st->qif->set_compression_level(now->qxl, compression_level);
write_message(now->channel, &message);
send_data(now->channel, &streaming_video, sizeof(uint32_t));
now = now->next;
@ -458,11 +458,11 @@ uint32_t red_dispatcher_qxl_ram_size()
if (!dispatchers) {
return 0;
}
dispatchers->qxl_interface->get_init_info(dispatchers->qxl_interface, &qxl_info);
dispatchers->qxl->st->qif->get_init_info(dispatchers->qxl, &qxl_info);
return qxl_info.qxl_ram_size;
}
RedDispatcher *red_dispatcher_init(QXLInterface *qxl_interface, int id)
RedDispatcher *red_dispatcher_init(QXLInstance *qxl)
{
RedDispatcher *dispatcher;
int channels[2];
@ -475,9 +475,9 @@ RedDispatcher *red_dispatcher_init(QXLInterface *qxl_interface, int id)
sigset_t thread_sig_mask;
sigset_t curr_sig_mask;
if (qxl_interface->pci_vendor != REDHAT_PCI_VENDOR_ID ||
qxl_interface->pci_id != QXL_DEVICE_ID ||
qxl_interface->pci_revision != QXL_REVISION) {
if (qxl->st->qif->pci_vendor != REDHAT_PCI_VENDOR_ID ||
qxl->st->qif->pci_id != QXL_DEVICE_ID ||
qxl->st->qif->pci_revision != QXL_REVISION) {
red_printf("pci mismatch");
return NULL;
}
@ -492,8 +492,8 @@ RedDispatcher *red_dispatcher_init(QXLInterface *qxl_interface, int id)
dispatcher = spice_new0(RedDispatcher, 1);
dispatcher->channel = channels[0];
init_data.qxl_interface = dispatcher->qxl_interface = qxl_interface;
init_data.id = id;
init_data.qxl = dispatcher->qxl = qxl;
init_data.id = qxl->id;
init_data.channel = channels[1];
init_data.pending = &dispatcher->pending;
init_data.num_renderers = num_renderers;
@ -502,8 +502,8 @@ RedDispatcher *red_dispatcher_init(QXLInterface *qxl_interface, int id)
init_data.image_compression = image_compression;
init_data.streaming_video = streaming_video;
dispatcher->base.major_version = VD_INTERFACE_QXL_MAJOR;
dispatcher->base.major_version = VD_INTERFACE_QXL_MINOR;
dispatcher->base.major_version = SPICE_INTERFACE_QXL_MAJOR;
dispatcher->base.minor_version = SPICE_INTERFACE_QXL_MINOR;
dispatcher->base.wakeup = qxl_worker_wakeup;
dispatcher->base.oom = qxl_worker_oom;
dispatcher->base.save = qxl_worker_save;
@ -522,7 +522,7 @@ RedDispatcher *red_dispatcher_init(QXLInterface *qxl_interface, int id)
dispatcher->base.reset_cursor = qxl_worker_reset_cursor;
dispatcher->base.destroy_surface_wait = qxl_worker_destroy_surface_wait;
qxl_interface->get_init_info(qxl_interface, &init_info);
qxl->st->qif->get_init_info(qxl, &init_info);
init_data.memslot_id_bits = init_info.memslot_id_bits;
init_data.memslot_gen_bits = init_info.memslot_gen_bits;
@ -548,7 +548,7 @@ RedDispatcher *red_dispatcher_init(QXLInterface *qxl_interface, int id)
reds_channel = spice_new0(Channel, 1);
reds_channel->type = SPICE_CHANNEL_DISPLAY;
reds_channel->id = id;
reds_channel->id = qxl->id;
reds_channel->link = red_dispatcher_set_peer;
reds_channel->shutdown = red_dispatcher_shutdown_peer;
reds_channel->migrate = red_dispatcher_migrate;
@ -557,14 +557,14 @@ RedDispatcher *red_dispatcher_init(QXLInterface *qxl_interface, int id)
cursor_channel = spice_new0(Channel, 1);
cursor_channel->type = SPICE_CHANNEL_CURSOR;
cursor_channel->id = id;
cursor_channel->id = qxl->id;
cursor_channel->link = red_dispatcher_set_cursor_peer;
cursor_channel->shutdown = red_dispatcher_shutdown_cursor_peer;
cursor_channel->migrate = red_dispatcher_cursor_migrate;
cursor_channel->data = dispatcher;
reds_register_channel(cursor_channel);
qxl_interface->attache_worker(qxl_interface, &dispatcher->base);
qxl_interface->set_compression_level(qxl_interface, calc_compression_level());
qxl->st->qif->attache_worker(qxl, &dispatcher->base);
qxl->st->qif->set_compression_level(qxl, calc_compression_level());
dispatcher->next = dispatchers;
dispatchers = dispatcher;

View File

@ -19,7 +19,7 @@
#define _H_RED_DISPATCHER
struct RedDispatcher *red_dispatcher_init(QXLInterface *qxl_interface, int id);
struct RedDispatcher *red_dispatcher_init(QXLInstance *qxl);
void red_dispatcher_set_mm_time(uint32_t);
void red_dispatcher_on_ic_change();

View File

@ -921,7 +921,7 @@ typedef struct RedWorker {
EventListener dev_listener;
DisplayChannel *display_channel;
CursorChannel *cursor_channel;
QXLInterface *qxl;
QXLInstance *qxl;
int id;
int channel;
int running;
@ -1508,7 +1508,7 @@ static inline void red_destroy_surface(RedWorker *worker, uint32_t surface_id)
release_info_ext.group_id = surface->release_group_id;
release_info_ext.info = surface->release_info;
worker->qxl->release_resource(worker->qxl, release_info_ext);
worker->qxl->st->qif->release_resource(worker->qxl, release_info_ext);
}
region_destroy(&surface->draw_dirty_region);
@ -1542,7 +1542,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);
worker->qxl->st->qif->release_resource(worker->qxl, release_info_ext);
}
static void remove_depended_item(DependItem *item)
@ -3903,7 +3903,7 @@ static inline void red_process_surface(RedWorker *worker, QXLSurfaceCmd *surface
height, stride, surface->u.surface_create.format, data);
release_info_ext.group_id = group_id;
release_info_ext.info = &surface->release_info;
worker->qxl->release_resource(worker->qxl, release_info_ext);
worker->qxl->st->qif->release_resource(worker->qxl, release_info_ext);
break;
}
case QXL_SURFACE_CMD_DESTROY:
@ -4730,7 +4730,7 @@ static void red_release_cursor(RedWorker *worker, CursorItem *cursor)
cursor_cmd = cursor->qxl_cursor;
release_info_ext.group_id = cursor->group_id;
release_info_ext.info = &cursor_cmd->release_info;
worker->qxl->release_resource(worker->qxl, release_info_ext);
worker->qxl->st->qif->release_resource(worker->qxl, release_info_ext);
free_cursor_item(worker, cursor);
}
}
@ -4836,14 +4836,14 @@ static int red_process_cursor(RedWorker *worker, uint32_t max_pipe_size)
int n = 0;
while (!worker->cursor_channel || worker->cursor_channel->base.pipe_size <= max_pipe_size) {
if (!worker->qxl->get_cursor_command(worker->qxl, &ext_cmd)) {
if (!worker->qxl->st->qif->get_cursor_command(worker->qxl, &ext_cmd)) {
if (worker->repoll_cursor_ring < CMD_RING_POLL_RETRIES) {
worker->repoll_cursor_ring++;
worker->epoll_timeout = MIN(worker->epoll_timeout, CMD_RING_POLL_TIMEOUT);
break;
}
if (worker->repoll_cursor_ring > CMD_RING_POLL_RETRIES ||
worker->qxl->req_cursor_notification(worker->qxl)) {
worker->qxl->st->qif->req_cursor_notification(worker->qxl)) {
worker->repoll_cursor_ring++;
break;
}
@ -4873,14 +4873,14 @@ static int red_process_commands(RedWorker *worker, uint32_t max_pipe_size)
uint64_t start = red_now();
while (!worker->display_channel || worker->display_channel->base.pipe_size <= max_pipe_size) {
if (!worker->qxl->get_command(worker->qxl, &ext_cmd)) {
if (!worker->qxl->st->qif->get_command(worker->qxl, &ext_cmd)) {
if (worker->repoll_cmd_ring < CMD_RING_POLL_RETRIES) {
worker->repoll_cmd_ring++;
worker->epoll_timeout = MIN(worker->epoll_timeout, CMD_RING_POLL_TIMEOUT);
break;
}
if (worker->repoll_cmd_ring > CMD_RING_POLL_RETRIES ||
worker->qxl->req_cmd_notification(worker->qxl)) {
worker->qxl->st->qif->req_cmd_notification(worker->qxl)) {
worker->repoll_cmd_ring++;
break;
}
@ -4904,10 +4904,10 @@ static int red_process_commands(RedWorker *worker, uint32_t max_pipe_size)
surface_id = draw_cmd->surface_id;
validate_surface(worker, surface_id);
red_update_area(worker, &draw_cmd->area, draw_cmd->surface_id);
worker->qxl->notify_update(worker->qxl, draw_cmd->update_id);
worker->qxl->st->qif->notify_update(worker->qxl, draw_cmd->update_id);
release_info_ext.group_id = ext_cmd.group_id;
release_info_ext.info = &draw_cmd->release_info;
worker->qxl->release_resource(worker->qxl, release_info_ext);
worker->qxl->st->qif->release_resource(worker->qxl, release_info_ext);
break;
}
case QXL_CMD_MESSAGE: {
@ -4917,7 +4917,7 @@ static int red_process_commands(RedWorker *worker, uint32_t max_pipe_size)
red_printf("MESSAGE: %s", message->data);
release_info_ext.group_id = ext_cmd.group_id;
release_info_ext.info = &message->release_info;
worker->qxl->release_resource(worker->qxl, release_info_ext);
worker->qxl->st->qif->release_resource(worker->qxl, release_info_ext);
break;
}
case QXL_CMD_SURFACE: {
@ -8098,7 +8098,7 @@ static inline void flush_display_commands(RedWorker *worker)
uint64_t end_time;
red_process_commands(worker, MAX_PIPE_SIZE);
if (!worker->qxl->has_command(worker->qxl)) {
if (!worker->qxl->st->qif->has_command(worker->qxl)) {
break;
}
@ -8106,7 +8106,7 @@ static inline void flush_display_commands(RedWorker *worker)
display_channel_push(worker);
}
if (!worker->qxl->has_command(worker->qxl)) {
if (!worker->qxl->st->qif->has_command(worker->qxl)) {
break;
}
end_time = red_now() + DISPLAY_CLIENT_TIMEOUT * 10;
@ -8869,7 +8869,7 @@ static void red_save_cursor(RedWorker *worker)
cursor_data->data_size = local->data_size;
cursor_data->_cursor.header = local->red_cursor.header;
memcpy(cursor_data->_cursor.data, local->red_cursor.data, local->data_size);
worker->qxl->set_save_data(worker->qxl, cursor_data, size);
worker->qxl->st->qif->set_save_data(worker->qxl, cursor_data, size);
}
static LocalCursor *_new_local_cursor(SpiceCursorHeader *header, int data_size, SpicePoint16 position)
@ -8934,7 +8934,7 @@ static void red_cursor_flush(RedWorker *worker)
static void red_save(RedWorker *worker)
{
if (!worker->cursor) {
worker->qxl->set_save_data(worker->qxl, NULL, 0);
worker->qxl->st->qif->set_save_data(worker->qxl, NULL, 0);
return;
}
red_save_cursor(worker);
@ -8942,7 +8942,7 @@ static void red_save(RedWorker *worker)
static void red_cursor_load(RedWorker *worker)
{
CursorData *cursor_data = worker->qxl->get_save_data(worker->qxl);
CursorData *cursor_data = worker->qxl->st->qif->get_save_data(worker->qxl);
LocalCursor *local;
if (!cursor_data) {
@ -9228,7 +9228,7 @@ static void handle_dev_input(EventListener *listener, uint32_t events)
while (red_process_commands(worker, MAX_PIPE_SIZE)) {
display_channel_push(worker);
}
if (worker->qxl->flush_resources(worker->qxl) == 0) {
if (worker->qxl->st->qif->flush_resources(worker->qxl) == 0) {
red_printf("oom current %u pipe %u", worker->current_size, worker->display_channel ?
worker->display_channel->base.pipe_size : 0);
red_free_some(worker);
@ -9437,7 +9437,7 @@ static void red_init(RedWorker *worker, WorkerInitData *init_data)
ASSERT(sizeof(CursorItem) <= QXL_CURSUR_DEVICE_DATA_SIZE);
memset(worker, 0, sizeof(RedWorker));
worker->qxl = init_data->qxl_interface;
worker->qxl = init_data->qxl;
worker->id = init_data->id;
worker->channel = init_data->channel;
worker->pending = init_data->pending;

View File

@ -83,7 +83,7 @@ enum {
};
typedef struct WorkerInitData {
struct QXLInterface *qxl_interface;
struct QXLInstance *qxl;
int id;
int channel;
uint32_t *pending;

View File

@ -4029,8 +4029,7 @@ static void attach_to_red_agent(VDIPortInterface *interface)
}
__visible__ int spice_server_add_interface(SpiceServer *s,
SpiceBaseInstance *sin,
int id)
SpiceBaseInstance *sin)
{
SpiceBaseInterface *interface = sin->sif;
@ -4083,17 +4082,20 @@ __visible__ int spice_server_add_interface(SpiceServer *s,
red_error("migration register failed");
}
} else if (strcmp(interface->type, VD_INTERFACE_QXL) == 0) {
QXLInterface *qxl_interface;
} else if (strcmp(interface->type, SPICE_INTERFACE_QXL) == 0) {
QXLInstance *qxl;
red_printf("VD_INTERFACE_QXL");
if (interface->major_version != VD_INTERFACE_QXL_MAJOR ||
interface->minor_version < VD_INTERFACE_QXL_MINOR) {
red_printf("SPICE_INTERFACE_QXL");
if (interface->major_version != SPICE_INTERFACE_QXL_MAJOR ||
interface->minor_version < SPICE_INTERFACE_QXL_MINOR) {
red_printf("unsuported qxl interface");
return -1;
}
qxl_interface = (QXLInterface *)interface;
red_dispatcher_init(qxl_interface, id);
qxl = SPICE_CONTAINEROF(sin, QXLInstance, base);
qxl->st = spice_new0(QXLState, 1);
qxl->st->qif = SPICE_CONTAINEROF(interface, QXLInterface, base);
qxl->st->dispatcher = red_dispatcher_init(qxl);
} else if (strcmp(interface->type, VD_INTERFACE_TABLET) == 0) {
red_printf("VD_INTERFACE_TABLET");

View File

@ -66,6 +66,11 @@ struct SpiceMouseState {
int dummy;
};
struct QXLState {
QXLInterface *qif;
struct RedDispatcher *dispatcher;
};
void reds_desable_mm_timer();
void reds_enable_mm_timer();
void reds_update_mm_timer(uint32_t mm_time);

View File

@ -41,8 +41,7 @@ int spice_server_set_tls(SpiceServer *s, int port,
const char *dh_key_file, const char *ciphersuite);
int spice_server_add_interface(SpiceServer *s,
SpiceBaseInstance *sin,
int id);
SpiceBaseInstance *sin);
int spice_server_remove_interface(SpiceBaseInstance *sin);
int spice_server_kbd_leds(SpiceKbdInstance *sin, int leds);

View File

@ -84,11 +84,12 @@ struct SpiceCoreInterface {
};
#define VD_INTERFACE_QXL "qxl"
#define VD_INTERFACE_QXL_MAJOR 3
#define VD_INTERFACE_QXL_MINOR 0
#define SPICE_INTERFACE_QXL "qxl"
#define SPICE_INTERFACE_QXL_MAJOR 3
#define SPICE_INTERFACE_QXL_MINOR 0
typedef struct QXLInterface QXLInterface;
typedef void (*qxl_mode_change_notifier_t)(void *opaque);
typedef struct QXLInstance QXLInstance;
typedef struct QXLState QXLState;
typedef struct QXLWorker QXLWorker;
typedef struct QXLDevMemSlot QXLDevMemSlot;
typedef struct QXLDevSurfaceCreate QXLDevSurfaceCreate;
@ -183,21 +184,27 @@ struct QXLInterface {
uint16_t pci_id;
uint8_t pci_revision;
void (*attache_worker)(QXLInterface *qxl, QXLWorker *qxl_worker);
void (*set_compression_level)(QXLInterface *qxl, int level);
void (*set_mm_time)(QXLInterface *qxl, uint32_t mm_time);
void (*attache_worker)(QXLInstance *qin, QXLWorker *qxl_worker);
void (*set_compression_level)(QXLInstance *qin, int level);
void (*set_mm_time)(QXLInstance *qin, uint32_t mm_time);
void (*get_init_info)(QXLInterface *qxl, QXLDevInitInfo *info);
int (*get_command)(QXLInterface *qxl, struct QXLCommandExt *cmd);
int (*req_cmd_notification)(QXLInterface *qxl);
int (*has_command)(QXLInterface *qxl);
void (*release_resource)(QXLInterface *qxl, struct QXLReleaseInfoExt release_info);
int (*get_cursor_command)(QXLInterface *qxl, struct QXLCommandExt *cmd);
int (*req_cursor_notification)(QXLInterface *qxl);
void (*notify_update)(QXLInterface *qxl, uint32_t update_id);
void (*set_save_data)(QXLInterface *qxl, void *data, int size);
void *(*get_save_data)(QXLInterface *qxl);
int (*flush_resources)(QXLInterface *qxl);
void (*get_init_info)(QXLInstance *qin, QXLDevInitInfo *info);
int (*get_command)(QXLInstance *qin, struct QXLCommandExt *cmd);
int (*req_cmd_notification)(QXLInstance *qin);
int (*has_command)(QXLInstance *qin);
void (*release_resource)(QXLInstance *qin, struct QXLReleaseInfoExt release_info);
int (*get_cursor_command)(QXLInstance *qin, struct QXLCommandExt *cmd);
int (*req_cursor_notification)(QXLInstance *qin);
void (*notify_update)(QXLInstance *qin, uint32_t update_id);
void (*set_save_data)(QXLInstance *qin, void *data, int size);
void *(*get_save_data)(QXLInstance *qin);
int (*flush_resources)(QXLInstance *qin);
};
struct QXLInstance {
SpiceBaseInstance base;
int id;
QXLState *st;
};
#define SPICE_INTERFACE_KEYBOARD "keyboard"