diff options
| author | 2014-01-03 18:31:53 +0000 | |
|---|---|---|
| committer | 2014-01-03 18:31:53 +0000 | |
| commit | 4c37d0886ca06c290e205cad2798406361bbbf53 (patch) | |
| tree | 8d2ff3fa240242cb565583252a1a785bf6d6d34f | |
| parent | 285bfefb01f24e98348628c115eb6c524417ea82 (diff) | |
| parent | 6c7dcfa956847a9f061fd1b2baa9dc43585599af (diff) | |
am 6c7dcfa9: am 662d3134: Merge "Move EGLConfig selection to RenderEngine"
* commit '6c7dcfa956847a9f061fd1b2baa9dc43585599af':
Move EGLConfig selection to RenderEngine
| -rw-r--r-- | services/surfaceflinger/RenderEngine/RenderEngine.cpp | 171 | ||||
| -rw-r--r-- | services/surfaceflinger/RenderEngine/RenderEngine.h | 8 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 170 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 6 |
4 files changed, 178 insertions, 177 deletions
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.cpp b/services/surfaceflinger/RenderEngine/RenderEngine.cpp index ba82cadb0d..759839b9e3 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 3c7f9ab094..4dc94575db 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; }; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 9d94c874fe..ec643906bf 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -318,128 +318,6 @@ void SurfaceFlinger::deleteTextureAsync(uint32_t 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 { public: DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync) : @@ -521,51 +399,12 @@ void SurfaceFlinger::init() { mHwc = new HWComposer(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) - mRenderEngine = RenderEngine::create(mEGLDisplay, mEGLConfig); + mRenderEngine = RenderEngine::create(mEGLDisplay, mHwc->getVisualID()); // retrieve the EGL context that was selected/created 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, "couldn't create EGLContext"); @@ -584,7 +423,7 @@ void SurfaceFlinger::init() { sp<DisplayDevice> hw = new DisplayDevice(this, type, allocateHwcDisplayId(type), isSecure, token, fbs, bq, - mEGLConfig); + mRenderEngine->getEGLConfig()); if (i > DisplayDevice::DISPLAY_PRIMARY) { // FIXME: currently we don't get blank/unblank requests // for displays other than the main display, so we always @@ -1347,7 +1186,8 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) if (dispSurface != NULL) { sp<DisplayDevice> hw = new DisplayDevice(this, state.type, hwcDisplayId, state.isSecure, - display, dispSurface, producer, mEGLConfig); + display, dispSurface, producer, + mRenderEngine->getEGLConfig()); hw->setLayerStack(state.layerStack); hw->setProjection(state.orientation, state.viewport, state.frame); @@ -2544,7 +2384,6 @@ void SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index, " refresh-rate : %f fps\n" " x-dpi : %f\n" " y-dpi : %f\n" - " EGL_NATIVE_VISUAL_ID : %d\n" " gpu_to_cpu_unsupported : %d\n" , mLastSwapBufferTime/1000.0, @@ -2553,7 +2392,6 @@ void SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index, 1e9 / hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY), hwc.getDpiX(HWC_DISPLAY_PRIMARY), hwc.getDpiY(HWC_DISPLAY_PRIMARY), - mEGLNativeVisualId, !mGpuToCpuSupported); result.appendFormat(" eglSwapBuffers time: %f us\n", diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index f08e66abcb..80bb619d67 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -317,10 +317,6 @@ private: /* ------------------------------------------------------------------------ * 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 getMaxViewportDims() const; @@ -431,9 +427,7 @@ private: sp<EventThread> mSFEventThread; sp<EventControlThread> mEventControlThread; EGLContext mEGLContext; - EGLConfig mEGLConfig; EGLDisplay mEGLDisplay; - EGLint mEGLNativeVisualId; sp<IBinder> mBuiltinDisplays[DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES]; // Can only accessed from the main thread, these members |