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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 #endif | 50 #endif |
51 #if !defined(EGL_PLATFORM_ANGLE_USE_WARP_ANGLE) | 51 #if !defined(EGL_PLATFORM_ANGLE_USE_WARP_ANGLE) |
52 #define EGL_PLATFORM_ANGLE_USE_WARP_ANGLE 0x3208 | 52 #define EGL_PLATFORM_ANGLE_USE_WARP_ANGLE 0x3208 |
53 #endif | 53 #endif |
54 #endif // defined(OS_WIN) | 54 #endif // defined(OS_WIN) |
55 | 55 |
56 using ui::GetLastEGLErrorString; | 56 using ui::GetLastEGLErrorString; |
57 | 57 |
58 namespace gfx { | 58 namespace gfx { |
59 | 59 |
| 60 #if defined(OS_WIN) |
| 61 unsigned int NativeViewGLSurfaceEGL::current_swap_generation_ = 0; |
| 62 unsigned int NativeViewGLSurfaceEGL::swaps_this_generation_ = 0; |
| 63 unsigned int NativeViewGLSurfaceEGL::last_multiswap_generation_ = 0; |
| 64 |
| 65 const unsigned int MULTISWAP_FRAME_VSYNC_THRESHOLD = 60; |
| 66 #endif |
| 67 |
60 namespace { | 68 namespace { |
61 | 69 |
62 EGLConfig g_config; | 70 EGLConfig g_config; |
63 EGLDisplay g_display; | 71 EGLDisplay g_display; |
64 EGLNativeDisplayType g_native_display_type; | 72 EGLNativeDisplayType g_native_display_type; |
65 | 73 |
66 // In the Cast environment, we need to destroy the EGLNativeDisplayType and | 74 // In the Cast environment, we need to destroy the EGLNativeDisplayType and |
67 // EGLDisplay returned by the GPU platform when we switch to an external app | 75 // EGLDisplay returned by the GPU platform when we switch to an external app |
68 // which will temporarily own all screen and GPU resources. | 76 // which will temporarily own all screen and GPU resources. |
69 // Even though Chromium is still in the background. | 77 // Even though Chromium is still in the background. |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 | 342 |
335 return eglGetDisplay(native_display); | 343 return eglGetDisplay(native_display); |
336 } | 344 } |
337 #endif | 345 #endif |
338 | 346 |
339 NativeViewGLSurfaceEGL::NativeViewGLSurfaceEGL(EGLNativeWindowType window) | 347 NativeViewGLSurfaceEGL::NativeViewGLSurfaceEGL(EGLNativeWindowType window) |
340 : window_(window), | 348 : window_(window), |
341 surface_(NULL), | 349 surface_(NULL), |
342 supports_post_sub_buffer_(false), | 350 supports_post_sub_buffer_(false), |
343 config_(NULL), | 351 config_(NULL), |
344 size_(1, 1) { | 352 size_(1, 1), |
| 353 swap_interval_(1) { |
345 #if defined(OS_ANDROID) | 354 #if defined(OS_ANDROID) |
346 if (window) | 355 if (window) |
347 ANativeWindow_acquire(window); | 356 ANativeWindow_acquire(window); |
348 #endif | 357 #endif |
349 | 358 |
350 #if defined(OS_WIN) | 359 #if defined(OS_WIN) |
| 360 vsync_override_ = false; |
| 361 swap_generation_ = 0; |
351 RECT windowRect; | 362 RECT windowRect; |
352 if (GetClientRect(window_, &windowRect)) | 363 if (GetClientRect(window_, &windowRect)) |
353 size_ = gfx::Rect(windowRect).size(); | 364 size_ = gfx::Rect(windowRect).size(); |
354 #endif | 365 #endif |
355 } | 366 } |
356 | 367 |
357 bool NativeViewGLSurfaceEGL::Initialize() { | 368 bool NativeViewGLSurfaceEGL::Initialize() { |
358 return Initialize(scoped_ptr<VSyncProvider>()); | 369 return Initialize(scoped_ptr<VSyncProvider>()); |
359 } | 370 } |
360 | 371 |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
498 | 509 |
499 bool NativeViewGLSurfaceEGL::IsOffscreen() { | 510 bool NativeViewGLSurfaceEGL::IsOffscreen() { |
500 return false; | 511 return false; |
501 } | 512 } |
502 | 513 |
503 bool NativeViewGLSurfaceEGL::SwapBuffers() { | 514 bool NativeViewGLSurfaceEGL::SwapBuffers() { |
504 TRACE_EVENT2("gpu", "NativeViewGLSurfaceEGL:RealSwapBuffers", | 515 TRACE_EVENT2("gpu", "NativeViewGLSurfaceEGL:RealSwapBuffers", |
505 "width", GetSize().width(), | 516 "width", GetSize().width(), |
506 "height", GetSize().height()); | 517 "height", GetSize().height()); |
507 | 518 |
| 519 #if defined(OS_WIN) |
| 520 if (swap_interval_ != 0) { |
| 521 // This code is a simple way of enforcing that we only vsync if one surface |
| 522 // is swapping per frame. This provides single window cases a stable refresh |
| 523 // while allowing multi-window cases to not slow down due to multiple syncs |
| 524 // on a single thread. A better way to fix this problem would be to have |
| 525 // each surface present on its own thread. |
| 526 |
| 527 if (current_swap_generation_ == swap_generation_) { |
| 528 if (swaps_this_generation_ > 1) |
| 529 last_multiswap_generation_ = current_swap_generation_; |
| 530 swaps_this_generation_ = 0; |
| 531 current_swap_generation_++; |
| 532 } |
| 533 |
| 534 swap_generation_ = current_swap_generation_; |
| 535 |
| 536 if (swaps_this_generation_ != 0 || |
| 537 (current_swap_generation_ - last_multiswap_generation_ < |
| 538 MULTISWAP_FRAME_VSYNC_THRESHOLD)) { |
| 539 // Override vsync settings and switch it off |
| 540 if (!vsync_override_) { |
| 541 eglSwapInterval(GetDisplay(), 0); |
| 542 vsync_override_ = true; |
| 543 } |
| 544 } else if (vsync_override_) { |
| 545 // Only one window swapping, so let the normal vsync setting take over |
| 546 eglSwapInterval(GetDisplay(), swap_interval_); |
| 547 vsync_override_ = false; |
| 548 } |
| 549 |
| 550 swaps_this_generation_++; |
| 551 } |
| 552 #endif |
| 553 |
508 if (!eglSwapBuffers(GetDisplay(), surface_)) { | 554 if (!eglSwapBuffers(GetDisplay(), surface_)) { |
509 DVLOG(1) << "eglSwapBuffers failed with error " | 555 DVLOG(1) << "eglSwapBuffers failed with error " |
510 << GetLastEGLErrorString(); | 556 << GetLastEGLErrorString(); |
511 return false; | 557 return false; |
512 } | 558 } |
513 | 559 |
514 return true; | 560 return true; |
515 } | 561 } |
516 | 562 |
517 gfx::Size NativeViewGLSurfaceEGL::GetSize() { | 563 gfx::Size NativeViewGLSurfaceEGL::GetSize() { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
578 << GetLastEGLErrorString(); | 624 << GetLastEGLErrorString(); |
579 return false; | 625 return false; |
580 } | 626 } |
581 return true; | 627 return true; |
582 } | 628 } |
583 | 629 |
584 VSyncProvider* NativeViewGLSurfaceEGL::GetVSyncProvider() { | 630 VSyncProvider* NativeViewGLSurfaceEGL::GetVSyncProvider() { |
585 return vsync_provider_.get(); | 631 return vsync_provider_.get(); |
586 } | 632 } |
587 | 633 |
| 634 void NativeViewGLSurfaceEGL::OnSetSwapInterval(int interval) { |
| 635 swap_interval_ = interval; |
| 636 } |
| 637 |
588 NativeViewGLSurfaceEGL::~NativeViewGLSurfaceEGL() { | 638 NativeViewGLSurfaceEGL::~NativeViewGLSurfaceEGL() { |
589 Destroy(); | 639 Destroy(); |
590 #if defined(OS_ANDROID) | 640 #if defined(OS_ANDROID) |
591 if (window_) | 641 if (window_) |
592 ANativeWindow_release(window_); | 642 ANativeWindow_release(window_); |
593 #endif | 643 #endif |
594 } | 644 } |
595 | 645 |
596 PbufferGLSurfaceEGL::PbufferGLSurfaceEGL(const gfx::Size& size) | 646 PbufferGLSurfaceEGL::PbufferGLSurfaceEGL(const gfx::Size& size) |
597 : size_(size), | 647 : size_(size), |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
760 } | 810 } |
761 | 811 |
762 void* SurfacelessEGL::GetShareHandle() { | 812 void* SurfacelessEGL::GetShareHandle() { |
763 return NULL; | 813 return NULL; |
764 } | 814 } |
765 | 815 |
766 SurfacelessEGL::~SurfacelessEGL() { | 816 SurfacelessEGL::~SurfacelessEGL() { |
767 } | 817 } |
768 | 818 |
769 } // namespace gfx | 819 } // namespace gfx |
OLD | NEW |