Hi, We had another deadlock between ComponentGraphics and CairoGraphics if the image wasn't a BufferedImage already. Then CairoGraphics would try to convert the Image to an BuffereImage which in some cases would need the gdk lock. So this patch makes sure that ComponentGraphics always passes an BufferedImage to its super class. While debugging this I noticed that ComponentGraphics would not directly draw a GtkVolatileImage if the transform set on the Graphics2D instance was the identity transform. That was easily solved and should make some operations a little faster. (Not really that many. I only observed JMenus using backbuffers that were drawn with the identity transform set).
2006-06-13 Mark Wielaard <[EMAIL PROTECTED]>
* gnu/java/awt/peer/gtk/CairoGraphics2D.java (drawImage): Don't
allocate unused AffineTransform. Add comment about conversion to
BufferedImage.
* gnu/java/awt/peer/gtk/ComponentGraphics.java (drawImage):
Recognize identity transform as "easy". Always convert to
BufferedImage before calling super.
Committed,
Mark
Index: gnu/java/awt/peer/gtk/CairoGraphics2D.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/CairoGraphics2D.java,v
retrieving revision 1.21
diff -u -r1.21 CairoGraphics2D.java
--- gnu/java/awt/peer/gtk/CairoGraphics2D.java 12 Jun 2006 21:10:11 -0000 1.21
+++ gnu/java/awt/peer/gtk/CairoGraphics2D.java 13 Jun 2006 12:48:51 -0000
@@ -1144,7 +1144,7 @@
// other way around. Therefore to get the "user -> pixel" transform
// that cairo wants from "image -> user" transform that we currently
// have, we will need to invert the transformation matrix.
- AffineTransform invertedXform = new AffineTransform();
+ AffineTransform invertedXform;
try
{
@@ -1157,6 +1157,9 @@
}
// Unrecognized image - convert to a BufferedImage
+ // Note - this can get us in trouble when the gdk lock is re-acquired.
+ // for example by VolatileImage. See ComponentGraphics for how we work
+ // around this.
if( !(img instanceof BufferedImage) )
{
ImageProducer source = img.getSource();
Index: gnu/java/awt/peer/gtk/ComponentGraphics.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java,v
retrieving revision 1.15
diff -u -r1.15 ComponentGraphics.java
--- gnu/java/awt/peer/gtk/ComponentGraphics.java 12 Jun 2006 21:10:11 -0000 1.15
+++ gnu/java/awt/peer/gtk/ComponentGraphics.java 13 Jun 2006 12:48:51 -0000
@@ -46,6 +46,7 @@
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Shape;
+import java.awt.Toolkit;
import java.awt.Point;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
@@ -53,6 +54,7 @@
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
+import java.awt.image.ImageProducer;
import java.awt.image.ImagingOpException;
import java.awt.image.RenderedImage;
@@ -277,33 +279,84 @@
public boolean drawImage(Image img, int x, int y, ImageObserver observer)
{
- if (img instanceof GtkVolatileImage
- && transform.getType() == AffineTransform.TYPE_TRANSLATION)
+ // If it is a GtkVolatileImage with an "easy" transform then
+ // draw directly. Always pass a BufferedImage to super to avoid
+ // deadlock (see Note in CairoGraphics.drawImage()).
+ if (img instanceof GtkVolatileImage)
{
- x += transform.getTranslateX();
- y += transform.getTranslateY();
GtkVolatileImage vimg = (GtkVolatileImage) img;
- drawVolatile( component, vimg.nativePointer,
- x, y, vimg.width, vimg.height );
- return true;
- }
- return super.drawImage( img, x, y, observer );
+ int type = transform.getType();
+ if (type == AffineTransform.TYPE_IDENTITY)
+ {
+ drawVolatile(component, vimg.nativePointer,
+ x, y, vimg.width, vimg.height);
+ return true;
+ }
+ else if (type == AffineTransform.TYPE_TRANSLATION)
+ {
+ x += transform.getTranslateX();
+ y += transform.getTranslateY();
+ drawVolatile(component, vimg.nativePointer,
+ x, y, vimg.width, vimg.height);
+ return true;
+ }
+ else
+ return super.drawImage(vimg.getSnapshot(), x, y, observer);
+ }
+
+ BufferedImage bimg;
+ if (img instanceof BufferedImage)
+ bimg = (BufferedImage) img;
+ else
+ {
+ ImageProducer source = img.getSource();
+ if (source == null)
+ return false;
+ bimg = (BufferedImage) Toolkit.getDefaultToolkit().createImage(source);
+ }
+ return super.drawImage(bimg, x, y, observer);
}
public boolean drawImage(Image img, int x, int y, int width, int height,
ImageObserver observer)
{
- if( img instanceof GtkVolatileImage
- && transform.getType() == AffineTransform.TYPE_TRANSLATION)
+ // If it is a GtkVolatileImage with an "easy" transform then
+ // draw directly. Always pass a BufferedImage to super to avoid
+ // deadlock (see Note in CairoGraphics.drawImage()).
+ if (img instanceof GtkVolatileImage)
{
- x += transform.getTranslateX();
- y += transform.getTranslateY();
GtkVolatileImage vimg = (GtkVolatileImage) img;
- drawVolatile( component, vimg.nativePointer, x, y,
- width, height );
- return true;
- }
- return super.drawImage( img, x, y, width, height, observer );
+ int type = transform.getType();
+ if (type == AffineTransform.TYPE_IDENTITY)
+ {
+ drawVolatile(component, vimg.nativePointer,
+ x, y, width, height);
+ return true;
+ }
+ else if (type == AffineTransform.TYPE_TRANSLATION)
+ {
+ x += transform.getTranslateX();
+ y += transform.getTranslateY();
+ drawVolatile(component, vimg.nativePointer,
+ x, y, width, height);
+ return true;
+ }
+ else
+ return super.drawImage(vimg.getSnapshot(), x, y,
+ width, height, observer);
+ }
+
+ BufferedImage bimg;
+ if (img instanceof BufferedImage)
+ bimg = (BufferedImage) img;
+ else
+ {
+ ImageProducer source = img.getSource();
+ if (source == null)
+ return false;
+ bimg = (BufferedImage) Toolkit.getDefaultToolkit().createImage(source);
+ }
+ return super.drawImage(bimg, x, y, width, height, observer);
}
}
signature.asc
Description: This is a digitally signed message part
