husker-dev / openglfx

OpenGL implementation for JavaFX
Apache License 2.0
80 stars 10 forks source link

Border flickering on resizing #1

Closed husker-dev closed 2 years ago

husker-dev commented 2 years ago

If the user has a large screen resolution or weak hardware, then flickering appears when the window is resized. It's not very noticeable on FullHD monitors.

(Screenshot captured on 4K monitor) image

husker-dev commented 2 years ago

This problem occurs because of compatibility with all devices, so the rendering algorithm looks like this:

GL frame buffer -> IntBuffer -> PixelBuffer -> WritableImage -> Window surface

The main problem here with the WritableImage - it takes a lot of time to create and show Also ImageView's properties fitWidth and fitHeight can't handle size difference as quickly as needed.


There is a way to avoid unnecessary steps, and turn the algorithm into the following:

GL frame buffer -> Window surface

(An example is in the mojtab23/jfxgl repository)

But the problem is that JavaFX uses different tools to render the image to the window. Direct3D for Windows, OpenGL for Linux and MacOS. Software Java2D is also used if none of the tools are available.

(Maybe I misunderstand the JavaFX rendering system)


So, there is no universal way to render content directly to the surface of a window.

husker-dev commented 2 years ago

In the current version of OpenGLFX flickering is fixed by optimization

lqyaos commented 2 years ago

Hello, I am now using jogl2.4 to implement NewtCanvasJFX. It provides a native window. I feel that this performance is the highest. I want to share with you and ask about the performance of this solution.

https://github.com/tpetrychyn/dockfx-newtcanvasjfx-example

husker-dev commented 2 years ago

Newt windows itself are cool, but mixing it with JavaFX is not the best idea.

I see several problems in using Newt as NewtCanvasJFX:

When I looked into JavaFX's OpenGL implementations, this was the first thing I saw. It is not very bad, but it has some flaws that were critical in my application. So I decided to get rid of them in my OpenGLFX library

Here is 100% NewtCanvasJFX size on windows 1.75 scale:

image

lqyaos commented 2 years ago

I'm a little bit clueless about HiDPI, can I do it by adjusting the width and height? If I don't care about the resize lag, don't I need to consider HiDPI?

husker-dev commented 2 years ago

Yes, you can fix it by multiplying height and width by screen DPI.

Also you need to increase the size by 1px to remove the empty border (I think it has to do with floating-point calculation errors).

image

For example in Kotlin

scene.widthProperty().addListener { _, _, _ ->
    canvas.widthProperty().set(scene.width * scene.window.outputScaleX + 1)
}
scene.heightProperty().addListener { _, _, _ ->
    canvas.heightProperty().set(scene.height * scene.window.outputScaleX + 1)
}

Don't forget to get CURRENT window, not default. User could have two monitors with different DPI

Resizing lag and HiDPI are not related. So, I recommend you to implement this fix anyway for better application support.

lqyaos commented 2 years ago

Yes, it is finally high enough to start business development, thank you for your support