4

So I noticed something about the framerate / smoothness of my animation. The Animation is somewhat choppy. However, after doing soing testing I noticed that it becomes smooth again as soon as I trigger a resize event, be it only 0.1 px. I have the newest Java installed.

I cant work with vsync unless its opengl and it seems javafx is using a triple bugger or something. Either way the performance is really bad. My windows machine is pretty good and on the newest version.

So after my the call of the show() function I added:

Window.setWidth(Window.getWidth() + 0.1)

Problem was solved but of course I want to know what is going on under the hood and how to I truly solve this without resorting to such primitive hacks?

JavaFX Canvas Double Buffering

My code is below:

import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.util.Duration;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.scene.control.Button;

public class Gui extends Application{

    Stage Window;

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {

        Window = primaryStage;
        Window.setTitle("Gui Tester");

        Group root = new Group();
        Rectangle box = new Rectangle(0, 0, 50,50);
        box.setFill(Color.GREEN);
        KeyValue x = new KeyValue(box.xProperty(), 900);
        KeyFrame keyFrame = new KeyFrame(Duration.millis(3000), x);
        Timeline timeline = new Timeline();
        timeline.setCycleCount(Timeline.INDEFINITE);
        timeline.setAutoReverse(true);
        timeline.getKeyFrames().add(keyFrame);
        timeline.play();
        root.getChildren().add(box);

        GridPane grid = new GridPane();
        grid.setVgap(8);

        root.getChildren().add(grid);

        Button newGame = new Button("START NEW GAME");

        GridPane.setConstraints(newGame, 1, 1);

        Button continueGame = new Button("CONTINUE");
        GridPane.setConstraints(continueGame, 1, 2);

        grid.getChildren().addAll(newGame, continueGame);

        Scene scene = new Scene(root, 1000, 1000);
        scene.getStylesheets().add("tester.css");
        Window.setScene(scene);
        Window.show();
        Window.setWidth(Window.getWidth() + 0.1)
    }
}
Community
  • 1
  • 1
Asperger
  • 3,064
  • 8
  • 52
  • 100
  • For me, the animation is not smooth regardless of the window width hack in Asperger's question (Java 8u66, OS X 10.9.5, 2015 15" MacBook Pro with Nvidia GT 750m). I tried a couple of debugging settings `-Djavafx.pulseLogger=true -Dprism.vsync=false -Dprism.order=sw` and adding a listener to the boxes x property to see if there was a time gap between pulses or a jump in the x position, but neither occurred (i.e. timing and movement deltas were smooth). However, the rectangle movement on the screen was occasionally jumpy and jittery (I don't know why). – jewelsea May 11 '16 at 18:58
  • @jewelsea This is indeed weird. Maybe its not hardware accelerated. Something is definately wrong with this code though because Im just drawing a simple triangle – Asperger May 11 '16 at 19:09
  • It shouldn't be like this and the up votes indicate that perhaps others have experienced the same issue. I have seen similar stuttering behavior in very early JavaFX builds, but from my experience those issues were fixed and I had not seen it replicated in a while. You might want to [file a bug report](http://bugreport.java.com). For the bug report, you don't need to include the code for the GridPane and controls, as the problem replicates without that, you just need the moving rectangle. – jewelsea May 11 '16 at 20:23
  • @jewelsea can you test out this github? it runs smooth here, not sure what he did: https://gist.github.com/james-d/8327842 . Im new to Java so im not entirely sure but he added something that made the bounce animation smooth. – Asperger May 11 '16 at 20:24
  • @jewelsea you might also want to see this: http://svanimpe.be/blog/game-loops-fx.html – Asperger May 11 '16 at 20:27
  • Yes, I've run that before, it animates fine for me without stuttering. I am not sure why a complex animation would have no issues but a simple one would. I don't think there is anything special in either your solution or his. Usually with issues such as this, the issue is in the user code rather than the library, graphics driver or OS system code, but I don't detect any issue with your code from a quick review. – jewelsea May 11 '16 at 20:27
  • @jewelsea but I do believe that this might be due to the so called "animationTimer" – Asperger May 11 '16 at 20:30
  • 2
    Perhaps, seems unlikely though. The JavaFX architecture is based upon a pulse generated by an internal system clock that fires sixty times per second. The animation timer is just a hook to get called whenever the pulse fires. What happens with timelines and transitions is that internally they are triggered and updated every time a pulse occurs (so they are in effect updated at exactly the same frequency as the animation timer is called). From my tests the pulses are firing regularly every 16.66ms and the key value being updated, so no real issue there. – jewelsea May 11 '16 at 20:45
  • @jewelsea pretty unusual then. If it works on both our machines then there must be something in his code. This is extremely weird. I mean you are so right about the fact that he uses a complex animation yet its so much smoother. – Asperger May 11 '16 at 21:28
  • @jewelsea: Does the MacBook slow to save energy? – trashgod May 12 '16 at 03:16
  • Yes, it does significantly slow for energy saving especially in hardware graphics related things, but with my tests it was plugged in to the wall, so that doesn't account for the choppy animation observed in this case. – jewelsea May 12 '16 at 03:46

1 Answers1

1

Tested on Mac OS X 10.11.4, Java 1.8.0_92, NVIDIA GeForce 9400, no energy saving.

Both the example shown, using Timeline, and this example, using PathTransition, start out choppy. Subsequently, they both smooth out after about one auto-reverse cycle. Using the -Xint option, which "Runs the application in interpreted-only mode" as shown here, significantly diminishes the initial stuttering, especially after a second run. Delays due to just-in-time compiler overhead may be exaggerated if the application remains confined to a single core or the animation creates a busy loop that fails to reach a safepoint, as illustrated here.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045