xwayland: Create duplicate TrueColor GLXFBConfigs for Composite

Similar to what is done in Xorg. Not doing this prevented apps from
using GLX with a Composite visual, e.g. Firefox WebRender or Chromium.

v2:
* Fix inverted direct_color test, fixes Chromium as well.
* Drop Composite extension guards, since other Xwayland code calls
  compRedirectWindow/compUnredirectWindow unconditionally anyway.

Closes: https://gitlab.freedesktop.org/xorg/xserver/issues/921
Fixes: 8469241592 "xwayland: Add EGL-backed GLX provider"
Reviewed-by: Adam Jackson <ajax@redhat.com> # v1
This commit is contained in:
Michel Dänzer 2019-12-17 18:39:17 +01:00 committed by Michel Dänzer
parent 02e7a497ce
commit 846e81ecb8

View File

@ -144,7 +144,7 @@ egl_create_glx_drawable(ClientPtr client, __GLXscreen *screen,
static struct egl_config * static struct egl_config *
translate_eglconfig(struct egl_screen *screen, EGLConfig hc, translate_eglconfig(struct egl_screen *screen, EGLConfig hc,
struct egl_config *chain, Bool direct_color, struct egl_config *chain, Bool direct_color,
Bool double_buffer) Bool double_buffer, Bool duplicate_for_composite)
{ {
EGLint value; EGLint value;
struct egl_config *c = calloc(1, sizeof *c); struct egl_config *c = calloc(1, sizeof *c);
@ -280,6 +280,28 @@ translate_eglconfig(struct egl_screen *screen, EGLConfig hc,
} }
} }
/*
* Here we decide which fbconfigs will be duplicated for compositing.
* fgbconfigs marked with duplicatedForComp will be reserved for
* compositing visuals.
* It might look strange to do this decision this late when translation
* from an EGLConfig is already done, but using the EGLConfig
* accessor functions becomes worse both with respect to code complexity
* and CPU usage.
*/
if (duplicate_for_composite &&
(c->base.renderType == GLX_RGBA_FLOAT_BIT_ARB ||
c->base.rgbBits != 32 ||
c->base.redBits != 8 ||
c->base.greenBits != 8 ||
c->base.blueBits != 8 ||
c->base.visualRating != GLX_NONE ||
c->base.sampleBuffers != 0)) {
free(c);
return chain;
}
c->base.duplicatedForComp = duplicate_for_composite;
c->base.next = chain ? &chain->base : NULL; c->base.next = chain ? &chain->base : NULL;
return c; return c;
} }
@ -290,7 +312,6 @@ egl_mirror_configs(ScreenPtr pScreen, struct egl_screen *screen)
int i, j, k, nconfigs; int i, j, k, nconfigs;
struct egl_config *c = NULL; struct egl_config *c = NULL;
EGLConfig *host_configs = NULL; EGLConfig *host_configs = NULL;
Bool offon[] = { FALSE, TRUE };
eglGetConfigs(screen->display, NULL, 0, &nconfigs); eglGetConfigs(screen->display, NULL, 0, &nconfigs);
if (!(host_configs = calloc(nconfigs, sizeof *host_configs))) if (!(host_configs = calloc(nconfigs, sizeof *host_configs)))
@ -302,12 +323,12 @@ egl_mirror_configs(ScreenPtr pScreen, struct egl_screen *screen)
* ->next chain easier. * ->next chain easier.
*/ */
for (i = nconfigs - 1; i > 0; i--) for (i = nconfigs - 1; i > 0; i--)
for (j = 0; j < 2; j++) /* direct_color */ for (j = 0; j < 3; j++) /* direct_color */
for (k = 0; k < 2; k++) /* double_buffer */ for (k = 0; k < 2; k++) /* double_buffer */
c = translate_eglconfig(screen, host_configs[i], c, c = translate_eglconfig(screen, host_configs[i], c,
/* direct_color */ offon[j], /* direct_color */ j == 1,
/* double_buffer */ offon[k] /* double_buffer */ k > 0,
); /* duplicate_for_composite */ j == 0);
screen->configs = host_configs; screen->configs = host_configs;
return c ? &c->base : NULL; return c ? &c->base : NULL;