--- a/jdk/src/share/classes/javax/print/attribute/standard/PrinterStateReasons.java Thu Nov 12 15:35:52 2009 -0800
+++ b/jdk/src/share/classes/javax/print/attribute/standard/PrinterStateReasons.java Wed Nov 18 17:16:27 2009 -0800
@@ -65,7 +65,7 @@
* PrinterStateReason PrinterStateReason} objects to an existing
* PrinterStateReasons object and remove them again. However, like class
* {@link java.util.HashMap java.util.HashMap}, class PrinterStateReasons is
- * bot multiple thread safe. If a PrinterStateReasons object will be used by
+ * not multiple thread safe. If a PrinterStateReasons object will be used by
* multiple threads, be sure to synchronize its operations (e.g., using a
* synchronized map view obtained from class {@link java.util.Collections
* java.util.Collections}).
--- a/jdk/src/share/classes/sun/font/Font2D.java Thu Nov 12 15:35:52 2009 -0800
+++ b/jdk/src/share/classes/sun/font/Font2D.java Wed Nov 18 17:16:27 2009 -0800
@@ -320,21 +320,6 @@
lastFontStrike = new SoftReference(strike);
StrikeCache.refStrike(strike);
return strike;
- } else {
- /* We have found a cleared reference that has not yet
- * been removed by the disposer.
- * If we make this reference unreachable by removing it
- * from the map,or overwriting it with a new reference to
- * a new strike, then it is possible it may never be
- * enqueued for disposal. That is the implication of
- * the docs for java.lang.ref. So on finding a cleared
- * reference, we need to dispose the native resources,
- * if they haven't already been freed.
- * The reference object needs to have a reference to
- * the disposer instance for this to occur.
- */
- ((StrikeCache.DisposableStrike)strikeRef)
- .getDisposer().dispose();
}
}
/* When we create a new FontStrike instance, we *must*
--- a/jdk/src/share/classes/sun/font/FontDesignMetrics.java Thu Nov 12 15:35:52 2009 -0800
+++ b/jdk/src/share/classes/sun/font/FontDesignMetrics.java Wed Nov 18 17:16:27 2009 -0800
@@ -171,7 +171,7 @@
* out we can clear the keys from the table.
*/
private static class KeyReference extends SoftReference
- implements DisposerRecord {
+ implements DisposerRecord, Disposer.PollDisposable {
static ReferenceQueue queue = Disposer.getQueue();
--- a/jdk/src/share/classes/sun/font/FontStrikeDisposer.java Thu Nov 12 15:35:52 2009 -0800
+++ b/jdk/src/share/classes/sun/font/FontStrikeDisposer.java Wed Nov 18 17:16:27 2009 -0800
@@ -25,6 +25,7 @@
package sun.font;
+import sun.java2d.Disposer;
import sun.java2d.DisposerRecord;
/*
@@ -49,7 +50,8 @@
* entries would be removed much more promptly than we need.
*/
-class FontStrikeDisposer implements DisposerRecord {
+class FontStrikeDisposer
+ implements DisposerRecord, Disposer.PollDisposable {
Font2D font2D;
FontStrikeDesc desc;
--- a/jdk/src/share/classes/sun/font/StrikeCache.java Thu Nov 12 15:35:52 2009 -0800
+++ b/jdk/src/share/classes/sun/font/StrikeCache.java Wed Nov 18 17:16:27 2009 -0800
@@ -254,9 +254,20 @@
// because they may be accessed on that thread at the time of the
// disposal (for example, when the accel. cache is invalidated)
- // REMIND: this look a bit heavyweight, but should be ok
- // because strike disposal is a relatively infrequent operation,
- // more worrisome is the necessity of getting a GC here.
+ // Whilst this is a bit heavyweight, in most applications
+ // strike disposal is a relatively infrequent operation, so it
+ // doesn't matter. But in some tests that use vast numbers
+ // of strikes, the switching back and forth is measurable.
+ // So the "pollRemove" call is added to batch up the work.
+ // If we are polling we know we've already been called back
+ // and can directly dispose the record.
+ // Also worrisome is the necessity of getting a GC here.
+
+ if (Disposer.pollingQueue) {
+ doDispose(disposer);
+ return;
+ }
+
RenderQueue rq = null;
GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
@@ -277,6 +288,7 @@
rq.flushAndInvokeNow(new Runnable() {
public void run() {
doDispose(disposer);
+ Disposer.pollRemove();
}
});
} finally {
--- a/jdk/src/share/classes/sun/java2d/Disposer.java Thu Nov 12 15:35:52 2009 -0800
+++ b/jdk/src/share/classes/sun/java2d/Disposer.java Wed Nov 18 17:16:27 2009 -0800
@@ -29,6 +29,7 @@
import java.lang.ref.ReferenceQueue;
import java.lang.ref.PhantomReference;
import java.lang.ref.WeakReference;
+import java.util.ArrayList;
import java.util.Hashtable;
/**
@@ -146,6 +147,7 @@
rec.dispose();
obj = null;
rec = null;
+ clearDeferredRecords();
} catch (Exception e) {
System.out.println("Exception while removing reference: " + e);
e.printStackTrace();
@@ -153,6 +155,85 @@
}
}
+ /*
+ * This is a marker interface that, if implemented, means it
+ * doesn't acquire any special locks, and is safe to
+ * be disposed in the poll loop on whatever thread
+ * which happens to be the Toolkit thread, is in use.
+ */
+ public static interface PollDisposable {
+ };
+
+ private static ArrayList<DisposerRecord> deferredRecords = null;
+
+ private static void clearDeferredRecords() {
+ if (deferredRecords == null || deferredRecords.isEmpty()) {
+ return;
+ }
+ for (int i=0;i<deferredRecords.size(); i++) {
+ try {
+ DisposerRecord rec = deferredRecords.get(i);
+ rec.dispose();
+ } catch (Exception e) {
+ System.out.println("Exception while disposing deferred rec.");
+ e.printStackTrace();
+ }
+ }
+ deferredRecords.clear();
+ }
+
+ /*
+ * Set to indicate the queue is presently being polled.
+ */
+ public static volatile boolean pollingQueue = false;
+
+ /*
+ * The pollRemove() method is called back from a dispose method
+ * that is running on the toolkit thread and wants to
+ * dispose any pending refs that are safe to be disposed
+ * on that thread.
+ */
+ public static void pollRemove() {
+
+ /* This should never be called recursively, so this check
+ * is just a safeguard against the unexpected.
+ */
+ if (pollingQueue) {
+ return;
+ }
+ Object obj;
+ pollingQueue = true;
+ int freed = 0;
+ int deferred = 0;
+ try {
+ while ((obj = queue.poll()) != null
+ && freed < 10000 && deferred < 100) {
+ freed++;
+ ((Reference)obj).clear();
+ DisposerRecord rec = (DisposerRecord)records.remove(obj);
+ if (rec instanceof PollDisposable) {
+ rec.dispose();
+ obj = null;
+ rec = null;
+ } else {
+ if (rec == null) { // shouldn't happen, but just in case.
+ continue;
+ }
+ deferred++;
+ if (deferredRecords == null) {
+ deferredRecords = new ArrayList<DisposerRecord>(5);
+ }
+ deferredRecords.add(rec);
+ }
+ }
+ } catch (Exception e) {
+ System.out.println("Exception while removing reference: " + e);
+ e.printStackTrace();
+ } finally {
+ pollingQueue = false;
+ }
+ }
+
private static native void initIDs();
/*
--- a/jdk/src/share/classes/sun/java2d/SunGraphics2D.java Thu Nov 12 15:35:52 2009 -0800
+++ b/jdk/src/share/classes/sun/java2d/SunGraphics2D.java Wed Nov 18 17:16:27 2009 -0800
@@ -257,7 +257,6 @@
font = defaultFont;
}
- loops = sd.getRenderLoops(this);
setDevClip(sd.getBounds());
invalidatePipe();
}
@@ -367,6 +366,7 @@
shapepipe = invalidpipe;
textpipe = invalidpipe;
imagepipe = invalidpipe;
+ loops = null;
}
public void validatePipe() {
--- a/jdk/src/share/classes/sun/java2d/SurfaceData.java Thu Nov 12 15:35:52 2009 -0800
+++ b/jdk/src/share/classes/sun/java2d/SurfaceData.java Wed Nov 18 17:16:27 2009 -0800
@@ -69,6 +69,7 @@
import sun.java2d.pipe.DrawImage;
import sun.awt.SunHints;
import sun.awt.image.SurfaceManager;
+import sun.java2d.pipe.LoopBasedPipe;
/**
* This class provides various pieces of information relevant to a
@@ -506,7 +507,6 @@
sg2d.textpipe = solidTextRenderer;
}
sg2d.shapepipe = colorPrimitives;
- sg2d.loops = getRenderLoops(sg2d);
// assert(sg2d.surfaceData == this);
}
} else if (sg2d.compositeState == sg2d.COMP_CUSTOM) {
@@ -603,8 +603,17 @@
sg2d.textpipe = getTextPipe(sg2d, false /* AA==OFF */);
sg2d.shapepipe = colorPrimitives;
+ // assert(sg2d.surfaceData == this);
+ }
+
+ // check for loops
+ if (sg2d.textpipe instanceof LoopBasedPipe ||
+ sg2d.shapepipe instanceof LoopBasedPipe ||
+ sg2d.fillpipe instanceof LoopBasedPipe ||
+ sg2d.drawpipe instanceof LoopBasedPipe ||
+ sg2d.imagepipe instanceof LoopBasedPipe)
+ {
sg2d.loops = getRenderLoops(sg2d);
- // assert(sg2d.surfaceData == this);
}
}
--- a/jdk/src/share/classes/sun/java2d/pipe/AATextRenderer.java Thu Nov 12 15:35:52 2009 -0800
+++ b/jdk/src/share/classes/sun/java2d/pipe/AATextRenderer.java Wed Nov 18 17:16:27 2009 -0800
@@ -34,8 +34,9 @@
* a solid source colour to an opaque destination.
*/
-public class AATextRenderer extends GlyphListLoopPipe {
-
+public class AATextRenderer extends GlyphListLoopPipe
+ implements LoopBasedPipe
+{
protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl) {
sg2d.loops.drawGlyphListAALoop.DrawGlyphListAA(sg2d, sg2d.surfaceData,
gl);
--- a/jdk/src/share/classes/sun/java2d/pipe/GlyphListLoopPipe.java Thu Nov 12 15:35:52 2009 -0800
+++ b/jdk/src/share/classes/sun/java2d/pipe/GlyphListLoopPipe.java Wed Nov 18 17:16:27 2009 -0800
@@ -36,8 +36,9 @@
* the installed loop may not match the glyphvector.
*/
-public abstract class GlyphListLoopPipe extends GlyphListPipe {
-
+public abstract class GlyphListLoopPipe extends GlyphListPipe
+ implements LoopBasedPipe
+{
protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl,
int aaHint) {
switch (aaHint) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/java2d/pipe/LoopBasedPipe.java Wed Nov 18 17:16:27 2009 -0800
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.java2d.pipe;
+
+/**
+ * This is a marker interface used by Pipes that need RenderLoops.
+ * RenderLoops are validated in SurfaceData when a pipe is recognised to
+ * implement this interface.
+ *
+ * @author Mario Torre <neugens@aicas.com>
+ */
+public interface LoopBasedPipe {
+
+}
--- a/jdk/src/share/classes/sun/java2d/pipe/LoopPipe.java Thu Nov 12 15:35:52 2009 -0800
+++ b/jdk/src/share/classes/sun/java2d/pipe/LoopPipe.java Wed Nov 18 17:16:27 2009 -0800
@@ -46,7 +46,8 @@
public class LoopPipe
implements PixelDrawPipe,
PixelFillPipe,
- ShapeDrawPipe
+ ShapeDrawPipe,
+ LoopBasedPipe
{
final static RenderingEngine RenderEngine = RenderingEngine.getInstance();
--- a/jdk/src/share/classes/sun/java2d/pipe/SolidTextRenderer.java Thu Nov 12 15:35:52 2009 -0800
+++ b/jdk/src/share/classes/sun/java2d/pipe/SolidTextRenderer.java Wed Nov 18 17:16:27 2009 -0800
@@ -35,8 +35,9 @@
* a solid source colour to an opaque destination.
*/
-public class SolidTextRenderer extends GlyphListLoopPipe {
-
+public class SolidTextRenderer extends GlyphListLoopPipe
+ implements LoopBasedPipe
+{
protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl) {
sg2d.loops.drawGlyphListLoop.DrawGlyphList(sg2d, sg2d.surfaceData, gl);
}
--- a/jdk/src/share/classes/sun/java2d/pipe/SpanShapeRenderer.java Thu Nov 12 15:35:52 2009 -0800
+++ b/jdk/src/share/classes/sun/java2d/pipe/SpanShapeRenderer.java Wed Nov 18 17:16:27 2009 -0800
@@ -65,7 +65,9 @@
}
}
- public static class Simple extends SpanShapeRenderer {
+ public static class Simple extends SpanShapeRenderer
+ implements LoopBasedPipe
+ {
public Object startSequence(SunGraphics2D sg, Shape s,
Rectangle devR, int[] bbox) {
return sg;
--- a/jdk/src/share/classes/sun/java2d/pisces/Renderer.java Thu Nov 12 15:35:52 2009 -0800
+++ b/jdk/src/share/classes/sun/java2d/pisces/Renderer.java Wed Nov 18 17:16:27 2009 -0800
@@ -775,10 +775,12 @@
// Free sorting arrays if larger than maximum size
private void crossingListFinished() {
- if (crossings.length > DEFAULT_CROSSINGS_SIZE) {
+ if (crossings != null && crossings.length > DEFAULT_CROSSINGS_SIZE) {
crossings = new int[DEFAULT_CROSSINGS_SIZE];
}
- if (crossingIndices.length > DEFAULT_INDICES_SIZE) {
+ if (crossingIndices != null &&
+ crossingIndices.length > DEFAULT_INDICES_SIZE)
+ {
crossingIndices = new int[DEFAULT_INDICES_SIZE];
}
}
--- a/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c Thu Nov 12 15:35:52 2009 -0800
+++ b/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c Wed Nov 18 17:16:27 2009 -0800
@@ -1437,6 +1437,7 @@
JNU_ThrowByName( env,
"java/lang/OutOfMemoryError",
"Initializing Reader");
+ free(cinfo);
return 0;
}
@@ -1473,6 +1474,7 @@
JNU_ThrowByName(env,
"java/lang/OutOfMemoryError",
"Initializing Reader");
+ imageio_dispose((j_common_ptr)cinfo);
return 0;
}
cinfo->src->bytes_in_buffer = 0;
@@ -1489,6 +1491,7 @@
JNU_ThrowByName( env,
"java/lang/OutOfMemoryError",
"Initializing Reader");
+ imageio_dispose((j_common_ptr)cinfo);
return 0;
}
return (jlong) ret;
@@ -2420,8 +2423,7 @@
JNU_ThrowByName( env,
"java/lang/OutOfMemoryError",
"Initializing Writer");
- free(cinfo);
- free(jerr);
+ imageio_dispose((j_common_ptr)cinfo);
return 0;
}
@@ -2439,8 +2441,7 @@
JNU_ThrowByName( env,
"java/lang/OutOfMemoryError",
"Initializing Writer");
- free(cinfo);
- free(jerr);
+ imageio_dispose((j_common_ptr)cinfo);
return 0;
}
return (jlong) ret;
--- a/jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c Thu Nov 12 15:35:52 2009 -0800
+++ b/jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c Wed Nov 18 17:16:27 2009 -0800
@@ -960,21 +960,15 @@
mlib_filter filter;
unsigned int *dP;
- if ((srcRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) {
- JNU_ThrowOutOfMemoryError(env, "Out of memory");
- return -1;
- }
-
- if ((dstRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) {
- JNU_ThrowOutOfMemoryError(env, "Out of memory");
- free(srcRasterP);
- return -1;
- }
-
/* This function requires a lot of local refs ??? Is 64 enough ??? */
if ((*env)->EnsureLocalCapacity(env, 64) < 0)
return 0;
+ if (s_nomlib) return 0;
+ if (s_timeIt) {
+ (*start_timer)(3600);
+ }
+
switch(interpType) {
case java_awt_image_AffineTransformOp_TYPE_BILINEAR:
filter = MLIB_BILINEAR;
@@ -990,9 +984,15 @@
return -1;
}
- if (s_nomlib) return 0;
- if (s_timeIt) {
- (*start_timer)(3600);
+ if ((srcRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) {
+ JNU_ThrowOutOfMemoryError(env, "Out of memory");
+ return -1;
+ }
+
+ if ((dstRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) {
+ JNU_ThrowOutOfMemoryError(env, "Out of memory");
+ free(srcRasterP);
+ return -1;
}
if ((*env)->GetArrayLength(env, jmatrix) < 6) {
@@ -1215,6 +1215,9 @@
}
if (tbl == NULL || table == NULL || jtable == NULL) {
+ if (tbl != NULL) free(tbl);
+ if (table != NULL) free(table);
+ if (jtable != NULL) free(jtable);
awt_freeParsedImage(srcImageP, TRUE);
awt_freeParsedImage(dstImageP, TRUE);
JNU_ThrowNullPointerException(env, "NULL LUT");
@@ -1224,6 +1227,11 @@
for (i=0; i < jlen; i++) {
jtable[i] = (*env)->GetObjectArrayElement(env, jtableArrays, i);
if (jtable[i] == NULL) {
+ free(tbl);
+ free(table);
+ free(jtable);
+ awt_freeParsedImage(srcImageP, TRUE);
+ awt_freeParsedImage(dstImageP, TRUE);
return 0;
}
}
@@ -1232,6 +1240,9 @@
FALSE, &hint);
if (nbands < 1) {
/* Can't handle any custom images */
+ free(tbl);
+ free(table);
+ free(jtable);
awt_freeParsedImage(srcImageP, TRUE);
awt_freeParsedImage(dstImageP, TRUE);
return 0;
@@ -1240,12 +1251,18 @@
/* Allocate the arrays */
if (allocateArray(env, srcImageP, &src, &sdata, TRUE, FALSE, FALSE) < 0) {
/* Must be some problem */
+ free(tbl);
+ free(table);
+ free(jtable);
awt_freeParsedImage(srcImageP, TRUE);
awt_freeParsedImage(dstImageP, TRUE);
return 0;
}
if (allocateArray(env, dstImageP, &dst, &ddata, FALSE, FALSE, FALSE) < 0) {
/* Must be some problem */
+ free(tbl);
+ free(table);
+ free(jtable);
freeArray(env, srcImageP, src, sdata, NULL, NULL, NULL);
awt_freeParsedImage(srcImageP, TRUE);
awt_freeParsedImage(dstImageP, TRUE);
@@ -1284,6 +1301,9 @@
(jbyte *) table[j],
JNI_ABORT);
}
+ free(tbl);
+ free(table);
+ free(jtable);
freeArray(env, srcImageP, src, sdata, NULL, NULL, NULL);
awt_freeParsedImage(srcImageP, TRUE);
awt_freeParsedImage(dstImageP, TRUE);
@@ -1413,12 +1433,15 @@
/* Parse the source raster - reject custom images */
if ((status = awt_parseRaster(env, jsrc, srcRasterP)) <= 0) {
+ free(srcRasterP);
+ free(dstRasterP);
return 0;
}
/* Parse the destination image - reject custom images */
if ((status = awt_parseRaster(env, jdst, dstRasterP)) <= 0) {
awt_freeParsedRaster(srcRasterP, TRUE);
+ free(dstRasterP);
return 0;
}
--- a/jdk/src/share/native/sun/font/freetypeScaler.c Thu Nov 12 15:35:52 2009 -0800
+++ b/jdk/src/share/native/sun/font/freetypeScaler.c Wed Nov 18 17:16:27 2009 -0800
@@ -102,9 +102,21 @@
}
static void freeNativeResources(JNIEnv *env, FTScalerInfo* scalerInfo) {
+ void *stream;
+
if (scalerInfo == NULL)
return;
+ //apparently Done_Face will only close the stream
+ // but will not relase the memory of stream structure.
+ // We need to free it explicitly to avoid leak.
+ //Direct access to the stream field might be not ideal solution as
+ // it is considred to be "private".
+ //Alternatively we could have stored pointer to the structure
+ // in the scalerInfo but this will increase size of the structure
+ // for no good reason
+ stream = scalerInfo->face->stream;
+
FT_Done_Face(scalerInfo->face);
FT_Done_FreeType(scalerInfo->library);
@@ -116,6 +128,10 @@
free(scalerInfo->fontData);
}
+ if (stream != NULL) {
+ free(stream);
+ }
+
free(scalerInfo);
}
--- a/jdk/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java Thu Nov 12 15:35:52 2009 -0800
+++ b/jdk/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java Wed Nov 18 17:16:27 2009 -0800
@@ -388,7 +388,10 @@
// if a GlyphVector overrides the AA setting.
// We use getRenderLoops() rather than setting solidloops
// directly so that we get the appropriate loops in XOR mode.
- sg2d.loops = getRenderLoops(sg2d);
+ if (sg2d.loops == null) {
+ // assert(some pipe will always be a LoopBasedPipe)
+ sg2d.loops = getRenderLoops(sg2d);
+ }
} else {
super.validatePipe(sg2d);
}
--- a/jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.h Thu Nov 12 15:35:52 2009 -0800
+++ b/jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.h Wed Nov 18 17:16:27 2009 -0800
@@ -42,6 +42,10 @@
#include <sys/ipc.h>
#include <sys/shm.h>
#include <X11/extensions/XShm.h>
+#ifndef X_ShmAttach
+#include <X11/Xmd.h>
+#include <X11/extensions/shmproto.h>
+#endif
extern int XShmQueryExtension();
--- a/jdk/src/windows/classes/sun/java2d/windows/GDIWindowSurfaceData.java Thu Nov 12 15:35:52 2009 -0800
+++ b/jdk/src/windows/classes/sun/java2d/windows/GDIWindowSurfaceData.java Wed Nov 18 17:16:27 2009 -0800
@@ -210,7 +210,10 @@
// if a GlyphVector overrides the AA setting.
// We use getRenderLoops() rather than setting solidloops
// directly so that we get the appropriate loops in XOR mode.
- sg2d.loops = getRenderLoops(sg2d);
+ if (sg2d.loops == null) {
+ // assert(some pipe will always be a LoopBasedPipe)
+ sg2d.loops = getRenderLoops(sg2d);
+ }
} else {
super.validatePipe(sg2d);
}
--- a/jdk/src/windows/native/sun/windows/awt_PrintControl.cpp Thu Nov 12 15:35:52 2009 -0800
+++ b/jdk/src/windows/native/sun/windows/awt_PrintControl.cpp Wed Nov 18 17:16:27 2009 -0800
@@ -687,7 +687,7 @@
// Now, set-up the struct for the real calls to ::PrintDlg and ::CreateDC
pd.hwndOwner = hwndOwner;
- pd.Flags = PD_ENABLEPRINTHOOK | PD_RETURNDC;
+ pd.Flags = PD_ENABLEPRINTHOOK | PD_RETURNDC | PD_USEDEVMODECOPIESANDCOLLATE;
pd.lpfnPrintHook = (LPPRINTHOOKPROC)PrintDlgHook;
if (env->CallBooleanMethod(printCtrl, AwtPrintControl::getCollateID)) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/java2d/pisces/Renderer/TestNPE.java Wed Nov 18 17:16:27 2009 -0800
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6887494
+ *
+ * @summary Verifies that no NullPointerException is thrown in Pisces Renderer
+ * under certain circumstances.
+ *
+ * @run main TestNPE
+ */
+
+import java.awt.*;
+import java.awt.geom.*;
+import java.awt.image.BufferedImage;
+
+public class TestNPE {
+
+ private static void paint(Graphics g) {
+ Graphics2D g2d = (Graphics2D) g;
+ g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+ g2d.setClip(0, 0, 0, 0);
+ g2d.setTransform(
+ new AffineTransform(4.0f, 0.0f, 0.0f, 4.0f, -1248.0f, -744.0f));
+ g2d.draw(new Line2D.Float(131.21428571428572f, 33.0f,
+ 131.21428571428572f, 201.0f));
+ }
+
+ public static void main(String[] args) {
+ BufferedImage im = new BufferedImage(100, 100,
+ BufferedImage.TYPE_INT_ARGB);
+
+ // Trigger exception in main thread.
+ Graphics g = im.getGraphics();
+ paint(g);
+ }
+}