| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/gl/gl_surface_egl.h" | 5 #include "ui/gl/gl_surface_egl.h" |
| 6 | 6 |
| 7 #if defined(OS_ANDROID) | 7 #if defined(OS_ANDROID) |
| 8 #include <android/native_window_jni.h> | 8 #include <android/native_window_jni.h> |
| 9 #endif | 9 #endif |
| 10 | 10 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 #endif // defined(OS_WIN) | 54 #endif // defined(OS_WIN) |
| 55 | 55 |
| 56 using ui::GetLastEGLErrorString; | 56 using ui::GetLastEGLErrorString; |
| 57 | 57 |
| 58 namespace gfx { | 58 namespace gfx { |
| 59 | 59 |
| 60 namespace { | 60 namespace { |
| 61 | 61 |
| 62 EGLConfig g_config; | 62 EGLConfig g_config; |
| 63 EGLDisplay g_display; | 63 EGLDisplay g_display; |
| 64 EGLNativeDisplayType g_native_display; | 64 EGLNativeDisplayType g_native_display_type; |
| 65 |
| 66 // In the Cast environment, we need to destroy the EGLNativeDisplayType and |
| 67 // EGLDisplay returned by the GPU platform when we switch to an external app |
| 68 // which will temporarily own all screen and GPU resources. |
| 69 // Even though Chromium is still in the background. |
| 70 // As such, it must be reinitialized each time we come back to the foreground. |
| 71 bool g_initialized = false; |
| 72 int g_num_surfaces = 0; |
| 73 bool g_terminate_pending = false; |
| 65 | 74 |
| 66 const char* g_egl_extensions = NULL; | 75 const char* g_egl_extensions = NULL; |
| 67 bool g_egl_create_context_robustness_supported = false; | 76 bool g_egl_create_context_robustness_supported = false; |
| 68 bool g_egl_sync_control_supported = false; | 77 bool g_egl_sync_control_supported = false; |
| 69 bool g_egl_window_fixed_size_supported = false; | 78 bool g_egl_window_fixed_size_supported = false; |
| 70 bool g_egl_surfaceless_context_supported = false; | 79 bool g_egl_surfaceless_context_supported = false; |
| 71 | 80 |
| 72 class EGLSyncControlVSyncProvider | 81 class EGLSyncControlVSyncProvider |
| 73 : public gfx::SyncControlVSyncProvider { | 82 : public gfx::SyncControlVSyncProvider { |
| 74 public: | 83 public: |
| (...skipping 23 matching lines...) Expand all Loading... |
| 98 bool GetMscRate(int32* numerator, int32* denominator) override { | 107 bool GetMscRate(int32* numerator, int32* denominator) override { |
| 99 return false; | 108 return false; |
| 100 } | 109 } |
| 101 | 110 |
| 102 private: | 111 private: |
| 103 EGLSurface surface_; | 112 EGLSurface surface_; |
| 104 | 113 |
| 105 DISALLOW_COPY_AND_ASSIGN(EGLSyncControlVSyncProvider); | 114 DISALLOW_COPY_AND_ASSIGN(EGLSyncControlVSyncProvider); |
| 106 }; | 115 }; |
| 107 | 116 |
| 117 void DeinitializeEgl() { |
| 118 if (g_initialized) { |
| 119 g_initialized = false; |
| 120 eglTerminate(g_display); |
| 121 } |
| 122 } |
| 123 |
| 108 } // namespace | 124 } // namespace |
| 109 | 125 |
| 110 GLSurfaceEGL::GLSurfaceEGL() {} | 126 GLSurfaceEGL::GLSurfaceEGL() { |
| 127 ++g_num_surfaces; |
| 128 if (!g_initialized) { |
| 129 bool result = GLSurfaceEGL::InitializeOneOff(); |
| 130 DCHECK(result); |
| 131 DCHECK(g_initialized); |
| 132 } |
| 133 } |
| 111 | 134 |
| 112 bool GLSurfaceEGL::InitializeOneOff() { | 135 bool GLSurfaceEGL::InitializeOneOff() { |
| 113 static bool initialized = false; | 136 if (g_initialized) |
| 114 if (initialized) | |
| 115 return true; | 137 return true; |
| 116 | 138 |
| 117 g_native_display = GetPlatformDefaultEGLNativeDisplay(); | 139 g_native_display_type = GetPlatformDefaultEGLNativeDisplay(); |
| 118 | 140 |
| 119 #if defined(OS_WIN) | 141 #if defined(OS_WIN) |
| 120 g_display = GetPlatformDisplay(g_native_display); | 142 g_display = GetPlatformDisplay(g_native_display_type); |
| 121 #else | 143 #else |
| 122 g_display = eglGetDisplay(g_native_display); | 144 g_display = eglGetDisplay(g_native_display_type); |
| 123 #endif | 145 #endif |
| 124 | 146 |
| 125 if (!g_display) { | 147 if (!g_display) { |
| 126 LOG(ERROR) << "eglGetDisplay failed with error " << GetLastEGLErrorString(); | 148 LOG(ERROR) << "eglGetDisplay failed with error " << GetLastEGLErrorString(); |
| 127 return false; | 149 return false; |
| 128 } | 150 } |
| 129 | 151 |
| 130 if (!eglInitialize(g_display, NULL, NULL)) { | 152 if (!eglInitialize(g_display, NULL, NULL)) { |
| 131 LOG(ERROR) << "eglInitialize failed with error " << GetLastEGLErrorString(); | 153 LOG(ERROR) << "eglInitialize failed with error " << GetLastEGLErrorString(); |
| 132 return false; | 154 return false; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 } | 202 } |
| 181 | 203 |
| 182 g_egl_extensions = eglQueryString(g_display, EGL_EXTENSIONS); | 204 g_egl_extensions = eglQueryString(g_display, EGL_EXTENSIONS); |
| 183 g_egl_create_context_robustness_supported = | 205 g_egl_create_context_robustness_supported = |
| 184 HasEGLExtension("EGL_EXT_create_context_robustness"); | 206 HasEGLExtension("EGL_EXT_create_context_robustness"); |
| 185 g_egl_sync_control_supported = | 207 g_egl_sync_control_supported = |
| 186 HasEGLExtension("EGL_CHROMIUM_sync_control"); | 208 HasEGLExtension("EGL_CHROMIUM_sync_control"); |
| 187 g_egl_window_fixed_size_supported = | 209 g_egl_window_fixed_size_supported = |
| 188 HasEGLExtension("EGL_ANGLE_window_fixed_size"); | 210 HasEGLExtension("EGL_ANGLE_window_fixed_size"); |
| 189 | 211 |
| 212 // We always succeed beyond this point so set g_initialized here to avoid |
| 213 // infinite recursion through CreateGLContext and GetDisplay |
| 214 // if g_egl_surfaceless_context_supported. |
| 215 g_initialized = true; |
| 216 g_terminate_pending = false; |
| 217 |
| 190 // TODO(oetuaho@nvidia.com): Surfaceless is disabled on Android as a temporary | 218 // TODO(oetuaho@nvidia.com): Surfaceless is disabled on Android as a temporary |
| 191 // workaround, since code written for Android WebView takes different paths | 219 // workaround, since code written for Android WebView takes different paths |
| 192 // based on whether GL surface objects have underlying EGL surface handles, | 220 // based on whether GL surface objects have underlying EGL surface handles, |
| 193 // conflicting with the use of surfaceless. See https://crbug.com/382349 | 221 // conflicting with the use of surfaceless. See https://crbug.com/382349 |
| 194 #if defined(OS_ANDROID) | 222 #if defined(OS_ANDROID) |
| 195 DCHECK(!g_egl_surfaceless_context_supported); | 223 DCHECK(!g_egl_surfaceless_context_supported); |
| 196 #else | 224 #else |
| 197 // Check if SurfacelessEGL is supported. | 225 // Check if SurfacelessEGL is supported. |
| 198 g_egl_surfaceless_context_supported = | 226 g_egl_surfaceless_context_supported = |
| 199 HasEGLExtension("EGL_KHR_surfaceless_context"); | 227 HasEGLExtension("EGL_KHR_surfaceless_context"); |
| 200 if (g_egl_surfaceless_context_supported) { | 228 if (g_egl_surfaceless_context_supported) { |
| 201 // EGL_KHR_surfaceless_context is supported but ensure | 229 // EGL_KHR_surfaceless_context is supported but ensure |
| 202 // GL_OES_surfaceless_context is also supported. We need a current context | 230 // GL_OES_surfaceless_context is also supported. We need a current context |
| 203 // to query for supported GL extensions. | 231 // to query for supported GL extensions. |
| 204 scoped_refptr<GLSurface> surface = new SurfacelessEGL(Size(1, 1)); | 232 scoped_refptr<GLSurface> surface = new SurfacelessEGL(Size(1, 1)); |
| 205 scoped_refptr<GLContext> context = GLContext::CreateGLContext( | 233 scoped_refptr<GLContext> context = GLContext::CreateGLContext( |
| 206 NULL, surface.get(), PreferIntegratedGpu); | 234 NULL, surface.get(), PreferIntegratedGpu); |
| 207 if (!context->MakeCurrent(surface.get())) | 235 if (!context->MakeCurrent(surface.get())) |
| 208 g_egl_surfaceless_context_supported = false; | 236 g_egl_surfaceless_context_supported = false; |
| 209 | 237 |
| 210 // Ensure context supports GL_OES_surfaceless_context. | 238 // Ensure context supports GL_OES_surfaceless_context. |
| 211 if (g_egl_surfaceless_context_supported) { | 239 if (g_egl_surfaceless_context_supported) { |
| 212 g_egl_surfaceless_context_supported = context->HasExtension( | 240 g_egl_surfaceless_context_supported = context->HasExtension( |
| 213 "GL_OES_surfaceless_context"); | 241 "GL_OES_surfaceless_context"); |
| 214 context->ReleaseCurrent(surface.get()); | 242 context->ReleaseCurrent(surface.get()); |
| 215 } | 243 } |
| 216 } | 244 } |
| 217 #endif | 245 #endif |
| 218 | 246 |
| 219 initialized = true; | |
| 220 | |
| 221 return true; | 247 return true; |
| 222 } | 248 } |
| 223 | 249 |
| 224 EGLDisplay GLSurfaceEGL::GetDisplay() { | 250 EGLDisplay GLSurfaceEGL::GetDisplay() { |
| 251 DCHECK(g_initialized); |
| 225 return g_display; | 252 return g_display; |
| 226 } | 253 } |
| 227 | 254 |
| 255 // static |
| 228 EGLDisplay GLSurfaceEGL::GetHardwareDisplay() { | 256 EGLDisplay GLSurfaceEGL::GetHardwareDisplay() { |
| 257 if (!g_initialized) { |
| 258 bool result = GLSurfaceEGL::InitializeOneOff(); |
| 259 DCHECK(result); |
| 260 } |
| 229 return g_display; | 261 return g_display; |
| 230 } | 262 } |
| 231 | 263 |
| 264 // static |
| 232 EGLNativeDisplayType GLSurfaceEGL::GetNativeDisplay() { | 265 EGLNativeDisplayType GLSurfaceEGL::GetNativeDisplay() { |
| 233 return g_native_display; | 266 if (!g_initialized) { |
| 267 bool result = GLSurfaceEGL::InitializeOneOff(); |
| 268 DCHECK(result); |
| 269 } |
| 270 return g_native_display_type; |
| 234 } | 271 } |
| 235 | 272 |
| 236 const char* GLSurfaceEGL::GetEGLExtensions() { | 273 const char* GLSurfaceEGL::GetEGLExtensions() { |
| 274 // No need for InitializeOneOff. Assume that extensions will not change |
| 275 // after the first initialization. |
| 237 return g_egl_extensions; | 276 return g_egl_extensions; |
| 238 } | 277 } |
| 239 | 278 |
| 240 bool GLSurfaceEGL::HasEGLExtension(const char* name) { | 279 bool GLSurfaceEGL::HasEGLExtension(const char* name) { |
| 241 return ExtensionsContain(GetEGLExtensions(), name); | 280 return ExtensionsContain(GetEGLExtensions(), name); |
| 242 } | 281 } |
| 243 | 282 |
| 244 bool GLSurfaceEGL::IsCreateContextRobustnessSupported() { | 283 bool GLSurfaceEGL::IsCreateContextRobustnessSupported() { |
| 245 return g_egl_create_context_robustness_supported; | 284 return g_egl_create_context_robustness_supported; |
| 246 } | 285 } |
| 247 | 286 |
| 248 bool GLSurfaceEGL::IsEGLSurfacelessContextSupported() { | 287 bool GLSurfaceEGL::IsEGLSurfacelessContextSupported() { |
| 249 return g_egl_surfaceless_context_supported; | 288 return g_egl_surfaceless_context_supported; |
| 250 } | 289 } |
| 251 | 290 |
| 252 GLSurfaceEGL::~GLSurfaceEGL() {} | 291 void GLSurfaceEGL::DestroyAndTerminateDisplay() { |
| 292 DCHECK(g_initialized); |
| 293 DCHECK_EQ(g_num_surfaces, 1); |
| 294 Destroy(); |
| 295 g_terminate_pending = true; |
| 296 } |
| 297 |
| 298 GLSurfaceEGL::~GLSurfaceEGL() { |
| 299 DCHECK_GT(g_num_surfaces, 0) << "Bad surface count"; |
| 300 if (--g_num_surfaces == 0 && g_terminate_pending) { |
| 301 DeinitializeEgl(); |
| 302 g_terminate_pending = false; |
| 303 } |
| 304 } |
| 253 | 305 |
| 254 #if defined(OS_WIN) | 306 #if defined(OS_WIN) |
| 255 static const EGLint kDisplayAttribsWarp[] { | 307 static const EGLint kDisplayAttribsWarp[] { |
| 256 EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, | 308 EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, |
| 257 EGL_PLATFORM_ANGLE_USE_WARP_ANGLE, EGL_TRUE, | 309 EGL_PLATFORM_ANGLE_USE_WARP_ANGLE, EGL_TRUE, |
| 258 EGL_NONE | 310 EGL_NONE |
| 259 }; | 311 }; |
| 260 | 312 |
| 261 // static | 313 // static |
| 262 EGLDisplay GLSurfaceEGL::GetPlatformDisplay( | 314 EGLDisplay GLSurfaceEGL::GetPlatformDisplay( |
| (...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 708 } | 760 } |
| 709 | 761 |
| 710 void* SurfacelessEGL::GetShareHandle() { | 762 void* SurfacelessEGL::GetShareHandle() { |
| 711 return NULL; | 763 return NULL; |
| 712 } | 764 } |
| 713 | 765 |
| 714 SurfacelessEGL::~SurfacelessEGL() { | 766 SurfacelessEGL::~SurfacelessEGL() { |
| 715 } | 767 } |
| 716 | 768 |
| 717 } // namespace gfx | 769 } // namespace gfx |
| OLD | NEW |