mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 01:53:24 +09:00
[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:
@@ -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";
|
||||
}
|
||||
Reference in New Issue
Block a user