jdk/src/share/classes/javax/swing/BufferStrategyPaintManager.java
changeset 3938 ef327bd847c0
parent 3109 da7f8bcd9650
child 5506 202f599c92aa
equal deleted inserted replaced
3934:487e1aa949c4 3938:ef327bd847c0
    30 import java.awt.image.*;
    30 import java.awt.image.*;
    31 import java.lang.reflect.*;
    31 import java.lang.reflect.*;
    32 import java.lang.ref.WeakReference;
    32 import java.lang.ref.WeakReference;
    33 import java.security.AccessController;
    33 import java.security.AccessController;
    34 import java.util.*;
    34 import java.util.*;
    35 import java.util.logging.*;
       
    36 
    35 
    37 import com.sun.java.swing.SwingUtilities3;
    36 import com.sun.java.swing.SwingUtilities3;
    38 
    37 
    39 import sun.awt.SubRegionShowable;
    38 import sun.awt.SubRegionShowable;
    40 import sun.java2d.SunGraphics2D;
    39 import sun.java2d.SunGraphics2D;
    41 import sun.security.action.GetPropertyAction;
    40 import sun.security.action.GetPropertyAction;
    42 import sun.java2d.pipe.hw.ExtendedBufferCapabilities;
    41 import sun.java2d.pipe.hw.ExtendedBufferCapabilities;
    43 import sun.awt.SunToolkit;
    42 import sun.awt.SunToolkit;
       
    43 import sun.util.logging.PlatformLogger;
    44 
    44 
    45 /**
    45 /**
    46  * A PaintManager implementation that uses a BufferStrategy for
    46  * A PaintManager implementation that uses a BufferStrategy for
    47  * rendering.
    47  * rendering.
    48  *
    48  *
    76     // Methods used to create BufferStrategy for Applets.
    76     // Methods used to create BufferStrategy for Applets.
    77     //
    77     //
    78     private static Method COMPONENT_CREATE_BUFFER_STRATEGY_METHOD;
    78     private static Method COMPONENT_CREATE_BUFFER_STRATEGY_METHOD;
    79     private static Method COMPONENT_GET_BUFFER_STRATEGY_METHOD;
    79     private static Method COMPONENT_GET_BUFFER_STRATEGY_METHOD;
    80 
    80 
    81     private static final Logger LOGGER = Logger.getLogger(
    81     private static final PlatformLogger LOGGER = PlatformLogger.getLogger(
    82                            "javax.swing.BufferStrategyPaintManager");
    82                            "javax.swing.BufferStrategyPaintManager");
    83 
    83 
    84     /**
    84     /**
    85      * List of BufferInfos.  We don't use a Map primarily because
    85      * List of BufferInfos.  We don't use a Map primarily because
    86      * there are typically only a handful of top level components making
    86      * there are typically only a handful of top level components making
   220             }
   220             }
   221         });
   221         });
   222     }
   222     }
   223 
   223 
   224     private void dispose(java.util.List<BufferInfo> bufferInfos) {
   224     private void dispose(java.util.List<BufferInfo> bufferInfos) {
   225         if (LOGGER.isLoggable(Level.FINER)) {
   225         if (LOGGER.isLoggable(PlatformLogger.FINER)) {
   226             LOGGER.log(Level.FINER, "BufferStrategyPaintManager disposed",
   226             LOGGER.finer("BufferStrategyPaintManager disposed",
   227                        new RuntimeException());
   227                          new RuntimeException());
   228         }
   228         }
   229         if (bufferInfos != null) {
   229         if (bufferInfos != null) {
   230             for (BufferInfo bufferInfo : bufferInfos) {
   230             for (BufferInfo bufferInfo : bufferInfos) {
   231                 bufferInfo.dispose();
   231                 bufferInfo.dispose();
   232             }
   232             }
   303                 bufferInfo.setInSync(false);
   303                 bufferInfo.setInSync(false);
   304                 // Fall through to old rendering.
   304                 // Fall through to old rendering.
   305             }
   305             }
   306         }
   306         }
   307         // Invalid root, do what Swing has always done.
   307         // Invalid root, do what Swing has always done.
   308         if (LOGGER.isLoggable(Level.FINER)) {
   308         if (LOGGER.isLoggable(PlatformLogger.FINER)) {
   309             LOGGER.finer("prepare failed");
   309             LOGGER.finer("prepare failed");
   310         }
   310         }
   311         return super.paint(paintingComponent, bufferComponent, g, x, y, w, h);
   311         return super.paint(paintingComponent, bufferComponent, g, x, y, w, h);
   312     }
   312     }
   313 
   313 
   333                 bsg.copyArea(xOffset + x, yOffset + y, w, h, deltaX,
   333                 bsg.copyArea(xOffset + x, yOffset + y, w, h, deltaX,
   334                              deltaY);
   334                              deltaY);
   335             }
   335             }
   336             accumulate(x + xOffset + deltaX, y + yOffset + deltaY, w, h);
   336             accumulate(x + xOffset + deltaX, y + yOffset + deltaY, w, h);
   337         } else {
   337         } else {
   338             if (LOGGER.isLoggable(Level.FINER)) {
   338             if (LOGGER.isLoggable(PlatformLogger.FINER)) {
   339                 LOGGER.finer("copyArea: prepare failed or not in sync");
   339                 LOGGER.finer("copyArea: prepare failed or not in sync");
   340             }
   340             }
   341             // Prepare failed, or not in sync. By calling super.copyArea
   341             // Prepare failed, or not in sync. By calling super.copyArea
   342             // we'll copy on screen. We need to flush any pending paint to
   342             // we'll copy on screen. We need to flush any pending paint to
   343             // the screen otherwise we'll do a copyArea on the wrong thing.
   343             // the screen otherwise we'll do a copyArea on the wrong thing.
   361                     wait();
   361                     wait();
   362                 } catch (InterruptedException ie) {
   362                 } catch (InterruptedException ie) {
   363                 }
   363                 }
   364             }
   364             }
   365         }
   365         }
   366         if (LOGGER.isLoggable(Level.FINEST)) {
   366         if (LOGGER.isLoggable(PlatformLogger.FINEST)) {
   367             LOGGER.finest("beginPaint");
   367             LOGGER.finest("beginPaint");
   368         }
   368         }
   369         // Reset the area that needs to be painted.
   369         // Reset the area that needs to be painted.
   370         resetAccumulated();
   370         resetAccumulated();
   371     }
   371     }
   372 
   372 
   373     public void endPaint() {
   373     public void endPaint() {
   374         if (LOGGER.isLoggable(Level.FINEST)) {
   374         if (LOGGER.isLoggable(PlatformLogger.FINEST)) {
   375             LOGGER.finest("endPaint: region " + accumulatedX + " " +
   375             LOGGER.finest("endPaint: region " + accumulatedX + " " +
   376                        accumulatedY + " " +  accumulatedMaxX + " " +
   376                        accumulatedY + " " +  accumulatedMaxX + " " +
   377                        accumulatedMaxY);
   377                        accumulatedMaxY);
   378         }
   378         }
   379         if (painting) {
   379         if (painting) {
   418                 bsSubRegion.show(accumulatedX, accumulatedY,
   418                 bsSubRegion.show(accumulatedX, accumulatedY,
   419                                  accumulatedMaxX, accumulatedMaxY);
   419                                  accumulatedMaxX, accumulatedMaxY);
   420                 contentsLost = bufferStrategy.contentsLost();
   420                 contentsLost = bufferStrategy.contentsLost();
   421             }
   421             }
   422             if (contentsLost) {
   422             if (contentsLost) {
   423                 if (LOGGER.isLoggable(Level.FINER)) {
   423                 if (LOGGER.isLoggable(PlatformLogger.FINER)) {
   424                     LOGGER.finer("endPaint: contents lost");
   424                     LOGGER.finer("endPaint: contents lost");
   425                 }
   425                 }
   426                 // Shown region was bogus, mark buffer as out of sync.
   426                 // Shown region was bogus, mark buffer as out of sync.
   427                 bufferInfo.setInSync(false);
   427                 bufferInfo.setInSync(false);
   428                 success = false;
   428                 success = false;
   512             BufferInfo bufferInfo = getBufferInfo(root);
   512             BufferInfo bufferInfo = getBufferInfo(root);
   513             if (bufferInfo == null) {
   513             if (bufferInfo == null) {
   514                 contentsLost = true;
   514                 contentsLost = true;
   515                 bufferInfo = new BufferInfo(root);
   515                 bufferInfo = new BufferInfo(root);
   516                 bufferInfos.add(bufferInfo);
   516                 bufferInfos.add(bufferInfo);
   517                 if (LOGGER.isLoggable(Level.FINER)) {
   517                 if (LOGGER.isLoggable(PlatformLogger.FINER)) {
   518                     LOGGER.finer("prepare: new BufferInfo: " + root);
   518                     LOGGER.finer("prepare: new BufferInfo: " + root);
   519                 }
   519                 }
   520             }
   520             }
   521             this.bufferInfo = bufferInfo;
   521             this.bufferInfo = bufferInfo;
   522             if (!bufferInfo.hasBufferStrategyChanged()) {
   522             if (!bufferInfo.hasBufferStrategyChanged()) {
   523                 bufferStrategy = bufferInfo.getBufferStrategy(true);
   523                 bufferStrategy = bufferInfo.getBufferStrategy(true);
   524                 if (bufferStrategy != null) {
   524                 if (bufferStrategy != null) {
   525                     bsg = bufferStrategy.getDrawGraphics();
   525                     bsg = bufferStrategy.getDrawGraphics();
   526                     if (bufferStrategy.contentsRestored()) {
   526                     if (bufferStrategy.contentsRestored()) {
   527                         contentsLost = true;
   527                         contentsLost = true;
   528                         if (LOGGER.isLoggable(Level.FINER)) {
   528                         if (LOGGER.isLoggable(PlatformLogger.FINER)) {
   529                             LOGGER.finer(
   529                             LOGGER.finer(
   530                                 "prepare: contents restored in prepare");
   530                                 "prepare: contents restored in prepare");
   531                         }
   531                         }
   532                     }
   532                     }
   533                 }
   533                 }
   537                     return false;
   537                     return false;
   538                 }
   538                 }
   539                 if (bufferInfo.getContentsLostDuringExpose()) {
   539                 if (bufferInfo.getContentsLostDuringExpose()) {
   540                     contentsLost = true;
   540                     contentsLost = true;
   541                     bufferInfo.setContentsLostDuringExpose(false);
   541                     bufferInfo.setContentsLostDuringExpose(false);
   542                     if (LOGGER.isLoggable(Level.FINER)) {
   542                     if (LOGGER.isLoggable(PlatformLogger.FINER)) {
   543                         LOGGER.finer("prepare: contents lost on expose");
   543                         LOGGER.finer("prepare: contents lost on expose");
   544                     }
   544                     }
   545                 }
   545                 }
   546                 if (isPaint && c == rootJ && x == 0 && y == 0 &&
   546                 if (isPaint && c == rootJ && x == 0 && y == 0 &&
   547                       c.getWidth() == w && c.getHeight() == h) {
   547                       c.getWidth() == w && c.getHeight() == h) {
   640             BufferInfo bufferInfo = bufferInfos.get(counter);
   640             BufferInfo bufferInfo = bufferInfos.get(counter);
   641             Container biRoot = bufferInfo.getRoot();
   641             Container biRoot = bufferInfo.getRoot();
   642             if (biRoot == null) {
   642             if (biRoot == null) {
   643                 // Window gc'ed
   643                 // Window gc'ed
   644                 bufferInfos.remove(counter);
   644                 bufferInfos.remove(counter);
   645                 if (LOGGER.isLoggable(Level.FINER)) {
   645                 if (LOGGER.isLoggable(PlatformLogger.FINER)) {
   646                     LOGGER.finer("BufferInfo pruned, root null");
   646                     LOGGER.finer("BufferInfo pruned, root null");
   647                 }
   647                 }
   648             }
   648             }
   649             else if (biRoot == root) {
   649             else if (biRoot == root) {
   650                 return bufferInfo;
   650                 return bufferInfo;
   746             if (bs == null && create) {
   746             if (bs == null && create) {
   747                 bs = createBufferStrategy();
   747                 bs = createBufferStrategy();
   748                 if (bs != null) {
   748                 if (bs != null) {
   749                     weakBS = new WeakReference<BufferStrategy>(bs);
   749                     weakBS = new WeakReference<BufferStrategy>(bs);
   750                 }
   750                 }
   751                 if (LOGGER.isLoggable(Level.FINER)) {
   751                 if (LOGGER.isLoggable(PlatformLogger.FINER)) {
   752                     LOGGER.finer("getBufferStrategy: created bs: " + bs);
   752                     LOGGER.finer("getBufferStrategy: created bs: " + bs);
   753                 }
   753                 }
   754             }
   754             }
   755             return bs;
   755             return bs;
   756         }
   756         }
   804                 return null;
   804                 return null;
   805             }
   805             }
   806             BufferStrategy bs = null;
   806             BufferStrategy bs = null;
   807             if (SwingUtilities3.isVsyncRequested(root)) {
   807             if (SwingUtilities3.isVsyncRequested(root)) {
   808                 bs = createBufferStrategy(root, true);
   808                 bs = createBufferStrategy(root, true);
   809                 if (LOGGER.isLoggable(Level.FINER)) {
   809                 if (LOGGER.isLoggable(PlatformLogger.FINER)) {
   810                     LOGGER.finer("createBufferStrategy: using vsynced strategy");
   810                     LOGGER.finer("createBufferStrategy: using vsynced strategy");
   811                 }
   811                 }
   812             }
   812             }
   813             if (bs == null) {
   813             if (bs == null) {
   814                 bs = createBufferStrategy(root, false);
   814                 bs = createBufferStrategy(root, false);
   846                     getCreateBufferStrategyMethod().invoke(root, 2, caps);
   846                     getCreateBufferStrategyMethod().invoke(root, 2, caps);
   847                     bs = (BufferStrategy)getGetBufferStrategyMethod().
   847                     bs = (BufferStrategy)getGetBufferStrategyMethod().
   848                                             invoke(root);
   848                                             invoke(root);
   849                 } catch (InvocationTargetException ite) {
   849                 } catch (InvocationTargetException ite) {
   850                     // Type is not supported
   850                     // Type is not supported
   851                     if (LOGGER.isLoggable(Level.FINER)) {
   851                     if (LOGGER.isLoggable(PlatformLogger.FINER)) {
   852                         LOGGER.log(Level.FINER, "createBufferStratety failed",
   852                         LOGGER.finer("createBufferStratety failed",
   853                                    ite);
   853                                      ite);
   854                     }
   854                     }
   855                 } catch (IllegalArgumentException iae) {
   855                 } catch (IllegalArgumentException iae) {
   856                     assert false;
   856                     assert false;
   857                 } catch (IllegalAccessException iae2) {
   857                 } catch (IllegalAccessException iae2) {
   858                     assert false;
   858                     assert false;
   862                 try {
   862                 try {
   863                     ((Window)root).createBufferStrategy(2, caps);
   863                     ((Window)root).createBufferStrategy(2, caps);
   864                     bs = ((Window)root).getBufferStrategy();
   864                     bs = ((Window)root).getBufferStrategy();
   865                 } catch (AWTException e) {
   865                 } catch (AWTException e) {
   866                     // Type not supported
   866                     // Type not supported
   867                     if (LOGGER.isLoggable(Level.FINER)) {
   867                     if (LOGGER.isLoggable(PlatformLogger.FINER)) {
   868                         LOGGER.log(Level.FINER, "createBufferStratety failed",
   868                         LOGGER.finer("createBufferStratety failed",
   869                                    e);
   869                                      e);
   870                     }
   870                     }
   871                 }
   871                 }
   872             }
   872             }
   873             return bs;
   873             return bs;
   874         }
   874         }
   876         /**
   876         /**
   877          * Cleans up and removes any references.
   877          * Cleans up and removes any references.
   878          */
   878          */
   879         public void dispose() {
   879         public void dispose() {
   880             Container root = getRoot();
   880             Container root = getRoot();
   881             if (LOGGER.isLoggable(Level.FINER)) {
   881             if (LOGGER.isLoggable(PlatformLogger.FINER)) {
   882                 LOGGER.log(Level.FINER, "disposed BufferInfo for: " + root);
   882                 LOGGER.finer("disposed BufferInfo for: " + root);
   883             }
   883             }
   884             if (root != null) {
   884             if (root != null) {
   885                 root.removeComponentListener(this);
   885                 root.removeComponentListener(this);
   886                 if (root instanceof Window) {
   886                 if (root instanceof Window) {
   887                     ((Window)root).removeWindowListener(this);
   887                     ((Window)root).removeWindowListener(this);