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 27 matching lines...) Expand all Loading... |
38 #endif | 38 #endif |
39 | 39 |
40 #if defined(OS_WIN) | 40 #if defined(OS_WIN) |
41 // From ANGLE's egl/eglext.h. | 41 // From ANGLE's egl/eglext.h. |
42 #if !defined(EGL_PLATFORM_ANGLE_ANGLE) | 42 #if !defined(EGL_PLATFORM_ANGLE_ANGLE) |
43 #define EGL_PLATFORM_ANGLE_ANGLE 0x3201 | 43 #define EGL_PLATFORM_ANGLE_ANGLE 0x3201 |
44 #endif | 44 #endif |
45 #if !defined(EGL_PLATFORM_ANGLE_TYPE_ANGLE) | 45 #if !defined(EGL_PLATFORM_ANGLE_TYPE_ANGLE) |
46 #define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3202 | 46 #define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3202 |
47 #endif | 47 #endif |
48 #if !defined(EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE) | 48 #if !defined(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) |
49 #define EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE 0x3206 | 49 #define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3207 |
| 50 #endif |
| 51 #if !defined(EGL_PLATFORM_ANGLE_USE_WARP_ANGLE) |
| 52 #define EGL_PLATFORM_ANGLE_USE_WARP_ANGLE 0x3208 |
50 #endif | 53 #endif |
51 #endif // defined(OS_WIN) | 54 #endif // defined(OS_WIN) |
52 | 55 |
53 using ui::GetLastEGLErrorString; | 56 using ui::GetLastEGLErrorString; |
54 | 57 |
55 namespace gfx { | 58 namespace gfx { |
56 | 59 |
57 unsigned int NativeViewGLSurfaceEGL::current_swap_generation_ = 0; | |
58 | |
59 namespace { | 60 namespace { |
60 | 61 |
61 EGLConfig g_config; | 62 EGLConfig g_config; |
62 EGLDisplay g_display; | 63 EGLDisplay g_display; |
63 EGLNativeDisplayType g_native_display; | 64 EGLNativeDisplayType g_native_display; |
64 | 65 |
65 const char* g_egl_extensions = NULL; | 66 const char* g_egl_extensions = NULL; |
66 bool g_egl_create_context_robustness_supported = false; | 67 bool g_egl_create_context_robustness_supported = false; |
67 bool g_egl_sync_control_supported = false; | 68 bool g_egl_sync_control_supported = false; |
68 bool g_egl_window_fixed_size_supported = false; | 69 bool g_egl_window_fixed_size_supported = false; |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 } | 246 } |
246 | 247 |
247 bool GLSurfaceEGL::IsEGLSurfacelessContextSupported() { | 248 bool GLSurfaceEGL::IsEGLSurfacelessContextSupported() { |
248 return g_egl_surfaceless_context_supported; | 249 return g_egl_surfaceless_context_supported; |
249 } | 250 } |
250 | 251 |
251 GLSurfaceEGL::~GLSurfaceEGL() {} | 252 GLSurfaceEGL::~GLSurfaceEGL() {} |
252 | 253 |
253 #if defined(OS_WIN) | 254 #if defined(OS_WIN) |
254 static const EGLint kDisplayAttribsWarp[] { | 255 static const EGLint kDisplayAttribsWarp[] { |
255 EGL_PLATFORM_ANGLE_TYPE_ANGLE, | 256 EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, |
256 EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE, | 257 EGL_PLATFORM_ANGLE_USE_WARP_ANGLE, EGL_TRUE, |
257 EGL_NONE | 258 EGL_NONE |
258 }; | 259 }; |
259 | 260 |
260 // static | 261 // static |
261 EGLDisplay GLSurfaceEGL::GetPlatformDisplay( | 262 EGLDisplay GLSurfaceEGL::GetPlatformDisplay( |
262 EGLNativeDisplayType native_display) { | 263 EGLNativeDisplayType native_display) { |
263 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseWarp)) { | 264 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseWarp)) { |
264 // Check for availability of WARP via ANGLE extension. | 265 // Check for availability of WARP via ANGLE extension. |
265 bool supports_warp = false; | 266 bool supports_warp = false; |
266 const char* no_display_extensions = eglQueryString(EGL_NO_DISPLAY, | 267 const char* no_display_extensions = eglQueryString(EGL_NO_DISPLAY, |
(...skipping 14 matching lines...) Expand all Loading... |
281 | 282 |
282 return eglGetDisplay(native_display); | 283 return eglGetDisplay(native_display); |
283 } | 284 } |
284 #endif | 285 #endif |
285 | 286 |
286 NativeViewGLSurfaceEGL::NativeViewGLSurfaceEGL(EGLNativeWindowType window) | 287 NativeViewGLSurfaceEGL::NativeViewGLSurfaceEGL(EGLNativeWindowType window) |
287 : window_(window), | 288 : window_(window), |
288 surface_(NULL), | 289 surface_(NULL), |
289 supports_post_sub_buffer_(false), | 290 supports_post_sub_buffer_(false), |
290 config_(NULL), | 291 config_(NULL), |
291 size_(1, 1), | 292 size_(1, 1) { |
292 swap_interval_(1), | |
293 swap_generation_(0) { | |
294 #if defined(OS_ANDROID) | 293 #if defined(OS_ANDROID) |
295 if (window) | 294 if (window) |
296 ANativeWindow_acquire(window); | 295 ANativeWindow_acquire(window); |
297 #endif | 296 #endif |
298 | 297 |
299 #if defined(OS_WIN) | 298 #if defined(OS_WIN) |
300 RECT windowRect; | 299 RECT windowRect; |
301 if (GetClientRect(window_, &windowRect)) | 300 if (GetClientRect(window_, &windowRect)) |
302 size_ = gfx::Rect(windowRect).size(); | 301 size_ = gfx::Rect(windowRect).size(); |
303 #endif | 302 #endif |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
447 | 446 |
448 bool NativeViewGLSurfaceEGL::IsOffscreen() { | 447 bool NativeViewGLSurfaceEGL::IsOffscreen() { |
449 return false; | 448 return false; |
450 } | 449 } |
451 | 450 |
452 bool NativeViewGLSurfaceEGL::SwapBuffers() { | 451 bool NativeViewGLSurfaceEGL::SwapBuffers() { |
453 TRACE_EVENT2("gpu", "NativeViewGLSurfaceEGL:RealSwapBuffers", | 452 TRACE_EVENT2("gpu", "NativeViewGLSurfaceEGL:RealSwapBuffers", |
454 "width", GetSize().width(), | 453 "width", GetSize().width(), |
455 "height", GetSize().height()); | 454 "height", GetSize().height()); |
456 | 455 |
457 #if defined(OS_WIN) | |
458 bool force_no_vsync = false; | |
459 if (swap_interval_ != 0) { | |
460 // This code is a simple way of enforcing that only one surface actually | |
461 // vsyncs per frame. This provides single window cases a stable refresh | |
462 // while allowing multi-window cases to not slow down due to multiple syncs | |
463 // on a single thread. A better way to fix this problem would be to have | |
464 // each surface present on its own thread. | |
465 if (current_swap_generation_ == swap_generation_) { | |
466 current_swap_generation_++; | |
467 } else { | |
468 force_no_vsync = true; | |
469 eglSwapInterval(GetDisplay(), 0); | |
470 } | |
471 | |
472 swap_generation_ = current_swap_generation_; | |
473 } | |
474 #endif | |
475 | |
476 if (!eglSwapBuffers(GetDisplay(), surface_)) { | 456 if (!eglSwapBuffers(GetDisplay(), surface_)) { |
477 DVLOG(1) << "eglSwapBuffers failed with error " | 457 DVLOG(1) << "eglSwapBuffers failed with error " |
478 << GetLastEGLErrorString(); | 458 << GetLastEGLErrorString(); |
479 return false; | 459 return false; |
480 } | 460 } |
481 | 461 |
482 #if defined(OS_WIN) | |
483 if (force_no_vsync) { | |
484 eglSwapInterval(GetDisplay(), swap_interval_); | |
485 } | |
486 #endif | |
487 | |
488 return true; | 462 return true; |
489 } | 463 } |
490 | 464 |
491 gfx::Size NativeViewGLSurfaceEGL::GetSize() { | 465 gfx::Size NativeViewGLSurfaceEGL::GetSize() { |
492 EGLint width; | 466 EGLint width; |
493 EGLint height; | 467 EGLint height; |
494 if (!eglQuerySurface(GetDisplay(), surface_, EGL_WIDTH, &width) || | 468 if (!eglQuerySurface(GetDisplay(), surface_, EGL_WIDTH, &width) || |
495 !eglQuerySurface(GetDisplay(), surface_, EGL_HEIGHT, &height)) { | 469 !eglQuerySurface(GetDisplay(), surface_, EGL_HEIGHT, &height)) { |
496 NOTREACHED() << "eglQuerySurface failed with error " | 470 NOTREACHED() << "eglQuerySurface failed with error " |
497 << GetLastEGLErrorString(); | 471 << GetLastEGLErrorString(); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
552 << GetLastEGLErrorString(); | 526 << GetLastEGLErrorString(); |
553 return false; | 527 return false; |
554 } | 528 } |
555 return true; | 529 return true; |
556 } | 530 } |
557 | 531 |
558 VSyncProvider* NativeViewGLSurfaceEGL::GetVSyncProvider() { | 532 VSyncProvider* NativeViewGLSurfaceEGL::GetVSyncProvider() { |
559 return vsync_provider_.get(); | 533 return vsync_provider_.get(); |
560 } | 534 } |
561 | 535 |
562 void NativeViewGLSurfaceEGL::SetSwapInterval(int interval) { | |
563 swap_interval_ = interval; | |
564 } | |
565 | |
566 NativeViewGLSurfaceEGL::~NativeViewGLSurfaceEGL() { | 536 NativeViewGLSurfaceEGL::~NativeViewGLSurfaceEGL() { |
567 Destroy(); | 537 Destroy(); |
568 #if defined(OS_ANDROID) | 538 #if defined(OS_ANDROID) |
569 if (window_) | 539 if (window_) |
570 ANativeWindow_release(window_); | 540 ANativeWindow_release(window_); |
571 #endif | 541 #endif |
572 } | 542 } |
573 | 543 |
574 PbufferGLSurfaceEGL::PbufferGLSurfaceEGL(const gfx::Size& size) | 544 PbufferGLSurfaceEGL::PbufferGLSurfaceEGL(const gfx::Size& size) |
575 : size_(size), | 545 : size_(size), |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
738 } | 708 } |
739 | 709 |
740 void* SurfacelessEGL::GetShareHandle() { | 710 void* SurfacelessEGL::GetShareHandle() { |
741 return NULL; | 711 return NULL; |
742 } | 712 } |
743 | 713 |
744 SurfacelessEGL::~SurfacelessEGL() { | 714 SurfacelessEGL::~SurfacelessEGL() { |
745 } | 715 } |
746 | 716 |
747 } // namespace gfx | 717 } // namespace gfx |
OLD | NEW |