egl: implement EGL_EXT_present_opaque on wayland

Signed-off-by: Eric Engestrom <eric@engestrom.ch>
Reviewed-by: James Jones <jajones@nvidia.com>
Reviewed-by: Simon Ser <contact@emersion.fr>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12373>
This commit is contained in:
Eric Engestrom 2021-08-02 21:16:34 +01:00 committed by Marge Bot
parent fe46280748
commit 9aee7855d2
6 changed files with 78 additions and 12 deletions

View File

@ -19,3 +19,4 @@ VK_KHR_synchronization2 on Intel
NGG shader based culling is now enabled by default on GFX10.3 on RADV.
VK_KHR_maintenance4 on RADV
VK_KHR_format_feature_flags2 on RADV.
EGL_EXT_present_opaque on wayland

View File

@ -157,7 +157,8 @@ static_assert(ARRAY_SIZE(dri2_wl_visuals) <= EGL_DRI2_MAX_FORMATS,
static int
dri2_wl_visual_idx_from_config(struct dri2_egl_display *dri2_dpy,
const __DRIconfig *config)
const __DRIconfig *config,
bool force_opaque)
{
int shifts[4];
unsigned int sizes[4];
@ -167,14 +168,14 @@ dri2_wl_visual_idx_from_config(struct dri2_egl_display *dri2_dpy,
for (unsigned int i = 0; i < ARRAY_SIZE(dri2_wl_visuals); i++) {
const struct dri2_wl_visual *wl_visual = &dri2_wl_visuals[i];
if (shifts[0] == wl_visual->rgba_shifts[0] &&
shifts[1] == wl_visual->rgba_shifts[1] &&
shifts[2] == wl_visual->rgba_shifts[2] &&
shifts[3] == wl_visual->rgba_shifts[3] &&
sizes[0] == wl_visual->rgba_sizes[0] &&
sizes[1] == wl_visual->rgba_sizes[1] &&
sizes[2] == wl_visual->rgba_sizes[2] &&
sizes[3] == wl_visual->rgba_sizes[3]) {
int cmp_rgb_shifts = memcmp(shifts, wl_visual->rgba_shifts,
3 * sizeof(shifts[0]));
int cmp_rgb_sizes = memcmp(sizes, wl_visual->rgba_sizes,
3 * sizeof(sizes[0]));
if (cmp_rgb_shifts == 0 && cmp_rgb_sizes == 0 &&
wl_visual->rgba_shifts[3] == (force_opaque ? -1 : shifts[3]) &&
wl_visual->rgba_sizes[3] == (force_opaque ? 0 : sizes[3])) {
return i;
}
}
@ -229,7 +230,8 @@ dri2_wl_is_format_supported(void* user_data, uint32_t format)
for (int i = 0; dri2_dpy->driver_configs[i]; i++)
if (j == dri2_wl_visual_idx_from_config(dri2_dpy,
dri2_dpy->driver_configs[i]))
dri2_dpy->driver_configs[i],
false))
return true;
return false;
@ -356,7 +358,42 @@ dri2_wl_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf,
dri2_surf->base.Width = window->width;
dri2_surf->base.Height = window->height;
visual_idx = dri2_wl_visual_idx_from_config(dri2_dpy, config);
#ifndef NDEBUG
/* Enforce that every visual has an opaque variant (requirement to support
* EGL_EXT_present_opaque)
*/
for (unsigned int i = 0; i < ARRAY_SIZE(dri2_wl_visuals); i++) {
const struct dri2_wl_visual *transparent_visual = &dri2_wl_visuals[i];
if (transparent_visual->rgba_sizes[3] == 0) {
continue;
}
bool found_opaque_equivalent = false;
for (unsigned int j = 0; j < ARRAY_SIZE(dri2_wl_visuals); j++) {
const struct dri2_wl_visual *opaque_visual = &dri2_wl_visuals[j];
if (opaque_visual->rgba_sizes[3] != 0) {
continue;
}
int cmp_rgb_shifts = memcmp(transparent_visual->rgba_shifts,
opaque_visual->rgba_shifts,
3 * sizeof(opaque_visual->rgba_shifts[0]));
int cmp_rgb_sizes = memcmp(transparent_visual->rgba_sizes,
opaque_visual->rgba_sizes,
3 * sizeof(opaque_visual->rgba_sizes[0]));
if (cmp_rgb_shifts == 0 && cmp_rgb_sizes == 0) {
found_opaque_equivalent = true;
break;
}
}
assert(found_opaque_equivalent);
}
#endif
visual_idx = dri2_wl_visual_idx_from_config(dri2_dpy, config,
dri2_surf->base.PresentOpaque);
assert(visual_idx != -1);
if (dri2_dpy->wl_dmabuf || dri2_dpy->wl_drm) {
@ -1438,7 +1475,8 @@ dri2_wl_add_configs_for_visuals(_EGLDisplay *disp)
/* No match for config. Try if we can blitImage convert to a visual */
c = dri2_wl_visual_idx_from_config(dri2_dpy,
dri2_dpy->driver_configs[i]);
dri2_dpy->driver_configs[i],
false);
if (c == -1)
continue;
@ -1637,6 +1675,8 @@ dri2_initialize_wayland_drm(_EGLDisplay *disp)
disp->Extensions.EXT_swap_buffers_with_damage = EGL_TRUE;
disp->Extensions.EXT_present_opaque = EGL_TRUE;
/* Fill vtbl last to prevent accidentally calling virtual function during
* initialization.
*/

View File

@ -502,6 +502,7 @@ _eglCreateExtensionsString(_EGLDisplay *disp)
_EGL_CHECK_EXTENSION(EXT_image_dma_buf_import);
_EGL_CHECK_EXTENSION(EXT_image_dma_buf_import_modifiers);
_EGL_CHECK_EXTENSION(EXT_protected_surface);
_EGL_CHECK_EXTENSION(EXT_present_opaque);
_EGL_CHECK_EXTENSION(EXT_surface_CTA861_3_metadata);
_EGL_CHECK_EXTENSION(EXT_surface_SMPTE2086_metadata);
_EGL_CHECK_EXTENSION(EXT_swap_buffers_with_damage);

View File

@ -109,6 +109,7 @@ struct _egl_extensions
EGLBoolean EXT_image_dma_buf_import_modifiers;
EGLBoolean EXT_pixel_format_float;
EGLBoolean EXT_protected_surface;
EGLBoolean EXT_present_opaque;
EGLBoolean EXT_surface_CTA861_3_metadata;
EGLBoolean EXT_surface_SMPTE2086_metadata;
EGLBoolean EXT_swap_buffers_with_damage;

View File

@ -216,6 +216,21 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
surf->ActiveRenderBuffer = val;
}
break;
case EGL_PRESENT_OPAQUE_EXT:
if (!disp->Extensions.EXT_present_opaque) {
err = EGL_BAD_ATTRIBUTE;
break;
}
if (type != EGL_WINDOW_BIT) {
err = EGL_BAD_ATTRIBUTE;
break;
}
if (val != EGL_TRUE && val != EGL_FALSE) {
err = EGL_BAD_PARAMETER;
break;
}
surf->PresentOpaque = val;
break;
case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
if (!disp->Extensions.NV_post_sub_buffer ||
type != EGL_WINDOW_BIT) {
@ -392,6 +407,7 @@ _eglInitSurface(_EGLSurface *surf, _EGLDisplay *disp, EGLint type,
surf->VGColorspace = EGL_VG_COLORSPACE_sRGB;
surf->GLColorspace = EGL_GL_COLORSPACE_LINEAR_KHR;
surf->ProtectedContent = EGL_FALSE;
surf->PresentOpaque = EGL_FALSE;
surf->MipmapLevel = 0;
surf->MultisampleResolve = EGL_MULTISAMPLE_RESOLVE_DEFAULT;
@ -595,6 +611,11 @@ _eglQuerySurface(_EGLDisplay *disp, _EGLSurface *surface,
return _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
*value = surface->ProtectedContent;
break;
case EGL_PRESENT_OPAQUE_EXT:
if (!disp->Extensions.EXT_present_opaque)
return _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
*value = surface->PresentOpaque;
break;
default:
return _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
}

View File

@ -171,6 +171,8 @@ struct _egl_surface
EGLBoolean ProtectedContent;
EGLBoolean PresentOpaque;
struct _egl_hdr_metadata HdrMetadata;
void *NativeSurface;