diff options
author | Brian Hinz <bphinz@users.sourceforge.net> | 2011-10-30 14:08:29 +0000 |
---|---|---|
committer | Brian Hinz <bphinz@users.sourceforge.net> | 2011-10-30 14:08:29 +0000 |
commit | ad78f752566d6cf699cf492641bae73e509e420b (patch) | |
tree | 96f9965954fe772f3c43b3bfc784f414f5b7de24 | |
parent | 1bb8b6c88e9add2771a56bfa56f4d9426d93edad (diff) | |
download | tigervnc-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.java | 30 | ||||
-rw-r--r-- | java/com/tigervnc/rdr/JavaInStream.java | 20 | ||||
-rw-r--r-- | java/com/tigervnc/rfb/RREDecoder.java | 2 | ||||
-rw-r--r-- | java/com/tigervnc/rfb/Rect.java | 7 | ||||
-rw-r--r-- | java/com/tigervnc/rfb/TightDecoder.java | 71 | ||||
-rw-r--r-- | java/com/tigervnc/rfb/ZRLEDecoder.java | 20 |
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 { |