vnc-jobs.c (e2766868d45d8c8f8991cfd133e6a0c14abfe577) vnc-jobs.c (55b400497cf9c79acbb5c01abc58737bc52c081c)
1/*
2 * QEMU VNC display driver
3 *
4 * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
5 * Copyright (C) 2006 Fabrice Bellard
6 * Copyright (C) 2009 Red Hat, Inc
7 * Copyright (C) 2010 Corentin Chary <corentin.chary@gmail.com>
8 *

--- 18 unchanged lines hidden (view full) ---

27
28
29#include "qemu/osdep.h"
30#include "vnc.h"
31#include "vnc-jobs.h"
32#include "qemu/sockets.h"
33#include "qemu/main-loop.h"
34#include "block/aio.h"
1/*
2 * QEMU VNC display driver
3 *
4 * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
5 * Copyright (C) 2006 Fabrice Bellard
6 * Copyright (C) 2009 Red Hat, Inc
7 * Copyright (C) 2010 Corentin Chary <corentin.chary@gmail.com>
8 *

--- 18 unchanged lines hidden (view full) ---

27
28
29#include "qemu/osdep.h"
30#include "vnc.h"
31#include "vnc-jobs.h"
32#include "qemu/sockets.h"
33#include "qemu/main-loop.h"
34#include "block/aio.h"
35#include "trace.h"
35
36/*
37 * Locking:
38 *
39 * There are three levels of locking:
40 * - jobs queue lock: for each operation on the queue (push, pop, isEmpty?)
41 * - VncDisplay global lock: mainly used for framebuffer updates to avoid
42 * screen corruption if the framebuffer is updated

--- 46 unchanged lines hidden (view full) ---

89 vnc_unlock_queue(queue);
90 return job;
91}
92
93int vnc_job_add_rect(VncJob *job, int x, int y, int w, int h)
94{
95 VncRectEntry *entry = g_new0(VncRectEntry, 1);
96
36
37/*
38 * Locking:
39 *
40 * There are three levels of locking:
41 * - jobs queue lock: for each operation on the queue (push, pop, isEmpty?)
42 * - VncDisplay global lock: mainly used for framebuffer updates to avoid
43 * screen corruption if the framebuffer is updated

--- 46 unchanged lines hidden (view full) ---

90 vnc_unlock_queue(queue);
91 return job;
92}
93
94int vnc_job_add_rect(VncJob *job, int x, int y, int w, int h)
95{
96 VncRectEntry *entry = g_new0(VncRectEntry, 1);
97
98 trace_vnc_job_add_rect(job->vs, job, x, y, w, h);
99
97 entry->rect.x = x;
98 entry->rect.y = y;
99 entry->rect.w = w;
100 entry->rect.h = h;
101
102 vnc_lock_queue(queue);
103 QLIST_INSERT_HEAD(&job->rectangles, entry, next);
104 vnc_unlock_queue(queue);

--- 80 unchanged lines hidden (view full) ---

185 local->lossy_rect = orig->lossy_rect;
186 local->write_pixels = orig->write_pixels;
187 local->client_pf = orig->client_pf;
188 local->client_be = orig->client_be;
189 local->tight = orig->tight;
190 local->zlib = orig->zlib;
191 local->hextile = orig->hextile;
192 local->zrle = orig->zrle;
100 entry->rect.x = x;
101 entry->rect.y = y;
102 entry->rect.w = w;
103 entry->rect.h = h;
104
105 vnc_lock_queue(queue);
106 QLIST_INSERT_HEAD(&job->rectangles, entry, next);
107 vnc_unlock_queue(queue);

--- 80 unchanged lines hidden (view full) ---

188 local->lossy_rect = orig->lossy_rect;
189 local->write_pixels = orig->write_pixels;
190 local->client_pf = orig->client_pf;
191 local->client_be = orig->client_be;
192 local->tight = orig->tight;
193 local->zlib = orig->zlib;
194 local->hextile = orig->hextile;
195 local->zrle = orig->zrle;
196 local->client_width = orig->client_width;
197 local->client_height = orig->client_height;
193}
194
195static void vnc_async_encoding_end(VncState *orig, VncState *local)
196{
197 buffer_free(&local->output);
198 orig->tight = local->tight;
199 orig->zlib = local->zlib;
200 orig->hextile = local->hextile;
201 orig->zrle = local->zrle;
202 orig->lossy_rect = local->lossy_rect;
203}
204
198}
199
200static void vnc_async_encoding_end(VncState *orig, VncState *local)
201{
202 buffer_free(&local->output);
203 orig->tight = local->tight;
204 orig->zlib = local->zlib;
205 orig->hextile = local->hextile;
206 orig->zrle = local->zrle;
207 orig->lossy_rect = local->lossy_rect;
208}
209
210static bool vnc_worker_clamp_rect(VncState *vs, VncJob *job, VncRect *rect)
211{
212 trace_vnc_job_clamp_rect(vs, job, rect->x, rect->y, rect->w, rect->h);
213
214 if (rect->x >= vs->client_width) {
215 goto discard;
216 }
217 rect->w = MIN(vs->client_width - rect->x, rect->w);
218 if (rect->w == 0) {
219 goto discard;
220 }
221
222 if (rect->y >= vs->client_height) {
223 goto discard;
224 }
225 rect->h = MIN(vs->client_height - rect->y, rect->h);
226 if (rect->h == 0) {
227 goto discard;
228 }
229
230 trace_vnc_job_clamped_rect(vs, job, rect->x, rect->y, rect->w, rect->h);
231 return true;
232
233 discard:
234 trace_vnc_job_discard_rect(vs, job, rect->x, rect->y, rect->w, rect->h);
235 return false;
236}
237
205static int vnc_worker_thread_loop(VncJobQueue *queue)
206{
207 VncJob *job;
208 VncRectEntry *entry, *tmp;
209 VncState vs = {};
210 int n_rectangles;
211 int saved_offset;
212

--- 42 unchanged lines hidden (view full) ---

255
256 if (job->vs->ioc == NULL) {
257 vnc_unlock_display(job->vs->vd);
258 /* Copy persistent encoding data */
259 vnc_async_encoding_end(job->vs, &vs);
260 goto disconnected;
261 }
262
238static int vnc_worker_thread_loop(VncJobQueue *queue)
239{
240 VncJob *job;
241 VncRectEntry *entry, *tmp;
242 VncState vs = {};
243 int n_rectangles;
244 int saved_offset;
245

--- 42 unchanged lines hidden (view full) ---

288
289 if (job->vs->ioc == NULL) {
290 vnc_unlock_display(job->vs->vd);
291 /* Copy persistent encoding data */
292 vnc_async_encoding_end(job->vs, &vs);
293 goto disconnected;
294 }
295
263 n = vnc_send_framebuffer_update(&vs, entry->rect.x, entry->rect.y,
264 entry->rect.w, entry->rect.h);
296 if (vnc_worker_clamp_rect(&vs, job, &entry->rect)) {
297 n = vnc_send_framebuffer_update(&vs, entry->rect.x, entry->rect.y,
298 entry->rect.w, entry->rect.h);
265
299
266 if (n >= 0) {
267 n_rectangles += n;
300 if (n >= 0) {
301 n_rectangles += n;
302 }
268 }
269 g_free(entry);
270 }
303 }
304 g_free(entry);
305 }
306 trace_vnc_job_nrects(&vs, job, n_rectangles);
271 vnc_unlock_display(job->vs->vd);
272
273 /* Put n_rectangles at the beginning of the message */
274 vs.output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
275 vs.output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
276
277 vnc_lock_output(job->vs);
278 if (job->vs->ioc != NULL) {

--- 68 unchanged lines hidden ---
307 vnc_unlock_display(job->vs->vd);
308
309 /* Put n_rectangles at the beginning of the message */
310 vs.output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
311 vs.output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
312
313 vnc_lock_output(job->vs);
314 if (job->vs->ioc != NULL) {

--- 68 unchanged lines hidden ---