]> source.dussan.org Git - tigervnc.git/commitdiff
Significantly improves the peak frame rate on platforms that support using BIPixelBuffer
authorBrian Hinz <bphinz@users.sourceforge.net>
Wed, 23 May 2012 03:43:10 +0000 (03:43 +0000)
committerBrian Hinz <bphinz@users.sourceforge.net>
Wed, 23 May 2012 03:43:10 +0000 (03:43 +0000)
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4917 3789f03b-4d11-0410-bbf8-ca57d06f2519

java/com/tigervnc/vncviewer/BIPixelBuffer.java

index 692b712cd534ec9bb42a921c1751fb7d8ff7e7a1..d5ec7b6b4039b2b4b18afdd5a989263c1866473e 100644 (file)
@@ -24,12 +24,25 @@ import java.awt.image.*;
 import com.tigervnc.rfb.*;
 import com.tigervnc.rfb.Exception;
 
-public class BIPixelBuffer extends PlatformPixelBuffer
+public class BIPixelBuffer extends PlatformPixelBuffer implements ImageObserver
 {
   public BIPixelBuffer(int w, int h, CConn cc_, DesktopWindow desktop_) {
     super(w, h, cc_, desktop_);
+    clip = new Rectangle();
   }
 
+  public void setPF(PixelFormat pf) {
+    super.setPF(pf);
+    if (source != null)
+      source.newPixels(data, cm, 0, width_);
+  }
+
+  public void updateColourMap() {
+    cm = new IndexColorModel(8, nColours, reds, greens, blues);
+    if (source != null)
+      source.newPixels(data, cm, 0, width_);
+  }
+  
   // resize() resizes the image, preserving the image data where possible.
   public void resize(int w, int h) {
     if (w == width() && h == height()) return;
@@ -43,6 +56,12 @@ public class BIPixelBuffer extends PlatformPixelBuffer
     image = gc.createCompatibleImage(w, h, Transparency.TRANSLUCENT);
     image.setAccelerationPriority(1);
     image.createGraphics();
+    data = new int[width() * height()];
+    source = new MemoryImageSource(w, h, cm, data, 0, w);
+    source.setAnimated(true);
+    source.setFullBufferUpdates(false);
+    source.newPixels(data, cm, 0, width_);
+    sourceImage = tk.createImage(source);
   }
 
   public void fillRect(int x, int y, int w, int h, int pix) {
@@ -63,29 +82,29 @@ public class BIPixelBuffer extends PlatformPixelBuffer
   }
 
   public void imageRect(int x, int y, int w, int h, Object pix) {
-    Graphics2D graphics = (Graphics2D)image.getGraphics();
-    Image img;
     if (pix instanceof Image) {
-      img = (Image)pix;
+      Image img = (Image)pix;
+      clip = new Rectangle(x, y, w, h); 
+      synchronized(clip) {
+        tk.prepareImage(img, -1, -1, this);
+        try {
+          clip.wait(1000);
+        } catch (InterruptedException e) {
+          throw new Exception("Error decoding JPEG data");
+        }
+      } 
+      clip = null;
+      img.flush();
     } else {
-      img = tk.createImage(new MemoryImageSource(w, h, cm, (int[])pix, 0, w));
-      img.setAccelerationPriority(1);
+      for (int j = 0; j < h; j++)
+        System.arraycopy(pix, (w*j), data, width_ * (y + j) + x, w);
+      source.newPixels(x, y, w, h, true);
+      Graphics2D graphics = (Graphics2D)image.getGraphics();
+      graphics.setClip(x, y, w, h);
+      graphics.drawImage(sourceImage, 0, 0, null);
+      graphics.setClip(0, 0, width(), height());
+      graphics.dispose();
     }
-    boolean ret = tk.prepareImage(img, -1, -1, null);
-    if (!ret) {
-      while ((tk.checkImage(img, -1, -1, null) & ImageObserver.ALLBITS) == 0) {
-        synchronized (this) {
-          try {
-            this.wait(0, 10000);
-          } catch (InterruptedException e) {
-            throw new Exception("Error decoding JPEG data");
-          }
-        }
-      }
-    } 
-    graphics.drawImage(img, x, y, w, h, null); 
-    graphics.dispose();
-    img.flush();
   }
 
   public void copyRect(int x, int y, int w, int h, int srcX, int srcY) {
@@ -98,7 +117,29 @@ public class BIPixelBuffer extends PlatformPixelBuffer
     return (Image)image;
   }
 
+  public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h) {
+    if ((infoflags & (ALLBITS | ABORT)) == 0) {
+      return true;
+    } else {
+      if ((infoflags & ALLBITS) != 0) {
+        if (clip != null) {
+          synchronized(clip) {
+            Graphics2D graphics = (Graphics2D)image.getGraphics();
+            graphics.drawImage(img, clip.x, clip.y, clip.width, clip.height, null); 
+            graphics.dispose();
+            clip.notify();
+          }
+        }
+      }
+      return false;
+    }
+  }
+
   BufferedImage image;
+  MemoryImageSource source;
+  int[] data;
+  Image sourceImage;
+  Rectangle clip;
 
   static LogWriter vlog = new LogWriter("BIPixelBuffer");
 }