diff options
| author | Thomas Fitzsimmons <fitzsim@gcc.gnu.org> | 2007-04-27 18:08:03 +0000 |
|---|---|---|
| committer | Thomas Fitzsimmons <fitzsim@gcc.gnu.org> | 2007-04-27 18:08:03 +0000 |
| commit | 415e62e2329a7f347ee0bb0f658daa35fa929a55 (patch) | |
| tree | cd4f0a646e2da364d4212a8678f7a4479d0a0ee8 /libjava/classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java | |
| parent | 328647780254d7781b48f21b8344dcee3c8afb2c (diff) | |
[multiple changes]
2007-03-16 Francis Kung <fkung@redhat.com>
* gnu/java/awt/peer/gtk/CairoGraphics2D.java
(cairoArc): Make protected rather than private so it can be over-ridden.
(cairoClip): Likewise.
(cairoClosePath): Likewise.
(cairoCurveTo): Likewise.
(cairoDrawGlyphVector): Likewise.
(cairoFill): Likewise.
(cairoLineTo): Likewise.
(cairoMoveTo): Likewise.
(cairoNewPath): Likewise.
(cairoRectangle): Likewise.
(cairoResetClip): Likewise.
(cairoRestore): Likewise.
(cairoSave): Likewise.
(cairoScale): Likewise.
(cairoSetAntialias): Likewise.
(cairoSetDash): Likewise.
(cairoSetFillRule): Likewise.
(cairoSetFont): Likewise.
(cairoSetLine): Likewise.
(cairoSetMatrix): Likewise.
(cairoSetOperator): Likewise.
(cairoSetRGBAColor): Likewise.
(cairoStroke): Likewise.
(drawPixels): Likewise.
(init): Likewise.
(setGradient): Likewise.
(setPaintPixels): Likewise.
(cairoDrawLine): Removed.
(cairoDrawRect): Removed.
(cairoFillRect): Removed.
(cairoPreserveClip): Removed.
(cairoRelCurveTo): Removed.
(cairoRelLineTo): Removed.
(cairoRelMoveTo): Removed.
* gnu/java/awt/peer/gtk/ComponentGraphics.java
(cairoArc): New method wrapping superclass method in locks.
(cairoClip): Likewise.
(cairoClosePath): Likewise.
(cairoCurveTo): Likewise.
(cairoDrawGlyphVector): Likewise.
(cairoFill): Likewise.
(cairoLineTo): Likewise.
(cairoMoveTo): Likewise.
(cairoNewPath): Likewise.
(cairoRectangle): Likewise.
(cairoResetClip): Likewise.
(cairoRestore): Likewise.
(cairoSave): Likewise.
(cairoScale): Likewise.
(cairoSetAntialias): Likewise.
(cairoSetDash): Likewise.
(cairoSetFillRule): Likewise.
(cairoSetFont): Likewise.
(cairoSetLine): Likewise.
(cairoSetMatrix): Likewise.
(cairoSetOperator): Likewise.
(cairoSetRGBAColor): Likewise.
(cairoStroke): Likewise.
(disposeNative): Likewise.
(drawPixels): Likewise.
(init): Likewise.
(setGradient): Likewise.
(setPaintPixels): Likewise.
(draw): Do not lock, as locking is now done in the wrapped native methods.
(drawComposite): Likewise.
(drawGlyphVector): Likewise.
(drawImage): Likewise.
(drawRenderedImage): Likewise.
(fill): Likewise.
(setClip): Removed.
(lock): Added documentation.
(unlock): Added documentation.
* include/gnu_java_awt_peer_gtk_CairoGraphics2D.h: Regenerated.
* include/gnu_java_awt_peer_gtk_ComponentGraphics.h: Regenerated.
* lib/gnu/java/awt/peer/gtk/ComponentGraphics.class: Regenerated.
* lib/gnu/java/awt/peer/gtk/CairoGraphics2D.class: Regenerated.
* native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c
(Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoDrawLine): Removed.
(Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoDrawRect): Removed.
(Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoFillRect): Removed.
(Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoPreserveClip): Removed.
(Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoRelCurveTo): Removed.
(Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoRelLineTo): Removed.
(Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoRelMoveTo): Removed.
2007-04-27 Thomas Fitzsimmons <fitzsim@redhat.com>
* gnu/java/awt/peer/gtk/CairoGraphics2D.h: Regenerate.
* gnu/java/awt/peer/gtk/ComponentGraphics.h: Regenerate.
From-SVN: r124226
Diffstat (limited to 'libjava/classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java')
| -rw-r--r-- | libjava/classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java | 629 |
1 files changed, 498 insertions, 131 deletions
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java b/libjava/classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java index 098052ae961..be82f81ecbd 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java @@ -112,6 +112,14 @@ public class ComponentGraphics extends CairoGraphics2D */ private native long initState(GtkComponentPeer component); + /** + * Obtain and hold a GDK lock, which is required for all drawing operations + * in this graphics context (since it is backed by an X surface). + * + * This method causes the GDK locking behaviour to be re-entrant. No race + * conditions are caused since a ThreadLocal is used and each thread has its + * own lock counter. + */ private void lock() { Integer i = (Integer) hasLock.get(); @@ -124,6 +132,9 @@ public class ComponentGraphics extends CairoGraphics2D hasLock.set(Integer.valueOf(i.intValue() + 1)); } + /** + * Release the re-entrant GDK lock. + */ private void unlock() { Integer i = (Integer) hasLock.get(); @@ -219,78 +230,54 @@ public class ComponentGraphics extends CairoGraphics2D */ public void draw(Shape s) { - lock(); - try - { - if (comp == null || comp instanceof AlphaComposite) - super.draw(s); + if (comp == null || comp instanceof AlphaComposite) + super.draw(s); - else - { - createBuffer(); + else + { + createBuffer(); - Graphics2D g2d = (Graphics2D)buffer.getGraphics(); - g2d.setStroke(this.getStroke()); - g2d.setColor(this.getColor()); - g2d.draw(s); + Graphics2D g2d = (Graphics2D)buffer.getGraphics(); + g2d.setStroke(this.getStroke()); + g2d.setColor(this.getColor()); + g2d.draw(s); - drawComposite(s.getBounds2D(), null); - } - } - finally - { - unlock(); + drawComposite(s.getBounds2D(), null); } } public void fill(Shape s) { - lock(); - try - { - if (comp == null || comp instanceof AlphaComposite) - super.fill(s); + if (comp == null || comp instanceof AlphaComposite) + super.fill(s); - else - { - createBuffer(); + else + { + createBuffer(); - Graphics2D g2d = (Graphics2D)buffer.getGraphics(); - g2d.setPaint(this.getPaint()); - g2d.setColor(this.getColor()); - g2d.fill(s); + Graphics2D g2d = (Graphics2D)buffer.getGraphics(); + g2d.setPaint(this.getPaint()); + g2d.setColor(this.getColor()); + g2d.fill(s); - drawComposite(s.getBounds2D(), null); - } - } - finally - { - unlock(); + drawComposite(s.getBounds2D(), null); } } public void drawRenderedImage(RenderedImage image, AffineTransform xform) { - lock(); - try - { - if (comp == null || comp instanceof AlphaComposite) - super.drawRenderedImage(image, xform); + if (comp == null || comp instanceof AlphaComposite) + super.drawRenderedImage(image, xform); - else - { - createBuffer(); + else + { + createBuffer(); - Graphics2D g2d = (Graphics2D)buffer.getGraphics(); - g2d.setRenderingHints(this.getRenderingHints()); - g2d.drawRenderedImage(image, xform); + Graphics2D g2d = (Graphics2D)buffer.getGraphics(); + g2d.setRenderingHints(this.getRenderingHints()); + g2d.drawRenderedImage(image, xform); - drawComposite(buffer.getRaster().getBounds(), null); - } - } - finally - { - unlock(); + drawComposite(buffer.getRaster().getBounds(), null); } } @@ -298,81 +285,65 @@ public class ComponentGraphics extends CairoGraphics2D Color bgcolor, ImageObserver obs) { boolean rv; - lock(); - try - { - if (comp == null || comp instanceof AlphaComposite) - rv = super.drawImage(img, xform, bgcolor, obs); + if (comp == null || comp instanceof AlphaComposite) + rv = super.drawImage(img, xform, bgcolor, obs); - else + else + { + // Get buffered image of source + if( !(img instanceof BufferedImage) ) { - // Get buffered image of source - if( !(img instanceof BufferedImage) ) - { - ImageProducer source = img.getSource(); - if (source == null) - return false; - img = Toolkit.getDefaultToolkit().createImage(source); - } - BufferedImage bImg = (BufferedImage) img; + ImageProducer source = img.getSource(); + if (source == null) + return false; + img = Toolkit.getDefaultToolkit().createImage(source); + } + BufferedImage bImg = (BufferedImage) img; - // Find translated bounds - Point2D origin = new Point2D.Double(bImg.getMinX(), bImg.getMinY()); - Point2D pt = new Point2D.Double(bImg.getWidth() + bImg.getMinX(), - bImg.getHeight() + bImg.getMinY()); - if (xform != null) - { - origin = xform.transform(origin, origin); - pt = xform.transform(pt, pt); - } + // Find translated bounds + Point2D origin = new Point2D.Double(bImg.getMinX(), bImg.getMinY()); + Point2D pt = new Point2D.Double(bImg.getWidth() + bImg.getMinX(), + bImg.getHeight() + bImg.getMinY()); + if (xform != null) + { + origin = xform.transform(origin, origin); + pt = xform.transform(pt, pt); + } - // Create buffer and draw image - createBuffer(); + // Create buffer and draw image + createBuffer(); - Graphics2D g2d = (Graphics2D)buffer.getGraphics(); - g2d.setRenderingHints(this.getRenderingHints()); - g2d.drawImage(img, xform, obs); - - // Perform compositing - rv = drawComposite(new Rectangle2D.Double(origin.getX(), - origin.getY(), - pt.getX(), pt.getY()), - obs); - } - } - finally - { - unlock(); + Graphics2D g2d = (Graphics2D)buffer.getGraphics(); + g2d.setRenderingHints(this.getRenderingHints()); + g2d.drawImage(img, xform, obs); + + // Perform compositing + rv = drawComposite(new Rectangle2D.Double(origin.getX(), + origin.getY(), + pt.getX(), pt.getY()), + obs); } return rv; } public void drawGlyphVector(GlyphVector gv, float x, float y) { - lock(); - try - { - if (comp == null || comp instanceof AlphaComposite) - super.drawGlyphVector(gv, x, y); + if (comp == null || comp instanceof AlphaComposite) + super.drawGlyphVector(gv, x, y); - else - { - createBuffer(); + else + { + createBuffer(); - Graphics2D g2d = (Graphics2D)buffer.getGraphics(); - g2d.setPaint(this.getPaint()); - g2d.setStroke(this.getStroke()); - g2d.drawGlyphVector(gv, x, y); + Graphics2D g2d = (Graphics2D)buffer.getGraphics(); + g2d.setPaint(this.getPaint()); + g2d.setStroke(this.getStroke()); + g2d.drawGlyphVector(gv, x, y); - Rectangle2D bounds = gv.getLogicalBounds(); - bounds = new Rectangle2D.Double(x + bounds.getX(), y + bounds.getY(), - bounds.getWidth(), bounds.getHeight()); - drawComposite(bounds, null); - } - } - finally - { - unlock(); + Rectangle2D bounds = gv.getLogicalBounds(); + bounds = new Rectangle2D.Double(x + bounds.getX(), y + bounds.getY(), + bounds.getWidth(), bounds.getHeight()); + drawComposite(bounds, null); } } @@ -466,20 +437,6 @@ public class ComponentGraphics extends CairoGraphics2D return super.drawImage(bimg, x, y, width, height, observer); } - public void setClip(Shape s) - { - lock(); - try - { - super.setClip(s); - } - finally - { - unlock(); - } - } - - private boolean drawComposite(Rectangle2D bounds, ImageObserver observer) { // Clip source to visible areas that need updating @@ -507,12 +464,10 @@ public class ComponentGraphics extends CairoGraphics2D Rectangle2D.intersect(deviceBounds, this.getClipInDevSpace(), deviceBounds); // Get current image on the component - unlock(); GtkImage img = grab(component); Graphics gr = componentBuffer.createGraphics(); gr.drawImage(img, 0, 0, null); gr.dispose(); - lock(); BufferedImage cBuffer = componentBuffer; if (!deviceBounds.equals(cBuffer.getRaster().getBounds())) @@ -573,5 +528,417 @@ public class ComponentGraphics extends CairoGraphics2D { return GtkVolatileImage.gdkColorModel; } + + /* --- START OVERRIDDEN NATIVE METHODS ---- + * All native methods in CairoGraphics2D should be overridden here and + * enclosed in locks, since the cairo surface is backed by an X surface + * in this graphics context and the X surface requires external locking. + * + * We lock everything "just in case", since it's difficult to know which + * calls are and aren't thread-safe. Overriding and locking the native + * methods allows superclass code in CairoGraphics2D to execute properly, + * without the need to override every single method. + * + * CAVEAT: if native code obtains a lock (using gdk_threads_enter(), not the + * lock() method provided here) and then calls back into Java and one of these + * methods ends up being called, we will deadlock. The lock is only reentrant + * when called via our lock() method. + */ + @Override + protected long init(long pointer) + { + long ret; + + try + { + lock(); + ret = super.init(pointer); + } + finally + { + unlock(); + } + + return ret; + } + + @Override + public void disposeNative(long pointer) + { + try + { + lock(); + super.disposeNative(pointer); + } + finally + { + unlock(); + } + } + + @Override + protected void drawPixels(long pointer, int[] pixels, int w, int h, + int stride, double[] i2u, double alpha, + int interpolation) + { + try + { + lock(); + super.drawPixels(pointer, pixels, w, h, stride, i2u, alpha, + interpolation); + } + finally + { + unlock(); + } + } + + @Override + protected void setGradient(long pointer, double x1, double y1, + double x2, double y2, + int r1, int g1, int b1, int a1, + int r2, int g2, int b2, int a2, boolean cyclic) + { + try + { + lock(); + super.setGradient(pointer, x1, y1, x2, y2, r1, g1, b1, a1, r2, g2, b2, a2, + cyclic); + } + finally + { + unlock(); + } + } + + @Override + protected void setPaintPixels(long pointer, int[] pixels, int w, int h, + int stride, boolean repeat, int x, int y) + { + try + { + lock(); + super.setPaintPixels(pointer, pixels, w, h, stride, repeat, x, y); + } + finally + { + unlock(); + } + } + + @Override + protected void cairoSetMatrix(long pointer, double[] m) + { + try + { + lock(); + super.cairoSetMatrix(pointer, m); + } + finally + { + unlock(); + } + } + + @Override + protected void cairoScale(long pointer, double x, double y) + { + try + { + lock(); + super.cairoScale(pointer, x, y); + } + finally + { + unlock(); + } + } + + @Override + protected void cairoSetOperator(long pointer, int cairoOperator) + { + try + { + lock(); + super.cairoSetOperator(pointer, cairoOperator); + } + finally + { + unlock(); + } + } + + @Override + protected void cairoSetRGBAColor(long pointer, double red, double green, + double blue, double alpha) + { + try + { + lock(); + super.cairoSetRGBAColor(pointer, red, green, blue, alpha); + } + finally + { + unlock(); + } + } + + @Override + protected void cairoSetFillRule(long pointer, int cairoFillRule) + { + try + { + lock(); + super.cairoSetFillRule(pointer, cairoFillRule); + } + finally + { + unlock(); + } + } + + @Override + protected void cairoSetLine(long pointer, double width, int cap, int join, + double miterLimit) + { + try + { + lock(); + super.cairoSetLine(pointer, width, cap, join, miterLimit); + } + finally + { + unlock(); + } + } + + @Override + protected void cairoSetDash(long pointer, double[] dashes, int ndash, + double offset) + { + try + { + lock(); + super.cairoSetDash(pointer, dashes, ndash, offset); + } + finally + { + unlock(); + } + } + + @Override + protected void cairoDrawGlyphVector(long pointer, GdkFontPeer font, + float x, float y, int n, + int[] codes, float[] positions) + { + try + { + lock(); + super.cairoDrawGlyphVector(pointer, font, x, y, n, codes, positions); + } + finally + { + unlock(); + } + } + + @Override + protected void cairoSetFont(long pointer, GdkFontPeer font) + { + try + { + lock(); + super.cairoSetFont(pointer, font); + } + finally + { + unlock(); + } + } + + @Override + protected void cairoRectangle(long pointer, double x, double y, + double width, double height) + { + try + { + lock(); + super.cairoRectangle(pointer, x, y, width, height); + } + finally + { + unlock(); + } + } + + @Override + protected void cairoArc(long pointer, double x, double y, + double radius, double angle1, double angle2) + { + try + { + lock(); + super.cairoArc(pointer, x, y, radius, angle1, angle2); + } + finally + { + unlock(); + } + } + + @Override + protected void cairoSave(long pointer) + { + try + { + lock(); + super.cairoSave(pointer); + } + finally + { + unlock(); + } + } + + @Override + protected void cairoRestore(long pointer) + { + try + { + lock(); + super.cairoRestore(pointer); + } + finally + { + unlock(); + } + } + + @Override + protected void cairoNewPath(long pointer) + { + try + { + lock(); + super.cairoNewPath(pointer); + } + finally + { + unlock(); + } + } + + @Override + protected void cairoClosePath(long pointer) + { + try + { + lock(); + super.cairoClosePath(pointer); + } + finally + { + unlock(); + } + } + + @Override + protected void cairoMoveTo(long pointer, double x, double y) + { + try + { + lock(); + super.cairoMoveTo(pointer, x, y); + } + finally + { + unlock(); + } + } + + @Override + protected void cairoLineTo(long pointer, double x, double y) + { + try + { + lock(); + super.cairoLineTo(pointer, x, y); + } + finally + { + unlock(); + } + } + + @Override + protected void cairoCurveTo(long pointer, double x1, double y1, double x2, + double y2, double x3, double y3) + { + try + { + lock(); + super.cairoCurveTo(pointer, x1, y1, x2, y2, x3, y3); + } + finally + { + unlock(); + } + } + + @Override + protected void cairoStroke(long pointer) + { + try + { + lock(); + super.cairoStroke(pointer); + } + finally + { + unlock(); + } + } + + @Override + protected void cairoFill(long pointer, double alpha) + { + try + { + lock(); + super.cairoFill(pointer, alpha); + } + finally + { + unlock(); + } + } + + @Override + protected void cairoClip(long pointer) + { + try + { + lock(); + super.cairoClip(pointer); + } + finally + { + unlock(); + } + } + + @Override + protected void cairoResetClip(long pointer) + { + try + { + lock(); + super.cairoResetClip(pointer); + } + finally + { + unlock(); + } + } } - |
