问题
I have a simple method which writes pixels to a canvas' GrapicConte2D. A int[]-pixelarray is getting randomized every frame and updated with the PixelWriters setPixels()-Method.
I have a Dual-Monitor-setup, a "regular" screen and a macbook pro retina. When dragging my application frame into my "regular" screen everything works very fine for me. But placing it on my MacBooks Retina Displays it gets really laggy.
I have really no idea what went wrong. I was checking my code a few times, but it seems that I cannot help myself.
I would be very grateful for every advise that could help me.
Thanks
Code:
public class CanvasTest extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
Random random = new Random();
BorderPane root = new BorderPane();
ScrollPane scrollPane = new ScrollPane();
Canvas canvas = new Canvas(1280, 800);
GraphicsContext gc = canvas.getGraphicsContext2D();
PixelWriter writer = gc.getPixelWriter();
PixelFormat format = PixelFormat.getIntArgbInstance();
int[] pixels = new int[(int) (canvas.getWidth() * canvas.getHeight())];
scrollPane.setContent(canvas);
AnimationTimer timer = new AnimationTimer() {
@Override
public void handle(long now) {
for (int i = 0; i < pixels.length; i++) {
pixels[i] = (255 << 24) | random.nextInt(0xffffff);
}
writer.setPixels(0, 0, (int) canvas.getWidth(), (int) canvas.getHeight(),
format, pixels, 0, (int) canvas.getWidth());
}
};
root.setCenter(scrollPane);
primaryStage.setScene(new Scene(root,1280,800));
primaryStage.show();
timer.start();
}
public static void main(String[] args) {
launch(args);
}
}
回答1:
My best guess is that your Retina display has more pixels total and a higher pixel density and therefore more calculations have to be done per frame. If you are not set on using the GraphicsContext2D
, I would look into OpenGL.
If you still want to use the GraphicsContext2D
, I would take less sample of randomness to make it less laggy. Instead of finding a random value for every pixel, you could find a random value for every other pixel, and just set the nearby pixels to that color as well. It would look slightly worse, but it would reduce lag. Again, OpenGL uses GPU rendering and will be much faster.
Try this instead:
for (int y = 0; y < height; y+=2) {
for (int x = 0; x < width; x+=2) {
int i = x + y * width;
screen[i] = (255 << 24) | (random.nextInt(256) << 16) | (random.nextInt(256) << 8) | random.nextInt(256);
screen[i+1] = screen[i]; // The pixel just to the right of the current one
screen[i+width] = screen[i]; // The pixel just below the current one
screen[i+width+1] = screen[i]; // The pixel one to the right and one below this one
}
}
Note: This will only work when the width and height are divisible by 2. That is why in this case, with many pixels, it is much easier to use the GPU instead.
来源:https://stackoverflow.com/questions/36362075/slow-laggy-javafx-performance-on-retina-display