openjdk-jfx
openjdk-jfx copied to clipboard
JDK-8181764 : Uncontrolled framerate on Linux machines with integrated GPUs
I'd like to reopen this bug, since it's still present in JavaFX 11.
The maintainer who was unable to reproduce the issue had an NVIDIA card. I believe the problem lies with integrated cards like Intel HD.
I'm using a laptop with Intel i5-6200U CPU and Intel HD Graphics 520 on Fedora 30 (issue is reproducible 100% of the time both on X.Org and on Wayland). When launching the following program from this StackOverflow question, I get framerates over 1k+. If I run java -Dquantum.multithreaded=false SimpleFrameRateMeter
then the framerate is limited to 60, as it should be. Initially I began investigating the issue when I noticed huge CPU consumption when using FillTransition
in my code even when using ES2 pipeline.
The program:
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class SimpleFrameRateMeter extends Application {
private final long[] frameTimes = new long[100];
private int frameTimeIndex = 0 ;
private boolean arrayFilled = false ;
@Override
public void start(Stage primaryStage) {
Label label = new Label();
AnimationTimer frameRateMeter = new AnimationTimer() {
@Override
public void handle(long now) {
long oldFrameTime = frameTimes[frameTimeIndex] ;
frameTimes[frameTimeIndex] = now ;
frameTimeIndex = (frameTimeIndex + 1) % frameTimes.length ;
if (frameTimeIndex == 0) {
arrayFilled = true ;
}
if (arrayFilled) {
long elapsedNanos = now - oldFrameTime ;
long elapsedNanosPerFrame = elapsedNanos / frameTimes.length ;
double frameRate = 1_000_000_000.0 / elapsedNanosPerFrame ;
label.setText(String.format("Current frame rate: %.3f", frameRate));
}
}
};
frameRateMeter.start();
primaryStage.setScene(new Scene(new StackPane(label), 250, 150));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
My prism.verbose
output:
Prism pipeline init order: es2 sw
Using Double Precision Marlin Rasterizer
Using dirty region optimizations
Not using texture mask for primitives
Not forcing power of 2 sizes for textures
Using hardware CLAMP_TO_ZERO mode
Opting in for HiDPI pixel scaling
Prism pipeline name = com.sun.prism.es2.ES2Pipeline
Loading ES2 native library ... prism_es2
succeeded.
GLFactory using com.sun.prism.es2.X11GLFactory
(X) Got class = class com.sun.prism.es2.ES2Pipeline
Initialized prism pipeline: com.sun.prism.es2.ES2Pipeline
Maximum supported texture size: 16384
Maximum texture size clamped to 4096
Non power of two texture support = true
Maximum number of vertex attributes = 16
Maximum number of uniform vertex components = 16384
Maximum number of uniform fragment components = 16384
Maximum number of varying components = 128
Maximum number of texture units usable in a vertex shader = 32
Maximum number of texture units usable in a fragment shader = 32
Graphics Vendor: Intel Open Source Technology Center
Renderer: Mesa DRI Intel(R) HD Graphics 520 (Skylake GT2)
Version: 3.0 Mesa 19.0.5
vsync: true vpipe: true
ES2ResourceFactory: Prism - createStockShader: FillPgram_Color.frag
ES2ResourceFactory: Prism - createStockShader: Solid_TextureRGB.frag
ES2ResourceFactory: Prism - createStockShader: Solid_TextureFirstPassLCD.frag
ES2ResourceFactory: Prism - createStockShader: Solid_TextureSecondPassLCD.frag
QuantumRenderer: shutdown
java version:
openjdk version "11.0.3-BellSoft" 2019-04-16
LibericaJDK Runtime Environment (build 11.0.3-BellSoft+12)
LibericaJDK 64-Bit Server VM (build 11.0.3-BellSoft+12, mixed mode)
When running on Windows, no such issue is present.
I see the same problem running Ubuntu 16.04.6 LTS on a Dell Precision Tower 3420 workstation with an Intel Xeon Processor E3-1225 v5, which includes the Intel HD Graphics P530 integrated graphics.
Run the JavaFX animation program at jgneff/epd-javafx on a similar system to see the problem. The output of the test program on my workstation is shown below.
Software rendering, 8 frames per second
$ $HOME/opt/jdk-12.0.1/bin/java --add-modules=javafx.graphics \
--module-path=$HOME/lib/javafx-sdk-12.0.1/lib \
-Dprism.order=sw -Djavafx.animation.pulse=8 \
-jar dist/epd-javafx.jar --width=800 --height=600 --pattern=3 --loops=0
Setting PULSE_DURATION to 8 hz
Frame rate: 80 frames in 10.06 s = 7.95 fps (126 ms/frame)
Frame rate: 80 frames in 10.04 s = 7.96 fps (126 ms/frame)
Frame rate: 80 frames in 10.06 s = 7.96 fps (126 ms/frame)
Key pressed: code = 0x51 (Q)
Total rate: 245 frames in 30.67 s = 7.99 fps (125 ms/frame)
Software rendering, 60 frames per second (upper limit)
$ $HOME/opt/jdk-12.0.1/bin/java --add-modules=javafx.graphics \
--module-path=$HOME/lib/javafx-sdk-12.0.1/lib \
-Dprism.order=sw \
-jar dist/epd-javafx.jar --width=800 --height=600 --pattern=3 --loops=0
Frame rate: 80 frames in 1.34 s = 59.63 fps (17 ms/frame)
Frame rate: 80 frames in 1.33 s = 60.21 fps (17 ms/frame)
Frame rate: 80 frames in 1.33 s = 59.95 fps (17 ms/frame)
Frame rate: 80 frames in 1.33 s = 59.96 fps (17 ms/frame)
Key pressed: code = 0x51 (Q)
Total rate: 351 frames in 5.84 s = 60.07 fps (17 ms/frame)
Hardware rendering, average of 228 frames per second (no limit)
$ $HOME/opt/jdk-12.0.1/bin/java --add-modules=javafx.graphics \
--module-path=$HOME/lib/javafx-sdk-12.0.1/lib \
-jar dist/epd-javafx.jar --width=800 --height=600 --pattern=3 --loops=0
Frame rate: 80 frames in 0.37 s = 215.03 fps (5 ms/frame)
Frame rate: 80 frames in 0.33 s = 245.93 fps (4 ms/frame)
Frame rate: 80 frames in 0.34 s = 236.71 fps (4 ms/frame)
Frame rate: 80 frames in 0.24 s = 337.66 fps (3 ms/frame)
Frame rate: 80 frames in 0.30 s = 266.66 fps (4 ms/frame)
Frame rate: 80 frames in 0.36 s = 223.41 fps (4 ms/frame)
Frame rate: 80 frames in 0.38 s = 207.87 fps (5 ms/frame)
Frame rate: 80 frames in 0.42 s = 190.80 fps (5 ms/frame)
Frame rate: 80 frames in 0.42 s = 190.88 fps (5 ms/frame)
Key pressed: code = 0x51 (Q)
Total rate: 724 frames in 3.18 s = 227.92 fps (4 ms/frame)