openjdk-jfx icon indicating copy to clipboard operation
openjdk-jfx copied to clipboard

JDK-8181764 : Uncontrolled framerate on Linux machines with integrated GPUs

Open graynk opened this issue 5 years ago • 1 comments

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.

graynk avatar May 28 '19 07:05 graynk

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)

jgneff avatar Jul 08 '19 19:07 jgneff