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

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: 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 468 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 controller_->UpdateState(); 479 controller_->UpdateState();
480 480
481 // Note that button up/down state is transient, so ButtonUpHappened only 481 // Note that button up/down state is transient, so ButtonUpHappened only
482 // returns true for a single frame (and we're guaranteed not to miss it). 482 // returns true for a single frame (and we're guaranteed not to miss it).
483 if (controller_->ButtonUpHappened( 483 if (controller_->ButtonUpHappened(
484 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_APP)) { 484 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_APP)) {
485 main_thread_task_runner_->PostTask( 485 main_thread_task_runner_->PostTask(
486 FROM_HERE, base::Bind(&VrShell::AppButtonPressed, weak_vr_shell_)); 486 FROM_HERE, base::Bind(&VrShell::AppButtonPressed, weak_vr_shell_));
487 } 487 }
488 488
489 if (web_vr_mode_) { 489 if (ShouldDrawWebVr()) {
490 // Process screen touch events for Cardboard button compatibility. 490 // Process screen touch events for Cardboard button compatibility.
491 // Also send tap events for controller "touchpad click" events. 491 // Also send tap events for controller "touchpad click" events.
492 if (touch_pending_ || 492 if (touch_pending_ ||
493 controller_->ButtonUpHappened( 493 controller_->ButtonUpHappened(
494 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_CLICK)) { 494 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_CLICK)) {
495 touch_pending_ = false; 495 touch_pending_ = false;
496 std::unique_ptr<WebGestureEvent> gesture(new WebGestureEvent( 496 std::unique_ptr<WebGestureEvent> gesture(new WebGestureEvent(
497 WebInputEvent::GestureTapDown, WebInputEvent::NoModifiers, 497 WebInputEvent::GestureTapDown, WebInputEvent::NoModifiers,
498 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF())); 498 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF()));
499 gesture->sourceDevice = blink::WebGestureDeviceTouchpad; 499 gesture->sourceDevice = blink::WebGestureDeviceTouchpad;
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
692 void VrShellGl::DrawFrame(int16_t frame_index) { 692 void VrShellGl::DrawFrame(int16_t frame_index) {
693 TRACE_EVENT1("gpu", "VrShellGl::DrawFrame", "frame", frame_index); 693 TRACE_EVENT1("gpu", "VrShellGl::DrawFrame", "frame", frame_index);
694 694
695 // Reset the viewport list to just the pair of viewports for the 695 // Reset the viewport list to just the pair of viewports for the
696 // primary buffer each frame. Head-locked viewports get added by 696 // primary buffer each frame. Head-locked viewports get added by
697 // DrawVrShell if needed. 697 // DrawVrShell if needed.
698 buffer_viewport_list_->SetToRecommendedBufferViewports(); 698 buffer_viewport_list_->SetToRecommendedBufferViewports();
699 699
700 // If needed, resize the primary buffer for use with WebVR. Resizing 700 // If needed, resize the primary buffer for use with WebVR. Resizing
701 // needs to happen before acquiring a frame. 701 // needs to happen before acquiring a frame.
702 if (web_vr_mode_) { 702 if (ShouldDrawWebVr()) {
cjgrant 2017/03/16 15:44:36 Seeing the number of spots we call this, a couple
tiborg 2017/03/16 19:40:22 Yes, web_vr_mode_ should only be set by the GL thr
cjgrant 2017/03/20 15:34:57 So it turns out that WebVR changes have fully brok
tiborg 2017/03/20 15:56:08 Acknowledged.
703 // Process all pending_bounds_ changes targeted for before this 703 // Process all pending_bounds_ changes targeted for before this
704 // frame, being careful of wrapping frame indices. 704 // frame, being careful of wrapping frame indices.
705 // TODO(cjgrant): Do not compare the constants on every frame.
tiborg 2017/03/16 19:40:22 Make a bug for this?
cjgrant 2017/03/16 21:21:51 For something this trivial, I don't think a bug is
tiborg 2017/03/17 15:13:44 Yes, it was just a suggestion. You could make a bu
cjgrant 2017/03/20 15:34:57 So I've tied this cleanup to the UI math optimizat
tiborg 2017/03/20 15:56:08 Great, thanks.
705 static constexpr unsigned max = 706 static constexpr unsigned max =
706 std::numeric_limits<decltype(frame_index_)>::max(); 707 std::numeric_limits<decltype(frame_index_)>::max();
707 static_assert(max > kPoseRingBufferSize * 2, 708 static_assert(max > kPoseRingBufferSize * 2,
708 "To detect wrapping, kPoseRingBufferSize must be smaller " 709 "To detect wrapping, kPoseRingBufferSize must be smaller "
709 "than half of frame_index_ range."); 710 "than half of frame_index_ range.");
710 while (!pending_bounds_.empty()) { 711 while (!pending_bounds_.empty()) {
711 uint16_t index = pending_bounds_.front().first; 712 uint16_t index = pending_bounds_.front().first;
712 // If index is less than the frame_index it's possible we've 713 // If index is less than the frame_index it's possible we've
713 // wrapped, so we extend the range and 'un-wrap' to account 714 // wrapped, so we extend the range and 'un-wrap' to account
714 // for this. 715 // for this.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
754 } 755 }
755 756
756 TRACE_EVENT_BEGIN0("gpu", "VrShellGl::AcquireFrame"); 757 TRACE_EVENT_BEGIN0("gpu", "VrShellGl::AcquireFrame");
757 gvr::Frame frame = swap_chain_->AcquireFrame(); 758 gvr::Frame frame = swap_chain_->AcquireFrame();
758 TRACE_EVENT_END0("gpu", "VrShellGl::AcquireFrame"); 759 TRACE_EVENT_END0("gpu", "VrShellGl::AcquireFrame");
759 if (!frame.is_valid()) { 760 if (!frame.is_valid()) {
760 return; 761 return;
761 } 762 }
762 frame.BindBuffer(kFramePrimaryBuffer); 763 frame.BindBuffer(kFramePrimaryBuffer);
763 764
764 if (web_vr_mode_) { 765 if (ShouldDrawWebVr()) {
765 DrawWebVr(); 766 DrawWebVr();
766 } 767 }
767 768
768 gvr::Mat4f head_pose; 769 gvr::Mat4f head_pose;
769 770
770 // When using async reprojection, we need to know which pose was 771 // When using async reprojection, we need to know which pose was
771 // used in the WebVR app for drawing this frame and supply it when 772 // used in the WebVR app for drawing this frame and supply it when
772 // submitting. Technically we don't need a pose if not reprojecting, 773 // submitting. Technically we don't need a pose if not reprojecting,
773 // but keeping it uninitialized seems likely to cause problems down 774 // but keeping it uninitialized seems likely to cause problems down
774 // the road. Copying it is cheaper than fetching a new one. 775 // the road. Copying it is cheaper than fetching a new one.
775 if (web_vr_mode_) { 776 if (ShouldDrawWebVr()) {
777 // TODO(cjgrant): Do not compare the constants on every frame.
tiborg 2017/03/16 19:40:22 Here, too.
776 static_assert(!((kPoseRingBufferSize - 1) & kPoseRingBufferSize), 778 static_assert(!((kPoseRingBufferSize - 1) & kPoseRingBufferSize),
777 "kPoseRingBufferSize must be a power of 2"); 779 "kPoseRingBufferSize must be a power of 2");
778 head_pose = webvr_head_pose_[frame_index % kPoseRingBufferSize]; 780 head_pose = webvr_head_pose_[frame_index % kPoseRingBufferSize];
779 } else { 781 } else {
780 gvr::ClockTimePoint target_time = gvr::GvrApi::GetTimePointNow(); 782 gvr::ClockTimePoint target_time = gvr::GvrApi::GetTimePointNow();
781 target_time.monotonic_system_time_nanos += kPredictionTimeWithoutVsyncNanos; 783 target_time.monotonic_system_time_nanos += kPredictionTimeWithoutVsyncNanos;
782 head_pose = gvr_api_->GetHeadSpaceFromStartSpaceRotation(target_time); 784 head_pose = gvr_api_->GetHeadSpaceFromStartSpaceRotation(target_time);
783 } 785 }
784 786
785 gvr::Vec3f position = GetTranslation(head_pose); 787 gvr::Vec3f position = GetTranslation(head_pose);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
826 for (const auto& rect : scene_->GetUiElements()) { 828 for (const auto& rect : scene_->GetUiElements()) {
827 if (!rect->IsVisible()) 829 if (!rect->IsVisible())
828 continue; 830 continue;
829 if (rect->lock_to_fov) { 831 if (rect->lock_to_fov) {
830 head_locked_elements.push_back(rect.get()); 832 head_locked_elements.push_back(rect.get());
831 } else { 833 } else {
832 world_elements.push_back(rect.get()); 834 world_elements.push_back(rect.get());
833 } 835 }
834 } 836 }
835 837
836 if (web_vr_mode_) { 838 if (ShouldDrawWebVr()) {
837 // WebVR is incompatible with 3D world compositing since the 839 // WebVR is incompatible with 3D world compositing since the
838 // depth buffer was already populated with unknown scaling - the 840 // depth buffer was already populated with unknown scaling - the
839 // WebVR app has full control over zNear/zFar. Just leave the 841 // WebVR app has full control over zNear/zFar. Just leave the
840 // existing content in place in the primary buffer without 842 // existing content in place in the primary buffer without
841 // clearing. Currently, there aren't any world elements in WebVR 843 // clearing. Currently, there aren't any world elements in WebVR
842 // mode, this will need further testing if those get added 844 // mode, this will need further testing if those get added
843 // later. 845 // later.
844 } else { 846 } else {
845 // Non-WebVR mode, enable depth testing and clear the primary buffers. 847 // Non-WebVR mode, enable depth testing and clear the primary buffers.
846 glEnable(GL_CULL_FACE); 848 glEnable(GL_CULL_FACE);
847 glEnable(GL_DEPTH_TEST); 849 glEnable(GL_DEPTH_TEST);
848 glDepthMask(GL_TRUE); 850 glDepthMask(GL_TRUE);
849 851
850 const Colorf& backgroundColor = scene_->GetBackgroundColor(); 852 const Colorf& backgroundColor = scene_->GetBackgroundColor();
851 glClearColor(backgroundColor.r, backgroundColor.g, backgroundColor.b, 853 glClearColor(backgroundColor.r, backgroundColor.g, backgroundColor.b,
852 backgroundColor.a); 854 backgroundColor.a);
853 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 855 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
854 } 856 }
855 if (!world_elements.empty()) { 857 if (!world_elements.empty()) {
856 DrawUiView(&head_pose, world_elements, render_size_primary_, 858 DrawUiView(head_pose, world_elements, render_size_primary_,
857 kViewportListPrimaryOffset); 859 kViewportListPrimaryOffset, scene_->GetCursorEnabled());
858 } 860 }
859 frame.Unbind(); // Done with the primary buffer. 861 frame.Unbind(); // Done with the primary buffer.
860 862
861 if (!head_locked_elements.empty()) { 863 if (!head_locked_elements.empty()) {
862 // Add head-locked viewports. The list gets reset to just 864 // Add head-locked viewports. The list gets reset to just
863 // the recommended viewports (for the primary buffer) each frame. 865 // the recommended viewports (for the primary buffer) each frame.
864 buffer_viewport_list_->SetBufferViewport( 866 buffer_viewport_list_->SetBufferViewport(
865 kViewportListHeadlockedOffset + GVR_LEFT_EYE, 867 kViewportListHeadlockedOffset + GVR_LEFT_EYE,
866 *headlocked_left_viewport_); 868 *headlocked_left_viewport_);
867 buffer_viewport_list_->SetBufferViewport( 869 buffer_viewport_list_->SetBufferViewport(
868 kViewportListHeadlockedOffset + GVR_RIGHT_EYE, 870 kViewportListHeadlockedOffset + GVR_RIGHT_EYE,
869 *headlocked_right_viewport_); 871 *headlocked_right_viewport_);
870 872
871 // Bind the headlocked framebuffer. 873 // Bind the headlocked framebuffer.
872 frame.BindBuffer(kFrameHeadlockedBuffer); 874 frame.BindBuffer(kFrameHeadlockedBuffer);
873 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 875 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
874 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 876 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
875 DrawUiView(nullptr, head_locked_elements, render_size_headlocked_, 877 gvr::Mat4f identity_matrix;
876 kViewportListHeadlockedOffset); 878 SetIdentityM(identity_matrix);
879 DrawUiView(identity_matrix, head_locked_elements, render_size_headlocked_,
880 kViewportListHeadlockedOffset, false);
877 frame.Unbind(); // Done with the headlocked buffer. 881 frame.Unbind(); // Done with the headlocked buffer.
878 } 882 }
879 } 883 }
880 884
881 void VrShellGl::DrawUiView(const gvr::Mat4f* head_pose, 885 void VrShellGl::DrawUiView(const gvr::Mat4f& head_pose,
882 const std::vector<const ContentRectangle*>& elements, 886 const std::vector<const ContentRectangle*>& elements,
883 const gvr::Sizei& render_size, 887 const gvr::Sizei& render_size,
884 int viewport_offset) { 888 int viewport_offset,
889 bool draw_cursor) {
885 TRACE_EVENT0("gpu", "VrShellGl::DrawUiView"); 890 TRACE_EVENT0("gpu", "VrShellGl::DrawUiView");
886 891
887 gvr::Mat4f view_matrix; 892 auto elementsInDrawOrder = GetElementsInDrawOrder(head_pose, elements);
888 if (head_pose) {
889 view_matrix = *head_pose;
890 } else {
891 SetIdentityM(view_matrix);
892 }
893 auto elementsInDrawOrder = GetElementsInDrawOrder(view_matrix, elements);
894 893
895 for (auto eye : {GVR_LEFT_EYE, GVR_RIGHT_EYE}) { 894 for (auto eye : {GVR_LEFT_EYE, GVR_RIGHT_EYE}) {
896 buffer_viewport_list_->GetBufferViewport(eye + viewport_offset, 895 buffer_viewport_list_->GetBufferViewport(eye + viewport_offset,
897 buffer_viewport_.get()); 896 buffer_viewport_.get());
898 897
899 const gvr::Mat4f eye_view_matrix = 898 const gvr::Mat4f eye_view_matrix =
900 MatrixMul(gvr_api_->GetEyeFromHeadMatrix(eye), view_matrix); 899 MatrixMul(gvr_api_->GetEyeFromHeadMatrix(eye), head_pose);
901 900
902 gvr::Recti pixel_rect = 901 gvr::Recti pixel_rect =
903 CalculatePixelSpaceRect(render_size, buffer_viewport_->GetSourceUv()); 902 CalculatePixelSpaceRect(render_size, buffer_viewport_->GetSourceUv());
904 glViewport(pixel_rect.left, pixel_rect.bottom, 903 glViewport(pixel_rect.left, pixel_rect.bottom,
905 pixel_rect.right - pixel_rect.left, 904 pixel_rect.right - pixel_rect.left,
906 pixel_rect.top - pixel_rect.bottom); 905 pixel_rect.top - pixel_rect.bottom);
907 906
908 const gvr::Mat4f render_matrix = 907 const gvr::Mat4f render_matrix =
909 MatrixMul(PerspectiveMatrixFromView(buffer_viewport_->GetSourceFov(), 908 MatrixMul(PerspectiveMatrixFromView(buffer_viewport_->GetSourceFov(),
910 kZNear, kZFar), 909 kZNear, kZFar),
911 eye_view_matrix); 910 eye_view_matrix);
912 911
913 DrawElements(render_matrix, eye_view_matrix, elementsInDrawOrder); 912 DrawElements(render_matrix, elementsInDrawOrder);
914 if (head_pose != nullptr && !web_vr_mode_) { 913 if (draw_cursor)
tiborg 2017/03/16 19:40:22 Isn't it better, i.e. less error prone, to use cur
cjgrant 2017/03/16 21:21:51 I prefer to, but senior reviewers keep telling me
amp 2017/03/17 00:26:46 Interesting. The style guide says you can do eith
tiborg 2017/03/17 15:13:43 If we all prefer it why not embrace it in our code
cjgrant 2017/03/20 15:34:57 We're the owners, so we can go either way. And, w
915 DrawCursor(render_matrix); 914 DrawCursor(render_matrix);
916 }
917 } 915 }
918 } 916 }
919 917
920 void VrShellGl::DrawElements( 918 void VrShellGl::DrawElements(
921 const gvr::Mat4f& view_proj_matrix, 919 const gvr::Mat4f& view_proj_matrix,
922 const gvr::Mat4f& view_matrix,
923 const std::vector<const ContentRectangle*>& elements) { 920 const std::vector<const ContentRectangle*>& elements) {
924 for (const auto* rect : elements) { 921 for (const auto* rect : elements) {
925 gvr::Mat4f transform = MatrixMul(view_proj_matrix, rect->TransformMatrix()); 922 gvr::Mat4f transform = MatrixMul(view_proj_matrix, rect->TransformMatrix());
926 923
927 switch (rect->fill) { 924 switch (rect->fill) {
928 case Fill::SPRITE: { 925 case Fill::SPRITE: {
929 Rectf copy_rect; 926 Rectf copy_rect;
930 copy_rect.x = static_cast<float>(rect->copy_rect.x) / ui_tex_css_width_; 927 copy_rect.x = static_cast<float>(rect->copy_rect.x) / ui_tex_css_width_;
931 copy_rect.y = 928 copy_rect.y =
932 static_cast<float>(rect->copy_rect.y) / ui_tex_css_height_; 929 static_cast<float>(rect->copy_rect.y) / ui_tex_css_height_;
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
1067 1064
1068 // Move the beam origin to the hand. 1065 // Move the beam origin to the hand.
1069 TranslateM(face_transform, face_transform, kHandPosition.x, kHandPosition.y, 1066 TranslateM(face_transform, face_transform, kHandPosition.x, kHandPosition.y,
1070 kHandPosition.z); 1067 kHandPosition.z);
1071 1068
1072 transform = MatrixMul(render_matrix, face_transform); 1069 transform = MatrixMul(render_matrix, face_transform);
1073 vr_shell_renderer_->GetLaserRenderer()->Draw(transform); 1070 vr_shell_renderer_->GetLaserRenderer()->Draw(transform);
1074 } 1071 }
1075 } 1072 }
1076 1073
1074 bool VrShellGl::ShouldDrawWebVr() {
1075 return web_vr_mode_ && scene_->GetWebVrRenderingEnabled();
1076 }
1077
1077 void VrShellGl::DrawWebVr() { 1078 void VrShellGl::DrawWebVr() {
1078 TRACE_EVENT0("gpu", "VrShellGl::DrawWebVr"); 1079 TRACE_EVENT0("gpu", "VrShellGl::DrawWebVr");
1079 // Don't need face culling, depth testing, blending, etc. Turn it all off. 1080 // Don't need face culling, depth testing, blending, etc. Turn it all off.
1080 glDisable(GL_CULL_FACE); 1081 glDisable(GL_CULL_FACE);
1081 glDepthMask(GL_FALSE); 1082 glDepthMask(GL_FALSE);
1082 glDisable(GL_DEPTH_TEST); 1083 glDisable(GL_DEPTH_TEST);
1083 glDisable(GL_SCISSOR_TEST); 1084 glDisable(GL_SCISSOR_TEST);
1084 glDisable(GL_BLEND); 1085 glDisable(GL_BLEND);
1085 glDisable(GL_POLYGON_OFFSET_FILL); 1086 glDisable(GL_POLYGON_OFFSET_FILL);
1086 1087
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
1183 task_runner_->PostDelayedTask(FROM_HERE, vsync_task_.callback(), 1184 task_runner_->PostDelayedTask(FROM_HERE, vsync_task_.callback(),
1184 target - now); 1185 target - now);
1185 1186
1186 base::TimeDelta time = intervals * vsync_interval_; 1187 base::TimeDelta time = intervals * vsync_interval_;
1187 if (!callback_.is_null()) { 1188 if (!callback_.is_null()) {
1188 SendVSync(time, base::ResetAndReturn(&callback_)); 1189 SendVSync(time, base::ResetAndReturn(&callback_));
1189 } else { 1190 } else {
1190 pending_vsync_ = true; 1191 pending_vsync_ = true;
1191 pending_time_ = time; 1192 pending_time_ = time;
1192 } 1193 }
1193 if (!web_vr_mode_) { 1194 if (!ShouldDrawWebVr()) {
1194 DrawFrame(-1); 1195 DrawFrame(-1);
1195 } 1196 }
1196 } 1197 }
1197 1198
1198 void VrShellGl::OnRequest(device::mojom::VRVSyncProviderRequest request) { 1199 void VrShellGl::OnRequest(device::mojom::VRVSyncProviderRequest request) {
1199 binding_.Close(); 1200 binding_.Close();
1200 binding_.Bind(std::move(request)); 1201 binding_.Bind(std::move(request));
1201 } 1202 }
1202 1203
1203 void VrShellGl::GetVSync(const GetVSyncCallback& callback) { 1204 void VrShellGl::GetVSync(const GetVSyncCallback& callback) {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1266 // appropriate recommended render resolution as the default size during 1267 // appropriate recommended render resolution as the default size during
1267 // InitializeGl. Revisit if the initialization order changes. 1268 // InitializeGl. Revisit if the initialization order changes.
1268 device::mojom::VRDisplayInfoPtr info = VrShell::CreateVRDisplayInfo( 1269 device::mojom::VRDisplayInfoPtr info = VrShell::CreateVRDisplayInfo(
1269 gvr_api_.get(), webvr_surface_size_, device_id); 1270 gvr_api_.get(), webvr_surface_size_, device_id);
1270 main_thread_task_runner_->PostTask( 1271 main_thread_task_runner_->PostTask(
1271 FROM_HERE, 1272 FROM_HERE,
1272 base::Bind(&RunVRDisplayInfoCallback, callback, base::Passed(&info))); 1273 base::Bind(&RunVRDisplayInfoCallback, callback, base::Passed(&info)));
1273 } 1274 }
1274 1275
1275 } // namespace vr_shell 1276 } // namespace vr_shell
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698