[Feature] (EGL): the platform and device extensions are one list, spelled once

A vendor string and an eglQueryString answer have to agree, and they are read by two different
parties: the system's libglvnd reads the first to decide which vendor a platform request should be
routed to, and an application reads the second before it decides to make that request at all.  Kept
apart they drift, and the drift has a signature - a library that is loaded, initialized, and never
called, while the caller reports that it found no provider for a function it never reached.

The list gains the device family for the same reason: a compositor asks which devices exist and
reads the DRM node off one before it asks for a display on it, so an implementation that answers
"no devices" is one it cannot use no matter how well the implementation draws.
This commit is contained in:
gold
2026-10-01 12:22:54 -04:00
committed by swung0x48
parent 57781688ce
commit 75f83b20fc
2 changed files with 80 additions and 8 deletions
+5 -8
View File
@@ -7,6 +7,7 @@
// End of Source File Header
#include "EGLImpl.h"
#include "EGLPlatformExtensions.h"
#include "../GetProcAddress.h"
#include <Init.h>
#include <MG_Backend/BackendObjects.h>
@@ -463,14 +464,10 @@ namespace MobileGL::MG_Impl::EGLImpl {
case EGL_CLIENT_APIS:
return "OpenGL OpenGL_ES";
case EGL_EXTENSIONS:
if (display == EGL_NO_DISPLAY) {
return "EGL_EXT_client_extensions "
"EGL_EXT_platform_base "
"EGL_KHR_platform_base "
"EGL_MESA_platform_surfaceless";
}
return "EGL_KHR_create_context "
"EGL_MESA_platform_surfaceless";
// One list, in EGLPlatformExtensions.h, because the vendor string glvnd reads and
// this query an application reads have to agree: an application that does not see the
// platform extension here never asks for a platform display at all.
return display == EGL_NO_DISPLAY ? kClientExtensionString : kDisplayExtensionString;
default:
state->SetError(EGL_BAD_PARAMETER);
return nullptr;
@@ -0,0 +1,75 @@
// MobileGL - MobileGL/MG_Impl/EGLImpl/EGLPlatformExtensions.h
// Copyright (c) 2025-2026 MobileGL-Dev
// Licensed under the GNU Lesser General Public License v3.0:
// https://www.gnu.org/licenses/gpl-3.0.txt
// https://www.gnu.org/licenses/lgpl-3.0.txt
// SPDX-License-Identifier: LGPL-3.0-only
// End of Source File Header
#pragma once
namespace MobileGL::MG_Impl::EGLImpl {
// THE PLATFORMS THIS IMPLEMENTATION SERVES, in the words EGL spells them.
//
// Two callers need exactly the same list, and they disagree if it is written twice:
// eglQueryString(EGL_EXTENSIONS) is what an application reads BEFORE it decides to call
// eglGetPlatformDisplay at all - libepoxy refuses to use eglGetPlatformDisplayEXT unless the
// string names EGL_EXT_platform_base - and the glvnd vendor string is what the system's
// libEGL reads to decide which vendor library a platform request should be routed to. A
// vendor that does not claim the platform is never asked for it, and the caller is told there
// is no provider: the library can be loaded, initialized, and still never called.
//
// GBM is on the list because a compositor asks for its display on the GBM device it owns.
// This side treats that device the way it treats every other native display - the frames come
// from the display host, not from the device - so the claim is exact rather than optimistic.
inline constexpr const char* kDeviceExtensionString =
"EGL_EXT_device_base "
"EGL_EXT_device_enumeration "
"EGL_EXT_device_query "
"EGL_EXT_device_drm "
"EGL_EXT_device_drm_render_node";
inline constexpr const char* kPlatformExtensionString =
"EGL_EXT_platform_base "
"EGL_KHR_platform_base "
"EGL_KHR_platform_gbm "
"EGL_EXT_platform_gbm "
"EGL_MESA_platform_gbm "
"EGL_EXT_platform_device "
"EGL_MESA_platform_surfaceless";
// What a display answers for EGL_EXTENSIONS: the extensions this implementation provides that
// are not platform ones, then the platform list above.
inline constexpr const char* kDisplayExtensionString =
"EGL_KHR_create_context "
"EGL_EXT_device_base "
"EGL_EXT_device_enumeration "
"EGL_EXT_device_query "
"EGL_EXT_device_drm "
"EGL_EXT_device_drm_render_node "
"EGL_EXT_platform_device "
"EGL_EXT_platform_base "
"EGL_KHR_platform_base "
"EGL_KHR_platform_gbm "
"EGL_EXT_platform_gbm "
"EGL_MESA_platform_gbm "
"EGL_MESA_platform_surfaceless";
// ... and what EGL_NO_DISPLAY answers: the same, plus the client-extension marker that tells a
// caller the no-display query is meaningful here.
inline constexpr const char* kClientExtensionString =
"EGL_EXT_client_extensions "
"EGL_KHR_create_context "
"EGL_EXT_device_base "
"EGL_EXT_device_enumeration "
"EGL_EXT_device_query "
"EGL_EXT_device_drm "
"EGL_EXT_device_drm_render_node "
"EGL_EXT_platform_device "
"EGL_EXT_platform_base "
"EGL_KHR_platform_base "
"EGL_KHR_platform_gbm "
"EGL_EXT_platform_gbm "
"EGL_MESA_platform_gbm "
"EGL_MESA_platform_surfaceless";
}