This is a cleanup. I disabled some parts of RepaintManager some time ago because I suspected that it doesn't improve painting performance, and now I rip these parts out. This also means some slight performance improvement, because the rectangle translation is done on the fly.

2006-08-17  Roman Kennke  <[EMAIL PROTECTED]>

        * javax/swing/RepaintManager.java
        (blitBuffer): Removed. This is now done in commitBuffer().
        (commitBuffer): Always paint on the root window or applet.
        No need to look for intermediate heavyweights. Optimized
        rectangle translation.
        (commitRemainingBuffers): Removed. Not needed anymore.
        (getHeavyweightParent): Removed. Not needed anymore.
        (getOffscreenBuffer): Fetch offscreen image from the
        actual root component.
        (paintDirtyRegions): Don't call commitRemainingBuffers().


/Roman
Index: javax/swing/RepaintManager.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/RepaintManager.java,v
retrieving revision 1.43
diff -u -1 -2 -r1.43 RepaintManager.java
--- javax/swing/RepaintManager.java	26 Jul 2006 21:16:51 -0000	1.43
+++ javax/swing/RepaintManager.java	17 Aug 2006 15:00:52 -0000
@@ -29,36 +29,36 @@
 modules, and to copy and distribute the resulting executable under
 terms of your choice, provided that you also meet, for each linked
 independent module, the terms and conditions of the license of that
 module.  An independent module is a module which is not derived from
 or based on this library.  If you modify this library, you may extend
 this exception to your version of the library, but you are not
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
 
 package javax.swing;
 
+import java.applet.Applet;
 import java.awt.Component;
 import java.awt.Dimension;
 import java.awt.Graphics;
 import java.awt.Image;
 import java.awt.Rectangle;
 import java.awt.Window;
 import java.awt.image.VolatileImage;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
-import java.util.Map;
 import java.util.Set;
 import java.util.WeakHashMap;
 
 /**
  * <p>The repaint manager holds a set of dirty regions, invalid components,
  * and a double buffer surface.  The dirty regions and invalid components
  * are used to coalesce multiple revalidate() and repaint() calls in the
  * component tree into larger groups to be refreshed "all at once"; the
  * double buffer surface is used by root components to paint
  * themselves.</p>
  *
  * <p>See <a
@@ -559,25 +559,24 @@
 
     repaintUnderway = true;
     for (Iterator i = repaintRoots.iterator(); i.hasNext();)
       {
         JComponent comp = (JComponent) i.next();
         Rectangle damaged = (Rectangle) dirtyComponentsWork.remove(comp);
         if (damaged == null || damaged.isEmpty())
           continue;
         comp.paintImmediately(damaged);
       }
     dirtyComponentsWork.clear();
     repaintUnderway = false;
-    commitRemainingBuffers();
   }
   
   /**
    * Compiles a list of components that really get repainted. This is called
    * once for each component in the dirtyComponents HashMap, each time with
    * another <code>dirty</code> parameter. This searches up the component
    * hierarchy of <code>dirty</code> to find the highest parent that is also
    * marked dirty and merges the dirty regions.
    *
    * @param dirtyRegions the dirty regions 
    * @param dirty the component for which to find the repaint root
    * @param roots the list to which new repaint roots get appended
@@ -634,148 +633,55 @@
                                   int proposedHeight)
   {
     Component root = SwingUtilities.getWindowAncestor(component);
     Image buffer = (Image) offscreenBuffers.get(root);
     if (buffer == null 
         || buffer.getWidth(null) < proposedWidth 
         || buffer.getHeight(null) < proposedHeight)
       {
         int width = Math.max(proposedWidth, root.getWidth());
         width = Math.min(doubleBufferMaximumSize.width, width);
         int height = Math.max(proposedHeight, root.getHeight());
         height = Math.min(doubleBufferMaximumSize.height, height);
-        buffer = root.createImage(width, height);
+        buffer = component.createImage(width, height);
         offscreenBuffers.put(root, buffer);
       }
     return buffer;
   }
 
   /**
-   * Blits the back buffer of the specified root component to the screen. If
-   * the RepaintManager is currently working on a paint request, the commit
-   * requests are queued up and committed at once when the paint request is
-   * done (by [EMAIL PROTECTED] #commitRemainingBuffers}). This is package private because
-   * it must get called by JComponent.
+   * Blits the back buffer of the specified root component to the screen.
+   * This is package private because it must get called by JComponent.
    *
    * @param comp the component to be painted
    * @param area the area to paint on screen, in comp coordinates
    */
   void commitBuffer(Component comp, Rectangle area)
   {
-    // Determine the component that we finally paint the buffer upon.
-    // We need to paint on the nearest heavyweight component, so that Swing
-    // hierarchies inside (non-window) heavyweights get painted correctly.
-    // Otherwise we would end up blitting the backbuffer behind the heavyweight
-    // which is wrong.
-    Component root = getHeavyweightParent(comp);
-    // FIXME: Optimize this.
-    Rectangle rootRect = SwingUtilities.convertRectangle(comp, area, root);
-
-    // We synchronize on dirtyComponents here because that is what
-    // paintDirtyRegions also synchronizes on while painting.
-    synchronized (dirtyComponents)
-      {
-        // If the RepaintManager is not currently painting, then directly
-        // blit the requested buffer on the screen.
-        if (true || ! repaintUnderway)
-          {
-            blitBuffer(root, rootRect);
-          }
-
-        // Otherwise queue this request up, until all the RepaintManager work
-        // is done.
-        else
-          {
-            if (commitRequests.containsKey(root))
-              SwingUtilities.computeUnion(rootRect.x, rootRect.y,
-                                          rootRect.width, rootRect.height,
-                                         (Rectangle) commitRequests.get(root));
-            else
-              commitRequests.put(root, rootRect);
-          }
-      }
-  }
-
-  /**
-   * Copies the buffer to the screen. Note that the root component here is
-   * not necessarily the component with which the offscreen buffer is
-   * associated. The offscreen buffers are always allocated for the toplevel
-   * windows. However, painted is performed on lower-level heavyweight
-   * components too, if they contain Swing components.
-   *
-   * @param root the heavyweight component to blit upon
-   * @param rootRect the rectangle in the root component's coordinate space
-   */
-  private void blitBuffer(Component root, Rectangle rootRect)
-  {
-    if (! root.isShowing())
-      return;
-
-    // Find the Window from which we use the backbuffer.
-    Component bufferRoot = root;
-    Rectangle bufferRect = rootRect.getBounds();
-    if (!(bufferRoot instanceof Window))
-      {
-        bufferRoot = SwingUtilities.getWindowAncestor(bufferRoot);
-        SwingUtilities.convertRectangleToAncestor(root, rootRect, bufferRoot);
+    Component root = comp;
+    while (root != null
+	   && ! (root instanceof Window || root instanceof Applet))
+      {
+	area.x += root.getX();
+	area.y += root.getY();
+	root = root.getParent();
       }
 
     Graphics g = root.getGraphics();
-    Image buffer = (Image) offscreenBuffers.get(bufferRoot);
+    Image buffer = (Image) offscreenBuffers.get(root);
 
     // Make sure we have a sane clip at this point.
-    g.clipRect(rootRect.x, rootRect.y, rootRect.width, rootRect.height);
-    g.drawImage(buffer, rootRect.x - bufferRect.x, rootRect.y - bufferRect.y,
-                root);
+    g.clipRect(area.x, area.y, area.width, area.height);
+    g.drawImage(buffer, 0, 0, root);
     g.dispose();
-
-  }
-
-  /**
-   * Finds and returns the nearest heavyweight parent for the specified
-   * component. If the component isn't contained inside a heavyweight parent,
-   * this returns null.
-   *
-   * @param comp the component
-   *
-   * @return the nearest heavyweight parent for the specified component or
-   *         null if the component has no heavyweight ancestor
-   */
-  private Component getHeavyweightParent(Component comp)
-  {
-    while (comp != null && comp.isLightweight())
-      comp = comp.getParent();
-    return comp;
-  }
-
-  /**
-   * Commits the queued up back buffers to screen all at once.
-   */
-  private void commitRemainingBuffers()
-  {
-    // We synchronize on dirtyComponents here because that is what
-    // paintDirtyRegions also synchronizes on while painting.
-    synchronized (dirtyComponents)
-      {
-        Set entrySet = commitRequests.entrySet();
-        Iterator i = entrySet.iterator();
-        while (i.hasNext())
-          {
-            Map.Entry entry = (Map.Entry) i.next();
-            Component root = (Component) entry.getKey();
-            Rectangle area = (Rectangle) entry.getValue();
-            blitBuffer(root, area);
-            i.remove();
-          }
-      }
   }
 
   /**
    * Creates and returns a volatile offscreen buffer for the specified
    * component that can be used as a double buffer. The returned image
    * is a [EMAIL PROTECTED] VolatileImage}. Its size will be <code>(proposedWidth,
    * proposedHeight)</code> except when the maximum double buffer size
    * has been set in this RepaintManager.
    *
    * @param comp the Component for which to create a volatile buffer
    * @param proposedWidth the proposed width of the buffer
    * @param proposedHeight the proposed height of the buffer

Reply via email to