summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2012-09-25 18:24:31 -0700
committerMathias Agopian <mathias@google.com>2012-09-25 18:38:09 -0700
commit722b98f9dfe8f04de8734630198b99a6cd024118 (patch)
treeed55aedce9afbffec5099ee78a1db0884e811e35 /services
parent7b1905113712281c777b230648d3fbb69ae4f42c (diff)
downloadframeworks_native-722b98f9dfe8f04de8734630198b99a6cd024118.zip
frameworks_native-722b98f9dfe8f04de8734630198b99a6cd024118.tar.gz
frameworks_native-722b98f9dfe8f04de8734630198b99a6cd024118.tar.bz2
add support for EGL_FRAMEBUFFER_TARGET_ANDROID
we now try first with EGL_FRAMEBUFFER_TARGET_ANDROID, and pick the first config we find. Otherwise, we revert to the old algorithm. Bug: 7232584 Change-Id: I8d5c5a4ce48420832c2e2828718a8f53325effb0
Diffstat (limited to 'services')
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp115
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h4
2 files changed, 95 insertions, 24 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index ceae8d7..b3650bd 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -237,10 +237,10 @@ void SurfaceFlinger::deleteTextureAsync(GLuint texture) {
postMessageAsync(new MessageDestroyGLTexture(texture));
}
-status_t SurfaceFlinger::selectConfigForPixelFormat(
+status_t SurfaceFlinger::selectConfigForAttribute(
EGLDisplay dpy,
EGLint const* attrs,
- PixelFormat format,
+ EGLint attribute, EGLint wanted,
EGLConfig* outConfig)
{
EGLConfig config = NULL;
@@ -249,11 +249,20 @@ status_t SurfaceFlinger::selectConfigForPixelFormat(
EGLConfig* const configs = new EGLConfig[numConfigs];
eglChooseConfig(dpy, attrs, configs, numConfigs, &n);
- for (int i=0 ; i<n ; i++) {
- EGLint nativeVisualId = 0;
- eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId);
- if (nativeVisualId>0 && format == nativeVisualId) {
- *outConfig = configs[i];
+ 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;
}
@@ -262,6 +271,58 @@ status_t SurfaceFlinger::selectConfigForPixelFormat(
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; }
+};
+
EGLConfig SurfaceFlinger::selectEGLConfig(EGLDisplay display, EGLint nativeVisualId) {
// select our EGLConfig. It must support EGL_RECORDABLE_ANDROID if
// it is to be used with WIFI displays
@@ -269,32 +330,42 @@ EGLConfig SurfaceFlinger::selectEGLConfig(EGLDisplay display, EGLint nativeVisua
EGLint dummy;
status_t err;
- EGLint attribs[] = {
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
- // The rest of the attributes must be in this order and at the end
- // of the list; we rely on that for fallback searches below.
- EGL_RED_SIZE, 8,
- EGL_GREEN_SIZE, 8,
- EGL_BLUE_SIZE, 8,
- EGL_RECORDABLE_ANDROID, EGL_TRUE,
- EGL_NONE
- };
- err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config);
+ EGLAttributeVector attribs;
+ attribs[EGL_SURFACE_TYPE] = EGL_WINDOW_BIT;
+ attribs[EGL_RECORDABLE_ANDROID] = EGL_TRUE;
+ attribs[EGL_FRAMEBUFFER_TARGET_ANDROID] = EGL_TRUE;
+ attribs[EGL_RED_SIZE] = 8;
+ attribs[EGL_GREEN_SIZE] = 8;
+ attribs[EGL_BLUE_SIZE] = 8;
+
+ err = selectConfigForAttribute(display, attribs, EGL_NONE, EGL_NONE, &config);
+ if (!err)
+ goto success;
+
+ // maybe we failed because of EGL_FRAMEBUFFER_TARGET_ANDROID
+ ALOGW("no suitable EGLConfig found, trying without EGL_FRAMEBUFFER_TARGET_ANDROID");
+ attribs.remove(EGL_FRAMEBUFFER_TARGET_ANDROID);
+ err = selectConfigForAttribute(display, attribs,
+ EGL_NATIVE_VISUAL_ID, nativeVisualId, &config);
if (!err)
goto success;
// maybe we failed because of EGL_RECORDABLE_ANDROID
ALOGW("no suitable EGLConfig found, trying without EGL_RECORDABLE_ANDROID");
- attribs[NELEM(attribs) - 3] = EGL_NONE;
- err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config);
+ attribs.remove(EGL_RECORDABLE_ANDROID);
+ err = selectConfigForAttribute(display, attribs,
+ EGL_NATIVE_VISUAL_ID, nativeVisualId, &config);
if (!err)
goto success;
// allow less than 24-bit color; the non-gpu-accelerated emulator only
// supports 16-bit color
ALOGW("no suitable EGLConfig found, trying with 16-bit color allowed");
- attribs[NELEM(attribs) - 9] = EGL_NONE;
- err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config);
+ attribs.remove(EGL_RED_SIZE);
+ attribs.remove(EGL_GREEN_SIZE);
+ attribs.remove(EGL_BLUE_SIZE);
+ err = selectConfigForAttribute(display, attribs,
+ EGL_NATIVE_VISUAL_ID, nativeVisualId, &config);
if (!err)
goto success;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 0a019ce..e5b939d 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -309,8 +309,8 @@ private:
/* ------------------------------------------------------------------------
* EGL
*/
- static status_t selectConfigForPixelFormat(EGLDisplay dpy,
- EGLint const* attrs, PixelFormat format, EGLConfig* outConfig);
+ static status_t selectConfigForAttribute(EGLDisplay dpy,
+ EGLint const* attrs, EGLint attribute, EGLint value, EGLConfig* outConfig);
static EGLConfig selectEGLConfig(EGLDisplay disp, EGLint visualId);
static EGLContext createGLContext(EGLDisplay disp, EGLConfig config);
void initializeGL(EGLDisplay display);