Chromium Code Reviews| 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::OnMouseLeave, | |
| 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::OnMouseEnter, | |
| 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 click_target_element_ = target_element; | |
|
mthiesse
2017/04/26 16:09:49
While we're here, can you do buttondown/up events
asimjour1
2017/04/26 16:16:25
It'll also force us to disable more UI elements, a
mthiesse
2017/04/26 16:17:45
This would only be for skia elements at the moment
cjgrant
2017/04/26 21:16:00
Done as discussed offline.
| |
| 777 } | |
| 778 if (controller_->ButtonUpHappened( | |
| 779 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_CLICK)) { | |
| 780 if (click_target_element_ == target_element) { | |
| 781 task_runner_->PostTask( | |
| 782 FROM_HERE, | |
| 783 base::Bind(&UiElement::OnClick, base::Unretained(target_element))); | |
| 784 } | |
| 785 click_target_element_ = nullptr; | |
| 786 } | |
| 787 } | |
| 788 } | |
| 789 | |
| 790 void VrShellGl::SendGestureToContent( | |
| 791 std::unique_ptr<blink::WebInputEvent> event) { | |
| 759 main_thread_task_runner_->PostTask( | 792 main_thread_task_runner_->PostTask( |
| 760 FROM_HERE, base::Bind(&VrShell::ProcessContentGesture, weak_vr_shell_, | 793 FROM_HERE, base::Bind(&VrShell::ProcessContentGesture, weak_vr_shell_, |
| 761 base::Passed(std::move(event)))); | 794 base::Passed(std::move(event)))); |
| 762 } | 795 } |
| 763 | 796 |
| 764 void VrShellGl::DrawFrame(int16_t frame_index) { | 797 void VrShellGl::DrawFrame(int16_t frame_index) { |
| 765 TRACE_EVENT1("gpu", "VrShellGl::DrawFrame", "frame", frame_index); | 798 TRACE_EVENT1("gpu", "VrShellGl::DrawFrame", "frame", frame_index); |
| 766 | 799 |
| 767 base::TimeTicks current_time = base::TimeTicks::Now(); | 800 base::TimeTicks current_time = base::TimeTicks::Now(); |
| 768 | 801 |
| (...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1325 // InitializeGl. Revisit if the initialization order changes. | 1358 // InitializeGl. Revisit if the initialization order changes. |
| 1326 device::mojom::VRDisplayInfoPtr info = | 1359 device::mojom::VRDisplayInfoPtr info = |
| 1327 device::GvrDelegate::CreateVRDisplayInfo(gvr_api_.get(), | 1360 device::GvrDelegate::CreateVRDisplayInfo(gvr_api_.get(), |
| 1328 webvr_surface_size_, device_id); | 1361 webvr_surface_size_, device_id); |
| 1329 main_thread_task_runner_->PostTask( | 1362 main_thread_task_runner_->PostTask( |
| 1330 FROM_HERE, | 1363 FROM_HERE, |
| 1331 base::Bind(&RunVRDisplayInfoCallback, callback, base::Passed(&info))); | 1364 base::Bind(&RunVRDisplayInfoCallback, callback, base::Passed(&info))); |
| 1332 } | 1365 } |
| 1333 | 1366 |
| 1334 } // namespace vr_shell | 1367 } // namespace vr_shell |
| OLD | NEW |