diff options
author | Jesse Hall <jessehall@google.com> | 2014-01-03 18:36:28 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2014-01-03 18:36:28 +0000 |
commit | 10ca42cbdc75c6a36d0b72dadbe845d990e31e95 (patch) | |
tree | 533fb77d2119dce9e606fb1a11b8e10a27a10606 /services/surfaceflinger/RenderEngine | |
parent | 95c6675db143a92f5398a112058e31a486c92932 (diff) | |
parent | 4c37d0886ca06c290e205cad2798406361bbbf53 (diff) | |
download | frameworks_native-10ca42cbdc75c6a36d0b72dadbe845d990e31e95.zip frameworks_native-10ca42cbdc75c6a36d0b72dadbe845d990e31e95.tar.gz frameworks_native-10ca42cbdc75c6a36d0b72dadbe845d990e31e95.tar.bz2 |
am 4c37d088: am 6c7dcfa9: am 662d3134: Merge "Move EGLConfig selection to RenderEngine"
* commit '4c37d0886ca06c290e205cad2798406361bbbf53':
Move EGLConfig selection to RenderEngine
Diffstat (limited to 'services/surfaceflinger/RenderEngine')
-rw-r--r-- | services/surfaceflinger/RenderEngine/RenderEngine.cpp | 171 | ||||
-rw-r--r-- | services/surfaceflinger/RenderEngine/RenderEngine.h | 8 |
2 files changed, 174 insertions, 5 deletions
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.cpp b/services/surfaceflinger/RenderEngine/RenderEngine.cpp index ba82cad..759839b 100644 --- a/services/surfaceflinger/RenderEngine/RenderEngine.cpp +++ b/services/surfaceflinger/RenderEngine/RenderEngine.cpp @@ -29,7 +29,9 @@ 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 contextClientVersion = 0; @@ -96,7 +98,7 @@ RenderEngine* RenderEngine::create(EGLDisplay display, EGLConfig config) { engine = new GLES20RenderEngine(); break; } - engine->setEGLContext(ctxt); + engine->setEGLHandles(config, ctxt); ALOGI("OpenGL ES informations:"); ALOGI("vendor : %s", extensions.getVendor()); @@ -118,10 +120,15 @@ RenderEngine::RenderEngine() : mEGLContext(EGL_NO_CONTEXT) { RenderEngine::~RenderEngine() { } -void RenderEngine::setEGLContext(EGLContext ctxt) { +void RenderEngine::setEGLHandles(EGLConfig config, EGLContext ctxt) { + mEGLConfig = config; mEGLContext = ctxt; } +EGLContext RenderEngine::getEGLConfig() const { + return mEGLConfig; +} + EGLContext RenderEngine::getEGLContext() const { return mEGLContext; } @@ -235,5 +242,163 @@ status_t RenderEngine::BindImageAsFramebuffer::getStatus() const { } // --------------------------------------------------------------------------- + +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 // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h index 3c7f9ab..4dc9457 100644 --- a/services/surfaceflinger/RenderEngine/RenderEngine.h +++ b/services/surfaceflinger/RenderEngine/RenderEngine.h @@ -44,8 +44,9 @@ class RenderEngine { }; static GlesVersion parseGlesVersion(const char* str); + EGLConfig mEGLConfig; 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 unbindFramebuffer(uint32_t texName, uint32_t fbName) = 0; @@ -55,7 +56,9 @@ protected: virtual ~RenderEngine() = 0; 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. virtual void dump(String8& result); @@ -107,6 +110,7 @@ public: virtual size_t getMaxTextureSize() const = 0; virtual size_t getMaxViewportDims() const = 0; + EGLConfig getEGLConfig() const; EGLContext getEGLContext() const; }; |