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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 #define EGL_ANGLE_platform_angle_opengl 1 | 73 #define EGL_ANGLE_platform_angle_opengl 1 |
74 #define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x320D | 74 #define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x320D |
75 #define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320E | 75 #define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320E |
76 #endif /* EGL_ANGLE_platform_angle_opengl */ | 76 #endif /* EGL_ANGLE_platform_angle_opengl */ |
77 | 77 |
78 #ifndef EGL_ANGLE_x11_visual | 78 #ifndef EGL_ANGLE_x11_visual |
79 #define EGL_ANGLE_x11_visual 1 | 79 #define EGL_ANGLE_x11_visual 1 |
80 #define EGL_X11_VISUAL_ID_ANGLE 0x33A3 | 80 #define EGL_X11_VISUAL_ID_ANGLE 0x33A3 |
81 #endif /* EGL_ANGLE_x11_visual */ | 81 #endif /* EGL_ANGLE_x11_visual */ |
82 | 82 |
| 83 #ifndef EGL_ANGLE_surface_orientation |
| 84 #define EGL_ANGLE_surface_orientation |
| 85 #define EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE 0x33A7 |
| 86 #define EGL_SURFACE_ORIENTATION_ANGLE 0x33A8 |
| 87 #define EGL_SURFACE_ORIENTATION_INVERT_X_ANGLE 0x0001 |
| 88 #define EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE 0x0002 |
| 89 #endif /* EGL_ANGLE_surface_orientation */ |
| 90 |
83 using ui::GetLastEGLErrorString; | 91 using ui::GetLastEGLErrorString; |
84 | 92 |
85 namespace gfx { | 93 namespace gfx { |
86 | 94 |
87 #if defined(OS_WIN) | 95 #if defined(OS_WIN) |
88 unsigned int NativeViewGLSurfaceEGL::current_swap_generation_ = 0; | 96 unsigned int NativeViewGLSurfaceEGL::current_swap_generation_ = 0; |
89 unsigned int NativeViewGLSurfaceEGL::swaps_this_generation_ = 0; | 97 unsigned int NativeViewGLSurfaceEGL::swaps_this_generation_ = 0; |
90 unsigned int NativeViewGLSurfaceEGL::last_multiswap_generation_ = 0; | 98 unsigned int NativeViewGLSurfaceEGL::last_multiswap_generation_ = 0; |
91 | 99 |
92 const unsigned int MULTISWAP_FRAME_VSYNC_THRESHOLD = 60; | 100 const unsigned int MULTISWAP_FRAME_VSYNC_THRESHOLD = 60; |
93 #endif | 101 #endif |
94 | 102 |
95 namespace { | 103 namespace { |
96 | 104 |
97 EGLConfig g_config; | 105 EGLConfig g_config; |
98 EGLDisplay g_display; | 106 EGLDisplay g_display; |
99 EGLNativeDisplayType g_native_display; | 107 EGLNativeDisplayType g_native_display; |
100 | 108 |
101 const char* g_egl_extensions = NULL; | 109 const char* g_egl_extensions = NULL; |
102 bool g_egl_create_context_robustness_supported = false; | 110 bool g_egl_create_context_robustness_supported = false; |
103 bool g_egl_sync_control_supported = false; | 111 bool g_egl_sync_control_supported = false; |
104 bool g_egl_window_fixed_size_supported = false; | 112 bool g_egl_window_fixed_size_supported = false; |
105 bool g_egl_surfaceless_context_supported = false; | 113 bool g_egl_surfaceless_context_supported = false; |
| 114 bool g_egl_surface_orientation_supported = false; |
106 | 115 |
107 class EGLSyncControlVSyncProvider | 116 class EGLSyncControlVSyncProvider |
108 : public gfx::SyncControlVSyncProvider { | 117 : public gfx::SyncControlVSyncProvider { |
109 public: | 118 public: |
110 explicit EGLSyncControlVSyncProvider(EGLSurface surface) | 119 explicit EGLSyncControlVSyncProvider(EGLSurface surface) |
111 : SyncControlVSyncProvider(), | 120 : SyncControlVSyncProvider(), |
112 surface_(surface) { | 121 surface_(surface) { |
113 } | 122 } |
114 | 123 |
115 ~EGLSyncControlVSyncProvider() override {} | 124 ~EGLSyncControlVSyncProvider() override {} |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 return false; | 362 return false; |
354 } | 363 } |
355 | 364 |
356 g_egl_extensions = eglQueryString(g_display, EGL_EXTENSIONS); | 365 g_egl_extensions = eglQueryString(g_display, EGL_EXTENSIONS); |
357 g_egl_create_context_robustness_supported = | 366 g_egl_create_context_robustness_supported = |
358 HasEGLExtension("EGL_EXT_create_context_robustness"); | 367 HasEGLExtension("EGL_EXT_create_context_robustness"); |
359 g_egl_sync_control_supported = | 368 g_egl_sync_control_supported = |
360 HasEGLExtension("EGL_CHROMIUM_sync_control"); | 369 HasEGLExtension("EGL_CHROMIUM_sync_control"); |
361 g_egl_window_fixed_size_supported = | 370 g_egl_window_fixed_size_supported = |
362 HasEGLExtension("EGL_ANGLE_window_fixed_size"); | 371 HasEGLExtension("EGL_ANGLE_window_fixed_size"); |
| 372 g_egl_surface_orientation_supported = |
| 373 HasEGLExtension("EGL_ANGLE_surface_orientation"); |
363 | 374 |
364 // TODO(oetuaho@nvidia.com): Surfaceless is disabled on Android as a temporary | 375 // TODO(oetuaho@nvidia.com): Surfaceless is disabled on Android as a temporary |
365 // workaround, since code written for Android WebView takes different paths | 376 // workaround, since code written for Android WebView takes different paths |
366 // based on whether GL surface objects have underlying EGL surface handles, | 377 // based on whether GL surface objects have underlying EGL surface handles, |
367 // conflicting with the use of surfaceless. See https://crbug.com/382349 | 378 // conflicting with the use of surfaceless. See https://crbug.com/382349 |
368 #if defined(OS_ANDROID) | 379 #if defined(OS_ANDROID) |
369 DCHECK(!g_egl_surfaceless_context_supported); | 380 DCHECK(!g_egl_surfaceless_context_supported); |
370 #else | 381 #else |
371 // Check if SurfacelessEGL is supported. | 382 // Check if SurfacelessEGL is supported. |
372 g_egl_surfaceless_context_supported = | 383 g_egl_surfaceless_context_supported = |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
481 return g_display; | 492 return g_display; |
482 } | 493 } |
483 | 494 |
484 NativeViewGLSurfaceEGL::NativeViewGLSurfaceEGL(EGLNativeWindowType window) | 495 NativeViewGLSurfaceEGL::NativeViewGLSurfaceEGL(EGLNativeWindowType window) |
485 : window_(window), | 496 : window_(window), |
486 config_(NULL), | 497 config_(NULL), |
487 size_(1, 1), | 498 size_(1, 1), |
488 surface_(NULL), | 499 surface_(NULL), |
489 supports_post_sub_buffer_(false), | 500 supports_post_sub_buffer_(false), |
490 alpha_(true), | 501 alpha_(true), |
| 502 flips_vertically_(false), |
491 swap_interval_(1) { | 503 swap_interval_(1) { |
492 #if defined(OS_ANDROID) | 504 #if defined(OS_ANDROID) |
493 if (window) | 505 if (window) |
494 ANativeWindow_acquire(window); | 506 ANativeWindow_acquire(window); |
495 #endif | 507 #endif |
496 | 508 |
497 #if defined(OS_WIN) | 509 #if defined(OS_WIN) |
498 vsync_override_ = false; | 510 vsync_override_ = false; |
499 swap_generation_ = 0; | 511 swap_generation_ = 0; |
500 RECT windowRect; | 512 RECT windowRect; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
532 egl_window_attributes.push_back(size_.width()); | 544 egl_window_attributes.push_back(size_.width()); |
533 egl_window_attributes.push_back(EGL_HEIGHT); | 545 egl_window_attributes.push_back(EGL_HEIGHT); |
534 egl_window_attributes.push_back(size_.height()); | 546 egl_window_attributes.push_back(size_.height()); |
535 } | 547 } |
536 | 548 |
537 if (gfx::g_driver_egl.ext.b_EGL_NV_post_sub_buffer) { | 549 if (gfx::g_driver_egl.ext.b_EGL_NV_post_sub_buffer) { |
538 egl_window_attributes.push_back(EGL_POST_SUB_BUFFER_SUPPORTED_NV); | 550 egl_window_attributes.push_back(EGL_POST_SUB_BUFFER_SUPPORTED_NV); |
539 egl_window_attributes.push_back(EGL_TRUE); | 551 egl_window_attributes.push_back(EGL_TRUE); |
540 } | 552 } |
541 | 553 |
| 554 if (g_egl_surface_orientation_supported) { |
| 555 EGLint attrib; |
| 556 eglGetConfigAttrib(GetDisplay(), GetConfig(), |
| 557 EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE, &attrib); |
| 558 flips_vertically_ = (attrib == EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE); |
| 559 } |
| 560 |
| 561 if (flips_vertically_) { |
| 562 egl_window_attributes.push_back(EGL_SURFACE_ORIENTATION_ANGLE); |
| 563 egl_window_attributes.push_back(EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE); |
| 564 } |
| 565 |
542 egl_window_attributes.push_back(EGL_NONE); | 566 egl_window_attributes.push_back(EGL_NONE); |
543 // Create a surface for the native window. | 567 // Create a surface for the native window. |
544 surface_ = eglCreateWindowSurface( | 568 surface_ = eglCreateWindowSurface( |
545 GetDisplay(), GetConfig(), window_, &egl_window_attributes[0]); | 569 GetDisplay(), GetConfig(), window_, &egl_window_attributes[0]); |
546 | 570 |
547 if (!surface_) { | 571 if (!surface_) { |
548 LOG(ERROR) << "eglCreateWindowSurface failed with error " | 572 LOG(ERROR) << "eglCreateWindowSurface failed with error " |
549 << GetLastEGLErrorString(); | 573 << GetLastEGLErrorString(); |
550 Destroy(); | 574 Destroy(); |
551 return false; | 575 return false; |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
693 } | 717 } |
694 | 718 |
695 EGLSurface NativeViewGLSurfaceEGL::GetHandle() { | 719 EGLSurface NativeViewGLSurfaceEGL::GetHandle() { |
696 return surface_; | 720 return surface_; |
697 } | 721 } |
698 | 722 |
699 bool NativeViewGLSurfaceEGL::SupportsPostSubBuffer() { | 723 bool NativeViewGLSurfaceEGL::SupportsPostSubBuffer() { |
700 return supports_post_sub_buffer_; | 724 return supports_post_sub_buffer_; |
701 } | 725 } |
702 | 726 |
| 727 bool NativeViewGLSurfaceEGL::FlipsVertically() const { |
| 728 return flips_vertically_; |
| 729 } |
| 730 |
703 gfx::SwapResult NativeViewGLSurfaceEGL::PostSubBuffer(int x, | 731 gfx::SwapResult NativeViewGLSurfaceEGL::PostSubBuffer(int x, |
704 int y, | 732 int y, |
705 int width, | 733 int width, |
706 int height) { | 734 int height) { |
707 DCHECK(supports_post_sub_buffer_); | 735 DCHECK(supports_post_sub_buffer_); |
708 if (!CommitAndClearPendingOverlays()) { | 736 if (!CommitAndClearPendingOverlays()) { |
709 DVLOG(1) << "Failed to commit pending overlay planes."; | 737 DVLOG(1) << "Failed to commit pending overlay planes."; |
710 return gfx::SwapResult::SWAP_FAILED; | 738 return gfx::SwapResult::SWAP_FAILED; |
711 } | 739 } |
| 740 if (flips_vertically_) { |
| 741 // With EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE the contents are rendered |
| 742 // inverted, but the PostSubBuffer rectangle is still measured from the |
| 743 // bottom left. |
| 744 y = GetSize().height() - y - height; |
| 745 } |
712 if (!eglPostSubBufferNV(GetDisplay(), surface_, x, y, width, height)) { | 746 if (!eglPostSubBufferNV(GetDisplay(), surface_, x, y, width, height)) { |
713 DVLOG(1) << "eglPostSubBufferNV failed with error " | 747 DVLOG(1) << "eglPostSubBufferNV failed with error " |
714 << GetLastEGLErrorString(); | 748 << GetLastEGLErrorString(); |
715 return gfx::SwapResult::SWAP_FAILED; | 749 return gfx::SwapResult::SWAP_FAILED; |
716 } | 750 } |
717 return gfx::SwapResult::SWAP_ACK; | 751 return gfx::SwapResult::SWAP_ACK; |
718 } | 752 } |
719 | 753 |
720 bool NativeViewGLSurfaceEGL::SupportsCommitOverlayPlanes() { | 754 bool NativeViewGLSurfaceEGL::SupportsCommitOverlayPlanes() { |
721 #if defined(OS_ANDROID) | 755 #if defined(OS_ANDROID) |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
947 } | 981 } |
948 | 982 |
949 void* SurfacelessEGL::GetShareHandle() { | 983 void* SurfacelessEGL::GetShareHandle() { |
950 return NULL; | 984 return NULL; |
951 } | 985 } |
952 | 986 |
953 SurfacelessEGL::~SurfacelessEGL() { | 987 SurfacelessEGL::~SurfacelessEGL() { |
954 } | 988 } |
955 | 989 |
956 } // namespace gfx | 990 } // namespace gfx |
OLD | NEW |