Chromium Code Reviews| Index: ui/gl/gl_surface_egl.cc |
| diff --git a/ui/gl/gl_surface_egl.cc b/ui/gl/gl_surface_egl.cc |
| index b6a7184c129f7e3e18588c69864f775420ab7ae3..208b40440beea7be1ef0bae10f69bb0a45176eec 100644 |
| --- a/ui/gl/gl_surface_egl.cc |
| +++ b/ui/gl/gl_surface_egl.cc |
| @@ -10,6 +10,7 @@ |
| #if defined(OS_ANDROID) |
| #include <android/native_window_jni.h> |
| +#include "base/android/sys_utils.h" |
| #endif |
| #include "base/command_line.h" |
| @@ -98,6 +99,25 @@ class EGLSyncControlVSyncProvider |
| GLSurfaceEGL::GLSurfaceEGL() {} |
| +static bool ValidateEglConfig(EGLDisplay display, |
| + const EGLint* config_attribs, |
| + EGLint* num_configs) { |
|
no sievers
2014/01/23 18:16:18
Can you put this in the anonymous namespace above?
sivag
2014/01/24 06:25:17
Done.
|
| + if (!eglChooseConfig(display, |
| + config_attribs, |
| + NULL, |
| + 0, |
| + num_configs)) { |
| + LOG(ERROR) << "eglChooseConfig failed with error " |
| + << GetLastEGLErrorString(); |
| + return false; |
| + } |
| + if (*num_configs == 0) { |
| + LOG(ERROR) << "No suitable EGL configs found."; |
| + return false; |
| + } |
| + return true; |
| +} |
| + |
| bool GLSurfaceEGL::InitializeOneOff() { |
| static bool initialized = false; |
| if (initialized) |
| @@ -137,7 +157,7 @@ bool GLSurfaceEGL::InitializeOneOff() { |
| // Choose an EGL configuration. |
| // On X this is only used for PBuffer surfaces. |
| - static const EGLint kConfigAttribs[] = { |
| + static EGLint config_attribs_8888[] = { |
| EGL_BUFFER_SIZE, 32, |
| EGL_ALPHA_SIZE, 8, |
| EGL_BLUE_SIZE, 8, |
| @@ -148,39 +168,109 @@ bool GLSurfaceEGL::InitializeOneOff() { |
| EGL_NONE |
| }; |
| +#if defined(OS_ANDROID) |
| + static EGLint config_attribs_565[] = { |
| + EGL_BUFFER_SIZE, 16, |
| + EGL_BLUE_SIZE, 5, |
| + EGL_GREEN_SIZE, 6, |
| + EGL_RED_SIZE, 5, |
| + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, |
| + EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT, |
| + EGL_NONE |
| + }; |
| +#endif |
| + EGLint* choose_attributes = config_attribs_8888; |
| + |
| +#if defined(OS_ANDROID) |
| + if (base::android::SysUtils::IsLowEndDevice()) { |
| + choose_attributes = config_attribs_565; |
| + } |
| +#endif |
| + |
| #if defined(USE_OZONE) |
| const EGLint* config_attribs = |
| - surface_factory->GetEGLSurfaceProperties(kConfigAttribs); |
| + surface_factory->GetEGLSurfaceProperties(choose_attributes); |
| #else |
| - const EGLint* config_attribs = kConfigAttribs; |
| + const EGLint* config_attribs = choose_attributes; |
| #endif |
| EGLint num_configs; |
| - if (!eglChooseConfig(g_display, |
| - config_attribs, |
| - NULL, |
| - 0, |
| - &num_configs)) { |
| - LOG(ERROR) << "eglChooseConfig failed with error " |
| - << GetLastEGLErrorString(); |
| + EGLint config_size = 1; |
| + EGLConfig* config_data = &g_config; |
| + // Validate if there are any configs for given atrribs. |
| + bool config_status = ValidateEglConfig(g_display, |
| + config_attribs, |
| + &num_configs); |
|
no sievers
2014/01/23 18:16:18
nit: if (!ValidateEglConfig(...))
return f
sivag
2014/01/24 06:25:17
Done.
|
| + if(!config_status){ |
| return false; |
| } |
| - if (num_configs == 0) { |
| - LOG(ERROR) << "No suitable EGL configs found."; |
| - return false; |
| +#if defined(OS_ANDROID) |
| + scoped_ptr<EGLConfig[]> matching_configs(new EGLConfig[num_configs]); |
| + if (base::android::SysUtils::IsLowEndDevice()) { |
| + config_size = num_configs; |
| + config_data = matching_configs.get(); |
| } |
| +#endif |
| if (!eglChooseConfig(g_display, |
| config_attribs, |
| - &g_config, |
| - 1, |
| + config_data, |
| + config_size, |
| &num_configs)) { |
| LOG(ERROR) << "eglChooseConfig failed with error " |
| << GetLastEGLErrorString(); |
| return false; |
| } |
| +#if defined(OS_ANDROID) |
| + if (base::android::SysUtils::IsLowEndDevice()) { |
| + // Because of the EGL config sort order, we have to iterate |
| + // through all of them (it'll put higher sum(R,G,B) bits |
| + // first with the above attribs). |
| + bool match_found = false; |
| + for (int i = 0; i < num_configs; i++) { |
| + EGLBoolean success; |
| + EGLint red, green, blue, alpha; |
| + // Read the relevent attributes of the EGLConfig. |
| + success = eglGetConfigAttrib(g_display, matching_configs[i], |
| + EGL_RED_SIZE, &red); |
| + success &= eglGetConfigAttrib(g_display, matching_configs[i], |
| + EGL_BLUE_SIZE, &blue); |
| + success &= eglGetConfigAttrib(g_display, matching_configs[i], |
| + EGL_GREEN_SIZE, &green); |
| + success &= eglGetConfigAttrib(g_display, matching_configs[i], |
| + EGL_ALPHA_SIZE, &alpha); |
| + if ((success == EGL_TRUE) && (red == 5) && |
| + (green == 6) && (blue == 5)) { |
| + g_config = matching_configs[i]; |
| + match_found = true; |
| + break; |
| + } |
| + } |
| + if (!match_found) { |
| + // To fall back to default 32 bit format, choose with |
| + // the right attributes again. |
| + config_status = ValidateEglConfig(g_display, |
| + config_attribs_8888, |
| + &num_configs); |
| + if (!config_status) { |
|
no sievers
2014/01/23 18:16:18
nit: same here and no need for |config_status| var
sivag
2014/01/24 06:25:17
Done.
|
| + return false; |
| + } |
| + if (!eglChooseConfig(g_display, |
| + config_attribs_8888, |
| + &g_config, |
| + 1, |
| + &num_configs)) { |
| + LOG(ERROR) << "eglChooseConfig failed with error " |
| + << GetLastEGLErrorString(); |
| + return false; |
| + } |
| + } |
| + } |
| + |
| +#endif |
| + |
| g_egl_extensions = eglQueryString(g_display, EGL_EXTENSIONS); |
| g_egl_create_context_robustness_supported = |
| HasEGLExtension("EGL_EXT_create_context_robustness"); |