Я столкнулся с очень странной проблемой. Я использую Убунту 20.04. В следующем минимальном примере предполагается настроить контекст EGL (для последующего рендеринга OpenGL).
#include <EGL/egl.h>
#include <stdexcept>
#include <sstream>
#define ASSERT( expression ) \
if( !( expression ) ) \
{ \
std::stringstream details; \
details \
<< "Failed expression: " << #expression << std::endl \
<< "File: " << __FILE__ << std::endl \
<< "Line: " << __LINE__; \
throw std::runtime_error( details.str() ); \
}
static const EGLint CONFIG_ATTRIBS[] =
{
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
EGL_BLUE_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_RED_SIZE, 8,
EGL_DEPTH_SIZE, 8,
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
EGL_NONE
};
static const EGLint PBUFFER_ATTRIBS[] =
{
EGL_WIDTH, 8,
EGL_HEIGHT, 8,
EGL_NONE
};
int main()
{
EGLDisplay eglDpy;
EGLSurface eglSurf;
EGLContext eglCtx;
eglDpy = eglGetDisplay( EGL_DEFAULT_DISPLAY );
EGLint major, minor;
eglInitialize( eglDpy, &major, &minor );
eglBindAPI( EGL_OPENGL_API );
EGLint numConfigs;
EGLConfig eglCfg;
auto cfgResult = eglChooseConfig( eglDpy, CONFIG_ATTRIBS, &eglCfg, 1, &numConfigs );
ASSERT( cfgResult == EGL_TRUE );
eglSurf = eglCreatePbufferSurface( eglDpy, eglCfg, PBUFFER_ATTRIBS );
ASSERT( eglSurf != EGL_NO_SURFACE ); // <-- this assertion fails
eglCtx = eglCreateContext( eglDpy, eglCfg, EGL_NO_CONTEXT, NULL );
ASSERT( eglCtx != EGL_NO_CONTEXT );
}
Я использую командную строку c++ egltest.cpp -lGL -lEGL -o egltest
для компиляции и компоновки. Когда я нахожусь на рабочем столе и после этого запускаю ./egltest
, возникает следующая ошибка:
terminate called after throwing an instance of 'std::runtime_error'
what(): Failed expression: eglSurf != EGL_NO_SURFACE
File: egltest.cpp
Line: 53
Однако это работает, если я использую unset DISPLAY && ./egltest
для запуска. Таким образом, обходным путем было бы использовать unsetenv( "DISPLAY" );
в первой строке моей функции main
(проверено и да, это тоже работает). Но, и это большое но, почему необходимо сбрасывать DISPLAY
?
eglChooseConfig()
возвращает что-то большее нуля дляnumConfigs
перед попыткойeglCreatePbufferSurface()
. - person genpfault   schedule 08.06.2021eglChooseConfig
всегда равно1
, независимо от того, отключил ли яDISPLAY
или нет. Однако, согласно документам, return значение1
указывает на успех, а0
указывает на неудачу, поэтомуeglChooseConfig
в порядке. Я обновил вопрос, чтобы отразить это. - person theV0ID   schedule 08.06.2021num_config
. Он может вернуть успех, но все же установитьnum_config
на ноль (и не обновитьconfigs
), если ни одна конфигурация не соответствуетattrib_list
. - person genpfault   schedule 08.06.2021num_config
устанавливается равным нулю, если установлена переменная средыDISPLAY
. В противном случае устанавливается значение1
. Но почему? - person theV0ID   schedule 08.06.2021EGLDisplay
, предоставленнымeglinfo
(изmesa-utils-extra
в Debian). - person genpfault   schedule 08.06.2021eglGetDisplay(EGL_DEFAULT_DISPLAY)
, похоже, используется платформа GBM, в которой нет конфигураций pbuffer. Принудительное использование X11 черезeglGetPlatformDisplay(EGL_PLATFORM_X11_KHR, EGL_DEFAULT_DISPLAY, nullptr)
показывает некоторые конфигурации pbuffer, соответствующиеeglinfo
. (Обратите внимание, чтоEGL_PLATFORM_X11_KHR
— это перечисление расширений и соответствующее расширение (KHR_platform_x11
а>) следует проверить на наличие поддержки во время выполнения, прежде чем использовать его) - person genpfault   schedule 08.06.2021