Slow JavaFx animation performance, consuming my entire processor

I wrote the following demo program. Four HBox (s) are added to the root (group), each containing one node text. The first and last animated with a timeline to swap. All HBox have the same css style.

The result is a very small arithmetic of frames per second. I have a dual core E7400 2.8Ghz Cpu. One core was used 100%. I expected the calculations to be done on the GPU. After removing most of the css (especially the shadow effect), the animation became smoother. Is there something I can do to keep the visual effects while I have the best performance? Is it bad practice to use css to decorate nodes to be animated?

I also used -Dprism.verbose = true to check if hardware acceleration is enabled. Everything looks ok

Prism pipeline init order: d3d sw Using platform text rasterizer Using native-based Pisces 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.d3d.D3DPipeline Loading D3D native library ... succeeded. D3DPipelineManager: Created D3D9 device Direct3D initialization succeeded (X) Got class = class com.sun.prism.d3d.D3DPipeline Initialized prism pipeline: com.sun.prism.d3d.D3DPipeline Maximum supported texture size: 8192 Maximum texture size clamped to 4096 OS Information: Windows 7 build 7601 D3D Driver Information: ATI Radeon HD 4800 Series \\.\DISPLAY1 Driver aticfx32.dll, version 8.17.10.1129 Pixel Shader version 3.0 Device : ven_1002, dev_9440, subsys_0502174B Max Multisamples supported: 4 vsync: true vpipe: true Loading Prism common native library ... succeeded. 

and here is the program

 public class Sample extends Application{ public void start(Stage primaryStage) throws Exception { Group root = new Group(); Card card1 = new Card(1); Card card2 = new Card(2); Card card3 = new Card(3); Card card4 = new Card(3); card1.relocate(100, 200); card2.relocate(250, 200); card3.relocate(400, 200); card4.relocate(550, 200); root.getChildren().add(card1); root.getChildren().add(card2); root.getChildren().add(card3); root.getChildren().add(card4); primaryStage.setScene(new Scene(root , 800, 600, Color.DARKSLATEGREY)); primaryStage.show(); Timeline tl = new Timeline(new KeyFrame( Duration.millis(500), new KeyValue(card1.layoutXProperty(), card4.getLayoutX()), new KeyValue(card4.layoutXProperty(), card1.getLayoutX()) )); tl.setAutoReverse(true); tl.setCycleCount(Timeline.INDEFINITE); tl.play(); } class Card extends HBox{ private static final String textStyle = "-fx-fill: linear-gradient(BROWN, WHITE);"+ "-fx-font-size: 100px;"+ "-fx-font-weight: BOLD;"+ "-fx-stroke-type: outside;"+ "-fx-stroke-width: 3;"+ "-fx-stroke: linear-gradient(WHITE, BROWN);"+ "-fx-blend-mode: hard-light;"; boolean active; public final Text text; public Card(int number) { setStyle("-fx-effect: dropshadow(one-pass-box, black, 30, 0, 10, 20);"); text = new Text(""+number); text.setStyle(textStyle); getChildren().add(text); } } public static void main(String[] args) { launch(args); } } 
+6
source share
1 answer

I expected the calculations to be done on the GPU.

JavaFX will do a lot of calculations on the GPU, however it does compromise - some calculations are better done on the processor, and JavaFX will use the CPU for these calculations. Your problem is not with GPU or CPU computing. There is too much computation in your problem because the appropriate caching hints were not provided to the JavaFX system.

Is it considered bad practice to use css to decorate nodes to be animated?

Inline css styles is a bad practice in general - put css in your stylesheet. Using CSS for animated nodes is great for most use cases.

Indeed, setting setCache (true) and setCacheHint (CacheHint.SPEED) improved the animation, but it still lags.

The animation does not linger on my machine, but then it is not completely comparable, because the hardware and software on my machine is from 2014, and not from 2008.

Perhaps try updating the graphics drivers and updating JavaFX to the latest development version .

Also, slow down the animation (for example, give it a duration of five seconds, not half a second). It is difficult to visually determine the smoothness of an animation when it moves very fast.

Write a bug report in JavaFX Tracking - JavaFX developers should be able to provide additional information on how to enable detailed JavaFX Performance Tracking, which logs rendering steps in the JavaFX pipeline and measures their performance on a personnel basis (I don't know how to do this )

+11
source

Source: https://habr.com/ru/post/977155/


All Articles