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 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
134 DISALLOW_COPY_AND_ASSIGN(EGLSyncControlVSyncProvider); | 134 DISALLOW_COPY_AND_ASSIGN(EGLSyncControlVSyncProvider); |
135 }; | 135 }; |
136 | 136 |
137 void DeinitializeEgl() { | 137 void DeinitializeEgl() { |
138 if (g_initialized) { | 138 if (g_initialized) { |
139 g_initialized = false; | 139 g_initialized = false; |
140 eglTerminate(g_display); | 140 eglTerminate(g_display); |
141 } | 141 } |
142 } | 142 } |
143 | 143 |
144 #if defined(OS_WIN) | |
145 EGLDisplay GetPlatformANGLEDisplay(EGLNativeDisplayType native_display, | |
146 EGLenum platform_type, | |
147 EGLenum device_type) { | |
148 const EGLint display_attribs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, | |
149 platform_type, | |
150 EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, | |
151 device_type, | |
152 EGL_NONE}; | |
153 return eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, native_display, | |
154 display_attribs); | |
155 } | |
156 | |
157 enum DisplayType { DEFAULT, SWIFT_SHADER, ANGLE_WARP, ANGLE_D3D9, ANGLE_D3D11 }; | |
158 | |
159 EGLDisplay GetDisplayFromType(DisplayType display_type, | |
160 EGLNativeDisplayType native_display) { | |
161 switch (display_type) { | |
162 case DEFAULT: | |
163 case SWIFT_SHADER: | |
164 return eglGetDisplay(native_display); | |
165 case ANGLE_WARP: | |
166 return GetPlatformANGLEDisplay(native_display, | |
167 EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, | |
168 EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE); | |
169 case ANGLE_D3D9: | |
170 return GetPlatformANGLEDisplay( | |
171 native_display, EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE, | |
172 EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE); | |
173 case ANGLE_D3D11: | |
174 return GetPlatformANGLEDisplay( | |
175 native_display, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, | |
176 EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE); | |
177 default: | |
178 NOTREACHED(); | |
179 return EGL_NO_DISPLAY; | |
180 } | |
181 } | |
182 | |
183 const char* DisplayTypeString(DisplayType display_type) { | |
184 switch (display_type) { | |
185 case DEFAULT: | |
186 return "Default"; | |
187 case SWIFT_SHADER: | |
188 return "SwiftShader"; | |
189 case ANGLE_WARP: | |
190 return "WARP"; | |
191 case ANGLE_D3D9: | |
192 return "D3D9"; | |
193 case ANGLE_D3D11: | |
194 return "D3D11"; | |
195 default: | |
196 NOTREACHED(); | |
197 return "Err"; | |
198 } | |
199 } | |
200 | |
201 void GetInitDisplays(bool supports_angle_d3d, | |
202 std::vector<DisplayType>* init_displays) { | |
203 const base::CommandLine* command_line = | |
204 base::CommandLine::ForCurrentProcess(); | |
205 bool using_swift_shader = | |
206 command_line->GetSwitchValueASCII(switches::kUseGL) == "swiftshader"; | |
207 | |
208 // SwiftShader does not use the platform extensions | |
209 if (using_swift_shader) { | |
210 init_displays->push_back(SWIFT_SHADER); | |
211 return; | |
212 } | |
213 | |
214 // If we're missing the ANGLE extensions, fall back to default. | |
215 if (!supports_angle_d3d) { | |
216 init_displays->push_back(DEFAULT); | |
217 return; | |
218 } | |
219 | |
220 if (command_line->HasSwitch(switches::kUseWarp)) { | |
221 init_displays->push_back(ANGLE_WARP); | |
222 return; | |
223 } | |
224 | |
225 if (command_line->HasSwitch(switches::kDisableD3D11)) { | |
226 init_displays->push_back(ANGLE_D3D9); | |
227 return; | |
228 } | |
229 | |
230 // Default mode for ANGLE - try D3D11, else try D3D9 | |
231 init_displays->push_back(ANGLE_D3D11); | |
232 init_displays->push_back(ANGLE_D3D9); | |
233 } | |
piman
2015/04/23 21:03:30
I like this, it's easier to follow with the logic
| |
234 | |
235 #endif | |
236 | |
144 } // namespace | 237 } // namespace |
145 | 238 |
146 GLSurfaceEGL::GLSurfaceEGL() { | 239 GLSurfaceEGL::GLSurfaceEGL() { |
147 ++g_num_surfaces; | 240 ++g_num_surfaces; |
148 if (!g_initialized) { | 241 if (!g_initialized) { |
149 bool result = GLSurfaceEGL::InitializeOneOff(); | 242 bool result = GLSurfaceEGL::InitializeOneOff(); |
150 DCHECK(result); | 243 DCHECK(result); |
151 DCHECK(g_initialized); | 244 DCHECK(g_initialized); |
152 } | 245 } |
153 } | 246 } |
154 | 247 |
155 bool GLSurfaceEGL::InitializeOneOff() { | 248 bool GLSurfaceEGL::InitializeOneOff() { |
156 if (g_initialized) | 249 if (g_initialized) |
157 return true; | 250 return true; |
158 | 251 |
252 #if defined(OS_WIN) | |
253 InitializeDisplay(); | |
254 if (g_display == EGL_NO_DISPLAY) | |
255 return false; | |
256 #else | |
159 g_native_display_type = GetPlatformDefaultEGLNativeDisplay(); | 257 g_native_display_type = GetPlatformDefaultEGLNativeDisplay(); |
160 | 258 |
161 #if defined(OS_WIN) | |
162 g_display = GetPlatformDisplay(g_native_display_type); | |
163 #else | |
164 g_display = eglGetDisplay(g_native_display_type); | 259 g_display = eglGetDisplay(g_native_display_type); |
165 #endif | |
166 | 260 |
167 if (!g_display) { | 261 if (!g_display) { |
168 LOG(ERROR) << "eglGetDisplay failed with error " << GetLastEGLErrorString(); | 262 LOG(ERROR) << "eglGetDisplay failed with error " << GetLastEGLErrorString(); |
169 return false; | 263 return false; |
170 } | 264 } |
171 | 265 |
172 if (!eglInitialize(g_display, NULL, NULL)) { | 266 bool egl_init_success = |
267 (eglInitialize(g_display, nullptr, nullptr) == EGL_TRUE); | |
268 | |
269 if (!egl_init_success) { | |
173 LOG(ERROR) << "eglInitialize failed with error " << GetLastEGLErrorString(); | 270 LOG(ERROR) << "eglInitialize failed with error " << GetLastEGLErrorString(); |
174 return false; | 271 return false; |
175 } | 272 } |
273 #endif | |
176 | 274 |
177 // Choose an EGL configuration. | 275 // Choose an EGL configuration. |
178 // On X this is only used for PBuffer surfaces. | 276 // On X this is only used for PBuffer surfaces. |
179 EGLint renderable_type = EGL_OPENGL_ES2_BIT; | 277 EGLint renderable_type = EGL_OPENGL_ES2_BIT; |
180 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 278 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
181 switches::kEnableUnsafeES3APIs)) { | 279 switches::kEnableUnsafeES3APIs)) { |
182 renderable_type = EGL_OPENGL_ES3_BIT; | 280 renderable_type = EGL_OPENGL_ES3_BIT; |
183 } | 281 } |
184 const EGLint kConfigAttribs[] = { | 282 const EGLint kConfigAttribs[] = { |
185 EGL_BUFFER_SIZE, 32, | 283 EGL_BUFFER_SIZE, 32, |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
322 | 420 |
323 GLSurfaceEGL::~GLSurfaceEGL() { | 421 GLSurfaceEGL::~GLSurfaceEGL() { |
324 DCHECK_GT(g_num_surfaces, 0) << "Bad surface count"; | 422 DCHECK_GT(g_num_surfaces, 0) << "Bad surface count"; |
325 if (--g_num_surfaces == 0 && g_terminate_pending) { | 423 if (--g_num_surfaces == 0 && g_terminate_pending) { |
326 DeinitializeEgl(); | 424 DeinitializeEgl(); |
327 g_terminate_pending = false; | 425 g_terminate_pending = false; |
328 } | 426 } |
329 } | 427 } |
330 | 428 |
331 #if defined(OS_WIN) | 429 #if defined(OS_WIN) |
332 static const EGLint kDisplayAttribsWarp[] { | |
333 EGL_PLATFORM_ANGLE_TYPE_ANGLE, | |
334 EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, | |
335 | 430 |
336 EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, | 431 // InitializeDisplay is necessary because the static binding code |
337 EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE, | 432 // needs a full Display init before it can query the Display extensions. |
338 | |
339 EGL_NONE | |
340 }; | |
341 | |
342 // static | 433 // static |
343 EGLDisplay GLSurfaceEGL::GetPlatformDisplay( | 434 EGLDisplay GLSurfaceEGL::InitializeDisplay() { |
344 EGLNativeDisplayType native_display) { | 435 if (g_display != EGL_NO_DISPLAY) { |
345 if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseWarp)) { | 436 return g_display; |
346 // Check for availability of WARP via ANGLE extension. | |
347 bool supports_warp = false; | |
348 const char* no_display_extensions = eglQueryString(EGL_NO_DISPLAY, | |
349 EGL_EXTENSIONS); | |
350 // If EGL_EXT_client_extensions not supported this call to eglQueryString | |
351 // will return NULL. | |
352 if (no_display_extensions) | |
353 supports_warp = | |
354 ExtensionsContain(no_display_extensions, "ANGLE_platform_angle") && | |
355 ExtensionsContain(no_display_extensions, "ANGLE_platform_angle_d3d"); | |
356 | |
357 if (!supports_warp) | |
358 return NULL; | |
359 | |
360 return eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, native_display, | |
361 kDisplayAttribsWarp); | |
362 } | 437 } |
363 | 438 |
364 return eglGetDisplay(native_display); | 439 g_native_display_type = GetPlatformDefaultEGLNativeDisplay(); |
440 | |
441 // If EGL_EXT_client_extensions not supported this call to eglQueryString | |
442 // will return NULL. | |
443 const char* client_extensions = | |
444 eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); | |
445 | |
446 bool supports_angle_d3d = false; | |
447 // Check for availability of ANGLE extensions. | |
448 if (client_extensions) { | |
449 supports_angle_d3d = | |
450 ExtensionsContain(client_extensions, "ANGLE_platform_angle") && | |
451 ExtensionsContain(client_extensions, "ANGLE_platform_angle_d3d"); | |
452 } | |
453 | |
454 std::vector<DisplayType> init_displays; | |
455 GetInitDisplays(supports_angle_d3d, &init_displays); | |
456 | |
457 for (size_t disp_index = 0; disp_index < init_displays.size(); ++disp_index) { | |
458 DisplayType display_type = init_displays[disp_index]; | |
459 EGLDisplay display = | |
460 GetDisplayFromType(display_type, g_native_display_type); | |
461 if (display == EGL_NO_DISPLAY) { | |
462 LOG(ERROR) << "EGL display query failed with error " | |
463 << GetLastEGLErrorString(); | |
464 } | |
465 | |
466 if (!eglInitialize(display, nullptr, nullptr)) { | |
467 bool is_last = disp_index == init_displays.size() - 1; | |
468 | |
469 LOG(ERROR) << "eglInitialize " << DisplayTypeString(display_type) | |
470 << " failed with error " << GetLastEGLErrorString() | |
471 << (is_last ? "" : ", trying next display type"); | |
472 } else { | |
473 g_display = display; | |
474 break; | |
475 } | |
476 } | |
477 | |
478 return g_display; | |
365 } | 479 } |
480 | |
366 #endif | 481 #endif |
367 | 482 |
368 NativeViewGLSurfaceEGL::NativeViewGLSurfaceEGL(EGLNativeWindowType window) | 483 NativeViewGLSurfaceEGL::NativeViewGLSurfaceEGL(EGLNativeWindowType window) |
369 : window_(window), | 484 : window_(window), |
370 surface_(NULL), | 485 surface_(NULL), |
371 supports_post_sub_buffer_(false), | 486 supports_post_sub_buffer_(false), |
372 config_(NULL), | 487 config_(NULL), |
373 size_(1, 1), | 488 size_(1, 1), |
374 swap_interval_(1) { | 489 swap_interval_(1) { |
375 #if defined(OS_ANDROID) | 490 #if defined(OS_ANDROID) |
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
831 } | 946 } |
832 | 947 |
833 void* SurfacelessEGL::GetShareHandle() { | 948 void* SurfacelessEGL::GetShareHandle() { |
834 return NULL; | 949 return NULL; |
835 } | 950 } |
836 | 951 |
837 SurfacelessEGL::~SurfacelessEGL() { | 952 SurfacelessEGL::~SurfacelessEGL() { |
838 } | 953 } |
839 | 954 |
840 } // namespace gfx | 955 } // namespace gfx |
OLD | NEW |