# HG changeset patch # User riono210 # Date 1556787249 -32400 # Node ID 96e15614a31f70bb4bc20941ee4da23d16a57cf0 # Parent fcd833c2e148a9f93bab9fd58a7857a41e8d613c create flushRectangle method diff -r fcd833c2e148 -r 96e15614a31f .idea/modules.xml --- a/.idea/modules.xml Thu May 02 16:18:44 2019 +0900 +++ b/.idea/modules.xml Thu May 02 17:54:09 2019 +0900 @@ -2,7 +2,7 @@ - + diff -r fcd833c2e148 -r 96e15614a31f TreeVNC.iml --- a/TreeVNC.iml Thu May 02 16:18:44 2019 +0900 +++ b/TreeVNC.iml Thu May 02 17:54:09 2019 +0900 @@ -1,13 +1,15 @@ - + + + + + + + - - - - - - + \ No newline at end of file diff -r fcd833c2e148 -r 96e15614a31f src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java --- a/src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java Thu May 02 16:18:44 2019 +0900 +++ b/src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java Thu May 02 17:54:09 2019 +0900 @@ -47,6 +47,8 @@ private ByteBuffer c1; private FramebufferUpdateRectangle c1rect; private int c1headerPos; + private int prevLineOffset; + private int prevC1Offset; @Override public void decode(Reader reader, Renderer renderer, @@ -107,10 +109,11 @@ offset += decodePacked(bytes, offset, renderer, paletteSize, tileX, tileY, tileWidth, tileHeight); } } - if (rfbProto != null && rfbProto.multicastBlocking) multicastPut(rfbProto, rect, bytes, prevoffset, offset, tileX, tileY,tileWidth, tileHeight); + if (rfbProto != null && rfbProto.multicastBlocking) multicastPut(rfbProto, false, header, rect, bytes, prevoffset, offset, tileX, tileY,tileWidth, tileHeight); prevoffset = offset; } } + if (rfbProto != null && rfbProto.multicastBlocking) multicastPut(rfbProto, false, header, rect, bytes, prevoffset, offset, maxX, maxY, 0, 0); } private int decodePlainRle(byte[] bytes, int offset, Renderer renderer, @@ -202,6 +205,18 @@ * read FrameBuffferUpdate. If it is ZLE, make it ZLEE which is self contained compressed packet. * put the packet to the multicastqueue. Then normal rendering engine read the same stream using is.reset(). * + * Haeder + * messageID ( FrameBuffer Update + * 1 byte padding + * 2 byte numberofrectangle + * 2 - U16 - x-position + * 2 - U16 - y-position + * 2 - U16 - width + * 2 - U16 - height + * 4 - S32 - encoding-type + * 4 byte datalengths + * datalengths databyte + * * @throws TransportException * @throws UnsupportedEncodingException */ @@ -221,37 +236,84 @@ c1rect = new FramebufferUpdateRectangle(rect.x, rect.y, 0, 0); return; } + int spanGap = 128; - public void multicastPut(TreeRFBProto rfb, ByteBuffer header, FramebufferUpdateRectangle rect, byte[] bytes, int prevoffset, int offset, int tileX, int tileY, int tileW, int tileH) { + public void multicastPut(TreeRFBProto rfb, boolean last, ByteBuffer header, FramebufferUpdateRectangle rect, byte[] bytes, int prevoffset, int offset, int tileX, int tileY, int tileW, int tileH) { int span = offset - prevoffset; rfb.deflater.setInput(bytes,prevoffset,span); c1rect.height = tileH; - if (c1.remaining() < span || c1rect.x + c1rect.width + tileW >= rect.x + rect.width ) { - rfb.deflater.deflate(c1, Deflater.FULL_FLUSH); - rfb.deflater.finish(); - c1.flip(); - //System.out.println("multicastPut: " + c1rect + " length: " + (c1.remaining()-c1headerPos-header.limit())); - try { - rfb.writeUpdateRectangleWithHeader(c1, c1headerPos, c1.remaining()-c1headerPos-header.limit()-4, c1rect.x, c1rect.y, c1rect.width + tileW, c1rect.height + tileY); - } catch (InterruptedException e) { - e.printStackTrace(); + if (c1rect.x > 0) { // phase0 + if (c1.remaining() > span + spanGap && c1rect.width + tileW < rect.width) { + rfb.deflater.deflate(c1, Deflater.SYNC_FLUSH); + return; } - c1rect.x += c1rect.width; - if (c1rect.x >= rect.x + rect.width) { - c1rect.x = rect.x; - c1rect.y += tileH; + flushRectangle(rfb, header, offset, rect, tileX, tileY, tileW, tileH, false); + return; + } + if (!last) { // phase1 + if (c1.remaining() > span + spanGap) { + if (tileX == tileW) { + prevLineOffset = offset; + prevC1Offset = c1.position(); + } + rfb.deflater.deflate(c1, Deflater.SYNC_FLUSH); + return; } - c1rect.width = 0; - c1 = rfb.multicastqueue.allocate(deflate_size); - if (rfb.addSerialNum) - c1.putLong(rfb.counter++); - c1headerPos = c1.position(); - c1.put(header); - header.flip(); - c1.putInt(0); - } else { - rfb.deflater.deflate(c1, Deflater.SYNC_FLUSH); + if (tileX < tileW) { // phase2 + c1.position(prevC1Offset); + flushRectangle(rfb, header, prevoffset, rect, 0, tileY-tileH, tileW, tileH, false); + rfb.deflater.setInput(bytes, prevLineOffset, span); + rfb.deflater.deflate(c1, Deflater.SYNC_FLUSH); + flushRectangle(rfb, header, prevoffset, rect, 0, tileY-tileH, tileW, tileH, false); + return; + } + return; } + flushRectangle(rfb, header, prevoffset, rect, 0, tileY-tileH, tileW, tileH, true); c1rect.width += tileW; } + + /** + * fix rectangle header + * create next rectangle header + * update position paramater + * send muticast pacate if necessary + * @param rfb + * @param header + * @param prevoffset + * @param rect + * @param i + * @param i1 + * @param tileW + * @param tileH + * @param b + */ + private void flushRectangle(TreeRFBProto rfb, ByteBuffer header, int prevoffset, FramebufferUpdateRectangle rect, int i, int i1, int tileW, int tileH, boolean b) { + flushMuticast(rfb, header, rect, tileY, tileW, tileH); + } + + private void flushMuticast(TreeRFBProto rfb, ByteBuffer header, FramebufferUpdateRectangle rect, int tileY, int tileW, int tileH) { + rfb.deflater.deflate(c1, Deflater.FULL_FLUSH); + rfb.deflater.finish(); + c1.flip(); + //System.out.println("multicastPut: " + c1rect + " length: " + (c1.remaining()-c1headerPos-header.limit())); + try { + rfb.writeUpdateRectangleWithHeader(c1, c1headerPos, c1.remaining()-c1headerPos-header.limit()-4, c1rect.x, c1rect.y, c1rect.width + tileW, c1rect.height + tileY); + } catch (InterruptedException e) { + e.printStackTrace(); + } + c1rect.x += c1rect.width; + if (c1rect.x >= rect.x + rect.width) { + c1rect.x = rect.x; + c1rect.y += tileH; + } + c1rect.width = 0; + c1 = rfb.multicastqueue.allocate(deflate_size); + if (rfb.addSerialNum) + c1.putLong(rfb.counter++); + c1headerPos = c1.position(); + c1.put(header); + header.flip(); + c1.putInt(0); + } }