aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Hinz <bphinz@users.sourceforge.net>2011-10-30 14:08:29 +0000
committerBrian Hinz <bphinz@users.sourceforge.net>2011-10-30 14:08:29 +0000
commitad78f752566d6cf699cf492641bae73e509e420b (patch)
tree96f9965954fe772f3c43b3bfc784f414f5b7de24
parent1bb8b6c88e9add2771a56bfa56f4d9426d93edad (diff)
downloadtigervnc-ad78f752566d6cf699cf492641bae73e509e420b.tar.gz
tigervnc-ad78f752566d6cf699cf492641bae73e509e420b.zip
massive performance improvements. zrle measured at 2.5x faster (no measurements for tight, but should be the same or better).
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4742 3789f03b-4d11-0410-bbf8-ca57d06f2519
-rw-r--r--java/com/tigervnc/rdr/InStream.java30
-rw-r--r--java/com/tigervnc/rdr/JavaInStream.java20
-rw-r--r--java/com/tigervnc/rfb/RREDecoder.java2
-rw-r--r--java/com/tigervnc/rfb/Rect.java7
-rw-r--r--java/com/tigervnc/rfb/TightDecoder.java71
-rw-r--r--java/com/tigervnc/rfb/ZRLEDecoder.java20
6 files changed, 60 insertions, 90 deletions
diff --git a/java/com/tigervnc/rdr/InStream.java b/java/com/tigervnc/rdr/InStream.java
index 803f55f6..60967991 100644
--- a/java/com/tigervnc/rdr/InStream.java
+++ b/java/com/tigervnc/rdr/InStream.java
@@ -130,20 +130,30 @@ abstract public class InStream {
int b1 = b[ptr++]; int b2 = b[ptr++];
return b0 << 16 | b1 << 8 | b2; }
- public final int readPixel(int bytesPerPixel, boolean e) {
- int[] pix = new int[4];
- for (int i=0; i < bytesPerPixel; i++)
- pix[i] = readU8();
- if (e) {
- return pix[0] << 16 | pix[1] << 8 | pix[2] | (0xff << 24);
+ public final int readPixel(int bytesPerPixel, boolean bigEndian) {
+ byte[] pix = new byte[4];
+ readBytes(pix, 0, bytesPerPixel);
+
+ if (bigEndian) {
+ return 0xff000000 | (pix[0] & 0xff)<<16 | (pix[1] & 0xff)<<8 | (pix[2] & 0xff);
} else {
- return pix[2] << 16 | pix[1] << 8 | pix[0] | (0xff << 24);
+ return 0xff000000 | (pix[2] & 0xff)<<16 | (pix[1] & 0xff)<<8 | (pix[0] & 0xff);
}
}
- public final void readPixels(int[] buf, int length, int bytesPerPixel, boolean e) {
- for (int i = 0; i < length; i++)
- buf[i] = readPixel(bytesPerPixel, e);
+ public final void readPixels(int[] buf, int length, int bytesPerPixel, boolean bigEndian) {
+ int npixels = length*bytesPerPixel;
+ byte[] pixels = new byte[npixels];
+ readBytes(pixels, 0, npixels);
+ for (int i = 0; i < length; i++) {
+ byte[] pix = new byte[4];
+ System.arraycopy(pixels, i*bytesPerPixel, pix, 0, bytesPerPixel);
+ if (bigEndian) {
+ buf[i] = 0xff000000 | (pix[0] & 0xff)<<16 | (pix[1] & 0xff)<<8 | (pix[2] & 0xff);
+ } else {
+ buf[i] = 0xff000000 | (pix[2] & 0xff)<<16 | (pix[1] & 0xff)<<8 | (pix[0] & 0xff);
+ }
+ }
}
public final int readCompactLength() {
diff --git a/java/com/tigervnc/rdr/JavaInStream.java b/java/com/tigervnc/rdr/JavaInStream.java
index 5c350369..d2eda520 100644
--- a/java/com/tigervnc/rdr/JavaInStream.java
+++ b/java/com/tigervnc/rdr/JavaInStream.java
@@ -32,6 +32,7 @@ public class JavaInStream extends InStream {
bufSize = bufSize_;
b = new byte[bufSize];
ptr = end = offset = 0;
+ timing = false;
timeWaitedIn100us = 5;
timedKbits = 0;
}
@@ -108,12 +109,17 @@ public class JavaInStream extends InStream {
}
private int read(byte[] buf, int bufPtr, int len, boolean wait) {
- try {
long before = 0;
if (timing)
before = System.nanoTime();
- int n = jis.read(buf, bufPtr, len);
+ int n = -1;
+ try {
+ n = jis.read(buf, bufPtr, len);
+ } catch (java.io.IOException e) {
+ throw new IOException(e);
+ }
+
if (n < 0) throw new EndOfStream();
if (timing) {
@@ -123,8 +129,11 @@ public class JavaInStream extends InStream {
// limit rate to between 10kbit/s and 40Mbit/s
- if (newTimeWaited > newKbits*1000) newTimeWaited = newKbits*1000;
- if (newTimeWaited < newKbits/4) newTimeWaited = newKbits/4;
+ if (newTimeWaited > newKbits*1000) {
+ newTimeWaited = newKbits*1000;
+ } else if (newTimeWaited < newKbits/4) {
+ newTimeWaited = newKbits/4;
+ }
timeWaitedIn100us += newTimeWaited;
timedKbits += newKbits;
@@ -132,9 +141,6 @@ public class JavaInStream extends InStream {
return n;
- } catch (java.io.IOException e) {
- throw new IOException(e);
- }
}
private int read(byte[] buf, int bufPtr, int len) { return read(buf, bufPtr, len, true); }
diff --git a/java/com/tigervnc/rfb/RREDecoder.java b/java/com/tigervnc/rfb/RREDecoder.java
index e0ff5cfe..f15ac109 100644
--- a/java/com/tigervnc/rfb/RREDecoder.java
+++ b/java/com/tigervnc/rfb/RREDecoder.java
@@ -38,7 +38,7 @@ public class RREDecoder extends Decoder {
int y = is.readU16();
int w = is.readU16();
int h = is.readU16();
- handler.fillRect(new Rect(r.tl.x+x, r.tl.y+y, r.tl.x+x+w, r.tl.y+y+h), pix);
+ handler.fillRect(new Rect(x, y, w, h), pix);
}
}
diff --git a/java/com/tigervnc/rfb/Rect.java b/java/com/tigervnc/rfb/Rect.java
index fab4f5dd..4aa69c14 100644
--- a/java/com/tigervnc/rfb/Rect.java
+++ b/java/com/tigervnc/rfb/Rect.java
@@ -76,7 +76,12 @@ public class Rect {
public final boolean overlaps(Rect r) {
return tl.x < r.br.x && tl.y < r.br.y && br.x > r.tl.x && br.y > r.tl.y;
}
- public final int area() {return is_empty() ? 0 : (br.x-tl.x)*(br.y-tl.y);}
+ public final int area() {
+ int area = (br.x-tl.x)*(br.y-tl.y);
+ if (area > 0)
+ return area;
+ return 0;
+ }
public final Point dimensions() {return new Point(width(), height());}
public final int width() {return br.x-tl.x;}
public final int height() {return br.y-tl.y;}
diff --git a/java/com/tigervnc/rfb/TightDecoder.java b/java/com/tigervnc/rfb/TightDecoder.java
index 24828fbb..2b97110d 100644
--- a/java/com/tigervnc/rfb/TightDecoder.java
+++ b/java/com/tigervnc/rfb/TightDecoder.java
@@ -78,15 +78,7 @@ public class TightDecoder extends Decoder {
if (comp_ctl == rfbTightFill) {
int pix;
if (cutZeros) {
- byte[] elem = new byte[3];
- is.readBytes(elem, 0, 3);
- if (bigEndian) {
- pix =
- (elem[2] & 0xFF) << 16 | (elem[1] & 0xFF) << 8 | (elem[0] & 0xFF) | 0xFF << 24;
- } else {
- pix =
- (elem[0] & 0xFF) << 16 | (elem[1] & 0xFF) << 8 | (elem[2] & 0xFF) | 0xFF << 24;
- }
+ pix = is.readPixel(3, false);
} else {
pix = (bpp == 8) ? is.readOpaque8() : is.readOpaque24B();
}
@@ -135,17 +127,7 @@ public class TightDecoder extends Decoder {
case rfbTightFilterPalette:
palSize = is.readU8() + 1;
if (cutZeros) {
- byte[] elem = new byte[3];
- for (int i = 0; i < palSize; i++) {
- is.readBytes(elem, 0, 3);
- if (bigEndian) {
- palette[i] =
- (elem[2] & 0xFF) << 16 | (elem[1] & 0xFF) << 8 | (elem[0] & 0xFF) | 0xFF << 24;
- } else {
- palette[i] =
- (elem[0] & 0xFF) << 16 | (elem[1] & 0xFF) << 8 | (elem[2] & 0xFF) | 0xFF << 24;
- }
- }
+ is.readPixels(palette, palSize, 3, false);
} else {
for (int i = 0; i < palSize; i++) {
palette[i] = (bpp == 8) ? is.readOpaque8() : is.readOpaque24B();
@@ -196,17 +178,7 @@ public class TightDecoder extends Decoder {
}
} else {
if (cutZeros) {
- byte[] elem = new byte[3];
- for (int i = 0; i < r.area(); i++) {
- input.readBytes(elem, 0, 3);
- if (bigEndian) {
- buf[i] =
- (elem[2] & 0xFF) << 16 | (elem[1] & 0xFF) << 8 | (elem[0] & 0xFF) | 0xFF << 24;
- } else {
- buf[i] =
- (elem[0] & 0xFF) << 16 | (elem[1] & 0xFF) << 8 | (elem[2] & 0xFF) | 0xFF << 24;
- }
- }
+ input.readPixels(buf, r.area(), 3, false);
} else {
for (int ptr=0; ptr < dataSize; ptr++)
buf[ptr] = input.readU8();
@@ -264,14 +236,12 @@ public class TightDecoder extends Decoder {
int[] thisRow = new int[TIGHT_MAX_WIDTH * 3];
int[] pix = new int[3];
int[] est = new int[3];
+ PixelFormat myFormat = handler.cp.pf();
// Allocate netbuf and read in data
int[] netbuf = new int[dataSize];
- for (int i = 0; i < dataSize; i++)
- netbuf[i] = is.readU8();
- //is.readBytes(netbuf, 0, dataSize);
+ is.readBytes(netbuf, 0, dataSize);
- PixelFormat myFormat = handler.cp.pf();
int rectHeight = r.height();
int rectWidth = r.width();
@@ -282,11 +252,9 @@ public class TightDecoder extends Decoder {
thisRow[c] = pix[c];
}
if (myFormat.bigEndian) {
- buf[y*rectWidth] =
- (pix[0] & 0xFF) << 16 | (pix[1] & 0xFF) << 8 | (pix[2] & 0xFF) | 0xFF << 24;
+ buf[y*rectWidth] = 0xff000000 | (pix[2] & 0xff)<<16 | (pix[1] & 0xff)<<8 | (pix[0] & 0xff);
} else {
- buf[y*rectWidth] =
- (pix[2] & 0xFF) << 16 | (pix[1] & 0xFF) << 8 | (pix[0] & 0xFF) | 0xFF << 24;
+ buf[y*rectWidth] = 0xff000000 | (pix[0] & 0xff)<<16 | (pix[1] & 0xff)<<8 | (pix[2] & 0xff);
}
/* Remaining pixels of a row */
@@ -302,11 +270,9 @@ public class TightDecoder extends Decoder {
thisRow[x*3+c] = pix[c];
}
if (myFormat.bigEndian) {
- buf[y*rectWidth] =
- (pix[2] & 0xFF) << 16 | (pix[1] & 0xFF) << 8 | (pix[0] & 0xFF) | 0xFF << 24;
+ buf[y*rectWidth+x] = 0xff000000 | (pix[2] & 0xff)<<16 | (pix[1] & 0xff)<<8 | (pix[0] & 0xff);
} else {
- buf[y*rectWidth] =
- (pix[0] & 0xFF) << 16 | (pix[1] & 0xFF) << 8 | (pix[2] & 0xFF) | 0xFF << 24;
+ buf[y*rectWidth+x] = 0xff000000 | (pix[0] & 0xff)<<16 | (pix[1] & 0xff)<<8 | (pix[2] & 0xff);
}
}
@@ -321,25 +287,21 @@ public class TightDecoder extends Decoder {
int[] thisRow = new int[TIGHT_MAX_WIDTH];
int[] pix = new int[3];
int[] est = new int[3];
+ PixelFormat myFormat = handler.cp.pf();
// Allocate netbuf and read in data
int[] netbuf = new int[dataSize];
- for (int i = 0; i < dataSize; i++)
- netbuf[i] = is.readU8();
- //is.readBytes(netbuf, 0, dataSize);
+ is.readBytes(netbuf, 0, dataSize);
- PixelFormat myFormat = handler.cp.pf();
int rectHeight = r.height();
int rectWidth = r.width();
for (y = 0; y < rectHeight; y++) {
/* First pixel in a row */
if (myFormat.bigEndian) {
- buf[y*rectWidth] =
- (pix[2] & 0xFF) << 16 | (pix[1] & 0xFF) << 8 | (pix[0] & 0xFF) | 0xFF << 24;
+ buf[y*rectWidth] = 0xff000000 | (pix[2] & 0xff)<<16 | (pix[1] & 0xff)<<8 | (pix[0] & 0xff);
} else {
- buf[y*rectWidth] =
- (pix[0] & 0xFF) << 16 | (pix[1] & 0xFF) << 8 | (pix[2] & 0xFF) | 0xFF << 24;
+ buf[y*rectWidth] = 0xff000000 | (pix[0] & 0xff)<<16 | (pix[1] & 0xff)<<8 | (pix[2] & 0xff);
}
for (c = 0; c < 3; c++)
pix[c] += prevRow[c];
@@ -363,13 +325,10 @@ public class TightDecoder extends Decoder {
System.arraycopy(thisRow, x*3, pix, 0, pix.length);
if (myFormat.bigEndian) {
- buf[y*rectWidth+x] =
- (pix[2] & 0xFF) << 16 | (pix[1] & 0xFF) << 8 | (pix[0] & 0xFF) | 0xFF << 24;
+ buf[y*rectWidth+x] = 0xff000000 | (pix[2] & 0xff)<<16 | (pix[1] & 0xff)<<8 | (pix[0] & 0xff);
} else {
- buf[y*rectWidth+x] =
- (pix[0] & 0xFF) << 16 | (pix[1] & 0xFF) << 8 | (pix[2] & 0xFF) | 0xFF << 24;
+ buf[y*rectWidth+x] = 0xff000000 | (pix[0] & 0xff)<<16 | (pix[1] & 0xff)<<8 | (pix[2] & 0xff);
}
-
}
System.arraycopy(thisRow, 0, prevRow, 0, prevRow.length);
diff --git a/java/com/tigervnc/rfb/ZRLEDecoder.java b/java/com/tigervnc/rfb/ZRLEDecoder.java
index 4f740f9d..f9a44c0f 100644
--- a/java/com/tigervnc/rfb/ZRLEDecoder.java
+++ b/java/com/tigervnc/rfb/ZRLEDecoder.java
@@ -30,7 +30,8 @@ public class ZRLEDecoder extends Decoder {
public void readRect(Rect r, CMsgHandler handler) {
InStream is = reader.getInStream();
int[] buf = reader.getImageBuf(64 * 64 * 4);
- int bytesPerPixel = handler.cp.pf().bpp / 8;
+ int bpp = handler.cp.pf().bpp;
+ int bytesPerPixel = (bpp > 24 ? 3 : bpp / 8);
boolean bigEndian = handler.cp.pf().bigEndian;
int length = is.readU32();
@@ -50,13 +51,7 @@ public class ZRLEDecoder extends Decoder {
int palSize = mode & 127;
int[] palette = new int[128];
- if (bytesPerPixel > 1) {
- zis.readPixels(palette, palSize, 3, bigEndian);
- } else {
- for (int i = 0; i < palSize; i++) {
- palette[i] = zis.readPixel(bytesPerPixel, bigEndian);
- }
- }
+ zis.readPixels(palette, palSize, bytesPerPixel, bigEndian);
if (palSize == 1) {
int pix = palette[0];
@@ -69,11 +64,7 @@ public class ZRLEDecoder extends Decoder {
// raw
- if (bytesPerPixel > 1) {
- zis.readPixels(buf, t.area(), 3, bigEndian);
- } else {
- zis.readPixels(buf, t.area(), bytesPerPixel, bigEndian);
- }
+ zis.readPixels(buf, t.area(), bytesPerPixel, bigEndian);
} else {
@@ -109,8 +100,7 @@ public class ZRLEDecoder extends Decoder {
int ptr = 0;
int end = ptr + t.area();
while (ptr < end) {
- int pix = (bytesPerPixel > 1 ? zis.readPixel(3, bigEndian) :
- zis.readPixel(bytesPerPixel, bigEndian));
+ int pix = zis.readPixel(bytesPerPixel, bigEndian);
int len = 1;
int b;
do {