Compare commits

...

1 Commits

Author SHA1 Message Date
Powei Feng
277669e5fe egl: allow for ordering display init paths
On certain platforms, initialization by query device is
preferred. On others, initialization by default device is
preferred. To accommodate for either, we use a bool to switch the
ordering if needed. PlatformEGLHeadless is assumed use the query
device path first, and PlatformEGL will still check the
default device/display first.
2026-02-18 11:43:31 -08:00
3 changed files with 52 additions and 10 deletions

View File

@@ -83,6 +83,22 @@ protected:
*/
Driver* createDriver(void* sharedContext, const DriverConfig& driverConfig) override;
/**
* The implementation of *createDriver*.
* @param sharedContext an optional shared context. This is not meaningful with all graphic
* APIs and platforms.
* For EGL platforms, this is an EGLContext.
*
* @param driverConfig specifies driver initialization parameters
*
* @param initFirstbyquery determines the order of initialization. If true, then we'd query by
* eglQueryDevicesEXT first instead of using the default display. Useful
* for headless egl initialization.
* @return nullptr on failure, or a pointer to the newly created driver.
*/
Driver* createDriverBase(void* sharedContext, const DriverConfig& driverConfig,
bool initFirstByQuery);
/**
* This returns zero. This method can be overridden to return something more useful.
* @return zero

View File

@@ -120,17 +120,28 @@ bool PlatformEGL::isOpenGL() const noexcept {
PlatformEGL::ExternalImageEGL::~ExternalImageEGL() = default;
Driver* PlatformEGL::createDriver(void* sharedContext, const DriverConfig& driverConfig) {
return createDriverBase(sharedContext, driverConfig, false /* initFirstByQuery */);
}
Driver* PlatformEGL::createDriverBase(void* sharedContext, const DriverConfig& driverConfig,
bool initFirstByQuery) {
static constexpr int kMaxNumEGLDevices = 32;
EGLint major, minor;
EGLBoolean initialized = false;
PFNEGLQUERYDEVICESEXTPROC const eglQueryDevicesEXT =
PFNEGLQUERYDEVICESEXTPROC(eglGetProcAddress("eglQueryDevicesEXT"));
PFNEGLGETPLATFORMDISPLAYEXTPROC const getPlatformDisplay =
PFNEGLGETPLATFORMDISPLAYEXTPROC(eglGetProcAddress("eglGetPlatformDisplay"));
using InitFunc = std::function<void()>;
InitFunc queryInit = [&]() {
PFNEGLQUERYDEVICESEXTPROC const eglQueryDevicesEXT =
PFNEGLQUERYDEVICESEXTPROC(eglGetProcAddress("eglQueryDevicesEXT"));
PFNEGLGETPLATFORMDISPLAYEXTPROC const getPlatformDisplay =
PFNEGLGETPLATFORMDISPLAYEXTPROC(eglGetProcAddress("eglGetPlatformDisplay"));
if (!eglQueryDevicesEXT || !getPlatformDisplay) {
return;
}
if (eglQueryDevicesEXT != nullptr && getPlatformDisplay != nullptr) {
EGLint numDevices = 0;
EGLDeviceEXT eglDevices[kMaxNumEGLDevices];
if (eglQueryDevicesEXT(kMaxNumEGLDevices, eglDevices, &numDevices)) {
@@ -139,12 +150,27 @@ Driver* PlatformEGL::createDriver(void* sharedContext, const DriverConfig& drive
initialized = eglInitialize(mEGLDisplay, &major, &minor);
}
}
};
InitFunc defaultInit = [&]() {
mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
initialized = eglInitialize(mEGLDisplay, &major, &minor);
};
// The order by which we check for display/device does matter because certain platforms have
// multiple displays/devices. We either return the first queried (and successfully init'd
// display) or just use the default display. Deciding which init path should go first is
// determined by the bool *initFirstByQuery*..
std::array<InitFunc, 2> initFuncs{ defaultInit, queryInit };
if (initFirstByQuery) {
std::swap(initFuncs[0], initFuncs[1]);
}
if (!initialized) {
mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
assert_invariant(mEGLDisplay != EGL_NO_DISPLAY);
initialized = eglInitialize(mEGLDisplay, &major, &minor);
for (auto& initFunc: initFuncs) {
if (initialized) {
break;
}
initFunc();
}
if (UTILS_UNLIKELY(!initialized)) {

View File

@@ -66,7 +66,7 @@ backend::Driver* PlatformEGLHeadless::createDriver(void* sharedContext,
return nullptr;
}
return PlatformEGL::createDriver(sharedContext, driverConfig);
return PlatformEGL::createDriverBase(sharedContext, driverConfig, true /* initFirstByQuery */);
}
} // namespace filament