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

[macosx] JProgressBar animation causes high CPU, paint flicker, and crashes on Aqua L&F

XMLWordPrintable

    • 2d
    • x86
    • os_x

      FULL PRODUCT VERSION :
      java version "1.8.0_66"
      Java(TM) SE Runtime Environment (build 1.8.0_66-b17)
      Java HotSpot(TM) 64-Bit Server VM (build 25.66-b17, mixed mode)


      ADDITIONAL OS VERSION INFORMATION :
      MacOS X 10.9.5

      EXTRA RELEVANT SYSTEM CONFIGURATION :
      This bug was observed on a 13-inch MacBook Air (Mid 2012 model, no "retina" display). Also tried a 2560x1440 external monitor for some of the tests.

      A DESCRIPTION OF THE PROBLEM :
      On MacOS, under the default Aqua L&F, the animation of a JProgressBar (blue/white barberpole animation when indeterminate, wavy effect when determinate) causes high CPU usage, flickering repaints in other windows, and occasional JVM crashes. There seems to be something very heavy-weight about the way this component is being repainted, as if the the L&F round-trips to the native window system on every single repaint.

      Here are the different symptoms experienced, using the simple test application pasted in the "source code for executable test case" field:
      ---- Symptom 1: High CPU Usage ----
      When run on a 13-inch Mid 2012 MacBook Air with the Window maximized (at 1440x900) and the indeterminate progress bar animation turned on, the ProgressBarTest process runs at between 20-27% CPU while the MacOS WindowServer process takes 10-14% CPU. If I connect my external monitor and maximize the window to 2560x1440, CPU usage increases to 24-29% for the ProgressBarTest process while WindowServer takes 12-17%. That's with no other Java apps running at the same time. Another user on the macosx-port-dev mailing list reports: "We are on Mac OS and we see huge energy impact when the progress bar is shown. The wave like animation when showing the progress is causing the impact.")
      ---- Symptom 2: JVM crashes ----
      The apparent high frequency of native window system calls during the indeterminate progress animation seems to expose other bugs that crash the JVM. The crash logs for two such crashes are pasted in the "Error Message(s)/ Crash Logs" field.
      --- Symptom 3: Flickering repaints in other Java processes ----
      This one I have only been able to reproduce by using the NetBeans IDE as the second process, with a large external monitor. Whenever the simple ProgressBarTest is running, in a separate process, with the progress bar animation enabled, the NetBeans IDE becomes near unusable due to a very odd kind of paint flicker. I have tried to illustrate this here: https://vimeo.com/147649683 (the voiceover is from before I had realized that the problem was relating to the JProgressBar animation). Note that the flickering happens so fast that it's difficult to see what's going on in a low-frame-rate screen recording. You can just see it happening during scrolling at 01:13 (compare with smooth scrolling in a different Java app for which the bug has not manifested itself at 02:40) and during editing right after 01:48. During editing, notice how the text cursor skips back while I'm typing characters (the recording only manages to catch it doing this
      every now and then).

      From observing the bug, what seems to be happening is that every time a new frame is painted, the old frame becomes briefly visible again for a fraction of a second before the new frame reappears. For instance, suppose the editor shows the word "tes" and the user types "t", then the following will happen:

      - The editor first shows "tes|". (where | is the cursor)
      - The user then types the letter "t", and the editor updates to show "test|".
      - Immediately afterwards, for a very brief moment, the editor shows "tes|" again.
      - Immediately afterwards again, the editor finally shows "test|" again.

      At the suggestion of people on the macosx-port-dev mailing list, I tried running the NetBeans IDE with J2D_TRACE_LEVEL=4; this gave no new log messages while observing the bug. I also tried -Dsun.java2d.opengl=false; this did _not_ make the bug go away (setting confirmed with System.getProperty("sun.java2d.opengl")).
      ----------------------

      This is a high impact bug, since the high CPU usage of the JProgressBar tends to occur when other threads need the CPU the most--that is, when some other expensive process is going on that warrants the display of a progress bar (e.g. the dreaded "Background Scanning of Projects" ( https://blogs.oracle.com/joshis/entry/netbeans_ide_is_scanning_parsing ) that always makes the NetBeans IDE feel sluggish).

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      The CPU usage symptom is the easiest one to reproduce. Run the attached app, click the button to turn on the progress bar animation, and watch the CPU usage in the Activity Monitor.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Displaying a progress bar should not cause a high CPU usage.
      ACTUAL -
      When run on a 13-inch Mid 2012 MacBook Air with the Window maximized (at 1440x900) and the indeterminate progress bar animation turned on, the ProgressBarTest process runs at between 20-27% CPU while the MacOS WindowServer process takes 10-14% CPU. If I connect my external monitor and maximize the window to 2560x1440, CPU usage increases to 24-29% for the ProgressBarTest process while WindowServer takes 12-17%.

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      ======= FIRST CRASH ============================================================
      EBLAIR:Deletables ebakke$ java ProgressBarTest
      [I] CGLGraphicsConfig_initCGL
      [I] OGLFuncs_OpenLibrary
      [I] OGLFuncs_InitPlatformFuncs
      [I] OGLFuncs_InitBaseFuncs
      [I] OGLFuncs_InitExtFuncs
      [I] CGLGraphicsConfig_getCGLConfigInfo
      [I] CGLGraphicsConfig_getCGLConfigInfo: OpenGL version=2.1 INTEL-8.28.36
      [I] OGLContext_IsExtensionAvailable: GL_ARB_fragment_shader=true
      [I] OGLContext_IsExtensionAvailable: GL_ARB_multitexture=true
      [I] OGLContext_IsExtensionAvailable: GL_ARB_texture_non_power_of_two=true
      [I] OGLContext_IsExtensionAvailable: GL_ARB_texture_rectangle=true
      [I] OGLContext_IsExtensionAvailable: GL_EXT_framebuffer_object=true
      [I] OGLContext_IsExtensionAvailable: GL_ARB_depth_texture=true
      [I] OGLContext_IsFBObjectExtensionAvailable: fbobject supported
      [I] OGLContext_IsLCDShaderSupportAvailable: LCD text shader supported
      [I] OGLContext_IsBIOpShaderSupportAvailable: BufferedImageOp shader supported
      [I] OGLContext_IsGradShaderSupportAvailable: Linear/RadialGradientPaint shader supported
      [I] OGLContext_IsExtensionAvailable: GL_NV_fragment_program=false
      [I] OGLContext_IsExtensionAvailable: GL_ARB_fragment_program=true
      [I] OGLContext_IsExtensionAvailable: GL_NV_texture_barrier=true
      [I] CGLGraphicsConfig_getCGLConfigInfo: db=1 alpha=1
      [I] CGLGraphicsConfig_getCGLConfigInfo
      [I] CGLGraphicsConfig_getCGLConfigInfo: OpenGL version=2.1 INTEL-8.28.36
      [I] OGLContext_IsExtensionAvailable: GL_ARB_fragment_shader=true
      [I] OGLContext_IsExtensionAvailable: GL_ARB_multitexture=true
      [I] OGLContext_IsExtensionAvailable: GL_ARB_texture_non_power_of_two=true
      [I] OGLContext_IsExtensionAvailable: GL_ARB_texture_rectangle=true
      [I] OGLContext_IsExtensionAvailable: GL_EXT_framebuffer_object=true
      [I] OGLContext_IsExtensionAvailable: GL_ARB_depth_texture=true
      [I] OGLContext_IsFBObjectExtensionAvailable: fbobject supported
      [I] OGLContext_IsLCDShaderSupportAvailable: LCD text shader supported
      [I] OGLContext_IsBIOpShaderSupportAvailable: BufferedImageOp shader supported
      [I] OGLContext_IsGradShaderSupportAvailable: Linear/RadialGradientPaint shader supported
      [I] OGLContext_IsExtensionAvailable: GL_NV_fragment_program=false
      [I] OGLContext_IsExtensionAvailable: GL_ARB_fragment_program=true
      [I] OGLContext_IsExtensionAvailable: GL_NV_texture_barrier=true
      [I] CGLGraphicsConfig_getCGLConfigInfo: db=1 alpha=1
      [I] CGLGraphicsConfig_getCGLConfigInfo
      [I] CGLGraphicsConfig_getCGLConfigInfo: OpenGL version=2.1 INTEL-8.28.36
      [I] OGLContext_IsExtensionAvailable: GL_ARB_fragment_shader=true
      [I] OGLContext_IsExtensionAvailable: GL_ARB_multitexture=true
      [I] OGLContext_IsExtensionAvailable: GL_ARB_texture_non_power_of_two=true
      [I] OGLContext_IsExtensionAvailable: GL_ARB_texture_rectangle=true
      [I] OGLContext_IsExtensionAvailable: GL_EXT_framebuffer_object=true
      [I] OGLContext_IsExtensionAvailable: GL_ARB_depth_texture=true
      [I] OGLContext_IsFBObjectExtensionAvailable: fbobject supported
      [I] OGLContext_IsLCDShaderSupportAvailable: LCD text shader supported
      [I] OGLContext_IsBIOpShaderSupportAvailable: BufferedImageOp shader supported
      [I] OGLContext_IsGradShaderSupportAvailable: Linear/RadialGradientPaint shader supported
      [I] OGLContext_IsExtensionAvailable: GL_NV_fragment_program=false
      [I] OGLContext_IsExtensionAvailable: GL_ARB_fragment_program=true
      [I] OGLContext_IsExtensionAvailable: GL_NV_texture_barrier=true
      [I] CGLGraphicsConfig_getCGLConfigInfo: db=1 alpha=1
      #
      # A fatal error has been detected by the Java Runtime Environment:
      #
      # SIGSEGV (0xb) at pc=0x000000011e7e1e43, pid=96584, tid=47879
      #
      # JRE version: Java(TM) SE Runtime Environment (8.0_66-b17) (build 1.8.0_66-b17)
      # Java VM: Java HotSpot(TM) 64-Bit Server VM (25.66-b17 mixed mode bsd-amd64 compressed oops)
      # Problematic frame:
      # C [libawt_lwawt.dylib+0x1ae43] OGLSD_SetScratchSurface+0x49
      #
      # Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
      #
      # An error report file with more information is saved as:
      # /Users/ebakke/Deletables/hs_err_pid96584.log
      Compiled method (nm) 553900 839 n 0 sun.java2d.opengl.OGLRenderQueue::flushBuffer (native)
       total in heap [0x000000010815db10,0x000000010815de30] = 800
       relocation [0x000000010815dc38,0x000000010815dc78] = 64
       main code [0x000000010815dc80,0x000000010815de30] = 432
      Compiled method (c1) 553900 1848 %s! 3 sun.java2d.opengl.OGLRenderQueue$QueueFlusher::run @ -2 (234 bytes)
       total in heap [0x00000001083d5910,0x00000001083d9850] = 16192
       relocation [0x00000001083d5a38,0x00000001083d5cb0] = 632
       main code [0x00000001083d5cc0,0x00000001083d81e0] = 9504
       stub code [0x00000001083d81e0,0x00000001083d8388] = 424
       oops [0x00000001083d8388,0x00000001083d8398] = 16
       metadata [0x00000001083d8398,0x00000001083d8428] = 144
       scopes data [0x00000001083d8428,0x00000001083d9060] = 3128
       scopes pcs [0x00000001083d9060,0x00000001083d9530] = 1232
       dependencies [0x00000001083d9530,0x00000001083d9540] = 16
       handler table [0x00000001083d9540,0x00000001083d9798] = 600
       nul chk table [0x00000001083d9798,0x00000001083d9850] = 184
      #
      # If you would like to submit a bug report, please visit:
      # http://bugreport.java.com/bugreport/crash.jsp
      # The crash happened outside the Java Virtual Machine in native code.
      # See problematic frame for where to report the bug.
      #
      Abort trap: 6

      ======= SECOND CRASH ===========================================================
      EBLAIR:Deletables ebakke$ java ProgressBarTest
      [I] CGLGraphicsConfig_initCGL
      [I] OGLFuncs_OpenLibrary
      [I] OGLFuncs_InitPlatformFuncs
      [I] OGLFuncs_InitBaseFuncs
      [I] OGLFuncs_InitExtFuncs
      [I] CGLGraphicsConfig_getCGLConfigInfo
      [I] CGLGraphicsConfig_getCGLConfigInfo: OpenGL version=2.1 INTEL-8.28.36
      [I] OGLContext_IsExtensionAvailable: GL_ARB_fragment_shader=true
      [I] OGLContext_IsExtensionAvailable: GL_ARB_multitexture=true
      [I] OGLContext_IsExtensionAvailable: GL_ARB_texture_non_power_of_two=true
      [I] OGLContext_IsExtensionAvailable: GL_ARB_texture_rectangle=true
      [I] OGLContext_IsExtensionAvailable: GL_EXT_framebuffer_object=true
      [I] OGLContext_IsExtensionAvailable: GL_ARB_depth_texture=true
      [I] OGLContext_IsFBObjectExtensionAvailable: fbobject supported
      [I] OGLContext_IsLCDShaderSupportAvailable: LCD text shader supported
      [I] OGLContext_IsBIOpShaderSupportAvailable: BufferedImageOp shader supported
      [I] OGLContext_IsGradShaderSupportAvailable: Linear/RadialGradientPaint shader supported
      [I] OGLContext_IsExtensionAvailable: GL_NV_fragment_program=false
      [I] OGLContext_IsExtensionAvailable: GL_ARB_fragment_program=true
      [I] OGLContext_IsExtensionAvailable: GL_NV_texture_barrier=true
      [I] CGLGraphicsConfig_getCGLConfigInfo: db=1 alpha=1
      [I] CGLGraphicsConfig_getCGLConfigInfo
      [I] CGLGraphicsConfig_getCGLConfigInfo: OpenGL version=2.1 INTEL-8.28.36
      [I] OGLContext_IsExtensionAvailable: GL_ARB_fragment_shader=true
      [I] OGLContext_IsExtensionAvailable: GL_ARB_multitexture=true
      [I] OGLContext_IsExtensionAvailable: GL_ARB_texture_non_power_of_two=true
      [I] OGLContext_IsExtensionAvailable: GL_ARB_texture_rectangle=true
      [I] OGLContext_IsExtensionAvailable: GL_EXT_framebuffer_object=true
      [I] OGLContext_IsExtensionAvailable: GL_ARB_depth_texture=true
      [I] OGLContext_IsFBObjectExtensionAvailable: fbobject supported
      [I] OGLContext_IsLCDShaderSupportAvailable: LCD text shader supported
      [I] OGLContext_IsBIOpShaderSupportAvailable: BufferedImageOp shader supported
      [I] OGLContext_IsGradShaderSupportAvailable: Linear/RadialGradientPaint shader supported
      [I] OGLContext_IsExtensionAvailable: GL_NV_fragment_program=false
      [I] OGLContext_IsExtensionAvailable: GL_ARB_fragment_program=true
      [I] OGLContext_IsExtensionAvailable: GL_NV_texture_barrier=true
      [I] CGLGraphicsConfig_getCGLConfigInfo: db=1 alpha=1
      #
      # A fatal error has been detected by the Java Runtime Environment:
      #
      # SIGSEGV (0xb) at pc=0x0000000127f1ee43, pid=96766, tid=48135
      #
      # JRE version: Java(TM) SE Runtime Environment (8.0_66-b17) (build 1.8.0_66-b17)
      # Java VM: Java HotSpot(TM) 64-Bit Server VM (25.66-b17 mixed mode bsd-amd64 compressed oops)
      # Problematic frame:
      # C [libawt_lwawt.dylib+0x1ae43] OGLSD_SetScratchSurface+0x49
      #
      # Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
      #
      # An error report file with more information is saved as:
      # /Users/ebakke/Deletables/hs_err_pid96766.log
      Compiled method (nm) 19419 742 n 0 sun.java2d.opengl.OGLRenderQueue::flushBuffer (native)
       total in heap [0x0000000111813ad0,0x0000000111813df0] = 800
       relocation [0x0000000111813bf8,0x0000000111813c38] = 64
       main code [0x0000000111813c40,0x0000000111813df0] = 432
      Compiled method (c1) 19419 738 3 sun.java2d.opengl.OGLRenderQueue::access$100 (5 bytes)
       total in heap [0x0000000111812a90,0x0000000111812e00] = 880
       relocation [0x0000000111812bb8,0x0000000111812bf0] = 56
       main code [0x0000000111812c00,0x0000000111812cc0] = 192
       stub code [0x0000000111812cc0,0x0000000111812d68] = 168
       metadata [0x0000000111812d68,0x0000000111812d78] = 16
       scopes data [0x0000000111812d78,0x0000000111812d98] = 32
       scopes pcs [0x0000000111812d98,0x0000000111812de8] = 80
       dependencies [0x0000000111812de8,0x0000000111812df0] = 8
       nul chk table [0x0000000111812df0,0x0000000111812e00] = 16
      #
      # If you would like to submit a bug report, please visit:
      # http://bugreport.java.com/bugreport/crash.jsp
      # The crash happened outside the Java Virtual Machine in native code.
      # See problematic frame for where to report the bug.
      #
      Abort trap: 6


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.awt.*;
      import java.awt.event.*;
      import javax.swing.*;

      public class ProgressBarTest extends JFrame {
        private final JProgressBar progressBar = new JProgressBar();
        private final JButton button = new JButton("Toggle Progress Bar State");

        public ProgressBarTest() {
          initComponents();
        }

        private void initComponents() {
          button.setText("Toggle Progress Bar State");
          button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
              progressBar.setIndeterminate(!progressBar.isIndeterminate());
            }
          });
          getContentPane().add(progressBar, BorderLayout.NORTH);
          getContentPane().add(button, BorderLayout.SOUTH);

          pack();
        }

        public static void main(String args[]) {
          SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
              new ProgressBarTest().setVisible(true);
            }
          });
        }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      No known workaround.

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

              Created:
              Updated: