Chromium Code Reviews| 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 |