Android 为什么eglMakeCurrent()与EGL\u匹配失败?

Android 为什么eglMakeCurrent()与EGL\u匹配失败?,android,c++,opengl-es,Android,C++,Opengl Es,我正在使用opengl/egl为Android开发。我的应用程序需要第二个上下文来从第二个线程加载纹理 我的代码在android 2.3上运行良好,但当我在4.0.3 android设备或仿真器上尝试该代码时,eglMakeCurrent()会因EGL_BAD_匹配而失败 第二个上下文的初始化和它的像素缓冲区也都很好,所以我不确定从哪里开始查找这个错误 这是初始化代码: ANativeWindow *window = (ANativeWindow*)displaySurface; EGLint

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

我的代码在android 2.3上运行良好,但当我在4.0.3 android设备或仿真器上尝试该代码时,eglMakeCurrent()会因EGL_BAD_匹配而失败

第二个上下文的初始化和它的像素缓冲区也都很好,所以我不确定从哪里开始查找这个错误

这是初始化代码:

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设备(三星Nexus S)和android 4.1设备(Galaxy Note 2)上,成功初始化后,eglMakeCurrent()与EGL_BAD_匹配失败


有人知道我为什么会犯这个错误吗?

啊,我确实知道一些事情[花了5年的大部分时间致力于各种EGL实现]


我很确定您的
表面
与实际显示表面的格式不同。我不确定到底会有什么不同,或者你需要改变什么。EGL_深度_大小?您可以尝试列举可用的模式,看看是否有“可能”的模式。我知道,这有点痛苦,但我在过去做过几次——不同的是,我通常可以查看EGL源代码,找出我做错了什么…;)

如果您收到此错误但未处理此表面或纹理内容,请转到运行并键入.android
转到AVD和当前仿真器删除用户日期文件(通常在.img文件上),重新启动仿真器,然后进行测试。这对我来说很有效,如果在设备上测试时发生这种情况,请清除数据并重新启动应用程序。为那些认为这很有帮助的人干杯。

确保在传递到
eglChooseConfig()
调用的属性中为
EGL\u SURFACE\u类型设置了
EGL\u PBUFFER\u位。这对我来说是可行的

问题是,makeCurrent()适用于所有手机上的主上下文,但不适用于其他两部手机上的第二个/共享上下文。然而,我发现一篇帖子也暗示了一些类似于你所说的内容:-我可能会得到一个不同于我所要求的surface配置的配置,但随后使用请求的配置而不是返回的配置创建像素缓冲区,这可能是批量匹配的原因。是的,完全可以在一部、两部、五部或16部手机上进行设置,但在另外一两部手机上失败。我曾经负责测试EGL驱动程序,测试使用不同于其他可用硬件的EGL配置的特定型号的硬件。因此,每当一个新的测试被引入到测试套件中时,它几乎肯定会在我的硬件上中断,但会在所有其他硬件上工作。接下来的挑战是为所有平台上的工作找到一个“好的折衷方案”——或者添加一些代码来处理“如果我们有HW X,那么就这样做,否则就那样做”。我尝试列举了所有配置,这导致了两个发现。首先,几乎所有支持EGL_WINDOW_位的显示配置都支持EGL_PBUFFER_位,这使得创建两个单独的配置完全没有意义。第二件事是eglChooseConfig似乎不能在所有android设备/版本上正常工作。这可能是出于设计,因为这发生在一个没有GPU支持的模拟器上,但是我得到的配置甚至不符合我输入的规范。因此,我编写了自己的eglChooseConfig,并对两个曲面使用了相同的配置,现在一切都正常了。@按位您可以分享eglChooseConfig的实现吗?@Jerikc我已经很长时间没有使用此代码了,所以我无法保证它能满足您的需要,更不用说工作了,但在这里:)-我注意到,有时从星系S2调用eglMakeCurrent时,我会得到EGL_BAD_匹配。我相信我已经将错误条件缩小到a)在不同线程上创建上下文,而不是将其设置为当前线程,或者b)在第二个线程上设置上下文,而不将其从第一个线程中释放出来。请参阅解决方案标记答案上的注释是的,我知道,但由于某种原因,这个错误发生在我身上,而被接受的答案对我的情况没有帮助。然后我解决了它并把它贴在这里。因此,如果其他人遇到这种错误,他们可能会发现它很有用。