| 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 23 matching lines...) Expand all Loading... |
| 34 #endif | 34 #endif |
| 35 | 35 |
| 36 #if !defined(EGL_FIXED_SIZE_ANGLE) | 36 #if !defined(EGL_FIXED_SIZE_ANGLE) |
| 37 #define EGL_FIXED_SIZE_ANGLE 0x3201 | 37 #define EGL_FIXED_SIZE_ANGLE 0x3201 |
| 38 #endif | 38 #endif |
| 39 | 39 |
| 40 #if !defined(EGL_OPENGL_ES3_BIT) | 40 #if !defined(EGL_OPENGL_ES3_BIT) |
| 41 #define EGL_OPENGL_ES3_BIT 0x00000040 | 41 #define EGL_OPENGL_ES3_BIT 0x00000040 |
| 42 #endif | 42 #endif |
| 43 | 43 |
| 44 #if defined(OS_WIN) | |
| 45 // From ANGLE's egl/eglext.h. | 44 // From ANGLE's egl/eglext.h. |
| 46 | 45 |
| 47 #ifndef EGL_ANGLE_platform_angle | 46 #ifndef EGL_ANGLE_platform_angle |
| 48 #define EGL_ANGLE_platform_angle 1 | 47 #define EGL_ANGLE_platform_angle 1 |
| 49 #define EGL_PLATFORM_ANGLE_ANGLE 0x3202 | 48 #define EGL_PLATFORM_ANGLE_ANGLE 0x3202 |
| 50 #define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203 | 49 #define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203 |
| 51 #define EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE 0x3204 | 50 #define EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE 0x3204 |
| 52 #define EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE 0x3205 | 51 #define EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE 0x3205 |
| 53 #define EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE 0x3206 | 52 #define EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE 0x3206 |
| 54 #endif /* EGL_ANGLE_platform_angle */ | 53 #endif /* EGL_ANGLE_platform_angle */ |
| 55 | 54 |
| 56 #ifndef EGL_ANGLE_platform_angle_d3d | 55 #ifndef EGL_ANGLE_platform_angle_d3d |
| 57 #define EGL_ANGLE_platform_angle_d3d 1 | 56 #define EGL_ANGLE_platform_angle_d3d 1 |
| 58 #define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3207 | 57 #define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3207 |
| 59 #define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208 | 58 #define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208 |
| 60 #define EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE 0x3209 | 59 #define EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE 0x3209 |
| 61 #define EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE 0x320A | 60 #define EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE 0x320A |
| 62 #define EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE 0x320B | 61 #define EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE 0x320B |
| 63 #define EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE 0x320C | 62 #define EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE 0x320C |
| 64 #endif /* EGL_ANGLE_platform_angle_d3d */ | 63 #endif /* EGL_ANGLE_platform_angle_d3d */ |
| 65 | 64 |
| 66 #endif // defined(OS_WIN) | |
| 67 | |
| 68 using ui::GetLastEGLErrorString; | 65 using ui::GetLastEGLErrorString; |
| 69 | 66 |
| 70 namespace gfx { | 67 namespace gfx { |
| 71 | 68 |
| 72 #if defined(OS_WIN) | 69 #if defined(OS_WIN) |
| 73 unsigned int NativeViewGLSurfaceEGL::current_swap_generation_ = 0; | 70 unsigned int NativeViewGLSurfaceEGL::current_swap_generation_ = 0; |
| 74 unsigned int NativeViewGLSurfaceEGL::swaps_this_generation_ = 0; | 71 unsigned int NativeViewGLSurfaceEGL::swaps_this_generation_ = 0; |
| 75 unsigned int NativeViewGLSurfaceEGL::last_multiswap_generation_ = 0; | 72 unsigned int NativeViewGLSurfaceEGL::last_multiswap_generation_ = 0; |
| 76 | 73 |
| 77 const unsigned int MULTISWAP_FRAME_VSYNC_THRESHOLD = 60; | 74 const unsigned int MULTISWAP_FRAME_VSYNC_THRESHOLD = 60; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 DISALLOW_COPY_AND_ASSIGN(EGLSyncControlVSyncProvider); | 131 DISALLOW_COPY_AND_ASSIGN(EGLSyncControlVSyncProvider); |
| 135 }; | 132 }; |
| 136 | 133 |
| 137 void DeinitializeEgl() { | 134 void DeinitializeEgl() { |
| 138 if (g_initialized) { | 135 if (g_initialized) { |
| 139 g_initialized = false; | 136 g_initialized = false; |
| 140 eglTerminate(g_display); | 137 eglTerminate(g_display); |
| 141 } | 138 } |
| 142 } | 139 } |
| 143 | 140 |
| 141 EGLDisplay GetPlatformANGLEDisplay(EGLNativeDisplayType native_display, |
| 142 EGLenum platform_type, |
| 143 EGLenum device_type) { |
| 144 const EGLint display_attribs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, |
| 145 platform_type, |
| 146 EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, |
| 147 device_type, |
| 148 EGL_NONE}; |
| 149 return eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, |
| 150 reinterpret_cast<void*>(native_display), |
| 151 display_attribs); |
| 152 } |
| 153 |
| 154 enum DisplayType { DEFAULT, SWIFT_SHADER, ANGLE_WARP, ANGLE_D3D9, ANGLE_D3D11 }; |
| 155 |
| 156 EGLDisplay GetDisplayFromType(DisplayType display_type, |
| 157 EGLNativeDisplayType native_display) { |
| 158 switch (display_type) { |
| 159 case DEFAULT: |
| 160 case SWIFT_SHADER: |
| 161 return eglGetDisplay(native_display); |
| 162 case ANGLE_WARP: |
| 163 return GetPlatformANGLEDisplay(native_display, |
| 164 EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, |
| 165 EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE); |
| 166 case ANGLE_D3D9: |
| 167 return GetPlatformANGLEDisplay( |
| 168 native_display, EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE, |
| 169 EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE); |
| 170 case ANGLE_D3D11: |
| 171 return GetPlatformANGLEDisplay( |
| 172 native_display, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, |
| 173 EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE); |
| 174 default: |
| 175 NOTREACHED(); |
| 176 return EGL_NO_DISPLAY; |
| 177 } |
| 178 } |
| 179 |
| 180 const char* DisplayTypeString(DisplayType display_type) { |
| 181 switch (display_type) { |
| 182 case DEFAULT: |
| 183 return "Default"; |
| 184 case SWIFT_SHADER: |
| 185 return "SwiftShader"; |
| 186 case ANGLE_WARP: |
| 187 return "WARP"; |
| 188 case ANGLE_D3D9: |
| 189 return "D3D9"; |
| 190 case ANGLE_D3D11: |
| 191 return "D3D11"; |
| 192 default: |
| 193 NOTREACHED(); |
| 194 return "Err"; |
| 195 } |
| 196 } |
| 197 |
| 198 void GetInitDisplays(bool supports_angle_d3d, |
| 199 std::vector<DisplayType>* init_displays) { |
| 200 const base::CommandLine* command_line = |
| 201 base::CommandLine::ForCurrentProcess(); |
| 202 bool using_swift_shader = |
| 203 command_line->GetSwitchValueASCII(switches::kUseGL) == "swiftshader"; |
| 204 |
| 205 // SwiftShader does not use the platform extensions |
| 206 if (using_swift_shader) { |
| 207 init_displays->push_back(SWIFT_SHADER); |
| 208 return; |
| 209 } |
| 210 |
| 211 // If we're missing the ANGLE extensions, fall back to default. |
| 212 if (!supports_angle_d3d) { |
| 213 init_displays->push_back(DEFAULT); |
| 214 return; |
| 215 } |
| 216 |
| 217 if (command_line->HasSwitch(switches::kUseWarp)) { |
| 218 init_displays->push_back(ANGLE_WARP); |
| 219 return; |
| 220 } |
| 221 |
| 222 if (command_line->HasSwitch(switches::kDisableD3D11)) { |
| 223 init_displays->push_back(ANGLE_D3D9); |
| 224 return; |
| 225 } |
| 226 |
| 227 // Default mode for ANGLE - try D3D11, else try D3D9 |
| 228 init_displays->push_back(ANGLE_D3D11); |
| 229 init_displays->push_back(ANGLE_D3D9); |
| 230 } |
| 231 |
| 144 } // namespace | 232 } // namespace |
| 145 | 233 |
| 146 GLSurfaceEGL::GLSurfaceEGL() { | 234 GLSurfaceEGL::GLSurfaceEGL() { |
| 147 ++g_num_surfaces; | 235 ++g_num_surfaces; |
| 148 if (!g_initialized) { | 236 if (!g_initialized) { |
| 149 bool result = GLSurfaceEGL::InitializeOneOff(); | 237 bool result = GLSurfaceEGL::InitializeOneOff(); |
| 150 DCHECK(result); | 238 DCHECK(result); |
| 151 DCHECK(g_initialized); | 239 DCHECK(g_initialized); |
| 152 } | 240 } |
| 153 } | 241 } |
| 154 | 242 |
| 155 bool GLSurfaceEGL::InitializeOneOff() { | 243 bool GLSurfaceEGL::InitializeOneOff() { |
| 156 if (g_initialized) | 244 if (g_initialized) |
| 157 return true; | 245 return true; |
| 158 | 246 |
| 159 g_native_display_type = GetPlatformDefaultEGLNativeDisplay(); | 247 InitializeDisplay(); |
| 160 | 248 if (g_display == EGL_NO_DISPLAY) |
| 161 #if defined(OS_WIN) | |
| 162 g_display = GetPlatformDisplay(g_native_display_type); | |
| 163 #else | |
| 164 g_display = eglGetDisplay(g_native_display_type); | |
| 165 #endif | |
| 166 | |
| 167 if (!g_display) { | |
| 168 LOG(ERROR) << "eglGetDisplay failed with error " << GetLastEGLErrorString(); | |
| 169 return false; | 249 return false; |
| 170 } | |
| 171 | |
| 172 if (!eglInitialize(g_display, NULL, NULL)) { | |
| 173 LOG(ERROR) << "eglInitialize failed with error " << GetLastEGLErrorString(); | |
| 174 return false; | |
| 175 } | |
| 176 | 250 |
| 177 // Choose an EGL configuration. | 251 // Choose an EGL configuration. |
| 178 // On X this is only used for PBuffer surfaces. | 252 // On X this is only used for PBuffer surfaces. |
| 179 EGLint renderable_type = EGL_OPENGL_ES2_BIT; | 253 EGLint renderable_type = EGL_OPENGL_ES2_BIT; |
| 180 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 254 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 181 switches::kEnableUnsafeES3APIs)) { | 255 switches::kEnableUnsafeES3APIs)) { |
| 182 renderable_type = EGL_OPENGL_ES3_BIT; | 256 renderable_type = EGL_OPENGL_ES3_BIT; |
| 183 } | 257 } |
| 184 const EGLint kConfigAttribs[] = { | 258 const EGLint kConfigAttribs[] = { |
| 185 EGL_BUFFER_SIZE, 32, | 259 EGL_BUFFER_SIZE, 32, |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 } | 395 } |
| 322 | 396 |
| 323 GLSurfaceEGL::~GLSurfaceEGL() { | 397 GLSurfaceEGL::~GLSurfaceEGL() { |
| 324 DCHECK_GT(g_num_surfaces, 0) << "Bad surface count"; | 398 DCHECK_GT(g_num_surfaces, 0) << "Bad surface count"; |
| 325 if (--g_num_surfaces == 0 && g_terminate_pending) { | 399 if (--g_num_surfaces == 0 && g_terminate_pending) { |
| 326 DeinitializeEgl(); | 400 DeinitializeEgl(); |
| 327 g_terminate_pending = false; | 401 g_terminate_pending = false; |
| 328 } | 402 } |
| 329 } | 403 } |
| 330 | 404 |
| 331 #if defined(OS_WIN) | 405 // InitializeDisplay is necessary because the static binding code |
| 332 static const EGLint kDisplayAttribsWarp[] { | 406 // needs a full Display init before it can query the Display extensions. |
| 333 EGL_PLATFORM_ANGLE_TYPE_ANGLE, | |
| 334 EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, | |
| 335 | |
| 336 EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, | |
| 337 EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE, | |
| 338 | |
| 339 EGL_NONE | |
| 340 }; | |
| 341 | |
| 342 // static | 407 // static |
| 343 EGLDisplay GLSurfaceEGL::GetPlatformDisplay( | 408 EGLDisplay GLSurfaceEGL::InitializeDisplay() { |
| 344 EGLNativeDisplayType native_display) { | 409 if (g_display != EGL_NO_DISPLAY) { |
| 345 if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseWarp)) { | 410 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 } | 411 } |
| 363 | 412 |
| 364 return eglGetDisplay(native_display); | 413 g_native_display_type = GetPlatformDefaultEGLNativeDisplay(); |
| 414 |
| 415 // If EGL_EXT_client_extensions not supported this call to eglQueryString |
| 416 // will return NULL. |
| 417 const char* client_extensions = |
| 418 eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); |
| 419 |
| 420 bool supports_angle_d3d = false; |
| 421 // Check for availability of ANGLE extensions. |
| 422 if (client_extensions) { |
| 423 supports_angle_d3d = |
| 424 ExtensionsContain(client_extensions, "ANGLE_platform_angle") && |
| 425 ExtensionsContain(client_extensions, "ANGLE_platform_angle_d3d"); |
| 426 } |
| 427 |
| 428 std::vector<DisplayType> init_displays; |
| 429 GetInitDisplays(supports_angle_d3d, &init_displays); |
| 430 |
| 431 for (size_t disp_index = 0; disp_index < init_displays.size(); ++disp_index) { |
| 432 DisplayType display_type = init_displays[disp_index]; |
| 433 EGLDisplay display = |
| 434 GetDisplayFromType(display_type, g_native_display_type); |
| 435 if (display == EGL_NO_DISPLAY) { |
| 436 LOG(ERROR) << "EGL display query failed with error " |
| 437 << GetLastEGLErrorString(); |
| 438 } |
| 439 |
| 440 if (!eglInitialize(display, nullptr, nullptr)) { |
| 441 bool is_last = disp_index == init_displays.size() - 1; |
| 442 |
| 443 LOG(ERROR) << "eglInitialize " << DisplayTypeString(display_type) |
| 444 << " failed with error " << GetLastEGLErrorString() |
| 445 << (is_last ? "" : ", trying next display type"); |
| 446 } else { |
| 447 g_display = display; |
| 448 break; |
| 449 } |
| 450 } |
| 451 |
| 452 return g_display; |
| 365 } | 453 } |
| 366 #endif | |
| 367 | 454 |
| 368 NativeViewGLSurfaceEGL::NativeViewGLSurfaceEGL(EGLNativeWindowType window) | 455 NativeViewGLSurfaceEGL::NativeViewGLSurfaceEGL(EGLNativeWindowType window) |
| 369 : window_(window), | 456 : window_(window), |
| 370 surface_(NULL), | 457 surface_(NULL), |
| 371 supports_post_sub_buffer_(false), | 458 supports_post_sub_buffer_(false), |
| 372 config_(NULL), | 459 config_(NULL), |
| 373 size_(1, 1), | 460 size_(1, 1), |
| 374 swap_interval_(1) { | 461 swap_interval_(1) { |
| 375 #if defined(OS_ANDROID) | 462 #if defined(OS_ANDROID) |
| 376 if (window) | 463 if (window) |
| (...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 831 } | 918 } |
| 832 | 919 |
| 833 void* SurfacelessEGL::GetShareHandle() { | 920 void* SurfacelessEGL::GetShareHandle() { |
| 834 return NULL; | 921 return NULL; |
| 835 } | 922 } |
| 836 | 923 |
| 837 SurfacelessEGL::~SurfacelessEGL() { | 924 SurfacelessEGL::~SurfacelessEGL() { |
| 838 } | 925 } |
| 839 | 926 |
| 840 } // namespace gfx | 927 } // namespace gfx |
| OLD | NEW |