aboutsummaryrefslogtreecommitdiff
path: root/libjava/gnu/gcj
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/gnu/gcj')
-rw-r--r--libjava/gnu/gcj/xlib/Clip.java7
-rw-r--r--libjava/gnu/gcj/xlib/Drawable.java36
-rw-r--r--libjava/gnu/gcj/xlib/GC.java34
-rw-r--r--libjava/gnu/gcj/xlib/Pixmap.java2
-rw-r--r--libjava/gnu/gcj/xlib/natClip.cc8
-rw-r--r--libjava/gnu/gcj/xlib/natGC.cc18
6 files changed, 87 insertions, 18 deletions
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<gcCachedCount; i++)
+ gcCache[i].disposeImpl ();
+ gcCachedCount = 0;
+ super.finalize();
+ }
+
+ /** Put a GC in the cache for this drawable, so it can be retrieved later.
+ * @param gc The GC to put
+ */
+ void putGCInCache (GC gc)
+ {
+ if (gcCachedCount >= 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<gnu::gcj::RawData*>(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<gnu::gcj::RawData*>(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<gnu::gcj::RawData*>(gc);
}
void gnu::gcj::xlib::GC::disposeImpl()