| 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..0db2fc72569c60ab0cbe27b0c22cca4ef6b88479 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"
|
| @@ -94,6 +95,25 @@ class EGLSyncControlVSyncProvider
|
| DISALLOW_COPY_AND_ASSIGN(EGLSyncControlVSyncProvider);
|
| };
|
|
|
| +bool ValidateEglConfig(EGLDisplay display,
|
| + const EGLint* config_attribs,
|
| + EGLint* num_configs) {
|
| + 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;
|
| +}
|
| +
|
| } // namespace
|
|
|
| GLSurfaceEGL::GLSurfaceEGL() {}
|
| @@ -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,105 @@ 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.
|
| + if (!ValidateEglConfig(g_display,
|
| + config_attribs,
|
| + &num_configs)) {
|
| 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;
|
| + // 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);
|
| + 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.
|
| + if (!ValidateEglConfig(g_display,
|
| + config_attribs_8888,
|
| + &num_configs)) {
|
| + 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");
|
|
|