为什么eglMakeCurrent()失败了EGL_BAD_MATCH?

时间:2022-05-28 14:47:49

I am developing for Android using opengl/egl. My app requires a second context for loading textures from a second thread.

我正在使用opengl / egl为Android开发。我的应用程序需要第二个上下文来从第二个线程加载纹理。

My code works fine on android 2.3, but when I try the code on a 4.0.3 android device or emulator, eglMakeCurrent() fails with EGL_BAD_MATCH.

我的代码在android 2.3上工作正常,但是当我在4.0.3 android设备或模拟器上尝试代码时,eglMakeCurrent()在EGL_BAD_MATCH失败。

The initialization of the second context and it's pixel buffer all works fine too, so I am not sure where to begin looking for this error.

第二个上下文和它的像素缓冲区的初始化也都可以正常工作,所以我不知道从哪里开始寻找这个错误。

This is the initialization code:

这是初始化代码:

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());

On my Android 2.3 device(HTC Desire), the above initialization code works perfectly, and I can make the auxContext current, and load textures just fine.

在我的Android 2.3设备(HTC Desire)上,上面的初始化代码工作正常,我可以使auxContext当前,并加载纹理就好了。

BUT, on my android 4.0.3 device(Samsung Nexus S) and my Android 4.1 device (Galaxy Note 2) eglMakeCurrent() fails with EGL_BAD_MATCH after a successful initialization.

但是,在我的android 4.0.3设备(Samsung Nexus S)和我的Android 4.1设备(Galaxy Note 2)上,eglMakeCurrent()在成功初始化后失败了EGL_BAD_MATCH。

Does anyone know why I may be getting this error?

有谁知道为什么我可能会收到此错误?

3 个解决方案

#1


11  

Ah, something I actually know something about. ;) [Having spent best part of 5 years working on various EGL implementations].

啊,我实际上知道一些事情。 ;)[花了5年时间研究各种EGL实现的最佳部分]。

I'm pretty certain your surface is a different format to the actual display surface. I'm not sure exactly WHAT the difference would be, or what you need to change. EGL_DEPTH_SIZE perhaps? You could try enumerating the modes that are available and see if any look "likely". I know, it's a bit of a pain, but I've been there done that a few times in the past - with the difference that I could usually look through the EGL source code and figure out what I'd done wrong... ;)

我很确定你的表面是与实际显示表面不同的格式。我不确定区别是什么,或者你需要改变什么。或许EGL_DEPTH_SIZE?您可以尝试枚举可用的模式,看看是否“可能”。我知道,这有点痛苦,但过去我曾经做过几次 - 不同之处在于我通常可以查看EGL源代码并弄清楚我做错了什么...... ;)

#2


5  

If your getting this error but not dealing with this surface or texture stuff, go to run and type .android go to AVD and your current Emulator delete the user-date file usually on .img file, restart your emulator then test. This works for me, if it happens on while testing on your device, clear the data and restart your app. Cheers for those who find this helpful.

如果你得到这个错误但没有处理这个表面或纹理的东西,去运行并输入.android转到AVD,你当前的Emulator通常在.img文件上删除用户日期文件,重新启动你的模拟器然后测试。这对我有用,如果它在您的设备上进行测试时发生,请清除数据并重新启动您的应用。为那些觉得有帮助的人干杯。

#3


-2  

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;
    }

#1


11  

Ah, something I actually know something about. ;) [Having spent best part of 5 years working on various EGL implementations].

啊,我实际上知道一些事情。 ;)[花了5年时间研究各种EGL实现的最佳部分]。

I'm pretty certain your surface is a different format to the actual display surface. I'm not sure exactly WHAT the difference would be, or what you need to change. EGL_DEPTH_SIZE perhaps? You could try enumerating the modes that are available and see if any look "likely". I know, it's a bit of a pain, but I've been there done that a few times in the past - with the difference that I could usually look through the EGL source code and figure out what I'd done wrong... ;)

我很确定你的表面是与实际显示表面不同的格式。我不确定区别是什么,或者你需要改变什么。或许EGL_DEPTH_SIZE?您可以尝试枚举可用的模式,看看是否“可能”。我知道,这有点痛苦,但过去我曾经做过几次 - 不同之处在于我通常可以查看EGL源代码并弄清楚我做错了什么...... ;)

#2


5  

If your getting this error but not dealing with this surface or texture stuff, go to run and type .android go to AVD and your current Emulator delete the user-date file usually on .img file, restart your emulator then test. This works for me, if it happens on while testing on your device, clear the data and restart your app. Cheers for those who find this helpful.

如果你得到这个错误但没有处理这个表面或纹理的东西,去运行并输入.android转到AVD,你当前的Emulator通常在.img文件上删除用户日期文件,重新启动你的模拟器然后测试。这对我有用,如果它在您的设备上进行测试时发生,请清除数据并重新启动您的应用。为那些觉得有帮助的人干杯。

#3


-2  

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;
    }