[cp-patches] FYI: RepaintManager fix
In the RepaintManager we used to merge regions of different components to one when blitting the buffer on the screen. However, this proves to cause painting artifacts. This happens when different distinct regions of the screen get updated simultanously (especially when using Timers and/or multiple Threads). Then these (possibly small) regions get merged and all the area between them gets blitted to screen too, even if it contains garbage (like, when some component has been removed in that area). This is what happened to some apps on my box. I disabled this feature and might need to rework it, or remove it. Gotta make up my mind about this. 2006-06-14 Roman Kennke [EMAIL PROTECTED] * javax/swing/RepaintManager.java (MERGE_REGIONS): New constant flag. (commitBuffer): Exclude the merging of regions by default. This was causing painting artifacts in some applications, especially when different areas of the GUI are updated synchronously. /Roman -- “Improvement makes straight roads, but the crooked roads, without Improvement, are roads of Genius.” - William Blake Index: javax/swing/RepaintManager.java === RCS file: /cvsroot/classpath/classpath/javax/swing/RepaintManager.java,v retrieving revision 1.38 diff -u -1 -0 -r1.38 RepaintManager.java --- javax/swing/RepaintManager.java 14 Jun 2006 11:01:25 - 1.38 +++ javax/swing/RepaintManager.java 14 Jun 2006 16:06:28 - @@ -31,21 +31,20 @@ 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; @@ -71,20 +70,26 @@ * @author Audrius Meskauskas ([EMAIL PROTECTED]) */ public class RepaintManager { /** * The current repaint managers, indexed by their ThreadGroups. */ static WeakHashMap currentRepaintManagers; /** + * Used to disable merging of regions in commitBuffer(). This has caused + * problems and may either need to be reworked or removed. + */ + private static final boolean MERGE_REGIONS = false; + + /** * A rectangle object to be reused in damaged regions calculation. */ private static Rectangle rectCache = new Rectangle(); /** * pA helper class which is placed into the system event queue at * various times in order to facilitate repainting and layout. There is * typically only one of these objects active at any time. When the * [EMAIL PROTECTED] RepaintManager} is told to queue a repaint, it checks to see if * a [EMAIL PROTECTED] RepaintWorker} is live in the system event queue, and if @@ -654,21 +659,21 @@ 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 (! repaintUnderway) +if (! MERGE_REGIONS || ! 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, signature.asc Description: Dies ist ein digital signierter Nachrichtenteil
[cp-patches] FYI: RepaintManager fix
I fixed a condition in RepaintManager.validateInvalidComponents() to avoid an NPE. 2006-01-10 Roman Kennke [EMAIL PROTECTED] * javax/swing/RepaintManager.java (validateInvalidComponents): Fixed condition to avoid NPE. /Roman Index: javax/swing/RepaintManager.java === RCS file: /cvsroot/classpath/classpath/javax/swing/RepaintManager.java,v retrieving revision 1.20 diff -u -r1.20 RepaintManager.java --- javax/swing/RepaintManager.java 5 Jan 2006 16:26:14 - 1.20 +++ javax/swing/RepaintManager.java 10 Jan 2006 13:05:23 - @@ -536,8 +536,8 @@ { Component comp = (Component) i.next(); // Find validate root. -while (!(comp instanceof JComponent) - || !((JComponent) comp).isValidateRoot() +while ((!(comp instanceof JComponent) + || !((JComponent) comp).isValidateRoot()) comp.getParent() != null) comp = comp.getParent(); ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] FYI: RepaintManager fix
Hi there, I fixed a bug in the RepaintManager. Until now, the RepaintManager iterated over all invalid components and simply called validate() on it. However, it should not validate() the invalid components directly, but instead search the component's validate root (see JComponent.isValidateRoot() for details) and validate that. This is fixed by this patch. This should give us some performance gain, since it avoids unnecessary multiple validations. 2006-01-05 Roman Kennke [EMAIL PROTECTED] * javax/swing/RepaintManager.java (validateInvalidComponents): Search for the validate root and start validating there. /Roman Index: javax/swing/RepaintManager.java === RCS file: /cvsroot/classpath/classpath/javax/swing/RepaintManager.java,v retrieving revision 1.19 diff -u -r1.19 RepaintManager.java --- javax/swing/RepaintManager.java 21 Nov 2005 14:01:43 - 1.19 +++ javax/swing/RepaintManager.java 5 Jan 2006 16:25:14 - @@ -534,7 +534,14 @@ } for (Iterator i = workInvalidComponents.iterator(); i.hasNext(); ) { -JComponent comp = (JComponent) i.next(); +Component comp = (Component) i.next(); +// Find validate root. +while (!(comp instanceof JComponent) + || !((JComponent) comp).isValidateRoot() +comp.getParent() != null) + comp = comp.getParent(); + +// Validate the validate root. if (! (comp.isVisible() comp.isShowing())) continue; comp.validate(); ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
Re: [cp-patches] FYI: RepaintManager fix
Am Samstag, den 19.11.2005, 19:09 +0100 schrieb Mark Wielaard: Hi Roman, On Mon, 2005-11-14 at 12:52 +, Roman Kennke wrote: + /** + * The current repaint managers, indexed by their ThreadGroups. + */ + static HashMap currentRepaintManagers; Isn't this a potential memory leak? Maybe there are not many ThreadGroups in an application ever. But it might be wise to use a WeakHashMap here so that the entry disappears when the ThreadGroup is garbage collected. This is fixed using the attached patch. 2005-11-21 Roman Kennke [EMAIL PROTECTED] * javax/swing/RepaintManager.java (currentRepaintManagers): Use a WeakHashMap to avoid potential memory leak. (currentManager): Instantiate WeakHashMap instead of HashMap. (setCurrentManager): Instantiate WeakHashMap instead of HashMap. /Roman signature.asc Description: Dies ist ein digital signierter Nachrichtenteil ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
Re: [cp-patches] FYI: RepaintManager fix
I forgot the patch. Here it comes now. /Roman Am Montag, den 21.11.2005, 15:02 +0100 schrieb Roman Kennke: Am Samstag, den 19.11.2005, 19:09 +0100 schrieb Mark Wielaard: Hi Roman, On Mon, 2005-11-14 at 12:52 +, Roman Kennke wrote: + /** + * The current repaint managers, indexed by their ThreadGroups. + */ + static HashMap currentRepaintManagers; Isn't this a potential memory leak? Maybe there are not many ThreadGroups in an application ever. But it might be wise to use a WeakHashMap here so that the entry disappears when the ThreadGroup is garbage collected. This is fixed using the attached patch. 2005-11-21 Roman Kennke [EMAIL PROTECTED] * javax/swing/RepaintManager.java (currentRepaintManagers): Use a WeakHashMap to avoid potential memory leak. (currentManager): Instantiate WeakHashMap instead of HashMap. (setCurrentManager): Instantiate WeakHashMap instead of HashMap. /Roman ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches Index: javax/swing/RepaintManager.java === RCS file: /cvsroot/classpath/classpath/javax/swing/RepaintManager.java,v retrieving revision 1.18 retrieving revision 1.19 diff -u -r1.18 -r1.19 --- javax/swing/RepaintManager.java 14 Nov 2005 12:50:01 - 1.18 +++ javax/swing/RepaintManager.java 21 Nov 2005 14:01:43 - 1.19 @@ -48,6 +48,7 @@ import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; +import java.util.WeakHashMap; /** * pThe repaint manager holds a set of dirty regions, invalid components, @@ -68,7 +69,7 @@ /** * The current repaint managers, indexed by their ThreadGroups. */ - static HashMap currentRepaintManagers; + static WeakHashMap currentRepaintManagers; /** * pA helper class which is placed into the system event queue at @@ -286,7 +287,7 @@ public static RepaintManager currentManager(Component component) { if (currentRepaintManagers == null) - currentRepaintManagers = new HashMap(); + currentRepaintManagers = new WeakHashMap(); ThreadGroup threadGroup = Thread.currentThread().getThreadGroup(); RepaintManager currentManager = (RepaintManager) currentRepaintManagers.get(threadGroup); @@ -330,7 +331,7 @@ public static void setCurrentManager(RepaintManager manager) { if (currentRepaintManagers == null) - currentRepaintManagers = new HashMap(); + currentRepaintManagers = new WeakHashMap(); ThreadGroup threadGroup = Thread.currentThread().getThreadGroup(); currentRepaintManagers.put(threadGroup, manager); signature.asc Description: Dies ist ein digital signierter Nachrichtenteil ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
Re: [cp-patches] FYI: RepaintManager fix
Hi Roman, On Mon, 2005-11-14 at 12:52 +, Roman Kennke wrote: + /** + * The current repaint managers, indexed by their ThreadGroups. + */ + static HashMap currentRepaintManagers; Isn't this a potential memory leak? Maybe there are not many ThreadGroups in an application ever. But it might be wise to use a WeakHashMap here so that the entry disappears when the ThreadGroup is garbage collected. Cheers, Mark signature.asc Description: This is a digitally signed message part ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
Re: [cp-patches] FYI: RepaintManager fix
Am Samstag, den 19.11.2005, 19:09 +0100 schrieb Mark Wielaard: Hi Roman, On Mon, 2005-11-14 at 12:52 +, Roman Kennke wrote: + /** + * The current repaint managers, indexed by their ThreadGroups. + */ + static HashMap currentRepaintManagers; Isn't this a potential memory leak? Maybe there are not many ThreadGroups in an application ever. But it might be wise to use a WeakHashMap here so that the entry disappears when the ThreadGroup is garbage collected. Yeah that is also correct. I'll fix this. /Roman signature.asc Description: Dies ist ein digital signierter Nachrichtenteil ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] FYI: RepaintManager fix
The RepaintManagers static access methods currentManager() and setCurrentManager() should manage the RepaintManager instances by the calling thread's ThreadGroup instead of using one global instance for everything. I implemented this in the following patch. 2005-11-14 Roman Kennke [EMAIL PROTECTED] * javax/swing/RepaintManager.java (globalManager): Removed obsolete field. (currentRepaintManagers): New field. (RepaintWorker.run): Fetch current RepaintManager for the current thread group. (currentManager): Return the current manager for the current thread group. (setCurrentManager): Set the repaint manager for the current thread group. /Roman Index: javax/swing/RepaintManager.java === RCS file: /cvsroot/classpath/classpath/javax/swing/RepaintManager.java,v retrieving revision 1.17 diff -u -r1.17 RepaintManager.java --- javax/swing/RepaintManager.java 27 Oct 2005 08:16:25 - 1.17 +++ javax/swing/RepaintManager.java 14 Nov 2005 12:49:37 - @@ -65,7 +65,11 @@ */ public class RepaintManager { - + /** + * The current repaint managers, indexed by their ThreadGroups. + */ + static HashMap currentRepaintManagers; + /** * pA helper class which is placed into the system event queue at * various times in order to facilitate repainting and layout. There is @@ -102,7 +106,9 @@ public void run() { - RepaintManager rm = RepaintManager.globalManager; + ThreadGroup threadGroup = Thread.currentThread().getThreadGroup(); + RepaintManager rm = +(RepaintManager) currentRepaintManagers.get(threadGroup); setLive(false); rm.validateInvalidComponents(); rm.paintDirtyRegions(); @@ -249,16 +255,6 @@ /** - * The global, shared RepaintManager instance. This is reused for all - * components in all windows. This is package-private to avoid an accessor - * method. - * - * @see #currentManager(JComponent) - * @see #setCurrentManager - */ - static RepaintManager globalManager; - - /** * Create a new RepaintManager object. */ public RepaintManager() @@ -275,31 +271,46 @@ } /** - * Get the value of the shared [EMAIL PROTECTED] #globalManager} instance, possibly - * returning a special manager associated with the specified - * component. The default implementaiton ignores the component parameter. + * Returns the codeRepaintManager/code for the current thread's + * thread group. The default implementation ignores the + * codecomponent/code parameter and returns the same repaint manager + * for all components. * - * @param component A component to look up the manager of + * @param component a component to look up the manager of * - * @return The current repaint manager + * @return the current repaint manager for the calling thread's thread group + * and the specified component * * @see #setCurrentManager */ public static RepaintManager currentManager(Component component) { -if (globalManager == null) - globalManager = new RepaintManager(); -return globalManager; +if (currentRepaintManagers == null) + currentRepaintManagers = new HashMap(); +ThreadGroup threadGroup = Thread.currentThread().getThreadGroup(); +RepaintManager currentManager = + (RepaintManager) currentRepaintManagers.get(threadGroup); +if (currentManager == null) + { +currentManager = new RepaintManager(); +currentRepaintManagers.put(threadGroup, currentManager); + } +return currentManager; } /** - * Get the value of the shared [EMAIL PROTECTED] #globalManager} instance, possibly - * returning a special manager associated with the specified - * component. The default implementaiton ignores the component parameter. + * Returns the codeRepaintManager/code for the current thread's + * thread group. The default implementation ignores the + * codecomponent/code parameter and returns the same repaint manager + * for all components. * - * @param component A component to look up the manager of + * This method is only here for backwards compatibility with older versions + * of Swing and simply forwards to [EMAIL PROTECTED] #currentManager(Component)}. * - * @return The current repaint manager + * @param component a component to look up the manager of + * + * @return the current repaint manager for the calling thread's thread group + * and the specified component * * @see #setCurrentManager */ @@ -309,15 +320,20 @@ } /** - * Set the value of the shared [EMAIL PROTECTED] #globalManager} instance. + * Sets the repaint manager for the calling thread's thread group. * - * @param manager The new value of the shared instance + * @param manager the repaint manager to set for the current thread's thread + *group *