Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2185f8b4 authored by Mathias Agopian's avatar Mathias Agopian
Browse files

Fix GLES context version selection

Explicitly selects an ES 2.0 config first, then an ES 1.x config,
before attempting the fallback path for the emulator.

Bug: 10820214
Change-Id: Ia8cc084c02a0e3de910def024da8a08d02bbd89d
parent c1c05de4
Loading
Loading
Loading
Loading
+17 −7
Original line number Diff line number Diff line
@@ -30,9 +30,25 @@ namespace android {
// ---------------------------------------------------------------------------

RenderEngine* RenderEngine::create(EGLDisplay display, EGLConfig config) {
    EGLint renderableType = 0;
    EGLint contextClientVersion = 0;

    // query the renderable type, setting the EGL_CONTEXT_CLIENT_VERSION accordingly
    if (!eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, &renderableType)) {
        LOG_ALWAYS_FATAL("can't query EGLConfig RENDERABLE_TYPE");
    }

    if (renderableType & EGL_OPENGL_ES2_BIT) {
        contextClientVersion = 2;
    } else if (renderableType & EGL_OPENGL_ES_BIT) {
        contextClientVersion = 1;
    } else {
        LOG_ALWAYS_FATAL("no supported EGL_RENDERABLE_TYPEs");
    }

    // Also create our EGLContext
    EGLint contextAttributes[] = {
            EGL_CONTEXT_CLIENT_VERSION, 2,      // MUST be first
            EGL_CONTEXT_CLIENT_VERSION, contextClientVersion,      // MUST be first
#ifdef EGL_IMG_context_priority
#ifdef HAS_CONTEXT_PRIORITY
#warning "using EGL_IMG_context_priority"
@@ -41,13 +57,7 @@ RenderEngine* RenderEngine::create(EGLDisplay display, EGLConfig config) {
#endif
            EGL_NONE, EGL_NONE
    };

    EGLContext ctxt = eglCreateContext(display, config, NULL, contextAttributes);
    if (ctxt == EGL_NO_CONTEXT) {
        // maybe ES 2.x is not supported
        ALOGW("can't create an ES 2.x context, trying 1.x");
        ctxt = eglCreateContext(display, config, NULL, contextAttributes + 2);
    }

    // if can't create a GL context, we can only abort.
    LOG_ALWAYS_FATAL_IF(ctxt==EGL_NO_CONTEXT, "EGLContext creation failed");
+42 −28
Original line number Diff line number Diff line
@@ -366,43 +366,40 @@ public:
    operator EGLint const* () const { return &mList.keyAt(0).v; }
};

EGLConfig SurfaceFlinger::selectEGLConfig(EGLDisplay display, EGLint nativeVisualId) {
EGLConfig SurfaceFlinger::selectEGLConfig(EGLDisplay display, EGLint nativeVisualId,
    EGLint renderableType) {
    // select our EGLConfig. It must support EGL_RECORDABLE_ANDROID if
    // it is to be used with WIFI displays
    EGLConfig config;
    EGLint dummy;
    status_t err;
    EGLint wantedAttribute;
    EGLint wantedAttributeValue;

    EGLAttributeVector attribs;
    // TODO: enable ES2
    //attribs[EGL_RENDERABLE_TYPE]            = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT;
    attribs[EGL_SURFACE_TYPE]               = EGL_WINDOW_BIT | EGL_PBUFFER_BIT;
    if (renderableType) {
        attribs[EGL_RENDERABLE_TYPE]            = renderableType;
        attribs[EGL_RECORDABLE_ANDROID]         = EGL_TRUE;
        attribs[EGL_SURFACE_TYPE]               = EGL_WINDOW_BIT|EGL_PBUFFER_BIT;
        attribs[EGL_FRAMEBUFFER_TARGET_ANDROID] = EGL_TRUE;
        attribs[EGL_RED_SIZE]                   = 8;
        attribs[EGL_GREEN_SIZE]                 = 8;
        attribs[EGL_BLUE_SIZE]                  = 8;
        wantedAttribute                         = EGL_NONE;
        wantedAttributeValue                    = EGL_NONE;

    err = selectConfigForAttribute(display, attribs, EGL_NONE, EGL_NONE, &config);
    if (!err)
        goto success;
    } else {
        // if no renderable type specified, fallback to a simplified query
        attribs[EGL_RECORDABLE_ANDROID]         = EGL_TRUE;
        wantedAttribute                         = EGL_NATIVE_VISUAL_ID;
        wantedAttributeValue                    = nativeVisualId;
    }

    // this didn't work, probably because we're on the emulator...
    // try a simplified query
    ALOGW("no suitable EGLConfig found, trying a simpler query");
    attribs.remove(EGL_RENDERABLE_TYPE);
    attribs.remove(EGL_FRAMEBUFFER_TARGET_ANDROID);
    attribs.remove(EGL_RECORDABLE_ANDROID);
    attribs.remove(EGL_RED_SIZE);
    attribs.remove(EGL_GREEN_SIZE);
    attribs.remove(EGL_BLUE_SIZE);
    err = selectConfigForAttribute(display, attribs,
            EGL_NATIVE_VISUAL_ID, nativeVisualId, &config);
    err = selectConfigForAttribute(display, attribs, wantedAttribute,
        wantedAttributeValue, &config);
    if (!err)
        goto success;

    // this EGL is too lame for Android
    LOG_ALWAYS_FATAL("no suitable EGLConfig found, giving up");
    return 0;

success:
@@ -427,8 +424,25 @@ void SurfaceFlinger::init() {
    mHwc = new HWComposer(this,
            *static_cast<HWComposer::EventHandler *>(this));

    // initialize the config and context (can't fail)
    mEGLConfig = selectEGLConfig(mEGLDisplay, mHwc->getVisualID());
    // First try to get an ES2 config
    mEGLConfig = selectEGLConfig(mEGLDisplay, mHwc->getVisualID(), EGL_OPENGL_ES2_BIT);

    if (!mEGLConfig) {
        // If ES2 fails, try ES1
        mEGLConfig = selectEGLConfig(mEGLDisplay, mHwc->getVisualID(), EGL_OPENGL_ES_BIT);
    }

    if (!mEGLConfig) {
        // still didn't work, probably because we're on the emulator...
        // try a simplified query
        ALOGW("no suitable EGLConfig found, trying a simpler query");
        mEGLConfig = selectEGLConfig(mEGLDisplay, mHwc->getVisualID(), 0);
    }

    if (!mEGLConfig) {
        // this EGL is too lame for android
        LOG_ALWAYS_FATAL("no suitable EGLConfig found, giving up");
    }

    // print some debugging info
    EGLint r,g,b,a;
+2 −1
Original line number Diff line number Diff line
@@ -317,7 +317,8 @@ private:
     */
    static status_t selectConfigForAttribute(EGLDisplay dpy,
        EGLint const* attrs, EGLint attribute, EGLint value, EGLConfig* outConfig);
    static EGLConfig selectEGLConfig(EGLDisplay disp, EGLint visualId);
    static EGLConfig selectEGLConfig(EGLDisplay disp, EGLint visualId,
		EGLint renderableType);
    size_t getMaxTextureSize() const;
    size_t getMaxViewportDims() const;