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 c34ca0e70e7a25396a82cd9310a90c2ef0630cd6..ee104802a69e16c51907f14d2fdfd02dddc269ff 100644 |
| --- a/ui/gl/gl_surface_egl.cc |
| +++ b/ui/gl/gl_surface_egl.cc |
| @@ -62,6 +62,14 @@ EGLConfig g_config; |
| EGLDisplay g_display; |
| EGLNativeDisplayType g_native_display; |
| +// In the Cast environment, we need to destroy the displayType |
| +// returned by the GPU platform when we switch to an external app |
| +// which will temporarily own all screen and GPU resources. |
| +// Even though Chromium is still in the background. |
| +// As such, it must be reinitialized each time we come back to the foreground. |
| +bool g_initialized = false; |
| +int g_num_surfaces = 0; |
| + |
| const char* g_egl_extensions = NULL; |
| bool g_egl_create_context_robustness_supported = false; |
| bool g_egl_sync_control_supported = false; |
| @@ -109,8 +117,7 @@ class EGLSyncControlVSyncProvider |
| GLSurfaceEGL::GLSurfaceEGL() {} |
| bool GLSurfaceEGL::InitializeOneOff() { |
| - static bool initialized = false; |
| - if (initialized) |
| + if (g_initialized) |
| return true; |
| g_native_display = GetPlatformDefaultEGLNativeDisplay(); |
| @@ -186,6 +193,11 @@ bool GLSurfaceEGL::InitializeOneOff() { |
| g_egl_window_fixed_size_supported = |
| HasEGLExtension("EGL_ANGLE_window_fixed_size"); |
| + // We always succeed beyond this point so set g_initialized here to avoid |
| + // infinite recursion through CreateGLContext and GetDisplay |
| + // if g_egl_surfaceless_context_supported. |
| + g_initialized = true; |
| + |
| // TODO(oetuaho@nvidia.com): Surfaceless is disabled on Android as a temporary |
| // workaround, since code written for Android WebView takes different paths |
| // based on whether GL surface objects have underlying EGL surface handles, |
| @@ -215,24 +227,44 @@ bool GLSurfaceEGL::InitializeOneOff() { |
| } |
| #endif |
| - initialized = true; |
| - |
| return true; |
| } |
| +// static |
| +void GLSurfaceEGL::Deinitialize() { |
| + if (g_initialized) { |
| + g_initialized = false; |
| + eglTerminate(g_display); |
| + } |
| +} |
| + |
| EGLDisplay GLSurfaceEGL::GetDisplay() { |
| + if (!g_initialized) { |
| + bool result = GLSurfaceEGL::InitializeOneOff(); |
| + DCHECK(result); |
| + } |
| return g_display; |
| } |
| EGLDisplay GLSurfaceEGL::GetHardwareDisplay() { |
| + if (!g_initialized) { |
| + bool result = GLSurfaceEGL::InitializeOneOff(); |
| + DCHECK(result); |
| + } |
| return g_display; |
| } |
| EGLNativeDisplayType GLSurfaceEGL::GetNativeDisplay() { |
| + if (!g_initialized) { |
| + bool result = GLSurfaceEGL::InitializeOneOff(); |
| + DCHECK(result); |
| + } |
| return g_native_display; |
| } |
| const char* GLSurfaceEGL::GetEGLExtensions() { |
| + // No need for InitializeOneOff. Assume that extensions will not change |
| + // after the first initialization. |
| return g_egl_extensions; |
| } |
| @@ -355,6 +387,7 @@ bool NativeViewGLSurfaceEGL::Initialize( |
| vsync_provider_.reset(sync_provider.release()); |
| else if (g_egl_sync_control_supported) |
| vsync_provider_.reset(new EGLSyncControlVSyncProvider(surface_)); |
| + ++g_num_surfaces; |
|
piman
2014/11/18 20:55:34
Could that tracking be done in the constructor/des
GusFernandez
2014/11/19 18:50:13
Good idea. This simplified the code somewhat.
|
| return true; |
| } |
| @@ -365,6 +398,11 @@ void NativeViewGLSurfaceEGL::Destroy() { |
| << GetLastEGLErrorString(); |
| } |
| surface_ = NULL; |
| + DCHECK_GT(g_num_surfaces, 0) << "Bad surface count"; |
| + if (--g_num_surfaces == 0) { |
| + DVLOG(2) << "Destroyed last (native) EGL surface. Deinitializing."; |
| + GLSurfaceEGL::Deinitialize(); |
| + } |
| } |
| } |
| @@ -608,8 +646,15 @@ bool PbufferGLSurfaceEGL::Initialize() { |
| return false; |
| } |
| - if (old_surface) |
| + if (old_surface) { |
| eglDestroySurface(display, old_surface); |
| + DVLOG(2) << "Reinitialized pbuffer surface. EGL surface count remains at " |
| + << g_num_surfaces; |
| + } else { |
| + ++g_num_surfaces; |
| + DVLOG(2) << "Initialized new pbuffer surface. EGL surface count now " |
| + << g_num_surfaces; |
| + } |
| surface_ = new_surface; |
| return true; |
| @@ -621,6 +666,11 @@ void PbufferGLSurfaceEGL::Destroy() { |
| LOG(ERROR) << "eglDestroySurface failed with error " |
| << GetLastEGLErrorString(); |
| } |
| + CHECK_GT(g_num_surfaces, 0) << "Bad surface count"; |
|
piman
2014/11/18 20:55:34
nit: DCHECK_GT
GusFernandez
2014/11/19 18:50:13
Irrelevant after the change above.
|
| + if (--g_num_surfaces == 0) { |
| + DVLOG(2) << "Destroyed last (pbuffer) EGL surface. Deinitializing."; |
| + GLSurfaceEGL::Deinitialize(); |
| + } |
| surface_ = NULL; |
| } |
| } |