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; |
} |
} |