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

Translucent windows are completely repainted on every paint event, on Windows

    Details

    • Subcomponent:
    • Resolved In Build:
      b04
    • CPU:
      generic
    • OS:
      windows
    • Verification:
      Verified

      Backports

        Description

        Many external developers complain about translucent windows performance, for example:

        http://www.miginfocom.com/blog/?p=30
        The current implementation of non-opaque windows in AWT/Swing is ugly. Here is a rough sequence of events for *every* user- or system-triggered repaint:

        1. Repaint request is registered by Swing (RepaintManager).
        2. Somewhen later, RepaintManager processes all the dirty regions - see RepaintManager.paintDirtyRegions().
        3. All the dirty components in non-opaque windows are removed from the list to repaint, and the corresponding windows are updated with Window.updateWindow(null) call - see RepaintManager.updateWindows().
        4. updateWindows(null) forwards to peer.updateWindow(null) and then to TranslucentWindowPainter.updateWindow(null).
        5. As the given image is null, the latter method calls window.paintAll() to get the whole window contents.

        See attached test to reproduce the problem. It shows a frame with a JButton and JTextArea at the bottom. The button changes window's opacity on and off, and text area prints all the upcoming paint() calls to the console. Launch the test, press button, observe the window gets non-opaque. Move the mouse over the button to trigger hover effect. If you see the text area is repainted on button hover, the bug is reproduced.

          Issue Links

            Activity

            Hide
            art Artem Ananiev added a comment -
            BT2:EVALUATION

            Note, this fix is not supposed for AWT components, they are too tightly related with the native resources. Direct drawing onto Swing components (via getGraphics()) is not supported too, as it's unknown when updateWindow() shoud be called in that case. For regular Swing painting, updateWindow() is called from RepaintManager after all the dirty regions are processed.
            Show
            art Artem Ananiev added a comment - BT2:EVALUATION Note, this fix is not supposed for AWT components, they are too tightly related with the native resources. Direct drawing onto Swing components (via getGraphics()) is not supported too, as it's unknown when updateWindow() shoud be called in that case. For regular Swing painting, updateWindow() is called from RepaintManager after all the dirty regions are processed.
            Hide
            art Artem Ananiev added a comment -
            BT2:EVALUATION

            The idea is to have a buffer which is used for incremental painting Swing components to, and use it if updateWindow() is called with an empty/null image. There are several possible solutions:

            1. If Swing uses buffer per window ("gray rect fix"), all the painting is performed to BufferStrategyPaintManager and its BufferStrategy. Unfortunately, there is no way to obtain a BufferedImage (required for updateWindow()) from it, so this is not an option.

            2. RepaintManager has several methods like getOffscreenBuffer() or getVolatileOffscreenBuffer(), however they return temporary images which are shared between different components and repaints and can't be used for incremental painting.

            3. Another idea is to have a special buffer (BufferedImage of type INT_ARGB_PRE) in Window class and use its Graphics for drawing when the window is not opaque. Then, if updateWindow() is called with 'null', use this buffer to update the native level.
            Show
            art Artem Ananiev added a comment - BT2:EVALUATION The idea is to have a buffer which is used for incremental painting Swing components to, and use it if updateWindow() is called with an empty/null image. There are several possible solutions: 1. If Swing uses buffer per window ("gray rect fix"), all the painting is performed to BufferStrategyPaintManager and its BufferStrategy. Unfortunately, there is no way to obtain a BufferedImage (required for updateWindow()) from it, so this is not an option. 2. RepaintManager has several methods like getOffscreenBuffer() or getVolatileOffscreenBuffer(), however they return temporary images which are shared between different components and repaints and can't be used for incremental painting. 3. Another idea is to have a special buffer (BufferedImage of type INT_ARGB_PRE) in Window class and use its Graphics for drawing when the window is not opaque. Then, if updateWindow() is called with 'null', use this buffer to update the native level.
            Hide
            anthony Anthony Petrov (Inactive) added a comment -
            BT2:EVALUATION

            The fix causes a regression described at 6884960. Back-porting is only possible after fixing that.
            Show
            anthony Anthony Petrov (Inactive) added a comment - BT2:EVALUATION The fix causes a regression described at 6884960. Back-porting is only possible after fixing that.
            Hide
            anthony Anthony Petrov (Inactive) added a comment -
            BT2:EVALUATION

            The back-ported fix will include the changes for 6884960.
            Show
            anthony Anthony Petrov (Inactive) added a comment - BT2:EVALUATION The back-ported fix will include the changes for 6884960.

              People

              • Assignee:
                anthony Anthony Petrov (Inactive)
                Reporter:
                art Artem Ananiev
              • Votes:
                0 Vote for this issue
                Watchers:
                3 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:
                  Imported:
                  Indexed: