为什么EGL_BAD_ALLOC不能使用eglMakeCurrent ?

时间:2022-01-19 15:02:55

I am using OpenGL ES 2.0, and Android NDK r8b. I have a shared context that I use for worker threads. When I try to bind the shared context to a worker thread using eglMakeCurrent, I get the error EGL_BAD_ALLOC.

我使用的是OpenGL ES 2.0和Android NDK r8b。我有一个用于工作线程的共享上下文。当我尝试使用eglMakeCurrent将共享上下文绑定到一个工作线程时,我得到了错误EGL_BAD_ALLOC。

Now what's confusing me is that this code was working perfectly before.. and I am not sure what I have done to break it.. The EGL docs say that this error has to do with resources being unavailable, but I am running the same app which used to work perfectly on this exact same device, and all the textures load fine from the main thread.

让我困惑的是,这段代码以前运行得很好。我不知道我做了什么来打破它。EGL文档说,这个错误与资源不可用有关,但是我运行的是同一个应用程序,它在这个完全相同的设备上运行得非常完美,而且所有的纹理都可以从主线程中加载。


So what could be causing this error?

那么是什么导致了这个错误呢?

This is my egl initialization:

这是我的egl初始化:

bool Initialize(void *displaySurface)
{
    assert(displaySurface);
    ANativeWindow *window = (ANativeWindow*)displaySurface;

    EGLint dummy, format;

    display = eglGetDisplay(EGL_DEFAULT_DISPLAY);

    eglInitialize(display, 0, 0);

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

    const EGLint auxConfigAttribs[] =
    {
        EGL_SURFACE_TYPE, EGL_PBUFFER_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 contextAttribs[] =
    {
        EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE
    };

    EGLint numConfigs;
    EGLConfig config;

//// create main context
    eglChooseConfig(display, configAttribs, &config, 1, &numConfigs);
    Trace("eglChooseConfig: " + GetEglError());

    eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);
    Trace("eglGetConfigAttrib: " + GetEglError());

    ANativeWindow_setBuffersGeometry(window, 0, 0, format);
    Trace("ANativeWindow_setBuffersGeometry: " + GetEglError());

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

    context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
    Trace("eglCreateContext: " + GetEglError());

//// create auxiliary context
    eglChooseConfig(display, auxConfigAttribs, &config, 1, &numConfigs);
    Trace("AUX eglChooseConfig: " + GetEglError());

    auxSurface = eglCreatePbufferSurface(display, config, NULL);
    Trace("AUX eglCreatePbufferSurface: " + GetEglError());

    auxContext = eglCreateContext(display, config, context, contextAttribs);
    Trace("AUX eglCreateContext: " + GetEglError());

//// make main context current
    eglMakeCurrent(display, surface, surface, context);
    Trace("eglMakeCurrent: " + GetError());

    eglQuerySurface(display, surface, EGL_WIDTH, &width);
    eglQuerySurface(display, surface, EGL_HEIGHT, &height);

    SetViewport(width, height);

    EnableDepthBuffer(enableDepthTest);
    EnableBackfaceCulling(enableBackfaceCull);
    SetBackgroundColor(backgroundColor);

    glDisable(GL_DITHER);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    Trace("finished" + GetEglError());

    alive = true;

    return true;
}

edit: I could be wrong, but this error seems to have appeared at the same time the ndk toolchain was updated... but I can't test this theory because I don't have any older copies of the ndk anymore.. So if anyone had a link to where I can get NDK 7c, that would also be helpful.

编辑:我可能是错的,但是这个错误似乎同时出现了ndk工具链的更新……但是我不能测试这个理论,因为我再也没有ndk的旧版本了。所以如果有人有一个链接到我可以得到ndk7c的地方,那也很有帮助。

1 个解决方案

#1


9  

Well, It seems that the problem was that the PBuffer needs to be at least 1x1 pixels for it to work, and the default is 0 for EGL_WIDTH and EGL_HEIGHT.

嗯,问题是PBuffer需要至少1x1像素才能工作,而默认值是EGL_WIDTH和EGL_HEIGHT值为0。

The winning configurtation:

获奖configurtation:

bool Initialize(void *displaySurface)
{
    assert(displaySurface);
    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
    };

//// create main context
    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);
    Trace("eglChooseConfig: " + GetEglError());

    eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);
    Trace("eglGetConfigAttrib: " + GetEglError());

    ANativeWindow_setBuffersGeometry(window, 0, 0, format);
    Trace("ANativeWindow_setBuffersGeometry: " + GetEglError());

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

    context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
    Trace("eglCreateContext: " + GetEglError());

//// create auxiliary context

    const EGLint auxConfigAttribs[] =
    {
        EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
        EGL_BLUE_SIZE, 8,
        EGL_GREEN_SIZE, 8,
        EGL_RED_SIZE, 8,
        EGL_ALPHA_SIZE, 0,
        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);
    Trace("AUX eglChooseConfig: " + GetEglError());

    auxSurface = eglCreatePbufferSurface(display, auxConfig, pbufferAttribs);
    Trace("AUX eglCreatePbufferSurface: " + GetEglError());

    auxContext = eglCreateContext(display, auxConfig, context, contextAttribs);
    Trace("AUX eglCreateContext: " + GetEglError());

//// make main context current
    eglMakeCurrent(display, surface, surface, context);
    Trace("eglMakeCurrent main: " + GetError());

    eglQuerySurface(display, surface, EGL_WIDTH, &width);
    eglQuerySurface(display, surface, EGL_HEIGHT, &height);

    SetViewport(width, height);

    EnableDepthBuffer(enableDepthTest);
    EnableBackfaceCulling(enableBackfaceCull);
    SetBackgroundColor(backgroundColor);

    glDisable(GL_DITHER);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    Trace("finished" + GetEglError());

    alive = true;

    return true;
}

#1


9  

Well, It seems that the problem was that the PBuffer needs to be at least 1x1 pixels for it to work, and the default is 0 for EGL_WIDTH and EGL_HEIGHT.

嗯,问题是PBuffer需要至少1x1像素才能工作,而默认值是EGL_WIDTH和EGL_HEIGHT值为0。

The winning configurtation:

获奖configurtation:

bool Initialize(void *displaySurface)
{
    assert(displaySurface);
    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
    };

//// create main context
    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);
    Trace("eglChooseConfig: " + GetEglError());

    eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);
    Trace("eglGetConfigAttrib: " + GetEglError());

    ANativeWindow_setBuffersGeometry(window, 0, 0, format);
    Trace("ANativeWindow_setBuffersGeometry: " + GetEglError());

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

    context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
    Trace("eglCreateContext: " + GetEglError());

//// create auxiliary context

    const EGLint auxConfigAttribs[] =
    {
        EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
        EGL_BLUE_SIZE, 8,
        EGL_GREEN_SIZE, 8,
        EGL_RED_SIZE, 8,
        EGL_ALPHA_SIZE, 0,
        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);
    Trace("AUX eglChooseConfig: " + GetEglError());

    auxSurface = eglCreatePbufferSurface(display, auxConfig, pbufferAttribs);
    Trace("AUX eglCreatePbufferSurface: " + GetEglError());

    auxContext = eglCreateContext(display, auxConfig, context, contextAttribs);
    Trace("AUX eglCreateContext: " + GetEglError());

//// make main context current
    eglMakeCurrent(display, surface, surface, context);
    Trace("eglMakeCurrent main: " + GetError());

    eglQuerySurface(display, surface, EGL_WIDTH, &width);
    eglQuerySurface(display, surface, EGL_HEIGHT, &height);

    SetViewport(width, height);

    EnableDepthBuffer(enableDepthTest);
    EnableBackfaceCulling(enableBackfaceCull);
    SetBackgroundColor(backgroundColor);

    glDisable(GL_DITHER);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    Trace("finished" + GetEglError());

    alive = true;

    return true;
}