mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 01:53:24 +09:00
[Fix] (EGL): answer client queries and proc lookups without bringing a session up
This commit is contained in:
@@ -51,7 +51,14 @@ namespace MobileGL::MG_Impl::EGLImpl {
|
||||
// re-initialize after the last eglTerminate tore everything down.
|
||||
// Teardown-ish entry points keep using GetState() and fail benignly
|
||||
// when MobileGL is not initialized.
|
||||
//
|
||||
// Bringing MobileGL up dials its server, and with none reachable that waits out the
|
||||
// bring-up's whole budget. So it is not attempted then: the entry point fails at once, as
|
||||
// it would on any implementation without a display to offer.
|
||||
EGLStateContext* GetStateEnsureInitialized() {
|
||||
if (!MG_State::pEGLContext && !MobileGL::ImplementationAvailable()) {
|
||||
return nullptr;
|
||||
}
|
||||
MobileGL::EnsureInitialized();
|
||||
return GetState();
|
||||
}
|
||||
@@ -852,6 +859,24 @@ namespace MobileGL::MG_Impl::EGLImpl {
|
||||
}
|
||||
|
||||
char const* QueryString(EGLDisplay display, EGLint name) {
|
||||
// THE CLIENT QUERIES BRING NOTHING UP. A dispatcher with several vendors asks every one of
|
||||
// them for its client extensions before it picks one, so answering this must not cost a
|
||||
// session - nor wait for a server that is not there.
|
||||
if (display == EGL_NO_DISPLAY) {
|
||||
switch (name) {
|
||||
case EGL_VENDOR:
|
||||
return "MobileGL";
|
||||
case EGL_VERSION:
|
||||
return "1.5 MobileGL";
|
||||
case EGL_CLIENT_APIS:
|
||||
return "OpenGL OpenGL_ES";
|
||||
case EGL_EXTENSIONS:
|
||||
return kClientExtensionString;
|
||||
default:
|
||||
if (auto* state = MG_State::pEGLContext.get()) state->SetError(EGL_BAD_PARAMETER);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
auto* state = GetStateEnsureInitialized();
|
||||
if (!state) {
|
||||
return nullptr;
|
||||
@@ -1348,7 +1373,11 @@ namespace MobileGL::MG_Impl::EGLImpl {
|
||||
if (!name) {
|
||||
return nullptr;
|
||||
}
|
||||
MobileGL::EnsureInitialized();
|
||||
// The answer is a static table; the bring-up is only the lazy-initialization contract, and
|
||||
// it is skipped when there is no server to bring up against (see GetStateEnsureInitialized).
|
||||
if (MobileGL::ImplementationAvailable()) {
|
||||
MobileGL::EnsureInitialized();
|
||||
}
|
||||
|
||||
MGLOG_D("eglGetProcAddress(%s)", name);
|
||||
void* proc = MG_Impl::GetProcAddress(name);
|
||||
|
||||
@@ -191,6 +191,7 @@ namespace {
|
||||
Int32 vendorDisplay = -1; // 1: the glvnd vendor's getPlatformDisplay did
|
||||
Int32 vendorDevices = -1; // the vendor's eglQueryDevicesEXT count
|
||||
Int32 glxLoaded = -1; // __glx_Main's answer
|
||||
Int32 clientQueries = -1; // 1: client extensions and a proc address answered (no display needed)
|
||||
Int64 elapsedMs = -1; // all of the above, end to end
|
||||
};
|
||||
|
||||
@@ -214,6 +215,11 @@ namespace {
|
||||
__EGLapiExports exports{};
|
||||
__EGLapiImports imports{};
|
||||
const bool vendor = __egl_Main(EGL_VENDOR_ABI_VERSION, &exports, nullptr, &imports) == EGL_TRUE;
|
||||
// What a dispatcher asks every vendor before choosing one: never a session bring-up.
|
||||
r.clientQueries = vendor && imports.getProcAddress("eglQueryString") != nullptr &&
|
||||
EGL::QueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS) != nullptr &&
|
||||
imports.getDispatchAddress("glClear") != nullptr &&
|
||||
EGL::GetProcAddress("eglQueryDmaBufModifiersEXT") != nullptr;
|
||||
r.vendorDisplay = vendor && imports.getPlatformDisplay(EGL_NONE, EGL_DEFAULT_DISPLAY, nullptr) != EGL_NO_DISPLAY;
|
||||
r.getDisplay = EGL::GetDisplay(EGL_DEFAULT_DISPLAY) != EGL_NO_DISPLAY;
|
||||
if (vendor) {
|
||||
@@ -253,6 +259,7 @@ namespace {
|
||||
EXPECT_EQ(r.getDisplay, 0);
|
||||
EXPECT_EQ(r.vendorDevices, 0) << "no device either, and no error (glvnd fails its merge on one)";
|
||||
EXPECT_EQ(r.glxLoaded, 0) << "the GLX vendor must refuse to load so libGLX falls back";
|
||||
EXPECT_EQ(r.clientQueries, 1) << "client queries are answered without a server";
|
||||
EXPECT_GE(r.elapsedMs, 0);
|
||||
EXPECT_LT(r.elapsedMs, 1000) << "declining must not cost the bring-up's 20 s connect budget";
|
||||
std::error_code ec;
|
||||
@@ -313,6 +320,7 @@ namespace {
|
||||
EXPECT_EQ(r.getDisplay, 1);
|
||||
EXPECT_EQ(r.vendorDevices, 1);
|
||||
EXPECT_EQ(r.glxLoaded, 1);
|
||||
EXPECT_EQ(r.clientQueries, 1);
|
||||
|
||||
// A process that asked for software rendering is left to the system's other GL, server or not.
|
||||
const EntryReport software = RunEntryPoints(server.endpoint, logBase, true);
|
||||
|
||||
Reference in New Issue
Block a user