cogl/egl: Make surface current before querying buffer age

Unknown since when, we started deferring the eglMakeCurrent for the
current framebuffer till we started painting on it, which means we
are preparing for rendering a view without guarantees that the
framebuffer we will paint to is the current drawing surface for the
EGL context.

A fairly common case where that assumption will break is multimonitor
set ups, in this case we will be preparing to paint to a view while
the current draw surface is that of the previously rendered view's.

Mesa will in this case return EGL_BAD_SURFACE when querying the buffer
age, since the surface is not yet the current draw surface. This
makes us give up on buffer age checks, and paint the whole view. Since
the problem repeats when painting the next view, we are effectively
doing full-screen redraws on all monitors.

Since cogl usually works implicitly, and querying the buffer age is
meaningless if you're not meant to paint on a surface, make the surface
the current draw surface implicitly before querying the buffer age.

This brings us glorious partial invalidations back when several views
had to be repainted.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/906
This commit is contained in:
Carlos Garnacho 2019-10-30 13:36:17 +01:00 committed by Georges Basile Stavracas Neto
parent 6ee7c0f486
commit ee4638ef5c

View File

@ -696,6 +696,7 @@ _cogl_winsys_onscreen_get_buffer_age (CoglOnscreen *onscreen)
CoglRenderer *renderer = context->display->renderer; CoglRenderer *renderer = context->display->renderer;
CoglRendererEGL *egl_renderer = renderer->winsys; CoglRendererEGL *egl_renderer = renderer->winsys;
CoglOnscreenEGL *egl_onscreen = onscreen->winsys; CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
CoglDisplayEGL *egl_display = context->display->winsys;
EGLSurface surface = egl_onscreen->egl_surface; EGLSurface surface = egl_onscreen->egl_surface;
static gboolean warned = FALSE; static gboolean warned = FALSE;
int age; int age;
@ -703,6 +704,11 @@ _cogl_winsys_onscreen_get_buffer_age (CoglOnscreen *onscreen)
if (!(egl_renderer->private_features & COGL_EGL_WINSYS_FEATURE_BUFFER_AGE)) if (!(egl_renderer->private_features & COGL_EGL_WINSYS_FEATURE_BUFFER_AGE))
return 0; return 0;
if (!_cogl_winsys_egl_make_current (context->display,
surface, surface,
egl_display->egl_context))
return 0;
if (!eglQuerySurface (egl_renderer->edpy, surface, EGL_BUFFER_AGE_EXT, &age)) if (!eglQuerySurface (egl_renderer->edpy, surface, EGL_BUFFER_AGE_EXT, &age))
{ {
if (!warned) if (!warned)