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 <chrono> | 7 #include <chrono> |
8 #include <limits> | 8 #include <limits> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
529 if (touch_pending_ || | 529 if (touch_pending_ || |
530 controller_->ButtonUpHappened( | 530 controller_->ButtonUpHappened( |
531 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_CLICK)) { | 531 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_CLICK)) { |
532 touch_pending_ = false; | 532 touch_pending_ = false; |
533 std::unique_ptr<WebGestureEvent> gesture(new WebGestureEvent( | 533 std::unique_ptr<WebGestureEvent> gesture(new WebGestureEvent( |
534 WebInputEvent::kGestureTapDown, WebInputEvent::kNoModifiers, | 534 WebInputEvent::kGestureTapDown, WebInputEvent::kNoModifiers, |
535 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF())); | 535 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF())); |
536 gesture->source_device = blink::kWebGestureDeviceTouchpad; | 536 gesture->source_device = blink::kWebGestureDeviceTouchpad; |
537 gesture->x = 0; | 537 gesture->x = 0; |
538 gesture->y = 0; | 538 gesture->y = 0; |
539 SendGesture(InputTarget::CONTENT, std::move(gesture)); | 539 SendGestureToContent(std::move(gesture)); |
540 DVLOG(1) << __FUNCTION__ << ": sent CLICK gesture"; | 540 DVLOG(1) << __FUNCTION__ << ": sent CLICK gesture"; |
541 } | 541 } |
542 } | 542 } |
543 | 543 |
544 gfx::Vector3dF ergo_neutral_pose; | 544 gfx::Vector3dF ergo_neutral_pose; |
545 if (!controller_->IsConnected()) { | 545 if (!controller_->IsConnected()) { |
546 // No controller detected, set up a gaze cursor that tracks the | 546 // No controller detected, set up a gaze cursor that tracks the |
547 // forward direction. | 547 // forward direction. |
548 ergo_neutral_pose = {0.0f, 0.0f, -1.0f}; | 548 ergo_neutral_pose = {0.0f, 0.0f, -1.0f}; |
549 controller_quat_ = GetRotationFromZAxis(forward_vector); | 549 controller_quat_ = GetRotationFromZAxis(forward_vector); |
(...skipping 29 matching lines...) Expand all Loading... |
579 // simplicity. | 579 // simplicity. |
580 float distance = scene_->GetBackgroundDistance(); | 580 float distance = scene_->GetBackgroundDistance(); |
581 target_point_ = | 581 target_point_ = |
582 vr::GetRayPoint(kHandPosition, controller_direction, distance); | 582 vr::GetRayPoint(kHandPosition, controller_direction, distance); |
583 gfx::Vector3dF eye_to_target = target_point_ - kOrigin; | 583 gfx::Vector3dF eye_to_target = target_point_ - kOrigin; |
584 vr::NormalizeVector(&eye_to_target); | 584 vr::NormalizeVector(&eye_to_target); |
585 | 585 |
586 // Determine which UI element (if any) intersects the line between the eyes | 586 // Determine which UI element (if any) intersects the line between the eyes |
587 // and the controller target position. | 587 // and the controller target position. |
588 float closest_element_distance = (target_point_ - kOrigin).Length(); | 588 float closest_element_distance = (target_point_ - kOrigin).Length(); |
| 589 previous_target_element_ = target_element_; |
589 target_element_ = nullptr; | 590 target_element_ = nullptr; |
590 float target_x; | 591 float target_x; |
591 float target_y; | 592 float target_y; |
592 | 593 |
593 for (const auto& plane : scene_->GetUiElements()) { | 594 for (auto& plane : scene_->GetUiElements()) { |
594 if (!plane->IsHitTestable()) | 595 if (!plane->IsHitTestable()) |
595 continue; | 596 continue; |
596 | 597 |
597 float distance_to_plane; | 598 float distance_to_plane; |
598 if (!plane->GetRayDistance(kOrigin, eye_to_target, &distance_to_plane)) | 599 if (!plane->GetRayDistance(kOrigin, eye_to_target, &distance_to_plane)) |
599 continue; | 600 continue; |
600 | 601 |
601 if (distance_to_plane < 0 || distance_to_plane >= closest_element_distance) | 602 if (distance_to_plane < 0 || distance_to_plane >= closest_element_distance) |
602 continue; | 603 continue; |
603 | 604 |
604 gfx::Point3F plane_intersection_point = | 605 gfx::Point3F plane_intersection_point = |
605 vr::GetRayPoint(kOrigin, eye_to_target, distance_to_plane); | 606 vr::GetRayPoint(kOrigin, eye_to_target, distance_to_plane); |
606 gfx::PointF unit_xy_point = | 607 gfx::PointF unit_xy_point = |
607 plane->GetUnitRectangleCoordinates(plane_intersection_point); | 608 plane->GetUnitRectangleCoordinates(plane_intersection_point); |
608 | 609 |
609 float x = 0.5f + unit_xy_point.x(); | 610 float x = 0.5f + unit_xy_point.x(); |
610 float y = 0.5f - unit_xy_point.y(); | 611 float y = 0.5f - unit_xy_point.y(); |
611 if (x < 0.0f || x >= 1.0f || y < 0.0f || y >= 1.0f) | 612 if (x < 0.0f || x >= 1.0f || y < 0.0f || y >= 1.0f) |
612 continue; | 613 continue; |
613 | 614 |
614 closest_element_distance = distance_to_plane; | 615 closest_element_distance = distance_to_plane; |
615 target_point_ = plane_intersection_point; | 616 target_point_ = plane_intersection_point; |
616 target_element_ = plane.get(); | 617 target_element_ = plane.get(); |
617 target_x = x; | 618 target_x = x; |
618 target_y = y; | 619 target_y = y; |
619 } | 620 } |
620 | 621 |
621 // Treat UI elements, which do not show web content, as NONE input | 622 // Handle input targeting on the content quad, ignoring any other elements. |
622 // targets since they cannot make use of the input anyway. | 623 // Content is treated specially to accomodate scrolling, flings, etc. |
623 InputTarget input_target = InputTarget::NONE; | 624 InputTarget input_target = InputTarget::NONE; |
624 int pixel_x = 0; | 625 int pixel_x = 0; |
625 int pixel_y = 0; | 626 int pixel_y = 0; |
626 | |
627 if (target_element_ != nullptr && target_element_->fill == Fill::CONTENT) { | 627 if (target_element_ != nullptr && target_element_->fill == Fill::CONTENT) { |
628 input_target = InputTarget::CONTENT; | 628 input_target = InputTarget::CONTENT; |
629 gfx::RectF pixel_rect(0, 0, content_tex_css_width_, | 629 gfx::RectF pixel_rect(0, 0, content_tex_css_width_, |
630 content_tex_css_height_); | 630 content_tex_css_height_); |
631 pixel_x = pixel_rect.x() + pixel_rect.width() * target_x; | 631 pixel_x = pixel_rect.x() + pixel_rect.width() * target_x; |
632 pixel_y = pixel_rect.y() + pixel_rect.height() * target_y; | 632 pixel_y = pixel_rect.y() + pixel_rect.height() * target_y; |
633 } | 633 } |
634 SendEventsToTarget(input_target, pixel_x, pixel_y); | 634 SendInputToContent(input_target, pixel_x, pixel_y); |
| 635 |
| 636 // Handle input targeting on all non-content elements. |
| 637 SendInputToUiElements(target_element_); |
635 } | 638 } |
636 | 639 |
637 void VrShellGl::HandleControllerAppButtonActivity( | 640 void VrShellGl::HandleControllerAppButtonActivity( |
638 const gfx::Vector3dF& controller_direction) { | 641 const gfx::Vector3dF& controller_direction) { |
639 // Note that button up/down state is transient, so ButtonDownHappened only | 642 // Note that button up/down state is transient, so ButtonDownHappened only |
640 // returns true for a single frame (and we're guaranteed not to miss it). | 643 // returns true for a single frame (and we're guaranteed not to miss it). |
641 if (controller_->ButtonDownHappened( | 644 if (controller_->ButtonDownHappened( |
642 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_APP)) { | 645 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_APP)) { |
643 controller_start_direction_ = controller_direction; | 646 controller_start_direction_ = controller_direction; |
644 } | 647 } |
(...skipping 16 matching lines...) Expand all Loading... |
661 weak_vr_shell_, direction)); | 664 weak_vr_shell_, direction)); |
662 } | 665 } |
663 } | 666 } |
664 if (direction == UiInterface::NONE) { | 667 if (direction == UiInterface::NONE) { |
665 main_thread_task_runner_->PostTask( | 668 main_thread_task_runner_->PostTask( |
666 FROM_HERE, base::Bind(&VrShell::AppButtonPressed, weak_vr_shell_)); | 669 FROM_HERE, base::Bind(&VrShell::AppButtonPressed, weak_vr_shell_)); |
667 } | 670 } |
668 } | 671 } |
669 } | 672 } |
670 | 673 |
671 void VrShellGl::SendEventsToTarget(InputTarget input_target, | 674 void VrShellGl::SendInputToContent(InputTarget input_target, |
672 int pixel_x, | 675 int pixel_x, |
673 int pixel_y) { | 676 int pixel_y) { |
674 std::vector<std::unique_ptr<WebGestureEvent>> gesture_list = | 677 std::vector<std::unique_ptr<WebGestureEvent>> gesture_list = |
675 controller_->DetectGestures(); | 678 controller_->DetectGestures(); |
676 double timestamp = gesture_list.front()->TimeStampSeconds(); | 679 double timestamp = gesture_list.front()->TimeStampSeconds(); |
677 | 680 |
678 if (touch_pending_) { | 681 if (touch_pending_) { |
679 touch_pending_ = false; | 682 touch_pending_ = false; |
680 std::unique_ptr<WebGestureEvent> event( | 683 std::unique_ptr<WebGestureEvent> event( |
681 new WebGestureEvent(WebInputEvent::kGestureTapDown, | 684 new WebGestureEvent(WebInputEvent::kGestureTapDown, |
682 WebInputEvent::kNoModifiers, timestamp)); | 685 WebInputEvent::kNoModifiers, timestamp)); |
683 event->source_device = blink::kWebGestureDeviceTouchpad; | 686 event->source_device = blink::kWebGestureDeviceTouchpad; |
684 event->x = pixel_x; | 687 event->x = pixel_x; |
685 event->y = pixel_y; | 688 event->y = pixel_y; |
686 gesture_list.push_back(std::move(event)); | 689 gesture_list.push_back(std::move(event)); |
687 } | 690 } |
688 | 691 |
689 for (auto& gesture : gesture_list) { | 692 for (auto& gesture : gesture_list) { |
690 gesture->x = pixel_x; | 693 gesture->x = pixel_x; |
691 gesture->y = pixel_y; | 694 gesture->y = pixel_y; |
692 auto movableGesture = base::MakeUnique<WebGestureEvent>(*gesture); | 695 auto movableGesture = base::MakeUnique<WebGestureEvent>(*gesture); |
693 | 696 |
694 switch (gesture->GetType()) { | 697 switch (gesture->GetType()) { |
695 // Once the user starts scrolling send all the scroll events to this | 698 // Once the user starts scrolling send all the scroll events to this |
696 // element until the scrolling stops. | 699 // element until the scrolling stops. |
697 case WebInputEvent::kGestureScrollBegin: | 700 case WebInputEvent::kGestureScrollBegin: |
698 current_scroll_target_ = input_target; | 701 current_scroll_target_ = input_target; |
699 if (current_scroll_target_ != InputTarget::NONE) { | 702 if (current_scroll_target_ != InputTarget::NONE) { |
700 SendGesture(current_scroll_target_, std::move(movableGesture)); | 703 SendGestureToContent(std::move(movableGesture)); |
701 } | 704 } |
702 break; | 705 break; |
703 case WebInputEvent::kGestureScrollEnd: | 706 case WebInputEvent::kGestureScrollEnd: |
704 if (current_scroll_target_ != InputTarget::NONE) { | 707 if (current_scroll_target_ != InputTarget::NONE) { |
705 SendGesture(current_scroll_target_, std::move(movableGesture)); | 708 SendGestureToContent(std::move(movableGesture)); |
706 } | 709 } |
707 current_fling_target_ = current_scroll_target_; | 710 current_fling_target_ = current_scroll_target_; |
708 current_scroll_target_ = InputTarget::NONE; | 711 current_scroll_target_ = InputTarget::NONE; |
709 break; | 712 break; |
710 case WebInputEvent::kGestureScrollUpdate: | 713 case WebInputEvent::kGestureScrollUpdate: |
711 if (current_scroll_target_ != InputTarget::NONE) { | 714 if (current_scroll_target_ != InputTarget::NONE) { |
712 SendGesture(current_scroll_target_, std::move(movableGesture)); | 715 SendGestureToContent(std::move(movableGesture)); |
713 } | 716 } |
714 break; | 717 break; |
715 case WebInputEvent::kGestureFlingStart: | 718 case WebInputEvent::kGestureFlingStart: |
716 if (current_fling_target_ != InputTarget::NONE) { | 719 if (current_fling_target_ != InputTarget::NONE) { |
717 SendGesture(current_fling_target_, std::move(movableGesture)); | 720 SendGestureToContent(std::move(movableGesture)); |
718 } | 721 } |
719 current_fling_target_ = InputTarget::NONE; | 722 current_fling_target_ = InputTarget::NONE; |
720 break; | 723 break; |
721 case WebInputEvent::kGestureFlingCancel: | 724 case WebInputEvent::kGestureFlingCancel: |
722 current_fling_target_ = InputTarget::NONE; | 725 current_fling_target_ = InputTarget::NONE; |
723 if (input_target != InputTarget::NONE) { | 726 if (input_target != InputTarget::NONE) { |
724 SendGesture(input_target, std::move(movableGesture)); | 727 SendGestureToContent(std::move(movableGesture)); |
725 } | 728 } |
726 break; | 729 break; |
727 case WebInputEvent::kGestureTapDown: | 730 case WebInputEvent::kGestureTapDown: |
728 current_fling_target_ = InputTarget::NONE; | 731 current_fling_target_ = InputTarget::NONE; |
729 if (input_target != InputTarget::NONE) { | 732 if (input_target != InputTarget::NONE) { |
730 SendGesture(input_target, std::move(movableGesture)); | 733 SendGestureToContent(std::move(movableGesture)); |
731 } | 734 } |
732 break; | 735 break; |
733 case WebInputEvent::kUndefined: | 736 case WebInputEvent::kUndefined: |
734 break; | 737 break; |
735 default: | 738 default: |
736 NOTREACHED(); | 739 NOTREACHED(); |
737 } | 740 } |
738 } | 741 } |
739 | 742 |
740 // Hover support | 743 // Hover support |
741 bool new_target = input_target != current_input_target_; | 744 bool new_target = input_target != current_input_target_; |
742 if (new_target && current_input_target_ != InputTarget::NONE) { | 745 if (new_target && current_input_target_ != InputTarget::NONE) { |
743 // Send a move event indicating that the pointer moved off of an element. | 746 // Send a move event indicating that the pointer moved off of an element. |
744 SendGesture(current_input_target_, | 747 SendGestureToContent( |
745 MakeMouseEvent(WebInputEvent::kMouseLeave, timestamp, 0, 0)); | 748 MakeMouseEvent(WebInputEvent::kMouseLeave, timestamp, 0, 0)); |
746 } | 749 } |
747 current_input_target_ = input_target; | 750 current_input_target_ = input_target; |
748 if (current_input_target_ != InputTarget::NONE) { | 751 if (current_input_target_ != InputTarget::NONE) { |
749 WebInputEvent::Type type = | 752 WebInputEvent::Type type = |
750 new_target ? WebInputEvent::kMouseEnter : WebInputEvent::kMouseMove; | 753 new_target ? WebInputEvent::kMouseEnter : WebInputEvent::kMouseMove; |
751 SendGesture(input_target, | 754 SendGestureToContent(MakeMouseEvent(type, timestamp, pixel_x, pixel_y)); |
752 MakeMouseEvent(type, timestamp, pixel_x, pixel_y)); | |
753 } | 755 } |
754 } | 756 } |
755 | 757 |
756 void VrShellGl::SendGesture(InputTarget input_target, | 758 void VrShellGl::SendInputToUiElements(UiElement* target_element) { |
757 std::unique_ptr<blink::WebInputEvent> event) { | 759 if (target_element != previous_target_element_) { |
758 DCHECK(input_target != InputTarget::NONE); | 760 if (previous_target_element_ && |
| 761 previous_target_element_->fill != Fill::CONTENT) { |
| 762 task_runner_->PostTask( |
| 763 FROM_HERE, base::Bind(&UiElement::OnHoverLeave, |
| 764 base::Unretained(previous_target_element_))); |
| 765 } |
| 766 if (target_element && target_element->fill != Fill::CONTENT) { |
| 767 task_runner_->PostTask(FROM_HERE, |
| 768 base::Bind(&UiElement::OnHoverEnter, |
| 769 base::Unretained(target_element))); |
| 770 } |
| 771 click_target_element_ = nullptr; |
| 772 } |
| 773 if (target_element && target_element->fill != Fill::CONTENT) { |
| 774 if (controller_->ButtonDownHappened( |
| 775 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_CLICK)) { |
| 776 task_runner_->PostTask(FROM_HERE, |
| 777 base::Bind(&UiElement::OnButtonDown, |
| 778 base::Unretained(target_element))); |
| 779 click_target_element_ = target_element; |
| 780 } |
| 781 if (controller_->ButtonUpHappened( |
| 782 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_CLICK)) { |
| 783 if (click_target_element_ == target_element) { |
| 784 task_runner_->PostTask(FROM_HERE, |
| 785 base::Bind(&UiElement::OnButtonUp, |
| 786 base::Unretained(target_element))); |
| 787 } |
| 788 click_target_element_ = nullptr; |
| 789 } |
| 790 } |
| 791 } |
| 792 |
| 793 void VrShellGl::SendGestureToContent( |
| 794 std::unique_ptr<blink::WebInputEvent> event) { |
759 main_thread_task_runner_->PostTask( | 795 main_thread_task_runner_->PostTask( |
760 FROM_HERE, base::Bind(&VrShell::ProcessContentGesture, weak_vr_shell_, | 796 FROM_HERE, base::Bind(&VrShell::ProcessContentGesture, weak_vr_shell_, |
761 base::Passed(std::move(event)))); | 797 base::Passed(std::move(event)))); |
762 } | 798 } |
763 | 799 |
764 void VrShellGl::DrawFrame(int16_t frame_index) { | 800 void VrShellGl::DrawFrame(int16_t frame_index) { |
765 TRACE_EVENT1("gpu", "VrShellGl::DrawFrame", "frame", frame_index); | 801 TRACE_EVENT1("gpu", "VrShellGl::DrawFrame", "frame", frame_index); |
766 | 802 |
767 base::TimeTicks current_time = base::TimeTicks::Now(); | 803 base::TimeTicks current_time = base::TimeTicks::Now(); |
768 | 804 |
(...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1325 // InitializeGl. Revisit if the initialization order changes. | 1361 // InitializeGl. Revisit if the initialization order changes. |
1326 device::mojom::VRDisplayInfoPtr info = | 1362 device::mojom::VRDisplayInfoPtr info = |
1327 device::GvrDelegate::CreateVRDisplayInfo(gvr_api_.get(), | 1363 device::GvrDelegate::CreateVRDisplayInfo(gvr_api_.get(), |
1328 webvr_surface_size_, device_id); | 1364 webvr_surface_size_, device_id); |
1329 main_thread_task_runner_->PostTask( | 1365 main_thread_task_runner_->PostTask( |
1330 FROM_HERE, | 1366 FROM_HERE, |
1331 base::Bind(&RunVRDisplayInfoCallback, callback, base::Passed(&info))); | 1367 base::Bind(&RunVRDisplayInfoCallback, callback, base::Passed(&info))); |
1332 } | 1368 } |
1333 | 1369 |
1334 } // namespace vr_shell | 1370 } // namespace vr_shell |
OLD | NEW |