< prev index next >

src/windows/classes/sun/awt/windows/TranslucentWindowPainter.java

Print this page
rev 1556 : 6794764: Translucent windows are completely repainted on every paint event, on Windows
6719382: Printing of AWT components on windows is not working
6726866: Repainting artifacts when resizing or dragging JInternalFrames in non-opaque toplevel
6683775: Painting artifacts is seen when panel is made setOpaque(false) for a translucent window
Reviewed-by: anthony, tdv, alexp

@@ -103,13 +103,14 @@
         this.peer = peer;
         this.window = (Window)peer.getTarget();
     }
 
     /**
-     * Creates (if needed), clears and returns the buffer for this painter.
+     * Creates (if needed), clears (if requested) and returns the buffer
+     * for this painter.
      */
-    protected abstract Image getBackBuffer();
+    protected abstract Image getBackBuffer(boolean clear);
 
     /**
      * Updates the the window associated with this painter with the contents
      * of the passed image.
      * The image can not be null, and NPE will be thrown if it is.

@@ -121,54 +122,34 @@
      * recreated as needed.
      */
     public abstract void flush();
 
     /**
-     * Updates the window associated with the painter given the passed image.
-     * If the passed image is null the painter will use its own buffer for
-     * rendering the contents of the window into it and updating the window.
+     * Updates the window associated with the painter.
      *
-     * If the passed buffer has dimensions different from the window, it is
-     * copied into the internal buffer first and the latter is used to update
-     * the window.
-     *
-     * @param bb the image to update the non opaque window with, or null.
-     * If not null, the image must be of ARGB_PRE type.
+     * @param repaint indicates if the window should be completely repainted
+     * to the back buffer using {@link java.awt.Window#paintAll} before update.
      */
-    public void updateWindow(Image bb) {
+    public void updateWindow(boolean repaint) {
         boolean done = false;
-        if (bb != null && (window.getWidth()  != bb.getWidth(null) ||
-                           window.getHeight() != bb.getHeight(null)))
-        {
-            Image ourBB = getBackBuffer();
-            Graphics2D g = (Graphics2D)ourBB.getGraphics();
-            g.drawImage(bb, 0, 0, null);
-            g.dispose();
-            bb = ourBB;
-        }
-        do {
-            if (bb == null) {
-                bb = getBackBuffer();
+        Image bb = getBackBuffer(repaint);
+        while (!done) {
+            if (repaint) {
                 Graphics2D g = (Graphics2D)bb.getGraphics();
                 try {
                     window.paintAll(g);
                 } finally {
                     g.dispose();
                 }
             }
 
-            peer.paintAppletWarning((Graphics2D)bb.getGraphics(),
-                                    bb.getWidth(null), bb.getHeight(null));
-
             done = update(bb);
-            // in case they passed us a lost VI, next time around we'll use our
-            // own bb because we can not validate and restore the contents of
-            // their VI
             if (!done) {
-                bb = null;
+                repaint = true;
+                bb = getBackBuffer(true);
+            }
             }
-        } while (!done);
     }
 
     private static final Image clearImage(Image bb) {
         Graphics2D g = (Graphics2D)bb.getGraphics();
         int w = bb.getWidth(null);

@@ -188,34 +169,28 @@
      *
      * This painter handles all types of images passed to its paint(Image)
      * method (VI, BI, regular Images).
      */
     private static class BIWindowPainter extends TranslucentWindowPainter {
-        private WeakReference<BufferedImage> biRef;
+        private BufferedImage backBuffer;
 
         protected BIWindowPainter(WWindowPeer peer) {
             super(peer);
         }
 
-        private BufferedImage getBIBackBuffer() {
+        @Override
+        protected Image getBackBuffer(boolean clear) {
             int w = window.getWidth();
             int h = window.getHeight();
-            BufferedImage bb = biRef == null ? null : biRef.get();
-            if (bb == null || bb.getWidth() != w || bb.getHeight() != h) {
-                if (bb != null) {
-                    bb.flush();
-                    bb = null;
-                }
-                bb = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE);
-                biRef = new WeakReference<BufferedImage>(bb);
+            if (backBuffer == null ||
+                backBuffer.getWidth() != w ||
+                backBuffer.getHeight() != h)
+            {
+                flush();
+                backBuffer = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE);
             }
-            return (BufferedImage)clearImage(bb);
-        }
-
-        @Override
-        protected Image getBackBuffer() {
-            return getBIBackBuffer();
+            return clear ? (BufferedImage)clearImage(backBuffer) : backBuffer;
         }
 
         @Override
         protected boolean update(Image bb) {
             VolatileImage viBB = null;

@@ -244,56 +219,49 @@
                     }
                 }
             }
 
             // copy the passed image into our own buffer, then upload
-            BufferedImage bi = getBIBackBuffer();
-            Graphics2D g = (Graphics2D)bi.getGraphics();
-            g.setComposite(AlphaComposite.Src);
-            g.drawImage(bb, 0, 0, null);
+            BufferedImage bi = (BufferedImage)clearImage(backBuffer);
 
             int data[] =
                 ((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
             peer.updateWindowImpl(data, bi.getWidth(), bi.getHeight());
 
             return (viBB != null ? !viBB.contentsLost() : true);
         }
 
         public void flush() {
-            if (biRef != null) {
-                biRef.clear();
+            if (backBuffer != null) {
+                backBuffer.flush();
+                backBuffer = null;
             }
         }
     }
 
     /**
      * A version of the painter which uses VolatileImage as the internal buffer.
      * The window is painted into this VI and then copied into the parent's
      * Java heap-based buffer (which is then uploaded to the layered window)
      */
     private static class VIWindowPainter extends BIWindowPainter {
-        private WeakReference<VolatileImage> viRef;
+        private VolatileImage viBB;
 
         protected VIWindowPainter(WWindowPeer peer) {
             super(peer);
         }
 
         @Override
-        protected Image getBackBuffer() {
+        protected Image getBackBuffer(boolean clear) {
             int w = window.getWidth();
             int h = window.getHeight();
             GraphicsConfiguration gc = peer.getGraphicsConfiguration();
 
-            VolatileImage viBB = viRef == null ? null : viRef.get();
-
             if (viBB == null || viBB.getWidth() != w || viBB.getHeight() != h ||
                 viBB.validate(gc) == IMAGE_INCOMPATIBLE)
             {
-                if (viBB != null) {
-                    viBB.flush();
-                    viBB = null;
-                }
+                flush();
 
                 if (gc instanceof AccelGraphicsConfig) {
                     AccelGraphicsConfig agc = ((AccelGraphicsConfig)gc);
                     viBB = agc.createCompatibleVolatileImage(w, h,
                                                              TRANSLUCENT,

@@ -301,26 +269,21 @@
                 }
                 if (viBB == null) {
                     viBB = gc.createCompatibleVolatileImage(w, h, TRANSLUCENT);
                 }
                 viBB.validate(gc);
-                viRef = new WeakReference<VolatileImage>(viBB);
             }
 
-            return clearImage(viBB);
+            return clear ? clearImage(viBB) : viBB;
         }
 
         @Override
         public void flush() {
-            if (viRef != null) {
-                VolatileImage viBB = viRef.get();
                 if (viBB != null) {
                     viBB.flush();
                     viBB = null;
                 }
-                viRef.clear();
-            }
         }
     }
 
     /**
      * Optimized version of hw painter. Uses VolatileImages for the
< prev index next >