am 4c37d088: am 6c7dcfa9: am 662d3134: Merge "Move EGLConfig selection to RenderEngine"
* commit '4c37d0886ca06c290e205cad2798406361bbbf53':
Move EGLConfig selection to RenderEngine
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 @@
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() {
}
-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 @@
}
// ---------------------------------------------------------------------------
+
+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 @@
};
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 @@
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 @@
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 189049c..b8fc599 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -319,128 +319,6 @@
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) :
@@ -522,51 +400,12 @@
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");
@@ -585,7 +424,7 @@
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
@@ -1348,7 +1187,8 @@
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);
@@ -2549,7 +2389,6 @@
" 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,
@@ -2558,7 +2397,6 @@
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 2e75f1c..9db0ce1 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -318,10 +318,6 @@
/* ------------------------------------------------------------------------
* 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;
@@ -432,9 +428,7 @@
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