# HG changeset patch # User riono # Date 1588848300 -32400 # Node ID c9d0d3e1a82f0024a9f7013b301b17585680f063 # Parent d2644d8f7893b4e96148219cdffd1320b5d89c33 add code diff -r d2644d8f7893 -r c9d0d3e1a82f Paper/riono-sigos.pdf Binary file Paper/riono-sigos.pdf has changed diff -r d2644d8f7893 -r c9d0d3e1a82f Paper/riono-sigos.tex --- a/Paper/riono-sigos.tex Thu May 07 18:45:22 2020 +0900 +++ b/Paper/riono-sigos.tex Thu May 07 19:45:00 2020 +0900 @@ -262,16 +262,21 @@ \end{table} 次にTileLoopの処理について説明する。 -Code\ref{code:tileloop}はTileLoopの処理を擬似的に抜粋したものである。 +Code \ref{code:tileloop}はTileLoopの処理を大まかに抜粋したものである。 \lstinputlisting[caption=TileLoopの処理関数, label=code:tileloop]{src/decode.java} -図\ref{fig:TileLoopFlow}中1にて、TileLoopの初期化でBlockingと構築するPacketの準備を行う。Loop本体ではZRLEで受け取ったRectangleを1Tile 64x64に分割し、1Tileずつ処理を行う。そして受け取ったZRLEより処理を行うTileのデータを取得し、圧縮段階に入る。 +Code \ref{code:tileloop}8 - 11行目はTileLoopの初期化でBlockingと構築するPacketの準備を行っている。Code \ref{code:tileloop}12行目からのLoopではZRLEで受け取ったRectangleを1Tile 64x64に分割し、1Tileずつ処理を行う。%そして受け取ったZRLEより処理を行うTileのデータを取得し、フェーズの確認と圧縮段階に入る。 TileLoopにはc1Rectと呼ばれるRectangleを持っている。これは読み込んだTile分だけ縦横を拡張していくことによってRectangleの再構成を行なっている。図\ref{fig:TIleLoopFlow}中2の圧縮段階では、読み込んだTileのデータを圧縮用のStreamに格納し、java.util.zip.deflaterを利用して圧縮を行なっている。Packetのサイズは60KBとしているが、一旦の制限として42KBまでを格納可能としている。 +Code \ref{code:tileloop}21行目では処理対象のTileのデータ圧縮とフェーズ確認を行う関数である。Code \ref{code:multicastput}はその関数の処理を大まかに抜粋したものである。 + + +\lstinputlisting[caption=TileLoopの処理関数, label=code:multicastput]{src/multicastPut.java} + java.util.zip.deflaterには下記の3種類の圧縮方法がある。 \begin{itemize} diff -r d2644d8f7893 -r c9d0d3e1a82f Paper/src/decode.java --- a/Paper/src/decode.java Thu May 07 18:45:22 2020 +0900 +++ b/Paper/src/decode.java Thu May 07 19:45:00 2020 +0900 @@ -18,7 +18,7 @@ int tileWidth = Math.min(maxX - tileX, MAX_TILE_SIZE); offset += decodePacked(bytes, offset, renderer, paletteSize, tileX, tileY, tileWidth, tileHeight); if (WifiMulticast) { - tileloop.multicastPut(rfbProto, false, bytes, offset, tileWidth, tileHeight, tileX, tileY); + tileloop.multicastPut(rfbProto, false, bytes, offset, tileWidth, tileHeight, tileX, tileY); } } } diff -r d2644d8f7893 -r c9d0d3e1a82f Paper/src/multicastPut.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Paper/src/multicastPut.java Thu May 07 19:45:00 2020 +0900 @@ -0,0 +1,65 @@ +public void multicastPut(TreeRFBProto rfb, boolean last, byte[] bytes, int offset, int tileW, int tileH, int tileX, int tileY) throws TransportException { + int span = offset - prevoffset; + if (span==0) return; + deflater.setInput(bytes, prevoffset, span); + width += tileW; + c1rect.width += tileW; + do { + deflater.deflate(c1, Deflater.SYNC_FLUSH); + if (!deflater.needsInput()) { + flushDeflator(true," full "); + int bytesRead = (int)deflater.getBytesRead(); + prevoffset = flushOffset+bytesRead; + if (c0rect!=null) { // finish pahse 1 + flushRectangle(c0rect,prevC1LineOffset," full c0rect"); + c0rect = null; + } + flushRectangle(c1rect,c1.position()," full c1rect"); // phase 2 + flushMuticast(rfb, bytes); + } + } while (! deflater.needsInput()); + prevoffset = offset; + if (last) { + flushDeflator(false," last"); + if (c0rect!=null) { + flushRectangle(c0rect,prevC1LineOffset," last c0rect"); + makeHeaderSpace(); + c0rect = null; + } + flushRectangle(c1rect,c1.position()," last c1rect"); + flushMuticast(rfb, bytes); + return; + } + if (c1rect.x > rect.x) { // phase 0 + assert(c0rect==null); + if (width >= rect.width) { // end of phase 0 + boolean end = flushDeflator(false," end of phase 0 "); + width = 0; + flushRectangle(c1rect,c1.position()," end of phase 0"); + c1rect = new FramebufferUpdateRectangle(rect.x,c1rect.y+tileH,0,0); + if (end || c1rect.y >= rect.y+rect.height) { + flushMuticast(rfb,bytes); + return; + } + c1.position(c1.position()+ RECT_HEADER_SIZE); // header space + prevC1Offset = c1.position(); + } + } else { // phase 1 + if (width >= rect.width) { // next line + boolean end = flushDeflator(false, " phoase 1 next line "); + width = 0; + prevC1LineOffset = c1.position(); + if (c0rect!=null) { // extend phase 1 + c0rect.height += tileH; + } else { // first phase 1 case + c0rect = c1rect; + } + c1rect = new FramebufferUpdateRectangle(rect.x, c0rect.y+c0rect.height, 0, 0); + if (end || c1rect.y >= rect.y+rect.height) { + c0rect = null; // next will be first phase 1 case + flushMuticast(rfb,bytes); + return; + } + } + } +}