6679840: provide a way to choose v-synced BufferStrategy
authormalenkov
Fri, 26 Jun 2009 16:58:46 +0400
changeset 3105 b5931be76fbc
parent 3104 cce457efb5d8
child 3106 bb4a4ea50e55
6679840: provide a way to choose v-synced BufferStrategy Reviewed-by: peterz
jdk/src/share/classes/com/sun/java/swing/SwingUtilities3.java
jdk/src/share/classes/javax/swing/BufferStrategyPaintManager.java
--- a/jdk/src/share/classes/com/sun/java/swing/SwingUtilities3.java	Fri Jun 26 16:30:02 2009 +0400
+++ b/jdk/src/share/classes/com/sun/java/swing/SwingUtilities3.java	Fri Jun 26 16:58:46 2009 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2002-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,13 +27,17 @@
 
 import sun.awt.EventQueueDelegate;
 import sun.awt.AppContext;
+import java.util.Collections;
 import java.util.Map;
+import java.util.WeakHashMap;
 import java.util.concurrent.Callable;
 import java.awt.AWTEvent;
 import java.awt.EventQueue;
 import java.awt.Component;
+import java.awt.Container;
 import javax.swing.JComponent;
 import javax.swing.RepaintManager;
+import javax.swing.SwingUtilities;
 
 /**
  * A collection of utility methods for Swing.
@@ -69,6 +73,43 @@
                                     repaintManager);
     }
 
+    private static final Map<Container, Boolean> vsyncedMap =
+        Collections.synchronizedMap(new WeakHashMap<Container, Boolean>());
+
+    /**
+     * Sets vsyncRequested state for the {@code rootContainer}.  If
+     * {@code isRequested} is {@code true} then vsynced
+     * {@code BufferStrategy} is enabled for this {@code rootContainer}.
+     *
+     * Note: requesting vsynced painting does not guarantee one. The outcome
+     * depends on current RepaintManager's RepaintManager.PaintManager
+     * and on the capabilities of the graphics hardware/software and what not.
+     *
+     * @param rootContainer topmost container. Should be either {@code Window}
+     *  or {@code Applet}
+     * @param isRequested the value to set vsyncRequested state to
+     */
+    public static void setVsyncRequested(Container rootContainer,
+                                         boolean isRequested) {
+        assert SwingUtilities.getRoot(rootContainer) == rootContainer;
+        if (isRequested) {
+            vsyncedMap.put(rootContainer, Boolean.TRUE);
+        } else {
+            vsyncedMap.remove(rootContainer);
+        }
+    }
+
+    /**
+     * Checks if vsync painting is requested for {@code rootContainer}
+     *
+     * @param rootContainer topmost container. Should be either Window or Applet
+     * @return {@code true} if vsync painting is requested for {@code rootContainer}
+     */
+    public static boolean isVsyncRequested(Container rootContainer) {
+        assert SwingUtilities.getRoot(rootContainer) == rootContainer;
+        return Boolean.TRUE == vsyncedMap.get(rootContainer);
+    }
+
     /**
      * Returns delegate {@code RepaintManager} for {@code component} hierarchy.
      */
--- a/jdk/src/share/classes/javax/swing/BufferStrategyPaintManager.java	Fri Jun 26 16:30:02 2009 +0400
+++ b/jdk/src/share/classes/javax/swing/BufferStrategyPaintManager.java	Fri Jun 26 16:58:46 2009 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,9 +33,13 @@
 import java.security.AccessController;
 import java.util.*;
 import java.util.logging.*;
+
+import com.sun.java.swing.SwingUtilities3;
+
 import sun.awt.SubRegionShowable;
 import sun.java2d.SunGraphics2D;
 import sun.security.action.GetPropertyAction;
+import sun.java2d.pipe.hw.ExtendedBufferCapabilities;
 
 /**
  * A PaintManager implementation that uses a BufferStrategy for
@@ -73,12 +77,6 @@
     private static Method COMPONENT_CREATE_BUFFER_STRATEGY_METHOD;
     private static Method COMPONENT_GET_BUFFER_STRATEGY_METHOD;
 
-    /**
-     * Indicates whether or not we should try and get a flip buffer strategy
-     * first, default is false.
-     */
-    private static boolean TRY_FLIP;
-
     private static final Logger LOGGER = Logger.getLogger(
                            "javax.swing.BufferStrategyPaintManager");
 
@@ -151,12 +149,6 @@
      */
     private boolean disposeBufferOnEnd;
 
-
-    static {
-        TRY_FLIP = "true".equals(AccessController.doPrivileged(
-              new GetPropertyAction("swing.useFlipBufferStrategy", "false")));
-    }
-
     private static Method getGetBufferStrategyMethod() {
         if (COMPONENT_GET_BUFFER_STRATEGY_METHOD == null) {
             getMethods();
@@ -257,7 +249,7 @@
         try {
             BufferInfo info = getBufferInfo(c);
             BufferStrategy bufferStrategy;
-            if (info != null && !info.usingFlip && info.isInSync() &&
+            if (info != null && info.isInSync() &&
                 (bufferStrategy = info.getBufferStrategy(false)) != null) {
                 SubRegionShowable bsSubRegion =
                         (SubRegionShowable)bufferStrategy;
@@ -685,8 +677,6 @@
         // same reason.
         private WeakReference<BufferStrategy> weakBS;
         private WeakReference<Container> root;
-        // Whether or not we're using flip bs or blit.
-        private boolean usingFlip;
         // Indicates whether or not the backbuffer and display are in sync.
         // This is set to true when a full repaint on the rootpane is done.
         private boolean inSync;
@@ -764,13 +754,6 @@
         }
 
         /**
-         * Returns true if using a flip buffer strategy.
-         */
-        public boolean usingFlip() {
-            return usingFlip;
-        }
-
-        /**
          * Returns true if the buffer strategy of the component differs
          * from current buffer strategy.
          */
@@ -814,23 +797,19 @@
          * blit.
          */
         private BufferStrategy createBufferStrategy() {
-            BufferCapabilities caps;
             Container root = getRoot();
             if (root == null) {
                 return null;
             }
             BufferStrategy bs = null;
-            if (TRY_FLIP) {
-                bs = createBufferStrategy(root,BufferCapabilities.FlipContents.
-                                          COPIED);
-                usingFlip = true;
+            if (SwingUtilities3.isVsyncRequested(root)) {
+                bs = createBufferStrategy(root, true);
                 if (LOGGER.isLoggable(Level.FINER)) {
-                    LOGGER.finer("createBufferStrategy: using flip strategy");
+                    LOGGER.finer("createBufferStrategy: using vsynced strategy");
                 }
             }
             if (bs == null) {
-                bs = createBufferStrategy(root, null);
-                usingFlip = false;
+                bs = createBufferStrategy(root, false);
             }
             if (!(bs instanceof SubRegionShowable)) {
                 // We do this for two reasons:
@@ -843,15 +822,22 @@
             return bs;
         }
 
-        // Creates and returns a buffer strategy of the requested type.  If
+        // Creates and returns a buffer strategy.  If
         // there is a problem creating the buffer strategy this will
         // eat the exception and return null.
         private BufferStrategy createBufferStrategy(Container root,
-                                     BufferCapabilities.FlipContents type) {
-            BufferCapabilities caps = new BufferCapabilities(
-                    new ImageCapabilities(true),
-                    new ImageCapabilities(true),
-                    type);
+                boolean isVsynced) {
+            BufferCapabilities caps;
+            if (isVsynced) {
+                caps = new ExtendedBufferCapabilities(
+                    new ImageCapabilities(true), new ImageCapabilities(true),
+                    BufferCapabilities.FlipContents.COPIED,
+                    ExtendedBufferCapabilities.VSyncType.VSYNC_ON);
+            } else {
+                caps = new BufferCapabilities(
+                    new ImageCapabilities(true), new ImageCapabilities(true),
+                    null);
+            }
             BufferStrategy bs = null;
             if (root instanceof Applet) {
                 try {