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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 namespace gfx { | 55 namespace gfx { |
56 | 56 |
57 unsigned int NativeViewGLSurfaceEGL::current_swap_generation_ = 0; | 57 unsigned int NativeViewGLSurfaceEGL::current_swap_generation_ = 0; |
58 | 58 |
59 namespace { | 59 namespace { |
60 | 60 |
61 EGLConfig g_config; | 61 EGLConfig g_config; |
62 EGLDisplay g_display; | 62 EGLDisplay g_display; |
63 EGLNativeDisplayType g_native_display; | 63 EGLNativeDisplayType g_native_display; |
64 | 64 |
| 65 // In the Cast environment, we need to destroy the displayType |
| 66 // returned by the GPU platform when we switch to an external app |
| 67 // which will temporarily own all screen and GPU resources. |
| 68 // Even though Chromium is still in the background. |
| 69 // As such, it must be reinitialized each time we come back to the foreground. |
| 70 bool g_initialized = false; |
| 71 int g_num_surfaces = 0; |
| 72 |
65 const char* g_egl_extensions = NULL; | 73 const char* g_egl_extensions = NULL; |
66 bool g_egl_create_context_robustness_supported = false; | 74 bool g_egl_create_context_robustness_supported = false; |
67 bool g_egl_sync_control_supported = false; | 75 bool g_egl_sync_control_supported = false; |
68 bool g_egl_window_fixed_size_supported = false; | 76 bool g_egl_window_fixed_size_supported = false; |
69 bool g_egl_surfaceless_context_supported = false; | 77 bool g_egl_surfaceless_context_supported = false; |
70 | 78 |
71 class EGLSyncControlVSyncProvider | 79 class EGLSyncControlVSyncProvider |
72 : public gfx::SyncControlVSyncProvider { | 80 : public gfx::SyncControlVSyncProvider { |
73 public: | 81 public: |
74 explicit EGLSyncControlVSyncProvider(EGLSurface surface) | 82 explicit EGLSyncControlVSyncProvider(EGLSurface surface) |
(...skipping 22 matching lines...) Expand all Loading... |
97 bool GetMscRate(int32* numerator, int32* denominator) override { | 105 bool GetMscRate(int32* numerator, int32* denominator) override { |
98 return false; | 106 return false; |
99 } | 107 } |
100 | 108 |
101 private: | 109 private: |
102 EGLSurface surface_; | 110 EGLSurface surface_; |
103 | 111 |
104 DISALLOW_COPY_AND_ASSIGN(EGLSyncControlVSyncProvider); | 112 DISALLOW_COPY_AND_ASSIGN(EGLSyncControlVSyncProvider); |
105 }; | 113 }; |
106 | 114 |
| 115 void DeinitializeEgl() { |
| 116 if (g_initialized) { |
| 117 g_initialized = false; |
| 118 eglTerminate(g_display); |
| 119 } |
| 120 } |
| 121 |
107 } // namespace | 122 } // namespace |
108 | 123 |
109 GLSurfaceEGL::GLSurfaceEGL() {} | 124 GLSurfaceEGL::GLSurfaceEGL() { |
| 125 ++g_num_surfaces; |
| 126 if (!g_initialized) { |
| 127 bool result = GLSurfaceEGL::InitializeOneOff(); |
| 128 DCHECK(result); |
| 129 DCHECK(g_initialized); |
| 130 } |
| 131 } |
110 | 132 |
111 bool GLSurfaceEGL::InitializeOneOff() { | 133 bool GLSurfaceEGL::InitializeOneOff() { |
112 static bool initialized = false; | 134 if (g_initialized) |
113 if (initialized) | |
114 return true; | 135 return true; |
115 | 136 |
116 g_native_display = GetPlatformDefaultEGLNativeDisplay(); | 137 g_native_display = GetPlatformDefaultEGLNativeDisplay(); |
117 | 138 |
118 #if defined(OS_WIN) | 139 #if defined(OS_WIN) |
119 g_display = GetPlatformDisplay(g_native_display); | 140 g_display = GetPlatformDisplay(g_native_display); |
120 #else | 141 #else |
121 g_display = eglGetDisplay(g_native_display); | 142 g_display = eglGetDisplay(g_native_display); |
122 #endif | 143 #endif |
123 | 144 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 } | 200 } |
180 | 201 |
181 g_egl_extensions = eglQueryString(g_display, EGL_EXTENSIONS); | 202 g_egl_extensions = eglQueryString(g_display, EGL_EXTENSIONS); |
182 g_egl_create_context_robustness_supported = | 203 g_egl_create_context_robustness_supported = |
183 HasEGLExtension("EGL_EXT_create_context_robustness"); | 204 HasEGLExtension("EGL_EXT_create_context_robustness"); |
184 g_egl_sync_control_supported = | 205 g_egl_sync_control_supported = |
185 HasEGLExtension("EGL_CHROMIUM_sync_control"); | 206 HasEGLExtension("EGL_CHROMIUM_sync_control"); |
186 g_egl_window_fixed_size_supported = | 207 g_egl_window_fixed_size_supported = |
187 HasEGLExtension("EGL_ANGLE_window_fixed_size"); | 208 HasEGLExtension("EGL_ANGLE_window_fixed_size"); |
188 | 209 |
| 210 // We always succeed beyond this point so set g_initialized here to avoid |
| 211 // infinite recursion through CreateGLContext and GetDisplay |
| 212 // if g_egl_surfaceless_context_supported. |
| 213 g_initialized = true; |
| 214 |
189 // TODO(oetuaho@nvidia.com): Surfaceless is disabled on Android as a temporary | 215 // TODO(oetuaho@nvidia.com): Surfaceless is disabled on Android as a temporary |
190 // workaround, since code written for Android WebView takes different paths | 216 // workaround, since code written for Android WebView takes different paths |
191 // based on whether GL surface objects have underlying EGL surface handles, | 217 // based on whether GL surface objects have underlying EGL surface handles, |
192 // conflicting with the use of surfaceless. See https://crbug.com/382349 | 218 // conflicting with the use of surfaceless. See https://crbug.com/382349 |
193 #if defined(OS_ANDROID) | 219 #if defined(OS_ANDROID) |
194 DCHECK(!g_egl_surfaceless_context_supported); | 220 DCHECK(!g_egl_surfaceless_context_supported); |
195 #else | 221 #else |
196 // Check if SurfacelessEGL is supported. | 222 // Check if SurfacelessEGL is supported. |
197 g_egl_surfaceless_context_supported = | 223 g_egl_surfaceless_context_supported = |
198 HasEGLExtension("EGL_KHR_surfaceless_context"); | 224 HasEGLExtension("EGL_KHR_surfaceless_context"); |
199 if (g_egl_surfaceless_context_supported) { | 225 if (g_egl_surfaceless_context_supported) { |
200 // EGL_KHR_surfaceless_context is supported but ensure | 226 // EGL_KHR_surfaceless_context is supported but ensure |
201 // GL_OES_surfaceless_context is also supported. We need a current context | 227 // GL_OES_surfaceless_context is also supported. We need a current context |
202 // to query for supported GL extensions. | 228 // to query for supported GL extensions. |
203 scoped_refptr<GLSurface> surface = new SurfacelessEGL(Size(1, 1)); | 229 scoped_refptr<GLSurface> surface = new SurfacelessEGL(Size(1, 1)); |
204 scoped_refptr<GLContext> context = GLContext::CreateGLContext( | 230 scoped_refptr<GLContext> context = GLContext::CreateGLContext( |
205 NULL, surface.get(), PreferIntegratedGpu); | 231 NULL, surface.get(), PreferIntegratedGpu); |
206 if (!context->MakeCurrent(surface.get())) | 232 if (!context->MakeCurrent(surface.get())) |
207 g_egl_surfaceless_context_supported = false; | 233 g_egl_surfaceless_context_supported = false; |
208 | 234 |
209 // Ensure context supports GL_OES_surfaceless_context. | 235 // Ensure context supports GL_OES_surfaceless_context. |
210 if (g_egl_surfaceless_context_supported) { | 236 if (g_egl_surfaceless_context_supported) { |
211 g_egl_surfaceless_context_supported = context->HasExtension( | 237 g_egl_surfaceless_context_supported = context->HasExtension( |
212 "GL_OES_surfaceless_context"); | 238 "GL_OES_surfaceless_context"); |
213 context->ReleaseCurrent(surface.get()); | 239 context->ReleaseCurrent(surface.get()); |
214 } | 240 } |
215 } | 241 } |
216 #endif | 242 #endif |
217 | 243 |
218 initialized = true; | |
219 | |
220 return true; | 244 return true; |
221 } | 245 } |
222 | 246 |
223 EGLDisplay GLSurfaceEGL::GetDisplay() { | 247 EGLDisplay GLSurfaceEGL::GetDisplay() { |
| 248 if (!g_initialized) { |
| 249 bool result = GLSurfaceEGL::InitializeOneOff(); |
| 250 DCHECK(result); |
| 251 } |
224 return g_display; | 252 return g_display; |
225 } | 253 } |
226 | 254 |
227 EGLDisplay GLSurfaceEGL::GetHardwareDisplay() { | 255 EGLDisplay GLSurfaceEGL::GetHardwareDisplay() { |
| 256 if (!g_initialized) { |
| 257 bool result = GLSurfaceEGL::InitializeOneOff(); |
| 258 DCHECK(result); |
| 259 } |
228 return g_display; | 260 return g_display; |
229 } | 261 } |
230 | 262 |
231 EGLNativeDisplayType GLSurfaceEGL::GetNativeDisplay() { | 263 EGLNativeDisplayType GLSurfaceEGL::GetNativeDisplay() { |
| 264 if (!g_initialized) { |
| 265 bool result = GLSurfaceEGL::InitializeOneOff(); |
| 266 DCHECK(result); |
| 267 } |
232 return g_native_display; | 268 return g_native_display; |
233 } | 269 } |
234 | 270 |
235 const char* GLSurfaceEGL::GetEGLExtensions() { | 271 const char* GLSurfaceEGL::GetEGLExtensions() { |
| 272 // No need for InitializeOneOff. Assume that extensions will not change |
| 273 // after the first initialization. |
236 return g_egl_extensions; | 274 return g_egl_extensions; |
237 } | 275 } |
238 | 276 |
239 bool GLSurfaceEGL::HasEGLExtension(const char* name) { | 277 bool GLSurfaceEGL::HasEGLExtension(const char* name) { |
240 return ExtensionsContain(GetEGLExtensions(), name); | 278 return ExtensionsContain(GetEGLExtensions(), name); |
241 } | 279 } |
242 | 280 |
243 bool GLSurfaceEGL::IsCreateContextRobustnessSupported() { | 281 bool GLSurfaceEGL::IsCreateContextRobustnessSupported() { |
244 return g_egl_create_context_robustness_supported; | 282 return g_egl_create_context_robustness_supported; |
245 } | 283 } |
246 | 284 |
247 bool GLSurfaceEGL::IsEGLSurfacelessContextSupported() { | 285 bool GLSurfaceEGL::IsEGLSurfacelessContextSupported() { |
248 return g_egl_surfaceless_context_supported; | 286 return g_egl_surfaceless_context_supported; |
249 } | 287 } |
250 | 288 |
251 GLSurfaceEGL::~GLSurfaceEGL() {} | 289 GLSurfaceEGL::~GLSurfaceEGL() { |
| 290 DCHECK_GT(g_num_surfaces, 0) << "Bad surface count"; |
| 291 if (--g_num_surfaces == 0) { |
| 292 DVLOG(1) << "Destroyed last EGL surface. Deinitializing."; |
| 293 DeinitializeEgl(); |
| 294 } |
| 295 } |
252 | 296 |
253 #if defined(OS_WIN) | 297 #if defined(OS_WIN) |
254 static const EGLint kDisplayAttribsWarp[] { | 298 static const EGLint kDisplayAttribsWarp[] { |
255 EGL_PLATFORM_ANGLE_TYPE_ANGLE, | 299 EGL_PLATFORM_ANGLE_TYPE_ANGLE, |
256 EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE, | 300 EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE, |
257 EGL_NONE | 301 EGL_NONE |
258 }; | 302 }; |
259 | 303 |
260 // static | 304 // static |
261 EGLDisplay GLSurfaceEGL::GetPlatformDisplay( | 305 EGLDisplay GLSurfaceEGL::GetPlatformDisplay( |
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
738 } | 782 } |
739 | 783 |
740 void* SurfacelessEGL::GetShareHandle() { | 784 void* SurfacelessEGL::GetShareHandle() { |
741 return NULL; | 785 return NULL; |
742 } | 786 } |
743 | 787 |
744 SurfacelessEGL::~SurfacelessEGL() { | 788 SurfacelessEGL::~SurfacelessEGL() { |
745 } | 789 } |
746 | 790 |
747 } // namespace gfx | 791 } // namespace gfx |
OLD | NEW |