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..762e2f5924b3a137d3b425c21376346ccff364d8 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,41 @@ bool GLSurfaceEGL::InitializeOneOff() { |
| } |
| #endif |
| - initialized = true; |
| - |
| return true; |
| } |
| +// static |
| +void GLSurfaceEGL::Deinitialize() { |
| + g_initialized = false; |
|
spang
2014/11/17 21:49:12
should this call eglTerminate?
GusFernandez
2014/11/18 15:03:59
Not strictly necessary with our platform, but it i
|
| +} |
| + |
| 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 +384,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; |
| return true; |
| } |
| @@ -365,6 +395,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 +643,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 +663,11 @@ void PbufferGLSurfaceEGL::Destroy() { |
| LOG(ERROR) << "eglDestroySurface failed with error " |
| << GetLastEGLErrorString(); |
| } |
| + CHECK_GT(g_num_surfaces, 0) << "Bad surface count"; |
| + if (--g_num_surfaces == 0) { |
|
spang
2014/11/17 21:49:12
This seems fairly magic.. shouldn't this be explic
GusFernandez
2014/11/18 15:03:59
I considered an explicit call here, but that got m
|
| + DVLOG(2) << "Destroyed last (pbuffer) EGL surface. Deinitializing."; |
| + GLSurfaceEGL::Deinitialize(); |
| + } |
| surface_ = NULL; |
| } |
| } |