From 9e9e204234b883d783914aa909e96c57d45ac081 Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Sat, 19 Apr 2003 19:54:39 +0000 Subject: [PATCH] XGraphics.java (XGraphics): Use new GC.create. 2003-04-19 Scott Gilbertson * gnu/awt/xlib/XGraphics.java (XGraphics): Use new GC.create. (dispose): Null metrics. * gnu/awt/xlib/XToolkit.java (sync): Implement. * gnu/gcj/xlib/Clip.java (dispose): Change name of native from finalize. (finalize): Call dispose. * gnu/gcj/xlib/Drawable.java (gcCache): New field. (gcCachedCount): New field. (finalize): New method. (putGCInCache): New method. (getGCFromCache): New method. * gnu/gcj/xlib/GC.java (GC): Make protected. (clone): Get new GC from cache if possible. (create): New static method. (dispose): Save old GC in cache. * gnu/gcj/xlib/natClip.cc (dispose): Check for null before deleting. * gnu/gcj/xlib/natGC.cc (initStructure): Call XCreateGC only if gc is null. * gnu/gcj/xlib/Pixmap.java (Pixmap): Use new GC.create. * java/awt/Container.java (visitChild): Dispose gfx2 when finished. From-SVN: r65827 --- libjava/ChangeLog | 25 +++++++++++++++++++++++++ libjava/gnu/awt/xlib/XGraphics.java | 9 +++++---- libjava/gnu/awt/xlib/XToolkit.java | 5 ++++- libjava/gnu/gcj/xlib/Clip.java | 7 ++++++- libjava/gnu/gcj/xlib/Drawable.java | 36 +++++++++++++++++++++++++++++++++++- libjava/gnu/gcj/xlib/GC.java | 34 +++++++++++++++++++++++++++++----- libjava/gnu/gcj/xlib/Pixmap.java | 2 +- libjava/gnu/gcj/xlib/natClip.cc | 8 ++++++-- libjava/gnu/gcj/xlib/natGC.cc | 18 ++++++++++-------- libjava/java/awt/Container.java | 15 +++++++++++---- 10 files changed, 132 insertions(+), 27 deletions(-) diff --git a/libjava/ChangeLog b/libjava/ChangeLog index ee610a8..f585134 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,28 @@ +2003-04-19 Scott Gilbertson + + * gnu/awt/xlib/XGraphics.java (XGraphics): Use new GC.create. + (dispose): Null metrics. + * gnu/awt/xlib/XToolkit.java (sync): Implement. + * gnu/gcj/xlib/Clip.java (dispose): Change name of native from + finalize. + (finalize): Call dispose. + * gnu/gcj/xlib/Drawable.java (gcCache): New field. + (gcCachedCount): New field. + (finalize): New method. + (putGCInCache): New method. + (getGCFromCache): New method. + * gnu/gcj/xlib/GC.java (GC): Make protected. + (clone): Get new GC from cache if possible. + (create): New static method. + (dispose): Save old GC in cache. + * gnu/gcj/xlib/natClip.cc (dispose): Check for null before + deleting. + * gnu/gcj/xlib/natGC.cc (initStructure): Call XCreateGC only if gc + is null. + * gnu/gcj/xlib/Pixmap.java (Pixmap): Use new GC.create. + * java/awt/Container.java (visitChild): Dispose gfx2 when + finished. + 2003-04-19 Jerry Quinn * java/math/BigInteger.java (probablePrime): New. diff --git a/libjava/gnu/awt/xlib/XGraphics.java b/libjava/gnu/awt/xlib/XGraphics.java index 90f5388..47ab2b8 100644 --- a/libjava/gnu/awt/xlib/XGraphics.java +++ b/libjava/gnu/awt/xlib/XGraphics.java @@ -58,16 +58,17 @@ public class XGraphics implements Cloneable, DirectRasterGraphics context = null; config = null; clipBounds = null; + metrics = null; if (lContext != null) - { - lContext.dispose(); - } + { + lContext.dispose(); + } } public XGraphics(Drawable drawable, XGraphicsConfiguration config) { - context = new GC(drawable); + context = GC.create(drawable); this.config = config; } diff --git a/libjava/gnu/awt/xlib/XToolkit.java b/libjava/gnu/awt/xlib/XToolkit.java index df3a2b6..3da993f 100644 --- a/libjava/gnu/awt/xlib/XToolkit.java +++ b/libjava/gnu/awt/xlib/XToolkit.java @@ -188,7 +188,10 @@ public class XToolkit extends Toolkit public void sync() { - throw new UnsupportedOperationException("not implemented yet"); + flushIfIdle (); + // FIXME: should instead wait for eventLoop to go idle + // (perhaps send a dummy event there and block till it makes + // it through the queue) } public Image getImage(String filename) diff --git a/libjava/gnu/gcj/xlib/Clip.java b/libjava/gnu/gcj/xlib/Clip.java index 28bb02a..311dfa6 100644 --- a/libjava/gnu/gcj/xlib/Clip.java +++ b/libjava/gnu/gcj/xlib/Clip.java @@ -29,7 +29,12 @@ final class Clip private native void init(Rectangle[] rects); - public native void finalize(); + public void finalize() + { + dispose (); + } + + public native void dispose(); RawData xrects; } diff --git a/libjava/gnu/gcj/xlib/Drawable.java b/libjava/gnu/gcj/xlib/Drawable.java index 5652792..551aca8 100644 --- a/libjava/gnu/gcj/xlib/Drawable.java +++ b/libjava/gnu/gcj/xlib/Drawable.java @@ -16,6 +16,9 @@ import java.awt.Rectangle; */ public class Drawable extends XID { + private GC[] gcCache = new GC[10]; + private int gcCachedCount = 0; + public Drawable(Display display, int xid) { super(display, xid); @@ -78,5 +81,36 @@ public class Drawable extends XID private static final String MSG_XGETSUBIMAGE_FAILED = "XGetSubImage() failed."; - + + protected void finalize() throws Throwable + { + // Dispose all the cached GCs, to reduce X server resource usage + for (int i=0; i= gcCache.length) + { + // List full - extend it to double its present size + GC[] oldList = gcCache; + gcCache = new GC[oldList.length*2]; + System.arraycopy (oldList,0,gcCache,0,oldList.length); + } + gcCache[gcCachedCount++] = gc; + } + + /** Get a GC from the cache, if available + * @return A GC from the cache, or null if the cache is empty + */ + GC getGCFromCache () + { + return (gcCachedCount>0) ? gcCache[--gcCachedCount] : null; + } } diff --git a/libjava/gnu/gcj/xlib/GC.java b/libjava/gnu/gcj/xlib/GC.java index 1806c2a..2c4d8a8 100644 --- a/libjava/gnu/gcj/xlib/GC.java +++ b/libjava/gnu/gcj/xlib/GC.java @@ -23,17 +23,25 @@ import java.awt.Rectangle; */ public class GC implements Cloneable { - - public GC(Drawable target) + /** Protected constructor, because GC.create(target) should be used instead. + */ + protected GC(Drawable target) { this.target = target; initStructure(null); } + /** Try to get a suitable GC from the drawable's cache. + * If there isn't one, create one. + */ public Object clone() { - GC gcClone = (GC) super.clone(); - gcClone.structure = null; + GC gcClone = target.getGCFromCache (); + if (gcClone==null) + { + gcClone = (GC) super.clone(); + gcClone.structure = null; + } gcClone.initStructure(this); gcClone.updateClip(); return gcClone; @@ -45,15 +53,31 @@ public class GC implements Cloneable { return (GC) clone(); } + + /** Create a GC, or if one is already cached for target, return that. + * @param target The Drawable for which a GC is needed + * @return The new or retrieved GC + */ + static public GC create (Drawable target) + { + GC returnValue = target.getGCFromCache (); + if (returnValue == null) + returnValue = new GC (target); + return returnValue; + } public void finalize() { disposeImpl(); } + /** Save this GC in the drawable's cache. + * The "real" dispose (disposeImpl) is called when the + * drawable is finialized, to free X server resources. + */ public void dispose() { - disposeImpl(); + target.putGCInCache (this); } public synchronized native void disposeImpl(); diff --git a/libjava/gnu/gcj/xlib/Pixmap.java b/libjava/gnu/gcj/xlib/Pixmap.java index a514d95..7ba5a62 100644 --- a/libjava/gnu/gcj/xlib/Pixmap.java +++ b/libjava/gnu/gcj/xlib/Pixmap.java @@ -25,7 +25,7 @@ public class Pixmap extends Drawable /* FIXME: don't create a new GC all the time. This might actually not be as bad as initially believed. The GC cache of Xlib makes this operation less costly. */ - GC gc = new GC(this); + GC gc = GC.create (this); gc.putImage(image, 0, 0, 0, 0, image.getWidth(), image.getHeight()); } diff --git a/libjava/gnu/gcj/xlib/natClip.cc b/libjava/gnu/gcj/xlib/natClip.cc index 51426c8..a1f626d 100644 --- a/libjava/gnu/gcj/xlib/natClip.cc +++ b/libjava/gnu/gcj/xlib/natClip.cc @@ -46,7 +46,11 @@ void gnu::gcj::xlib::Clip::init(AWTRectArray* rectangles) xrects = reinterpret_cast(xrectvector); } -void gnu::gcj::xlib::Clip::finalize() +void gnu::gcj::xlib::Clip::dispose() { - delete xrects; xrects = 0; + if (xrects) + { + delete xrects; + xrects = 0; + } } diff --git a/libjava/gnu/gcj/xlib/natGC.cc b/libjava/gnu/gcj/xlib/natGC.cc index 11f4b28..16b0bc5 100644 --- a/libjava/gnu/gcj/xlib/natGC.cc +++ b/libjava/gnu/gcj/xlib/natGC.cc @@ -34,12 +34,16 @@ void gnu::gcj::xlib::GC::initStructure(GC* copyFrom) { Display* display = target->getDisplay(); ::Display* dpy = (::Display*) (display->display); - ::Drawable drawableXID = target->getXID(); - - ::GC gc = XCreateGC(dpy, drawableXID, 0, 0); - - if (gc == 0) - throw new XException(JvNewStringLatin1("GC creation failed")); + ::GC gc = (::GC) structure; + if (gc == 0) + { + // If we haven't already created a GC, create one now + ::Drawable drawableXID = target->getXID(); + gc = XCreateGC(dpy, drawableXID, 0, 0); + structure = reinterpret_cast(gc); + if (gc == 0) + throw new XException(JvNewStringLatin1("GC creation failed")); + } if (copyFrom != 0) { @@ -47,8 +51,6 @@ void gnu::gcj::xlib::GC::initStructure(GC* copyFrom) XCopyGC(dpy, fromGC, ~0, gc); // no fast fail } - - structure = reinterpret_cast(gc); } void gnu::gcj::xlib::GC::disposeImpl() diff --git a/libjava/java/awt/Container.java b/libjava/java/awt/Container.java index caffc50..9ef6add 100644 --- a/libjava/java/awt/Container.java +++ b/libjava/java/awt/Container.java @@ -1,5 +1,5 @@ /* Container.java -- parent container class in AWT - Copyright (C) 1999, 2000, 2002 Free Software Foundation + Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation This file is part of GNU Classpath. @@ -1205,10 +1205,17 @@ public class Container extends Component if (clip.isEmpty()) return; Graphics gfx2 = gfx.create(); - gfx2.setClip(clip.x, clip.y, clip.width, clip.height); - gfx2.translate(bounds.x, bounds.y); + try + { + gfx2.setClip(clip.x, clip.y, clip.width, clip.height); + gfx2.translate(bounds.x, bounds.y); - visitor.visit(comp, gfx2); + visitor.visit(comp, gfx2); + } + finally + { + gfx2.dispose (); + } } void dispatchEventImpl(AWTEvent e) -- 2.7.4