diff options
Diffstat (limited to 'server')
-rw-r--r-- | server/red_dispatcher.c | 9 | ||||
-rw-r--r-- | server/red_worker.c | 33 | ||||
-rw-r--r-- | server/vd_interface.h | 6 |
3 files changed, 39 insertions, 9 deletions
diff --git a/server/red_dispatcher.c b/server/red_dispatcher.c index 2930dea4..5b719bd0 100644 --- a/server/red_dispatcher.c +++ b/server/red_dispatcher.c @@ -199,12 +199,19 @@ static void update_client_mouse_allowed() } } -static void qxl_worker_update_area(QXLWorker *qxl_worker) +static void qxl_worker_update_area(QXLWorker *qxl_worker, uint32_t surface_id, + SpiceRect *area, SpiceRect *dirty_rects, + uint32_t num_dirty_rects, uint32_t clear_dirty_region) { RedDispatcher *dispatcher = (RedDispatcher *)qxl_worker; RedWorkeMessage message = RED_WORKER_MESSAGE_UPDATE; write_message(dispatcher->channel, &message); + send_data(dispatcher->channel, &surface_id, sizeof(uint32_t)); + send_data(dispatcher->channel, &area, sizeof(SpiceRect *)); + send_data(dispatcher->channel, &dirty_rects, sizeof(SpiceRect *)); + send_data(dispatcher->channel, &num_dirty_rects, sizeof(uint32_t)); + send_data(dispatcher->channel, &clear_dirty_region, sizeof(uint32_t)); read_message(dispatcher->channel, &message); ASSERT(message == RED_WORKER_MESSAGE_READY); } diff --git a/server/red_worker.c b/server/red_worker.c index 03f3d32f..28927285 100644 --- a/server/red_worker.c +++ b/server/red_worker.c @@ -885,6 +885,7 @@ typedef struct RedSurface { DrawContext context; Ring depend_on_me; + QRegion draw_dirty_region; //fix me - better handling here QXLReleaseInfo *release_info; @@ -1505,6 +1506,7 @@ static inline void red_destroy_surface(RedWorker *worker, uint32_t surface_id) worker->qxl->release_resource(worker->qxl, release_info_ext); } + region_destroy(&surface->draw_dirty_region); surface->context.canvas = NULL; red_destroy_surface_item(worker, surface_id); } @@ -4315,6 +4317,8 @@ static void red_draw_qxl_drawable(RedWorker *worker, Drawable *drawable) worker->preload_group_id = drawable->group_id; + region_add(&surface->draw_dirty_region, &drawable->qxl_drawable->bbox); + localize_clip(worker, &clip, drawable->group_id); switch (drawable->qxl_drawable->type) { case QXL_DRAW_FILL: { @@ -7961,6 +7965,7 @@ static inline void red_create_surface(RedWorker *worker, uint32_t surface_id, ui ring_init(&surface->current_list); ring_init(&surface->depend_on_me); ring_init(&surface->glz_drawables); + region_init(&surface->draw_dirty_region); surface->refs = 1; if (worker->renderer != RED_RENDERER_INVALID) { surface->context.canvas = create_canvas_for_surface(worker, surface, worker->renderer, @@ -8890,16 +8895,32 @@ static inline void handle_dev_update(RedWorker *worker) { RedWorkeMessage message; const SpiceRect *rect; - uint32_t *surface_id; - uint32_t _surface_id; + SpiceRect *dirty_rects; + RedSurface *surface; + uint32_t num_dirty_rects; + uint32_t surface_id; + uint32_t clear_dirty_region; + + receive_data(worker->channel, &surface_id, sizeof(uint32_t)); + receive_data(worker->channel, &rect, sizeof(SpiceRect *)); + receive_data(worker->channel, &dirty_rects, sizeof(SpiceRect *)); + receive_data(worker->channel, &num_dirty_rects, sizeof(uint32_t)); + receive_data(worker->channel, &clear_dirty_region, sizeof(uint32_t)); flush_display_commands(worker); - worker->qxl->get_update_area(worker->qxl, &rect, &surface_id); ASSERT(worker->running); - _surface_id = *surface_id; - validate_surface(worker, _surface_id); - red_update_area(worker, rect, _surface_id); + + validate_surface(worker, surface_id); + red_update_area(worker, rect, surface_id); + + surface = &worker->surfaces[surface_id]; + region_ret_rects(&surface->draw_dirty_region, dirty_rects, num_dirty_rects); + + if (clear_dirty_region) { + region_clear(&surface->draw_dirty_region); + } + message = RED_WORKER_MESSAGE_READY; write_message(worker->channel, &message); } diff --git a/server/vd_interface.h b/server/vd_interface.h index 6d76b9ec..25ff007e 100644 --- a/server/vd_interface.h +++ b/server/vd_interface.h @@ -104,6 +104,7 @@ union QXLReleaseInfo; struct QXLReleaseInfoExt; struct QXLCommand; struct QXLCommandExt; +struct SpiceRect; struct QXLWorker { uint32_t minor_version; uint32_t major_version; @@ -113,7 +114,9 @@ struct QXLWorker { void (*load)(QXLWorker *worker); void (*start)(QXLWorker *worker); void (*stop)(QXLWorker *worker); - void (*update_area)(QXLWorker *worker); + void (*update_area)(QXLWorker *qxl_worker, uint32_t surface_id, + struct SpiceRect *area, struct SpiceRect *dirty_rects, + uint32_t num_dirty_rects, uint32_t clear_dirty_region); void (*add_memslot)(QXLWorker *worker, QXLDevMemSlot *slot); void (*del_memslot)(QXLWorker *worker, uint32_t slot_group_id, uint32_t slot_id); void (*reset_memslots)(QXLWorker *worker); @@ -199,7 +202,6 @@ struct QXLInterface { 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 (*get_update_area)(QXLInterface *qxl, const struct SpiceRect **rect, uint32_t **surface_id); 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); |