Revision: 4860
          http://tigervnc.svn.sourceforge.net/tigervnc/?rev=4860&view=rev
Author:   bphinz
Date:     2012-03-05 23:57:05 +0000 (Mon, 05 Mar 2012)
Log Message:
-----------
Improve performance of Java viewer by using buffered image as drawing surface. 
Simplified soft cursor construction.

Modified Paths:
--------------
    trunk/java/com/tigervnc/rfb/CMsgHandler.java
    trunk/java/com/tigervnc/rfb/TightDecoder.java
    trunk/java/com/tigervnc/vncviewer/CConn.java
    trunk/java/com/tigervnc/vncviewer/DesktopWindow.java
    trunk/java/com/tigervnc/vncviewer/PixelBufferImage.java

Modified: trunk/java/com/tigervnc/rfb/CMsgHandler.java
===================================================================
--- trunk/java/com/tigervnc/rfb/CMsgHandler.java        2012-03-05 23:31:46 UTC 
(rev 4859)
+++ trunk/java/com/tigervnc/rfb/CMsgHandler.java        2012-03-05 23:57:05 UTC 
(rev 4860)
@@ -89,7 +89,7 @@
   public void serverCutText(String str, int len) {}
 
   public void fillRect(Rect r, int pix) {}
-  public void imageRect(Rect r, int[] pixels) {}
+  public void imageRect(Rect r, Object pixels) {}
   public void copyRect(Rect r, int srcX, int srcY) {}
 
   abstract public PixelFormat getPreferredPF();

Modified: trunk/java/com/tigervnc/rfb/TightDecoder.java
===================================================================
--- trunk/java/com/tigervnc/rfb/TightDecoder.java       2012-03-05 23:31:46 UTC 
(rev 4859)
+++ trunk/java/com/tigervnc/rfb/TightDecoder.java       2012-03-05 23:57:05 UTC 
(rev 4860)
@@ -23,7 +23,7 @@
 import com.tigervnc.rdr.ZlibInStream;
 import java.util.ArrayList;
 import java.io.InputStream;
-import java.awt.image.PixelGrabber;
+import java.awt.image.*;
 import java.awt.*;
 
 public class TightDecoder extends Decoder {
@@ -249,20 +249,18 @@
 
     // Create an Image object from the JPEG data.
     Image jpeg = tk.createImage(netbuf);
-        
-    int w = r.width();
-    int h = r.height();
-
-    int[] buf = reader.getImageBuf(w*h);
-    PixelGrabber pg = new PixelGrabber(jpeg, 0, 0, w, h, buf, 0, w);
-         try {
-           pg.grabPixels(0);
-         } catch (InterruptedException e) {
-           System.out.println("Tight Decoding: Wrong JPEG data received.");
-         }
-
+    tk.prepareImage(jpeg, -1, -1, null); 
+    synchronized(this) { 
+      while ((tk.checkImage(jpeg, -1, -1, null) & ImageObserver.ALLBITS) == 0) 
{
+        try {
+          this.wait(1);
+        } catch (InterruptedException e) {
+          throw new Exception("Error decoding JPEG data");
+        }
+      }
+    }
+    handler.imageRect(r, jpeg);
     jpeg.flush();
-    handler.imageRect(r, buf);
   }
 
   final private void FilterGradient24(byte[] netbuf, int[] buf, int stride, 

Modified: trunk/java/com/tigervnc/vncviewer/CConn.java
===================================================================
--- trunk/java/com/tigervnc/vncviewer/CConn.java        2012-03-05 23:31:46 UTC 
(rev 4859)
+++ trunk/java/com/tigervnc/vncviewer/CConn.java        2012-03-05 23:57:05 UTC 
(rev 4860)
@@ -514,7 +514,7 @@
     desktop.fillRect(r.tl.x, r.tl.y, r.width(), r.height(), p);
   }
 
-  public void imageRect(Rect r, int[] p) {
+  public void imageRect(Rect r, Object p) {
     desktop.imageRect(r.tl.x, r.tl.y, r.width(), r.height(), p);
   }
 

Modified: trunk/java/com/tigervnc/vncviewer/DesktopWindow.java
===================================================================
--- trunk/java/com/tigervnc/vncviewer/DesktopWindow.java        2012-03-05 
23:31:46 UTC (rev 4859)
+++ trunk/java/com/tigervnc/vncviewer/DesktopWindow.java        2012-03-05 
23:57:05 UTC (rev 4860)
@@ -86,7 +86,7 @@
   // to work.
 
   synchronized public void initGraphics() { 
-    graphics = this.getGraphics();
+    graphics = im.image.getGraphics();
     prepareImage(im.image, scaledWidth, scaledHeight, this);
   }
 
@@ -131,20 +131,16 @@
     cursor.data = new int[cursor.width() * cursor.height()];
     cursor.mask = new byte[cursor.maskLen()];
 
-    // set the masked pixels of the cursor transparent by using an extra bit in
-    // the colormap.  We'll OR this into the data based on the values in the 
mask.
-    if (cursor.getPF().bpp == 8) {
-      cursor.cm = new DirectColorModel(9, 7, (7 << 3), (3 << 6), (1 << 8));
-    }
-
     int maskBytesPerRow = (w + 7) / 8;
     for (int y = 0; y < h; y++) {
       for (int x = 0; x < w; x++) {
         int byte_ = y * maskBytesPerRow + x / 8;
         int bit = 7 - x % 8;
         if ((mask[byte_] & (1 << bit)) > 0) {
-          cursor.data[y * cursor.width() + x] = (cursor.getPF().bpp == 8) ?
-            data[y * w + x] | (1 << 8) : data[y * w + x];
+          cursor.data[y * cursor.width() + x] = (0xff << 24) |
+            (im.cm.getRed(data[y * w + x]) << 16) |
+            (im.cm.getGreen(data[y * w + x]) << 8) |
+            (im.cm.getBlue(data[y * w + x]));
         }
       }
       System.arraycopy(mask, y * maskBytesPerRow, cursor.mask, 
@@ -152,7 +148,7 @@
     }
 
     MemoryImageSource bitmap = 
-      new MemoryImageSource(cursor.width(), cursor.height(), cursor.cm,
+      new MemoryImageSource(cursor.width(), cursor.height(), 
ColorModel.getRGBdefault(),
                             cursor.data, 0, cursor.width());
     int cw = (int)Math.floor((float)cursor.width() * scaleWidthRatio);
     int ch = (int)Math.floor((float)cursor.height() * scaleHeightRatio);
@@ -198,7 +194,6 @@
     im.setColourMapEntries(firstColour, nColours, rgbs);
     if (nColours <= 256) {
       im.updateColourMap();
-      im.put(0, 0, im.width(), im.height(), graphics);
     } else {
       if (setColourMapEntriesTimerThread == null) {
         setColourMapEntriesTimerThread = new Thread(this);
@@ -233,7 +228,9 @@
     invalidRect = false;
 
     synchronized (im) {
-      im.put(x, y, w, h, graphics);
+      graphics.setClip(x, y, w, h);
+      repaint(x, y, w, h);
+      graphics.setClip(0, 0, im.width(), im.height());
     }
   }
 
@@ -268,7 +265,7 @@
   }
 
   final public void imageRect(int x, int y, int w, int h,
-                                           int[] pix) {
+                                           Object pix) {
     if (overlapsCursor(x, y, w, h)) hideLocalCursor();
     synchronized (im) {
       im.imageRect(x, y, w, h, pix);
@@ -283,11 +280,9 @@
     if (overlapsCursor(x, y, w, h) || overlapsCursor(srcX, srcY, w, h))
       hideLocalCursor();
     synchronized (im) {
-      im.copyRect(x, y, w, h, srcX, srcY, graphics);
+      im.copyRect(x, y, w, h, srcX, srcY);
     }
-    if (!cc.viewer.fastCopyRect.getValue()) {
-      invalidate(x, y, w, h);
-    }
+    invalidate(x, y, w, h);
   }
 
 
@@ -480,8 +475,6 @@
       cursorVisible = false;
       im.imageRect(cursorBackingX, cursorBackingY, cursorBacking.width(),
                    cursorBacking.height(), cursorBacking.data);
-      im.put(cursorBackingX, cursorBackingY, cursorBacking.width(),
-             cursorBacking.height(), graphics);
     }
   }
 
@@ -516,7 +509,6 @@
 
       im.maskRect(cursorLeft, cursorTop, cursor.width(), cursor.height(),
                   cursor.data, cursor.mask);
-      im.put(x, y, w, h, graphics);
     }
   }
 
@@ -528,7 +520,6 @@
       Thread.sleep(100);
     } catch (InterruptedException e) {}
     im.updateColourMap();
-    im.put(0, 0, im.width(), im.height(), graphics);
     setColourMapEntriesTimerThread = null;
   }
 

Modified: trunk/java/com/tigervnc/vncviewer/PixelBufferImage.java
===================================================================
--- trunk/java/com/tigervnc/vncviewer/PixelBufferImage.java     2012-03-05 
23:31:46 UTC (rev 4859)
+++ trunk/java/com/tigervnc/vncviewer/PixelBufferImage.java     2012-03-05 
23:57:05 UTC (rev 4860)
@@ -30,7 +30,7 @@
 
 import com.tigervnc.rfb.*;
 
-public class PixelBufferImage extends PixelBuffer implements ImageProducer
+public class PixelBufferImage extends PixelBuffer
 {
   public PixelBufferImage(int w, int h, CConn cc_, DesktopWindow desktop_) {
     cc = cc_;
@@ -48,25 +48,31 @@
   public void resize(int w, int h) {
     if (w == width() && h == height()) return;
 
-    int rowsToCopy = h < height() ? h : height();
-    int copyWidth = w < width() ? w : width();
-    int[] oldData = data;
-
     width_ = w;
     height_ = h;
-    image = desktop.createImage(this);
+    switch (format.depth) {
+    case  3: 
+      // Fall-through to depth 8
+    case  6: 
+      // Fall-through to depth 8
+    case 8:
+      image = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_INDEXED);
+      break;
+    default:
+      GraphicsEnvironment ge =
+        GraphicsEnvironment.getLocalGraphicsEnvironment();
+      GraphicsDevice gd = ge.getDefaultScreenDevice();
+      GraphicsConfiguration gc = gd.getDefaultConfiguration();
+      image = gc.createCompatibleImage(w, h, Transparency.OPAQUE);
+      break;
+    }
     image.setAccelerationPriority(1);
-
-    data = new int[width() * height()];
-
-    for (int i = 0; i < rowsToCopy; i++)
-      System.arraycopy(oldData, copyWidth * i,
-                       data, width() * i, copyWidth);
+    graphics = image.createGraphics();
   }
 
   public PixelFormat getNativePF() {
     PixelFormat pf;
-    cm = java.awt.Toolkit.getDefaultToolkit().getColorModel();
+    cm = tk.getColorModel();
     if (cm.getColorSpace().getType() == java.awt.color.ColorSpace.TYPE_RGB) {
       int depth = cm.getPixelSize();
       int bpp = (depth > 16 ? 32 : (depth > 8 ? 16 : 8));
@@ -90,24 +96,33 @@
     return pf;
   }
 
-  // put() causes the given rectangle to be drawn using the given graphics
-  // context.
-  public void put(int x, int y, int w, int h, Graphics g) {
-    if (ic != null) {
-      ic.setPixels(x, y, w, h, cm, data, width() * y + x, width());
-      desktop.repaint(x, y, w, h);
+  public void fillRect(int x, int y, int w, int h, int pix) {
+    switch (format.depth) {
+    case 24:
+      graphics.setColor(new Color(pix)); 
+      graphics.fillRect(x, y, w, h); 
+      break;
+    default:
+      Color color = new Color((0xff << 24) | (cm.getRed(pix) << 16) |
+                              (cm.getGreen(pix) << 8) | (cm.getBlue(pix)));
+      graphics.setColor(color); 
+      graphics.fillRect(x, y, w, h); 
+      break;
     }
   }
 
-  // fillRect(), imageRect(), maskRect() are inherited from PixelBuffer.  For
-  // copyRect() we also need to tell the ImageConsumer that the pixels have
-  // changed (this is done in the put() call for the others).
+  public void imageRect(int x, int y, int w, int h, Object pix) {
+    if (pix instanceof java.awt.Image) {
+      graphics.drawImage((Image)pix, x, y, w, h, null); 
+    } else {
+      Image img = tk.createImage(new MemoryImageSource(w, h, cm, (int[])pix, 
0, w));
+      graphics.drawImage(img, x, y, w, h, null); 
+      img.flush();
+    }
+  }
 
-  public void copyRect(int x, int y, int w, int h, int srcX, int srcY, 
Graphics g) {
-    super.copyRect(x, y, w, h, srcX, srcY);
-    if (ic == null) return;
-    ic.setPixels(x, y, w, h, cm, data, width() * y + x, width());
-    desktop.repaint(x, y, w, h);
+  public void copyRect(int x, int y, int w, int h, int srcX, int srcY) {
+    graphics.copyArea(srcX, srcY, w, h, x - srcX, y - srcY);
   }
 
   // setColourMapEntries() changes some of the entries in the colourmap.
@@ -128,40 +143,14 @@
     }
   }
 
-  // ImageProducer methods
-
   public void updateColourMap() {
     cm = new IndexColorModel(8, nColours, reds, greens, blues);
   }
 
-  public void addConsumer(ImageConsumer c) {
-    if (ic == c) return;
-    
-    vlog.debug("adding consumer "+c);
-    
-    if (ic != null)
-      vlog.error("Only one ImageConsumer allowed - discarding old one");
-    
-    ic = c;
-    ic.setDimensions(width(), height());
-    ic.setHints(ImageConsumer.RANDOMPIXELORDER);
-    // Calling ic.setColorModel(cm) seemed to help in some earlier versions of
-    // the JDK, but it shouldn't be necessary because we pass the ColorModel
-    // with each setPixels() call.
-    ic.setPixels(0, 0, width(), height(), cm, data, 0, width());
-    ic.imageComplete(ImageConsumer.SINGLEFRAMEDONE);
-  }
+  private static Toolkit tk = java.awt.Toolkit.getDefaultToolkit();
 
-  public void removeConsumer(ImageConsumer c) {
-    System.err.println("removeConsumer "+c);
-    if (ic == c) ic = null;
-  }
-
-  public boolean isConsumer(ImageConsumer c) { return ic == c; }
-  public void requestTopDownLeftRightResend(ImageConsumer c) {}
-  public void startProduction(ImageConsumer c) { addConsumer(c); }
-
-  Image image;
+  Graphics2D graphics;
+  BufferedImage image;
   ImageConsumer ic;
 
   int nColours;

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
Try before you buy = See our experts in action!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-dev2
_______________________________________________
Tigervnc-commits mailing list
Tigervnc-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tigervnc-commits

Reply via email to