diff options
author | Pekka Paalanen <pekka.paalanen@collabora.com> | 2020-12-08 13:24:23 +0200 |
---|---|---|
committer | Pekka Paalanen <pekka.paalanen@collabora.com> | 2021-02-25 12:47:07 +0200 |
commit | 1e365c8c4c4f0cb8a613ce35953d850d4d9e84be (patch) | |
tree | 14b52a875557f4568eb1a52d6d4b0ddb420306ac | |
parent | b4f91edb5e27610b38607858f2694508a8f1950d (diff) | |
download | weston-1e365c8c4c4f0cb8a613ce35953d850d4d9e84be.tar.gz |
gl-renderer: assume pbuffers preserve contents
For a pbuffer EGLSurface, assume that EGL swap behavior is "preserved"
which means buffer age is always 1 (after the very first
eglSwapBuffers()).
EGL pbuffers are always single-buffered.
Mesa EGL Surfaceless platform does not seem to expose EGL_EXT_buffer_age
that could have told us the same. Hence all repaints to pbuffer surfaces
used to need to repaint the whole output always. This patch makes
repainting only the latest damage possible.
Repainting only the latest damage is required for a future test on
output damage regions: "tests: add output damage test".
Technically, setting buffer_age to 1 is not correct before the very
first eglSwapBuffers(), but to keep the code simpler I chose to rely on
a newly enabled output always having full damage anyway.
Checking that EGL_SWAP_BEHAVIOR is EGL_BUFFER_PRESERVED would do too.
Unfortunately, Mesa seems to return EGL_BUFFER_DESTROYED, so I cannot
fail the headless-backend in that check. Even so, the output damage test
actually succeeds.
See also: https://gitlab.freedesktop.org/mesa/mesa/-/issues/4278
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
-rw-r--r-- | libweston/renderer-gl/gl-renderer.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/libweston/renderer-gl/gl-renderer.c b/libweston/renderer-gl/gl-renderer.c index b1e3c2b2..4e9d54a4 100644 --- a/libweston/renderer-gl/gl-renderer.c +++ b/libweston/renderer-gl/gl-renderer.c @@ -90,6 +90,7 @@ struct gl_output_state { enum gl_border_status border_damage[BUFFER_DAMAGE_COUNT]; struct gl_border_image borders[4]; enum gl_border_status border_status; + bool swap_behavior_is_preserved; struct weston_matrix output_matrix; @@ -1259,6 +1260,8 @@ output_get_damage(struct weston_output *output, weston_log("buffer age query failed.\n"); gl_renderer_print_egl_error_state(); } + } else if (go->swap_behavior_is_preserved) { + buffer_age = 1; } if (buffer_age == 0 || buffer_age - 1 > BUFFER_DAMAGE_COUNT) { @@ -3276,8 +3279,10 @@ gl_renderer_output_pbuffer_create(struct weston_output *output, const struct gl_renderer_pbuffer_options *options) { struct gl_renderer *gr = get_renderer(output->compositor); + struct gl_output_state *go; EGLConfig pbuffer_config; EGLSurface egl_surface; + EGLint value = 0; int ret; EGLint pbuffer_attribs[] = { EGL_WIDTH, options->width, @@ -3303,9 +3308,22 @@ gl_renderer_output_pbuffer_create(struct weston_output *output, return -1; } + eglSurfaceAttrib(gr->egl_display, egl_surface, + EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED); + if (!eglQuerySurface(gr->egl_display, egl_surface, + EGL_SWAP_BEHAVIOR, &value) || + value != EGL_BUFFER_PRESERVED) { + weston_log("Error: pbuffer surface does not support EGL_BUFFER_PRESERVED, got 0x%x." + " Continuing anyway.\n", value); + } + ret = gl_renderer_output_create(output, egl_surface); - if (ret < 0) + if (ret < 0) { eglDestroySurface(gr->egl_display, egl_surface); + } else { + go = get_output_state(output); + go->swap_behavior_is_preserved = true; + } return ret; } |