summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/red_dispatcher.c9
-rw-r--r--server/red_worker.c33
-rw-r--r--server/vd_interface.h6
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);