Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(125)

Side by Side Diff: chrome/browser/android/vr_shell/vr_shell_gl.cc

Issue 2749703007: Add menu mode plumbing for WebVR mode. (Closed)
Patch Set: Address comments. Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "chrome/browser/android/vr_shell/vr_shell_gl.h" 5 #include "chrome/browser/android/vr_shell/vr_shell_gl.h"
6 6
7 #include <limits> 7 #include <limits>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/android/jni_android.h" 10 #include "base/android/jni_android.h"
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 webvr_right_viewport_.get()); 468 webvr_right_viewport_.get());
469 webvr_right_viewport_->SetSourceBufferIndex(kFramePrimaryBuffer); 469 webvr_right_viewport_->SetSourceBufferIndex(kFramePrimaryBuffer);
470 470
471 main_thread_task_runner_->PostTask( 471 main_thread_task_runner_->PostTask(
472 FROM_HERE, base::Bind(&VrShell::GvrDelegateReady, weak_vr_shell_)); 472 FROM_HERE, base::Bind(&VrShell::GvrDelegateReady, weak_vr_shell_));
473 } 473 }
474 474
475 void VrShellGl::UpdateController(const gvr::Vec3f& forward_vector) { 475 void VrShellGl::UpdateController(const gvr::Vec3f& forward_vector) {
476 controller_->UpdateState(); 476 controller_->UpdateState();
477 477
478 if (web_vr_mode_) { 478 if (ShouldDrawWebVr()) {
479 // Process screen touch events for Cardboard button compatibility. 479 // Process screen touch events for Cardboard button compatibility.
480 // Also send tap events for controller "touchpad click" events. 480 // Also send tap events for controller "touchpad click" events.
481 if (touch_pending_ || 481 if (touch_pending_ ||
482 controller_->ButtonUpHappened( 482 controller_->ButtonUpHappened(
483 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_CLICK)) { 483 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_CLICK)) {
484 touch_pending_ = false; 484 touch_pending_ = false;
485 std::unique_ptr<WebGestureEvent> gesture(new WebGestureEvent( 485 std::unique_ptr<WebGestureEvent> gesture(new WebGestureEvent(
486 WebInputEvent::GestureTapDown, WebInputEvent::NoModifiers, 486 WebInputEvent::GestureTapDown, WebInputEvent::NoModifiers,
487 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF())); 487 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF()));
488 gesture->sourceDevice = blink::WebGestureDeviceTouchpad; 488 gesture->sourceDevice = blink::WebGestureDeviceTouchpad;
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
710 void VrShellGl::DrawFrame(int16_t frame_index) { 710 void VrShellGl::DrawFrame(int16_t frame_index) {
711 TRACE_EVENT1("gpu", "VrShellGl::DrawFrame", "frame", frame_index); 711 TRACE_EVENT1("gpu", "VrShellGl::DrawFrame", "frame", frame_index);
712 712
713 // Reset the viewport list to just the pair of viewports for the 713 // Reset the viewport list to just the pair of viewports for the
714 // primary buffer each frame. Head-locked viewports get added by 714 // primary buffer each frame. Head-locked viewports get added by
715 // DrawVrShell if needed. 715 // DrawVrShell if needed.
716 buffer_viewport_list_->SetToRecommendedBufferViewports(); 716 buffer_viewport_list_->SetToRecommendedBufferViewports();
717 717
718 // If needed, resize the primary buffer for use with WebVR. Resizing 718 // If needed, resize the primary buffer for use with WebVR. Resizing
719 // needs to happen before acquiring a frame. 719 // needs to happen before acquiring a frame.
720 if (web_vr_mode_) { 720 if (ShouldDrawWebVr()) {
721 // Process all pending_bounds_ changes targeted for before this 721 // Process all pending_bounds_ changes targeted for before this
722 // frame, being careful of wrapping frame indices. 722 // frame, being careful of wrapping frame indices.
723 // TODO(crbug.com/680253): Do not compare the constants on every frame.
mthiesse 2017/03/20 17:32:16 Note that this is a static assert and is checked b
cjgrant 2017/03/20 17:57:22 Done. Sweet, I learned something cool today!
723 static constexpr unsigned max = 724 static constexpr unsigned max =
724 std::numeric_limits<decltype(frame_index_)>::max(); 725 std::numeric_limits<decltype(frame_index_)>::max();
725 static_assert(max > kPoseRingBufferSize * 2, 726 static_assert(max > kPoseRingBufferSize * 2,
726 "To detect wrapping, kPoseRingBufferSize must be smaller " 727 "To detect wrapping, kPoseRingBufferSize must be smaller "
727 "than half of frame_index_ range."); 728 "than half of frame_index_ range.");
728 while (!pending_bounds_.empty()) { 729 while (!pending_bounds_.empty()) {
729 uint16_t index = pending_bounds_.front().first; 730 uint16_t index = pending_bounds_.front().first;
730 // If index is less than the frame_index it's possible we've 731 // If index is less than the frame_index it's possible we've
731 // wrapped, so we extend the range and 'un-wrap' to account 732 // wrapped, so we extend the range and 'un-wrap' to account
732 // for this. 733 // for this.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
772 } 773 }
773 774
774 TRACE_EVENT_BEGIN0("gpu", "VrShellGl::AcquireFrame"); 775 TRACE_EVENT_BEGIN0("gpu", "VrShellGl::AcquireFrame");
775 gvr::Frame frame = swap_chain_->AcquireFrame(); 776 gvr::Frame frame = swap_chain_->AcquireFrame();
776 TRACE_EVENT_END0("gpu", "VrShellGl::AcquireFrame"); 777 TRACE_EVENT_END0("gpu", "VrShellGl::AcquireFrame");
777 if (!frame.is_valid()) { 778 if (!frame.is_valid()) {
778 return; 779 return;
779 } 780 }
780 frame.BindBuffer(kFramePrimaryBuffer); 781 frame.BindBuffer(kFramePrimaryBuffer);
781 782
782 if (web_vr_mode_) { 783 if (ShouldDrawWebVr()) {
783 DrawWebVr(); 784 DrawWebVr();
784 } 785 }
785 786
786 gvr::Mat4f head_pose; 787 gvr::Mat4f head_pose;
787 788
788 // When using async reprojection, we need to know which pose was 789 // When using async reprojection, we need to know which pose was
789 // used in the WebVR app for drawing this frame and supply it when 790 // used in the WebVR app for drawing this frame and supply it when
790 // submitting. Technically we don't need a pose if not reprojecting, 791 // submitting. Technically we don't need a pose if not reprojecting,
791 // but keeping it uninitialized seems likely to cause problems down 792 // but keeping it uninitialized seems likely to cause problems down
792 // the road. Copying it is cheaper than fetching a new one. 793 // the road. Copying it is cheaper than fetching a new one.
793 if (web_vr_mode_) { 794 if (ShouldDrawWebVr()) {
795 // TODO(crbug.com/680253): Do not compare the constants on every frame.
mthiesse 2017/03/20 17:32:16 Same as above.
794 static_assert(!((kPoseRingBufferSize - 1) & kPoseRingBufferSize), 796 static_assert(!((kPoseRingBufferSize - 1) & kPoseRingBufferSize),
795 "kPoseRingBufferSize must be a power of 2"); 797 "kPoseRingBufferSize must be a power of 2");
796 head_pose = webvr_head_pose_[frame_index % kPoseRingBufferSize]; 798 head_pose = webvr_head_pose_[frame_index % kPoseRingBufferSize];
797 } else { 799 } else {
798 gvr::ClockTimePoint target_time = gvr::GvrApi::GetTimePointNow(); 800 gvr::ClockTimePoint target_time = gvr::GvrApi::GetTimePointNow();
799 target_time.monotonic_system_time_nanos += kPredictionTimeWithoutVsyncNanos; 801 target_time.monotonic_system_time_nanos += kPredictionTimeWithoutVsyncNanos;
800 head_pose = gvr_api_->GetHeadSpaceFromStartSpaceRotation(target_time); 802 head_pose = gvr_api_->GetHeadSpaceFromStartSpaceRotation(target_time);
801 } 803 }
802 804
803 gvr::Vec3f position = GetTranslation(head_pose); 805 gvr::Vec3f position = GetTranslation(head_pose);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
844 for (const auto& rect : scene_->GetUiElements()) { 846 for (const auto& rect : scene_->GetUiElements()) {
845 if (!rect->IsVisible()) 847 if (!rect->IsVisible())
846 continue; 848 continue;
847 if (rect->computed_lock_to_fov) { 849 if (rect->computed_lock_to_fov) {
848 head_locked_elements.push_back(rect.get()); 850 head_locked_elements.push_back(rect.get());
849 } else { 851 } else {
850 world_elements.push_back(rect.get()); 852 world_elements.push_back(rect.get());
851 } 853 }
852 } 854 }
853 855
854 if (web_vr_mode_) { 856 if (ShouldDrawWebVr()) {
855 // WebVR is incompatible with 3D world compositing since the 857 // WebVR is incompatible with 3D world compositing since the
856 // depth buffer was already populated with unknown scaling - the 858 // depth buffer was already populated with unknown scaling - the
857 // WebVR app has full control over zNear/zFar. Just leave the 859 // WebVR app has full control over zNear/zFar. Just leave the
858 // existing content in place in the primary buffer without 860 // existing content in place in the primary buffer without
859 // clearing. Currently, there aren't any world elements in WebVR 861 // clearing. Currently, there aren't any world elements in WebVR
860 // mode, this will need further testing if those get added 862 // mode, this will need further testing if those get added
861 // later. 863 // later.
862 } else { 864 } else {
863 // Non-WebVR mode, enable depth testing and clear the primary buffers. 865 // Non-WebVR mode, enable depth testing and clear the primary buffers.
864 glEnable(GL_CULL_FACE); 866 glEnable(GL_CULL_FACE);
865 glEnable(GL_DEPTH_TEST); 867 glEnable(GL_DEPTH_TEST);
866 glDepthMask(GL_TRUE); 868 glDepthMask(GL_TRUE);
867 869
868 const Colorf& backgroundColor = scene_->GetBackgroundColor(); 870 const Colorf& backgroundColor = scene_->GetBackgroundColor();
869 glClearColor(backgroundColor.r, backgroundColor.g, backgroundColor.b, 871 glClearColor(backgroundColor.r, backgroundColor.g, backgroundColor.b,
870 backgroundColor.a); 872 backgroundColor.a);
871 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 873 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
872 } 874 }
873 if (!world_elements.empty()) { 875 if (!world_elements.empty()) {
874 DrawUiView(&head_pose, world_elements, render_size_primary_, 876 DrawUiView(head_pose, world_elements, render_size_primary_,
875 kViewportListPrimaryOffset); 877 kViewportListPrimaryOffset, !ShouldDrawWebVr());
876 } 878 }
877 frame.Unbind(); // Done with the primary buffer. 879 frame.Unbind(); // Done with the primary buffer.
878 880
879 if (!head_locked_elements.empty()) { 881 if (!head_locked_elements.empty()) {
880 // Add head-locked viewports. The list gets reset to just 882 // Add head-locked viewports. The list gets reset to just
881 // the recommended viewports (for the primary buffer) each frame. 883 // the recommended viewports (for the primary buffer) each frame.
882 buffer_viewport_list_->SetBufferViewport( 884 buffer_viewport_list_->SetBufferViewport(
883 kViewportListHeadlockedOffset + GVR_LEFT_EYE, 885 kViewportListHeadlockedOffset + GVR_LEFT_EYE,
884 *headlocked_left_viewport_); 886 *headlocked_left_viewport_);
885 buffer_viewport_list_->SetBufferViewport( 887 buffer_viewport_list_->SetBufferViewport(
886 kViewportListHeadlockedOffset + GVR_RIGHT_EYE, 888 kViewportListHeadlockedOffset + GVR_RIGHT_EYE,
887 *headlocked_right_viewport_); 889 *headlocked_right_viewport_);
888 890
889 // Bind the headlocked framebuffer. 891 // Bind the headlocked framebuffer.
890 frame.BindBuffer(kFrameHeadlockedBuffer); 892 frame.BindBuffer(kFrameHeadlockedBuffer);
891 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 893 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
892 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 894 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
893 DrawUiView(nullptr, head_locked_elements, render_size_headlocked_, 895 gvr::Mat4f identity_matrix;
894 kViewportListHeadlockedOffset); 896 SetIdentityM(identity_matrix);
897 DrawUiView(identity_matrix, head_locked_elements, render_size_headlocked_,
898 kViewportListHeadlockedOffset, false);
895 frame.Unbind(); // Done with the headlocked buffer. 899 frame.Unbind(); // Done with the headlocked buffer.
896 } 900 }
897 } 901 }
898 902
899 void VrShellGl::DrawUiView(const gvr::Mat4f* head_pose, 903 void VrShellGl::DrawUiView(const gvr::Mat4f& head_pose,
900 const std::vector<const ContentRectangle*>& elements, 904 const std::vector<const ContentRectangle*>& elements,
901 const gvr::Sizei& render_size, 905 const gvr::Sizei& render_size,
902 int viewport_offset) { 906 int viewport_offset,
907 bool draw_cursor) {
903 TRACE_EVENT0("gpu", "VrShellGl::DrawUiView"); 908 TRACE_EVENT0("gpu", "VrShellGl::DrawUiView");
904 909
905 gvr::Mat4f view_matrix; 910 auto elementsInDrawOrder = GetElementsInDrawOrder(head_pose, elements);
906 if (head_pose) {
907 view_matrix = *head_pose;
908 } else {
909 SetIdentityM(view_matrix);
910 }
911 auto elementsInDrawOrder = GetElementsInDrawOrder(view_matrix, elements);
912 911
913 for (auto eye : {GVR_LEFT_EYE, GVR_RIGHT_EYE}) { 912 for (auto eye : {GVR_LEFT_EYE, GVR_RIGHT_EYE}) {
914 buffer_viewport_list_->GetBufferViewport(eye + viewport_offset, 913 buffer_viewport_list_->GetBufferViewport(eye + viewport_offset,
915 buffer_viewport_.get()); 914 buffer_viewport_.get());
916 915
917 const gvr::Mat4f eye_view_matrix = 916 const gvr::Mat4f eye_view_matrix =
918 MatrixMul(gvr_api_->GetEyeFromHeadMatrix(eye), view_matrix); 917 MatrixMul(gvr_api_->GetEyeFromHeadMatrix(eye), head_pose);
919 918
920 gvr::Recti pixel_rect = 919 gvr::Recti pixel_rect =
921 CalculatePixelSpaceRect(render_size, buffer_viewport_->GetSourceUv()); 920 CalculatePixelSpaceRect(render_size, buffer_viewport_->GetSourceUv());
922 glViewport(pixel_rect.left, pixel_rect.bottom, 921 glViewport(pixel_rect.left, pixel_rect.bottom,
923 pixel_rect.right - pixel_rect.left, 922 pixel_rect.right - pixel_rect.left,
924 pixel_rect.top - pixel_rect.bottom); 923 pixel_rect.top - pixel_rect.bottom);
925 924
926 const gvr::Mat4f render_matrix = 925 const gvr::Mat4f render_matrix =
927 MatrixMul(PerspectiveMatrixFromView(buffer_viewport_->GetSourceFov(), 926 MatrixMul(PerspectiveMatrixFromView(buffer_viewport_->GetSourceFov(),
928 kZNear, kZFar), 927 kZNear, kZFar),
929 eye_view_matrix); 928 eye_view_matrix);
930 929
931 DrawElements(render_matrix, eye_view_matrix, elementsInDrawOrder); 930 DrawElements(render_matrix, elementsInDrawOrder);
932 if (head_pose != nullptr && !web_vr_mode_) { 931 if (draw_cursor) {
933 DrawCursor(render_matrix); 932 DrawCursor(render_matrix);
934 } 933 }
935 } 934 }
936 } 935 }
937 936
938 void VrShellGl::DrawElements( 937 void VrShellGl::DrawElements(
939 const gvr::Mat4f& view_proj_matrix, 938 const gvr::Mat4f& view_proj_matrix,
940 const gvr::Mat4f& view_matrix,
941 const std::vector<const ContentRectangle*>& elements) { 939 const std::vector<const ContentRectangle*>& elements) {
942 for (const auto* rect : elements) { 940 for (const auto* rect : elements) {
943 gvr::Mat4f transform = MatrixMul(view_proj_matrix, rect->TransformMatrix()); 941 gvr::Mat4f transform = MatrixMul(view_proj_matrix, rect->TransformMatrix());
944 942
945 switch (rect->fill) { 943 switch (rect->fill) {
946 case Fill::SPRITE: { 944 case Fill::SPRITE: {
947 Rectf copy_rect; 945 Rectf copy_rect;
948 copy_rect.x = static_cast<float>(rect->copy_rect.x) / ui_tex_css_width_; 946 copy_rect.x = static_cast<float>(rect->copy_rect.x) / ui_tex_css_width_;
949 copy_rect.y = 947 copy_rect.y =
950 static_cast<float>(rect->copy_rect.y) / ui_tex_css_height_; 948 static_cast<float>(rect->copy_rect.y) / ui_tex_css_height_;
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
1085 1083
1086 // Move the beam origin to the hand. 1084 // Move the beam origin to the hand.
1087 TranslateM(face_transform, face_transform, kHandPosition.x, kHandPosition.y, 1085 TranslateM(face_transform, face_transform, kHandPosition.x, kHandPosition.y,
1088 kHandPosition.z); 1086 kHandPosition.z);
1089 1087
1090 transform = MatrixMul(render_matrix, face_transform); 1088 transform = MatrixMul(render_matrix, face_transform);
1091 vr_shell_renderer_->GetLaserRenderer()->Draw(transform); 1089 vr_shell_renderer_->GetLaserRenderer()->Draw(transform);
1092 } 1090 }
1093 } 1091 }
1094 1092
1093 bool VrShellGl::ShouldDrawWebVr() {
1094 return web_vr_mode_ && scene_->GetWebVrRenderingEnabled();
1095 }
1096
1095 void VrShellGl::DrawWebVr() { 1097 void VrShellGl::DrawWebVr() {
1096 TRACE_EVENT0("gpu", "VrShellGl::DrawWebVr"); 1098 TRACE_EVENT0("gpu", "VrShellGl::DrawWebVr");
1097 // Don't need face culling, depth testing, blending, etc. Turn it all off. 1099 // Don't need face culling, depth testing, blending, etc. Turn it all off.
1098 glDisable(GL_CULL_FACE); 1100 glDisable(GL_CULL_FACE);
1099 glDepthMask(GL_FALSE); 1101 glDepthMask(GL_FALSE);
1100 glDisable(GL_DEPTH_TEST); 1102 glDisable(GL_DEPTH_TEST);
1101 glDisable(GL_SCISSOR_TEST); 1103 glDisable(GL_SCISSOR_TEST);
1102 glDisable(GL_BLEND); 1104 glDisable(GL_BLEND);
1103 glDisable(GL_POLYGON_OFFSET_FILL); 1105 glDisable(GL_POLYGON_OFFSET_FILL);
1104 1106
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
1201 task_runner_->PostDelayedTask(FROM_HERE, vsync_task_.callback(), 1203 task_runner_->PostDelayedTask(FROM_HERE, vsync_task_.callback(),
1202 target - now); 1204 target - now);
1203 1205
1204 base::TimeDelta time = intervals * vsync_interval_; 1206 base::TimeDelta time = intervals * vsync_interval_;
1205 if (!callback_.is_null()) { 1207 if (!callback_.is_null()) {
1206 SendVSync(time, base::ResetAndReturn(&callback_)); 1208 SendVSync(time, base::ResetAndReturn(&callback_));
1207 } else { 1209 } else {
1208 pending_vsync_ = true; 1210 pending_vsync_ = true;
1209 pending_time_ = time; 1211 pending_time_ = time;
1210 } 1212 }
1211 if (!web_vr_mode_) { 1213 if (!ShouldDrawWebVr()) {
1212 DrawFrame(-1); 1214 DrawFrame(-1);
1213 } 1215 }
1214 } 1216 }
1215 1217
1216 void VrShellGl::OnRequest(device::mojom::VRVSyncProviderRequest request) { 1218 void VrShellGl::OnRequest(device::mojom::VRVSyncProviderRequest request) {
1217 binding_.Close(); 1219 binding_.Close();
1218 binding_.Bind(std::move(request)); 1220 binding_.Bind(std::move(request));
1219 } 1221 }
1220 1222
1221 void VrShellGl::GetVSync(const GetVSyncCallback& callback) { 1223 void VrShellGl::GetVSync(const GetVSyncCallback& callback) {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1284 // appropriate recommended render resolution as the default size during 1286 // appropriate recommended render resolution as the default size during
1285 // InitializeGl. Revisit if the initialization order changes. 1287 // InitializeGl. Revisit if the initialization order changes.
1286 device::mojom::VRDisplayInfoPtr info = VrShell::CreateVRDisplayInfo( 1288 device::mojom::VRDisplayInfoPtr info = VrShell::CreateVRDisplayInfo(
1287 gvr_api_.get(), webvr_surface_size_, device_id); 1289 gvr_api_.get(), webvr_surface_size_, device_id);
1288 main_thread_task_runner_->PostTask( 1290 main_thread_task_runner_->PostTask(
1289 FROM_HERE, 1291 FROM_HERE,
1290 base::Bind(&RunVRDisplayInfoCallback, callback, base::Passed(&info))); 1292 base::Bind(&RunVRDisplayInfoCallback, callback, base::Passed(&info)));
1291 } 1293 }
1292 1294
1293 } // namespace vr_shell 1295 } // namespace vr_shell
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698