Skip to content

Commit e4df209

Browse files
author
Laurent Bourgès
committedJan 12, 2021
7018932: Drawing very large coordinates with a dashed Stroke can cause Java to hang
Reviewed-by: serb, prr
1 parent 5f7ccce commit e4df209

File tree

7 files changed

+344
-38
lines changed

7 files changed

+344
-38
lines changed
 

‎src/java.desktop/share/classes/sun/java2d/marlin/DMarlinRenderingEngine.java

+88-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -170,16 +170,20 @@ public Shape createStrokedShape(Shape src,
170170
* {@code antialias} boolean parameter is true.
171171
* <p>
172172
* The geometry of the widened path is forwarded to the indicated
173-
* {@link DPathConsumer2D} object as it is calculated.
173+
* {@link PathConsumer2D} object as it is calculated.
174174
*
175175
* @param src the source path to be widened
176-
* @param bs the {@code BasicSroke} object specifying the
176+
* @param at the transform to be applied to the shape and the
177+
* stroke attributes
178+
* @param bs the {@code BasicStroke} object specifying the
177179
* decorations to be applied to the widened path
180+
* @param thin true if the transformed stroke attributes are smaller
181+
* than the minimum dropout pen width
178182
* @param normalize indicates whether stroke normalization should
179183
* be applied
180184
* @param antialias indicates whether or not adjustments appropriate
181185
* to antialiased rendering should be applied
182-
* @param consumer the {@code DPathConsumer2D} instance to forward
186+
* @param consumer the {@code PathConsumer2D} instance to forward
183187
* the widened geometry to
184188
* @since 1.7
185189
*/
@@ -192,13 +196,92 @@ public void strokeTo(Shape src,
192196
boolean antialias,
193197
final PathConsumer2D consumer)
194198
{
199+
strokeTo(src, at, null, bs, thin, normalize, antialias, consumer);
200+
}
201+
202+
/**
203+
* Sends the geometry for a widened path as specified by the parameters
204+
* to the specified consumer.
205+
* <p>
206+
* The specified {@code src} {@link Shape} is widened according
207+
* to the parameters specified by the {@link BasicStroke} object.
208+
* Adjustments are made to the path as appropriate for the
209+
* {@link java.awt.RenderingHints#VALUE_STROKE_NORMALIZE} hint if the
210+
* {@code normalize} boolean parameter is true.
211+
* Adjustments are made to the path as appropriate for the
212+
* {@link java.awt.RenderingHints#VALUE_ANTIALIAS_ON} hint if the
213+
* {@code antialias} boolean parameter is true.
214+
* <p>
215+
* The geometry of the widened path is forwarded to the indicated
216+
* {@link PathConsumer2D} object as it is calculated.
217+
*
218+
* @param src the source path to be widened
219+
* @param at the transform to be applied to the shape and the
220+
* stroke attributes
221+
* @param clip the current clip in effect in device coordinates
222+
* @param bs the {@code BasicStroke} object specifying the
223+
* decorations to be applied to the widened path
224+
* @param thin true if the transformed stroke attributes are smaller
225+
* than the minimum dropout pen width
226+
* @param normalize indicates whether stroke normalization should
227+
* be applied
228+
* @param antialias indicates whether or not adjustments appropriate
229+
* to antialiased rendering should be applied
230+
* @param consumer the {@code PathConsumer2D} instance to forward
231+
* the widened geometry to
232+
* @since 17
233+
*/
234+
/* @Override (only for 17+) */
235+
public void strokeTo(Shape src,
236+
AffineTransform at,
237+
Region clip,
238+
BasicStroke bs,
239+
boolean thin,
240+
boolean normalize,
241+
boolean antialias,
242+
final PathConsumer2D consumer)
243+
{
244+
// Test if at is identity:
245+
final AffineTransform _at = (at != null && !at.isIdentity()) ? at
246+
: null;
247+
195248
final NormMode norm = (normalize) ?
196249
((antialias) ? NormMode.ON_WITH_AA : NormMode.ON_NO_AA)
197250
: NormMode.OFF;
198251

199252
final DRendererContext rdrCtx = getRendererContext();
200253
try {
201-
strokeTo(rdrCtx, src, at, bs, thin, norm, antialias,
254+
if ((clip != null) &&
255+
(DO_CLIP || (DO_CLIP_RUNTIME_ENABLE && MarlinProperties.isDoClipAtRuntime()))) {
256+
// Define the initial clip bounds:
257+
final double[] clipRect = rdrCtx.clipRect;
258+
259+
// Adjust the clipping rectangle with the renderer offsets
260+
final double rdrOffX = 0.25d; // LBO: is it correct for AA or non AA cases ?
261+
final double rdrOffY = 0.25d; // see NearestPixelQuarter (depends on normalization ?)
262+
263+
// add a small rounding error:
264+
final double margin = 1e-3d;
265+
266+
clipRect[0] = clip.getLoY()
267+
- margin + rdrOffY;
268+
clipRect[1] = clip.getLoY() + clip.getHeight()
269+
+ margin + rdrOffY;
270+
clipRect[2] = clip.getLoX()
271+
- margin + rdrOffX;
272+
clipRect[3] = clip.getLoX() + clip.getWidth()
273+
+ margin + rdrOffX;
274+
275+
if (MarlinConst.DO_LOG_CLIP) {
276+
MarlinUtils.logInfo("clipRect (clip): "
277+
+ Arrays.toString(rdrCtx.clipRect));
278+
}
279+
280+
// Enable clipping:
281+
rdrCtx.doClip = true;
282+
}
283+
284+
strokeTo(rdrCtx, src, _at, bs, thin, norm, antialias,
202285
rdrCtx.p2dAdapter.init(consumer));
203286
} finally {
204287
// recycle the DRendererContext instance

‎src/java.desktop/share/classes/sun/java2d/marlin/MarlinRenderingEngine.java

+86-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -173,8 +173,12 @@ public Shape createStrokedShape(Shape src,
173173
* {@link PathConsumer2D} object as it is calculated.
174174
*
175175
* @param src the source path to be widened
176-
* @param bs the {@code BasicSroke} object specifying the
176+
* @param at the transform to be applied to the shape and the
177+
* stroke attributes
178+
* @param bs the {@code BasicStroke} object specifying the
177179
* decorations to be applied to the widened path
180+
* @param thin true if the transformed stroke attributes are smaller
181+
* than the minimum dropout pen width
178182
* @param normalize indicates whether stroke normalization should
179183
* be applied
180184
* @param antialias indicates whether or not adjustments appropriate
@@ -192,13 +196,92 @@ public void strokeTo(Shape src,
192196
boolean antialias,
193197
final PathConsumer2D consumer)
194198
{
199+
strokeTo(src, at, null, bs, thin, normalize, antialias, consumer);
200+
}
201+
202+
/**
203+
* Sends the geometry for a widened path as specified by the parameters
204+
* to the specified consumer.
205+
* <p>
206+
* The specified {@code src} {@link Shape} is widened according
207+
* to the parameters specified by the {@link BasicStroke} object.
208+
* Adjustments are made to the path as appropriate for the
209+
* {@link java.awt.RenderingHints#VALUE_STROKE_NORMALIZE} hint if the
210+
* {@code normalize} boolean parameter is true.
211+
* Adjustments are made to the path as appropriate for the
212+
* {@link java.awt.RenderingHints#VALUE_ANTIALIAS_ON} hint if the
213+
* {@code antialias} boolean parameter is true.
214+
* <p>
215+
* The geometry of the widened path is forwarded to the indicated
216+
* {@link PathConsumer2D} object as it is calculated.
217+
*
218+
* @param src the source path to be widened
219+
* @param at the transform to be applied to the shape and the
220+
* stroke attributes
221+
* @param clip the current clip in effect in device coordinates
222+
* @param bs the {@code BasicStroke} object specifying the
223+
* decorations to be applied to the widened path
224+
* @param thin true if the transformed stroke attributes are smaller
225+
* than the minimum dropout pen width
226+
* @param normalize indicates whether stroke normalization should
227+
* be applied
228+
* @param antialias indicates whether or not adjustments appropriate
229+
* to antialiased rendering should be applied
230+
* @param consumer the {@code PathConsumer2D} instance to forward
231+
* the widened geometry to
232+
* @since 17
233+
*/
234+
/* @Override (only for 17+) */
235+
public void strokeTo(Shape src,
236+
AffineTransform at,
237+
Region clip,
238+
BasicStroke bs,
239+
boolean thin,
240+
boolean normalize,
241+
boolean antialias,
242+
final PathConsumer2D consumer)
243+
{
244+
// Test if at is identity:
245+
final AffineTransform _at = (at != null && !at.isIdentity()) ? at
246+
: null;
247+
195248
final NormMode norm = (normalize) ?
196249
((antialias) ? NormMode.ON_WITH_AA : NormMode.ON_NO_AA)
197250
: NormMode.OFF;
198251

199252
final RendererContext rdrCtx = getRendererContext();
200253
try {
201-
strokeTo(rdrCtx, src, at, bs, thin, norm, antialias, consumer);
254+
if ((clip != null) &&
255+
(DO_CLIP || (DO_CLIP_RUNTIME_ENABLE && MarlinProperties.isDoClipAtRuntime()))) {
256+
// Define the initial clip bounds:
257+
final float[] clipRect = rdrCtx.clipRect;
258+
259+
// Adjust the clipping rectangle with the renderer offsets
260+
final float rdrOffX = 0.25f; // LBO: is it correct for AA or non AA cases ?
261+
final float rdrOffY = 0.25f; // see NearestPixelQuarter (depends on normalization ?)
262+
263+
// add a small rounding error:
264+
final float margin = 1e-3f;
265+
266+
clipRect[0] = clip.getLoY()
267+
- margin + rdrOffY;
268+
clipRect[1] = clip.getLoY() + clip.getHeight()
269+
+ margin + rdrOffY;
270+
clipRect[2] = clip.getLoX()
271+
- margin + rdrOffX;
272+
clipRect[3] = clip.getLoX() + clip.getWidth()
273+
+ margin + rdrOffX;
274+
275+
if (MarlinConst.DO_LOG_CLIP) {
276+
MarlinUtils.logInfo("clipRect (clip): "
277+
+ Arrays.toString(rdrCtx.clipRect));
278+
}
279+
280+
// Enable clipping:
281+
rdrCtx.doClip = true;
282+
}
283+
284+
strokeTo(rdrCtx, src, _at, bs, thin, norm, antialias, consumer);
202285
} finally {
203286
// recycle the RendererContext instance
204287
returnRendererContext(rdrCtx);

‎src/java.desktop/share/classes/sun/java2d/marlin/TransformingPathConsumer2D.java

+24-23
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -880,6 +880,7 @@ public long getNativeConsumer() {
880880
}
881881
}
882882

883+
/* note: CurveClipSplitter uses double-precision for higher accuracy */
883884
static final class CurveClipSplitter {
884885

885886
static final float LEN_TH = MarlinProperties.getSubdividerMinLength();
@@ -898,22 +899,22 @@ static final class CurveClipSplitter {
898899
final float[] clipRect;
899900

900901
// clip rectangle (ymin, ymax, xmin, xmax) including padding:
901-
final float[] clipRectPad = new float[4];
902+
final double[] clipRectPad = new double[4];
902903
private boolean init_clipRectPad = false;
903904

904905
// This is where the curve to be processed is put. We give it
905906
// enough room to store all curves.
906-
final float[] middle = new float[MAX_N_CURVES * 8 + 2];
907+
final double[] middle = new double[MAX_N_CURVES * 8 + 2];
907908
// t values at subdivision points
908-
private final float[] subdivTs = new float[MAX_N_CURVES];
909+
private final double[] subdivTs = new double[MAX_N_CURVES];
909910

910911
// dirty curve
911-
private final Curve curve;
912+
private final DCurve curve;
912913

913914
CurveClipSplitter(final RendererContext rdrCtx) {
914915
this.rdrCtx = rdrCtx;
915916
this.clipRect = rdrCtx.clipRect;
916-
this.curve = rdrCtx.curve;
917+
this.curve = /* rdrCtx.curve */ new DCurve(); // double-precision curve
917918
}
918919

919920
void init() {
@@ -935,7 +936,7 @@ private void initPaddedClip() {
935936
// adjust padded clip rectangle (ymin, ymax, xmin, xmax):
936937
// add a rounding error (curve subdivision ~ 0.1px):
937938
final float[] _clipRect = clipRect;
938-
final float[] _clipRectPad = clipRectPad;
939+
final double[] _clipRectPad = clipRectPad;
939940

940941
_clipRectPad[0] = _clipRect[0] - CLIP_RECT_PADDING;
941942
_clipRectPad[1] = _clipRect[1] + CLIP_RECT_PADDING;
@@ -961,7 +962,7 @@ boolean splitLine(final float x0, final float y0,
961962
return false;
962963
}
963964

964-
final float[] mid = middle;
965+
final double[] mid = middle;
965966
mid[0] = x0; mid[1] = y0;
966967
mid[2] = x1; mid[3] = y1;
967968

@@ -982,7 +983,7 @@ boolean splitQuad(final float x0, final float y0,
982983
return false;
983984
}
984985

985-
final float[] mid = middle;
986+
final double[] mid = middle;
986987
mid[0] = x0; mid[1] = y0;
987988
mid[2] = x1; mid[3] = y1;
988989
mid[4] = x2; mid[5] = y2;
@@ -1005,7 +1006,7 @@ boolean splitCurve(final float x0, final float y0,
10051006
return false;
10061007
}
10071008

1008-
final float[] mid = middle;
1009+
final double[] mid = middle;
10091010
mid[0] = x0; mid[1] = y0;
10101011
mid[2] = x1; mid[3] = y1;
10111012
mid[4] = x2; mid[5] = y2;
@@ -1017,15 +1018,15 @@ boolean splitCurve(final float x0, final float y0,
10171018
private boolean subdivideAtIntersections(final int type, final int outCodeOR,
10181019
final PathConsumer2D out)
10191020
{
1020-
final float[] mid = middle;
1021-
final float[] subTs = subdivTs;
1021+
final double[] mid = middle;
1022+
final double[] subTs = subdivTs;
10221023

10231024
if (init_clipRectPad) {
10241025
init_clipRectPad = false;
10251026
initPaddedClip();
10261027
}
10271028

1028-
final int nSplits = Helpers.findClipPoints(curve, mid, subTs, type,
1029+
final int nSplits = DHelpers.findClipPoints(curve, mid, subTs, type,
10291030
outCodeOR, clipRectPad);
10301031

10311032
if (TRACE) {
@@ -1036,12 +1037,12 @@ private boolean subdivideAtIntersections(final int type, final int outCodeOR,
10361037
// only curve support shortcut
10371038
return false;
10381039
}
1039-
float prevT = 0.0f;
1040+
double prevT = 0.0d;
10401041

10411042
for (int i = 0, off = 0; i < nSplits; i++, off += type) {
1042-
final float t = subTs[i];
1043+
final double t = subTs[i];
10431044

1044-
Helpers.subdivideAt((t - prevT) / (1.0f - prevT),
1045+
DHelpers.subdivideAt((t - prevT) / (1.0d - prevT),
10451046
mid, off, mid, off, type);
10461047
prevT = t;
10471048
}
@@ -1055,19 +1056,19 @@ private boolean subdivideAtIntersections(final int type, final int outCodeOR,
10551056
return true;
10561057
}
10571058

1058-
static void emitCurrent(final int type, final float[] pts,
1059+
static void emitCurrent(final int type, final double[] pts,
10591060
final int off, final PathConsumer2D out)
10601061
{
10611062
// if instead of switch (perf + most probable cases first)
10621063
if (type == 8) {
1063-
out.curveTo(pts[off + 2], pts[off + 3],
1064-
pts[off + 4], pts[off + 5],
1065-
pts[off + 6], pts[off + 7]);
1064+
out.curveTo((float)pts[off + 2], (float)pts[off + 3],
1065+
(float)pts[off + 4], (float)pts[off + 5],
1066+
(float)pts[off + 6], (float)pts[off + 7]);
10661067
} else if (type == 4) {
1067-
out.lineTo(pts[off + 2], pts[off + 3]);
1068+
out.lineTo((float)pts[off + 2], (float)pts[off + 3]);
10681069
} else {
1069-
out.quadTo(pts[off + 2], pts[off + 3],
1070-
pts[off + 4], pts[off + 5]);
1070+
out.quadTo((float)pts[off + 2], (float)pts[off + 3],
1071+
(float)pts[off + 4], (float)pts[off + 5]);
10711072
}
10721073
}
10731074
}

‎src/java.desktop/share/classes/sun/java2d/pipe/LoopPipe.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -261,7 +261,8 @@ public static ShapeSpanIterator getStrokeSpans(SunGraphics2D sg2d,
261261
ShapeSpanIterator sr = new ShapeSpanIterator(false);
262262

263263
try {
264-
sr.setOutputArea(sg2d.getCompClip());
264+
final Region clip = sg2d.getCompClip();
265+
sr.setOutputArea(clip);
265266
sr.setRule(PathIterator.WIND_NON_ZERO);
266267

267268
BasicStroke bs = (BasicStroke) sg2d.stroke;
@@ -270,7 +271,7 @@ public static ShapeSpanIterator getStrokeSpans(SunGraphics2D sg2d,
270271
(sg2d.strokeHint != SunHints.INTVAL_STROKE_PURE);
271272

272273
RenderEngine.strokeTo(s,
273-
sg2d.transform, bs,
274+
sg2d.transform, clip, bs,
274275
thin, normalize, false, sr);
275276
} catch (Throwable t) {
276277
sr.dispose();

‎src/java.desktop/share/classes/sun/java2d/pipe/RenderingEngine.java

+75-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -200,8 +200,12 @@ public abstract Shape createStrokedShape(Shape src,
200200
* {@link PathConsumer2D} object as it is calculated.
201201
*
202202
* @param src the source path to be widened
203-
* @param bs the {@code BasicSroke} object specifying the
203+
* @param at the transform to be applied to the shape and the
204+
* stroke attributes
205+
* @param bs the {@code BasicStroke} object specifying the
204206
* decorations to be applied to the widened path
207+
* @param thin true if the transformed stroke attributes are smaller
208+
* than the minimum dropout pen width
205209
* @param normalize indicates whether stroke normalization should
206210
* be applied
207211
* @param antialias indicates whether or not adjustments appropriate
@@ -218,6 +222,53 @@ public abstract void strokeTo(Shape src,
218222
boolean antialias,
219223
PathConsumer2D consumer);
220224

225+
/**
226+
* Sends the geometry for a widened path as specified by the parameters
227+
* to the specified consumer.
228+
* <p>
229+
* The specified {@code src} {@link Shape} is widened according
230+
* to the parameters specified by the {@link BasicStroke} object.
231+
* The clip region can be optionally given to let the renderer only
232+
* send geometries overlapping the clip region.
233+
* Adjustments are made to the path as appropriate for the
234+
* {@link java.awt.RenderingHints#VALUE_STROKE_NORMALIZE} hint if the
235+
* {@code normalize} boolean parameter is true.
236+
* Adjustments are made to the path as appropriate for the
237+
* {@link java.awt.RenderingHints#VALUE_ANTIALIAS_ON} hint if the
238+
* {@code antialias} boolean parameter is true.
239+
* <p>
240+
* The geometry of the widened path is forwarded to the indicated
241+
* {@link PathConsumer2D} object as it is calculated.
242+
*
243+
* @param src the source path to be widened
244+
* @param at the transform to be applied to the shape and the
245+
* stroke attributes
246+
* @param clip the current clip in effect in device coordinates
247+
* @param bs the {@code BasicStroke} object specifying the
248+
* decorations to be applied to the widened path
249+
* @param thin true if the transformed stroke attributes are smaller
250+
* than the minimum dropout pen width
251+
* @param normalize indicates whether stroke normalization should
252+
* be applied
253+
* @param antialias indicates whether or not adjustments appropriate
254+
* to antialiased rendering should be applied
255+
* @param consumer the {@code PathConsumer2D} instance to forward
256+
* the widened geometry to
257+
* @since 17
258+
*/
259+
public void strokeTo(Shape src,
260+
AffineTransform at,
261+
Region clip,
262+
BasicStroke bs,
263+
boolean thin,
264+
boolean normalize,
265+
boolean antialias,
266+
final PathConsumer2D consumer)
267+
{
268+
// As default implementation, call the strokeTo() method without the clip region.
269+
strokeTo(src, at, bs, thin, normalize, antialias, consumer);
270+
}
271+
221272
/**
222273
* Construct an antialiased tile generator for the given shape with
223274
* the given rendering attributes and store the bounds of the tile
@@ -428,6 +479,28 @@ public void strokeTo(Shape src,
428479
target.strokeTo(src, at, bs, thin, normalize, antialias, consumer);
429480
}
430481

482+
public void strokeTo(Shape src,
483+
AffineTransform at,
484+
Region clip,
485+
BasicStroke bs,
486+
boolean thin,
487+
boolean normalize,
488+
boolean antialias,
489+
PathConsumer2D consumer)
490+
{
491+
System.out.println(name+".strokeTo("+
492+
src.getClass().getName()+", "+
493+
at+", "+
494+
clip+", "+
495+
bs+", "+
496+
(thin ? "thin" : "wide")+", "+
497+
(normalize ? "normalized" : "pure")+", "+
498+
(antialias ? "AA" : "non-AA")+", "+
499+
consumer.getClass().getName()+")");
500+
target.strokeTo(src, at, clip, bs, thin, normalize, antialias, consumer);
501+
}
502+
503+
431504
public float getMinimumAAPenSize() {
432505
System.out.println(name+".getMinimumAAPenSize()");
433506
return target.getMinimumAAPenSize();

‎src/java.desktop/share/classes/sun/java2d/pipe/SpanShapeRenderer.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -42,7 +42,6 @@
4242
* perform the actual rendering.
4343
*/
4444
public abstract class SpanShapeRenderer implements ShapeDrawPipe {
45-
static final RenderingEngine RenderEngine = RenderingEngine.getInstance();
4645

4746
public static class Composite extends SpanShapeRenderer {
4847
CompositePipe comppipe;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
import java.awt.BasicStroke;
25+
import java.awt.Graphics2D;
26+
import java.awt.RenderingHints;
27+
import java.awt.Stroke;
28+
import java.awt.geom.Line2D;
29+
import java.awt.image.BufferedImage;
30+
31+
import static java.awt.image.BufferedImage.TYPE_INT_ARGB_PRE;
32+
33+
/**
34+
* @test
35+
* @bug 7018932
36+
* @summary fix LoopPipe.getStrokedSpans() performance (clipping enabled by Marlin renderer)
37+
* @run main/othervm/timeout=10 -Dsun.java2d.renderer=sun.java2d.marlin.MarlinRenderingEngine StrokedLinePerf
38+
* @run main/othervm/timeout=10 -Dsun.java2d.renderer=sun.java2d.marlin.DMarlinRenderingEngine StrokedLinePerf
39+
*/
40+
public class StrokedLinePerf {
41+
42+
public static void main(String[] unused) {
43+
BufferedImage bi = new BufferedImage(400, 400, TYPE_INT_ARGB_PRE);
44+
test(bi, true);
45+
test(bi, false);
46+
}
47+
48+
private static void test(BufferedImage bi, boolean useAA) {
49+
final long start = System.nanoTime();
50+
51+
final Graphics2D g2d = bi.createGraphics();
52+
53+
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
54+
(useAA) ? RenderingHints.VALUE_ANTIALIAS_ON
55+
: RenderingHints.VALUE_ANTIALIAS_OFF);
56+
57+
Stroke stroke = new BasicStroke(2.0f, 1, 0, 1.0f, new float[]{0.0f, 4.0f}, 0.0f);
58+
g2d.setStroke(stroke);
59+
60+
//Large values to trigger crash / infinite loop.
61+
g2d.draw(new Line2D.Double(4.0, 1.794369841E9, 567.0, -2.147483648E9));
62+
63+
System.out.println("StrokedLinePerf(" + useAA + "): Test duration= " + (1e-6 * (System.nanoTime() - start)) + " ms.");
64+
g2d.dispose();
65+
}
66+
}

1 commit comments

Comments
 (1)

openjdk-notifier[bot] commented on Jan 12, 2021

@openjdk-notifier[bot]
Please sign in to comment.