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

[FXCanvas] Poor performance of FXCanvas (50% frame drop)

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: P4 P4
    • tbd
    • 8u5, 8u20
    • javafx
    • Windows 7 x64, JDK8 u5 x64

      I tried to run FlexGanttFX in an E4 application (using an FXCanvas) and I've noticed that the performance is lower than when running a standalone JavaFX application.

      I made a little benchmark using Oracle samples. I've run the same code (thousands of colorful circles drawn on a 1080p scene) using FXCanvas and in a standalone JavaFX application (the code is available on github.com: mcmil/fxcanvas-benchmark).

      The results are as follows (values are FPS measured by Performance tracker):

      Standalone JavaFX app
      Avg: 0.0 instant 0.0
      Avg: 34.598766 instant 0.0
      Avg: 45.718437 instant 36.872547
      Avg: 49.234116 instant 55.55428
      Avg: 50.958836 instant 56.874763
      Avg: 51.982483 instant 55.835545
      Avg: 52.82121 instant 54.849483
      Avg: 49.67068 instant 57.75312
      Avg: 43.40379 instant 57.75312
      FXCanvas
      Avg: 0.0 instant 0.0
      Avg: 19.496336 instant 0.0
      Avg: 23.803656 instant 19.982939
      Avg: 25.214998 instant 27.849215
      Avg: 25.412786 instant 27.835789
      Avg: 25.731888 instant 26.75477
      Avg: 26.278933 instant 26.842173
      Avg: 23.945173 instant 28.574305
      Avg: 20.942469 instant 28.574305

       
      As you can see I got around 50% frame drop. But the problem is that the drop is really noticeable for the end user.

      I went to investigate the FXCanvas class, and saw something like this in it:

            // Consider optimizing this
              ImageData imageData = null;
              if ("win32".equals(SWT.getPlatform())) {
                  PaletteData palette = new PaletteData(0xFF00, 0xFF0000, 0xFF000000);
                  int scanline = width * 4;
                  byte[] dstData = new byte[scanline * height];
                  int[] srcData = buffer.array();
                  int dp = 0, sp = 0;
                  for (int y = 0; y < height; y++) {
                      for (int x = 0; x < width; x++) {
                          int p = srcData[sp++];
                          dstData[dp++] = (byte) (p & 0xFF); //dst:blue
                          dstData[dp++] = (byte)((p >> 8) & 0xFF); //dst:green
                          dstData[dp++] = (byte)((p >> 16) & 0xFF); //dst:green
                          dstData[dp++] = (byte)0x00; //alpha
                      }
                  }
                  /*ImageData*/ imageData = new ImageData(width, height, 32, palette, 4, dstData);
      }

       
      Well, that looks like a potential bottleneck. But even when I removed this looping - the performance gain was not that big (and of course the colors were off). So the problem must be somewhere else.

            Unassigned Unassigned
            duke J. Duke
            Votes:
            1 Vote for this issue
            Watchers:
            8 Start watching this issue

              Created:
              Updated:
              Imported: