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 659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
670 } else if (vsync_override_) { | 670 } else if (vsync_override_) { |
671 // Only one window swapping, so let the normal vsync setting take over | 671 // Only one window swapping, so let the normal vsync setting take over |
672 eglSwapInterval(GetDisplay(), swap_interval_); | 672 eglSwapInterval(GetDisplay(), swap_interval_); |
673 vsync_override_ = false; | 673 vsync_override_ = false; |
674 } | 674 } |
675 | 675 |
676 swaps_this_generation_++; | 676 swaps_this_generation_++; |
677 } | 677 } |
678 #endif | 678 #endif |
679 | 679 |
| 680 if (!CommitAndClearPendingOverlays()) { |
| 681 DVLOG(1) << "Failed to commit pending overlay planes."; |
| 682 return gfx::SwapResult::SWAP_FAILED; |
| 683 } |
| 684 |
680 if (!eglSwapBuffers(GetDisplay(), surface_)) { | 685 if (!eglSwapBuffers(GetDisplay(), surface_)) { |
681 DVLOG(1) << "eglSwapBuffers failed with error " | 686 DVLOG(1) << "eglSwapBuffers failed with error " |
682 << GetLastEGLErrorString(); | 687 << GetLastEGLErrorString(); |
683 return gfx::SwapResult::SWAP_FAILED; | 688 return gfx::SwapResult::SWAP_FAILED; |
684 } | 689 } |
685 | 690 |
686 return gfx::SwapResult::SWAP_ACK; | 691 return gfx::SwapResult::SWAP_ACK; |
687 } | 692 } |
688 | 693 |
689 gfx::Size NativeViewGLSurfaceEGL::GetSize() { | 694 gfx::Size NativeViewGLSurfaceEGL::GetSize() { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
740 | 745 |
741 bool NativeViewGLSurfaceEGL::SupportsPostSubBuffer() { | 746 bool NativeViewGLSurfaceEGL::SupportsPostSubBuffer() { |
742 return supports_post_sub_buffer_; | 747 return supports_post_sub_buffer_; |
743 } | 748 } |
744 | 749 |
745 gfx::SwapResult NativeViewGLSurfaceEGL::PostSubBuffer(int x, | 750 gfx::SwapResult NativeViewGLSurfaceEGL::PostSubBuffer(int x, |
746 int y, | 751 int y, |
747 int width, | 752 int width, |
748 int height) { | 753 int height) { |
749 DCHECK(supports_post_sub_buffer_); | 754 DCHECK(supports_post_sub_buffer_); |
| 755 if (!CommitAndClearPendingOverlays()) { |
| 756 DVLOG(1) << "Failed to commit pending overlay planes."; |
| 757 return gfx::SwapResult::SWAP_FAILED; |
| 758 } |
750 if (!eglPostSubBufferNV(GetDisplay(), surface_, x, y, width, height)) { | 759 if (!eglPostSubBufferNV(GetDisplay(), surface_, x, y, width, height)) { |
751 DVLOG(1) << "eglPostSubBufferNV failed with error " | 760 DVLOG(1) << "eglPostSubBufferNV failed with error " |
752 << GetLastEGLErrorString(); | 761 << GetLastEGLErrorString(); |
753 return gfx::SwapResult::SWAP_FAILED; | 762 return gfx::SwapResult::SWAP_FAILED; |
754 } | 763 } |
755 return gfx::SwapResult::SWAP_ACK; | 764 return gfx::SwapResult::SWAP_ACK; |
756 } | 765 } |
757 | 766 |
| 767 bool NativeViewGLSurfaceEGL::SupportsCommitOverlayPlanes() { |
| 768 #if defined(OS_ANDROID) |
| 769 return true; |
| 770 #else |
| 771 return false; |
| 772 #endif |
| 773 } |
| 774 |
| 775 gfx::SwapResult NativeViewGLSurfaceEGL::CommitOverlayPlanes() { |
| 776 DCHECK(SupportsCommitOverlayPlanes()); |
| 777 // Here we assume that the overlays scheduled on this surface will display |
| 778 // themselves to the screen right away in |CommitAndClearPendingOverlays|, |
| 779 // rather than being queued and waiting for a "swap" signal. |
| 780 return CommitAndClearPendingOverlays() ? gfx::SwapResult::SWAP_ACK |
| 781 : gfx::SwapResult::SWAP_FAILED; |
| 782 } |
| 783 |
758 VSyncProvider* NativeViewGLSurfaceEGL::GetVSyncProvider() { | 784 VSyncProvider* NativeViewGLSurfaceEGL::GetVSyncProvider() { |
759 return vsync_provider_.get(); | 785 return vsync_provider_.get(); |
760 } | 786 } |
761 | 787 |
762 bool NativeViewGLSurfaceEGL::ScheduleOverlayPlane(int z_order, | 788 bool NativeViewGLSurfaceEGL::ScheduleOverlayPlane(int z_order, |
763 OverlayTransform transform, | 789 OverlayTransform transform, |
764 gl::GLImage* image, | 790 gl::GLImage* image, |
765 const Rect& bounds_rect, | 791 const Rect& bounds_rect, |
766 const RectF& crop_rect) { | 792 const RectF& crop_rect) { |
767 #if defined(OS_ANDROID) | 793 #if !defined(OS_ANDROID) |
768 // Overlay planes are used on Android for fullscreen video. The image is | |
769 // expected to update the plane as soon as possible to display the video frame | |
770 // chosen for this vsync interval. | |
771 return image->ScheduleOverlayPlane(window_, z_order, transform, bounds_rect, | |
772 crop_rect); | |
773 #else | |
774 NOTIMPLEMENTED(); | 794 NOTIMPLEMENTED(); |
775 return false; | 795 return false; |
| 796 #else |
| 797 pending_overlays_.push_back( |
| 798 GLSurfaceOverlay(z_order, transform, image, bounds_rect, crop_rect)); |
| 799 return true; |
776 #endif | 800 #endif |
777 } | 801 } |
778 | 802 |
779 void NativeViewGLSurfaceEGL::OnSetSwapInterval(int interval) { | 803 void NativeViewGLSurfaceEGL::OnSetSwapInterval(int interval) { |
780 swap_interval_ = interval; | 804 swap_interval_ = interval; |
781 } | 805 } |
782 | 806 |
783 NativeViewGLSurfaceEGL::~NativeViewGLSurfaceEGL() { | 807 NativeViewGLSurfaceEGL::~NativeViewGLSurfaceEGL() { |
784 Destroy(); | 808 Destroy(); |
785 #if defined(OS_ANDROID) | 809 #if defined(OS_ANDROID) |
786 if (window_) | 810 if (window_) |
787 ANativeWindow_release(window_); | 811 ANativeWindow_release(window_); |
788 #endif | 812 #endif |
789 } | 813 } |
790 | 814 |
| 815 bool NativeViewGLSurfaceEGL::CommitAndClearPendingOverlays() { |
| 816 if (pending_overlays_.empty()) |
| 817 return true; |
| 818 |
| 819 bool success = true; |
| 820 for (const auto& overlay : pending_overlays_) |
| 821 success &= overlay.ScheduleOverlayPlane(window_); |
| 822 pending_overlays_.clear(); |
| 823 return success; |
| 824 } |
| 825 |
791 PbufferGLSurfaceEGL::PbufferGLSurfaceEGL(const gfx::Size& size) | 826 PbufferGLSurfaceEGL::PbufferGLSurfaceEGL(const gfx::Size& size) |
792 : size_(size), | 827 : size_(size), |
793 surface_(NULL) { | 828 surface_(NULL) { |
794 // Some implementations of Pbuffer do not support having a 0 size. For such | 829 // Some implementations of Pbuffer do not support having a 0 size. For such |
795 // cases use a (1, 1) surface. | 830 // cases use a (1, 1) surface. |
796 if (size_.GetArea() == 0) | 831 if (size_.GetArea() == 0) |
797 size_.SetSize(1, 1); | 832 size_.SetSize(1, 1); |
798 } | 833 } |
799 | 834 |
800 bool PbufferGLSurfaceEGL::Initialize() { | 835 bool PbufferGLSurfaceEGL::Initialize() { |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
955 } | 990 } |
956 | 991 |
957 void* SurfacelessEGL::GetShareHandle() { | 992 void* SurfacelessEGL::GetShareHandle() { |
958 return NULL; | 993 return NULL; |
959 } | 994 } |
960 | 995 |
961 SurfacelessEGL::~SurfacelessEGL() { | 996 SurfacelessEGL::~SurfacelessEGL() { |
962 } | 997 } |
963 | 998 |
964 } // namespace gfx | 999 } // namespace gfx |
OLD | NEW |