| 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. | |
| 46 | |
| 47 #ifndef EGL_ANGLE_platform_angle | |
| 48 #define EGL_ANGLE_platform_angle 1 | |
| 49 #define EGL_PLATFORM_ANGLE_ANGLE 0x3202 | |
| 50 #define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203 | |
| 51 #define EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE 0x3204 | |
| 52 #define EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE 0x3205 | |
| 53 #define EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE 0x3206 | |
| 54 #endif /* EGL_ANGLE_platform_angle */ | |
| 55 | |
| 56 #ifndef EGL_ANGLE_platform_angle_d3d | |
| 57 #define EGL_ANGLE_platform_angle_d3d 1 | |
| 58 #define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3207 | |
| 59 #define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208 | |
| 60 #define EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE 0x3209 | |
| 61 #define EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE 0x320A | |
| 62 #define EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE 0x320B | |
| 63 #define EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE 0x320C | |
| 64 #endif /* EGL_ANGLE_platform_angle_d3d */ | |
| 65 | |
| 66 #endif // defined(OS_WIN) | |
| 67 | |
| 68 using ui::GetLastEGLErrorString; | 44 using ui::GetLastEGLErrorString; |
| 69 | 45 |
| 70 namespace gfx { | 46 namespace gfx { |
| 71 | 47 |
| 72 #if defined(OS_WIN) | |
| 73 unsigned int NativeViewGLSurfaceEGL::current_swap_generation_ = 0; | |
| 74 unsigned int NativeViewGLSurfaceEGL::swaps_this_generation_ = 0; | |
| 75 unsigned int NativeViewGLSurfaceEGL::last_multiswap_generation_ = 0; | |
| 76 | |
| 77 const unsigned int MULTISWAP_FRAME_VSYNC_THRESHOLD = 60; | |
| 78 #endif | |
| 79 | |
| 80 namespace { | 48 namespace { |
| 81 | 49 |
| 82 EGLConfig g_config; | 50 EGLConfig g_config; |
| 83 EGLDisplay g_display; | 51 EGLDisplay g_display; |
| 84 EGLNativeDisplayType g_native_display_type; | 52 EGLNativeDisplayType g_native_display_type; |
| 85 | 53 |
| 86 // In the Cast environment, we need to destroy the EGLNativeDisplayType and | 54 // In the Cast environment, we need to destroy the EGLNativeDisplayType and |
| 87 // EGLDisplay returned by the GPU platform when we switch to an external app | 55 // EGLDisplay returned by the GPU platform when we switch to an external app |
| 88 // which will temporarily own all screen and GPU resources. | 56 // which will temporarily own all screen and GPU resources. |
| 89 // Even though Chromium is still in the background. | 57 // Even though Chromium is still in the background. |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 DCHECK(g_initialized); | 119 DCHECK(g_initialized); |
| 152 } | 120 } |
| 153 } | 121 } |
| 154 | 122 |
| 155 bool GLSurfaceEGL::InitializeOneOff() { | 123 bool GLSurfaceEGL::InitializeOneOff() { |
| 156 if (g_initialized) | 124 if (g_initialized) |
| 157 return true; | 125 return true; |
| 158 | 126 |
| 159 g_native_display_type = GetPlatformDefaultEGLNativeDisplay(); | 127 g_native_display_type = GetPlatformDefaultEGLNativeDisplay(); |
| 160 | 128 |
| 161 #if defined(OS_WIN) | |
| 162 g_display = GetPlatformDisplay(g_native_display_type); | |
| 163 #else | |
| 164 g_display = eglGetDisplay(g_native_display_type); | 129 g_display = eglGetDisplay(g_native_display_type); |
| 165 #endif | |
| 166 | 130 |
| 167 if (!g_display) { | 131 if (!g_display) { |
| 168 LOG(ERROR) << "eglGetDisplay failed with error " << GetLastEGLErrorString(); | 132 LOG(ERROR) << "eglGetDisplay failed with error " << GetLastEGLErrorString(); |
| 169 return false; | 133 return false; |
| 170 } | 134 } |
| 171 | 135 |
| 172 if (!eglInitialize(g_display, NULL, NULL)) { | 136 if (!eglInitialize(g_display, NULL, NULL)) { |
| 173 LOG(ERROR) << "eglInitialize failed with error " << GetLastEGLErrorString(); | 137 LOG(ERROR) << "eglInitialize failed with error " << GetLastEGLErrorString(); |
| 174 return false; | 138 return false; |
| 175 } | 139 } |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 } | 285 } |
| 322 | 286 |
| 323 GLSurfaceEGL::~GLSurfaceEGL() { | 287 GLSurfaceEGL::~GLSurfaceEGL() { |
| 324 DCHECK_GT(g_num_surfaces, 0) << "Bad surface count"; | 288 DCHECK_GT(g_num_surfaces, 0) << "Bad surface count"; |
| 325 if (--g_num_surfaces == 0 && g_terminate_pending) { | 289 if (--g_num_surfaces == 0 && g_terminate_pending) { |
| 326 DeinitializeEgl(); | 290 DeinitializeEgl(); |
| 327 g_terminate_pending = false; | 291 g_terminate_pending = false; |
| 328 } | 292 } |
| 329 } | 293 } |
| 330 | 294 |
| 331 #if defined(OS_WIN) | |
| 332 static const EGLint kDisplayAttribsWarp[] { | |
| 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 | |
| 343 EGLDisplay GLSurfaceEGL::GetPlatformDisplay( | |
| 344 EGLNativeDisplayType native_display) { | |
| 345 if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseWarp)) { | |
| 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 } | |
| 363 | |
| 364 return eglGetDisplay(native_display); | |
| 365 } | |
| 366 #endif | |
| 367 | |
| 368 NativeViewGLSurfaceEGL::NativeViewGLSurfaceEGL(EGLNativeWindowType window) | 295 NativeViewGLSurfaceEGL::NativeViewGLSurfaceEGL(EGLNativeWindowType window) |
| 369 : window_(window), | 296 : window_(window), |
| 370 surface_(NULL), | 297 surface_(NULL), |
| 371 supports_post_sub_buffer_(false), | 298 supports_post_sub_buffer_(false), |
| 372 config_(NULL), | 299 config_(NULL), |
| 373 size_(1, 1), | 300 size_(1, 1), |
| 374 swap_interval_(1) { | 301 swap_interval_(1) { |
| 375 #if defined(OS_ANDROID) | 302 #if defined(OS_ANDROID) |
| 376 if (window) | 303 if (window) |
| 377 ANativeWindow_acquire(window); | 304 ANativeWindow_acquire(window); |
| 378 #endif | 305 #endif |
| 379 | |
| 380 #if defined(OS_WIN) | |
| 381 vsync_override_ = false; | |
| 382 swap_generation_ = 0; | |
| 383 RECT windowRect; | |
| 384 if (GetClientRect(window_, &windowRect)) | |
| 385 size_ = gfx::Rect(windowRect).size(); | |
| 386 #endif | |
| 387 } | 306 } |
| 388 | 307 |
| 389 bool NativeViewGLSurfaceEGL::Initialize() { | 308 bool NativeViewGLSurfaceEGL::Initialize() { |
| 390 return Initialize(nullptr); | 309 return Initialize(nullptr); |
| 391 } | 310 } |
| 392 | 311 |
| 393 bool NativeViewGLSurfaceEGL::Initialize( | 312 bool NativeViewGLSurfaceEGL::Initialize( |
| 394 scoped_ptr<VSyncProvider> sync_provider) { | 313 scoped_ptr<VSyncProvider> sync_provider) { |
| 395 DCHECK(!surface_); | 314 DCHECK(!surface_); |
| 396 | 315 |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 530 | 449 |
| 531 bool NativeViewGLSurfaceEGL::IsOffscreen() { | 450 bool NativeViewGLSurfaceEGL::IsOffscreen() { |
| 532 return false; | 451 return false; |
| 533 } | 452 } |
| 534 | 453 |
| 535 bool NativeViewGLSurfaceEGL::SwapBuffers() { | 454 bool NativeViewGLSurfaceEGL::SwapBuffers() { |
| 536 TRACE_EVENT2("gpu", "NativeViewGLSurfaceEGL:RealSwapBuffers", | 455 TRACE_EVENT2("gpu", "NativeViewGLSurfaceEGL:RealSwapBuffers", |
| 537 "width", GetSize().width(), | 456 "width", GetSize().width(), |
| 538 "height", GetSize().height()); | 457 "height", GetSize().height()); |
| 539 | 458 |
| 540 #if defined(OS_WIN) | |
| 541 if (swap_interval_ != 0) { | |
| 542 // This code is a simple way of enforcing that we only vsync if one surface | |
| 543 // is swapping per frame. This provides single window cases a stable refresh | |
| 544 // while allowing multi-window cases to not slow down due to multiple syncs | |
| 545 // on a single thread. A better way to fix this problem would be to have | |
| 546 // each surface present on its own thread. | |
| 547 | |
| 548 if (current_swap_generation_ == swap_generation_) { | |
| 549 if (swaps_this_generation_ > 1) | |
| 550 last_multiswap_generation_ = current_swap_generation_; | |
| 551 swaps_this_generation_ = 0; | |
| 552 current_swap_generation_++; | |
| 553 } | |
| 554 | |
| 555 swap_generation_ = current_swap_generation_; | |
| 556 | |
| 557 if (swaps_this_generation_ != 0 || | |
| 558 (current_swap_generation_ - last_multiswap_generation_ < | |
| 559 MULTISWAP_FRAME_VSYNC_THRESHOLD)) { | |
| 560 // Override vsync settings and switch it off | |
| 561 if (!vsync_override_) { | |
| 562 eglSwapInterval(GetDisplay(), 0); | |
| 563 vsync_override_ = true; | |
| 564 } | |
| 565 } else if (vsync_override_) { | |
| 566 // Only one window swapping, so let the normal vsync setting take over | |
| 567 eglSwapInterval(GetDisplay(), swap_interval_); | |
| 568 vsync_override_ = false; | |
| 569 } | |
| 570 | |
| 571 swaps_this_generation_++; | |
| 572 } | |
| 573 #endif | |
| 574 | |
| 575 if (!eglSwapBuffers(GetDisplay(), surface_)) { | 459 if (!eglSwapBuffers(GetDisplay(), surface_)) { |
| 576 DVLOG(1) << "eglSwapBuffers failed with error " | 460 DVLOG(1) << "eglSwapBuffers failed with error " |
| 577 << GetLastEGLErrorString(); | 461 << GetLastEGLErrorString(); |
| 578 return false; | 462 return false; |
| 579 } | 463 } |
| 580 | 464 |
| 581 return true; | 465 return true; |
| 582 } | 466 } |
| 583 | 467 |
| 584 gfx::Size NativeViewGLSurfaceEGL::GetSize() { | 468 gfx::Size NativeViewGLSurfaceEGL::GetSize() { |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 831 } | 715 } |
| 832 | 716 |
| 833 void* SurfacelessEGL::GetShareHandle() { | 717 void* SurfacelessEGL::GetShareHandle() { |
| 834 return NULL; | 718 return NULL; |
| 835 } | 719 } |
| 836 | 720 |
| 837 SurfacelessEGL::~SurfacelessEGL() { | 721 SurfacelessEGL::~SurfacelessEGL() { |
| 838 } | 722 } |
| 839 | 723 |
| 840 } // namespace gfx | 724 } // namespace gfx |
| OLD | NEW |