Loading services/surfaceflinger/RenderEngine/RenderEngine.cpp +168 −3 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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()); Loading @@ -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; } } Loading Loading @@ -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 // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- services/surfaceflinger/RenderEngine/RenderEngine.h +6 −2 Original line number Original line Diff line number Diff line Loading @@ -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; Loading @@ -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); Loading Loading @@ -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; }; }; Loading services/surfaceflinger/SurfaceFlinger.cpp +4 −166 Original line number Original line Diff line number Diff line Loading @@ -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) : Loading Loading @@ -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"); Loading @@ -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 Loading Loading @@ -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); Loading Loading @@ -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, Loading @@ -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", Loading services/surfaceflinger/SurfaceFlinger.h +0 −6 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading Loading
services/surfaceflinger/RenderEngine/RenderEngine.cpp +168 −3 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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()); Loading @@ -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; } } Loading Loading @@ -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 // --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
services/surfaceflinger/RenderEngine/RenderEngine.h +6 −2 Original line number Original line Diff line number Diff line Loading @@ -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; Loading @@ -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); Loading Loading @@ -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; }; }; Loading
services/surfaceflinger/SurfaceFlinger.cpp +4 −166 Original line number Original line Diff line number Diff line Loading @@ -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) : Loading Loading @@ -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"); Loading @@ -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 Loading Loading @@ -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); Loading Loading @@ -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, Loading @@ -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", Loading
services/surfaceflinger/SurfaceFlinger.h +0 −6 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading