-
Bug
-
Resolution: Duplicate
-
P4
-
7u55, 8u5
-
Red Hat Enterprise Linux 6.2
Xorg 1.10.4
Gnome 2.28.2
nVidia Quadro 410 driver rev. 331.79
Intel Xeon E5-1630
Our application runs as a JFXPanel in a full screen JFrame with legacy Swing dialogue windows on linux.
When the application is run on high resolution screens (EG 2560x1440) the CPU load on the AWT EDT is noticeably higher. This is somewhat expected as the JFXPanel is forced to transfer more pixels at higher resolutions however it ties up the AWT EDT which can cause problems with legacy swing features.
Internally the JFXPanel uses a BufferedImage created using the BufferedImage constructor to store the pixels being transferred between JavaFX and Swing.
Changing the JFXPanel to create this BufferedImage using GraphicsConfiguration.createCompatibleImage can result in lower CPU load on the AWT EDT.
Using the example application below which updates the JavaFX scene at 10 Hz the following results were measured on linux.
- JDK7u55 BufferedImage constructor : 45% of one CPU core consumed by EDT
- JDK7u55 createCompatibleImage : 18.5% of one CPU core consumed by EDT
- JDK8u5 BufferedImage constructor : 24% of one CPU core consumed by EDT
- JDK8u5 createCompatibleImage : 10.5% of one CPU core consumed by EDT
The X11 configuration generated by xdpyinfo is as follows:
name of display: :0.0
version number: 11.0
vendor string: Red Hat, Inc.
vendor release number: 11004000
maximum request size: 16777212 bytes
motion buffer size: 256
bitmap unit, bit order, padding: 32, LSBFirst, 32
image byte order: LSBFirst
number of supported pixmap formats: 7
supported pixmap formats:
depth 1, bits_per_pixel 1, scanline_pad 32
depth 4, bits_per_pixel 8, scanline_pad 32
depth 8, bits_per_pixel 8, scanline_pad 32
depth 15, bits_per_pixel 16, scanline_pad 32
depth 16, bits_per_pixel 16, scanline_pad 32
depth 24, bits_per_pixel 32, scanline_pad 32
depth 32, bits_per_pixel 32, scanline_pad 32
keycode range: minimum 8, maximum 255
focus: PointerRoot
number of extensions: 28
BIG-REQUESTS
Composite
DAMAGE
DOUBLE-BUFFER
DPMS
DRI2
GLX
Generic Event Extension
MIT-SCREEN-SAVER
MIT-SHM
NV-CONTROL
NV-GLX
RANDR
RECORD
RENDER
SHAPE
SYNC
X-Resource
XC-MISC
XFIXES
XFree86-DGA
XFree86-VidModeExtension
XINERAMA
XINERAMA
XInputExtension
XKEYBOARD
XTEST
XVideo
default screen number: 0
number of screens: 1
screen #0:
print screen: no
dimensions: 2560x1440 pixels (602x341 millimeters)
resolution: 108x107 dots per inch
depths (7): 24, 1, 4, 8, 15, 16, 32
root window id: 0x2f2
depth of root window: 24 planes
number of colormaps: minimum 1, maximum 1
default colormap: 0x20
default number of colormap cells: 256
preallocated pixels: black 0, white 16777215
options: backing-store YES, save-unders NO
largest cursor: 256x256
current input event mask: 0x0
number of visuals: 276
default visual id: 0x21
visual:
visual id: 0x21
class: TrueColor
depth: 24 planes
available colormap entries: 256 per subfield
red, green, blue masks: 0xff0000, 0xff00, 0xff
significant bits in color specification: 14 bits
visual:
visual id: 0x22
class: DirectColor
depth: 24 planes
available colormap entries: 256 per subfield
red, green, blue masks: 0xff0000, 0xff00, 0xff
significant bits in color specification: 14 bits
.....
The following sample application updates a full screen JFXPanel at 10 Hz and was used to produce the figures above:
import java.awt.HeadlessException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javafx.animation.AnimationTimer;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javax.swing.JFrame;
public class JFXPanelTest extends JFrame {
private Label timeLabel;
public JFXPanelTest() throws HeadlessException {
super("JFXPanel Test");
setUndecorated(true);
setExtendedState(JFrame.MAXIMIZED_BOTH);
final JFXPanel fxPanel = new JFXPanel();
add(fxPanel);
Platform.runLater(new Runnable() {
@Override
public void run() {
fxPanel.setScene(buildScene());
}
});
}
private Scene buildScene() {
BorderPane fxContent = new BorderPane();
timeLabel = new Label();
fxContent.centerProperty().set(timeLabel);
ClockTimer clockTimer = new ClockTimer();
clockTimer.start();
return new Scene(fxContent);
}
public static void main(String[] args) {
JFXPanelTest fxPanelTest = new JFXPanelTest();
fxPanelTest.setDefaultCloseOperation(EXIT_ON_CLOSE);
fxPanelTest.setVisible(true);
}
private class ClockTimer extends AnimationTimer {
private SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss.S");
private String previousTime;
@Override
public void handle(long arg0) {
String currentTime = dateFormat.format(new Date());
// truncate to tenths of a second
currentTime = currentTime.substring(0, currentTime.length() - 2);
if (!currentTime.equals(previousTime)) {
timeLabel.setText(currentTime);
previousTime = currentTime;
}
}
}
}
When the application is run on high resolution screens (EG 2560x1440) the CPU load on the AWT EDT is noticeably higher. This is somewhat expected as the JFXPanel is forced to transfer more pixels at higher resolutions however it ties up the AWT EDT which can cause problems with legacy swing features.
Internally the JFXPanel uses a BufferedImage created using the BufferedImage constructor to store the pixels being transferred between JavaFX and Swing.
Changing the JFXPanel to create this BufferedImage using GraphicsConfiguration.createCompatibleImage can result in lower CPU load on the AWT EDT.
Using the example application below which updates the JavaFX scene at 10 Hz the following results were measured on linux.
- JDK7u55 BufferedImage constructor : 45% of one CPU core consumed by EDT
- JDK7u55 createCompatibleImage : 18.5% of one CPU core consumed by EDT
- JDK8u5 BufferedImage constructor : 24% of one CPU core consumed by EDT
- JDK8u5 createCompatibleImage : 10.5% of one CPU core consumed by EDT
The X11 configuration generated by xdpyinfo is as follows:
name of display: :0.0
version number: 11.0
vendor string: Red Hat, Inc.
vendor release number: 11004000
maximum request size: 16777212 bytes
motion buffer size: 256
bitmap unit, bit order, padding: 32, LSBFirst, 32
image byte order: LSBFirst
number of supported pixmap formats: 7
supported pixmap formats:
depth 1, bits_per_pixel 1, scanline_pad 32
depth 4, bits_per_pixel 8, scanline_pad 32
depth 8, bits_per_pixel 8, scanline_pad 32
depth 15, bits_per_pixel 16, scanline_pad 32
depth 16, bits_per_pixel 16, scanline_pad 32
depth 24, bits_per_pixel 32, scanline_pad 32
depth 32, bits_per_pixel 32, scanline_pad 32
keycode range: minimum 8, maximum 255
focus: PointerRoot
number of extensions: 28
BIG-REQUESTS
Composite
DAMAGE
DOUBLE-BUFFER
DPMS
DRI2
GLX
Generic Event Extension
MIT-SCREEN-SAVER
MIT-SHM
NV-CONTROL
NV-GLX
RANDR
RECORD
RENDER
SHAPE
SYNC
X-Resource
XC-MISC
XFIXES
XFree86-DGA
XFree86-VidModeExtension
XINERAMA
XINERAMA
XInputExtension
XKEYBOARD
XTEST
XVideo
default screen number: 0
number of screens: 1
screen #0:
print screen: no
dimensions: 2560x1440 pixels (602x341 millimeters)
resolution: 108x107 dots per inch
depths (7): 24, 1, 4, 8, 15, 16, 32
root window id: 0x2f2
depth of root window: 24 planes
number of colormaps: minimum 1, maximum 1
default colormap: 0x20
default number of colormap cells: 256
preallocated pixels: black 0, white 16777215
options: backing-store YES, save-unders NO
largest cursor: 256x256
current input event mask: 0x0
number of visuals: 276
default visual id: 0x21
visual:
visual id: 0x21
class: TrueColor
depth: 24 planes
available colormap entries: 256 per subfield
red, green, blue masks: 0xff0000, 0xff00, 0xff
significant bits in color specification: 14 bits
visual:
visual id: 0x22
class: DirectColor
depth: 24 planes
available colormap entries: 256 per subfield
red, green, blue masks: 0xff0000, 0xff00, 0xff
significant bits in color specification: 14 bits
.....
The following sample application updates a full screen JFXPanel at 10 Hz and was used to produce the figures above:
import java.awt.HeadlessException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javafx.animation.AnimationTimer;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javax.swing.JFrame;
public class JFXPanelTest extends JFrame {
private Label timeLabel;
public JFXPanelTest() throws HeadlessException {
super("JFXPanel Test");
setUndecorated(true);
setExtendedState(JFrame.MAXIMIZED_BOTH);
final JFXPanel fxPanel = new JFXPanel();
add(fxPanel);
Platform.runLater(new Runnable() {
@Override
public void run() {
fxPanel.setScene(buildScene());
}
});
}
private Scene buildScene() {
BorderPane fxContent = new BorderPane();
timeLabel = new Label();
fxContent.centerProperty().set(timeLabel);
ClockTimer clockTimer = new ClockTimer();
clockTimer.start();
return new Scene(fxContent);
}
public static void main(String[] args) {
JFXPanelTest fxPanelTest = new JFXPanelTest();
fxPanelTest.setDefaultCloseOperation(EXIT_ON_CLOSE);
fxPanelTest.setVisible(true);
}
private class ClockTimer extends AnimationTimer {
private SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss.S");
private String previousTime;
@Override
public void handle(long arg0) {
String currentTime = dateFormat.format(new Date());
// truncate to tenths of a second
currentTime = currentTime.substring(0, currentTime.length() - 2);
if (!currentTime.equals(previousTime)) {
timeLabel.setText(currentTime);
previousTime = currentTime;
}
}
}
}
- duplicates
-
JDK-8088247 [JFXPanel, Mac Intel Iris Pro GPU] JDialog with JavaFX scene has major performance problem on Mac PowerBook w/retina display
- Resolved