【问题标题】:Why is eglMakeCurrent() failing with EGL_BAD_MATCH?为什么 eglMakeCurrent() 因 EGL_BAD_MATCH 而失败?
【发布时间】:2012-12-27 23:48:08
【问题描述】:

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

我的代码在 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。

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

【问题讨论】:

  • 我注意到有时从 Galaxy S2 调用 eglMakeCurrent 时会得到 EGL_BAD_MATCH。我相信我已经将错误条件缩小到a)在与当前线程不同的线程上创建上下文,或者b)在第二个线程上使上下文成为当前线程而不将其从第一个线程中释放出来。
  • 查看解决方案标记答案上的 cmets

标签: android c++ opengl-es


【解决方案1】:

啊,我实际上知道一些事情。 ;) [花费了 5 年中最好的部分来研究各种 EGL 实施]。

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

【讨论】:

  • 问题是,makeCurrent() 适用于所有手机上的主要上下文,但不适用于其他两部手机上的第二个/共享上下文。但是,我发现一个帖子也暗示了类似你所说的内容:stackoverflow.com/questions/7523597/… - 我可能会得到一个不同于我为 surface 请求的配置,但随后创建像素缓冲区requested 配置而不是 returned 配置,这可能是批量匹配的原因。
  • 是的,完全有可能有一个设置可以在一部、两部、五部或 16 部手机上运行,​​但在另外一两部手机上失败。我曾经负责为特定型号的硬件测试 EGL 驱动程序,该硬件使用与我们可用的其他硬件不同的 EGL 配置集。因此,每当向测试套件引入新测试时,它几乎肯定会在我的硬件上崩溃,但在所有其他硬件上都可以工作。然后面临的挑战是为所有平台上的工作找到一个“良好的折衷方案”——或者添加一些代码来处理“如果我们有 HW X,就这样做,否则就那样做”。
  • 我尝试枚举所有配置,这导致了两个发现。首先,几乎所有支持 EGL_WINDOW_BIT 的显示配置也支持 EGL_PBUFFER_BIT,这使得创建两个单独的配置完全没有意义。第二件事是 eglChooseConfig 似乎无法在所有 android 设备/版本上正常工作。这可能是设计使然,因为这发生在一个不支持 GPU 的模拟器上,但我得到的配置甚至不符合我输入的规范。所以我编写了自己的 eglChooseConfig,并使用相同的配置两个表面,现在一切正常。
  • @bitwise 你能分享一下 eglChooseConfig 的实现吗?
  • @Jerikc 我已经很长时间没有使用这个代码了,所以我不能保证它会满足你的需要,更不用说工作了,但是这里是 :) - ideone.com/etNRSW
【解决方案2】:

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

【讨论】:

  • 是的,我知道,但由于某种原因,这个错误发生在我身上,并且接受的答案对我的情况没有帮助。然后我解决了它并在这里发布。因此,如果其他人遇到此类错误,他们可能会发现它很有用。
【解决方案3】:

确保您在传递给eglChooseConfig() 调用的属性中为EGL_SURFACE_TYPE 设置了EGL_PBUFFER_BIT。这对我有用

【讨论】:

    猜你喜欢
    • 2012-09-08
    • 2012-04-06
    • 1970-01-01
    • 2013-09-24
    • 2011-07-23
    • 1970-01-01
    • 1970-01-01
    • 2015-12-19
    • 2013-04-08
    相关资源
    最近更新 更多