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

Commit 4c37d088 authored by Jesse Hall's avatar Jesse Hall Committed by Android Git Automerger
Browse files

am 6c7dcfa9: am 662d3134: Merge "Move EGLConfig selection to RenderEngine"

* commit '6c7dcfa9':
  Move EGLConfig selection to RenderEngine
parents 285bfefb 6c7dcfa9
Loading
Loading
Loading
Loading
+168 −3
Original line number Original line Diff line number Diff line
@@ -29,7 +29,9 @@
namespace android {
namespace android {
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------


RenderEngine* RenderEngine::create(EGLDisplay display, EGLConfig config) {
RenderEngine* RenderEngine::create(EGLDisplay display, int hwcFormat) {
    EGLConfig config = chooseEglConfig(display, hwcFormat);

    EGLint renderableType = 0;
    EGLint renderableType = 0;
    EGLint contextClientVersion = 0;
    EGLint contextClientVersion = 0;


@@ -96,7 +98,7 @@ RenderEngine* RenderEngine::create(EGLDisplay display, EGLConfig config) {
        engine = new GLES20RenderEngine();
        engine = new GLES20RenderEngine();
        break;
        break;
    }
    }
    engine->setEGLContext(ctxt);
    engine->setEGLHandles(config, ctxt);


    ALOGI("OpenGL ES informations:");
    ALOGI("OpenGL ES informations:");
    ALOGI("vendor    : %s", extensions.getVendor());
    ALOGI("vendor    : %s", extensions.getVendor());
@@ -118,10 +120,15 @@ RenderEngine::RenderEngine() : mEGLContext(EGL_NO_CONTEXT) {
RenderEngine::~RenderEngine() {
RenderEngine::~RenderEngine() {
}
}


void RenderEngine::setEGLContext(EGLContext ctxt) {
void RenderEngine::setEGLHandles(EGLConfig config, EGLContext ctxt) {
    mEGLConfig = config;
    mEGLContext = ctxt;
    mEGLContext = ctxt;
}
}


EGLContext RenderEngine::getEGLConfig() const {
    return mEGLConfig;
}

EGLContext RenderEngine::getEGLContext() const {
EGLContext RenderEngine::getEGLContext() const {
    return mEGLContext;
    return mEGLContext;
}
}
@@ -234,6 +241,164 @@ status_t RenderEngine::BindImageAsFramebuffer::getStatus() const {
    return mStatus == GL_FRAMEBUFFER_COMPLETE_OES ? NO_ERROR : BAD_VALUE;
    return mStatus == GL_FRAMEBUFFER_COMPLETE_OES ? NO_ERROR : BAD_VALUE;
}
}


// ---------------------------------------------------------------------------

static status_t selectConfigForAttribute(EGLDisplay dpy, EGLint const* attrs,
        EGLint attribute, EGLint wanted, EGLConfig* outConfig) {
    EGLConfig config = NULL;
    EGLint numConfigs = -1, n = 0;
    eglGetConfigs(dpy, NULL, 0, &numConfigs);
    EGLConfig* const configs = new EGLConfig[numConfigs];
    eglChooseConfig(dpy, attrs, configs, numConfigs, &n);

    if (n) {
        if (attribute != EGL_NONE) {
            for (int i=0 ; i<n ; i++) {
                EGLint value = 0;
                eglGetConfigAttrib(dpy, configs[i], attribute, &value);
                if (wanted == value) {
                    *outConfig = configs[i];
                    delete [] configs;
                    return NO_ERROR;
                }
            }
        } else {
            // just pick the first one
            *outConfig = configs[0];
            delete [] configs;
            return NO_ERROR;
        }
    }
    delete [] configs;
    return NAME_NOT_FOUND;
}

class EGLAttributeVector {
    struct Attribute;
    class Adder;
    friend class Adder;
    KeyedVector<Attribute, EGLint> mList;
    struct Attribute {
        Attribute() {};
        Attribute(EGLint v) : v(v) { }
        EGLint v;
        bool operator < (const Attribute& other) const {
            // this places EGL_NONE at the end
            EGLint lhs(v);
            EGLint rhs(other.v);
            if (lhs == EGL_NONE) lhs = 0x7FFFFFFF;
            if (rhs == EGL_NONE) rhs = 0x7FFFFFFF;
            return lhs < rhs;
        }
    };
    class Adder {
        friend class EGLAttributeVector;
        EGLAttributeVector& v;
        EGLint attribute;
        Adder(EGLAttributeVector& v, EGLint attribute)
            : v(v), attribute(attribute) {
        }
    public:
        void operator = (EGLint value) {
            if (attribute != EGL_NONE) {
                v.mList.add(attribute, value);
            }
        }
        operator EGLint () const { return v.mList[attribute]; }
    };
public:
    EGLAttributeVector() {
        mList.add(EGL_NONE, EGL_NONE);
    }
    void remove(EGLint attribute) {
        if (attribute != EGL_NONE) {
            mList.removeItem(attribute);
        }
    }
    Adder operator [] (EGLint attribute) {
        return Adder(*this, attribute);
    }
    EGLint operator [] (EGLint attribute) const {
       return mList[attribute];
    }
    // cast-operator to (EGLint const*)
    operator EGLint const* () const { return &mList.keyAt(0).v; }
};


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

    EGLAttributeVector attribs;
    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;
    } else {
        // if no renderable type specified, fallback to a simplified query
        wantedAttribute                         = EGL_NATIVE_VISUAL_ID;
        wantedAttributeValue                    = format;
    }

    err = selectConfigForAttribute(display, attribs,
            wantedAttribute, wantedAttributeValue, config);
    if (err == NO_ERROR) {
        EGLint caveat;
        if (eglGetConfigAttrib(display, *config, EGL_CONFIG_CAVEAT, &caveat))
            ALOGW_IF(caveat == EGL_SLOW_CONFIG, "EGL_SLOW_CONFIG selected!");
    }

    return err;
}

EGLConfig RenderEngine::chooseEglConfig(EGLDisplay display, int format) {
    status_t err;
    EGLConfig config;

    // First try to get an ES2 config
    err = selectEGLConfig(display, format, EGL_OPENGL_ES2_BIT, &config);
    if (err != NO_ERROR) {
        // If ES2 fails, try ES1
        err = selectEGLConfig(display, format, EGL_OPENGL_ES_BIT, &config);
        if (err != NO_ERROR) {
            // still didn't work, probably because we're on the emulator...
            // try a simplified query
            ALOGW("no suitable EGLConfig found, trying a simpler query");
            err = selectEGLConfig(display, format, 0, &config);
            if (err != NO_ERROR) {
                // 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;
    eglGetConfigAttrib(display, config, EGL_RED_SIZE,   &r);
    eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &g);
    eglGetConfigAttrib(display, config, EGL_BLUE_SIZE,  &b);
    eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &a);
    ALOGI("EGL information:");
    ALOGI("vendor    : %s", eglQueryString(display, EGL_VENDOR));
    ALOGI("version   : %s", eglQueryString(display, EGL_VERSION));
    ALOGI("extensions: %s", eglQueryString(display, EGL_EXTENSIONS));
    ALOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported");
    ALOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, config);

    return config;
}

// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
}; // namespace android
}; // namespace android
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
+6 −2
Original line number Original line Diff line number Diff line
@@ -44,8 +44,9 @@ class RenderEngine {
    };
    };
    static GlesVersion parseGlesVersion(const char* str);
    static GlesVersion parseGlesVersion(const char* str);


    EGLConfig mEGLConfig;
    EGLContext mEGLContext;
    EGLContext mEGLContext;
    void setEGLContext(EGLContext ctxt);
    void setEGLHandles(EGLConfig config, EGLContext ctxt);


    virtual void bindImageAsFramebuffer(EGLImageKHR image, uint32_t* texName, uint32_t* fbName, uint32_t* status) = 0;
    virtual void bindImageAsFramebuffer(EGLImageKHR image, uint32_t* texName, uint32_t* fbName, uint32_t* status) = 0;
    virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName) = 0;
    virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName) = 0;
@@ -55,7 +56,9 @@ protected:
    virtual ~RenderEngine() = 0;
    virtual ~RenderEngine() = 0;


public:
public:
    static RenderEngine* create(EGLDisplay display, EGLConfig config);
    static RenderEngine* create(EGLDisplay display, int hwcFormat);

    static EGLConfig chooseEglConfig(EGLDisplay display, int format);


    // dump the extension strings. always call the base class.
    // dump the extension strings. always call the base class.
    virtual void dump(String8& result);
    virtual void dump(String8& result);
@@ -107,6 +110,7 @@ public:
    virtual size_t getMaxTextureSize() const = 0;
    virtual size_t getMaxTextureSize() const = 0;
    virtual size_t getMaxViewportDims() const = 0;
    virtual size_t getMaxViewportDims() const = 0;


    EGLConfig getEGLConfig() const;
    EGLContext getEGLContext() const;
    EGLContext getEGLContext() const;
};
};


+4 −166
Original line number Original line Diff line number Diff line
@@ -318,128 +318,6 @@ void SurfaceFlinger::deleteTextureAsync(uint32_t texture) {
    postMessageAsync(new MessageDestroyGLTexture(getRenderEngine(), texture));
    postMessageAsync(new MessageDestroyGLTexture(getRenderEngine(), texture));
}
}


status_t SurfaceFlinger::selectConfigForAttribute(
        EGLDisplay dpy,
        EGLint const* attrs,
        EGLint attribute, EGLint wanted,
        EGLConfig* outConfig)
{
    EGLConfig config = NULL;
    EGLint numConfigs = -1, n=0;
    eglGetConfigs(dpy, NULL, 0, &numConfigs);
    EGLConfig* const configs = new EGLConfig[numConfigs];
    eglChooseConfig(dpy, attrs, configs, numConfigs, &n);

    if (n) {
        if (attribute != EGL_NONE) {
            for (int i=0 ; i<n ; i++) {
                EGLint value = 0;
                eglGetConfigAttrib(dpy, configs[i], attribute, &value);
                if (wanted == value) {
                    *outConfig = configs[i];
                    delete [] configs;
                    return NO_ERROR;
                }
            }
        } else {
            // just pick the first one
            *outConfig = configs[0];
            delete [] configs;
            return NO_ERROR;
        }
    }
    delete [] configs;
    return NAME_NOT_FOUND;
}

class EGLAttributeVector {
    struct Attribute;
    class Adder;
    friend class Adder;
    KeyedVector<Attribute, EGLint> mList;
    struct Attribute {
        Attribute() {};
        Attribute(EGLint v) : v(v) { }
        EGLint v;
        bool operator < (const Attribute& other) const {
            // this places EGL_NONE at the end
            EGLint lhs(v);
            EGLint rhs(other.v);
            if (lhs == EGL_NONE) lhs = 0x7FFFFFFF;
            if (rhs == EGL_NONE) rhs = 0x7FFFFFFF;
            return lhs < rhs;
        }
    };
    class Adder {
        friend class EGLAttributeVector;
        EGLAttributeVector& v;
        EGLint attribute;
        Adder(EGLAttributeVector& v, EGLint attribute)
            : v(v), attribute(attribute) {
        }
    public:
        void operator = (EGLint value) {
            if (attribute != EGL_NONE) {
                v.mList.add(attribute, value);
            }
        }
        operator EGLint () const { return v.mList[attribute]; }
    };
public:
    EGLAttributeVector() {
        mList.add(EGL_NONE, EGL_NONE);
    }
    void remove(EGLint attribute) {
        if (attribute != EGL_NONE) {
            mList.removeItem(attribute);
        }
    }
    Adder operator [] (EGLint attribute) {
        return Adder(*this, attribute);
    }
    EGLint operator [] (EGLint attribute) const {
       return mList[attribute];
    }
    // cast-operator to (EGLint const*)
    operator EGLint const* () const { return &mList.keyAt(0).v; }
};

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

    EGLAttributeVector attribs;
    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;

    } else {
        // if no renderable type specified, fallback to a simplified query
        wantedAttribute                         = EGL_NATIVE_VISUAL_ID;
        wantedAttributeValue                    = nativeVisualId;
    }

    err = selectConfigForAttribute(display, attribs, wantedAttribute,
        wantedAttributeValue, config);
    if (err == NO_ERROR) {
        EGLint caveat;
        if (eglGetConfigAttrib(display, *config, EGL_CONFIG_CAVEAT, &caveat))
            ALOGW_IF(caveat == EGL_SLOW_CONFIG, "EGL_SLOW_CONFIG selected!");
    }
    return err;
}

class DispSyncSource : public VSyncSource, private DispSync::Callback {
class DispSyncSource : public VSyncSource, private DispSync::Callback {
public:
public:
    DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync) :
    DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync) :
@@ -521,51 +399,12 @@ void SurfaceFlinger::init() {
    mHwc = new HWComposer(this,
    mHwc = new HWComposer(this,
            *static_cast<HWComposer::EventHandler *>(this));
            *static_cast<HWComposer::EventHandler *>(this));


    // First try to get an ES2 config
    err = selectEGLConfig(mEGLDisplay, mHwc->getVisualID(), EGL_OPENGL_ES2_BIT,
            &mEGLConfig);

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

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

    if (err != NO_ERROR) {
        // 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;
    eglGetConfigAttrib(mEGLDisplay, mEGLConfig, EGL_RED_SIZE,   &r);
    eglGetConfigAttrib(mEGLDisplay, mEGLConfig, EGL_GREEN_SIZE, &g);
    eglGetConfigAttrib(mEGLDisplay, mEGLConfig, EGL_BLUE_SIZE,  &b);
    eglGetConfigAttrib(mEGLDisplay, mEGLConfig, EGL_ALPHA_SIZE, &a);
    ALOGI("EGL informations:");
    ALOGI("vendor    : %s", eglQueryString(mEGLDisplay, EGL_VENDOR));
    ALOGI("version   : %s", eglQueryString(mEGLDisplay, EGL_VERSION));
    ALOGI("extensions: %s", eglQueryString(mEGLDisplay, EGL_EXTENSIONS));
    ALOGI("Client API: %s", eglQueryString(mEGLDisplay, EGL_CLIENT_APIS)?:"Not Supported");
    ALOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, mEGLConfig);

    // get a RenderEngine for the given display / config (can't fail)
    // get a RenderEngine for the given display / config (can't fail)
    mRenderEngine = RenderEngine::create(mEGLDisplay, mEGLConfig);
    mRenderEngine = RenderEngine::create(mEGLDisplay, mHwc->getVisualID());


    // retrieve the EGL context that was selected/created
    // retrieve the EGL context that was selected/created
    mEGLContext = mRenderEngine->getEGLContext();
    mEGLContext = mRenderEngine->getEGLContext();


    // figure out which format we got
    eglGetConfigAttrib(mEGLDisplay, mEGLConfig,
            EGL_NATIVE_VISUAL_ID, &mEGLNativeVisualId);

    LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
    LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
            "couldn't create EGLContext");
            "couldn't create EGLContext");


@@ -584,7 +423,7 @@ void SurfaceFlinger::init() {
            sp<DisplayDevice> hw = new DisplayDevice(this,
            sp<DisplayDevice> hw = new DisplayDevice(this,
                    type, allocateHwcDisplayId(type), isSecure, token,
                    type, allocateHwcDisplayId(type), isSecure, token,
                    fbs, bq,
                    fbs, bq,
                    mEGLConfig);
                    mRenderEngine->getEGLConfig());
            if (i > DisplayDevice::DISPLAY_PRIMARY) {
            if (i > DisplayDevice::DISPLAY_PRIMARY) {
                // FIXME: currently we don't get blank/unblank requests
                // FIXME: currently we don't get blank/unblank requests
                // for displays other than the main display, so we always
                // for displays other than the main display, so we always
@@ -1347,7 +1186,8 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
                    if (dispSurface != NULL) {
                    if (dispSurface != NULL) {
                        sp<DisplayDevice> hw = new DisplayDevice(this,
                        sp<DisplayDevice> hw = new DisplayDevice(this,
                                state.type, hwcDisplayId, state.isSecure,
                                state.type, hwcDisplayId, state.isSecure,
                                display, dispSurface, producer, mEGLConfig);
                                display, dispSurface, producer,
                                mRenderEngine->getEGLConfig());
                        hw->setLayerStack(state.layerStack);
                        hw->setLayerStack(state.layerStack);
                        hw->setProjection(state.orientation,
                        hw->setProjection(state.orientation,
                                state.viewport, state.frame);
                                state.viewport, state.frame);
@@ -2544,7 +2384,6 @@ void SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index,
            "  refresh-rate              : %f fps\n"
            "  refresh-rate              : %f fps\n"
            "  x-dpi                     : %f\n"
            "  x-dpi                     : %f\n"
            "  y-dpi                     : %f\n"
            "  y-dpi                     : %f\n"
            "  EGL_NATIVE_VISUAL_ID      : %d\n"
            "  gpu_to_cpu_unsupported    : %d\n"
            "  gpu_to_cpu_unsupported    : %d\n"
            ,
            ,
            mLastSwapBufferTime/1000.0,
            mLastSwapBufferTime/1000.0,
@@ -2553,7 +2392,6 @@ void SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index,
            1e9 / hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY),
            1e9 / hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY),
            hwc.getDpiX(HWC_DISPLAY_PRIMARY),
            hwc.getDpiX(HWC_DISPLAY_PRIMARY),
            hwc.getDpiY(HWC_DISPLAY_PRIMARY),
            hwc.getDpiY(HWC_DISPLAY_PRIMARY),
            mEGLNativeVisualId,
            !mGpuToCpuSupported);
            !mGpuToCpuSupported);


    result.appendFormat("  eglSwapBuffers time: %f us\n",
    result.appendFormat("  eglSwapBuffers time: %f us\n",
+0 −6
Original line number Original line Diff line number Diff line
@@ -317,10 +317,6 @@ private:
    /* ------------------------------------------------------------------------
    /* ------------------------------------------------------------------------
     * EGL
     * EGL
     */
     */
    static status_t selectConfigForAttribute(EGLDisplay dpy,
        EGLint const* attrs, EGLint attribute, EGLint value, EGLConfig* outConfig);
    static status_t selectEGLConfig(EGLDisplay disp, EGLint visualId,
        EGLint renderableType, EGLConfig* config);
    size_t getMaxTextureSize() const;
    size_t getMaxTextureSize() const;
    size_t getMaxViewportDims() const;
    size_t getMaxViewportDims() const;


@@ -431,9 +427,7 @@ private:
    sp<EventThread> mSFEventThread;
    sp<EventThread> mSFEventThread;
    sp<EventControlThread> mEventControlThread;
    sp<EventControlThread> mEventControlThread;
    EGLContext mEGLContext;
    EGLContext mEGLContext;
    EGLConfig mEGLConfig;
    EGLDisplay mEGLDisplay;
    EGLDisplay mEGLDisplay;
    EGLint mEGLNativeVisualId;
    sp<IBinder> mBuiltinDisplays[DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES];
    sp<IBinder> mBuiltinDisplays[DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES];


    // Can only accessed from the main thread, these members
    // Can only accessed from the main thread, these members