Почему eglMakeCurrent() не работает с EGL_BAD_MATCH?

15 bitwise [2012-12-28 02:48:00]

Я разрабатываю для Android, используя opengl/egl. Моему приложению требуется второй контекст для загрузки текстур из второго потока.

Мой код отлично работает на Android 2.3, но когда я пытаюсь выполнить код на 4.0.3 Android-устройстве или эмуляторе, eglMakeCurrent() терпит неудачу с EGL_BAD_MATCH.

Инициализация второго контекста и его пиксельного буфера тоже отлично работает, поэтому я не уверен, где начать поиск этой ошибки.

Это код инициализации:

ANativeWindow *window = (ANativeWindow*)displaySurface;

EGLint dummy, format;

display = eglGetDisplay(EGL_DEFAULT_DISPLAY);

eglInitialize(display, 0, 0);

EGLint contextAttribs[] =
{
    EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE
};

const EGLint configAttribs[] =
{
    EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
    EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
    EGL_BLUE_SIZE, 8,
    EGL_GREEN_SIZE, 8,
    EGL_RED_SIZE, 8,
    EGL_ALPHA_SIZE, 8,
    EGL_BUFFER_SIZE, 32,
    EGL_DEPTH_SIZE, 24,
    EGL_NONE
};

EGLint numConfigs;
EGLConfig config;

eglChooseConfig(display, configAttribs, &config, 1, &numConfigs);
eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);
ANativeWindow_setBuffersGeometry(window, 0, 0, format);

surface = eglCreateWindowSurface(display, config, window, NULL);
if(surface == NULL)
    Trace("error creating window surface: " + GetEglError());

context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
if(context == NULL)
    Trace("error creating main context: " + GetEglError());

const EGLint auxConfigAttribs[] =
{
    EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
    EGL_BLUE_SIZE, 8,
    EGL_GREEN_SIZE, 8,
    EGL_RED_SIZE, 8,
    EGL_ALPHA_SIZE, 8,
    EGL_DEPTH_SIZE, 0,
    EGL_STENCIL_SIZE, 0,
    EGL_NONE
};

EGLint pbufferAttribs[] =
{
    EGL_WIDTH, 1,
    EGL_HEIGHT, 1,
    EGL_TEXTURE_TARGET, EGL_NO_TEXTURE,
    EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE,
    EGL_NONE
};

EGLint auxNumConfigs;
EGLConfig auxConfig;

eglChooseConfig(display, auxConfigAttribs, &auxConfig, 1, &auxNumConfigs);

auxSurface = eglCreatePbufferSurface(display, auxConfig, pbufferAttribs);
if(auxSurface == NULL)
    Trace("error creating pbuffer surface: " + GetEglError());

auxContext = eglCreateContext(display, auxConfig, context, contextAttribs);
if(auxSurface == NULL)
    Trace("error creating auxilliary context: " + GetEglError());

if(!eglMakeCurrent(display, surface, surface, context))
    Trace("could not make main context current: " + GetEglError());

На моем устройстве Android 2.3 (HTC Desire) приведенный выше код инициализации работает отлично, и я могу сделать поток auxContext текущим и загрузить текстуры просто отлично.

НО, на моем устройстве Android 4.0.3 (Samsung Nexus S) и моем устройстве Android 4.1 (Galaxy Note 2) eglMakeCurrent() завершил с ошибкой EGL_BAD_MATCH после успешной инициализации.

Кто-нибудь знает, почему я могу получить эту ошибку?

c++ android opengl-es


3 ответа


11 Решение Mats Petersson [2012-12-28 03:04:00]

А, кое-что, о чем я действительно что-то знаю.;) [Проведя большую часть 5 лет работы над различными реализациями EGL].

Я уверен, что ваш surface - это другой формат для реальной поверхности дисплея. Я не уверен точно, в чем разница, или что вам нужно изменить. Возможно, EGL_DEPTH_SIZE? Вы можете попробовать перечислить доступные режимы и посмотреть, есть ли какой-либо взгляд "вероятно". Я знаю, это немного боль, но я уже там делал это несколько раз в прошлом - с той разницей, что я обычно мог просматривать исходный код EGL и выяснять, что я сделал неправильно...;)


5 ralphgabb [2014-08-28 11:25:00]

Если вы получаете эту ошибку, но не имеете дело с этой поверхностью или материалом текстуры, перейдите к запуску и введите .android перейдите в AVD, и ваш текущий эмулятор удалит файл с именем пользователя, обычно на .img файле, затем перезапустите ваш эмулятор, затем проверьте. Это работает для меня, если это происходит при тестировании на вашем устройстве, очистите данные и перезапустите приложение. Приветствия для тех, кто считает это полезным.


-2 Jesse Stone [2015-03-22 02:32:00]

int config_attrs[] =
    {
        EGL_RED_SIZE, 8,

EGL_GREEN_SIZE, 8,

        EGL_BLUE_SIZE, 8,

        EGL_ALPHA_SIZE, 8,

        EGL_BUFFER_SIZE, 16,

        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,

        EGL_DEPTH_SIZE, 16,

        EGL_STENCIL_SIZE, 8,

        EGL_SAMPLE_BUFFERS, 0,

        EGL_SAMPLES, 0,
#ifdef _IRR_COMPILE_WITH_OGLES1_    
        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
#else
        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
#endif
        EGL_NONE, 0
    };

    int context_attrs[] = 
    {
#ifdef _IRR_COMPILE_WITH_OGLES1_        
        EGL_CONTEXT_CLIENT_VERSION, 1,
#else
        EGL_CONTEXT_CLIENT_VERSION, 2,
#endif
        EGL_NONE, 0
    };

/////
//ogles1 and ogles2 use different libEGL.dll,  make sure 

s_egl_display = eglGetDisplay ( g_hDC );

    if ( s_egl_display == EGL_NO_DISPLAY )
    {
        return;
    }

    if ( !eglInitialize ( s_egl_display, &major, &minor ) )
    {
        return;
    }

    if ( !eglChooseConfig ( s_egl_display, config_attrs, &g_egl_config, 1, &configs ) || ( configs != 1 ) )
    {
        return;
    }

    s_egl_surface = eglCreateWindowSurface ( s_egl_display, g_egl_config, g_hWnd, 0 );
    if ( eglGetError() != EGL_SUCCESS )
    {
        return;
    }

    eRet = eglBindAPI( EGL_OPENGL_ES_API );

    s_egl_context = eglCreateContext ( s_egl_display, g_egl_config, EGL_NO_CONTEXT, context_attrs );
    if ( eglGetError() != EGL_SUCCESS )
    {
        return;
    }

    eglMakeCurrent ( s_egl_display, s_egl_surface, s_egl_surface, s_egl_context );
    if ( eglGetError() != EGL_SUCCESS )
    {
        return;
    }