From nobody Sat Nov 15 23:38:09 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1744882951; cv=none; d=zohomail.com; s=zohoarc; b=mpQddLJDO4D0wscPWMhyrErhK9n7cq9dX66bvtYPNCcjIwVvg0+TyFsLH7fT4qhzSHRcgTsK7fJqymiz9ioT6pHDS6zKzdjwQ3Cx017kYsZKPufE32itx3ao+mywUyg+KjoovJsB9BAq0CUKwQHGznXMbRHoT5f20dE0dN0X7Jk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1744882951; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=s1uVPVljvkIQtNRusqALXRBIbeVKCABhO+qziJGICvQ=; b=ZWtcxIuGPh4hOYM2kwgVthjU+/zdw+HtIM7odMC5u8P0qH0/GTcpoxBBTNi+P3csMRrS9EumHxhsQ7l8GBzgLKeu87e6tp/2Ap2ZWyEbeRC9PTvgzLAF3L5UtVUS+D7SUotmRGueNERPWf5vpteP+lBiYWSKKinCOKA+sI4E+zY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1744882951716452.9583735009446; Thu, 17 Apr 2025 02:42:31 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1u5LlF-0007oe-HE; Thu, 17 Apr 2025 05:42:21 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1u5Ll8-0007dF-AJ for qemu-devel@nongnu.org; Thu, 17 Apr 2025 05:42:16 -0400 Received: from mail-pl1-x62a.google.com ([2607:f8b0:4864:20::62a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1u5Ll4-0007wg-9C for qemu-devel@nongnu.org; Thu, 17 Apr 2025 05:42:14 -0400 Received: by mail-pl1-x62a.google.com with SMTP id d9443c01a7336-224019ad9edso9223225ad.1 for ; Thu, 17 Apr 2025 02:42:09 -0700 (PDT) Received: from localhost ([2400:4050:b783:b00:9e36:5f4c:928c:4ec2]) by smtp.gmail.com with UTF8SMTPSA id d9443c01a7336-22c33fccafcsm29111135ad.205.2025.04.17.02.42.06 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 17 Apr 2025 02:42:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1744882928; x=1745487728; darn=nongnu.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=s1uVPVljvkIQtNRusqALXRBIbeVKCABhO+qziJGICvQ=; b=ga3xfjLx54mqZUac0Lwd8oFTKDQsQ6j2A6m0SnEk43WfqsHsLka2vSwcF3iDfQCpyn FlUrHRJEWg8jTtjmmEopHKtB1XrMa+DqxI7XszF/wuuixGox81RZOsK9XHm5nUy4By30 2qhgZsazrOuHZ2uUlUSIspzwXbvHHcg9PlErlzG7/8JvUMELIXrkz0jYAZnLaPUhEqgO K8EeVWvineDgp+9kci4xXHvDKTIJ5AqtZzLTAltb7ViA8yL2ChSa0FHbJmE3Z2OWoTYg AYQ7iYlrZqCfW/TC10zuoiLocEFOKB01tEImbJaeRGqnMhLkJepcVADLxWmkxYwY2amu 8gbw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744882928; x=1745487728; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=s1uVPVljvkIQtNRusqALXRBIbeVKCABhO+qziJGICvQ=; b=EYmoVYaFn08vlt3JOGlgL2AMUY4rANCzJr0g1G7Mw3QkMcH54cZXKzIwvfULeLLSIk wZxsReIfESMtTQONqFdpQ1hx52SJs42nuJBl4KmWIsNa2jsQusHqHtf5mWLMhmePbd3/ lhPNS+XcAKz1TXzmXFf4/G5Q7FtabsZt2+BevjyU31M925UMTo5re0j7Is1E/phqmQFT ds3QIbOuMx3xy/3TAY8gSupBfYRVFkDlmREGvikicMXi2UScyqXE3C12SJOA6XEWNArQ aSc9BnU9udX+L0sX6KpJhiFaCm9eiIjLf++26LEFRv+AHlk16yQAc2/w8I+nQzV/VB8r 4XDQ== X-Gm-Message-State: AOJu0YytR7RUEQMLNpUaCNJiz4cfBdIq+b1nfy75pIjZT/lccWCqfSRb qUM4STfbcihkLdL0ZhOCASBEGfdU7gcGug+V4/RkaoK05cxh5WiQnpdY1X1vcxjgR8dNWRRi7lx V5Q0= X-Gm-Gg: ASbGncuLR/3Jj6Swqy/z8pRRrPvNR6IWnup5DUjBOxpL0Dp2Gkgq+VPldsaxmDUQKWV iKYINKngS/fDDp5F+DTUWj2QNdblDbsdyYWkQeIsvQik4RjnMFGiuXBYYyexNjucq2KK2H8bIdH dQLhJSUwmppe6IoeGMDZWKEa7m7vvoRIb3u6NMRJKhkpUgXOmZRvfFL/LL1T/AFxZSb9Wm1UJUA 2sPymMg1NjM6Jy++EE3PaBXb46yRruIih9cUxAfWe7Jss1d49g25foF5HjAjGNH4NowB8M4HENo wnXnaMn9d9eE1CFeSXbOLBCCNJDZoHpiU4yC9A6UQx4XnCg= X-Google-Smtp-Source: AGHT+IE0HC6sH3FudWShtaubfUq/hvVBX1rQ2kvIJOpp3Uqj9c7RwTm8bVdEITz5WDw8djos1VeXyQ== X-Received: by 2002:a17:903:41cd:b0:220:d078:eb33 with SMTP id d9443c01a7336-22c3596f812mr72821985ad.36.1744882927895; Thu, 17 Apr 2025 02:42:07 -0700 (PDT) From: Akihiko Odaki Date: Thu, 17 Apr 2025 18:42:00 +0900 Subject: [PATCH 1/2] ui/vnc: Introduce the VncWorker type MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250417-zlib-v1-1-34fad73b843b@daynix.com> References: <20250417-zlib-v1-0-34fad73b843b@daynix.com> In-Reply-To: <20250417-zlib-v1-0-34fad73b843b@daynix.com> To: qemu-devel@nongnu.org Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , devel@daynix.com, Akihiko Odaki X-Mailer: b4 0.15-dev-edae6 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::62a; envelope-from=akihiko.odaki@daynix.com; helo=mail-pl1-x62a.google.com X-Spam_score_int: 1 X-Spam_score: 0.1 X-Spam_bar: / X-Spam_report: (0.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, PDS_OTHER_BAD_TLD=1.999, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @daynix-com.20230601.gappssmtp.com) X-ZM-MESSAGEID: 1744882953748019100 The worker thread copies data in VncState to avoid race, but some data are too big to copy. Such data are held with pointers to avoid the overhead to copy, but it requires tedious memory management and makes them vulnerable to race. Introduce the VncWorker type to contain all data shared without copying. It allows allocating and freeing all shared data at once and shows that the race with the worker thread needs to be taken care of when accessing them. Signed-off-by: Akihiko Odaki Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- ui/vnc.h | 12 +- ui/vnc-enc-tight.c | 341 ++++++++++++++++++++++++++--------------------= ---- ui/vnc-enc-zlib.c | 10 +- ui/vnc-enc-zrle.c | 69 +++++----- ui/vnc-jobs.c | 7 +- ui/vnc.c | 56 ++++----- ui/vnc-enc-zrle.c.inc | 2 +- 7 files changed, 245 insertions(+), 252 deletions(-) diff --git a/ui/vnc.h b/ui/vnc.h index acc53a2cc114..1dc76c270c35 100644 --- a/ui/vnc.h +++ b/ui/vnc.h @@ -261,6 +261,13 @@ typedef enum { =20 #define VNC_MAGIC ((uint64_t)0x05b3f069b3d204bb) =20 +typedef struct VncWorker { + uint8_t lossy_rect[VNC_STAT_ROWS][VNC_STAT_COLS]; + + VncTight tight; + VncZrle zrle; +} VncWorker; + struct VncState { uint64_t magic; @@ -270,8 +277,7 @@ struct VncState gboolean disconnecting; =20 DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT], VNC_DIRTY_BITS); - uint8_t **lossy_rect; /* Not an Array to avoid costly memcpy in - * vnc-jobs-async.c */ + VncWorker *worker; =20 VncDisplay *vd; VncStateUpdate update; /* Most recent pending request from client */ @@ -339,10 +345,8 @@ struct VncState /* Encoding specific, if you add something here, don't forget to * update vnc_async_encoding_start() */ - VncTight *tight; VncZlib zlib; VncHextile hextile; - VncZrle *zrle; VncZywrle zywrle; =20 Notifier mouse_mode_notifier; diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c index 41f559eb837e..a8d06a125044 100644 --- a/ui/vnc-enc-tight.c +++ b/ui/vnc-enc-tight.c @@ -116,7 +116,7 @@ static int send_png_rect(VncState *vs, int x, int y, in= t w, int h, =20 static bool tight_can_send_png_rect(VncState *vs, int w, int h) { - if (vs->tight->type !=3D VNC_ENCODING_TIGHT_PNG) { + if (vs->worker->tight.type !=3D VNC_ENCODING_TIGHT_PNG) { return false; } =20 @@ -144,7 +144,7 @@ tight_detect_smooth_image24(VncState *vs, int w, int h) int pixels =3D 0; int pix, left[3]; unsigned int errors; - unsigned char *buf =3D vs->tight->tight.buffer; + unsigned char *buf =3D vs->worker->tight.tight.buffer; =20 /* * If client is big-endian, color samples begin from the second @@ -215,7 +215,7 @@ tight_detect_smooth_image24(VncState *vs, int w, int h) int pixels =3D 0; \ int sample, sum, left[3]; \ unsigned int errors; \ - unsigned char *buf =3D vs->tight->tight.buffer; = \ + unsigned char *buf =3D vs->worker->tight.tight.buffer; \ \ endian =3D 0; /* FIXME */ \ \ @@ -296,8 +296,8 @@ static int tight_detect_smooth_image(VncState *vs, int w, int h) { unsigned int errors; - int compression =3D vs->tight->compression; - int quality =3D vs->tight->quality; + int compression =3D vs->worker->tight.compression; + int quality =3D vs->worker->tight.quality; =20 if (!vs->vd->lossy) { return 0; @@ -309,7 +309,7 @@ tight_detect_smooth_image(VncState *vs, int w, int h) return 0; } =20 - if (vs->tight->quality !=3D (uint8_t)-1) { + if (vs->worker->tight.quality !=3D (uint8_t)-1) { if (w * h < VNC_TIGHT_JPEG_MIN_RECT_SIZE) { return 0; } @@ -320,9 +320,9 @@ tight_detect_smooth_image(VncState *vs, int w, int h) } =20 if (vs->client_pf.bytes_per_pixel =3D=3D 4) { - if (vs->tight->pixel24) { + if (vs->worker->tight.pixel24) { errors =3D tight_detect_smooth_image24(vs, w, h); - if (vs->tight->quality !=3D (uint8_t)-1) { + if (vs->worker->tight.quality !=3D (uint8_t)-1) { return (errors < tight_conf[quality].jpeg_threshold24); } return (errors < tight_conf[compression].gradient_threshold24); @@ -352,7 +352,7 @@ tight_detect_smooth_image(VncState *vs, int w, int h) uint##bpp##_t c0, c1, ci; \ int i, n0, n1; \ \ - data =3D (uint##bpp##_t *)vs->tight->tight.buffer; \ + data =3D (uint##bpp##_t *)vs->worker->tight.tight.buffer; \ \ c0 =3D data[0]; \ i =3D 1; \ @@ -421,11 +421,12 @@ static int tight_fill_palette(VncState *vs, int x, in= t y, size_t count, uint32_t *bg, uint32_t *fg, VncPalette *palette) { + uint8_t compression =3D vs->worker->tight.compression; int max; =20 - max =3D count / tight_conf[vs->tight->compression].idx_max_colors_divi= sor; + max =3D count / tight_conf[compression].idx_max_colors_divisor; if (max < 2 && - count >=3D tight_conf[vs->tight->compression].mono_min_rect_size) { + count >=3D tight_conf[compression].mono_min_rect_size) { max =3D 2; } if (max >=3D 256) { @@ -558,7 +559,7 @@ tight_filter_gradient24(VncState *vs, uint8_t *buf, int= w, int h) int x, y, c; =20 buf32 =3D (uint32_t *)buf; - memset(vs->tight->gradient.buffer, 0, w * 3 * sizeof(int)); + memset(vs->worker->tight.gradient.buffer, 0, w * 3 * sizeof(int)); =20 if (1 /* FIXME */) { shift[0] =3D vs->client_pf.rshift; @@ -575,7 +576,7 @@ tight_filter_gradient24(VncState *vs, uint8_t *buf, int= w, int h) upper[c] =3D 0; here[c] =3D 0; } - prev =3D (int *)vs->tight->gradient.buffer; + prev =3D (int *)vs->worker->tight.gradient.buffer; for (x =3D 0; x < w; x++) { pix32 =3D *buf32++; for (c =3D 0; c < 3; c++) { @@ -602,64 +603,64 @@ tight_filter_gradient24(VncState *vs, uint8_t *buf, i= nt w, int h) * ``Gradient'' filter for other color depths. */ =20 -#define DEFINE_GRADIENT_FILTER_FUNCTION(bpp) \ - \ - static void \ - tight_filter_gradient##bpp(VncState *vs, uint##bpp##_t *buf, \ - int w, int h) { \ - uint##bpp##_t pix, diff; \ - bool endian; \ - int *prev; \ - int max[3], shift[3]; \ - int here[3], upper[3], left[3], upperleft[3]; \ - int prediction; \ - int x, y, c; \ - \ - memset(vs->tight->gradient.buffer, 0, w * 3 * sizeof(int)); \ - \ - endian =3D 0; /* FIXME */ \ - \ - max[0] =3D vs->client_pf.rmax; \ - max[1] =3D vs->client_pf.gmax; \ - max[2] =3D vs->client_pf.bmax; \ - shift[0] =3D vs->client_pf.rshift; \ - shift[1] =3D vs->client_pf.gshift; \ - shift[2] =3D vs->client_pf.bshift; \ - \ - for (y =3D 0; y < h; y++) { \ - for (c =3D 0; c < 3; c++) { \ - upper[c] =3D 0; \ - here[c] =3D 0; \ - } \ - prev =3D (int *)vs->tight->gradient.buffer; = \ - for (x =3D 0; x < w; x++) { \ - pix =3D *buf; \ - if (endian) { \ - pix =3D bswap##bpp(pix); \ - } \ - diff =3D 0; \ - for (c =3D 0; c < 3; c++) { \ - upperleft[c] =3D upper[c]; \ - left[c] =3D here[c]; \ - upper[c] =3D *prev; \ - here[c] =3D (int)(pix >> shift[c] & max[c]); \ - *prev++ =3D here[c]; \ - \ - prediction =3D left[c] + upper[c] - upperleft[c]; \ - if (prediction < 0) { \ - prediction =3D 0; \ - } else if (prediction > max[c]) { \ - prediction =3D max[c]; \ - } \ - diff |=3D ((here[c] - prediction) & max[c]) \ - << shift[c]; \ - } \ - if (endian) { \ - diff =3D bswap##bpp(diff); \ - } \ - *buf++ =3D diff; \ - } \ - } \ +#define DEFINE_GRADIENT_FILTER_FUNCTION(bpp) = \ + = \ + static void = \ + tight_filter_gradient##bpp(VncState *vs, uint##bpp##_t *buf, = \ + int w, int h) { = \ + uint##bpp##_t pix, diff; = \ + bool endian; = \ + int *prev; = \ + int max[3], shift[3]; = \ + int here[3], upper[3], left[3], upperleft[3]; = \ + int prediction; = \ + int x, y, c; = \ + = \ + memset(vs->worker->tight.gradient.buffer, 0, w * 3 * sizeof(int));= \ + = \ + endian =3D 0; /* FIXME */ = \ + = \ + max[0] =3D vs->client_pf.rmax; = \ + max[1] =3D vs->client_pf.gmax; = \ + max[2] =3D vs->client_pf.bmax; = \ + shift[0] =3D vs->client_pf.rshift; = \ + shift[1] =3D vs->client_pf.gshift; = \ + shift[2] =3D vs->client_pf.bshift; = \ + = \ + for (y =3D 0; y < h; y++) { = \ + for (c =3D 0; c < 3; c++) { = \ + upper[c] =3D 0; = \ + here[c] =3D 0; = \ + } = \ + prev =3D (int *)vs->worker->tight.gradient.buffer; = \ + for (x =3D 0; x < w; x++) { = \ + pix =3D *buf; = \ + if (endian) { = \ + pix =3D bswap##bpp(pix); = \ + } = \ + diff =3D 0; = \ + for (c =3D 0; c < 3; c++) { = \ + upperleft[c] =3D upper[c]; = \ + left[c] =3D here[c]; = \ + upper[c] =3D *prev; = \ + here[c] =3D (int)(pix >> shift[c] & max[c]); = \ + *prev++ =3D here[c]; = \ + = \ + prediction =3D left[c] + upper[c] - upperleft[c]; = \ + if (prediction < 0) { = \ + prediction =3D 0; = \ + } else if (prediction > max[c]) { = \ + prediction =3D max[c]; = \ + } = \ + diff |=3D ((here[c] - prediction) & max[c]) = \ + << shift[c]; = \ + } = \ + if (endian) { = \ + diff =3D bswap##bpp(diff); = \ + } = \ + *buf++ =3D diff; = \ + } = \ + } = \ } =20 DEFINE_GRADIENT_FILTER_FUNCTION(16) @@ -785,7 +786,7 @@ static void extend_solid_area(VncState *vs, int x, int = y, int w, int h, static int tight_init_stream(VncState *vs, int stream_id, int level, int strategy) { - z_streamp zstream =3D &vs->tight->stream[stream_id]; + z_streamp zstream =3D &vs->worker->tight.stream[stream_id]; =20 if (zstream->opaque =3D=3D NULL) { int err; @@ -803,15 +804,15 @@ static int tight_init_stream(VncState *vs, int stream= _id, return -1; } =20 - vs->tight->levels[stream_id] =3D level; + vs->worker->tight.levels[stream_id] =3D level; zstream->opaque =3D vs; } =20 - if (vs->tight->levels[stream_id] !=3D level) { + if (vs->worker->tight.levels[stream_id] !=3D level) { if (deflateParams(zstream, level, strategy) !=3D Z_OK) { return -1; } - vs->tight->levels[stream_id] =3D level; + vs->worker->tight.levels[stream_id] =3D level; } return 0; } @@ -839,11 +840,12 @@ static void tight_send_compact_size(VncState *vs, siz= e_t len) static int tight_compress_data(VncState *vs, int stream_id, size_t bytes, int level, int strategy) { - z_streamp zstream =3D &vs->tight->stream[stream_id]; + VncTight *tight =3D &vs->worker->tight; + z_streamp zstream =3D &vs->worker->tight.stream[stream_id]; int previous_out; =20 if (bytes < VNC_TIGHT_MIN_TO_COMPRESS) { - vnc_write(vs, vs->tight->tight.buffer, vs->tight->tight.offset); + vnc_write(vs, tight->tight.buffer, tight->tight.offset); return bytes; } =20 @@ -852,13 +854,13 @@ static int tight_compress_data(VncState *vs, int stre= am_id, size_t bytes, } =20 /* reserve memory in output buffer */ - buffer_reserve(&vs->tight->zlib, bytes + 64); + buffer_reserve(&tight->zlib, bytes + 64); =20 /* set pointers */ - zstream->next_in =3D vs->tight->tight.buffer; - zstream->avail_in =3D vs->tight->tight.offset; - zstream->next_out =3D vs->tight->zlib.buffer + vs->tight->zlib.offset; - zstream->avail_out =3D vs->tight->zlib.capacity - vs->tight->zlib.offs= et; + zstream->next_in =3D tight->tight.buffer; + zstream->avail_in =3D tight->tight.offset; + zstream->next_out =3D tight->zlib.buffer + tight->zlib.offset; + zstream->avail_out =3D tight->zlib.capacity - tight->zlib.offset; previous_out =3D zstream->avail_out; zstream->data_type =3D Z_BINARY; =20 @@ -868,14 +870,14 @@ static int tight_compress_data(VncState *vs, int stre= am_id, size_t bytes, return -1; } =20 - vs->tight->zlib.offset =3D vs->tight->zlib.capacity - zstream->avail_o= ut; + tight->zlib.offset =3D tight->zlib.capacity - zstream->avail_out; /* ...how much data has actually been produced by deflate() */ bytes =3D previous_out - zstream->avail_out; =20 tight_send_compact_size(vs, bytes); - vnc_write(vs, vs->tight->zlib.buffer, bytes); + vnc_write(vs, tight->zlib.buffer, bytes); =20 - buffer_reset(&vs->tight->zlib); + buffer_reset(&tight->zlib); =20 return bytes; } @@ -916,6 +918,7 @@ static void tight_pack24(VncState *vs, uint8_t *buf, si= ze_t count, size_t *ret) =20 static int send_full_color_rect(VncState *vs, int x, int y, int w, int h) { + int level =3D tight_conf[vs->worker->tight.compression].raw_zlib_level; int stream =3D 0; ssize_t bytes; =20 @@ -927,16 +930,15 @@ static int send_full_color_rect(VncState *vs, int x, = int y, int w, int h) =20 vnc_write_u8(vs, stream << 4); /* no flushing, no filter */ =20 - if (vs->tight->pixel24) { - tight_pack24(vs, vs->tight->tight.buffer, w * h, - &vs->tight->tight.offset); + if (vs->worker->tight.pixel24) { + tight_pack24(vs, vs->worker->tight.tight.buffer, w * h, + &vs->worker->tight.tight.offset); bytes =3D 3; } else { bytes =3D vs->client_pf.bytes_per_pixel; } =20 - bytes =3D tight_compress_data(vs, stream, w * h * bytes, - tight_conf[vs->tight->compression].raw_zlib_le= vel, + bytes =3D tight_compress_data(vs, stream, w * h * bytes, level, Z_DEFAULT_STRATEGY); =20 return (bytes >=3D 0); @@ -944,18 +946,19 @@ static int send_full_color_rect(VncState *vs, int x, = int y, int w, int h) =20 static int send_solid_rect(VncState *vs) { + VncTight *tight =3D &vs->worker->tight; size_t bytes; =20 vnc_write_u8(vs, VNC_TIGHT_FILL << 4); /* no flushing, no filter */ =20 - if (vs->tight->pixel24) { - tight_pack24(vs, vs->tight->tight.buffer, 1, &vs->tight->tight.off= set); + if (tight->pixel24) { + tight_pack24(vs, tight->tight.buffer, 1, &tight->tight.offset); bytes =3D 3; } else { bytes =3D vs->client_pf.bytes_per_pixel; } =20 - vnc_write(vs, vs->tight->tight.buffer, bytes); + vnc_write(vs, tight->tight.buffer, bytes); return 1; } =20 @@ -964,7 +967,7 @@ static int send_mono_rect(VncState *vs, int x, int y, { ssize_t bytes; int stream =3D 1; - int level =3D tight_conf[vs->tight->compression].mono_zlib_level; + int level =3D tight_conf[vs->worker->tight.compression].mono_zlib_leve= l; =20 #ifdef CONFIG_PNG if (tight_can_send_png_rect(vs, w, h)) { @@ -992,26 +995,26 @@ static int send_mono_rect(VncState *vs, int x, int y, uint32_t buf[2] =3D {bg, fg}; size_t ret =3D sizeof (buf); =20 - if (vs->tight->pixel24) { + if (vs->worker->tight.pixel24) { tight_pack24(vs, (unsigned char*)buf, 2, &ret); } vnc_write(vs, buf, ret); =20 - tight_encode_mono_rect32(vs->tight->tight.buffer, w, h, bg, fg); + tight_encode_mono_rect32(vs->worker->tight.tight.buffer, w, h, bg,= fg); break; } case 2: vnc_write(vs, &bg, 2); vnc_write(vs, &fg, 2); - tight_encode_mono_rect16(vs->tight->tight.buffer, w, h, bg, fg); + tight_encode_mono_rect16(vs->worker->tight.tight.buffer, w, h, bg,= fg); break; default: vnc_write_u8(vs, bg); vnc_write_u8(vs, fg); - tight_encode_mono_rect8(vs->tight->tight.buffer, w, h, bg, fg); + tight_encode_mono_rect8(vs->worker->tight.tight.buffer, w, h, bg, = fg); break; } - vs->tight->tight.offset =3D bytes; + vs->worker->tight.tight.offset =3D bytes; =20 bytes =3D tight_compress_data(vs, stream, bytes, level, Z_DEFAULT_STRA= TEGY); return (bytes >=3D 0); @@ -1040,8 +1043,9 @@ static void write_palette(int idx, uint32_t color, vo= id *opaque) =20 static bool send_gradient_rect(VncState *vs, int x, int y, int w, int h) { + VncTight *tight =3D &vs->worker->tight; int stream =3D 3; - int level =3D tight_conf[vs->tight->compression].gradient_zlib_level; + int level =3D tight_conf[tight->compression].gradient_zlib_level; ssize_t bytes; =20 if (vs->client_pf.bytes_per_pixel =3D=3D 1) { @@ -1051,23 +1055,23 @@ static bool send_gradient_rect(VncState *vs, int x,= int y, int w, int h) vnc_write_u8(vs, (stream | VNC_TIGHT_EXPLICIT_FILTER) << 4); vnc_write_u8(vs, VNC_TIGHT_FILTER_GRADIENT); =20 - buffer_reserve(&vs->tight->gradient, w * 3 * sizeof(int)); + buffer_reserve(&tight->gradient, w * 3 * sizeof(int)); =20 - if (vs->tight->pixel24) { - tight_filter_gradient24(vs, vs->tight->tight.buffer, w, h); + if (tight->pixel24) { + tight_filter_gradient24(vs, tight->tight.buffer, w, h); bytes =3D 3; } else if (vs->client_pf.bytes_per_pixel =3D=3D 4) { - tight_filter_gradient32(vs, (uint32_t *)vs->tight->tight.buffer, w= , h); + tight_filter_gradient32(vs, (uint32_t *)tight->tight.buffer, w, h); bytes =3D 4; } else { - tight_filter_gradient16(vs, (uint16_t *)vs->tight->tight.buffer, w= , h); + tight_filter_gradient16(vs, (uint16_t *)tight->tight.buffer, w, h); bytes =3D 2; } =20 - buffer_reset(&vs->tight->gradient); + buffer_reset(&tight->gradient); =20 bytes =3D w * h * bytes; - vs->tight->tight.offset =3D bytes; + tight->tight.offset =3D bytes; =20 bytes =3D tight_compress_data(vs, stream, bytes, level, Z_FILTERED); @@ -1077,8 +1081,9 @@ static bool send_gradient_rect(VncState *vs, int x, i= nt y, int w, int h) static int send_palette_rect(VncState *vs, int x, int y, int w, int h, VncPalette *palette) { + VncTight *tight =3D &vs->worker->tight; int stream =3D 2; - int level =3D tight_conf[vs->tight->compression].idx_zlib_level; + int level =3D tight_conf[tight->compression].idx_zlib_level; int colors; ssize_t bytes; =20 @@ -1105,12 +1110,12 @@ static int send_palette_rect(VncState *vs, int x, i= nt y, palette_iter(palette, write_palette, &priv); vnc_write(vs, header, palette_sz * sizeof(uint32_t)); =20 - if (vs->tight->pixel24) { + if (tight->pixel24) { tight_pack24(vs, vs->output.buffer + old_offset, colors, &offs= et); vs->output.offset =3D old_offset + offset; } =20 - tight_encode_indexed_rect32(vs->tight->tight.buffer, w * h, palett= e); + tight_encode_indexed_rect32(tight->tight.buffer, w * h, palette); break; } case 2: @@ -1121,14 +1126,14 @@ static int send_palette_rect(VncState *vs, int x, i= nt y, =20 palette_iter(palette, write_palette, &priv); vnc_write(vs, header, palette_sz * sizeof(uint16_t)); - tight_encode_indexed_rect16(vs->tight->tight.buffer, w * h, palett= e); + tight_encode_indexed_rect16(tight->tight.buffer, w * h, palette); break; } default: return -1; /* No palette for 8bits colors */ } bytes =3D w * h; - vs->tight->tight.offset =3D bytes; + tight->tight.offset =3D bytes; =20 bytes =3D tight_compress_data(vs, stream, bytes, level, Z_DEFAULT_STRATEGY); @@ -1147,7 +1152,7 @@ static int send_palette_rect(VncState *vs, int x, int= y, static void jpeg_init_destination(j_compress_ptr cinfo) { VncState *vs =3D cinfo->client_data; - Buffer *buffer =3D &vs->tight->jpeg; + Buffer *buffer =3D &vs->worker->tight.jpeg; =20 cinfo->dest->next_output_byte =3D (JOCTET *)buffer->buffer + buffer->o= ffset; cinfo->dest->free_in_buffer =3D (size_t)(buffer->capacity - buffer->of= fset); @@ -1157,7 +1162,7 @@ static void jpeg_init_destination(j_compress_ptr cinf= o) static boolean jpeg_empty_output_buffer(j_compress_ptr cinfo) { VncState *vs =3D cinfo->client_data; - Buffer *buffer =3D &vs->tight->jpeg; + Buffer *buffer =3D &vs->worker->tight.jpeg; =20 buffer->offset =3D buffer->capacity; buffer_reserve(buffer, 2048); @@ -1169,7 +1174,7 @@ static boolean jpeg_empty_output_buffer(j_compress_pt= r cinfo) static void jpeg_term_destination(j_compress_ptr cinfo) { VncState *vs =3D cinfo->client_data; - Buffer *buffer =3D &vs->tight->jpeg; + Buffer *buffer =3D &vs->worker->tight.jpeg; =20 buffer->offset =3D buffer->capacity - cinfo->dest->free_in_buffer; } @@ -1188,7 +1193,7 @@ static int send_jpeg_rect(VncState *vs, int x, int y,= int w, int h, int quality) return send_full_color_rect(vs, x, y, w, h); } =20 - buffer_reserve(&vs->tight->jpeg, 2048); + buffer_reserve(&vs->worker->tight.jpeg, 2048); =20 cinfo.err =3D jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); @@ -1223,9 +1228,9 @@ static int send_jpeg_rect(VncState *vs, int x, int y,= int w, int h, int quality) =20 vnc_write_u8(vs, VNC_TIGHT_JPEG << 4); =20 - tight_send_compact_size(vs, vs->tight->jpeg.offset); - vnc_write(vs, vs->tight->jpeg.buffer, vs->tight->jpeg.offset); - buffer_reset(&vs->tight->jpeg); + tight_send_compact_size(vs, vs->worker->tight.jpeg.offset); + vnc_write(vs, vs->worker->tight.jpeg.buffer, vs->worker->tight.jpeg.of= fset); + buffer_reset(&vs->worker->tight.jpeg); =20 return 1; } @@ -1241,7 +1246,7 @@ static void write_png_palette(int idx, uint32_t pix, = void *opaque) VncState *vs =3D priv->vs; png_colorp color =3D &priv->png_palette[idx]; =20 - if (vs->tight->pixel24) + if (vs->worker->tight.pixel24) { color->red =3D (pix >> vs->client_pf.rshift) & vs->client_pf.rmax; color->green =3D (pix >> vs->client_pf.gshift) & vs->client_pf.gma= x; @@ -1266,12 +1271,12 @@ static void write_png_palette(int idx, uint32_t pix= , void *opaque) static void png_write_data(png_structp png_ptr, png_bytep data, png_size_t length) { - VncState *vs =3D png_get_io_ptr(png_ptr); + VncWorker *worker =3D png_get_io_ptr(png_ptr); =20 - buffer_reserve(&vs->tight->png, vs->tight->png.offset + length); - memcpy(vs->tight->png.buffer + vs->tight->png.offset, data, length); + buffer_reserve(&worker->tight.png, worker->tight.png.offset + length); + memcpy(worker->tight.png.buffer + worker->tight.png.offset, data, leng= th); =20 - vs->tight->png.offset +=3D length; + worker->tight.png.offset +=3D length; } =20 static void png_flush_data(png_structp png_ptr) @@ -1296,8 +1301,8 @@ static int send_png_rect(VncState *vs, int x, int y, = int w, int h, png_infop info_ptr; png_colorp png_palette =3D NULL; pixman_image_t *linebuf; - int level =3D tight_png_conf[vs->tight->compression].png_zlib_level; - int filters =3D tight_png_conf[vs->tight->compression].png_filters; + int level =3D tight_png_conf[vs->worker->tight.compression].png_zlib_l= evel; + int filters =3D tight_png_conf[vs->worker->tight.compression].png_filt= ers; uint8_t *buf; int dy; =20 @@ -1314,7 +1319,7 @@ static int send_png_rect(VncState *vs, int x, int y, = int w, int h, return -1; } =20 - png_set_write_fn(png_ptr, (void *) vs, png_write_data, png_flush_data); + png_set_write_fn(png_ptr, vs->worker, png_write_data, png_flush_data); png_set_compression_level(png_ptr, level); png_set_filter(png_ptr, PNG_FILTER_TYPE_DEFAULT, filters); =20 @@ -1341,23 +1346,23 @@ static int send_png_rect(VncState *vs, int x, int y= , int w, int h, png_set_PLTE(png_ptr, info_ptr, png_palette, palette_size(palette)= ); =20 if (vs->client_pf.bytes_per_pixel =3D=3D 4) { - tight_encode_indexed_rect32(vs->tight->tight.buffer, w * h, + tight_encode_indexed_rect32(vs->worker->tight.tight.buffer, w = * h, palette); } else { - tight_encode_indexed_rect16(vs->tight->tight.buffer, w * h, + tight_encode_indexed_rect16(vs->worker->tight.tight.buffer, w = * h, palette); } } =20 png_write_info(png_ptr, info_ptr); =20 - buffer_reserve(&vs->tight->png, 2048); + buffer_reserve(&vs->worker->tight.png, 2048); linebuf =3D qemu_pixman_linebuf_create(PIXMAN_BE_r8g8b8, w); buf =3D (uint8_t *)pixman_image_get_data(linebuf); for (dy =3D 0; dy < h; dy++) { if (color_type =3D=3D PNG_COLOR_TYPE_PALETTE) { - memcpy(buf, vs->tight->tight.buffer + (dy * w), w); + memcpy(buf, vs->worker->tight.tight.buffer + (dy * w), w); } else { qemu_pixman_linebuf_fill(linebuf, vs->vd->server, w, x, y + dy= ); } @@ -1375,27 +1380,27 @@ static int send_png_rect(VncState *vs, int x, int y= , int w, int h, =20 vnc_write_u8(vs, VNC_TIGHT_PNG << 4); =20 - tight_send_compact_size(vs, vs->tight->png.offset); - vnc_write(vs, vs->tight->png.buffer, vs->tight->png.offset); - buffer_reset(&vs->tight->png); + tight_send_compact_size(vs, vs->worker->tight.png.offset); + vnc_write(vs, vs->worker->tight.png.buffer, vs->worker->tight.png.offs= et); + buffer_reset(&vs->worker->tight.png); return 1; } #endif /* CONFIG_PNG */ =20 static void vnc_tight_start(VncState *vs) { - buffer_reset(&vs->tight->tight); + buffer_reset(&vs->worker->tight.tight); =20 // make the output buffer be the zlib buffer, so we can compress it la= ter - vs->tight->tmp =3D vs->output; - vs->output =3D vs->tight->tight; + vs->worker->tight.tmp =3D vs->output; + vs->output =3D vs->worker->tight.tight; } =20 static void vnc_tight_stop(VncState *vs) { // switch back to normal output/zlib buffers - vs->tight->tight =3D vs->output; - vs->output =3D vs->tight->tmp; + vs->worker->tight.tight =3D vs->output; + vs->output =3D vs->worker->tight.tmp; } =20 static int send_sub_rect_nojpeg(VncState *vs, int x, int y, int w, int h, @@ -1429,9 +1434,9 @@ static int send_sub_rect_jpeg(VncState *vs, int x, in= t y, int w, int h, int ret; =20 if (colors =3D=3D 0) { - if (force || (tight_jpeg_conf[vs->tight->quality].jpeg_full && + if (force || (tight_jpeg_conf[vs->worker->tight.quality].jpeg_full= && tight_detect_smooth_image(vs, w, h))) { - int quality =3D tight_conf[vs->tight->quality].jpeg_quality; + int quality =3D tight_conf[vs->worker->tight.quality].jpeg_qua= lity; =20 ret =3D send_jpeg_rect(vs, x, y, w, h, quality); } else { @@ -1443,9 +1448,9 @@ static int send_sub_rect_jpeg(VncState *vs, int x, in= t y, int w, int h, ret =3D send_mono_rect(vs, x, y, w, h, bg, fg); } else if (colors <=3D 256) { if (force || (colors > 96 && - tight_jpeg_conf[vs->tight->quality].jpeg_idx && + tight_jpeg_conf[vs->worker->tight.quality].jpeg_idx = && tight_detect_smooth_image(vs, w, h))) { - int quality =3D tight_conf[vs->tight->quality].jpeg_quality; + int quality =3D tight_conf[vs->worker->tight.quality].jpeg_qua= lity; =20 ret =3D send_jpeg_rect(vs, x, y, w, h, quality); } else { @@ -1469,6 +1474,7 @@ static void vnc_tight_cleanup(Notifier *n, void *valu= e) =20 static int send_sub_rect(VncState *vs, int x, int y, int w, int h) { + VncTight *tight =3D &vs->worker->tight; uint32_t bg =3D 0, fg =3D 0; int colors; int ret =3D 0; @@ -1483,20 +1489,20 @@ static int send_sub_rect(VncState *vs, int x, int y= , int w, int h) qemu_thread_atexit_add(&vnc_tight_cleanup_notifier); } =20 - vnc_framebuffer_update(vs, x, y, w, h, vs->tight->type); + vnc_framebuffer_update(vs, x, y, w, h, tight->type); =20 vnc_tight_start(vs); vnc_raw_send_framebuffer_update(vs, x, y, w, h); vnc_tight_stop(vs); =20 #ifdef CONFIG_VNC_JPEG - if (!vs->vd->non_adaptive && vs->tight->quality !=3D (uint8_t)-1) { + if (!vs->vd->non_adaptive && tight->quality !=3D (uint8_t)-1) { double freq =3D vnc_update_freq(vs, x, y, w, h); =20 - if (freq < tight_jpeg_conf[vs->tight->quality].jpeg_freq_min) { + if (freq < tight_jpeg_conf[tight->quality].jpeg_freq_min) { allow_jpeg =3D false; } - if (freq >=3D tight_jpeg_conf[vs->tight->quality].jpeg_freq_thresh= old) { + if (freq >=3D tight_jpeg_conf[tight->quality].jpeg_freq_threshold)= { force_jpeg =3D true; vnc_sent_lossy_rect(vs, x, y, w, h); } @@ -1506,7 +1512,7 @@ static int send_sub_rect(VncState *vs, int x, int y, = int w, int h) colors =3D tight_fill_palette(vs, x, y, w * h, &bg, &fg, color_count_p= alette); =20 #ifdef CONFIG_VNC_JPEG - if (allow_jpeg && vs->tight->quality !=3D (uint8_t)-1) { + if (allow_jpeg && tight->quality !=3D (uint8_t)-1) { ret =3D send_sub_rect_jpeg(vs, x, y, w, h, bg, fg, colors, color_count_palette, force_jpeg); } else { @@ -1523,7 +1529,7 @@ static int send_sub_rect(VncState *vs, int x, int y, = int w, int h) =20 static int send_sub_rect_solid(VncState *vs, int x, int y, int w, int h) { - vnc_framebuffer_update(vs, x, y, w, h, vs->tight->type); + vnc_framebuffer_update(vs, x, y, w, h, vs->worker->tight.type); =20 vnc_tight_start(vs); vnc_raw_send_framebuffer_update(vs, x, y, w, h); @@ -1541,8 +1547,8 @@ static int send_rect_simple(VncState *vs, int x, int = y, int w, int h, int rw, rh; int n =3D 0; =20 - max_size =3D tight_conf[vs->tight->compression].max_rect_size; - max_width =3D tight_conf[vs->tight->compression].max_rect_width; + max_size =3D tight_conf[vs->worker->tight.compression].max_rect_size; + max_width =3D tight_conf[vs->worker->tight.compression].max_rect_width; =20 if (split && (w > max_width || w * h > max_size)) { max_sub_width =3D (w > max_width) ? max_width : w; @@ -1647,20 +1653,21 @@ static int find_large_solid_color_rect(VncState *vs= , int x, int y, static int tight_send_framebuffer_update(VncState *vs, int x, int y, int w, int h) { + VncTight *tight =3D &vs->worker->tight; int max_rows; =20 if (vs->client_pf.bytes_per_pixel =3D=3D 4 && vs->client_pf.rmax =3D= =3D 0xFF && vs->client_pf.bmax =3D=3D 0xFF && vs->client_pf.gmax =3D=3D 0xFF) { - vs->tight->pixel24 =3D true; + tight->pixel24 =3D true; } else { - vs->tight->pixel24 =3D false; + tight->pixel24 =3D false; } =20 #ifdef CONFIG_VNC_JPEG - if (vs->tight->quality !=3D (uint8_t)-1) { + if (tight->quality !=3D (uint8_t)-1) { double freq =3D vnc_update_freq(vs, x, y, w, h); =20 - if (freq > tight_jpeg_conf[vs->tight->quality].jpeg_freq_threshold= ) { + if (freq > tight_jpeg_conf[tight->quality].jpeg_freq_threshold) { return send_rect_simple(vs, x, y, w, h, false); } } @@ -1672,8 +1679,8 @@ static int tight_send_framebuffer_update(VncState *vs= , int x, int y, =20 /* Calculate maximum number of rows in one non-solid rectangle. */ =20 - max_rows =3D tight_conf[vs->tight->compression].max_rect_size; - max_rows /=3D MIN(tight_conf[vs->tight->compression].max_rect_width, w= ); + max_rows =3D tight_conf[tight->compression].max_rect_size; + max_rows /=3D MIN(tight_conf[tight->compression].max_rect_width, w); =20 return find_large_solid_color_rect(vs, x, y, w, h, max_rows); } @@ -1681,33 +1688,33 @@ static int tight_send_framebuffer_update(VncState *= vs, int x, int y, int vnc_tight_send_framebuffer_update(VncState *vs, int x, int y, int w, int h) { - vs->tight->type =3D VNC_ENCODING_TIGHT; + vs->worker->tight.type =3D VNC_ENCODING_TIGHT; return tight_send_framebuffer_update(vs, x, y, w, h); } =20 int vnc_tight_png_send_framebuffer_update(VncState *vs, int x, int y, int w, int h) { - vs->tight->type =3D VNC_ENCODING_TIGHT_PNG; + vs->worker->tight.type =3D VNC_ENCODING_TIGHT_PNG; return tight_send_framebuffer_update(vs, x, y, w, h); } =20 void vnc_tight_clear(VncState *vs) { int i; - for (i =3D 0; i < ARRAY_SIZE(vs->tight->stream); i++) { - if (vs->tight->stream[i].opaque) { - deflateEnd(&vs->tight->stream[i]); + for (i =3D 0; i < ARRAY_SIZE(vs->worker->tight.stream); i++) { + if (vs->worker->tight.stream[i].opaque) { + deflateEnd(&vs->worker->tight.stream[i]); } } =20 - buffer_free(&vs->tight->tight); - buffer_free(&vs->tight->zlib); - buffer_free(&vs->tight->gradient); + buffer_free(&vs->worker->tight.tight); + buffer_free(&vs->worker->tight.zlib); + buffer_free(&vs->worker->tight.gradient); #ifdef CONFIG_VNC_JPEG - buffer_free(&vs->tight->jpeg); + buffer_free(&vs->worker->tight.jpeg); #endif #ifdef CONFIG_PNG - buffer_free(&vs->tight->png); + buffer_free(&vs->worker->tight.png); #endif } diff --git a/ui/vnc-enc-zlib.c b/ui/vnc-enc-zlib.c index 900ae5b30f6b..605030730a44 100644 --- a/ui/vnc-enc-zlib.c +++ b/ui/vnc-enc-zlib.c @@ -76,7 +76,7 @@ static int vnc_zlib_stop(VncState *vs) zstream->zalloc =3D vnc_zlib_zalloc; zstream->zfree =3D vnc_zlib_zfree; =20 - err =3D deflateInit2(zstream, vs->tight->compression, Z_DEFLATED, + err =3D deflateInit2(zstream, vs->worker->tight.compression, Z_DEF= LATED, MAX_WBITS, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY); =20 @@ -85,16 +85,16 @@ static int vnc_zlib_stop(VncState *vs) return -1; } =20 - vs->zlib.level =3D vs->tight->compression; + vs->zlib.level =3D vs->worker->tight.compression; zstream->opaque =3D vs; } =20 - if (vs->tight->compression !=3D vs->zlib.level) { - if (deflateParams(zstream, vs->tight->compression, + if (vs->worker->tight.compression !=3D vs->zlib.level) { + if (deflateParams(zstream, vs->worker->tight.compression, Z_DEFAULT_STRATEGY) !=3D Z_OK) { return -1; } - vs->zlib.level =3D vs->tight->compression; + vs->zlib.level =3D vs->worker->tight.compression; } =20 // reserve memory in output buffer diff --git a/ui/vnc-enc-zrle.c b/ui/vnc-enc-zrle.c index bd33b890639f..4ed3d17d17a0 100644 --- a/ui/vnc-enc-zrle.c +++ b/ui/vnc-enc-zrle.c @@ -37,18 +37,18 @@ static const int bits_per_packed_pixel[] =3D { =20 static void vnc_zrle_start(VncState *vs) { - buffer_reset(&vs->zrle->zrle); + buffer_reset(&vs->worker->zrle.zrle); =20 /* make the output buffer be the zlib buffer, so we can compress it la= ter */ - vs->zrle->tmp =3D vs->output; - vs->output =3D vs->zrle->zrle; + vs->worker->zrle.tmp =3D vs->output; + vs->output =3D vs->worker->zrle.zrle; } =20 static void vnc_zrle_stop(VncState *vs) { /* switch back to normal output/zlib buffers */ - vs->zrle->zrle =3D vs->output; - vs->output =3D vs->zrle->tmp; + vs->worker->zrle.zrle =3D vs->output; + vs->output =3D vs->worker->zrle.tmp; } =20 static void *zrle_convert_fb(VncState *vs, int x, int y, int w, int h, @@ -56,24 +56,25 @@ static void *zrle_convert_fb(VncState *vs, int x, int y= , int w, int h, { Buffer tmp; =20 - buffer_reset(&vs->zrle->fb); - buffer_reserve(&vs->zrle->fb, w * h * bpp + bpp); + buffer_reset(&vs->worker->zrle.fb); + buffer_reserve(&vs->worker->zrle.fb, w * h * bpp + bpp); =20 tmp =3D vs->output; - vs->output =3D vs->zrle->fb; + vs->output =3D vs->worker->zrle.fb; =20 vnc_raw_send_framebuffer_update(vs, x, y, w, h); =20 - vs->zrle->fb =3D vs->output; + vs->worker->zrle.fb =3D vs->output; vs->output =3D tmp; - return vs->zrle->fb.buffer; + return vs->worker->zrle.fb.buffer; } =20 static int zrle_compress_data(VncState *vs, int level) { - z_streamp zstream =3D &vs->zrle->stream; + VncZrle *zrle =3D &vs->worker->zrle; + z_streamp zstream =3D &zrle->stream; =20 - buffer_reset(&vs->zrle->zlib); + buffer_reset(&zrle->zlib); =20 if (zstream->opaque !=3D vs) { int err; @@ -93,13 +94,13 @@ static int zrle_compress_data(VncState *vs, int level) } =20 /* reserve memory in output buffer */ - buffer_reserve(&vs->zrle->zlib, vs->zrle->zrle.offset + 64); + buffer_reserve(&zrle->zlib, zrle->zrle.offset + 64); =20 /* set pointers */ - zstream->next_in =3D vs->zrle->zrle.buffer; - zstream->avail_in =3D vs->zrle->zrle.offset; - zstream->next_out =3D vs->zrle->zlib.buffer; - zstream->avail_out =3D vs->zrle->zlib.capacity; + zstream->next_in =3D zrle->zrle.buffer; + zstream->avail_in =3D zrle->zrle.offset; + zstream->next_out =3D zrle->zlib.buffer; + zstream->avail_out =3D zrle->zlib.capacity; zstream->data_type =3D Z_BINARY; =20 /* start encoding */ @@ -108,8 +109,8 @@ static int zrle_compress_data(VncState *vs, int level) return -1; } =20 - vs->zrle->zlib.offset =3D vs->zrle->zlib.capacity - zstream->avail_out; - return vs->zrle->zlib.offset; + zrle->zlib.offset =3D zrle->zlib.capacity - zstream->avail_out; + return zrle->zlib.offset; } =20 /* Try to work out whether to use RLE and/or a palette. We do this by @@ -259,14 +260,14 @@ static int zrle_send_framebuffer_update(VncState *vs,= int x, int y, size_t bytes; int zywrle_level; =20 - if (vs->zrle->type =3D=3D VNC_ENCODING_ZYWRLE) { - if (!vs->vd->lossy || vs->tight->quality =3D=3D (uint8_t)-1 - || vs->tight->quality =3D=3D 9) { + if (vs->worker->zrle.type =3D=3D VNC_ENCODING_ZYWRLE) { + if (!vs->vd->lossy || vs->worker->tight.quality =3D=3D (uint8_t)-1 + || vs->worker->tight.quality =3D=3D 9) { zywrle_level =3D 0; - vs->zrle->type =3D VNC_ENCODING_ZRLE; - } else if (vs->tight->quality < 3) { + vs->worker->zrle.type =3D VNC_ENCODING_ZRLE; + } else if (vs->worker->tight.quality < 3) { zywrle_level =3D 3; - } else if (vs->tight->quality < 6) { + } else if (vs->worker->tight.quality < 6) { zywrle_level =3D 2; } else { zywrle_level =3D 1; @@ -337,30 +338,30 @@ static int zrle_send_framebuffer_update(VncState *vs,= int x, int y, =20 vnc_zrle_stop(vs); bytes =3D zrle_compress_data(vs, Z_DEFAULT_COMPRESSION); - vnc_framebuffer_update(vs, x, y, w, h, vs->zrle->type); + vnc_framebuffer_update(vs, x, y, w, h, vs->worker->zrle.type); vnc_write_u32(vs, bytes); - vnc_write(vs, vs->zrle->zlib.buffer, vs->zrle->zlib.offset); + vnc_write(vs, vs->worker->zrle.zlib.buffer, vs->worker->zrle.zlib.offs= et); return 1; } =20 int vnc_zrle_send_framebuffer_update(VncState *vs, int x, int y, int w, in= t h) { - vs->zrle->type =3D VNC_ENCODING_ZRLE; + vs->worker->zrle.type =3D VNC_ENCODING_ZRLE; return zrle_send_framebuffer_update(vs, x, y, w, h); } =20 int vnc_zywrle_send_framebuffer_update(VncState *vs, int x, int y, int w, = int h) { - vs->zrle->type =3D VNC_ENCODING_ZYWRLE; + vs->worker->zrle.type =3D VNC_ENCODING_ZYWRLE; return zrle_send_framebuffer_update(vs, x, y, w, h); } =20 void vnc_zrle_clear(VncState *vs) { - if (vs->zrle->stream.opaque) { - deflateEnd(&vs->zrle->stream); + if (vs->worker->zrle.stream.opaque) { + deflateEnd(&vs->worker->zrle.stream); } - buffer_free(&vs->zrle->zrle); - buffer_free(&vs->zrle->fb); - buffer_free(&vs->zrle->zlib); + buffer_free(&vs->worker->zrle.zrle); + buffer_free(&vs->worker->zrle.fb); + buffer_free(&vs->worker->zrle.zlib); } diff --git a/ui/vnc-jobs.c b/ui/vnc-jobs.c index fcca7ec632b1..d019d88536b7 100644 --- a/ui/vnc-jobs.c +++ b/ui/vnc-jobs.c @@ -185,14 +185,12 @@ static void vnc_async_encoding_start(VncState *orig, = VncState *local) local->vnc_encoding =3D orig->vnc_encoding; local->features =3D orig->features; local->vd =3D orig->vd; - local->lossy_rect =3D orig->lossy_rect; + local->worker =3D orig->worker; local->write_pixels =3D orig->write_pixels; local->client_pf =3D orig->client_pf; local->client_be =3D orig->client_be; - local->tight =3D orig->tight; local->zlib =3D orig->zlib; local->hextile =3D orig->hextile; - local->zrle =3D orig->zrle; local->client_width =3D orig->client_width; local->client_height =3D orig->client_height; } @@ -200,11 +198,8 @@ static void vnc_async_encoding_start(VncState *orig, V= ncState *local) static void vnc_async_encoding_end(VncState *orig, VncState *local) { buffer_free(&local->output); - orig->tight =3D local->tight; orig->zlib =3D local->zlib; orig->hextile =3D local->hextile; - orig->zrle =3D local->zrle; - orig->lossy_rect =3D local->lossy_rect; } =20 static bool vnc_worker_clamp_rect(VncState *vs, VncJob *job, VncRect *rect) diff --git a/ui/vnc.c b/ui/vnc.c index 9241caaad96b..ce0538f3654f 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -1308,8 +1308,6 @@ static void vnc_disconnect_start(VncState *vs) =20 void vnc_disconnect_finish(VncState *vs) { - int i; - trace_vnc_client_disconnect_finish(vs, vs->ioc); =20 vnc_jobs_join(vs); /* Wait encoding jobs */ @@ -1352,18 +1350,13 @@ void vnc_disconnect_finish(VncState *vs) } buffer_free(&vs->jobs_buffer); =20 - for (i =3D 0; i < VNC_STAT_ROWS; ++i) { - g_free(vs->lossy_rect[i]); - } - g_free(vs->lossy_rect); + g_free(vs->worker); =20 object_unref(OBJECT(vs->ioc)); vs->ioc =3D NULL; object_unref(OBJECT(vs->sioc)); vs->sioc =3D NULL; vs->magic =3D 0; - g_free(vs->zrle); - g_free(vs->tight); g_free(vs); } =20 @@ -2133,8 +2126,8 @@ static void set_encodings(VncState *vs, int32_t *enco= dings, size_t n_encodings) =20 vs->features =3D 0; vs->vnc_encoding =3D 0; - vs->tight->compression =3D 9; - vs->tight->quality =3D -1; /* Lossless by default */ + vs->worker->tight.compression =3D 9; + vs->worker->tight.quality =3D -1; /* Lossless by default */ vs->absolute =3D -1; =20 /* @@ -2222,11 +2215,11 @@ static void set_encodings(VncState *vs, int32_t *en= codings, size_t n_encodings) vnc_server_cut_text_caps(vs); break; case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 += 9: - vs->tight->compression =3D (enc & 0x0F); + vs->worker->tight.compression =3D (enc & 0x0F); break; case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9: if (vs->vd->lossy) { - vs->tight->quality =3D (enc & 0x0F); + vs->worker->tight.quality =3D (enc & 0x0F); } break; default: @@ -2965,7 +2958,7 @@ void vnc_sent_lossy_rect(VncState *vs, int x, int y, = int w, int h) =20 for (j =3D y; j <=3D h; j++) { for (i =3D x; i <=3D w; i++) { - vs->lossy_rect[j][i] =3D 1; + vs->worker->lossy_rect[j][i] =3D 1; } } } @@ -2988,11 +2981,11 @@ static int vnc_refresh_lossy_rect(VncDisplay *vd, i= nt x, int y) continue; } =20 - if (!vs->lossy_rect[sty][stx]) { + if (!vs->worker->lossy_rect[sty][stx]) { continue; } =20 - vs->lossy_rect[sty][stx] =3D 0; + vs->worker->lossy_rect[sty][stx] =3D 0; for (j =3D 0; j < VNC_STAT_RECT; ++j) { bitmap_set(vs->dirty[y + j], x / VNC_DIRTY_PIXELS_PER_BIT, @@ -3244,11 +3237,9 @@ static void vnc_connect(VncDisplay *vd, QIOChannelSo= cket *sioc, { VncState *vs =3D g_new0(VncState, 1); bool first_client =3D QTAILQ_EMPTY(&vd->clients); - int i; =20 trace_vnc_client_connect(vs, sioc); - vs->zrle =3D g_new0(VncZrle, 1); - vs->tight =3D g_new0(VncTight, 1); + vs->worker =3D g_new0(VncWorker, 1); vs->magic =3D VNC_MAGIC; vs->sioc =3D sioc; object_ref(OBJECT(vs->sioc)); @@ -3256,23 +3247,23 @@ static void vnc_connect(VncDisplay *vd, QIOChannelS= ocket *sioc, object_ref(OBJECT(vs->ioc)); vs->vd =3D vd; =20 - buffer_init(&vs->input, "vnc-input/%p", sioc); - buffer_init(&vs->output, "vnc-output/%p", sioc); - buffer_init(&vs->jobs_buffer, "vnc-jobs_buffer/%p", sioc); + buffer_init(&vs->input, "vnc-input/%p", sioc); + buffer_init(&vs->output, "vnc-output/%p", sioc); + buffer_init(&vs->jobs_buffer, "vnc-jobs_buffer/%p", sioc); =20 - buffer_init(&vs->tight->tight, "vnc-tight/%p", sioc); - buffer_init(&vs->tight->zlib, "vnc-tight-zlib/%p", sioc); - buffer_init(&vs->tight->gradient, "vnc-tight-gradient/%p", sioc); + buffer_init(&vs->worker->tight.tight, "vnc-tight/%p", sioc); + buffer_init(&vs->worker->tight.zlib, "vnc-tight-zlib/%p", sioc); + buffer_init(&vs->worker->tight.gradient, "vnc-tight-gradient/%p", sioc= ); #ifdef CONFIG_VNC_JPEG - buffer_init(&vs->tight->jpeg, "vnc-tight-jpeg/%p", sioc); + buffer_init(&vs->worker->tight.jpeg, "vnc-tight-jpeg/%p", sioc); #endif #ifdef CONFIG_PNG - buffer_init(&vs->tight->png, "vnc-tight-png/%p", sioc); + buffer_init(&vs->worker->tight.png, "vnc-tight-png/%p", sioc); #endif - buffer_init(&vs->zlib.zlib, "vnc-zlib/%p", sioc); - buffer_init(&vs->zrle->zrle, "vnc-zrle/%p", sioc); - buffer_init(&vs->zrle->fb, "vnc-zrle-fb/%p", sioc); - buffer_init(&vs->zrle->zlib, "vnc-zrle-zlib/%p", sioc); + buffer_init(&vs->zlib.zlib, "vnc-zlib/%p", sioc); + buffer_init(&vs->worker->zrle.zrle, "vnc-zrle/%p", sioc); + buffer_init(&vs->worker->zrle.fb, "vnc-zrle-fb/%p", sioc); + buffer_init(&vs->worker->zrle.zlib, "vnc-zrle-zlib/%p", sioc); =20 if (skipauth) { vs->auth =3D VNC_AUTH_NONE; @@ -3289,11 +3280,6 @@ static void vnc_connect(VncDisplay *vd, QIOChannelSo= cket *sioc, VNC_DEBUG("Client sioc=3D%p ws=3D%d auth=3D%d subauth=3D%d\n", sioc, websocket, vs->auth, vs->subauth); =20 - vs->lossy_rect =3D g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect)); - for (i =3D 0; i < VNC_STAT_ROWS; ++i) { - vs->lossy_rect[i] =3D g_new0(uint8_t, VNC_STAT_COLS); - } - VNC_DEBUG("New client on socket %p\n", vs->sioc); update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE); qio_channel_set_blocking(vs->ioc, false, NULL); diff --git a/ui/vnc-enc-zrle.c.inc b/ui/vnc-enc-zrle.c.inc index 2ef7501d5216..964beef74bdd 100644 --- a/ui/vnc-enc-zrle.c.inc +++ b/ui/vnc-enc-zrle.c.inc @@ -96,7 +96,7 @@ static void ZRLE_ENCODE(VncState *vs, int x, int y, int w= , int h, static void ZRLE_ENCODE_TILE(VncState *vs, ZRLE_PIXEL *data, int w, int h, int zywrle_level) { - VncPalette *palette =3D &vs->zrle->palette; + VncPalette *palette =3D &vs->worker->zrle.palette; =20 int runs =3D 0; int single_pixels =3D 0; --=20 2.49.0 From nobody Sat Nov 15 23:38:09 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1744882943; cv=none; d=zohomail.com; s=zohoarc; b=EGmYu1yVsh1kY7s+2WMWK8cjCZcJuMdrXnPnh1jNpIbxunL+MPWvog+mcc7+/M/AK9JW1H0P5Nzx2ErcMa+yIpT1SBJ8bdfZyXjarN5v06E/O21ydlAYrq6rZjbtgqExWAH1/vvMA7Rnh4AlRH57xchWySapb3bxRWQRjrcESF8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1744882943; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=CJoboHjY6J+jdcgbJlQKuZWK2SjqrcVgmsi0cNijwro=; b=dja6HYM4X1N+ruVyzQqpER3+HMmq004yVEitVoJXw+pFrJdXb2kvezZNge0q4NM42mkJ3vrB5oHfWCBGPFcguX0cdxKInkEhwneZaKdnxtrg1E86DuPd0+/YeKO3+Zvs+Mn+y4ouH3cD8x4Kql99KBhDCu0NQCi/5TpAVwkelr8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 174488294296587.53731063823068; Thu, 17 Apr 2025 02:42:22 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1u5LlD-0007k1-CN; Thu, 17 Apr 2025 05:42:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1u5Ll9-0007dg-E3 for qemu-devel@nongnu.org; Thu, 17 Apr 2025 05:42:16 -0400 Received: from mail-pl1-x62a.google.com ([2607:f8b0:4864:20::62a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1u5Ll7-0007xF-Bl for qemu-devel@nongnu.org; Thu, 17 Apr 2025 05:42:15 -0400 Received: by mail-pl1-x62a.google.com with SMTP id d9443c01a7336-22435603572so5923305ad.1 for ; Thu, 17 Apr 2025 02:42:12 -0700 (PDT) Received: from localhost ([2400:4050:b783:b00:9e36:5f4c:928c:4ec2]) by smtp.gmail.com with UTF8SMTPSA id d2e1a72fcca58-73bd21e1957sm11841296b3a.78.2025.04.17.02.42.10 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 17 Apr 2025 02:42:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20230601.gappssmtp.com; s=20230601; t=1744882931; x=1745487731; darn=nongnu.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=CJoboHjY6J+jdcgbJlQKuZWK2SjqrcVgmsi0cNijwro=; b=pPSbt1yWWep+U2iuYUU7AZ+ir5Al7huE9NuorQmyNTmJl+0FKyqzheAB9iQ7Aq1i13 d0PeSV8TDJEiiTAAebr2XRL385TiK08l+gXeLKJLdq+/Op69sQ3dkvg4cWHk8AS0UV9O y1cZQBypmVEWFNKolNNLVzBGbeoymYis4v/f0VgCOijtHOGpffPEVYcNRkpS9aLzczAn Yt2XXx/NzA7RNQf/EGP43m/x4u/yGQ21NEqVKsTbPYPbf/xVG9uvw1rzNvd+GqdCqUsb DIRgvIUmp8kJNGWPQM1wv5jkOS/6dEpRXSqvzn4lcZe9q/N7UgLqv7p9EtLZG/rkOx8f B7xg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744882931; x=1745487731; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=CJoboHjY6J+jdcgbJlQKuZWK2SjqrcVgmsi0cNijwro=; b=TZQV/1WaGHm9Kh2wbzw9BsWJco4Gj4DBkhdX7CqmC0E+RLlRLCL9UP7qI7ZxnD4BcH qxzIMZfozu7iiJSQKozbh9Aij79Vi/XPy1d4BI6X7/5x1lU8iSNFDE4UPmyzho1oH4vi qxz0Dv905FGcIKiNzLAwr0BXit5A1aKSv5t5pNu6/sgz9Y80rBZS3jEv0qDKkbr30P0j VnkUHgnT4SX73cn9aVDJjWEB5cBLXuaGeblXnPK2NMvOV5YWILHIMRs8pvo0Msq74zu1 a+voofdmsd5waPmsjLh35CSjWEE3KjAQmexXjr8GrjFqbQLSm4JFDyZyzX/jw5rV/yFB O8ug== X-Gm-Message-State: AOJu0YyG5/dma6Q/1vdsc8/jrLqPo1slWPkyOgNAP/KlKvygn43uk4dB njyDmOuuD7lbfx+XIHze3QjpPD7a29d2e3BrJdbko+o0VROi2lO7UA0IBPVXt7fNvQ9GXdfKm2O W+/k= X-Gm-Gg: ASbGncuchKf+flIbYH1u62HCJnor+o3/YqHbezUPN5CQhlacnogEHFzTOFk26dGBDvI XNpuqLbSQJxUF0m9k40EbQi6IvTYq2yor6oq0Z5zuO+McIrr5TsoLMwhtmuj/ZefOtciSDqcqbc I57cGNhthXSNQgw59dW4b4xJlzwOv8R6cqmc7IjkmrZNuZhnnIB92Ub/9tq5VYSCMqV8tcR0Nak T9P4/zeAFvTJrwyAxmNvrDbTZnc4bWx7xAAydpXEMT+WS3kHRMB1zXAZZvbLjXBU70ShjKj8byp xe6QaA5U2v5SOgNnit0TTzdorHkd8pSYPjfJ9fCAgf4wzK9NqCVthrflAw== X-Google-Smtp-Source: AGHT+IFPKpVZ7B6Q+BslnifdAlqBMI/sddIoY1J+TEctzVr3eF8QK49v8kuJgaaYXmsLslVrdjhATA== X-Received: by 2002:a17:902:f68b:b0:211:e812:3948 with SMTP id d9443c01a7336-22c3579bae9mr84711395ad.0.1744882931337; Thu, 17 Apr 2025 02:42:11 -0700 (PDT) From: Akihiko Odaki Date: Thu, 17 Apr 2025 18:42:01 +0900 Subject: [PATCH 2/2] ui/vnc: Do not copy z_stream MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250417-zlib-v1-2-34fad73b843b@daynix.com> References: <20250417-zlib-v1-0-34fad73b843b@daynix.com> In-Reply-To: <20250417-zlib-v1-0-34fad73b843b@daynix.com> To: qemu-devel@nongnu.org Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , devel@daynix.com, Akihiko Odaki X-Mailer: b4 0.15-dev-edae6 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::62a; envelope-from=akihiko.odaki@daynix.com; helo=mail-pl1-x62a.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @daynix-com.20230601.gappssmtp.com) X-ZM-MESSAGEID: 1744882944460019000 vnc_worker_thread_loop() copies z_stream stored in its local VncState to the persistent VncState, and the copied one is freed with deflateEnd() later. However, deflateEnd() refuses to operate with a copied z_stream and returns Z_STREAM_ERROR, leaking the allocated memory. Avoid copying the zlib state to fix the memory leak. Fixes: bd023f953e5e ("vnc: threaded VNC server") Signed-off-by: Akihiko Odaki Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- ui/vnc.h | 2 +- ui/vnc-enc-zlib.c | 30 +++++++++++++++--------------- ui/vnc-jobs.c | 2 -- ui/vnc.c | 2 +- 4 files changed, 17 insertions(+), 19 deletions(-) diff --git a/ui/vnc.h b/ui/vnc.h index 1dc76c270c35..78a5fdfdc0d0 100644 --- a/ui/vnc.h +++ b/ui/vnc.h @@ -265,6 +265,7 @@ typedef struct VncWorker { uint8_t lossy_rect[VNC_STAT_ROWS][VNC_STAT_COLS]; =20 VncTight tight; + VncZlib zlib; VncZrle zrle; } VncWorker; =20 @@ -345,7 +346,6 @@ struct VncState /* Encoding specific, if you add something here, don't forget to * update vnc_async_encoding_start() */ - VncZlib zlib; VncHextile hextile; VncZywrle zywrle; =20 diff --git a/ui/vnc-enc-zlib.c b/ui/vnc-enc-zlib.c index 605030730a44..d8b4cf038b02 100644 --- a/ui/vnc-enc-zlib.c +++ b/ui/vnc-enc-zlib.c @@ -48,21 +48,21 @@ void vnc_zlib_zfree(void *x, void *addr) =20 static void vnc_zlib_start(VncState *vs) { - buffer_reset(&vs->zlib.zlib); + buffer_reset(&vs->worker->zlib.zlib); =20 // make the output buffer be the zlib buffer, so we can compress it la= ter - vs->zlib.tmp =3D vs->output; - vs->output =3D vs->zlib.zlib; + vs->worker->zlib.tmp =3D vs->output; + vs->output =3D vs->worker->zlib.zlib; } =20 static int vnc_zlib_stop(VncState *vs) { - z_streamp zstream =3D &vs->zlib.stream; + z_streamp zstream =3D &vs->worker->zlib.stream; int previous_out; =20 // switch back to normal output/zlib buffers - vs->zlib.zlib =3D vs->output; - vs->output =3D vs->zlib.tmp; + vs->worker->zlib.zlib =3D vs->output; + vs->output =3D vs->worker->zlib.tmp; =20 // compress the zlib buffer =20 @@ -85,24 +85,24 @@ static int vnc_zlib_stop(VncState *vs) return -1; } =20 - vs->zlib.level =3D vs->worker->tight.compression; + vs->worker->zlib.level =3D vs->worker->tight.compression; zstream->opaque =3D vs; } =20 - if (vs->worker->tight.compression !=3D vs->zlib.level) { + if (vs->worker->tight.compression !=3D vs->worker->zlib.level) { if (deflateParams(zstream, vs->worker->tight.compression, Z_DEFAULT_STRATEGY) !=3D Z_OK) { return -1; } - vs->zlib.level =3D vs->worker->tight.compression; + vs->worker->zlib.level =3D vs->worker->tight.compression; } =20 // reserve memory in output buffer - buffer_reserve(&vs->output, vs->zlib.zlib.offset + 64); + buffer_reserve(&vs->output, vs->worker->zlib.zlib.offset + 64); =20 // set pointers - zstream->next_in =3D vs->zlib.zlib.buffer; - zstream->avail_in =3D vs->zlib.zlib.offset; + zstream->next_in =3D vs->worker->zlib.zlib.buffer; + zstream->avail_in =3D vs->worker->zlib.zlib.offset; zstream->next_out =3D vs->output.buffer + vs->output.offset; zstream->avail_out =3D vs->output.capacity - vs->output.offset; previous_out =3D zstream->avail_out; @@ -147,8 +147,8 @@ int vnc_zlib_send_framebuffer_update(VncState *vs, int = x, int y, int w, int h) =20 void vnc_zlib_clear(VncState *vs) { - if (vs->zlib.stream.opaque) { - deflateEnd(&vs->zlib.stream); + if (vs->worker->zlib.stream.opaque) { + deflateEnd(&vs->worker->zlib.stream); } - buffer_free(&vs->zlib.zlib); + buffer_free(&vs->worker->zlib.zlib); } diff --git a/ui/vnc-jobs.c b/ui/vnc-jobs.c index d019d88536b7..dbbf62212c79 100644 --- a/ui/vnc-jobs.c +++ b/ui/vnc-jobs.c @@ -189,7 +189,6 @@ static void vnc_async_encoding_start(VncState *orig, Vn= cState *local) local->write_pixels =3D orig->write_pixels; local->client_pf =3D orig->client_pf; local->client_be =3D orig->client_be; - local->zlib =3D orig->zlib; local->hextile =3D orig->hextile; local->client_width =3D orig->client_width; local->client_height =3D orig->client_height; @@ -198,7 +197,6 @@ static void vnc_async_encoding_start(VncState *orig, Vn= cState *local) static void vnc_async_encoding_end(VncState *orig, VncState *local) { buffer_free(&local->output); - orig->zlib =3D local->zlib; orig->hextile =3D local->hextile; } =20 diff --git a/ui/vnc.c b/ui/vnc.c index ce0538f3654f..2203312fcbc9 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -3260,7 +3260,7 @@ static void vnc_connect(VncDisplay *vd, QIOChannelSoc= ket *sioc, #ifdef CONFIG_PNG buffer_init(&vs->worker->tight.png, "vnc-tight-png/%p", sioc); #endif - buffer_init(&vs->zlib.zlib, "vnc-zlib/%p", sioc); + buffer_init(&vs->worker->zlib.zlib, "vnc-zlib/%p", sioc); buffer_init(&vs->worker->zrle.zrle, "vnc-zrle/%p", sioc); buffer_init(&vs->worker->zrle.fb, "vnc-zrle-fb/%p", sioc); buffer_init(&vs->worker->zrle.zlib, "vnc-zrle-zlib/%p", sioc); --=20 2.49.0