XGraphics.java (XGraphics): Use new GC.create.
2003-04-19 Scott Gilbertson <scottg@mantatest.com> * 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
This commit is contained in:
parent
afd4910af1
commit
9e9e204234
10 changed files with 132 additions and 27 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue