< prev index next >

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

Print this page




   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package sun.awt.windows;
  26 
  27 import java.awt.AlphaComposite;
  28 import java.awt.Color;

  29 import java.awt.Graphics2D;
  30 import java.awt.GraphicsConfiguration;
  31 import java.awt.Image;
  32 import java.awt.Window;

  33 import java.awt.image.BufferedImage;
  34 import java.awt.image.DataBufferInt;
  35 import java.awt.image.VolatileImage;
  36 import java.security.AccessController;
  37 import sun.awt.image.BufImgSurfaceData;
  38 import sun.java2d.DestSurfaceProvider;
  39 import sun.java2d.InvalidPipeException;
  40 import sun.java2d.Surface;

  41 import sun.java2d.pipe.RenderQueue;
  42 import sun.java2d.pipe.BufferedContext;
  43 import sun.java2d.pipe.hw.AccelGraphicsConfig;
  44 import sun.java2d.pipe.hw.AccelSurface;
  45 import sun.security.action.GetPropertyAction;
  46 
  47 import static java.awt.image.VolatileImage.*;
  48 import static sun.java2d.pipe.hw.AccelSurface.*;
  49 import static sun.java2d.pipe.hw.ContextCapabilities.*;
  50 
  51 /**
  52  * This class handles the updates of the non-opaque windows.
  53  * The window associated with the peer is updated either given an image or
  54  * the window is repainted to an internal buffer which is then used to update
  55  * the window.
  56  *
  57  * Note: this class does not attempt to be thread safe, it is expected to be
  58  * called from a single thread (EDT).
  59  */
  60 abstract class TranslucentWindowPainter {


 100 
 101     protected TranslucentWindowPainter(WWindowPeer peer) {
 102         this.peer = peer;
 103         this.window = (Window)peer.getTarget();
 104     }
 105 
 106     /**
 107      * Creates (if needed), clears (if requested) and returns the buffer
 108      * for this painter.
 109      */
 110     protected abstract Image getBackBuffer(boolean clear);
 111 
 112     /**
 113      * Updates the window associated with this painter with the contents
 114      * of the passed image.
 115      * The image can not be null, and NPE will be thrown if it is.
 116      */
 117     protected abstract boolean update(Image bb);
 118 
 119     /**






 120      * Flushes the resources associated with the painter. They will be
 121      * recreated as needed.
 122      */
 123     public abstract void flush();
 124 
 125     /**
 126      * Updates the window associated with the painter.
 127      *
 128      * @param repaint indicates if the window should be completely repainted
 129      * to the back buffer using {@link java.awt.Window#paintAll} before update.
 130      */
 131     public void updateWindow(boolean repaint) {
 132         boolean done = false;
 133         Image bb = getBackBuffer(repaint);
 134         while (!done) {
 135             if (repaint) {
 136                 Graphics2D g = (Graphics2D)bb.getGraphics();
 137                 try {
 138                     window.paintAll(g);
 139                 } finally {
 140                     g.dispose();
 141                 }
 142             }
 143 
 144             done = update(bb);
 145             if (!done) {
 146                 repaint = true;
 147                 bb = getBackBuffer(true);
 148             }
 149         }
 150     }
 151 
 152     private static final Image clearImage(Image bb) {
 153         Graphics2D g = (Graphics2D)bb.getGraphics();
 154         int w = bb.getWidth(null);
 155         int h = bb.getHeight(null);
 156 
 157         g.setComposite(AlphaComposite.Src);
 158         g.setColor(new Color(0, 0, 0, 0));
 159         g.fillRect(0, 0, w, h);
 160 
 161         return bb;
 162     }
 163 
 164     /**
 165      * A painter which uses BufferedImage as the internal buffer. The window
 166      * is painted into this buffer, and the contents then are uploaded
 167      * into the layered window.
 168      *
 169      * This painter handles all types of images passed to its paint(Image)
 170      * method (VI, BI, regular Images).
 171      */
 172     private static class BIWindowPainter extends TranslucentWindowPainter {
 173         private BufferedImage backBuffer;
 174 
 175         protected BIWindowPainter(WWindowPeer peer) {
 176             super(peer);
 177         }
 178 
 179         @Override
 180         protected Image getBackBuffer(boolean clear) {
 181             int w = window.getWidth();
 182             int h = window.getHeight();




 183             if (backBuffer == null ||
 184                 backBuffer.getWidth() != w ||
 185                 backBuffer.getHeight() != h)
 186             {
 187                 flush();
 188                 backBuffer = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE);
 189             }
 190             return clear ? (BufferedImage)clearImage(backBuffer) : backBuffer;
 191         }
 192 
 193         @Override
 194         protected boolean update(Image bb) {
 195             VolatileImage viBB = null;
 196 
 197             if (bb instanceof BufferedImage) {
 198                 BufferedImage bi = (BufferedImage)bb;
 199                 int data[] =
 200                     ((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
 201                 peer.updateWindowImpl(data, bi.getWidth(), bi.getHeight());
 202                 return true;


 219                 }
 220             }
 221 
 222             // copy the passed image into our own buffer, then upload
 223             BufferedImage bi = (BufferedImage)clearImage(backBuffer);
 224 
 225             int data[] =
 226                 ((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
 227             peer.updateWindowImpl(data, bi.getWidth(), bi.getHeight());
 228 
 229             return (viBB != null ? !viBB.contentsLost() : true);
 230         }
 231 
 232         @Override
 233         public void flush() {
 234             if (backBuffer != null) {
 235                 backBuffer.flush();
 236                 backBuffer = null;
 237             }
 238         }













 239     }
 240 
 241     /**
 242      * A version of the painter which uses VolatileImage as the internal buffer.
 243      * The window is painted into this VI and then copied into the parent's
 244      * Java heap-based buffer (which is then uploaded to the layered window)
 245      */
 246     private static class VIWindowPainter extends BIWindowPainter {
 247         private VolatileImage viBB;
 248 
 249         protected VIWindowPainter(WWindowPeer peer) {
 250             super(peer);
 251         }
 252 
 253         @Override
 254         protected Image getBackBuffer(boolean clear) {
 255             int w = window.getWidth();
 256             int h = window.getHeight();
 257             GraphicsConfiguration gc = peer.getGraphicsConfiguration();
 258 


 265                     AccelGraphicsConfig agc = ((AccelGraphicsConfig)gc);
 266                     viBB = agc.createCompatibleVolatileImage(w, h,
 267                                                              TRANSLUCENT,
 268                                                              RT_PLAIN);
 269                 }
 270                 if (viBB == null) {
 271                     viBB = gc.createCompatibleVolatileImage(w, h, TRANSLUCENT);
 272                 }
 273                 viBB.validate(gc);
 274             }
 275 
 276             return clear ? clearImage(viBB) : viBB;
 277         }
 278 
 279         @Override
 280         public void flush() {
 281             if (viBB != null) {
 282                 viBB.flush();
 283                 viBB = null;
 284             }





 285         }
 286     }
 287 
 288     /**
 289      * Optimized version of hw painter. Uses VolatileImages for the
 290      * buffer, and uses an optimized path to pull the data from those into
 291      * the layered window, bypassing Java heap-based image.
 292      */
 293     private abstract static class VIOptWindowPainter extends VIWindowPainter {
 294 
 295         protected VIOptWindowPainter(WWindowPeer peer) {
 296             super(peer);
 297         }
 298 
 299         protected abstract boolean updateWindowAccel(long psdops, int w, int h);
 300 
 301         @Override
 302         protected boolean update(Image bb) {
 303             if (bb instanceof DestSurfaceProvider) {
 304                 Surface s = ((DestSurfaceProvider)bb).getDestSurface();




   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package sun.awt.windows;
  26 
  27 import java.awt.AlphaComposite;
  28 import java.awt.Color;
  29 import java.awt.Graphics;
  30 import java.awt.Graphics2D;
  31 import java.awt.GraphicsConfiguration;
  32 import java.awt.Image;
  33 import java.awt.Window;
  34 import java.awt.geom.AffineTransform;
  35 import java.awt.image.BufferedImage;
  36 import java.awt.image.DataBufferInt;
  37 import java.awt.image.VolatileImage;
  38 import java.security.AccessController;
  39 import sun.awt.image.BufImgSurfaceData;
  40 import sun.java2d.DestSurfaceProvider;
  41 import sun.java2d.InvalidPipeException;
  42 import sun.java2d.Surface;
  43 import sun.java2d.pipe.Region;
  44 import sun.java2d.pipe.RenderQueue;
  45 import sun.java2d.pipe.BufferedContext;
  46 import sun.java2d.pipe.hw.AccelGraphicsConfig;
  47 import sun.java2d.pipe.hw.AccelSurface;
  48 import sun.security.action.GetPropertyAction;
  49 
  50 import static java.awt.image.VolatileImage.*;
  51 import static sun.java2d.pipe.hw.AccelSurface.*;
  52 import static sun.java2d.pipe.hw.ContextCapabilities.*;
  53 
  54 /**
  55  * This class handles the updates of the non-opaque windows.
  56  * The window associated with the peer is updated either given an image or
  57  * the window is repainted to an internal buffer which is then used to update
  58  * the window.
  59  *
  60  * Note: this class does not attempt to be thread safe, it is expected to be
  61  * called from a single thread (EDT).
  62  */
  63 abstract class TranslucentWindowPainter {


 103 
 104     protected TranslucentWindowPainter(WWindowPeer peer) {
 105         this.peer = peer;
 106         this.window = (Window)peer.getTarget();
 107     }
 108 
 109     /**
 110      * Creates (if needed), clears (if requested) and returns the buffer
 111      * for this painter.
 112      */
 113     protected abstract Image getBackBuffer(boolean clear);
 114 
 115     /**
 116      * Updates the window associated with this painter with the contents
 117      * of the passed image.
 118      * The image can not be null, and NPE will be thrown if it is.
 119      */
 120     protected abstract boolean update(Image bb);
 121 
 122     /**
 123      * Create (if needed), clears back buffer (if requested) and return
 124      * graphics for this class depending upon the buffer type
 125      */
 126     protected abstract Graphics getGraphics(boolean clear);
 127 
 128     /**
 129      * Flushes the resources associated with the painter. They will be
 130      * recreated as needed.
 131      */
 132     public abstract void flush();
 133 
 134     /**
 135      * Updates the window associated with the painter.
 136      *
 137      * @param repaint indicates if the window should be completely repainted
 138      * to the back buffer using {@link java.awt.Window#paintAll} before update.
 139      */
 140     public void updateWindow(boolean repaint) {
 141         boolean done = false;

 142         while (!done) {
 143             if (repaint) {
 144                 Graphics2D g = (Graphics2D) getGraphics(repaint);
 145                 try {
 146                     window.paintAll(g);
 147                 } finally {
 148                     g.dispose();
 149                 }
 150             }
 151 
 152             done = update(getBackBuffer(false));
 153             if (!done) {
 154                 repaint = true;

 155             }
 156         }
 157     }
 158 
 159     private static final Image clearImage(Image bb) {
 160         Graphics2D g = (Graphics2D)bb.getGraphics();
 161         int w = bb.getWidth(null);
 162         int h = bb.getHeight(null);
 163 
 164         g.setComposite(AlphaComposite.Src);
 165         g.setColor(new Color(0, 0, 0, 0));
 166         g.fillRect(0, 0, w, h);
 167 
 168         return bb;
 169     }
 170 
 171     /**
 172      * A painter which uses BufferedImage as the internal buffer. The window
 173      * is painted into this buffer, and the contents then are uploaded
 174      * into the layered window.
 175      *
 176      * This painter handles all types of images passed to its paint(Image)
 177      * method (VI, BI, regular Images).
 178      */
 179     private static class BIWindowPainter extends TranslucentWindowPainter {
 180         private BufferedImage backBuffer;
 181 
 182         protected BIWindowPainter(WWindowPeer peer) {
 183             super(peer);
 184         }
 185 
 186         @Override
 187         protected Image getBackBuffer(boolean clear) {
 188             GraphicsConfiguration gc = peer.getGraphicsConfiguration();
 189             AffineTransform transform = gc.getDefaultTransform();
 190             int w = Region.clipRound(
 191                     window.getWidth() * transform.getScaleX());
 192             int h = Region.clipRound(
 193                     window.getHeight() * transform.getScaleY());
 194             if (backBuffer == null ||
 195                 backBuffer.getWidth() != w ||
 196                 backBuffer.getHeight() != h)
 197             {
 198                 flush();
 199                 backBuffer = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE);
 200             }
 201             return clear ? (BufferedImage)clearImage(backBuffer) : backBuffer;
 202         }
 203 
 204         @Override
 205         protected boolean update(Image bb) {
 206             VolatileImage viBB = null;
 207 
 208             if (bb instanceof BufferedImage) {
 209                 BufferedImage bi = (BufferedImage)bb;
 210                 int data[] =
 211                     ((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
 212                 peer.updateWindowImpl(data, bi.getWidth(), bi.getHeight());
 213                 return true;


 230                 }
 231             }
 232 
 233             // copy the passed image into our own buffer, then upload
 234             BufferedImage bi = (BufferedImage)clearImage(backBuffer);
 235 
 236             int data[] =
 237                 ((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
 238             peer.updateWindowImpl(data, bi.getWidth(), bi.getHeight());
 239 
 240             return (viBB != null ? !viBB.contentsLost() : true);
 241         }
 242 
 243         @Override
 244         public void flush() {
 245             if (backBuffer != null) {
 246                 backBuffer.flush();
 247                 backBuffer = null;
 248             }
 249         }
 250 
 251         @Override
 252         protected Graphics getGraphics(boolean clear) {
 253             Graphics g = getBackBuffer(clear).getGraphics();
 254             /*
 255             This graphics object returned by BuffereImage is not scaled to
 256             graphics configuration, but this graphics object can be used by
 257             components inside this TranslucentWindow. So need to scale this
 258             before returning.
 259              */
 260             ((Graphics2D)g).transform(peer.getGraphicsConfiguration().getDefaultTransform());
 261             return g;
 262         }
 263     }
 264 
 265     /**
 266      * A version of the painter which uses VolatileImage as the internal buffer.
 267      * The window is painted into this VI and then copied into the parent's
 268      * Java heap-based buffer (which is then uploaded to the layered window)
 269      */
 270     private static class VIWindowPainter extends BIWindowPainter {
 271         private VolatileImage viBB;
 272 
 273         protected VIWindowPainter(WWindowPeer peer) {
 274             super(peer);
 275         }
 276 
 277         @Override
 278         protected Image getBackBuffer(boolean clear) {
 279             int w = window.getWidth();
 280             int h = window.getHeight();
 281             GraphicsConfiguration gc = peer.getGraphicsConfiguration();
 282 


 289                     AccelGraphicsConfig agc = ((AccelGraphicsConfig)gc);
 290                     viBB = agc.createCompatibleVolatileImage(w, h,
 291                                                              TRANSLUCENT,
 292                                                              RT_PLAIN);
 293                 }
 294                 if (viBB == null) {
 295                     viBB = gc.createCompatibleVolatileImage(w, h, TRANSLUCENT);
 296                 }
 297                 viBB.validate(gc);
 298             }
 299 
 300             return clear ? clearImage(viBB) : viBB;
 301         }
 302 
 303         @Override
 304         public void flush() {
 305             if (viBB != null) {
 306                 viBB.flush();
 307                 viBB = null;
 308             }
 309         }
 310 
 311         @Override
 312         protected Graphics getGraphics(boolean clear) {
 313             return getBackBuffer(clear).getGraphics();
 314         }
 315     }
 316 
 317     /**
 318      * Optimized version of hw painter. Uses VolatileImages for the
 319      * buffer, and uses an optimized path to pull the data from those into
 320      * the layered window, bypassing Java heap-based image.
 321      */
 322     private abstract static class VIOptWindowPainter extends VIWindowPainter {
 323 
 324         protected VIOptWindowPainter(WWindowPeer peer) {
 325             super(peer);
 326         }
 327 
 328         protected abstract boolean updateWindowAccel(long psdops, int w, int h);
 329 
 330         @Override
 331         protected boolean update(Image bb) {
 332             if (bb instanceof DestSurfaceProvider) {
 333                 Surface s = ((DestSurfaceProvider)bb).getDestSurface();


< prev index next >