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.
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.