Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4190429

Java 2: drawString is slow on win32 when no Direct Draw is available.

XMLWordPrintable

    • 2d
    • b02
    • x86, sparc
    • solaris_2.6, windows_95, windows_nt



        Name: gsC80088 Date: 11/16/98


        // execute the code below,
        // stretch the frame to be bigger
        // notice how long it takes the updates

        import java.awt.*;
        import java.awt.event.*;
        import java.awt.geom.*;

        public class Example04 extends Frame {
        Object AntiAlias = RenderingHints.VALUE_ANTIALIAS_ON;

        public static void main(String args[]) {
        new Example04();
        }

        public Example04() {
        super("Java 2D Example04");

        setSize(330,270);
        setVisible(true);

        addWindowListener(new WindowAdapter() {
        public void windowClosing(WindowEvent e) {
        System.exit(0);
        } });
        }

        public void paint(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        Dimension dim = getSize();

        AffineTransform at = new AffineTransform();
        at.setToTranslation(100, 100);
        g2d.transform(at);
        Font exFont = new Font("TimesRoman",Font.PLAIN,30);

        g2d.setFont(exFont);
        g2d.setColor(Color.black);
        g2d.drawString("non-Alias",300, 0);
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, AntiAlias);
        g2d.drawString("Alias",0.0f, 0.0f);
        }
        }
        (Review ID: 42708)
        ======================================================================
        Here's some better code that does timing from another user reporting this same problem. He elaborates to indicate problems on solaris x86 too. I also ran his test case on my win95 HP vectra in high color (1024x786)mode and the update took 151 seconds! Truecolor at a mere 800x600 gave worse results 187 seconds. Direct draw is installed. When this is run on my ultra 1 it can update the full screen in under 1 second.


        His bug report follows.

        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        java.awt.Frame in this case) with text using the Graphics.drawString
        method in the component's paint method. After running ``java fnt2'',
        resize the frame, close/open it, hide/un-hide parts of the java frame, etc ...
        to force repaint events.


        Painting is *extremely* slow on

        - A SS20 / w. a Ross HS180 and a SX 8MB frame buffer, Solaris 2.6
        - A PII i86 system with an ATI xpert@work AGP graphics card, also running
        Solaris 2.6, both in 24 bit/pixel and 8 bit/pixel video mode

        (btw. drawChars and drawBytes seems to have the same problem)


        Here are some times:

        1. The SS20 from above with jdk1.1.7:
           ~ 0.1 sec at 200x400 pixels
           ~ 0.4 sec at 1200x1000 pixels

           Looks good.
           
        2. The SS20 with jdk1.2fcs rc2
           ~ 10 seconds at the initial 200x400 pixels
           ~ 60 seconds after a resize to 500x500 pixels
           ~ 1224 seconds after a resize to ~1200x1000 pixels
           
           The system uses 100% cpu while the re-paint runs.
           Drawing speed gets worse the larger the frame is resized!
           
           20 minutes for a screen refresh/repaint is a bit too much... :-)

           The 500x500 repaint with jdk12 is over 10000% (!) slower
           than jdk11x !!
            
        3. Exactly the same effect can be observed on the Solaris x86 system mentioned
           above with roughly the same times...


        Setting the environment variable JAVA2D_USEPLATFORMFONT=1 brings speed up to
        jdk1.1.x levels but unfortunatelly it prints a comment that this feature/hack
        "... will be removed in the next build."

        ----------------------------------------------------------------------------
        import java.awt.*;
        import java.awt.event.*;

        public class fnt2 extends Frame {

            public fnt2() {
                super("fnt2");
                add(new DataCanvas());
            }

            public static void main(String[] args) {
                Frame f = new fnt2();
                f.addWindowListener(new WindowAdapter() {
                    public void windowClosing(WindowEvent e) { System.exit(0); }
                });
                f.pack();
                f.setVisible(true);
            }
        }


        class DataCanvas extends Canvas {
            public Dimension getPreferredSize() {
                return new Dimension(200, 400);
            }

            
            Font[] fonts = {
                new Font("serif", Font.PLAIN, 10),
                new Font("sansserif", Font.PLAIN, 10),
                new Font("monospaced", Font.ITALIC, 10),
                new Font("serif", Font.BOLD, 14),
            };



            public void paint(Graphics g) {
                long startTime = System.currentTimeMillis();

                FontMetrics[] cachedMetrics = new FontMetrics[fonts.length];

                String text = "Hello, world!";

                Dimension size = getSize();
                int i = 0;
                int spaceWidth = 5;

                for (int y = 0; y < size.height; y += 20) {
                    for (int x = 0; x < size.width; i++) {
                        Font font = fonts[i % fonts.length];
                        FontMetrics metrics = cachedMetrics[i % fonts.length];
                        if (metrics == null) {
                            metrics = g.getFontMetrics(font);
                            cachedMetrics[i % fonts.length] = metrics;
                        }

                        g.setFont(font);
                        g.drawString(text, x, y);

                        x += metrics.stringWidth(text) + spaceWidth;
                    }
                }

                long endTime = System.currentTimeMillis();
                System.out.println("repaint took " + (endTime-startTime)/1000f + " secon
        ds");
            }
        }
        ----------------------------------------------------------------------------

        gstone@eng 1998-11-19

        Name: sg39081 Date: 03/05/99


        To observe the problem, compile and run this application.
        Notice that the words WHY IS THIS SO SLOW? appear ten times,
        but that there is a noticable delay between each itteration.

        Now maximize the size of the frame in which these words
        appear. (I'm in 600 * 800, Win95 machine)

        Notice that now the delay in completing a single itteration
        is absurdly and unacceptably long.

        This problem occurs in jdk1.2 but not 1.1.7 or before.

        /*
        Expand the window and see how long it takes
        to complete ten calls to Graphics.drawString()
        */

        import java.awt.*;

        public class DSbug extends Panel {
        public static void main (String args[]) {
        Frame f = new Frame();
        f.setBounds (0, 0, 500, 300);
        f.add (new DSbug());
        f.setVisible (true);
        }

        public void paint (Graphics g) {
        String s = "WHY IS THIS SO SLOW?";
        for (int a = 0; a < 10; ++a)
        g.drawString (s, 30, 30 + (20 * a));
        }
        }
        ======================================================================

              prr Philip Race
              gstone Greg Stone
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: