Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is eglMakeCurrent failing with EGL_BAD_ALLOC?

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.

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.


So what could be causing this error?

This is my egl initialization:

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.

like image 437
CuriousGeorge Avatar asked Sep 15 '12 22:09

CuriousGeorge


1 Answers

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.

The winning 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;
}
like image 74
CuriousGeorge Avatar answered Oct 06 '22 02:10

CuriousGeorge