Package: libgvnc-1.0-0
Version: 0.5.0-3.1
Severity: normal
Tags: upstream patch

libgvnc becomes extremely slow with ZRLE encryption. The library spends most
time for memmove operations. Removing memmove significantly increases
performance. See patch.



-- System Information:
Debian Release: 7.1
  APT prefers stable
  APT policy: (700, 'stable'), (600, 'unstable'), (500, 'stable-updates')
Architecture: amd64 (x86_64)

Kernel: Linux 3.9-0.bpo.1-amd64 (SMP w/4 CPU cores)
Locale: LANG=ru_RU.UTF-8, LC_CTYPE=ru_RU.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages libgvnc-1.0-0 depends on:
ii  libc6               2.13-38
ii  libgcrypt11         1.5.0-5+deb7u1
ii  libgdk-pixbuf2.0-0  2.26.1-1
ii  libglib2.0-0        2.33.12+really2.32.4-5
ii  libgnutls26         2.12.20-7
ii  libgpg-error0       1.10-3.1
ii  libpulse0           2.0-6.1
ii  libsasl2-2          2.1.25.dfsg1-6+deb7u1
ii  zlib1g              1:1.2.7.dfsg-13

libgvnc-1.0-0 recommends no packages.

libgvnc-1.0-0 suggests no packages.

-- no debconf information
--- a/src/vncconnection.c	2013-07-20 01:11:58.660247691 +0400
+++ b/src/vncconnection.c	2013-07-20 01:22:33.826646101 +0400
@@ -208,7 +208,8 @@
     z_stream *strm;
     z_stream streams[5];
 
-    size_t uncompressed_length;
+    size_t uncompressed_offset;
+    size_t uncompressed_size;
     guint8 uncompressed_buffer[4096];
 
     size_t compressed_length;
@@ -624,19 +625,15 @@
     while (offset < size) {
         /* if data is available in the uncompressed buffer, then
          * copy */
-        if (priv->uncompressed_length) {
-            size_t len = MIN(priv->uncompressed_length,
+        if (priv->uncompressed_size - priv->uncompressed_offset) {
+            size_t len = MIN(priv->uncompressed_size - priv->uncompressed_offset,
                              size - offset);
 
             memcpy(ptr + offset,
-                   priv->uncompressed_buffer,
+                   priv->uncompressed_buffer + priv->uncompressed_offset,
                    len);
 
-            priv->uncompressed_length -= len;
-            if (priv->uncompressed_length)
-                memmove(priv->uncompressed_buffer,
-                        priv->uncompressed_buffer + len,
-                        priv->uncompressed_length);
+            priv->uncompressed_offset += len;
             offset += len;
         } else {
             int err;
@@ -653,7 +650,8 @@
                 return -1;
             }
 
-            priv->uncompressed_length = (guint8 *)priv->strm->next_out - priv->uncompressed_buffer;
+            priv->uncompressed_offset = 0;
+            priv->uncompressed_size = (guint8 *)priv->strm->next_out - priv->uncompressed_buffer;
             priv->compressed_length -= (guint8 *)priv->strm->next_in - priv->compressed_buffer;
             priv->compressed_buffer = priv->strm->next_in;
         }
@@ -2288,7 +2286,8 @@
     vnc_connection_read(conn, zlib_data, length);
 
     /* setup subsequent calls to vnc_connection_read*() to use the compressed data */
-    priv->uncompressed_length = 0;
+    priv->uncompressed_offset = 0;
+    priv->uncompressed_size = 0;
     priv->compressed_length = length;
     priv->compressed_buffer = zlib_data;
     priv->strm = &priv->streams[0];
@@ -2304,7 +2303,8 @@
     }
 
     priv->strm = NULL;
-    priv->uncompressed_length = 0;
+    priv->uncompressed_offset = 0;
+    priv->uncompressed_size = 0;
     priv->compressed_length = 0;
     priv->compressed_buffer = NULL;
 
@@ -2568,7 +2568,8 @@
 
             vnc_connection_read(conn, zlib_data, zlib_length);
 
-            priv->uncompressed_length = 0;
+            priv->uncompressed_offset = 0;
+            priv->uncompressed_size = 0;
             priv->compressed_length = zlib_length;
             priv->compressed_buffer = zlib_data;
         }
@@ -2592,7 +2593,8 @@
         }
 
         if (data_size >= 12) {
-            priv->uncompressed_length = 0;
+            priv->uncompressed_offset = 0;
+            priv->uncompressed_size = 0;
             priv->compressed_length = 0;
             priv->compressed_buffer = NULL;
 
@@ -4813,7 +4815,8 @@
 
     priv->read_offset = priv->read_size = 0;
     priv->write_offset = 0;
-    priv->uncompressed_length = 0;
+    priv->uncompressed_offset = 0;
+    priv->uncompressed_size = 0;
     priv->compressed_length = 0;
 
     priv->width = priv->height = 0;

Reply via email to