[OpenJDK 2D-Dev] RFR: 7018932 : Drawing very large coordinates with a dashed Stroke can cause Java to hang [v3]

Sergey Bylokhov serb at openjdk.java.net
Sun Jan 10 02:49:57 UTC 2021


On Sat, 9 Jan 2021 10:05:11 GMT, Laurent Bourgès <lbourges at openjdk.org> wrote:

>> This is my fix proposal to this bug:
>> - added new method strokeTo(... Region clip ...) in the abstract RenderingEngine class
>> - fixed all RenderingEngine implementations in java.desktop module
>> - MarlinRenderingEngine now uses the clip region to roughly & quickly clip the given shape in strokeTo(clip) 
>> - LoopPipe.getStrokeSpans() uses the new strokeTo(clip) method to get good performance with huge dashed shapes.
>> 
>> I wrote a new test class to validate the bug fix.
>
> Laurent Bourgès has updated the pull request incrementally with one additional commit since the last revision:
> 
>   fixed white spaces

src/java.desktop/share/classes/sun/java2d/pipe/RenderingEngine.java line 257:

> 255:      * @since 17
> 256:      */
> 257:     public abstract void strokeTo(Shape src,

I think we need to clarify the backward compatibility of this change.
 - If we would like to support the old marlin version via "-Dsun.java2d.renderer" option in jdk17 then adding the new abstract method to this interface breaks this possibility. To support that this method should be made default and call the old strokeTo method.
 - If support for the old marlin library is not necessary then we could drop the old method from this interface(but preserve it in the MarlinRenderingEngine to have the same marlin codebase), it won't be used anyway.

src/java.desktop/share/classes/sun/java2d/pipe/LoopPipe.java line 273:

> 271:                 (sg2d.strokeHint != SunHints.INTVAL_STROKE_PURE);
> 272: 
> 273: // No clipping (pre-jdk17)

This code is not a part of the marlin, so exists only in the jdk17. Do we need these commented lines here?

test/jdk/sun/java2d/marlin/DrawingTest7018932.java line 42:

> 40:  * @run main DrawingTest7018932
> 41:  */
> 42: public class DrawingTest7018932 extends JPanel {

This will work only in the headful environment, I suggest something like this:
/*
 * Copyright (c) 2021, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

import java.awt.BasicStroke;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.geom.Line2D;
import java.awt.image.BufferedImage;

import static java.awt.image.BufferedImage.TYPE_INT_ARGB_PRE;

/*
 * @test
 * @bug 7018932
 * @summary fix LoopPipe.getStrokedSpans() performance (clipping enabled by Marlin renderer)
 */
public final class StrokedLinePerf {

    public static void main(String[] args) {
        BufferedImage bi = new BufferedImage(400, 400, TYPE_INT_ARGB_PRE);
        test(bi, true);
        test(bi, false);
    }

    private static void test(BufferedImage bi, boolean useAA) {
        Graphics2D g2d = bi.createGraphics();
        long start = System.nanoTime();

        if (useAA) {
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);
        } else {
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_OFF);
        }

        Stroke stroke = new BasicStroke(2.0f, 1, 0, 1.0f, new float[]{0.0f, 4.0f}, 0.0f);
        g2d.setStroke(stroke);

        //Large values to trigger crash / infinite loop.
        g2d.draw(new Line2D.Double(4.0, 1.794369841E9, 567.0, -2.147483648E9));

        System.out.println("Test duration= " + (1e-6 * (System.nanoTime() - start)) + " ms.");
        g2d.dispose();
    }
}

-------------

PR: https://git.openjdk.java.net/jdk/pull/2013


More information about the 2d-dev mailing list