OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |