Unverified Commit c72df6cf authored by Denis Bazhenov's avatar Denis Bazhenov Committed by GitHub

Using glFlush() instead of glFinish() (#1037)

We have a situation on a Linux where a significant portion of time spent
in EDT is spent inside a `glFinish()` call.

OS: Linux bazhenov 6.11.0-19-generic #19~24.04.1-Ubuntu SMP
PREEMPT_DYNAMIC Mon Feb 17 11:51:52 UTC 2 x86_64 x86_64 x86_64 GNU/Linux
Distribution: Ubuntu 24.04
GPU: Intel Corporation AlderLake-S GT1 [8086:4680] (rev 0c) (Intel UHD
Graphics 770)
Driver: i915


![screenshot_from_2025-03-24_14-04-41](https://github.com/user-attachments/assets/a4ed84e1-d299-418e-912c-3f32b15bfaaa)

According to the
[documentation](https://registry.khronos.org/OpenGL-Refpages/gl4/html/glFinish.xhtml):

> glFinish does not return until the effects of all previously called GL
commands are complete. Such effects include all changes to GL state, all
changes to connection state, and all changes to the frame buffer
contents.

It effectively means that there is no overlap in work being done on the
CPU and GPU; we only start to prepare a new frame when we finish
rendering the previous one. It makes sense in the context of direct
draw, but AFAIK, Skiko has a swap chain of frame buffers (I assume 2?),
so `glFlush()` should be enough. Probably, we can get away without
`glFinish()`/`glFlush()` at all, because `glSwapBuffers()`, according to
the documentation, is doing `glFlush()`, but I'm not an expert.

Using `SkiaAwtSample`, I can confirm that performance is improved
significantly (in both cases first 3 FPS samples are skipped).

Before change

```
[1039125906] FPS 36 (29-63)
[1039127906] FPS 46 (29-62)
[1039129906] FPS 43 (29-64)
[1039131922] FPS 39 (29-64)
[1039133923] FPS 42 (29-65)
[1039135940] FPS 52 (29-63)
[1039137957] FPS 36 (29-62)
[1039139974] FPS 53 (29-66)
[1039142008] FPS 34 (29-63)
[1039144024] FPS 47 (30-66)
```

After change

```
[1038654097] FPS 60 (46-67)
[1038656097] FPS 60 (57-65)
[1038658114] FPS 60 (47-68)
[1038660114] FPS 60 (41-67)
[1038662114] FPS 60 (51-67)
[1038664115] FPS 60 (47-67)
[1038666115] FPS 60 (51-67)
[1038668115] FPS 60 (51-67)
[1038670127] FPS 60 (42-67)
[1038672132] FPS 60 (48-67)
```
parent 10a91fc9
......@@ -12,6 +12,12 @@ extern "C" {
glFinish();
}
void glFlush(void) {
typedef void (*PROC_glFlush) (void);
static auto glFlush = (PROC_glFlush) GetProcAddress(OpenGL32Library, "glFlush");
glFlush();
}
void glGetIntegerv(GLenum pname, GLint *data) {
typedef void (*PROC_glGetIntegerv) (GLenum pname, GLint *data);
static auto glGetIntegerv = (PROC_glGetIntegerv) GetProcAddress(OpenGL32Library, "glGetIntegerv");
......
......@@ -89,7 +89,7 @@ internal class LinuxOpenGLRedrawer(
it.setSwapInterval(0)
}
it.swapBuffers()
OpenGLApi.instance.glFinish()
OpenGLApi.instance.glFlush()
if (turnOfVsync) {
it.setSwapInterval(swapInterval)
}
......@@ -147,14 +147,14 @@ internal class LinuxOpenGLRedrawer(
drawingSurfaces[redrawer]!!.makeCurrent(redrawer.context)
drawingSurfaces[redrawer]!!.setSwapInterval(0)
drawingSurfaces[redrawer]!!.swapBuffers()
OpenGLApi.instance.glFinish()
OpenGLApi.instance.glFlush()
}
if (vsyncRedrawer != null) {
drawingSurfaces[vsyncRedrawer]!!.makeCurrent(vsyncRedrawer.context)
drawingSurfaces[vsyncRedrawer]!!.setSwapInterval(1)
drawingSurfaces[vsyncRedrawer]!!.swapBuffers()
OpenGLApi.instance.glFinish()
OpenGLApi.instance.glFlush()
}
} finally {
drawingSurfaces.values.forEach(::unlockLinuxDrawingSurface)
......
......@@ -19,6 +19,10 @@ JNIEXPORT void JNICALL Java_org_jetbrains_skiko_OpenGLApi_glFinish(JNIEnv * env,
glFinish();
}
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_OpenGLApi_glFlush(JNIEnv * env, jobject object) {
glFlush();
}
JNIEXPORT jint JNICALL Java_org_jetbrains_skiko_OpenGLApi_glGetIntegerv(JNIEnv * env, jobject object, jint pname) {
GLint data;
glGetIntegerv(pname, &data);
......
......@@ -14,6 +14,7 @@ internal class OpenGLApi private constructor() {
// OpenGL functions
external fun glFinish()
external fun glFlush()
external fun glGetIntegerv(pname: Int): Int
external fun glGetString(value: Int): String?
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment