ADDITIONAL SYSTEM INFORMATION :
Linux, Mesa 24.0
A DESCRIPTION OF THE PROBLEM :
When using GLX on Linux, JavaFX applications should run at a frame rate matching the display refresh rate, since they do not change the default swap interval of 1. Alas, this is not the case, they run at an uncapped framerate resulting in excessive CPU usage.
The reason is that they switch the current GLX drawable every frame between the main window and a scratch pbuffer. With modern GLX implementations, driver-private drawable data is mostly tracked client-side. When using a plain X11 Window as a GLX drawable (as opposed to a GLXWindow) all of this data is freed every time the drawable is made non-current and re-created when it is made current again.
Not only does this have serious negative performance implications, but it also means the driver cannot ensure that presentation of the current frame waits for presentation of the previous frame to complete because drawable state is not retained between frames. This is the reason for the uncapped framerate.
The most straight-forward fix would be for JavaFX to use a GLXWindow as its drawable instead of a plain X11 Window. That way, drawable data will be retained until glXDestroyWindow is called, even if the drawable is made non-current.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run the following JavaFX program...
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class Repro extends Application {
@Override public void start(Stage stage) throws Exception {
stage.setScene(new Scene(new StackPane(new ProgressIndicator()), 500, 500, Color.BLACK));
stage.show();
}
}
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The application should run at a frame rate matching the display refresh rate and should not use an excessive amount of CPU time.
ACTUAL -
The application runs at an uncapped frame rate and uses 100% of a CPU core.
FREQUENCY : always
Linux, Mesa 24.0
A DESCRIPTION OF THE PROBLEM :
When using GLX on Linux, JavaFX applications should run at a frame rate matching the display refresh rate, since they do not change the default swap interval of 1. Alas, this is not the case, they run at an uncapped framerate resulting in excessive CPU usage.
The reason is that they switch the current GLX drawable every frame between the main window and a scratch pbuffer. With modern GLX implementations, driver-private drawable data is mostly tracked client-side. When using a plain X11 Window as a GLX drawable (as opposed to a GLXWindow) all of this data is freed every time the drawable is made non-current and re-created when it is made current again.
Not only does this have serious negative performance implications, but it also means the driver cannot ensure that presentation of the current frame waits for presentation of the previous frame to complete because drawable state is not retained between frames. This is the reason for the uncapped framerate.
The most straight-forward fix would be for JavaFX to use a GLXWindow as its drawable instead of a plain X11 Window. That way, drawable data will be retained until glXDestroyWindow is called, even if the drawable is made non-current.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run the following JavaFX program...
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class Repro extends Application {
@Override public void start(Stage stage) throws Exception {
stage.setScene(new Scene(new StackPane(new ProgressIndicator()), 500, 500, Color.BLACK));
stage.show();
}
}
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The application should run at a frame rate matching the display refresh rate and should not use an excessive amount of CPU time.
ACTUAL -
The application runs at an uncapped frame rate and uses 100% of a CPU core.
FREQUENCY : always