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

[macosx] double buffered painting of offscreen image is 8 times slower then java 6

XMLWordPrintable

    • os_x

      FULL PRODUCT VERSION :
      java: 1.7.0_11

      ADDITIONAL OS VERSION INFORMATION :
      Mac OS X 10.8.2

      EXTRA RELEVANT SYSTEM CONFIGURATION :
      application was started with JavaWebstart

      A DESCRIPTION OF THE PROBLEM :
      Our fat swing application " ClassWizard " behaves unprofessional slow. While dragging elements there is not a smooth liquid moving but a slow moving with jumping and flickering elements. The reason of this is the fact, that the double buffered painting of offscreen image is 8 times slower then in java 6.

      REGRESSION. Last worked in version 6u31

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      I have added a small application to reproduce the bug. Start the application under java 7 and java 6 and wait 1 minute until the drawing of a rectangle at 2 different positions at an interval of 25 milliseconds has stopped. Then close the application by the red window button. A Log file " RuntimeTest " is written to the users home directory. It contains the time sampled for the paint and paintComponent methods of the JPanel. The time sampled for the paint method is 8 times higher then under java 6.

      log file under java 6:

      Mac OS X 10.6.8 java: 1.6.0_37
      count1: 2000 mess1: 937 time spend in paint
      count2: 2000 mess2: 430 time spend in paintComponent

      logfile under java 7


      Mac OS X 10.8.2 java: 1.7.0_11
      count1: 1995 mess1: 7774 time spend in paint
      count2: 1995 mess2: 473 time spend in paintComponent

      7774 millisec is 8 times higher then 937 millisec



      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      double buffered paint Method in java 7 is as fast as in java 6

      ACTUAL -
      double buffered paint Method in java 7 is 8 times slower then in java 6.


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      package com.classwizard.cw;


      import java.awt.BorderLayout;
      import java.awt.Color;
      import java.awt.Dimension;
      import java.awt.Graphics;
      import java.awt.Image;
      import java.awt.Rectangle;
      import java.awt.event.ActionEvent;
      import java.awt.event.ActionListener;
      import java.awt.event.WindowAdapter;
      import java.awt.event.WindowEvent;
      import java.io.BufferedWriter;
      import java.io.File;
      import java.io.FileOutputStream;
      import java.io.OutputStreamWriter;
      import java.io.PrintWriter;

      import javax.swing.JComponent;
      import javax.swing.JDesktopPane;
      import javax.swing.JFrame;
      import javax.swing.JInternalFrame;
      import javax.swing.JPanel;
      import javax.swing.JScrollPane;
      import javax.swing.WindowConstants;


      public class ClassWizard extends Object{
          public static void main(String args[]) throws Exception{
              try{
                  RuntimeTestFrame ket = new RuntimeTestFrame();
                  GJApp.launch(ket, " RuntimeTest " ,0,0,700,700,null);
              }catch (Exception e){
                  System.out.println(e.getMessage());
                  e.printStackTrace();
              }
          }
      }
      class GJApp extends WindowAdapter{
          public static void launch(final RuntimeTestFrame f, String title,final int x, final int y,final int w, int h,String propertiesFilename){
              f.setTitle(title);
              f.setBounds(x,y,w,h);
              f.setVisible(true);
              f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
              f.addWindowListener(new WindowAdapter(){
                  public void windowClosed(WindowEvent e){
                      f.closefile();
                      System.exit(0);
                  }
              });
          }
      }

      class RuntimeTestFrame extends JFrame{
          protected JDesktopPane desktopPane = new JDesktopPane();
          protected Page worksheet = null;
          PrintWriter writer = null;
          protected File outfile = null;
          boolean _even = true;
          int _flickercount = 0;
          javax.swing.Timer _timer = null;
          public RuntimeTestFrame() throws Exception{
              String user_home = System.getProperty( " user.home " );
              String filepath = user_home + " /RuntimeTest.txt " ;
              outfile = new File(filepath);
              writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outfile), " UTF-8 " )));
              JComponent contentPane = (JComponent)getContentPane();
              contentPane.setDoubleBuffered(true);
              worksheet = new Page( " Worksheet " ,true,false,true,true,writer,this);
              desktopPane.add(worksheet);
              contentPane.add(desktopPane,BorderLayout.CENTER);
              worksheet.setPreferredSize(new Dimension(500, 500));
              Rectangle bounds2 = new Rectangle(0, 0, 500, 500);
              worksheet.setBounds(bounds2);
              String osname = System.getProperty( " os.name " );
              String osversion = System.getProperty( " os.version " );
              String java_version = System.getProperty( " java.version " );
              writer.print(osname + " " + osversion + " java: " + java_version + "
       " );
              worksheet.setVisible(true);
              desktopPane.revalidate();
              
              // move the carea 1000 times for and back and sample time spend
              _timer = new javax.swing.Timer(25, new ActionListener(){
                  public void actionPerformed(ActionEvent evt){
                      try{
                          if(_even == true){
                              worksheet.repaint();
                              _even = false;
                          }
                          else{
                              worksheet.repaint();
                              _even = true;
                          }
                          _flickercount++;
                          if(_flickercount == 2000){
                              _timer.stop();
                              writer.print( " count1: " + worksheet.count1 + " mess1: " + worksheet.mess1 + " time spend in paint " + "
       " );
                              writer.print( " count2: " + worksheet.count2 + " mess2: " + worksheet.mess2 + " time spend in paintComponent " + "
       " );
                          }
                      }
                      catch (Exception ex){
                          System.out.println(ex.getMessage());
                          ex.printStackTrace();
                      }
                  }
              });

              _timer.start();
              

          }
          public void closefile(){
              writer.flush();
              writer.close();
          }
      }

      class Page extends JInternalFrame
      {
          long mess1 = 0;
          long mess2 = 0;

          int count1 = 0;
          int count2 = 0;

          protected RuntimeTestFrame _owner = null;
          protected PrintWriter _writer = null;
          protected Canvas canvas = null; // drawarea of page
          protected JScrollPane _sp = null;
          public Page(String title,boolean resizable, boolean closable, boolean maximizable, boolean iconifiable,PrintWriter writer,RuntimeTestFrame owner) throws Exception{
              super(title,resizable,closable,maximizable,iconifiable);
              _writer = writer;
              _owner = owner;
              JComponent contentPane = (JComponent)this.getContentPane();
              canvas = new Canvas(writer,this);
              _sp = new JScrollPane(canvas);
              contentPane.add(_sp,BorderLayout.CENTER);
              canvas.setBackground(Color.WHITE);
              canvas.setSize(new Dimension(500,500));
          }
          public void displayRectangle(Graphics g){
              Color boxcolor = new Color(0, 250, 0);
              g.setColor(boxcolor);
              if(_owner._even == true){
                  Rectangle r1 = new Rectangle(100, 100, 100, 100);
                  g.fillRect(r1.x, r1.y, r1.width, r1.height);
              }else{
                  Rectangle r1 = new Rectangle(300, 300, 100, 100);
                   g.fillRect(r1.x, r1.y, r1.width, r1.height);
              }
          }
      }
      class Canvas extends JPanel{
          PrintWriter _writer = null;
          Page _page = null;
          Image offscreen = null;
          
          public Canvas(PrintWriter writer, Page page) throws Exception{
              super();
              _writer = writer;
              _page = page;
          }
          @Override
          public void paint(Graphics g){
              long tmess1 = System.currentTimeMillis();
              try{
                      Rectangle r222 = g.getClipBounds();
                      if(offscreen == null){
                          int width = getSize().width;
                          int height = getSize().height;
                          offscreen = createImage(width, height);
                      }
                      Graphics og = offscreen.getGraphics();
                      og.setClip(r222.x, r222.y, r222.width, r222.height);
                      super.paint(og); // all drawing into offsreenbuffer
                      Rectangle clip = g.getClipBounds();
                      // copy offsreenbuffer to screen in changed rectangle
                      g.drawImage(offscreen, clip.x, clip.y,clip.x+clip.width,clip.y+clip.height,clip.x, clip.y,clip.x+clip.width,clip.y+clip.height, null);
                      og.dispose();
              }catch (Exception ex){
                  System.out.println(ex.getMessage());
                  ex.printStackTrace();
              }
              tmess1 = System.currentTimeMillis() - tmess1;
              _page.mess1 += tmess1;
              _page.count1++;
          }
          @Override
          public void paintComponent(Graphics g){
              long tmess2 = System.currentTimeMillis();
              try{
                  super.paintComponent(g);
                  _page.displayRectangle(g);
              }catch (Exception e){
                  System.out.println(e.getMessage());
                  e.printStackTrace();
              }
              tmess2 = System.currentTimeMillis() - tmess2;
              _page.mess2 += tmess2;
              _page.count2++;
          }

      }

      ---------- END SOURCE ----------

      SUPPORT :
      YES

            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated: